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
1=== modified file 'include/test/mir_test_framework/display_server_test_fixture.h'
2--- include/test/mir_test_framework/display_server_test_fixture.h 2013-09-26 15:07:59 +0000
3+++ include/test/mir_test_framework/display_server_test_fixture.h 2013-10-29 11:05:03 +0000
4@@ -67,6 +67,9 @@
5 void kill_client_processes();
6 void terminate_client_processes();
7
8+ bool wait_for_server_to_pause();
9+ void resume_server_process();
10+
11 void run_in_test_process(std::function<void()> const& run_code);
12
13 protected:
14
15=== modified file 'include/test/mir_test_framework/process.h'
16--- include/test/mir_test_framework/process.h 2013-08-28 03:41:48 +0000
17+++ include/test/mir_test_framework/process.h 2013-10-29 11:05:03 +0000
18@@ -73,6 +73,8 @@
19 // Wait for the process to terminate, and return the results.
20 Result wait_for_termination(const std::chrono::milliseconds& timeout = std::chrono::milliseconds(60 * 1000));
21
22+ bool wait_for_stop(const std::chrono::milliseconds& timeout = std::chrono::milliseconds(60 * 1000));
23+
24 void kill();
25 void terminate();
26 void stop();
27
28=== modified file 'include/test/mir_test_framework/testing_process_manager.h'
29--- include/test/mir_test_framework/testing_process_manager.h 2013-09-25 18:25:11 +0000
30+++ include/test/mir_test_framework/testing_process_manager.h 2013-10-29 11:05:03 +0000
31@@ -60,6 +60,8 @@
32 Result shutdown_server_process();
33 void kill_client_processes();
34 void terminate_client_processes();
35+ bool wait_for_server_to_pause();
36+ void resume_server();
37 void run_in_test_process(std::function<void()> const& run_code);
38
39 private:
40
41=== modified file 'tests/acceptance-tests/test_server_shutdown.cpp'
42--- tests/acceptance-tests/test_server_shutdown.cpp 2013-10-25 09:01:53 +0000
43+++ tests/acceptance-tests/test_server_shutdown.cpp 2013-10-29 11:05:03 +0000
44@@ -375,19 +375,20 @@
45 {
46 void exec() override
47 {
48+ raise(SIGSTOP);
49 abort();
50 }
51 };
52
53 ServerConfig server_config;
54 launch_server_process(server_config);
55+ // ^ This blocks until the socket file exists
56
57 run_in_test_process([&]
58 {
59- using std::chrono::steady_clock;
60- std::chrono::seconds const limit(2);
61-
62+ ASSERT_TRUE(wait_for_server_to_pause());
63 ASSERT_TRUE(file_exists(server_config.the_socket_file()));
64+ resume_server_process();
65
66 // shutdown should fail as the server aborted
67 ASSERT_FALSE(shutdown_server_process());
68@@ -404,6 +405,7 @@
69 {
70 void exec() override
71 {
72+ raise(SIGSTOP);
73 raise(sig);
74 }
75
76@@ -413,13 +415,13 @@
77
78 ServerConfig server_config(GetParam());
79 launch_server_process(server_config);
80+ // ^ This blocks until the socket file exists
81
82 run_in_test_process([&]
83 {
84- using std::chrono::steady_clock;
85- std::chrono::seconds const limit(2);
86-
87+ ASSERT_TRUE(wait_for_server_to_pause());
88 ASSERT_TRUE(file_exists(server_config.the_socket_file()));
89+ resume_server_process();
90
91 // shutdown should fail as the server faulted
92 ASSERT_FALSE(shutdown_server_process());
93
94=== modified file 'tests/mir_test_framework/display_server_test_fixture.cpp'
95--- tests/mir_test_framework/display_server_test_fixture.cpp 2013-09-26 15:07:59 +0000
96+++ tests/mir_test_framework/display_server_test_fixture.cpp 2013-10-29 11:05:03 +0000
97@@ -86,6 +86,16 @@
98 process_manager.kill_client_processes();
99 }
100
101+bool BespokeDisplayServerTestFixture::wait_for_server_to_pause()
102+{
103+ return process_manager.wait_for_server_to_pause();
104+}
105+
106+void BespokeDisplayServerTestFixture::resume_server_process()
107+{
108+ process_manager.resume_server();
109+}
110+
111 void BespokeDisplayServerTestFixture::run_in_test_process(
112 std::function<void()> const& run_code)
113 {
114
115=== modified file 'tests/mir_test_framework/process.cpp'
116--- tests/mir_test_framework/process.cpp 2013-08-28 03:41:48 +0000
117+++ tests/mir_test_framework/process.cpp 2013-10-29 11:05:03 +0000
118@@ -166,6 +166,39 @@
119 return result;
120 }
121
122+bool mtf::Process::wait_for_stop(const std::chrono::milliseconds& timeout)
123+{
124+ auto deadline = std::chrono::system_clock::now() + timeout;
125+ bool stopped = false;
126+
127+ while (std::chrono::system_clock::now() < deadline)
128+ {
129+ int status;
130+ int ret = waitpid(pid, &status, WNOHANG | WUNTRACED);
131+
132+ if (ret == pid)
133+ {
134+ if (WIFSTOPPED(status))
135+ {
136+ stopped = true;
137+ break;
138+ }
139+ else if (WIFSIGNALED(status) || WIFEXITED(status))
140+ {
141+ break;
142+ }
143+ }
144+ else if (ret < 0)
145+ {
146+ break;
147+ }
148+
149+ std::this_thread::yield();
150+ }
151+
152+ return stopped;
153+}
154+
155 void mtf::Process::kill()
156 {
157 if (!detached) signal_process(pid, SIGKILL);
158
159=== modified file 'tests/mir_test_framework/testing_process_manager.cpp'
160--- tests/mir_test_framework/testing_process_manager.cpp 2013-09-30 09:18:00 +0000
161+++ tests/mir_test_framework/testing_process_manager.cpp 2013-10-29 11:05:03 +0000
162@@ -225,6 +225,24 @@
163 }
164 }
165
166+bool mtf::TestingProcessManager::wait_for_server_to_pause()
167+{
168+ bool paused = false;
169+
170+ if (server_process)
171+ {
172+ paused = server_process->wait_for_stop(std::chrono::minutes(1));
173+ }
174+
175+ return paused;
176+}
177+
178+void mtf::TestingProcessManager::resume_server()
179+{
180+ if (server_process)
181+ server_process->cont();
182+}
183+
184 void mtf::TestingProcessManager::run_in_test_process(std::function<void()> const& run_code)
185 {
186 if (is_test_process)

Subscribers

People subscribed via source and target branches