Mir

Merge lp:~alan-griffiths/mir/fix-1236698 into lp:mir

Proposed by Alan Griffiths
Status: Merged
Approved by: Daniel van Vugt
Approved revision: no longer in the source branch.
Merged at revision: 1126
Proposed branch: lp:~alan-griffiths/mir/fix-1236698
Merge into: lp:mir
Diff against target: 128 lines (+44/-13)
2 files modified
src/client/mir_connection.cpp (+0/-1)
tests/unit-tests/frontend/test_published_socket_connector.cpp (+44/-12)
To merge this branch: bzr merge lp:~alan-griffiths/mir/fix-1236698
Reviewer Review Type Date Requested Status
Daniel van Vugt Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+190400@code.launchpad.net

Commit message

client, tests: deal correctly with a race condition during double
disconnection test (LP: #1236698)

Description of the change

client, tests: deal correctly with a race condition during double disconnection test

To post a comment you must log in.
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

Sorry, the SetUpTestCase, SetUp and TearDown changes are not essential to the fix (but are useful tidy-up).

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Seems to do the trick.

review: Approve
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

I'm going to rush this one through, because the spurious CI failures are holding up other MPs.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/client/mir_connection.cpp'
--- src/client/mir_connection.cpp 2013-10-07 09:27:32 +0000
+++ src/client/mir_connection.cpp 2013-10-10 15:41:01 +0000
@@ -288,7 +288,6 @@
288 catch (std::exception const& x)288 catch (std::exception const& x)
289 {289 {
290 set_error_message(std::string("disconnect: ") + x.what());290 set_error_message(std::string("disconnect: ") + x.what());
291 disconnect_wait_handle.result_received();
292 }291 }
293292
294 return &disconnect_wait_handle;293 return &disconnect_wait_handle;
295294
=== modified file 'tests/unit-tests/frontend/test_published_socket_connector.cpp'
--- tests/unit-tests/frontend/test_published_socket_connector.cpp 2013-10-07 09:27:32 +0000
+++ tests/unit-tests/frontend/test_published_socket_connector.cpp 2013-10-10 15:41:01 +0000
@@ -49,6 +49,18 @@
49class MockConnectorReport : public mf::ConnectorReport49class MockConnectorReport : public mf::ConnectorReport
50{50{
51public:51public:
52 MockConnectorReport()
53 {
54 using namespace testing;
55 EXPECT_CALL(*this, thread_start()).Times(AnyNumber());
56 EXPECT_CALL(*this, thread_end()).Times(AnyNumber());
57 EXPECT_CALL(*this, starting_threads(_)).Times(AnyNumber());
58 EXPECT_CALL(*this, stopping_threads(_)).Times(AnyNumber());
59 EXPECT_CALL(*this, creating_session_for(_)).Times(AnyNumber());
60 EXPECT_CALL(*this, creating_socket_pair(_, _)).Times(AnyNumber());
61 EXPECT_CALL(*this, listening_on(_)).Times(AnyNumber());
62 EXPECT_CALL(*this, error(_)).Times(AnyNumber());
63 }
5264
53 ~MockConnectorReport() noexcept {}65 ~MockConnectorReport() noexcept {}
5466
@@ -68,8 +80,10 @@
6880
69struct PublishedSocketConnector : public ::testing::Test81struct PublishedSocketConnector : public ::testing::Test
70{82{
83 static const char* const test_socket;
71 static void SetUpTestCase()84 static void SetUpTestCase()
72 {85 {
86 remove(test_socket);
73 }87 }
7488
75 void SetUp()89 void SetUp()
@@ -77,23 +91,20 @@
77 communicator_report = std::make_shared<MockConnectorReport>();91 communicator_report = std::make_shared<MockConnectorReport>();
78 stub_server_tool = std::make_shared<mt::StubServerTool>();92 stub_server_tool = std::make_shared<mt::StubServerTool>();
79 stub_server = std::make_shared<mt::TestProtobufServer>(93 stub_server = std::make_shared<mt::TestProtobufServer>(
80 "./test_socket",94 test_socket,
81 stub_server_tool,95 stub_server_tool,
82 communicator_report);96 communicator_report);
8397
84 using namespace testing;
85 EXPECT_CALL(*communicator_report, error(_)).Times(AnyNumber());
86 stub_server->comm->start();98 stub_server->comm->start();
87 client = std::make_shared<mt::TestProtobufClient>("./test_socket", 100);99 client = std::make_shared<mt::TestProtobufClient>(test_socket, 100);
88 client->connect_parameters.set_application_name(__PRETTY_FUNCTION__);100 client->connect_parameters.set_application_name(__PRETTY_FUNCTION__);
89 }101 }
90102
91 void TearDown()103 void TearDown()
92 {104 {
105 client.reset();
106
93 stub_server->comm->stop();107 stub_server->comm->stop();
94 testing::Mock::VerifyAndClearExpectations(communicator_report.get());
95 client.reset();
96
97 stub_server.reset();108 stub_server.reset();
98 stub_server_tool.reset();109 stub_server_tool.reset();
99 communicator_report.reset();110 communicator_report.reset();
@@ -109,6 +120,7 @@
109 static std::shared_ptr<mt::TestProtobufServer> stub_server;120 static std::shared_ptr<mt::TestProtobufServer> stub_server;
110};121};
111122
123const char* const PublishedSocketConnector::test_socket = "./test_socket";
112std::shared_ptr<mt::StubServerTool> PublishedSocketConnector::stub_server_tool;124std::shared_ptr<mt::StubServerTool> PublishedSocketConnector::stub_server_tool;
113std::shared_ptr<MockConnectorReport> PublishedSocketConnector::communicator_report;125std::shared_ptr<MockConnectorReport> PublishedSocketConnector::communicator_report;
114std::shared_ptr<mt::TestProtobufServer> PublishedSocketConnector::stub_server;126std::shared_ptr<mt::TestProtobufServer> PublishedSocketConnector::stub_server;
@@ -196,7 +208,7 @@
196208
197}209}
198210
199TEST_F(PublishedSocketConnector, double_disconnection_attempt_throws_exception)211TEST_F(PublishedSocketConnector, double_disconnection_does_not_break)
200{212{
201 using namespace testing;213 using namespace testing;
202214
@@ -220,13 +232,33 @@
220232
221 Mock::VerifyAndClearExpectations(client.get());233 Mock::VerifyAndClearExpectations(client.get());
222234
223 EXPECT_CALL(*client->rpc_report, invocation_failed(InvocationMethodEq("disconnect"),_));235 // There is a race between the server closing the socket and
236 // the client sending the second "disconnect".
237 // Usually[*] the server wins and the "disconnect" fails resulting
238 // in an invocation_failed() report and an exception.
239 // Occasionally, the client wins and the message is sent to dying socket.
240 // [*] ON my desktop under valgrind "Usually" is ~49 times out of 50
241
242 EXPECT_CALL(*client->rpc_report, invocation_failed(InvocationMethodEq("disconnect"),_)).Times(AtMost(1));
224 EXPECT_CALL(*client, disconnect_done()).Times(1);243 EXPECT_CALL(*client, disconnect_done()).Times(1);
225244
226 EXPECT_THROW({245 try
227 client->display_server.disconnect(0, &client->ignored, &client->ignored, google::protobuf::NewCallback(client.get(), &mt::TestProtobufClient::disconnect_done));246 {
247 client->display_server.disconnect(
248 0,
249 &client->ignored,
250 &client->ignored,
251 google::protobuf::NewCallback(client.get(), &mt::TestProtobufClient::disconnect_done));
252
253 // the write beat the socket closing
254 }
255 catch (std::runtime_error const& x)
256 {
257 // the socket closing beat the write
258 EXPECT_THAT(x.what(), HasSubstr("Failed to send message to server:"));
259 }
260
228 client->wait_for_disconnect_done();261 client->wait_for_disconnect_done();
229 }, std::runtime_error);
230}262}
231263
232TEST_F(PublishedSocketConnector, getting_and_advancing_buffers)264TEST_F(PublishedSocketConnector, getting_and_advancing_buffers)

Subscribers

People subscribed via source and target branches