Merge lp:~alan-griffiths/mir/fix-1188451 into lp:~mir-team/mir/trunk
- fix-1188451
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Daniel van Vugt | ||||
Approved revision: | no longer in the source branch. | ||||
Merged at revision: | 764 | ||||
Proposed branch: | lp:~alan-griffiths/mir/fix-1188451 | ||||
Merge into: | lp:~mir-team/mir/trunk | ||||
Diff against target: |
547 lines (+237/-43) 14 files modified
include/server/mir/frontend/communicator_report.h (+51/-0) include/server/mir/frontend/session_mediator.h (+2/-0) include/test/mir_test/test_protobuf_server.h (+20/-12) src/server/frontend/make_protobuf_socket_communicator.cpp (+3/-1) src/server/frontend/protobuf_socket_communicator.cpp (+22/-3) src/server/frontend/protobuf_socket_communicator.h (+5/-1) src/server/frontend/session_mediator.cpp (+9/-0) src/server/frontend/socket_session.cpp (+28/-10) src/server/frontend/socket_session.h (+3/-5) tests/integration-tests/client/test_client_render.cpp (+2/-0) tests/mir_test_doubles/test_protobuf_socket_server.cpp (+24/-5) tests/unit-tests/client/test_client_mir_surface.cpp (+1/-0) tests/unit-tests/frontend/test_protobuf_communicator.cpp (+66/-6) tests/unit-tests/frontend/test_protobuf_reports_errors.cpp (+1/-0) |
||||
To merge this branch: | bzr merge lp:~alan-griffiths/mir/fix-1188451 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Daniel van Vugt | Approve | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
Alan Griffiths | Abstain | ||
Alexandros Frantzis (community) | Approve | ||
Review via email: mp+169786@code.launchpad.net |
Commit message
frontend: detect and drop dead client sessions
Description of the change
frontend: detect and drop dead client sessions
PS Jenkins bot (ps-jenkins) wrote : | # |
Daniel van Vugt (vanvugt) wrote : | # |
Regression: The Mir server now wakes up 10 times per second, even when all clients are idle. That's bad. The reason is:
32 + io_service.post([&]
33 + {
34 + do
35 + {
36 + std::this_
37 + connected_
38 + }
39 + while (!io_service.
40 + });
That has to be re-thought because polling is not an option.
An example of a well-behaved almost-idling client to test is mir_demo_
Daniel van Vugt (vanvugt) wrote : | # |
If we really do need to poll, then just make sure it's not on a timer or in a loop.
Try piggy-backing the polling on some other event, like "the screen is redrawing (for some other clients) but I haven't got any communication from this client for a while".
Alan Griffiths (alan-griffiths) wrote : | # |
On 18/06/13 04:33, Daniel van Vugt wrote:
> Regression: The Mir server now wakes up 10 times per second, even when all clients are idle. That's bad.
Agreed. Unfortunately I've not come up with anything better than polling
yet (but we could tie it to another event that wakes the server).
--
Alan Griffiths +44 (0)798 9938 758
Octopull Ltd http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:755
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Alexandros Frantzis (afrantzis) wrote : | # |
Looks good. It would nice to have a test for this.
Alan Griffiths (alan-griffiths) wrote : | # |
> Looks good. It would nice to have a test for this.
Yes, I'm thinking of rolling that with the "TODO need a way to report errors" resolution.
Happy to to that here or on another MP (depending upon much folks want the bug fix landed).
Alan Griffiths (alan-griffiths) wrote : | # |
It always happens at EOD! This no longer seems to be working. (Will try again in the morning.)
Daniel van Vugt (vanvugt) wrote : | # |
Sorry to say it doesn't work.
Following the test case in bug 1188451, I still get moveable leaked surfaces on the screen after a client dies. And even when I start a new client the dead clients' surface remains there, frozen and moveable.
Alan Griffiths (alan-griffiths) wrote : | # |
Having found the problem I can't see how it ever did anything that made me think it worked. (Wishes for a video of earlier testing session.)
Please try r759.
Daniel van Vugt (vanvugt) wrote : | # |
Since Eleni's extra error checking has landed...
/home/dan/
In file included from /home/dan/
/home/dan/
Alan Griffiths (alan-griffiths) wrote : | # |
> Since Eleni's extra error checking has landed...
>
> /home/dan/
> error: declaration of ‘virtual
> mir::frontend:
> specifier
> In file included from
> /home/dan/
> /home/dan/
> : error: from previous declaration ‘virtual
> mir::frontend:
Weird, that's true (and fixed), but I didn't get a diagnostic. (g++ (Ubuntu 4.8.1-3ubuntu2) 4.8.1)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:759
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
UNSTABLE: http://
Click here to trigger a rebuild:
http://
Daniel van Vugt (vanvugt) wrote : | # |
And again:
/home/dan/
In file included from /home/dan/
/home/dan/
Try merging in lp:mir to get the new error checking flag that just landed.
Alan Griffiths (alan-griffiths) wrote : | # |
> Try merging in lp:mir to get the new error checking flag that just landed.
That was merged in 758 (but that flag has nothing to do with this error).
What compiler are you using?
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:760
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
FAILURE: http://
UNSTABLE: http://
Click here to trigger a rebuild:
http://
Alan Griffiths (alan-griffiths) wrote : | # |
> > Try merging in lp:mir to get the new error checking flag that just landed.
>
> That was merged in 758 (but that flag has nothing to do with this error).
>
> What compiler are you using?
Nevermind, clang reports these
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:762
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
FAILURE: http://
UNSTABLE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:763
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:764
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
UNSTABLE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:765
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Daniel van Vugt (vanvugt) wrote : | # |
Verified the bug is fixed.
1. Needs fixing: Unused protocol changes:
src/shared/
2. Query: void mf::ProtobufSoc
I find the structure of this loop a bit confusing. Can it be simplified?
Alan Griffiths (alan-griffiths) wrote : | # |
> Verified the bug is fixed.
>
> 1. Needs fixing: Unused protocol changes:
> src/shared/
OK, that's an unrelated change.
> 2. Query: void mf::ProtobufSoc
> I find the structure of this loop a bit confusing. Can it be simplified?
Would using "break" in place of "return" help? (I don't feel that introducing a goto or a loop variable simplifies in this case.)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:767
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Daniel van Vugt (vanvugt) wrote : | # |
Approved based on reviewing the diff for r767. I'm assuming it still works well.
Preview Diff
1 | === added file 'include/server/mir/frontend/communicator_report.h' |
2 | --- include/server/mir/frontend/communicator_report.h 1970-01-01 00:00:00 +0000 |
3 | +++ include/server/mir/frontend/communicator_report.h 2013-06-21 08:43:41 +0000 |
4 | @@ -0,0 +1,51 @@ |
5 | +/* |
6 | + * Copyright © 2013 Canonical Ltd. |
7 | + * |
8 | + * This program is free software: you can redistribute it and/or modify it |
9 | + * under the terms of the GNU General Public License version 3, |
10 | + * as published by the Free Software Foundation. |
11 | + * |
12 | + * This program is distributed in the hope that it will be useful, |
13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | + * GNU General Public License for more details. |
16 | + * |
17 | + * You should have received a copy of the GNU General Public License |
18 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 | + * |
20 | + * Authored by: Alan Griffiths <alan@octopull.co.uk |
21 | + */ |
22 | + |
23 | +#ifndef MIR_FRONTEND_COMMUNICATOR_REPORT_H_ |
24 | +#define MIR_FRONTEND_COMMUNICATOR_REPORT_H_ |
25 | + |
26 | +#include <stdexcept> |
27 | + |
28 | +namespace mir |
29 | +{ |
30 | +namespace frontend |
31 | +{ |
32 | + |
33 | +class CommunicatorReport |
34 | +{ |
35 | +public: |
36 | + |
37 | + virtual void error(std::exception const& error) = 0; |
38 | + |
39 | +protected: |
40 | + virtual ~CommunicatorReport() = default; |
41 | + CommunicatorReport() = default; |
42 | + CommunicatorReport(const CommunicatorReport&) = delete; |
43 | + CommunicatorReport& operator=(const CommunicatorReport&) = delete; |
44 | +}; |
45 | + |
46 | +class NullCommunicatorReport : public CommunicatorReport |
47 | +{ |
48 | +public: |
49 | + |
50 | + void error(std::exception const& error); |
51 | +}; |
52 | +} |
53 | +} |
54 | + |
55 | +#endif // MIR_FRONTEND_COMMUNICATOR_REPORT_H_ |
56 | |
57 | === modified file 'include/server/mir/frontend/session_mediator.h' |
58 | --- include/server/mir/frontend/session_mediator.h 2013-05-30 03:50:54 +0000 |
59 | +++ include/server/mir/frontend/session_mediator.h 2013-06-21 08:43:41 +0000 |
60 | @@ -67,6 +67,8 @@ |
61 | std::shared_ptr<events::EventSink> const& event_sink, |
62 | std::shared_ptr<ResourceCache> const& resource_cache); |
63 | |
64 | + ~SessionMediator() noexcept; |
65 | + |
66 | /* Platform independent requests */ |
67 | void connect(::google::protobuf::RpcController* controller, |
68 | const ::mir::protobuf::ConnectParameters* request, |
69 | |
70 | === modified file 'include/test/mir_test/test_protobuf_server.h' |
71 | --- include/test/mir_test/test_protobuf_server.h 2013-04-24 05:22:20 +0000 |
72 | +++ include/test/mir_test/test_protobuf_server.h 2013-06-21 08:43:41 +0000 |
73 | @@ -19,29 +19,37 @@ |
74 | #ifndef MIR_TEST_TEST_PROTOBUF_SERVER_H_ |
75 | #define MIR_TEST_TEST_PROTOBUF_SERVER_H_ |
76 | |
77 | -#include "mir_test/stub_server_tool.h" |
78 | -#include "mir_test_doubles/stub_ipc_factory.h" |
79 | -#include "mir/frontend/communicator.h" |
80 | +#include <memory> |
81 | |
82 | namespace mir |
83 | { |
84 | +namespace frontend |
85 | +{ |
86 | +class Communicator; |
87 | +class CommunicatorReport; |
88 | +} |
89 | + |
90 | +namespace protobuf |
91 | +{ |
92 | +class DisplayServer; |
93 | +} |
94 | + |
95 | namespace test |
96 | { |
97 | - |
98 | struct TestProtobufServer |
99 | { |
100 | - TestProtobufServer(std::string socket_name, |
101 | - const std::shared_ptr<protobuf::DisplayServer>& tool); |
102 | + TestProtobufServer( |
103 | + std::string const& socket_name, |
104 | + std::shared_ptr<protobuf::DisplayServer> const& tool); |
105 | |
106 | - std::shared_ptr<frontend::Communicator> make_communicator( |
107 | - const std::string& socket_name, |
108 | - std::shared_ptr<frontend::ProtobufIpcFactory> const& factory); |
109 | + TestProtobufServer( |
110 | + std::string const& socket_name, |
111 | + std::shared_ptr<protobuf::DisplayServer> const& tool, |
112 | + std::shared_ptr<frontend::CommunicatorReport> const& report); |
113 | |
114 | // "Server" side |
115 | - std::shared_ptr<doubles::StubIpcFactory> factory; |
116 | - std::shared_ptr<frontend::Communicator> comm; |
117 | + std::shared_ptr<frontend::Communicator> const comm; |
118 | }; |
119 | - |
120 | } |
121 | } |
122 | #endif /* MIR_TEST_TEST_PROTOBUF_SERVER_H_ */ |
123 | |
124 | === modified file 'src/server/frontend/make_protobuf_socket_communicator.cpp' |
125 | --- src/server/frontend/make_protobuf_socket_communicator.cpp 2013-04-25 09:48:54 +0000 |
126 | +++ src/server/frontend/make_protobuf_socket_communicator.cpp 2013-06-21 08:43:41 +0000 |
127 | @@ -22,6 +22,7 @@ |
128 | #include "mir/shell/session_container.h" |
129 | #include "mir/shell/session.h" |
130 | #include "protobuf_socket_communicator.h" |
131 | +#include "mir/frontend/communicator_report.h" |
132 | |
133 | namespace mf = mir::frontend; |
134 | namespace mg = mir::graphics; |
135 | @@ -46,7 +47,8 @@ |
136 | { |
137 | session->force_requests_to_complete(); |
138 | }); |
139 | - }); |
140 | + }, |
141 | + std::make_shared<mf::NullCommunicatorReport>()); |
142 | }); |
143 | } |
144 | |
145 | |
146 | === modified file 'src/server/frontend/protobuf_socket_communicator.cpp' |
147 | --- src/server/frontend/protobuf_socket_communicator.cpp 2013-04-25 09:48:54 +0000 |
148 | +++ src/server/frontend/protobuf_socket_communicator.cpp 2013-06-21 08:43:41 +0000 |
149 | @@ -20,6 +20,7 @@ |
150 | #include "protobuf_message_processor.h" |
151 | #include "socket_session.h" |
152 | |
153 | +#include "mir/frontend/communicator_report.h" |
154 | #include "mir/frontend/protobuf_ipc_factory.h" |
155 | #include "mir/protobuf/google_protobuf_guard.h" |
156 | #include "event_pipe.h" |
157 | @@ -36,14 +37,16 @@ |
158 | std::string const& socket_file, |
159 | std::shared_ptr<ProtobufIpcFactory> const& ipc_factory, |
160 | int threads, |
161 | - std::function<void()> const& force_requests_to_complete) |
162 | + std::function<void()> const& force_requests_to_complete, |
163 | + std::shared_ptr<CommunicatorReport> const& report) |
164 | : socket_file((std::remove(socket_file.c_str()), socket_file)), |
165 | acceptor(io_service, socket_file), |
166 | io_service_threads(threads), |
167 | ipc_factory(ipc_factory), |
168 | next_session_id(0), |
169 | connected_sessions(std::make_shared<mfd::ConnectedSessions<mfd::SocketSession>>()), |
170 | - force_requests_to_complete(force_requests_to_complete) |
171 | + force_requests_to_complete(force_requests_to_complete), |
172 | + report(report) |
173 | { |
174 | start_accept(); |
175 | } |
176 | @@ -85,7 +88,19 @@ |
177 | |
178 | void mf::ProtobufSocketCommunicator::start() |
179 | { |
180 | - auto run_io_service = boost::bind(&ba::io_service::run, &io_service); |
181 | + auto run_io_service = [&] |
182 | + { |
183 | + while (true) |
184 | + try |
185 | + { |
186 | + io_service.run(); |
187 | + return; |
188 | + } |
189 | + catch (std::exception const& e) |
190 | + { |
191 | + report->error(e); |
192 | + } |
193 | + }; |
194 | |
195 | for (auto& thread : io_service_threads) |
196 | { |
197 | @@ -138,3 +153,7 @@ |
198 | } |
199 | start_accept(); |
200 | } |
201 | + |
202 | +void mf::NullCommunicatorReport::error(std::exception const& /*error*/) |
203 | +{ |
204 | +} |
205 | |
206 | === modified file 'src/server/frontend/protobuf_socket_communicator.h' |
207 | --- src/server/frontend/protobuf_socket_communicator.h 2013-04-25 09:48:54 +0000 |
208 | +++ src/server/frontend/protobuf_socket_communicator.h 2013-06-21 08:43:41 +0000 |
209 | @@ -52,6 +52,8 @@ |
210 | struct SocketSession; |
211 | } |
212 | |
213 | +class CommunicatorReport; |
214 | + |
215 | class ProtobufSocketCommunicator : public Communicator |
216 | { |
217 | public: |
218 | @@ -61,7 +63,8 @@ |
219 | const std::string& socket_file, |
220 | std::shared_ptr<ProtobufIpcFactory> const& ipc_factory, |
221 | int threads, |
222 | - std::function<void()> const& force_requests_to_complete); |
223 | + std::function<void()> const& force_requests_to_complete, |
224 | + std::shared_ptr<CommunicatorReport> const& report); |
225 | ~ProtobufSocketCommunicator(); |
226 | void start(); |
227 | void stop(); |
228 | @@ -79,6 +82,7 @@ |
229 | std::atomic<int> next_session_id; |
230 | std::shared_ptr<detail::ConnectedSessions<detail::SocketSession>> const connected_sessions; |
231 | std::function<void()> const force_requests_to_complete; |
232 | + std::shared_ptr<CommunicatorReport> const report; |
233 | }; |
234 | |
235 | } |
236 | |
237 | === modified file 'src/server/frontend/session_mediator.cpp' |
238 | --- src/server/frontend/session_mediator.cpp 2013-06-12 15:36:31 +0000 |
239 | +++ src/server/frontend/session_mediator.cpp 2013-06-21 08:43:41 +0000 |
240 | @@ -61,6 +61,15 @@ |
241 | { |
242 | } |
243 | |
244 | +mf::SessionMediator::~SessionMediator() noexcept |
245 | +{ |
246 | + if (session) |
247 | + { |
248 | + report->session_error(session->name(), __PRETTY_FUNCTION__, "connection dropped without disconnect"); |
249 | + shell->close_session(session); |
250 | + } |
251 | +} |
252 | + |
253 | void mf::SessionMediator::connect( |
254 | ::google::protobuf::RpcController*, |
255 | const ::mir::protobuf::ConnectParameters* request, |
256 | |
257 | === modified file 'src/server/frontend/socket_session.cpp' |
258 | --- src/server/frontend/socket_session.cpp 2013-05-27 09:39:39 +0000 |
259 | +++ src/server/frontend/socket_session.cpp 2013-06-21 08:43:41 +0000 |
260 | @@ -27,6 +27,21 @@ |
261 | |
262 | namespace mfd = mir::frontend::detail; |
263 | |
264 | +mfd::SocketSession::SocketSession( |
265 | + boost::asio::io_service& io_service, |
266 | + int id_, |
267 | + std::shared_ptr<ConnectedSessions<SocketSession>> const& connected_sessions) : |
268 | + socket(io_service), |
269 | + id_(id_), |
270 | + connected_sessions(connected_sessions), |
271 | + processor(std::make_shared<NullMessageProcessor>()) |
272 | +{ |
273 | +} |
274 | + |
275 | +mfd::SocketSession::~SocketSession() noexcept |
276 | +{ |
277 | +} |
278 | + |
279 | void mfd::SocketSession::send(std::string const& body) |
280 | { |
281 | const size_t size = body.size(); |
282 | @@ -62,19 +77,22 @@ |
283 | this, ba::placeholders::error)); |
284 | } |
285 | |
286 | -void mfd::SocketSession::on_read_size(const boost::system::error_code& ec) |
287 | +void mfd::SocketSession::on_read_size(const boost::system::error_code& error) |
288 | { |
289 | - if (!ec) |
290 | + if (error) |
291 | { |
292 | - size_t const body_size = (message_header_bytes[0] << 8) + message_header_bytes[1]; |
293 | - // Read newline delimited messages for now |
294 | - ba::async_read( |
295 | - socket, |
296 | - message, |
297 | - ba::transfer_exactly(body_size), |
298 | - boost::bind(&mfd::SocketSession::on_new_message, |
299 | - this, ba::placeholders::error)); |
300 | + connected_sessions->remove(id()); |
301 | + BOOST_THROW_EXCEPTION(std::runtime_error(error.message())); |
302 | } |
303 | + |
304 | + size_t const body_size = (message_header_bytes[0] << 8) + message_header_bytes[1]; |
305 | + // Read newline delimited messages for now |
306 | + ba::async_read( |
307 | + socket, |
308 | + message, |
309 | + ba::transfer_exactly(body_size), |
310 | + boost::bind(&mfd::SocketSession::on_new_message, |
311 | + this, ba::placeholders::error)); |
312 | } |
313 | |
314 | void mfd::SocketSession::on_new_message(const boost::system::error_code& error) |
315 | |
316 | === modified file 'src/server/frontend/socket_session.h' |
317 | --- src/server/frontend/socket_session.h 2013-05-27 09:39:39 +0000 |
318 | +++ src/server/frontend/socket_session.h 2013-06-21 08:43:41 +0000 |
319 | @@ -37,11 +37,9 @@ |
320 | SocketSession( |
321 | boost::asio::io_service& io_service, |
322 | int id_, |
323 | - std::shared_ptr<ConnectedSessions<SocketSession>> const& connected_sessions) : |
324 | - socket(io_service), |
325 | - id_(id_), |
326 | - connected_sessions(connected_sessions), |
327 | - processor(std::make_shared<NullMessageProcessor>()) {} |
328 | + std::shared_ptr<ConnectedSessions<SocketSession>> const& connected_sessions); |
329 | + |
330 | + ~SocketSession() noexcept; |
331 | |
332 | int id() const { return id_; } |
333 | |
334 | |
335 | === modified file 'tests/integration-tests/client/test_client_render.cpp' |
336 | --- tests/integration-tests/client/test_client_render.cpp 2013-06-06 08:36:17 +0000 |
337 | +++ tests/integration-tests/client/test_client_render.cpp 2013-06-21 08:43:41 +0000 |
338 | @@ -27,6 +27,8 @@ |
339 | #include "mir_test/stub_server_tool.h" |
340 | #include "mir_test/test_protobuf_server.h" |
341 | |
342 | +#include "mir/frontend/communicator.h" |
343 | + |
344 | #include <gmock/gmock.h> |
345 | #include <thread> |
346 | #include <hardware/gralloc.h> |
347 | |
348 | === modified file 'tests/mir_test_doubles/test_protobuf_socket_server.cpp' |
349 | --- tests/mir_test_doubles/test_protobuf_socket_server.cpp 2013-04-25 09:48:54 +0000 |
350 | +++ tests/mir_test_doubles/test_protobuf_socket_server.cpp 2013-06-21 08:43:41 +0000 |
351 | @@ -17,22 +17,41 @@ |
352 | */ |
353 | |
354 | #include "mir_test/test_protobuf_server.h" |
355 | +#include "mir_test_doubles/stub_ipc_factory.h" |
356 | +#include "mir/frontend/communicator_report.h" |
357 | #include "src/server/frontend/protobuf_socket_communicator.h" |
358 | |
359 | namespace mt = mir::test; |
360 | namespace mtd = mir::test::doubles; |
361 | namespace mf = mir::frontend; |
362 | |
363 | +namespace |
364 | +{ |
365 | +std::shared_ptr<mf::Communicator> make_communicator( |
366 | + std::string const& socket_name, |
367 | + std::shared_ptr<mf::ProtobufIpcFactory> const& factory, |
368 | + std::shared_ptr<mf::CommunicatorReport> const& report) |
369 | +{ |
370 | + return std::make_shared<mf::ProtobufSocketCommunicator>( |
371 | + socket_name, |
372 | + factory, |
373 | + 10, |
374 | + []{}, |
375 | + report); |
376 | +} |
377 | +} |
378 | |
379 | mt::TestProtobufServer::TestProtobufServer( |
380 | - std::string socket_name, |
381 | + std::string const& socket_name, |
382 | const std::shared_ptr<protobuf::DisplayServer>& tool) : |
383 | - factory(std::make_shared<mtd::StubIpcFactory>(*tool)), |
384 | - comm(make_communicator(socket_name, factory)) |
385 | + TestProtobufServer(socket_name, tool, std::make_shared<mf::NullCommunicatorReport>()) |
386 | { |
387 | } |
388 | |
389 | -std::shared_ptr<mf::Communicator> mt::TestProtobufServer::make_communicator(const std::string& socket_name, std::shared_ptr<frontend::ProtobufIpcFactory> const& factory) |
390 | +mt::TestProtobufServer::TestProtobufServer( |
391 | + std::string const& socket_name, |
392 | + const std::shared_ptr<protobuf::DisplayServer>& tool, |
393 | + std::shared_ptr<frontend::CommunicatorReport> const& report) : |
394 | + comm(make_communicator(socket_name, std::make_shared<mtd::StubIpcFactory>(*tool), report)) |
395 | { |
396 | - return std::make_shared<mf::ProtobufSocketCommunicator>(socket_name, factory, 10, []{}); |
397 | } |
398 | |
399 | === modified file 'tests/unit-tests/client/test_client_mir_surface.cpp' |
400 | --- tests/unit-tests/client/test_client_mir_surface.cpp 2013-06-03 08:14:01 +0000 |
401 | +++ tests/unit-tests/client/test_client_mir_surface.cpp 2013-06-21 08:43:41 +0000 |
402 | @@ -30,6 +30,7 @@ |
403 | #include "src/client/rpc/mir_basic_rpc_channel.h" |
404 | |
405 | #include "mir/frontend/resource_cache.h" |
406 | +#include "mir/frontend/communicator.h" |
407 | #include "mir/input/input_platform.h" |
408 | #include "mir/input/input_receiver_thread.h" |
409 | |
410 | |
411 | === modified file 'tests/unit-tests/frontend/test_protobuf_communicator.cpp' |
412 | --- tests/unit-tests/frontend/test_protobuf_communicator.cpp 2013-05-30 03:50:54 +0000 |
413 | +++ tests/unit-tests/frontend/test_protobuf_communicator.cpp 2013-06-21 08:43:41 +0000 |
414 | @@ -18,6 +18,7 @@ |
415 | */ |
416 | |
417 | #include "mir/frontend/communicator.h" |
418 | +#include "mir/frontend/communicator_report.h" |
419 | #include "mir/frontend/resource_cache.h" |
420 | #include "src/server/frontend/protobuf_socket_communicator.h" |
421 | |
422 | @@ -41,24 +42,43 @@ |
423 | namespace mt = mir::test; |
424 | namespace mtd = mir::test::doubles; |
425 | |
426 | +namespace |
427 | +{ |
428 | +class MockCommunicatorReport : public mf::CommunicatorReport |
429 | +{ |
430 | +public: |
431 | + |
432 | + ~MockCommunicatorReport() noexcept {} |
433 | + |
434 | + MOCK_METHOD1(error, void (std::exception const& error)); |
435 | +}; |
436 | +} |
437 | + |
438 | struct ProtobufCommunicator : public ::testing::Test |
439 | { |
440 | static void SetUpTestCase() |
441 | { |
442 | + communicator_report = std::make_shared<MockCommunicatorReport>(); |
443 | stub_server_tool = std::make_shared<mt::StubServerTool>(); |
444 | - stub_server = std::make_shared<mt::TestProtobufServer>("./test_socket", stub_server_tool); |
445 | + stub_server = std::make_shared<mt::TestProtobufServer>( |
446 | + "./test_socket", |
447 | + stub_server_tool, |
448 | + communicator_report); |
449 | + } |
450 | |
451 | + void SetUp() |
452 | + { |
453 | + using namespace testing; |
454 | + EXPECT_CALL(*communicator_report, error(_)).Times(AnyNumber()); |
455 | stub_server->comm->start(); |
456 | - } |
457 | - |
458 | - void SetUp() |
459 | - { |
460 | client = std::make_shared<mt::TestProtobufClient>("./test_socket", 100); |
461 | client->connect_parameters.set_application_name(__PRETTY_FUNCTION__); |
462 | } |
463 | |
464 | void TearDown() |
465 | { |
466 | + stub_server->comm->stop(); |
467 | + testing::Mock::VerifyAndClearExpectations(communicator_report.get()); |
468 | client.reset(); |
469 | } |
470 | |
471 | @@ -66,15 +86,18 @@ |
472 | { |
473 | stub_server.reset(); |
474 | stub_server_tool.reset(); |
475 | + communicator_report.reset(); |
476 | } |
477 | |
478 | std::shared_ptr<mt::TestProtobufClient> client; |
479 | + static std::shared_ptr<MockCommunicatorReport> communicator_report; |
480 | static std::shared_ptr<mt::StubServerTool> stub_server_tool; |
481 | private: |
482 | static std::shared_ptr<mt::TestProtobufServer> stub_server; |
483 | }; |
484 | |
485 | std::shared_ptr<mt::StubServerTool> ProtobufCommunicator::stub_server_tool; |
486 | +std::shared_ptr<MockCommunicatorReport> ProtobufCommunicator::communicator_report; |
487 | std::shared_ptr<mt::TestProtobufServer> ProtobufCommunicator::stub_server; |
488 | |
489 | TEST_F(ProtobufCommunicator, create_surface_results_in_a_callback) |
490 | @@ -297,7 +320,44 @@ |
491 | auto comms = std::make_shared<mf::ProtobufSocketCommunicator>( |
492 | "./test_socket1", ipc_factory, 10, |
493 | std::bind(&MockForceRequests::force_requests_to_complete, |
494 | - &mock_force_requests)); |
495 | + &mock_force_requests), |
496 | + std::make_shared<mf::NullCommunicatorReport>()); |
497 | comms->start(); |
498 | comms->stop(); |
499 | } |
500 | + |
501 | +TEST_F(ProtobufCommunicator, |
502 | + disorderly_disconnection_handled) |
503 | +{ |
504 | + using namespace testing; |
505 | + |
506 | + EXPECT_CALL(*client, create_surface_done()).Times(AnyNumber()); |
507 | + client->display_server.create_surface( |
508 | + 0, |
509 | + &client->surface_parameters, |
510 | + &client->surface, |
511 | + google::protobuf::NewCallback(client.get(), &mt::TestProtobufClient::create_surface_done)); |
512 | + |
513 | + client->wait_for_create_surface(); |
514 | + |
515 | + std::mutex m; |
516 | + std::condition_variable cv; |
517 | + bool done = false; |
518 | + |
519 | + ON_CALL(*communicator_report, error(_)).WillByDefault(Invoke([&] (std::exception const&) |
520 | + { |
521 | + std::unique_lock<std::mutex> lock(m); |
522 | + |
523 | + done = true; |
524 | + cv.notify_all(); |
525 | + })); |
526 | + |
527 | + EXPECT_CALL(*communicator_report, error(_)).Times(1); |
528 | + |
529 | + client.reset(); |
530 | + |
531 | + std::unique_lock<std::mutex> lock(m); |
532 | + |
533 | + auto const deadline = std::chrono::system_clock::now() + std::chrono::seconds(1); |
534 | + while (!done && cv.wait_until(lock, deadline) != std::cv_status::timeout); |
535 | +} |
536 | |
537 | === modified file 'tests/unit-tests/frontend/test_protobuf_reports_errors.cpp' |
538 | --- tests/unit-tests/frontend/test_protobuf_reports_errors.cpp 2013-01-21 12:05:00 +0000 |
539 | +++ tests/unit-tests/frontend/test_protobuf_reports_errors.cpp 2013-06-21 08:43:41 +0000 |
540 | @@ -20,6 +20,7 @@ |
541 | #include "mir/frontend/communicator.h" |
542 | #include "mir/frontend/resource_cache.h" |
543 | |
544 | +#include "mir_test/stub_server_tool.h" |
545 | #include "mir_test/test_protobuf_server.h" |
546 | #include "mir_test_doubles/stub_ipc_factory.h" |
547 | #include "mir_test/test_protobuf_client.h" |
PASSED: Continuous integration, rev:752 jenkins. qa.ubuntu. com/job/ mir-ci/ 747/ jenkins. qa.ubuntu. com/job/ mir-android- raring- i386-build/ 932 jenkins. qa.ubuntu. com/job/ mir-clang- raring- amd64-build/ 814 jenkins. qa.ubuntu. com/job/ mir-raring- amd64-ci/ 232 jenkins. qa.ubuntu. com/job/ mir-raring- amd64-ci/ 232/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ mir-vm- ci-build/ ./distribution= quantal, flavor= amd64/432
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins: 8080/job/ mir-ci/ 747/rebuild
http://