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
1=== modified file 'include/server/mir/default_server_configuration.h'
2--- include/server/mir/default_server_configuration.h 2014-01-13 06:12:33 +0000
3+++ include/server/mir/default_server_configuration.h 2014-01-21 15:42:35 +0000
4@@ -239,6 +239,9 @@
5
6 virtual std::shared_ptr<input::InputChannelFactory> the_input_channel_factory();
7 virtual std::shared_ptr<scene::MediatingDisplayChanger> the_mediating_display_changer();
8+ virtual std::shared_ptr<frontend::ProtobufIpcFactory> the_ipc_factory(
9+ std::shared_ptr<frontend::Shell> const& shell,
10+ std::shared_ptr<graphics::GraphicBufferAllocator> const& allocator);
11
12 CachedPtr<frontend::Connector> connector;
13
14@@ -292,10 +295,6 @@
15
16 private:
17 std::shared_ptr<input::EventFilter> const default_filter;
18- // the communications interface to use
19- virtual std::shared_ptr<frontend::ProtobufIpcFactory> the_ipc_factory(
20- std::shared_ptr<frontend::Shell> const& shell,
21- std::shared_ptr<graphics::GraphicBufferAllocator> const& allocator);
22
23 virtual std::string the_socket_file() const;
24
25
26=== renamed file 'src/server/frontend/connected_sessions.h' => 'include/server/mir/frontend/connected_sessions.h'
27=== modified file 'include/server/mir/frontend/message_processor.h'
28--- include/server/mir/frontend/message_processor.h 2014-01-16 14:39:11 +0000
29+++ include/server/mir/frontend/message_processor.h 2014-01-21 15:42:35 +0000
30@@ -1,5 +1,5 @@
31 /*
32- * Copyright © 2012 Canonical Ltd.
33+ * Copyright © 2012, 2014 Canonical Ltd.
34 *
35 * This program is free software: you can redistribute it and/or modify it
36 * under the terms of the GNU General Public License version 3,
37@@ -19,10 +19,15 @@
38 #ifndef MIR_FRONTEND_MESSAGE_PROCESSOR_H_
39 #define MIR_FRONTEND_MESSAGE_PROCESSOR_H_
40
41-#include <iosfwd>
42-
43 namespace mir
44 {
45+namespace protobuf
46+{
47+namespace wire
48+{
49+class Invocation;
50+}
51+}
52 namespace frontend
53 {
54 namespace detail
55@@ -31,20 +36,14 @@
56 class MessageProcessor
57 {
58 public:
59- virtual bool process_message(std::istream& msg) = 0;
60+ virtual bool dispatch(mir::protobuf::wire::Invocation const& invocation) = 0;
61+
62 protected:
63 MessageProcessor() = default;
64 virtual ~MessageProcessor() = default;
65 MessageProcessor(MessageProcessor const&) = delete;
66 MessageProcessor& operator=(MessageProcessor const&) = delete;
67 };
68-
69-class NullMessageProcessor : MessageProcessor
70-{
71-public:
72- bool process_message(std::istream&);
73-};
74-
75 }
76 }
77 }
78
79=== renamed file 'src/server/frontend/protobuf_session_creator.h' => 'include/server/mir/frontend/protobuf_session_creator.h'
80--- src/server/frontend/protobuf_session_creator.h 2014-01-15 12:26:01 +0000
81+++ include/server/mir/frontend/protobuf_session_creator.h 2014-01-21 15:42:35 +0000
82@@ -20,12 +20,13 @@
83 #define MIR_FRONTEND_PROTOBUF_SESSION_CREATOR_H_
84
85 #include "mir/frontend/session_creator.h"
86-#include "connected_sessions.h"
87+#include "mir/frontend/connected_sessions.h"
88
89 #include <atomic>
90
91 namespace mir
92 {
93+namespace protobuf { class DisplayServer; }
94 namespace frontend
95 {
96 class MessageProcessorReport;
97@@ -35,6 +36,8 @@
98 namespace detail
99 {
100 struct SocketSession;
101+class MessageProcessor;
102+class ProtobufMessageSender;
103 }
104
105 class ProtobufSessionCreator : public SessionCreator
106@@ -48,6 +51,11 @@
107
108 void create_session_for(std::shared_ptr<boost::asio::local::stream_protocol::socket> const& socket);
109
110+ virtual std::shared_ptr<detail::MessageProcessor> create_processor(
111+ std::shared_ptr<detail::ProtobufMessageSender> const& sender,
112+ std::shared_ptr<protobuf::DisplayServer> const& display_server,
113+ std::shared_ptr<MessageProcessorReport> const& report) const;
114+
115 private:
116 int next_id();
117
118
119=== modified file 'include/server/mir/frontend/template_protobuf_message_processor.h'
120--- include/server/mir/frontend/template_protobuf_message_processor.h 2014-01-17 10:55:55 +0000
121+++ include/server/mir/frontend/template_protobuf_message_processor.h 2014-01-21 15:42:35 +0000
122@@ -36,40 +36,15 @@
123 {
124 namespace detail
125 {
126-class ProtobufMessageSender;
127-
128-// This class is intended to make implementation of a protobuf based MessageProcessor simpler.
129-// The template method process_message() calls dispatch after unpacking the received "invocation"
130-// message. The related invoke<>() template handles further unpacking of the parameter
131-// message and packing of the response and calls send_response.
132-// Derived classes can overload send_response, but need to specialize result_ptr_t before instantiating
133-// invoke<>() to ensure the correct overload is called.
134-class TemplateProtobufMessageProcessor : public MessageProcessor
135-{
136-public:
137- TemplateProtobufMessageProcessor(
138- std::shared_ptr<ProtobufMessageSender> const& sender);
139-
140- ~TemplateProtobufMessageProcessor() noexcept {}
141-
142- void send_response(::google::protobuf::uint32 id, ::google::protobuf::Message* response);
143-
144- std::shared_ptr<ProtobufMessageSender> const sender;
145-
146-private:
147- virtual bool dispatch(mir::protobuf::wire::Invocation const& invocation) = 0;
148-
149- bool process_message(std::istream& msg) override final;
150-};
151-
152-// Utility function result_ptr() allows invoke() to pick the right send_response() overload
153-// Client code may specialize result_ptr_t to get an overload of send_response called.
154-template<typename ResultType> struct result_ptr_t { typedef ::google::protobuf::Message* type; };
155-template<typename ResultType> inline
156-auto result_ptr(ResultType& result) -> typename result_ptr_t<ResultType>::type { return &result; }
157+// Utility metafunction result_ptr_t<> allows invoke() to pick the right
158+// send_response() overload. The base template resolves to the prototype
159+// "send_response(::google::protobuf::uint32 id, ::google::protobuf::Message* response)"
160+// Client code may specialize result_ptr_t to resolve to another overload.
161+template<typename ResultType> struct result_ptr_t
162+{ typedef ::google::protobuf::Message* type; };
163
164 // Boiler plate for unpacking a parameter message, invoking a server function, and
165-// sending the result message.
166+// sending the result message. Assumes the existence of Self::send_response().
167 template<class Self, class Server, class ParameterMessage, class ResultMessage>
168 void invoke(
169 Self* self,
170@@ -88,10 +63,14 @@
171 try
172 {
173 std::unique_ptr<google::protobuf::Closure> callback(
174- google::protobuf::NewPermanentCallback(self,
175- &Self::send_response,
176- invocation.id(),
177- result_ptr(result_message)));
178+ google::protobuf::NewPermanentCallback<
179+ Self,
180+ ::google::protobuf::uint32,
181+ typename result_ptr_t<ResultMessage>::type>(
182+ self,
183+ &Self::send_response,
184+ invocation.id(),
185+ &result_message));
186
187 (server->*function)(
188 0,
189
190=== modified file 'src/server/frontend/CMakeLists.txt'
191--- src/server/frontend/CMakeLists.txt 2014-01-20 07:11:48 +0000
192+++ src/server/frontend/CMakeLists.txt 2014-01-21 15:42:35 +0000
193@@ -8,11 +8,9 @@
194 protobuf_message_processor.cpp
195 protobuf_responder.cpp
196 protobuf_buffer_packer.cpp
197- null_message_processor.cpp
198 published_socket_connector.cpp
199 protobuf_session_creator.cpp
200 socket_session.cpp
201- template_protobuf_message_processor.cpp
202 resource_cache.cpp
203 socket_messenger.cpp
204 event_sender.cpp
205
206=== modified file 'src/server/frontend/default_configuration.cpp'
207--- src/server/frontend/default_configuration.cpp 2014-01-20 07:11:48 +0000
208+++ src/server/frontend/default_configuration.cpp 2014-01-21 15:42:35 +0000
209@@ -17,10 +17,10 @@
210 */
211
212 #include "mir/default_server_configuration.h"
213+#include "mir/frontend/protobuf_session_creator.h"
214
215 #include "resource_cache.h"
216 #include "protobuf_ipc_factory.h"
217-#include "protobuf_session_creator.h"
218 #include "published_socket_connector.h"
219 #include "session_mediator.h"
220 #include "unauthorized_display_changer.h"
221
222=== removed file 'src/server/frontend/null_message_processor.cpp'
223--- src/server/frontend/null_message_processor.cpp 2014-01-16 14:39:11 +0000
224+++ src/server/frontend/null_message_processor.cpp 1970-01-01 00:00:00 +0000
225@@ -1,26 +0,0 @@
226-/*
227- * Copyright © 2012 Canonical Ltd.
228- *
229- * This program is free software: you can redistribute it and/or modify it
230- * under the terms of the GNU General Public License version 3,
231- * as published by the Free Software Foundation.
232- *
233- * This program is distributed in the hope that it will be useful,
234- * but WITHOUT ANY WARRANTY; without even the implied warranty of
235- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
236- * GNU General Public License for more details.
237- *
238- * You should have received a copy of the GNU General Public License
239- * along with this program. If not, see <http://www.gnu.org/licenses/>.
240- *
241- * Authored by: Alan Griffiths <alan@octopull.co.uk>
242- */
243-
244-#include "mir/frontend/message_processor.h"
245-
246-namespace mfd = mir::frontend::detail;
247-
248-bool mfd::NullMessageProcessor::process_message(std::istream& )
249-{
250- return false;
251-}
252
253=== modified file 'src/server/frontend/protobuf_message_processor.cpp'
254--- src/server/frontend/protobuf_message_processor.cpp 2014-01-20 07:11:48 +0000
255+++ src/server/frontend/protobuf_message_processor.cpp 2014-01-21 15:42:35 +0000
256@@ -17,8 +17,9 @@
257 */
258
259 #include "protobuf_message_processor.h"
260+#include "mir/frontend/message_processor_report.h"
261 #include "mir/frontend/protobuf_message_sender.h"
262-#include "mir/frontend/message_processor_report.h"
263+#include "mir/frontend/template_protobuf_message_processor.h"
264
265 namespace mfd = mir::frontend::detail;
266
267@@ -38,7 +39,7 @@
268 std::shared_ptr<ProtobufMessageSender> const& sender,
269 std::shared_ptr<protobuf::DisplayServer> const& display_server,
270 std::shared_ptr<MessageProcessorReport> const& report) :
271- TemplateProtobufMessageProcessor(sender),
272+ sender(sender),
273 display_server(display_server),
274 report(report)
275 {
276@@ -121,6 +122,11 @@
277 return result;
278 }
279
280+void mfd::ProtobufMessageProcessor::send_response(::google::protobuf::uint32 id, ::google::protobuf::Message* response)
281+{
282+ sender->send_response(id, response, {});
283+}
284+
285 void mfd::ProtobufMessageProcessor::send_response(::google::protobuf::uint32 id, mir::protobuf::Buffer* response)
286 {
287 const auto& fd = extract_fds_from(response);
288
289=== modified file 'src/server/frontend/protobuf_message_processor.h'
290--- src/server/frontend/protobuf_message_processor.h 2014-01-20 07:11:48 +0000
291+++ src/server/frontend/protobuf_message_processor.h 2014-01-21 15:42:35 +0000
292@@ -20,7 +20,7 @@
293 #ifndef MIR_FRONTEND_PROTOBUF_MESSAGE_PROCESSOR_H_
294 #define MIR_FRONTEND_PROTOBUF_MESSAGE_PROCESSOR_H_
295
296-#include "mir/frontend/template_protobuf_message_processor.h"
297+#include "mir/frontend/message_processor.h"
298
299 #include "mir_protobuf.pb.h"
300
301@@ -36,7 +36,9 @@
302
303 namespace detail
304 {
305-class ProtobufMessageProcessor : public TemplateProtobufMessageProcessor
306+class ProtobufMessageSender;
307+
308+class ProtobufMessageProcessor : public MessageProcessor
309 {
310 public:
311 ProtobufMessageProcessor(
312@@ -46,7 +48,7 @@
313
314 ~ProtobufMessageProcessor() noexcept {}
315
316- using TemplateProtobufMessageProcessor::send_response;
317+ void send_response(::google::protobuf::uint32 id, ::google::protobuf::Message* response);
318 void send_response(::google::protobuf::uint32 id, protobuf::Buffer* response);
319 void send_response(::google::protobuf::uint32 id, protobuf::Connection* response);
320 void send_response(::google::protobuf::uint32 id, protobuf::Surface* response);
321@@ -54,6 +56,7 @@
322 private:
323 bool dispatch(mir::protobuf::wire::Invocation const& invocation);
324
325+ std::shared_ptr<ProtobufMessageSender> const sender;
326 std::shared_ptr<protobuf::DisplayServer> const display_server;
327 std::shared_ptr<MessageProcessorReport> const report;
328 };
329
330=== modified file 'src/server/frontend/protobuf_session_creator.cpp'
331--- src/server/frontend/protobuf_session_creator.cpp 2014-01-20 07:11:48 +0000
332+++ src/server/frontend/protobuf_session_creator.cpp 2014-01-21 15:42:35 +0000
333@@ -16,7 +16,7 @@
334 * Authored by: Alan Griffiths <alan@octopull.co.uk>
335 */
336
337-#include "protobuf_session_creator.h"
338+#include "mir/frontend/protobuf_session_creator.h"
339
340 #include "event_sender.h"
341 #include "protobuf_message_processor.h"
342@@ -67,7 +67,7 @@
343 ipc_factory->resource_cache());
344
345 auto const event_sink = std::make_shared<detail::EventSender>(messenger);
346- auto const msg_processor = std::make_shared<detail::ProtobufMessageProcessor>(
347+ auto const msg_processor = create_processor(
348 message_sender,
349 ipc_factory->make_ipc_server(event_sink, authorized_to_resize_display),
350 report);
351@@ -77,3 +77,15 @@
352 session->read_next_message();
353 }
354 }
355+
356+std::shared_ptr<mfd::MessageProcessor>
357+mf::ProtobufSessionCreator::create_processor(
358+ std::shared_ptr<mfd::ProtobufMessageSender> const& sender,
359+ std::shared_ptr<protobuf::DisplayServer> const& display_server,
360+ std::shared_ptr<mf::MessageProcessorReport> const& report) const
361+{
362+ return std::make_shared<detail::ProtobufMessageProcessor>(
363+ sender,
364+ display_server,
365+ report);
366+}
367
368=== modified file 'src/server/frontend/published_socket_connector.cpp'
369--- src/server/frontend/published_socket_connector.cpp 2014-01-13 06:12:33 +0000
370+++ src/server/frontend/published_socket_connector.cpp 2014-01-21 15:42:35 +0000
371@@ -17,7 +17,7 @@
372 */
373
374 #include "published_socket_connector.h"
375-#include "protobuf_session_creator.h"
376+#include "mir/frontend/protobuf_session_creator.h"
377
378 #include "mir/frontend/connector_report.h"
379
380
381=== modified file 'src/server/frontend/socket_session.cpp'
382--- src/server/frontend/socket_session.cpp 2014-01-20 07:11:48 +0000
383+++ src/server/frontend/socket_session.cpp 2014-01-21 15:42:35 +0000
384@@ -21,6 +21,8 @@
385 #include "message_receiver.h"
386 #include "mir/frontend/message_processor.h"
387
388+#include "mir_protobuf_wire.pb.h"
389+
390 #include <boost/signals2.hpp>
391 #include <boost/throw_exception.hpp>
392
393@@ -85,8 +87,13 @@
394 }
395
396 std::istream msg(&message);
397-
398- if (processor->process_message(msg))
399+ mir::protobuf::wire::Invocation invocation;
400+ invocation.ParseFromIstream(&msg);
401+
402+ if (!invocation.has_protocol_version() || invocation.protocol_version() != 1)
403+ BOOST_THROW_EXCEPTION(std::runtime_error("Unsupported protocol version"));
404+
405+ if (processor->dispatch(invocation))
406 {
407 read_next_message();
408 }
409
410=== modified file 'src/server/frontend/socket_session.h'
411--- src/server/frontend/socket_session.h 2014-01-16 14:39:11 +0000
412+++ src/server/frontend/socket_session.h 2014-01-21 15:42:35 +0000
413@@ -20,7 +20,7 @@
414 #ifndef MIR_FRONTEND_DETAIL_SOCKET_SESSION_H_
415 #define MIR_FRONTEND_DETAIL_SOCKET_SESSION_H_
416
417-#include "connected_sessions.h"
418+#include "mir/frontend/connected_sessions.h"
419
420 #include <boost/asio.hpp>
421
422
423=== removed file 'src/server/frontend/template_protobuf_message_processor.cpp'
424--- src/server/frontend/template_protobuf_message_processor.cpp 2014-01-16 14:39:11 +0000
425+++ src/server/frontend/template_protobuf_message_processor.cpp 1970-01-01 00:00:00 +0000
426@@ -1,44 +0,0 @@
427-/*
428- * Copyright © 2014 Canonical Ltd.
429- *
430- * This program is free software: you can redistribute it and/or modify it
431- * under the terms of the GNU General Public License version 3,
432- * as published by the Free Software Foundation.
433- *
434- * This program is distributed in the hope that it will be useful,
435- * but WITHOUT ANY WARRANTY; without even the implied warranty of
436- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
437- * GNU General Public License for more details.
438- *
439- * You should have received a copy of the GNU General Public License
440- * along with this program. If not, see <http://www.gnu.org/licenses/>.
441- *
442- * Authored by: Alan Griffiths <alan@octopull.co.uk>
443- */
444-
445-#include "mir/frontend/template_protobuf_message_processor.h"
446-#include "mir/frontend/protobuf_message_sender.h"
447-
448-namespace mfd = mir::frontend::detail;
449-
450-mfd::TemplateProtobufMessageProcessor::TemplateProtobufMessageProcessor(
451- std::shared_ptr<ProtobufMessageSender> const& sender) :
452- sender(sender)
453-{
454-}
455-
456-bool mfd::TemplateProtobufMessageProcessor::process_message(std::istream& msg)
457-{
458- mir::protobuf::wire::Invocation invocation;
459- invocation.ParseFromIstream(&msg);
460-
461- if (invocation.has_protocol_version() && invocation.protocol_version() != 1)
462- BOOST_THROW_EXCEPTION(std::runtime_error("Unsupported protocol version"));
463-
464- return dispatch(invocation);
465-}
466-
467-void mfd::TemplateProtobufMessageProcessor::send_response(::google::protobuf::uint32 id, ::google::protobuf::Message* response)
468-{
469- sender->send_response(id, response, {});
470-}
471
472=== modified file 'src/shared/protobuf/mir_protobuf_wire.proto'
473--- src/shared/protobuf/mir_protobuf_wire.proto 2013-08-29 03:48:16 +0000
474+++ src/shared/protobuf/mir_protobuf_wire.proto 2014-01-21 15:42:35 +0000
475@@ -4,7 +4,7 @@
476 required uint32 id = 1;
477 required string method_name = 2;
478 required bytes parameters = 3;
479- optional uint32 protocol_version = 4;
480+ required uint32 protocol_version = 4;
481 }
482
483 message Result {
484
485=== modified file 'tests/acceptance-tests/test_protobuf.cpp'
486--- tests/acceptance-tests/test_protobuf.cpp 2014-01-10 17:34:40 +0000
487+++ tests/acceptance-tests/test_protobuf.cpp 2014-01-21 15:42:35 +0000
488@@ -20,29 +20,169 @@
489
490 #include "mir_toolkit/mir_client_library.h"
491 #include "mir/client/private.h"
492+#include "mir/frontend/protobuf_message_sender.h"
493+#include "mir/frontend/protobuf_session_creator.h"
494+#include "mir/frontend/template_protobuf_message_processor.h"
495
496 #include "mir_test_framework/stubbed_server_configuration.h"
497 #include "mir_test_framework/in_process_server.h"
498
499 #include <gtest/gtest.h>
500+#include <gmock/gmock.h>
501
502 #include <atomic>
503
504+namespace mf = mir::frontend;
505+namespace mfd = mir::frontend::detail;
506+
507+/*************************************************************************/
508+/*************************************************************************/
509+/* Note that the functionality demonstrated here relies on "detail" and */
510+/* is not guaranteed to be supported in future. */
511+/*************************************************************************/
512+/*************************************************************************/
513 namespace
514 {
515-class DemoPrivateProtobuf : public mir_test_framework::InProcessServer
516-{
517- mir::DefaultServerConfiguration& server_config() override { return server_config_; }
518-
519- mir_test_framework::StubbedServerConfiguration server_config_;
520+struct DemoMirServer : mir::protobuf::MirServer
521+{
522+ MOCK_CONST_METHOD1(on_call, std::string(std::string));
523+
524+ DemoMirServer()
525+ {
526+ using namespace testing;
527+ ON_CALL(*this, on_call(_)).WillByDefault(Return("ok"));
528+ }
529+
530+ void function(
531+ ::google::protobuf::RpcController* ,
532+ ::mir::protobuf::Parameters const* parameters,
533+ ::mir::protobuf::Result* response,
534+ ::google::protobuf::Closure* done)
535+ {
536+ response->set_value(on_call(parameters->name()));
537+ done->Run();
538+ }
539+};
540+
541+// using a global for easy access from tests and DemoMessageProcessor::dispatch()
542+DemoMirServer* demo_mir_server;
543+
544+struct DemoMessageProcessor : mfd::MessageProcessor
545+{
546+ DemoMessageProcessor(
547+ std::shared_ptr<mfd::ProtobufMessageSender> const& sender,
548+ std::shared_ptr<mfd::MessageProcessor> const& wrapped) :
549+ sender(sender),
550+ wrapped(wrapped) {}
551+
552+ bool dispatch(mir::protobuf::wire::Invocation const& invocation)
553+ {
554+ if ("function" == invocation.method_name())
555+ {
556+ mfd::invoke(
557+ this,
558+ demo_mir_server,
559+ &DemoMirServer::function,
560+ invocation);
561+ return true;
562+ }
563+
564+ return wrapped->dispatch(invocation);
565+ }
566+
567+ void send_response(::google::protobuf::uint32 id, ::google::protobuf::Message* response)
568+ {
569+ sender->send_response(id, response, {});
570+ }
571+
572+ std::shared_ptr<mfd::ProtobufMessageSender> const sender;
573+ std::shared_ptr<mfd::MessageProcessor> const wrapped;
574+};
575+
576+struct DemoSessionCreator : mf::ProtobufSessionCreator
577+{
578+ using ProtobufSessionCreator::ProtobufSessionCreator;
579+
580+ MOCK_CONST_METHOD3(create_processor,
581+ std::shared_ptr<mfd::MessageProcessor>(
582+ std::shared_ptr<mfd::ProtobufMessageSender> const& sender,
583+ std::shared_ptr<mir::protobuf::DisplayServer> const& display_server,
584+ std::shared_ptr<mf::MessageProcessorReport> const& report));
585+
586+ std::shared_ptr<mfd::MessageProcessor> create_wrapped_processor(
587+ std::shared_ptr<mfd::ProtobufMessageSender> const& sender,
588+ std::shared_ptr<mir::protobuf::DisplayServer> const& display_server,
589+ std::shared_ptr<mf::MessageProcessorReport> const& report) const
590+ {
591+ auto const wrapped = mf::ProtobufSessionCreator::create_processor(
592+ sender,
593+ display_server,
594+ report);
595+
596+ return std::make_shared<DemoMessageProcessor>(sender, wrapped);
597+ }
598+
599+ std::shared_ptr<mfd::MessageProcessor> create_unwrapped_processor(
600+ std::shared_ptr<mfd::ProtobufMessageSender> const& sender,
601+ std::shared_ptr<mir::protobuf::DisplayServer> const& display_server,
602+ std::shared_ptr<mf::MessageProcessorReport> const& report) const
603+ {
604+ return mf::ProtobufSessionCreator::create_processor(
605+ sender,
606+ display_server,
607+ report);
608+ }
609+};
610+
611+struct DemoServerConfiguration : mir_test_framework::StubbedServerConfiguration
612+{
613+ std::shared_ptr<mf::SessionCreator> the_session_creator() override
614+ {
615+ return session_creator([this]
616+ {
617+ return std::make_shared<DemoSessionCreator>(
618+ the_ipc_factory(the_frontend_shell(), the_buffer_allocator()),
619+ the_session_authorizer(),
620+ the_message_processor_report());
621+ });
622+ }
623+
624+};
625+
626+struct DemoPrivateProtobuf : mir_test_framework::InProcessServer
627+{
628+ mir::DefaultServerConfiguration& server_config() override { return my_server_config; }
629+
630+ DemoServerConfiguration my_server_config;
631+
632+ std::shared_ptr<DemoSessionCreator> demo_session_creator;
633+
634+ void SetUp()
635+ {
636+ ::demo_mir_server = &demo_mir_server;
637+
638+ mir_test_framework::InProcessServer::SetUp();
639+ demo_session_creator = std::dynamic_pointer_cast<DemoSessionCreator>(my_server_config.the_session_creator());
640+
641+ using namespace testing;
642+ ASSERT_THAT(demo_session_creator, NotNull());
643+
644+ ON_CALL(*demo_session_creator, create_processor(_, _, _))
645+ .WillByDefault(Invoke(demo_session_creator.get(), &DemoSessionCreator::create_unwrapped_processor));
646+ }
647+
648+ testing::NiceMock<DemoMirServer> demo_mir_server;
649 };
650
651 void callback(std::atomic<bool>* called_back) { called_back->store(true); }
652 char const* const nothing_returned = "Nothing returned";
653 }
654
655-TEST_F(DemoPrivateProtobuf, client_can_call_server)
656+TEST_F(DemoPrivateProtobuf, client_calls_server)
657 {
658+ using namespace testing;
659+ EXPECT_CALL(*demo_session_creator, create_processor(_, _, _));
660+
661 auto const connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
662 ASSERT_TRUE(mir_connection_is_valid(connection));
663
664@@ -72,5 +212,74 @@
665 mir_connection_release(connection);
666
667 EXPECT_TRUE(called_back);
668- EXPECT_EQ(nothing_returned, result.error());
669+ EXPECT_THAT(result.error(), Eq(nothing_returned));
670+}
671+
672+TEST_F(DemoPrivateProtobuf, wrapping_message_processor)
673+{
674+ using namespace testing;
675+ EXPECT_CALL(*demo_session_creator, create_processor(_, _, _))
676+ .Times(1)
677+ .WillOnce(Invoke(demo_session_creator.get(), &DemoSessionCreator::create_wrapped_processor));
678+
679+ auto const connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
680+
681+ mir_connection_release(connection);
682+}
683+
684+TEST_F(DemoPrivateProtobuf, server_receives_function_call)
685+{
686+ using namespace testing;
687+ EXPECT_CALL(*demo_session_creator, create_processor(_, _, _))
688+ .WillRepeatedly(Invoke(demo_session_creator.get(), &DemoSessionCreator::create_wrapped_processor));
689+
690+ auto const connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
691+ ASSERT_TRUE(mir_connection_is_valid(connection));
692+
693+ auto const rpc_channel = mir::client::the_rpc_channel(connection);
694+
695+ using namespace mir::protobuf;
696+ using namespace google::protobuf;
697+
698+ MirServer::Stub server(rpc_channel.get());
699+
700+ Parameters parameters;
701+ Result result;
702+ parameters.set_name(__PRETTY_FUNCTION__);
703+
704+ EXPECT_CALL(demo_mir_server, on_call(__PRETTY_FUNCTION__)).Times(1);
705+
706+ server.function(nullptr, &parameters, &result, NewCallback([]{}));
707+
708+ mir_connection_release(connection);
709+}
710+
711+
712+TEST_F(DemoPrivateProtobuf, client_receives_result)
713+{
714+ using namespace testing;
715+ EXPECT_CALL(*demo_session_creator, create_processor(_, _, _))
716+ .WillRepeatedly(Invoke(demo_session_creator.get(), &DemoSessionCreator::create_wrapped_processor));
717+ EXPECT_CALL(demo_mir_server, on_call(_)).WillRepeatedly(Return(__PRETTY_FUNCTION__));
718+
719+ auto const connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
720+ ASSERT_TRUE(mir_connection_is_valid(connection));
721+
722+ auto const rpc_channel = mir::client::the_rpc_channel(connection);
723+
724+ using namespace mir::protobuf;
725+ using namespace google::protobuf;
726+
727+ MirServer::Stub server(rpc_channel.get());
728+
729+ Parameters parameters;
730+ Result result;
731+ parameters.set_name(__PRETTY_FUNCTION__);
732+
733+ server.function(nullptr, &parameters, &result, NewCallback([]{}));
734+
735+ mir_connection_release(connection);
736+
737+ EXPECT_THAT(result.has_error(), Eq(false));
738+ EXPECT_THAT(result.value(), Eq(__PRETTY_FUNCTION__));
739 }
740
741=== modified file 'tests/acceptance-tests/test_protobuf.proto'
742--- tests/acceptance-tests/test_protobuf.proto 2014-01-10 16:51:32 +0000
743+++ tests/acceptance-tests/test_protobuf.proto 2014-01-21 15:42:35 +0000
744@@ -9,6 +9,7 @@
745
746 message Result {
747 optional string error = 127;
748+ optional string value = 1;
749 }
750
751 service MirServer {
752
753=== modified file 'tests/mir_test_doubles/test_protobuf_socket_server.cpp'
754--- tests/mir_test_doubles/test_protobuf_socket_server.cpp 2014-01-15 12:26:01 +0000
755+++ tests/mir_test_doubles/test_protobuf_socket_server.cpp 2014-01-21 15:42:35 +0000
756@@ -21,8 +21,8 @@
757 #include "mir_test_doubles/stub_session_authorizer.h"
758 #include "mir/frontend/connector_report.h"
759 #include "mir/frontend/null_message_processor_report.h"
760+#include "mir/frontend/protobuf_session_creator.h"
761 #include "src/server/frontend/published_socket_connector.h"
762-#include "src/server/frontend/protobuf_session_creator.h"
763
764 namespace mt = mir::test;
765 namespace mtd = mir::test::doubles;
766
767=== modified file 'tests/unit-tests/frontend/test_published_socket_connector.cpp'
768--- tests/unit-tests/frontend/test_published_socket_connector.cpp 2014-01-20 07:11:48 +0000
769+++ tests/unit-tests/frontend/test_published_socket_connector.cpp 2014-01-21 15:42:35 +0000
770@@ -20,9 +20,9 @@
771 #include "mir/frontend/connector.h"
772 #include "mir/frontend/connector_report.h"
773 #include "mir/frontend/null_message_processor_report.h"
774+#include "mir/frontend/protobuf_session_creator.h"
775 #include "src/server/frontend/resource_cache.h"
776 #include "src/server/frontend/published_socket_connector.h"
777-#include "src/server/frontend/protobuf_session_creator.h"
778
779 #include "mir_protobuf.pb.h"
780
781
782=== modified file 'tests/unit-tests/frontend/test_socket_session.cpp'
783--- tests/unit-tests/frontend/test_socket_session.cpp 2014-01-20 07:11:48 +0000
784+++ tests/unit-tests/frontend/test_socket_session.cpp 2014-01-21 15:42:35 +0000
785@@ -1,5 +1,5 @@
786 /*
787- * Copyright © 2013 Canonical Ltd.
788+ * Copyright © 2013, 2014 Canonical Ltd.
789 *
790 * This program is free software: you can redistribute it and/or modify
791 * it under the terms of the GNU General Public License version 3 as
792@@ -14,6 +14,7 @@
793 * along with this program. If not, see <http://www.gnu.org/licenses/>.
794 *
795 * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
796+ * Alan Griffiths <alan@octopull.co.uk>
797 */
798
799 #include "src/server/frontend/socket_session.h"
800@@ -22,6 +23,8 @@
801
802 #include "mir_test/fake_shared.h"
803
804+#include "mir_protobuf_wire.pb.h"
805+
806 #include <gmock/gmock.h>
807 #include <gtest/gtest.h>
808
809@@ -31,55 +34,76 @@
810
811 namespace
812 {
813-struct MockReceiver : public mfd::MessageReceiver
814+struct StubReceiver : public mfd::MessageReceiver
815 {
816- MOCK_METHOD3(async_receive_msg, void(std::function<void(boost::system::error_code const&, size_t)> const&,
817- boost::asio::streambuf&, size_t));
818+ void async_receive_msg(
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;
826+ }
827+
828+ void fake_receive_msg(char* buffer, size_t size)
829+ {
830+ using namespace testing;
831+ ASSERT_NE(nullptr, callback_function);
832+ ASSERT_THAT(pstream, NotNull());
833+ ASSERT_THAT(read_size, Eq(size));
834+
835+ pstream->sputn(buffer, size);
836+ pstream->commit(size);
837+
838+ boost::system::error_code code;
839+ callback_function(code, size);
840+ }
841+
842+private:
843+ std::function<void(boost::system::error_code const&, size_t)> callback_function;
844+ boost::asio::streambuf* pstream = nullptr;
845+ size_t read_size = 0;
846+
847 MOCK_METHOD0(client_pid, pid_t());
848 };
849
850 struct MockProcessor : public mfd::MessageProcessor
851 {
852- MOCK_METHOD1(process_message, bool(std::istream&));
853+ MOCK_METHOD1(dispatch, bool(mir::protobuf::wire::Invocation const& invocation));
854 };
855 }
856 struct SocketSessionTest : public ::testing::Test
857 {
858 testing::NiceMock<MockProcessor> mock_processor;
859- testing::NiceMock<MockReceiver> mock_receiver;
860+ StubReceiver stub_receiver;
861 };
862
863-TEST_F(SocketSessionTest, basic_msg)
864+TEST_F(SocketSessionTest, basic_msg_is_received_and_dispatched)
865 {
866+ int const header_size = 2;
867+ char buffer[512];
868+ mir::protobuf::wire::Invocation invocation;
869+ invocation.set_id(1);
870+ invocation.set_method_name("");
871+ invocation.set_parameters(buffer, 0);
872+ invocation.set_protocol_version(1);
873+ auto const body_size = invocation.ByteSize();
874+
875 using namespace testing;
876
877 std::shared_ptr<mfd::ConnectedSessions<mfd::SocketSession>> null_sessions;
878- std::function<void(boost::system::error_code const&, size_t)> header_read, body_read;
879-
880- size_t header_size = 2;
881- EXPECT_CALL(mock_receiver, async_receive_msg(_,_, header_size))
882- .Times(1)
883- .WillOnce(SaveArg<0>(&header_read));
884-
885- mfd::SocketSession session(mt::fake_shared(mock_receiver), 0, null_sessions, mt::fake_shared(mock_processor));
886-
887- //trigger wait for header
888+
889+ mfd::SocketSession session(mt::fake_shared(stub_receiver), 0, null_sessions, mt::fake_shared(mock_processor));
890+
891+ EXPECT_CALL(mock_processor, dispatch(_)).Times(1).WillOnce(Return(true));
892+
893 session.read_next_message();
894- testing::Mock::VerifyAndClearExpectations(&mock_receiver);
895-
896- //trigger body read
897- EXPECT_CALL(mock_receiver, async_receive_msg(_,_,_))
898- .Times(1)
899- .WillOnce(SaveArg<0>(&body_read));
900-
901- boost::system::error_code code;
902- header_read(code, 2);
903-
904- testing::Mock::VerifyAndClearExpectations(&mock_receiver);
905-
906- //trigger message process
907- EXPECT_CALL(mock_processor, process_message(_))
908- .Times(1)
909- .WillOnce(Return(true));
910- body_read(code, 9);
911+
912+ buffer[0] = body_size / 0x100;
913+ buffer[1] = body_size % 0x100;
914+ stub_receiver.fake_receive_msg(buffer, header_size);
915+
916+ invocation.SerializeToArray(buffer, sizeof buffer);
917+ stub_receiver.fake_receive_msg(buffer, body_size);
918 }

Subscribers

People subscribed via source and target branches