Mir

Merge lp:~alan-griffiths/mir/spike-exposing-rpc-in-frontend into lp:mir

Proposed by Alan Griffiths
Status: Merged
Approved by: Alan Griffiths
Approved revision: no longer in the source branch.
Merged at revision: 1344
Proposed branch: lp:~alan-griffiths/mir/spike-exposing-rpc-in-frontend
Merge into: lp:mir
Diff against target: 918 lines (+355/-180)
20 files modified
include/server/mir/default_server_configuration.h (+3/-4)
include/server/mir/frontend/message_processor.h (+10/-11)
include/server/mir/frontend/protobuf_session_creator.h (+9/-1)
include/server/mir/frontend/template_protobuf_message_processor.h (+15/-36)
src/server/frontend/CMakeLists.txt (+0/-2)
src/server/frontend/default_configuration.cpp (+1/-1)
src/server/frontend/null_message_processor.cpp (+0/-26)
src/server/frontend/protobuf_message_processor.cpp (+8/-2)
src/server/frontend/protobuf_message_processor.h (+6/-3)
src/server/frontend/protobuf_session_creator.cpp (+14/-2)
src/server/frontend/published_socket_connector.cpp (+1/-1)
src/server/frontend/socket_session.cpp (+9/-2)
src/server/frontend/socket_session.h (+1/-1)
src/server/frontend/template_protobuf_message_processor.cpp (+0/-44)
src/shared/protobuf/mir_protobuf_wire.proto (+1/-1)
tests/acceptance-tests/test_protobuf.cpp (+216/-7)
tests/acceptance-tests/test_protobuf.proto (+1/-0)
tests/mir_test_doubles/test_protobuf_socket_server.cpp (+1/-1)
tests/unit-tests/frontend/test_published_socket_connector.cpp (+1/-1)
tests/unit-tests/frontend/test_socket_session.cpp (+58/-34)
To merge this branch: bzr merge lp:~alan-griffiths/mir/spike-exposing-rpc-in-frontend
Reviewer Review Type Date Requested Status
Alexandros Frantzis (community) Approve
Kevin DuBois (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+202351@code.launchpad.net

Commit message

frontend: exposing internals of the RPC mechanism to enable custom function calls to be added.

Description of the change

frontend: exposing internals of the RPC mechanism to enable custom function calls to be added. (As illustrated by DemoPrivateProtobuf.*)

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

I like the new version better.

Looks OK, besides some stray tabs:

272 + sender(sender),

819 + std::function<void(boost::system::error_code const&, size_t)> const& callback,
820 + boost::asio::streambuf& stream,
821 + size_t size)
822 + {
823 + read_size = size;
824 + pstream = &stream;
825 + callback_function = callback;831

831 + ASSERT_THAT(callback_function, Ne(nullptr));
839 + callback_function(code, size);

866 + int const header_size = 2;

review: Needs Fixing
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> I like the new version better.
>
> Looks OK, besides some stray tabs:
>

Weird, I've checked that the editor is set to insert spaces, but tabs appear in the text.

Fixed anyway.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote :

nit:
l913, 914, 867 seem like bit magic numbers.

other than that, looks okay though

review: Approve
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

Looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'include/server/mir/default_server_configuration.h'
--- include/server/mir/default_server_configuration.h 2014-01-13 06:12:33 +0000
+++ include/server/mir/default_server_configuration.h 2014-01-21 15:42:35 +0000
@@ -239,6 +239,9 @@
239239
240 virtual std::shared_ptr<input::InputChannelFactory> the_input_channel_factory();240 virtual std::shared_ptr<input::InputChannelFactory> the_input_channel_factory();
241 virtual std::shared_ptr<scene::MediatingDisplayChanger> the_mediating_display_changer();241 virtual std::shared_ptr<scene::MediatingDisplayChanger> the_mediating_display_changer();
242 virtual std::shared_ptr<frontend::ProtobufIpcFactory> the_ipc_factory(
243 std::shared_ptr<frontend::Shell> const& shell,
244 std::shared_ptr<graphics::GraphicBufferAllocator> const& allocator);
242245
243 CachedPtr<frontend::Connector> connector;246 CachedPtr<frontend::Connector> connector;
244247
@@ -292,10 +295,6 @@
292295
293private:296private:
294 std::shared_ptr<input::EventFilter> const default_filter;297 std::shared_ptr<input::EventFilter> const default_filter;
295 // the communications interface to use
296 virtual std::shared_ptr<frontend::ProtobufIpcFactory> the_ipc_factory(
297 std::shared_ptr<frontend::Shell> const& shell,
298 std::shared_ptr<graphics::GraphicBufferAllocator> const& allocator);
299298
300 virtual std::string the_socket_file() const;299 virtual std::string the_socket_file() const;
301300
302301
=== renamed file 'src/server/frontend/connected_sessions.h' => 'include/server/mir/frontend/connected_sessions.h'
=== modified file 'include/server/mir/frontend/message_processor.h'
--- include/server/mir/frontend/message_processor.h 2014-01-16 14:39:11 +0000
+++ include/server/mir/frontend/message_processor.h 2014-01-21 15:42:35 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright © 2012 Canonical Ltd.2 * Copyright © 2012, 2014 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,5 * under the terms of the GNU General Public License version 3,
@@ -19,10 +19,15 @@
19#ifndef MIR_FRONTEND_MESSAGE_PROCESSOR_H_19#ifndef MIR_FRONTEND_MESSAGE_PROCESSOR_H_
20#define MIR_FRONTEND_MESSAGE_PROCESSOR_H_20#define MIR_FRONTEND_MESSAGE_PROCESSOR_H_
2121
22#include <iosfwd>
23
24namespace mir22namespace mir
25{23{
24namespace protobuf
25{
26namespace wire
27{
28class Invocation;
29}
30}
26namespace frontend31namespace frontend
27{32{
28namespace detail33namespace detail
@@ -31,20 +36,14 @@
31class MessageProcessor36class MessageProcessor
32{37{
33public:38public:
34 virtual bool process_message(std::istream& msg) = 0;39 virtual bool dispatch(mir::protobuf::wire::Invocation const& invocation) = 0;
40
35protected:41protected:
36 MessageProcessor() = default;42 MessageProcessor() = default;
37 virtual ~MessageProcessor() = default;43 virtual ~MessageProcessor() = default;
38 MessageProcessor(MessageProcessor const&) = delete;44 MessageProcessor(MessageProcessor const&) = delete;
39 MessageProcessor& operator=(MessageProcessor const&) = delete;45 MessageProcessor& operator=(MessageProcessor const&) = delete;
40};46};
41
42class NullMessageProcessor : MessageProcessor
43{
44public:
45 bool process_message(std::istream&);
46};
47
48}47}
49}48}
50}49}
5150
=== renamed file 'src/server/frontend/protobuf_session_creator.h' => 'include/server/mir/frontend/protobuf_session_creator.h'
--- src/server/frontend/protobuf_session_creator.h 2014-01-15 12:26:01 +0000
+++ include/server/mir/frontend/protobuf_session_creator.h 2014-01-21 15:42:35 +0000
@@ -20,12 +20,13 @@
20#define MIR_FRONTEND_PROTOBUF_SESSION_CREATOR_H_20#define MIR_FRONTEND_PROTOBUF_SESSION_CREATOR_H_
2121
22#include "mir/frontend/session_creator.h"22#include "mir/frontend/session_creator.h"
23#include "connected_sessions.h"23#include "mir/frontend/connected_sessions.h"
2424
25#include <atomic>25#include <atomic>
2626
27namespace mir27namespace mir
28{28{
29namespace protobuf { class DisplayServer; }
29namespace frontend30namespace frontend
30{31{
31class MessageProcessorReport;32class MessageProcessorReport;
@@ -35,6 +36,8 @@
35namespace detail36namespace detail
36{37{
37struct SocketSession;38struct SocketSession;
39class MessageProcessor;
40class ProtobufMessageSender;
38}41}
3942
40class ProtobufSessionCreator : public SessionCreator43class ProtobufSessionCreator : public SessionCreator
@@ -48,6 +51,11 @@
4851
49 void create_session_for(std::shared_ptr<boost::asio::local::stream_protocol::socket> const& socket);52 void create_session_for(std::shared_ptr<boost::asio::local::stream_protocol::socket> const& socket);
5053
54 virtual std::shared_ptr<detail::MessageProcessor> create_processor(
55 std::shared_ptr<detail::ProtobufMessageSender> const& sender,
56 std::shared_ptr<protobuf::DisplayServer> const& display_server,
57 std::shared_ptr<MessageProcessorReport> const& report) const;
58
51private:59private:
52 int next_id();60 int next_id();
5361
5462
=== modified file 'include/server/mir/frontend/template_protobuf_message_processor.h'
--- include/server/mir/frontend/template_protobuf_message_processor.h 2014-01-17 10:55:55 +0000
+++ include/server/mir/frontend/template_protobuf_message_processor.h 2014-01-21 15:42:35 +0000
@@ -36,40 +36,15 @@
36{36{
37namespace detail37namespace detail
38{38{
39class ProtobufMessageSender;39// Utility metafunction result_ptr_t<> allows invoke() to pick the right
4040// send_response() overload. The base template resolves to the prototype
41// This class is intended to make implementation of a protobuf based MessageProcessor simpler.41// "send_response(::google::protobuf::uint32 id, ::google::protobuf::Message* response)"
42// The template method process_message() calls dispatch after unpacking the received "invocation"42// Client code may specialize result_ptr_t to resolve to another overload.
43// message. The related invoke<>() template handles further unpacking of the parameter43template<typename ResultType> struct result_ptr_t
44// message and packing of the response and calls send_response.44{ typedef ::google::protobuf::Message* type; };
45// Derived classes can overload send_response, but need to specialize result_ptr_t before instantiating
46// invoke<>() to ensure the correct overload is called.
47class TemplateProtobufMessageProcessor : public MessageProcessor
48{
49public:
50 TemplateProtobufMessageProcessor(
51 std::shared_ptr<ProtobufMessageSender> const& sender);
52
53 ~TemplateProtobufMessageProcessor() noexcept {}
54
55 void send_response(::google::protobuf::uint32 id, ::google::protobuf::Message* response);
56
57 std::shared_ptr<ProtobufMessageSender> const sender;
58
59private:
60 virtual bool dispatch(mir::protobuf::wire::Invocation const& invocation) = 0;
61
62 bool process_message(std::istream& msg) override final;
63};
64
65// Utility function result_ptr() allows invoke() to pick the right send_response() overload
66// Client code may specialize result_ptr_t to get an overload of send_response called.
67template<typename ResultType> struct result_ptr_t { typedef ::google::protobuf::Message* type; };
68template<typename ResultType> inline
69auto result_ptr(ResultType& result) -> typename result_ptr_t<ResultType>::type { return &result; }
7045
71// Boiler plate for unpacking a parameter message, invoking a server function, and46// Boiler plate for unpacking a parameter message, invoking a server function, and
72// sending the result message.47// sending the result message. Assumes the existence of Self::send_response().
73template<class Self, class Server, class ParameterMessage, class ResultMessage>48template<class Self, class Server, class ParameterMessage, class ResultMessage>
74void invoke(49void invoke(
75 Self* self,50 Self* self,
@@ -88,10 +63,14 @@
88 try63 try
89 {64 {
90 std::unique_ptr<google::protobuf::Closure> callback(65 std::unique_ptr<google::protobuf::Closure> callback(
91 google::protobuf::NewPermanentCallback(self,66 google::protobuf::NewPermanentCallback<
92 &Self::send_response,67 Self,
93 invocation.id(),68 ::google::protobuf::uint32,
94 result_ptr(result_message)));69 typename result_ptr_t<ResultMessage>::type>(
70 self,
71 &Self::send_response,
72 invocation.id(),
73 &result_message));
9574
96 (server->*function)(75 (server->*function)(
97 0,76 0,
9877
=== modified file 'src/server/frontend/CMakeLists.txt'
--- src/server/frontend/CMakeLists.txt 2014-01-20 07:11:48 +0000
+++ src/server/frontend/CMakeLists.txt 2014-01-21 15:42:35 +0000
@@ -8,11 +8,9 @@
8 protobuf_message_processor.cpp8 protobuf_message_processor.cpp
9 protobuf_responder.cpp9 protobuf_responder.cpp
10 protobuf_buffer_packer.cpp10 protobuf_buffer_packer.cpp
11 null_message_processor.cpp
12 published_socket_connector.cpp11 published_socket_connector.cpp
13 protobuf_session_creator.cpp12 protobuf_session_creator.cpp
14 socket_session.cpp13 socket_session.cpp
15 template_protobuf_message_processor.cpp
16 resource_cache.cpp14 resource_cache.cpp
17 socket_messenger.cpp15 socket_messenger.cpp
18 event_sender.cpp16 event_sender.cpp
1917
=== modified file 'src/server/frontend/default_configuration.cpp'
--- src/server/frontend/default_configuration.cpp 2014-01-20 07:11:48 +0000
+++ src/server/frontend/default_configuration.cpp 2014-01-21 15:42:35 +0000
@@ -17,10 +17,10 @@
17 */17 */
1818
19#include "mir/default_server_configuration.h"19#include "mir/default_server_configuration.h"
20#include "mir/frontend/protobuf_session_creator.h"
2021
21#include "resource_cache.h"22#include "resource_cache.h"
22#include "protobuf_ipc_factory.h"23#include "protobuf_ipc_factory.h"
23#include "protobuf_session_creator.h"
24#include "published_socket_connector.h"24#include "published_socket_connector.h"
25#include "session_mediator.h"25#include "session_mediator.h"
26#include "unauthorized_display_changer.h"26#include "unauthorized_display_changer.h"
2727
=== removed file 'src/server/frontend/null_message_processor.cpp'
--- src/server/frontend/null_message_processor.cpp 2014-01-16 14:39:11 +0000
+++ src/server/frontend/null_message_processor.cpp 1970-01-01 00:00:00 +0000
@@ -1,26 +0,0 @@
1/*
2 * Copyright © 2012 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Alan Griffiths <alan@octopull.co.uk>
17 */
18
19#include "mir/frontend/message_processor.h"
20
21namespace mfd = mir::frontend::detail;
22
23bool mfd::NullMessageProcessor::process_message(std::istream& )
24{
25 return false;
26}
270
=== modified file 'src/server/frontend/protobuf_message_processor.cpp'
--- src/server/frontend/protobuf_message_processor.cpp 2014-01-20 07:11:48 +0000
+++ src/server/frontend/protobuf_message_processor.cpp 2014-01-21 15:42:35 +0000
@@ -17,8 +17,9 @@
17 */17 */
1818
19#include "protobuf_message_processor.h"19#include "protobuf_message_processor.h"
20#include "mir/frontend/message_processor_report.h"
20#include "mir/frontend/protobuf_message_sender.h"21#include "mir/frontend/protobuf_message_sender.h"
21#include "mir/frontend/message_processor_report.h"22#include "mir/frontend/template_protobuf_message_processor.h"
2223
23namespace mfd = mir::frontend::detail;24namespace mfd = mir::frontend::detail;
2425
@@ -38,7 +39,7 @@
38 std::shared_ptr<ProtobufMessageSender> const& sender,39 std::shared_ptr<ProtobufMessageSender> const& sender,
39 std::shared_ptr<protobuf::DisplayServer> const& display_server,40 std::shared_ptr<protobuf::DisplayServer> const& display_server,
40 std::shared_ptr<MessageProcessorReport> const& report) :41 std::shared_ptr<MessageProcessorReport> const& report) :
41 TemplateProtobufMessageProcessor(sender),42 sender(sender),
42 display_server(display_server),43 display_server(display_server),
43 report(report)44 report(report)
44{45{
@@ -121,6 +122,11 @@
121 return result;122 return result;
122}123}
123124
125void mfd::ProtobufMessageProcessor::send_response(::google::protobuf::uint32 id, ::google::protobuf::Message* response)
126{
127 sender->send_response(id, response, {});
128}
129
124void mfd::ProtobufMessageProcessor::send_response(::google::protobuf::uint32 id, mir::protobuf::Buffer* response)130void mfd::ProtobufMessageProcessor::send_response(::google::protobuf::uint32 id, mir::protobuf::Buffer* response)
125{131{
126 const auto& fd = extract_fds_from(response);132 const auto& fd = extract_fds_from(response);
127133
=== modified file 'src/server/frontend/protobuf_message_processor.h'
--- src/server/frontend/protobuf_message_processor.h 2014-01-20 07:11:48 +0000
+++ src/server/frontend/protobuf_message_processor.h 2014-01-21 15:42:35 +0000
@@ -20,7 +20,7 @@
20#ifndef MIR_FRONTEND_PROTOBUF_MESSAGE_PROCESSOR_H_20#ifndef MIR_FRONTEND_PROTOBUF_MESSAGE_PROCESSOR_H_
21#define MIR_FRONTEND_PROTOBUF_MESSAGE_PROCESSOR_H_21#define MIR_FRONTEND_PROTOBUF_MESSAGE_PROCESSOR_H_
2222
23#include "mir/frontend/template_protobuf_message_processor.h"23#include "mir/frontend/message_processor.h"
2424
25#include "mir_protobuf.pb.h"25#include "mir_protobuf.pb.h"
2626
@@ -36,7 +36,9 @@
3636
37namespace detail37namespace detail
38{38{
39class ProtobufMessageProcessor : public TemplateProtobufMessageProcessor39class ProtobufMessageSender;
40
41class ProtobufMessageProcessor : public MessageProcessor
40{42{
41public:43public:
42 ProtobufMessageProcessor(44 ProtobufMessageProcessor(
@@ -46,7 +48,7 @@
4648
47 ~ProtobufMessageProcessor() noexcept {}49 ~ProtobufMessageProcessor() noexcept {}
4850
49 using TemplateProtobufMessageProcessor::send_response;51 void send_response(::google::protobuf::uint32 id, ::google::protobuf::Message* response);
50 void send_response(::google::protobuf::uint32 id, protobuf::Buffer* response);52 void send_response(::google::protobuf::uint32 id, protobuf::Buffer* response);
51 void send_response(::google::protobuf::uint32 id, protobuf::Connection* response);53 void send_response(::google::protobuf::uint32 id, protobuf::Connection* response);
52 void send_response(::google::protobuf::uint32 id, protobuf::Surface* response);54 void send_response(::google::protobuf::uint32 id, protobuf::Surface* response);
@@ -54,6 +56,7 @@
54private:56private:
55 bool dispatch(mir::protobuf::wire::Invocation const& invocation);57 bool dispatch(mir::protobuf::wire::Invocation const& invocation);
5658
59 std::shared_ptr<ProtobufMessageSender> const sender;
57 std::shared_ptr<protobuf::DisplayServer> const display_server;60 std::shared_ptr<protobuf::DisplayServer> const display_server;
58 std::shared_ptr<MessageProcessorReport> const report;61 std::shared_ptr<MessageProcessorReport> const report;
59};62};
6063
=== modified file 'src/server/frontend/protobuf_session_creator.cpp'
--- src/server/frontend/protobuf_session_creator.cpp 2014-01-20 07:11:48 +0000
+++ src/server/frontend/protobuf_session_creator.cpp 2014-01-21 15:42:35 +0000
@@ -16,7 +16,7 @@
16 * Authored by: Alan Griffiths <alan@octopull.co.uk>16 * Authored by: Alan Griffiths <alan@octopull.co.uk>
17 */17 */
1818
19#include "protobuf_session_creator.h"19#include "mir/frontend/protobuf_session_creator.h"
2020
21#include "event_sender.h"21#include "event_sender.h"
22#include "protobuf_message_processor.h"22#include "protobuf_message_processor.h"
@@ -67,7 +67,7 @@
67 ipc_factory->resource_cache());67 ipc_factory->resource_cache());
6868
69 auto const event_sink = std::make_shared<detail::EventSender>(messenger);69 auto const event_sink = std::make_shared<detail::EventSender>(messenger);
70 auto const msg_processor = std::make_shared<detail::ProtobufMessageProcessor>(70 auto const msg_processor = create_processor(
71 message_sender,71 message_sender,
72 ipc_factory->make_ipc_server(event_sink, authorized_to_resize_display),72 ipc_factory->make_ipc_server(event_sink, authorized_to_resize_display),
73 report);73 report);
@@ -77,3 +77,15 @@
77 session->read_next_message();77 session->read_next_message();
78 }78 }
79}79}
80
81std::shared_ptr<mfd::MessageProcessor>
82mf::ProtobufSessionCreator::create_processor(
83 std::shared_ptr<mfd::ProtobufMessageSender> const& sender,
84 std::shared_ptr<protobuf::DisplayServer> const& display_server,
85 std::shared_ptr<mf::MessageProcessorReport> const& report) const
86{
87 return std::make_shared<detail::ProtobufMessageProcessor>(
88 sender,
89 display_server,
90 report);
91}
8092
=== modified file 'src/server/frontend/published_socket_connector.cpp'
--- src/server/frontend/published_socket_connector.cpp 2014-01-13 06:12:33 +0000
+++ src/server/frontend/published_socket_connector.cpp 2014-01-21 15:42:35 +0000
@@ -17,7 +17,7 @@
17 */17 */
1818
19#include "published_socket_connector.h"19#include "published_socket_connector.h"
20#include "protobuf_session_creator.h"20#include "mir/frontend/protobuf_session_creator.h"
2121
22#include "mir/frontend/connector_report.h"22#include "mir/frontend/connector_report.h"
2323
2424
=== modified file 'src/server/frontend/socket_session.cpp'
--- src/server/frontend/socket_session.cpp 2014-01-20 07:11:48 +0000
+++ src/server/frontend/socket_session.cpp 2014-01-21 15:42:35 +0000
@@ -21,6 +21,8 @@
21#include "message_receiver.h"21#include "message_receiver.h"
22#include "mir/frontend/message_processor.h"22#include "mir/frontend/message_processor.h"
2323
24#include "mir_protobuf_wire.pb.h"
25
24#include <boost/signals2.hpp>26#include <boost/signals2.hpp>
25#include <boost/throw_exception.hpp>27#include <boost/throw_exception.hpp>
2628
@@ -85,8 +87,13 @@
85 }87 }
8688
87 std::istream msg(&message);89 std::istream msg(&message);
8890 mir::protobuf::wire::Invocation invocation;
89 if (processor->process_message(msg))91 invocation.ParseFromIstream(&msg);
92
93 if (!invocation.has_protocol_version() || invocation.protocol_version() != 1)
94 BOOST_THROW_EXCEPTION(std::runtime_error("Unsupported protocol version"));
95
96 if (processor->dispatch(invocation))
90 {97 {
91 read_next_message();98 read_next_message();
92 }99 }
93100
=== modified file 'src/server/frontend/socket_session.h'
--- src/server/frontend/socket_session.h 2014-01-16 14:39:11 +0000
+++ src/server/frontend/socket_session.h 2014-01-21 15:42:35 +0000
@@ -20,7 +20,7 @@
20#ifndef MIR_FRONTEND_DETAIL_SOCKET_SESSION_H_20#ifndef MIR_FRONTEND_DETAIL_SOCKET_SESSION_H_
21#define MIR_FRONTEND_DETAIL_SOCKET_SESSION_H_21#define MIR_FRONTEND_DETAIL_SOCKET_SESSION_H_
2222
23#include "connected_sessions.h"23#include "mir/frontend/connected_sessions.h"
2424
25#include <boost/asio.hpp>25#include <boost/asio.hpp>
2626
2727
=== removed file 'src/server/frontend/template_protobuf_message_processor.cpp'
--- src/server/frontend/template_protobuf_message_processor.cpp 2014-01-16 14:39:11 +0000
+++ src/server/frontend/template_protobuf_message_processor.cpp 1970-01-01 00:00:00 +0000
@@ -1,44 +0,0 @@
1/*
2 * Copyright © 2014 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Alan Griffiths <alan@octopull.co.uk>
17 */
18
19#include "mir/frontend/template_protobuf_message_processor.h"
20#include "mir/frontend/protobuf_message_sender.h"
21
22namespace mfd = mir::frontend::detail;
23
24mfd::TemplateProtobufMessageProcessor::TemplateProtobufMessageProcessor(
25 std::shared_ptr<ProtobufMessageSender> const& sender) :
26 sender(sender)
27{
28}
29
30bool mfd::TemplateProtobufMessageProcessor::process_message(std::istream& msg)
31{
32 mir::protobuf::wire::Invocation invocation;
33 invocation.ParseFromIstream(&msg);
34
35 if (invocation.has_protocol_version() && invocation.protocol_version() != 1)
36 BOOST_THROW_EXCEPTION(std::runtime_error("Unsupported protocol version"));
37
38 return dispatch(invocation);
39}
40
41void mfd::TemplateProtobufMessageProcessor::send_response(::google::protobuf::uint32 id, ::google::protobuf::Message* response)
42{
43 sender->send_response(id, response, {});
44}
450
=== modified file 'src/shared/protobuf/mir_protobuf_wire.proto'
--- src/shared/protobuf/mir_protobuf_wire.proto 2013-08-29 03:48:16 +0000
+++ src/shared/protobuf/mir_protobuf_wire.proto 2014-01-21 15:42:35 +0000
@@ -4,7 +4,7 @@
4 required uint32 id = 1;4 required uint32 id = 1;
5 required string method_name = 2;5 required string method_name = 2;
6 required bytes parameters = 3;6 required bytes parameters = 3;
7 optional uint32 protocol_version = 4;7 required uint32 protocol_version = 4;
8}8}
99
10message Result {10message Result {
1111
=== modified file 'tests/acceptance-tests/test_protobuf.cpp'
--- tests/acceptance-tests/test_protobuf.cpp 2014-01-10 17:34:40 +0000
+++ tests/acceptance-tests/test_protobuf.cpp 2014-01-21 15:42:35 +0000
@@ -20,29 +20,169 @@
2020
21#include "mir_toolkit/mir_client_library.h"21#include "mir_toolkit/mir_client_library.h"
22#include "mir/client/private.h"22#include "mir/client/private.h"
23#include "mir/frontend/protobuf_message_sender.h"
24#include "mir/frontend/protobuf_session_creator.h"
25#include "mir/frontend/template_protobuf_message_processor.h"
2326
24#include "mir_test_framework/stubbed_server_configuration.h"27#include "mir_test_framework/stubbed_server_configuration.h"
25#include "mir_test_framework/in_process_server.h"28#include "mir_test_framework/in_process_server.h"
2629
27#include <gtest/gtest.h>30#include <gtest/gtest.h>
31#include <gmock/gmock.h>
2832
29#include <atomic>33#include <atomic>
3034
35namespace mf = mir::frontend;
36namespace mfd = mir::frontend::detail;
37
38/*************************************************************************/
39/*************************************************************************/
40/* Note that the functionality demonstrated here relies on "detail" and */
41/* is not guaranteed to be supported in future. */
42/*************************************************************************/
43/*************************************************************************/
31namespace44namespace
32{45{
33class DemoPrivateProtobuf : public mir_test_framework::InProcessServer46struct DemoMirServer : mir::protobuf::MirServer
34{47{
35 mir::DefaultServerConfiguration& server_config() override { return server_config_; }48 MOCK_CONST_METHOD1(on_call, std::string(std::string));
3649
37 mir_test_framework::StubbedServerConfiguration server_config_;50 DemoMirServer()
51 {
52 using namespace testing;
53 ON_CALL(*this, on_call(_)).WillByDefault(Return("ok"));
54 }
55
56 void function(
57 ::google::protobuf::RpcController* ,
58 ::mir::protobuf::Parameters const* parameters,
59 ::mir::protobuf::Result* response,
60 ::google::protobuf::Closure* done)
61 {
62 response->set_value(on_call(parameters->name()));
63 done->Run();
64 }
65};
66
67// using a global for easy access from tests and DemoMessageProcessor::dispatch()
68DemoMirServer* demo_mir_server;
69
70struct DemoMessageProcessor : mfd::MessageProcessor
71{
72 DemoMessageProcessor(
73 std::shared_ptr<mfd::ProtobufMessageSender> const& sender,
74 std::shared_ptr<mfd::MessageProcessor> const& wrapped) :
75 sender(sender),
76 wrapped(wrapped) {}
77
78 bool dispatch(mir::protobuf::wire::Invocation const& invocation)
79 {
80 if ("function" == invocation.method_name())
81 {
82 mfd::invoke(
83 this,
84 demo_mir_server,
85 &DemoMirServer::function,
86 invocation);
87 return true;
88 }
89
90 return wrapped->dispatch(invocation);
91 }
92
93 void send_response(::google::protobuf::uint32 id, ::google::protobuf::Message* response)
94 {
95 sender->send_response(id, response, {});
96 }
97
98 std::shared_ptr<mfd::ProtobufMessageSender> const sender;
99 std::shared_ptr<mfd::MessageProcessor> const wrapped;
100};
101
102struct DemoSessionCreator : mf::ProtobufSessionCreator
103{
104 using ProtobufSessionCreator::ProtobufSessionCreator;
105
106 MOCK_CONST_METHOD3(create_processor,
107 std::shared_ptr<mfd::MessageProcessor>(
108 std::shared_ptr<mfd::ProtobufMessageSender> const& sender,
109 std::shared_ptr<mir::protobuf::DisplayServer> const& display_server,
110 std::shared_ptr<mf::MessageProcessorReport> const& report));
111
112 std::shared_ptr<mfd::MessageProcessor> create_wrapped_processor(
113 std::shared_ptr<mfd::ProtobufMessageSender> const& sender,
114 std::shared_ptr<mir::protobuf::DisplayServer> const& display_server,
115 std::shared_ptr<mf::MessageProcessorReport> const& report) const
116 {
117 auto const wrapped = mf::ProtobufSessionCreator::create_processor(
118 sender,
119 display_server,
120 report);
121
122 return std::make_shared<DemoMessageProcessor>(sender, wrapped);
123 }
124
125 std::shared_ptr<mfd::MessageProcessor> create_unwrapped_processor(
126 std::shared_ptr<mfd::ProtobufMessageSender> const& sender,
127 std::shared_ptr<mir::protobuf::DisplayServer> const& display_server,
128 std::shared_ptr<mf::MessageProcessorReport> const& report) const
129 {
130 return mf::ProtobufSessionCreator::create_processor(
131 sender,
132 display_server,
133 report);
134 }
135};
136
137struct DemoServerConfiguration : mir_test_framework::StubbedServerConfiguration
138{
139 std::shared_ptr<mf::SessionCreator> the_session_creator() override
140 {
141 return session_creator([this]
142 {
143 return std::make_shared<DemoSessionCreator>(
144 the_ipc_factory(the_frontend_shell(), the_buffer_allocator()),
145 the_session_authorizer(),
146 the_message_processor_report());
147 });
148 }
149
150};
151
152struct DemoPrivateProtobuf : mir_test_framework::InProcessServer
153{
154 mir::DefaultServerConfiguration& server_config() override { return my_server_config; }
155
156 DemoServerConfiguration my_server_config;
157
158 std::shared_ptr<DemoSessionCreator> demo_session_creator;
159
160 void SetUp()
161 {
162 ::demo_mir_server = &demo_mir_server;
163
164 mir_test_framework::InProcessServer::SetUp();
165 demo_session_creator = std::dynamic_pointer_cast<DemoSessionCreator>(my_server_config.the_session_creator());
166
167 using namespace testing;
168 ASSERT_THAT(demo_session_creator, NotNull());
169
170 ON_CALL(*demo_session_creator, create_processor(_, _, _))
171 .WillByDefault(Invoke(demo_session_creator.get(), &DemoSessionCreator::create_unwrapped_processor));
172 }
173
174 testing::NiceMock<DemoMirServer> demo_mir_server;
38};175};
39176
40void callback(std::atomic<bool>* called_back) { called_back->store(true); }177void callback(std::atomic<bool>* called_back) { called_back->store(true); }
41char const* const nothing_returned = "Nothing returned";178char const* const nothing_returned = "Nothing returned";
42}179}
43180
44TEST_F(DemoPrivateProtobuf, client_can_call_server)181TEST_F(DemoPrivateProtobuf, client_calls_server)
45{182{
183 using namespace testing;
184 EXPECT_CALL(*demo_session_creator, create_processor(_, _, _));
185
46 auto const connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);186 auto const connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
47 ASSERT_TRUE(mir_connection_is_valid(connection));187 ASSERT_TRUE(mir_connection_is_valid(connection));
48188
@@ -72,5 +212,74 @@
72 mir_connection_release(connection);212 mir_connection_release(connection);
73213
74 EXPECT_TRUE(called_back);214 EXPECT_TRUE(called_back);
75 EXPECT_EQ(nothing_returned, result.error());215 EXPECT_THAT(result.error(), Eq(nothing_returned));
216}
217
218TEST_F(DemoPrivateProtobuf, wrapping_message_processor)
219{
220 using namespace testing;
221 EXPECT_CALL(*demo_session_creator, create_processor(_, _, _))
222 .Times(1)
223 .WillOnce(Invoke(demo_session_creator.get(), &DemoSessionCreator::create_wrapped_processor));
224
225 auto const connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
226
227 mir_connection_release(connection);
228}
229
230TEST_F(DemoPrivateProtobuf, server_receives_function_call)
231{
232 using namespace testing;
233 EXPECT_CALL(*demo_session_creator, create_processor(_, _, _))
234 .WillRepeatedly(Invoke(demo_session_creator.get(), &DemoSessionCreator::create_wrapped_processor));
235
236 auto const connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
237 ASSERT_TRUE(mir_connection_is_valid(connection));
238
239 auto const rpc_channel = mir::client::the_rpc_channel(connection);
240
241 using namespace mir::protobuf;
242 using namespace google::protobuf;
243
244 MirServer::Stub server(rpc_channel.get());
245
246 Parameters parameters;
247 Result result;
248 parameters.set_name(__PRETTY_FUNCTION__);
249
250 EXPECT_CALL(demo_mir_server, on_call(__PRETTY_FUNCTION__)).Times(1);
251
252 server.function(nullptr, &parameters, &result, NewCallback([]{}));
253
254 mir_connection_release(connection);
255}
256
257
258TEST_F(DemoPrivateProtobuf, client_receives_result)
259{
260 using namespace testing;
261 EXPECT_CALL(*demo_session_creator, create_processor(_, _, _))
262 .WillRepeatedly(Invoke(demo_session_creator.get(), &DemoSessionCreator::create_wrapped_processor));
263 EXPECT_CALL(demo_mir_server, on_call(_)).WillRepeatedly(Return(__PRETTY_FUNCTION__));
264
265 auto const connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
266 ASSERT_TRUE(mir_connection_is_valid(connection));
267
268 auto const rpc_channel = mir::client::the_rpc_channel(connection);
269
270 using namespace mir::protobuf;
271 using namespace google::protobuf;
272
273 MirServer::Stub server(rpc_channel.get());
274
275 Parameters parameters;
276 Result result;
277 parameters.set_name(__PRETTY_FUNCTION__);
278
279 server.function(nullptr, &parameters, &result, NewCallback([]{}));
280
281 mir_connection_release(connection);
282
283 EXPECT_THAT(result.has_error(), Eq(false));
284 EXPECT_THAT(result.value(), Eq(__PRETTY_FUNCTION__));
76}285}
77286
=== modified file 'tests/acceptance-tests/test_protobuf.proto'
--- tests/acceptance-tests/test_protobuf.proto 2014-01-10 16:51:32 +0000
+++ tests/acceptance-tests/test_protobuf.proto 2014-01-21 15:42:35 +0000
@@ -9,6 +9,7 @@
99
10message Result {10message Result {
11 optional string error = 127;11 optional string error = 127;
12 optional string value = 1;
12}13}
1314
14service MirServer {15service MirServer {
1516
=== modified file 'tests/mir_test_doubles/test_protobuf_socket_server.cpp'
--- tests/mir_test_doubles/test_protobuf_socket_server.cpp 2014-01-15 12:26:01 +0000
+++ tests/mir_test_doubles/test_protobuf_socket_server.cpp 2014-01-21 15:42:35 +0000
@@ -21,8 +21,8 @@
21#include "mir_test_doubles/stub_session_authorizer.h"21#include "mir_test_doubles/stub_session_authorizer.h"
22#include "mir/frontend/connector_report.h"22#include "mir/frontend/connector_report.h"
23#include "mir/frontend/null_message_processor_report.h"23#include "mir/frontend/null_message_processor_report.h"
24#include "mir/frontend/protobuf_session_creator.h"
24#include "src/server/frontend/published_socket_connector.h"25#include "src/server/frontend/published_socket_connector.h"
25#include "src/server/frontend/protobuf_session_creator.h"
2626
27namespace mt = mir::test;27namespace mt = mir::test;
28namespace mtd = mir::test::doubles;28namespace mtd = mir::test::doubles;
2929
=== modified file 'tests/unit-tests/frontend/test_published_socket_connector.cpp'
--- tests/unit-tests/frontend/test_published_socket_connector.cpp 2014-01-20 07:11:48 +0000
+++ tests/unit-tests/frontend/test_published_socket_connector.cpp 2014-01-21 15:42:35 +0000
@@ -20,9 +20,9 @@
20#include "mir/frontend/connector.h"20#include "mir/frontend/connector.h"
21#include "mir/frontend/connector_report.h"21#include "mir/frontend/connector_report.h"
22#include "mir/frontend/null_message_processor_report.h"22#include "mir/frontend/null_message_processor_report.h"
23#include "mir/frontend/protobuf_session_creator.h"
23#include "src/server/frontend/resource_cache.h"24#include "src/server/frontend/resource_cache.h"
24#include "src/server/frontend/published_socket_connector.h"25#include "src/server/frontend/published_socket_connector.h"
25#include "src/server/frontend/protobuf_session_creator.h"
2626
27#include "mir_protobuf.pb.h"27#include "mir_protobuf.pb.h"
2828
2929
=== modified file 'tests/unit-tests/frontend/test_socket_session.cpp'
--- tests/unit-tests/frontend/test_socket_session.cpp 2014-01-20 07:11:48 +0000
+++ tests/unit-tests/frontend/test_socket_session.cpp 2014-01-21 15:42:35 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright © 2013 Canonical Ltd.2 * Copyright © 2013, 2014 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as5 * it under the terms of the GNU General Public License version 3 as
@@ -14,6 +14,7 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *15 *
16 * Authored by: Kevin DuBois <kevin.dubois@canonical.com>16 * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
17 * Alan Griffiths <alan@octopull.co.uk>
17 */18 */
1819
19#include "src/server/frontend/socket_session.h"20#include "src/server/frontend/socket_session.h"
@@ -22,6 +23,8 @@
2223
23#include "mir_test/fake_shared.h"24#include "mir_test/fake_shared.h"
2425
26#include "mir_protobuf_wire.pb.h"
27
25#include <gmock/gmock.h>28#include <gmock/gmock.h>
26#include <gtest/gtest.h>29#include <gtest/gtest.h>
2730
@@ -31,55 +34,76 @@
3134
32namespace35namespace
33{36{
34struct MockReceiver : public mfd::MessageReceiver37struct StubReceiver : public mfd::MessageReceiver
35{38{
36 MOCK_METHOD3(async_receive_msg, void(std::function<void(boost::system::error_code const&, size_t)> const&,39 void async_receive_msg(
37 boost::asio::streambuf&, size_t));40 std::function<void(boost::system::error_code const&, size_t)> const& callback,
41 boost::asio::streambuf& stream,
42 size_t size)
43 {
44 read_size = size;
45 pstream = &stream;
46 callback_function = callback;
47 }
48
49 void fake_receive_msg(char* buffer, size_t size)
50 {
51 using namespace testing;
52 ASSERT_NE(nullptr, callback_function);
53 ASSERT_THAT(pstream, NotNull());
54 ASSERT_THAT(read_size, Eq(size));
55
56 pstream->sputn(buffer, size);
57 pstream->commit(size);
58
59 boost::system::error_code code;
60 callback_function(code, size);
61 }
62
63private:
64 std::function<void(boost::system::error_code const&, size_t)> callback_function;
65 boost::asio::streambuf* pstream = nullptr;
66 size_t read_size = 0;
67
38 MOCK_METHOD0(client_pid, pid_t());68 MOCK_METHOD0(client_pid, pid_t());
39};69};
4070
41struct MockProcessor : public mfd::MessageProcessor71struct MockProcessor : public mfd::MessageProcessor
42{72{
43 MOCK_METHOD1(process_message, bool(std::istream&));73 MOCK_METHOD1(dispatch, bool(mir::protobuf::wire::Invocation const& invocation));
44};74};
45}75}
46struct SocketSessionTest : public ::testing::Test76struct SocketSessionTest : public ::testing::Test
47{77{
48 testing::NiceMock<MockProcessor> mock_processor;78 testing::NiceMock<MockProcessor> mock_processor;
49 testing::NiceMock<MockReceiver> mock_receiver;79 StubReceiver stub_receiver;
50};80};
5181
52TEST_F(SocketSessionTest, basic_msg)82TEST_F(SocketSessionTest, basic_msg_is_received_and_dispatched)
53{83{
84 int const header_size = 2;
85 char buffer[512];
86 mir::protobuf::wire::Invocation invocation;
87 invocation.set_id(1);
88 invocation.set_method_name("");
89 invocation.set_parameters(buffer, 0);
90 invocation.set_protocol_version(1);
91 auto const body_size = invocation.ByteSize();
92
54 using namespace testing;93 using namespace testing;
5594
56 std::shared_ptr<mfd::ConnectedSessions<mfd::SocketSession>> null_sessions;95 std::shared_ptr<mfd::ConnectedSessions<mfd::SocketSession>> null_sessions;
57 std::function<void(boost::system::error_code const&, size_t)> header_read, body_read;96
5897 mfd::SocketSession session(mt::fake_shared(stub_receiver), 0, null_sessions, mt::fake_shared(mock_processor));
59 size_t header_size = 2;98
60 EXPECT_CALL(mock_receiver, async_receive_msg(_,_, header_size))99 EXPECT_CALL(mock_processor, dispatch(_)).Times(1).WillOnce(Return(true));
61 .Times(1)100
62 .WillOnce(SaveArg<0>(&header_read));
63
64 mfd::SocketSession session(mt::fake_shared(mock_receiver), 0, null_sessions, mt::fake_shared(mock_processor));
65
66 //trigger wait for header
67 session.read_next_message();101 session.read_next_message();
68 testing::Mock::VerifyAndClearExpectations(&mock_receiver);102
69103 buffer[0] = body_size / 0x100;
70 //trigger body read104 buffer[1] = body_size % 0x100;
71 EXPECT_CALL(mock_receiver, async_receive_msg(_,_,_))105 stub_receiver.fake_receive_msg(buffer, header_size);
72 .Times(1)106
73 .WillOnce(SaveArg<0>(&body_read));107 invocation.SerializeToArray(buffer, sizeof buffer);
74108 stub_receiver.fake_receive_msg(buffer, body_size);
75 boost::system::error_code code;
76 header_read(code, 2);
77
78 testing::Mock::VerifyAndClearExpectations(&mock_receiver);
79
80 //trigger message process
81 EXPECT_CALL(mock_processor, process_message(_))
82 .Times(1)
83 .WillOnce(Return(true));
84 body_read(code, 9);
85}109}

Subscribers

People subscribed via source and target branches