Mir

Merge lp:~mir-team/mir/fix-1245336.2 into lp:mir

Proposed by Daniel van Vugt
Status: Rejected
Rejected by: Daniel van Vugt
Proposed branch: lp:~mir-team/mir/fix-1245336.2
Merge into: lp:mir
Diff against target: 186 lines (+76/-6)
7 files modified
include/test/mir_test_framework/display_server_test_fixture.h (+3/-0)
include/test/mir_test_framework/process.h (+2/-0)
include/test/mir_test_framework/testing_process_manager.h (+2/-0)
tests/acceptance-tests/test_server_shutdown.cpp (+8/-6)
tests/mir_test_framework/display_server_test_fixture.cpp (+10/-0)
tests/mir_test_framework/process.cpp (+33/-0)
tests/mir_test_framework/testing_process_manager.cpp (+18/-0)
To merge this branch: bzr merge lp:~mir-team/mir/fix-1245336.2
Reviewer Review Type Date Requested Status
Alan Griffiths Disapprove
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+193035@code.launchpad.net

Commit message

Avoid a race condition that could lead to spurious failures of server
shutdown tests (LP: #1245336)

The race is between the acceptance-tests process and its child server process.
In our signal/abort tests, it's possible the server process may start and
stop so quickly that the parent process doesn't have time to detect the
socket file (before it's correctly cleaned up).

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
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :
review: Disapprove

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'include/test/mir_test_framework/display_server_test_fixture.h'
--- include/test/mir_test_framework/display_server_test_fixture.h 2013-09-26 15:07:59 +0000
+++ include/test/mir_test_framework/display_server_test_fixture.h 2013-10-29 11:05:03 +0000
@@ -67,6 +67,9 @@
67 void kill_client_processes();67 void kill_client_processes();
68 void terminate_client_processes();68 void terminate_client_processes();
6969
70 bool wait_for_server_to_pause();
71 void resume_server_process();
72
70 void run_in_test_process(std::function<void()> const& run_code);73 void run_in_test_process(std::function<void()> const& run_code);
7174
72protected:75protected:
7376
=== modified file 'include/test/mir_test_framework/process.h'
--- include/test/mir_test_framework/process.h 2013-08-28 03:41:48 +0000
+++ include/test/mir_test_framework/process.h 2013-10-29 11:05:03 +0000
@@ -73,6 +73,8 @@
73 // Wait for the process to terminate, and return the results.73 // Wait for the process to terminate, and return the results.
74 Result wait_for_termination(const std::chrono::milliseconds& timeout = std::chrono::milliseconds(60 * 1000));74 Result wait_for_termination(const std::chrono::milliseconds& timeout = std::chrono::milliseconds(60 * 1000));
7575
76 bool wait_for_stop(const std::chrono::milliseconds& timeout = std::chrono::milliseconds(60 * 1000));
77
76 void kill();78 void kill();
77 void terminate();79 void terminate();
78 void stop();80 void stop();
7981
=== modified file 'include/test/mir_test_framework/testing_process_manager.h'
--- include/test/mir_test_framework/testing_process_manager.h 2013-09-25 18:25:11 +0000
+++ include/test/mir_test_framework/testing_process_manager.h 2013-10-29 11:05:03 +0000
@@ -60,6 +60,8 @@
60 Result shutdown_server_process();60 Result shutdown_server_process();
61 void kill_client_processes();61 void kill_client_processes();
62 void terminate_client_processes();62 void terminate_client_processes();
63 bool wait_for_server_to_pause();
64 void resume_server();
63 void run_in_test_process(std::function<void()> const& run_code);65 void run_in_test_process(std::function<void()> const& run_code);
6466
65private:67private:
6668
=== modified file 'tests/acceptance-tests/test_server_shutdown.cpp'
--- tests/acceptance-tests/test_server_shutdown.cpp 2013-10-25 09:01:53 +0000
+++ tests/acceptance-tests/test_server_shutdown.cpp 2013-10-29 11:05:03 +0000
@@ -375,19 +375,20 @@
375 {375 {
376 void exec() override376 void exec() override
377 {377 {
378 raise(SIGSTOP);
378 abort();379 abort();
379 }380 }
380 };381 };
381382
382 ServerConfig server_config;383 ServerConfig server_config;
383 launch_server_process(server_config);384 launch_server_process(server_config);
385 // ^ This blocks until the socket file exists
384386
385 run_in_test_process([&]387 run_in_test_process([&]
386 {388 {
387 using std::chrono::steady_clock;389 ASSERT_TRUE(wait_for_server_to_pause());
388 std::chrono::seconds const limit(2);
389
390 ASSERT_TRUE(file_exists(server_config.the_socket_file()));390 ASSERT_TRUE(file_exists(server_config.the_socket_file()));
391 resume_server_process();
391392
392 // shutdown should fail as the server aborted393 // shutdown should fail as the server aborted
393 ASSERT_FALSE(shutdown_server_process());394 ASSERT_FALSE(shutdown_server_process());
@@ -404,6 +405,7 @@
404 {405 {
405 void exec() override406 void exec() override
406 {407 {
408 raise(SIGSTOP);
407 raise(sig);409 raise(sig);
408 }410 }
409411
@@ -413,13 +415,13 @@
413415
414 ServerConfig server_config(GetParam());416 ServerConfig server_config(GetParam());
415 launch_server_process(server_config);417 launch_server_process(server_config);
418 // ^ This blocks until the socket file exists
416419
417 run_in_test_process([&]420 run_in_test_process([&]
418 {421 {
419 using std::chrono::steady_clock;422 ASSERT_TRUE(wait_for_server_to_pause());
420 std::chrono::seconds const limit(2);
421
422 ASSERT_TRUE(file_exists(server_config.the_socket_file()));423 ASSERT_TRUE(file_exists(server_config.the_socket_file()));
424 resume_server_process();
423425
424 // shutdown should fail as the server faulted426 // shutdown should fail as the server faulted
425 ASSERT_FALSE(shutdown_server_process());427 ASSERT_FALSE(shutdown_server_process());
426428
=== modified file 'tests/mir_test_framework/display_server_test_fixture.cpp'
--- tests/mir_test_framework/display_server_test_fixture.cpp 2013-09-26 15:07:59 +0000
+++ tests/mir_test_framework/display_server_test_fixture.cpp 2013-10-29 11:05:03 +0000
@@ -86,6 +86,16 @@
86 process_manager.kill_client_processes();86 process_manager.kill_client_processes();
87}87}
8888
89bool BespokeDisplayServerTestFixture::wait_for_server_to_pause()
90{
91 return process_manager.wait_for_server_to_pause();
92}
93
94void BespokeDisplayServerTestFixture::resume_server_process()
95{
96 process_manager.resume_server();
97}
98
89void BespokeDisplayServerTestFixture::run_in_test_process(99void BespokeDisplayServerTestFixture::run_in_test_process(
90 std::function<void()> const& run_code)100 std::function<void()> const& run_code)
91{101{
92102
=== modified file 'tests/mir_test_framework/process.cpp'
--- tests/mir_test_framework/process.cpp 2013-08-28 03:41:48 +0000
+++ tests/mir_test_framework/process.cpp 2013-10-29 11:05:03 +0000
@@ -166,6 +166,39 @@
166 return result;166 return result;
167}167}
168168
169bool mtf::Process::wait_for_stop(const std::chrono::milliseconds& timeout)
170{
171 auto deadline = std::chrono::system_clock::now() + timeout;
172 bool stopped = false;
173
174 while (std::chrono::system_clock::now() < deadline)
175 {
176 int status;
177 int ret = waitpid(pid, &status, WNOHANG | WUNTRACED);
178
179 if (ret == pid)
180 {
181 if (WIFSTOPPED(status))
182 {
183 stopped = true;
184 break;
185 }
186 else if (WIFSIGNALED(status) || WIFEXITED(status))
187 {
188 break;
189 }
190 }
191 else if (ret < 0)
192 {
193 break;
194 }
195
196 std::this_thread::yield();
197 }
198
199 return stopped;
200}
201
169void mtf::Process::kill()202void mtf::Process::kill()
170{203{
171 if (!detached) signal_process(pid, SIGKILL);204 if (!detached) signal_process(pid, SIGKILL);
172205
=== modified file 'tests/mir_test_framework/testing_process_manager.cpp'
--- tests/mir_test_framework/testing_process_manager.cpp 2013-09-30 09:18:00 +0000
+++ tests/mir_test_framework/testing_process_manager.cpp 2013-10-29 11:05:03 +0000
@@ -225,6 +225,24 @@
225 }225 }
226}226}
227227
228bool mtf::TestingProcessManager::wait_for_server_to_pause()
229{
230 bool paused = false;
231
232 if (server_process)
233 {
234 paused = server_process->wait_for_stop(std::chrono::minutes(1));
235 }
236
237 return paused;
238}
239
240void mtf::TestingProcessManager::resume_server()
241{
242 if (server_process)
243 server_process->cont();
244}
245
228void mtf::TestingProcessManager::run_in_test_process(std::function<void()> const& run_code)246void mtf::TestingProcessManager::run_in_test_process(std::function<void()> const& run_code)
229{247{
230 if (is_test_process)248 if (is_test_process)

Subscribers

People subscribed via source and target branches