Merge lp:~xnox/upstart/cgroup-states into lp:~jamesodhunt/upstart/cgroups
- cgroup-states
- Merge into cgroups
Status: | Work in progress |
---|---|
Proposed branch: | lp:~xnox/upstart/cgroup-states |
Merge into: | lp:~jamesodhunt/upstart/cgroups |
Diff against target: |
1234 lines (+343/-197) 10 files modified
init/job.c (+1/-11) init/job_process.c (+17/-82) init/tests/test_event.c (+6/-6) init/tests/test_job.c (+72/-34) scripts/Makefile.am (+9/-9) scripts/pyupstart.py (+102/-4) scripts/tests/test_pyupstart_cgmanager.py (+63/-0) scripts/tests/test_pyupstart_session_init.py (+0/-26) scripts/tests/test_pyupstart_system_cgroups.py (+73/-0) scripts/tests/test_pyupstart_system_init.py (+0/-25) |
To merge this branch: | bzr merge lp:~xnox/upstart/cgroup-states |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
James Hunt | Pending | ||
Review via email: mp+214514@code.launchpad.net |
Commit message
Description of the change
- 1605. By Dimitri John Ledkov
-
Actually, it looks like the tests might be broken.
- 1606. By Dimitri John Ledkov
-
Extend asserts to setup stages
Dimitri John Ledkov (xnox) wrote : | # |
so running under cgmanager in a container i notice that jobs do not progress from *_SETUP -> * states.
Also process tracking with e.g. expect stop did not work it seems (well, i've kill -s CONT a few processes to get the container booting)
I am now leaning to believe that stats in job_process.c (e.g. PROCESS_PRE_STOP) should assert state JOB_PRE_STOP. And that it's buggy behavior for jobs to get stuck in _SETUP state and not transition to the full one. (when cgroups stanza is specified that is)
Dimitri John Ledkov (xnox) wrote : | # |
I've tested all but "security" and "pre-stop" processes and they all get cgroups containment now.
- 1607. By Dimitri John Ledkov
-
We need to both SIGCONT & switch to next state for 'expect stop' and setup states.
Dimitri John Ledkov (xnox) wrote : | # |
With -r1607 i get correct transitions from *_SETUP -> * states.
However, expect stop jobs are still stuck in "setup" and do not transition to running. Investigating.
- 1608. By Dimitri John Ledkov
-
SIGCONT in setup as well.
Dimitri John Ledkov (xnox) wrote : | # |
Now the states progress to quickly, e.g. we jump to spawning the main process and running, ahead of pre-start process completing, if and only if cgroups stanza is specified in the job.
- 1609. By Dimitri John Ledkov
-
Merge pythonic CGManager
- 1610. By Dimitri John Ledkov
-
Add pyupstart CGManager tests
- 1611. By Dimitri John Ledkov
-
And kaboom!
Unmerged revisions
- 1611. By Dimitri John Ledkov
-
And kaboom!
- 1610. By Dimitri John Ledkov
-
Add pyupstart CGManager tests
- 1609. By Dimitri John Ledkov
-
Merge pythonic CGManager
- 1608. By Dimitri John Ledkov
-
SIGCONT in setup as well.
- 1607. By Dimitri John Ledkov
-
We need to both SIGCONT & switch to next state for 'expect stop' and setup states.
- 1606. By Dimitri John Ledkov
-
Extend asserts to setup stages
- 1605. By Dimitri John Ledkov
-
Actually, it looks like the tests might be broken.
- 1604. By Dimitri John Ledkov
-
Fix up cgroup-states.
- 1603. By Dimitri John Ledkov
-
Remove debug
Preview Diff
1 | === modified file 'init/job.c' |
2 | --- init/job.c 2014-04-04 18:42:18 +0000 |
3 | +++ init/job.c 2014-04-08 20:51:56 +0000 |
4 | @@ -278,8 +278,6 @@ |
5 | { |
6 | nih_assert (job != NULL); |
7 | |
8 | - nih_message ("XXX:%s:%d: ", __func__, __LINE__); |
9 | - |
10 | if (job->goal == goal) |
11 | return; |
12 | |
13 | @@ -348,9 +346,6 @@ |
14 | { |
15 | nih_assert (job != NULL); |
16 | |
17 | - nih_message ("XXX:%s:%d:job '%s': goal=%s, state=%s, new state=%s", __func__, __LINE__, |
18 | - job_name (job), job_goal_name (job->goal), job_state_name (job->state), job_state_name (state)); |
19 | - |
20 | while (job->state != state) { |
21 | JobState old_state; |
22 | int unused; |
23 | @@ -363,9 +358,6 @@ |
24 | old_state = job->state; |
25 | job->state = state; |
26 | |
27 | - nih_message ("XXX:%s:%d:job '%s': goal=%s, state=%s, old state=%s", __func__, __LINE__, |
28 | - job_name (job), job_goal_name (job->goal), job_state_name (job->state), job_state_name (old_state)); |
29 | - |
30 | NIH_LIST_FOREACH (control_conns, iter) { |
31 | NihListEntry *entry = (NihListEntry *)iter; |
32 | DBusConnection *conn = (DBusConnection *)entry->data; |
33 | @@ -673,8 +665,6 @@ |
34 | { |
35 | nih_assert (job != NULL); |
36 | |
37 | - nih_message ("XXX:%s:%d: ", __func__, __LINE__); |
38 | - |
39 | switch (job->state) { |
40 | case JOB_WAITING: |
41 | switch (job->goal) { |
42 | @@ -789,7 +779,7 @@ |
43 | case JOB_PRE_STOP_SETUP: |
44 | switch (job->goal) { |
45 | case JOB_STOP: |
46 | - return JOB_STOPPING; |
47 | + return JOB_PRE_STOP; |
48 | case JOB_START: |
49 | return JOB_PRE_STOP; |
50 | case JOB_RESPAWN: |
51 | |
52 | === modified file 'init/job_process.c' |
53 | --- init/job_process.c 2014-04-04 18:42:18 +0000 |
54 | +++ init/job_process.c 2014-04-08 20:51:56 +0000 |
55 | @@ -199,8 +199,6 @@ |
56 | |
57 | nih_assert (job != NULL); |
58 | |
59 | - nih_message ("XXX:%s:%d: ", __func__, __LINE__); |
60 | - |
61 | proc = job->class->process[process]; |
62 | nih_assert (proc != NULL); |
63 | nih_assert (proc->command != NULL); |
64 | @@ -449,8 +447,6 @@ |
65 | int cgroups_needed = FALSE; |
66 | #endif /* ENABLE_CGROUPS */ |
67 | |
68 | - //nih_message ("XXX:%s:%d: ", __func__, __LINE__); |
69 | - |
70 | nih_assert (job != NULL); |
71 | nih_assert (job->class != NULL); |
72 | nih_assert (job->log != NULL); |
73 | @@ -950,11 +946,8 @@ |
74 | /* Signal to parent that the (final) setup phase |
75 | * is complete. |
76 | */ |
77 | - nih_message ("XXX:%s:%d: raising SIGSTOP to %s process %s pid %d (state=%s)", __func__, __LINE__, |
78 | - job_name (job), process_name (process), getpid(), job_state_name (job->state));fflush (NULL); |
79 | raise (SIGSTOP); |
80 | } |
81 | - nih_message ("XXX:%s:%d: ", __func__, __LINE__); |
82 | |
83 | #endif /* ENABLE_CGROUPS */ |
84 | |
85 | @@ -964,14 +957,11 @@ |
86 | job_process_error_abort (fds[1], JOB_PROCESS_ERROR_SETGID, 0); |
87 | } |
88 | |
89 | - nih_message ("XXX:%s:%d: ", __func__, __LINE__); |
90 | if (job_setuid != (uid_t)-1 && setuid (job_setuid) < 0) { |
91 | nih_error_raise_system (); |
92 | job_process_error_abort (fds[1], JOB_PROCESS_ERROR_SETUID, 0); |
93 | } |
94 | - nih_message ("XXX:%s:%d: ", __func__, __LINE__); |
95 | } |
96 | - nih_message ("XXX:%s:%d: ", __func__, __LINE__); |
97 | |
98 | /* Reset all the signal handlers back to their default handling so |
99 | * the child isn't unexpectedly ignoring any, and so we won't |
100 | @@ -980,7 +970,6 @@ |
101 | nih_signal_reset (); |
102 | sigprocmask (SIG_SETMASK, &orig_set, NULL); |
103 | |
104 | - nih_message ("XXX:%s:%d: ", __func__, __LINE__); |
105 | /* Notes: |
106 | * |
107 | * - we can't use pause() here since there would then be no way to |
108 | @@ -1003,7 +992,6 @@ |
109 | close (fds[1]); |
110 | raise (SIGSTOP); |
111 | } |
112 | - nih_message ("XXX:%s:%d: ", __func__, __LINE__); |
113 | |
114 | #ifdef ENABLE_CGROUPS |
115 | /* Move the pid into the appropriate cgroups now that |
116 | @@ -1022,17 +1010,14 @@ |
117 | } |
118 | #endif /* ENABLE_CGROUPS */ |
119 | |
120 | - nih_message ("XXX:%s:%d: ", __func__, __LINE__); |
121 | /* Set up a process trace if we need to trace forks */ |
122 | if (trace) { |
123 | - nih_message ("XXX:%s:%d: ", __func__, __LINE__); |
124 | if (ptrace (PTRACE_TRACEME, 0, NULL, 0) < 0) { |
125 | nih_error_raise_system(); |
126 | job_process_error_abort (fds[1], |
127 | JOB_PROCESS_ERROR_PTRACE, 0); |
128 | } |
129 | } |
130 | - nih_message ("XXX:%s:%d: ", __func__, __LINE__); |
131 | |
132 | /* Execute the process, if we escape from here it failed */ |
133 | if (execvp (argv[0], argv) < 0) { |
134 | @@ -1526,9 +1511,6 @@ |
135 | |
136 | nih_assert (pid > 0); |
137 | |
138 | - nih_message ("XXX:%s:%d:pid=%d, event=%x, status=%d", __func__, __LINE__, |
139 | - pid, event, status); |
140 | - |
141 | /* Find the job that an event ocurred for, and identify which of the |
142 | * job's process it was. If we don't know about it, then we simply |
143 | * ignore the event. |
144 | @@ -1537,9 +1519,6 @@ |
145 | if (! job) |
146 | return; |
147 | |
148 | - nih_message ("XXX:%s:%d:job '%s': goal=%s, state=%s", __func__, __LINE__, |
149 | - job_name (job), job_goal_name (job->goal), job_state_name (job->state)); |
150 | - |
151 | /* Check the job's normal exit clauses to see whether this is a failure |
152 | * worth warning about. |
153 | */ |
154 | @@ -1553,7 +1532,6 @@ |
155 | |
156 | switch (event) { |
157 | case NIH_CHILD_EXITED: |
158 | - nih_message ("XXX:%s:%d:", __func__, __LINE__); |
159 | /* Child exited; check status to see whether it exited |
160 | * normally (zero) or with a non-zero status. |
161 | */ |
162 | @@ -1571,7 +1549,6 @@ |
163 | break; |
164 | case NIH_CHILD_KILLED: |
165 | case NIH_CHILD_DUMPED: |
166 | - nih_message ("XXX:%s:%d:", __func__, __LINE__); |
167 | /* Child was killed by a signal, and maybe dumped core. We |
168 | * store the signal value in the higher byte of status (it's |
169 | * safe to do that) to distinguish it from a normal exit |
170 | @@ -1592,7 +1569,6 @@ |
171 | job_process_terminated (job, process, status); |
172 | break; |
173 | case NIH_CHILD_STOPPED: |
174 | - nih_message ("XXX:%s:%d:", __func__, __LINE__); |
175 | /* Child was stopped by a signal, make sure it was SIGSTOP |
176 | * and not a tty-related signal. |
177 | */ |
178 | @@ -1608,13 +1584,11 @@ |
179 | } |
180 | |
181 | if (status == SIGSTOP) { |
182 | - nih_message ("XXX:%s:%d:", __func__, __LINE__); |
183 | job_process_stopped (job, process); |
184 | } |
185 | |
186 | break; |
187 | case NIH_CHILD_CONTINUED: |
188 | - nih_message ("XXX:%s:%d:", __func__, __LINE__); |
189 | /* Child was continued by a signal. |
190 | */ |
191 | sig = nih_signal_to_name (status); |
192 | @@ -1629,7 +1603,6 @@ |
193 | } |
194 | break; |
195 | case NIH_CHILD_TRAPPED: |
196 | - nih_message ("XXX:%s:%d:", __func__, __LINE__); |
197 | /* Child received a signal while we were tracing it. This |
198 | * can be a signal raised inside the kernel as a side-effect |
199 | * of the trace because the child called fork() or exec(); |
200 | @@ -1637,29 +1610,23 @@ |
201 | */ |
202 | if ((job->trace_state == TRACE_NEW) |
203 | && (status == SIGTRAP)) { |
204 | - nih_message ("XXX:%s:%d:", __func__, __LINE__); |
205 | job_process_trace_new (job, process); |
206 | } else if ((job->trace_state == TRACE_NEW_CHILD) |
207 | && (status == SIGSTOP)) { |
208 | - nih_message ("XXX:%s:%d:", __func__, __LINE__); |
209 | job_process_trace_new_child (job, process); |
210 | } else { |
211 | - nih_message ("XXX:%s:%d:", __func__, __LINE__); |
212 | job_process_trace_signal (job, process, status); |
213 | } |
214 | break; |
215 | case NIH_CHILD_PTRACE: |
216 | - nih_message ("XXX:%s:%d:", __func__, __LINE__); |
217 | /* Child called an important syscall that can modify the |
218 | * state of the process trace we hold. |
219 | */ |
220 | switch (status) { |
221 | case PTRACE_EVENT_FORK: |
222 | - nih_message ("XXX:%s:%d:", __func__, __LINE__); |
223 | job_process_trace_fork (job, process); |
224 | break; |
225 | case PTRACE_EVENT_EXEC: |
226 | - nih_message ("XXX:%s:%d:", __func__, __LINE__); |
227 | job_process_trace_exec (job, process); |
228 | break; |
229 | default: |
230 | @@ -1697,10 +1664,6 @@ |
231 | |
232 | nih_assert (job != NULL); |
233 | |
234 | - nih_message ("XXX:%s:%d:job '%s': goal=%s, state=%s, process=%s, status=%d", __func__, __LINE__, |
235 | - job_name (job), job_goal_name (job->goal), job_state_name (job->state), |
236 | - process_name (process), status); |
237 | - |
238 | switch (process) { |
239 | case PROCESS_MAIN: |
240 | nih_assert ((job->state == JOB_RUNNING) |
241 | @@ -1708,7 +1671,9 @@ |
242 | || (job->state == JOB_KILLED) |
243 | || (job->state == JOB_STOPPING) |
244 | || (job->state == JOB_POST_START) |
245 | + || (job->state == JOB_POST_START_SETUP) |
246 | || (job->state == JOB_PRE_STOP) |
247 | + || (job->state == JOB_PRE_STOP_SETUP) |
248 | || (job->state == JOB_SETUP)); |
249 | |
250 | /* We don't change the state if we're in post-start and there's |
251 | @@ -1800,7 +1765,8 @@ |
252 | stop = TRUE; |
253 | break; |
254 | case PROCESS_SECURITY: |
255 | - nih_assert (job->state == JOB_SECURITY_SETUP); |
256 | + nih_assert ((job->state == JOB_SECURITY) |
257 | + || (job->state == JOB_SECURITY_SETUP)); |
258 | |
259 | /* We should always fail the job if the security profile |
260 | * failed to load |
261 | @@ -1811,7 +1777,8 @@ |
262 | } |
263 | break; |
264 | case PROCESS_PRE_START: |
265 | - nih_assert (job->state == JOB_PRE_START_SETUP); |
266 | + nih_assert ((job->state == JOB_PRE_START) |
267 | + || (job->state == JOB_PRE_START_SETUP)); |
268 | |
269 | /* If the pre-start script is killed or exits with a status |
270 | * other than zero, it's always considered a failure since |
271 | @@ -1823,7 +1790,8 @@ |
272 | } |
273 | break; |
274 | case PROCESS_POST_START: |
275 | - nih_assert (job->state == JOB_POST_START_SETUP); |
276 | + nih_assert ((job->state == JOB_POST_START) |
277 | + || (job->state == JOB_POST_START_SETUP)); |
278 | |
279 | /* We always want to change the state when the post-start |
280 | * script terminates; if the main process is running, we'll |
281 | @@ -1834,7 +1802,8 @@ |
282 | */ |
283 | break; |
284 | case PROCESS_PRE_STOP: |
285 | - nih_assert (job->state == JOB_PRE_STOP_SETUP); |
286 | + nih_assert ((job->state == JOB_PRE_STOP) |
287 | + || (job->state == JOB_PRE_STOP_SETUP)); |
288 | |
289 | /* We always want to change the state when the pre-stop |
290 | * script terminates, we either want to go back into running |
291 | @@ -1845,7 +1814,8 @@ |
292 | */ |
293 | break; |
294 | case PROCESS_POST_STOP: |
295 | - nih_assert (job->state == JOB_POST_STOP_SETUP); |
296 | + nih_assert ((job->state == JOB_POST_STOP) |
297 | + || (job->state == JOB_POST_STOP_SETUP)); |
298 | |
299 | /* If the post-stop script is killed or exits with a status |
300 | * other than zero, it's always considered a failure since |
301 | @@ -2022,34 +1992,19 @@ |
302 | break; |
303 | } |
304 | |
305 | - nih_message ("XXX:%s:%d: job=%s, process=%s, pid %d (state=%s, goal=%s)", __func__, __LINE__, |
306 | - job_name (job), process_name (process), job->pid[process], job_state_name (job->state), job_goal_name (job->goal)); |
307 | - |
308 | /* Any process can stop on a signal, but we only care about the |
309 | * main process when the state is still spawned and any jobs |
310 | * which require (cgroup) setup. |
311 | - */ |
312 | - if (! ((process == PROCESS_MAIN && job->state == JOB_SPAWNED) || setup)) |
313 | - return; |
314 | - |
315 | - /* Send SIGCONT back and change the state to the next one for |
316 | + * |
317 | + * Send SIGCONT back and change the state to the next one for |
318 | * 'expect stop' jobs and those that require cgroup setup. |
319 | */ |
320 | - if (job->class->expect == EXPECT_STOP || (job_needs_cgroups (job) && setup)) { |
321 | - nih_message ("XXX:%s:%d: sending SIGCONT to %s process %s pid %d (state=%s)", __func__, __LINE__, |
322 | - job_name (job), process_name (process), job->pid[process], job_state_name (job->state)); |
323 | - |
324 | + if (job->class->expect == EXPECT_STOP && process == PROCESS_MAIN |
325 | + && (job->state == JOB_SETUP || job->state == JOB_SPAWNED) |
326 | + || (job_needs_cgroups (job) && setup)) { |
327 | kill (job->pid[process], SIGCONT); |
328 | - } |
329 | - |
330 | - if (job->class->expect == EXPECT_STOP && process == PROCESS_MAIN && job->state == JOB_SPAWNED) { |
331 | - nih_message ("XXX:%s:%d: changing state for job %s process %s pid %d (state=%s)", __func__, __LINE__, |
332 | - job_name (job), process_name (process), job->pid[process], job_state_name (job->state)); |
333 | - |
334 | job_change_state (job, job_next_state (job)); |
335 | } |
336 | - |
337 | - nih_message ("XXX:%s:%d: ", __func__, __LINE__); |
338 | } |
339 | |
340 | |
341 | @@ -2072,10 +2027,6 @@ |
342 | nih_assert ((job->trace_state == TRACE_NEW) |
343 | || (job->trace_state == TRACE_NEW_CHILD)); |
344 | |
345 | - nih_message ("XXX:%s:%d:job '%s': goal=%s, state=%s, process=%s", __func__, __LINE__, |
346 | - job_name (job), job_goal_name (job->goal), job_state_name (job->state), |
347 | - process_name (process)); |
348 | - |
349 | /* Any process can get us to trace them, but we only care about the |
350 | * main process when the state is still spawned. |
351 | */ |
352 | @@ -2127,10 +2078,6 @@ |
353 | nih_assert (job != NULL); |
354 | nih_assert (job->trace_state == TRACE_NEW_CHILD); |
355 | |
356 | - nih_message ("XXX:%s:%d:job '%s': goal=%s, state=%s, process=%s", __func__, __LINE__, |
357 | - job_name (job), job_goal_name (job->goal), job_state_name (job->state), |
358 | - process_name (process)); |
359 | - |
360 | /* Any process can get us to trace them, but we only care about the |
361 | * main process when the state is still spawned. |
362 | */ |
363 | @@ -2176,10 +2123,6 @@ |
364 | { |
365 | nih_assert (job != NULL); |
366 | |
367 | - nih_message ("XXX:%s:%d:job '%s': goal=%s, state=%s, process=%s, signum=%d", __func__, __LINE__, |
368 | - job_name (job), job_goal_name (job->goal), job_state_name (job->state), |
369 | - process_name (process), signum); |
370 | - |
371 | /* Any process can get us to trace them, but we only care about the |
372 | * main process when the state is still spawned. |
373 | */ |
374 | @@ -2215,10 +2158,6 @@ |
375 | |
376 | nih_assert (job != NULL); |
377 | |
378 | - nih_message ("XXX:%s:%d:job '%s': goal=%s, state=%s, process=%s", __func__, __LINE__, |
379 | - job_name (job), job_goal_name (job->goal), job_state_name (job->state), |
380 | - process_name (process)); |
381 | - |
382 | /* Any process can get us to trace them, but we only care about the |
383 | * main process when the state is still spawned. |
384 | */ |
385 | @@ -2287,10 +2226,6 @@ |
386 | { |
387 | nih_assert (job != NULL); |
388 | |
389 | - nih_message ("XXX:%s:%d:job '%s': goal=%s, state=%s, process=%s", __func__, __LINE__, |
390 | - job_name (job), job_goal_name (job->goal), job_state_name (job->state), |
391 | - process_name (process)); |
392 | - |
393 | /* Any process can get us to trace them, but we only care about the |
394 | * main process when the state is still spawned and we're tracing it. |
395 | */ |
396 | |
397 | === modified file 'init/tests/test_event.c' |
398 | --- init/tests/test_event.c 2013-01-31 17:23:55 +0000 |
399 | +++ init/tests/test_event.c 2014-04-08 20:51:56 +0000 |
400 | @@ -1259,7 +1259,7 @@ |
401 | job = (Job *)nih_hash_lookup (class->instances, ""); |
402 | |
403 | TEST_EQ (job->goal, JOB_STOP); |
404 | - TEST_EQ (job->state, JOB_POST_STOP); |
405 | + TEST_EQ (job->state, JOB_POST_STOP_SETUP); |
406 | |
407 | TEST_GT (job->pid[PROCESS_POST_STOP], 0); |
408 | waitpid (job->pid[PROCESS_POST_STOP], NULL, 0); |
409 | @@ -1335,7 +1335,7 @@ |
410 | job = (Job *)nih_hash_lookup (class->instances, ""); |
411 | |
412 | TEST_EQ (job->goal, JOB_STOP); |
413 | - TEST_EQ (job->state, JOB_POST_STOP); |
414 | + TEST_EQ (job->state, JOB_POST_STOP_SETUP); |
415 | |
416 | TEST_GT (job->pid[PROCESS_POST_STOP], 0); |
417 | waitpid (job->pid[PROCESS_POST_STOP], NULL, 0); |
418 | @@ -1439,7 +1439,7 @@ |
419 | job = (Job *)nih_hash_lookup (class->instances, ""); |
420 | |
421 | TEST_EQ (job->goal, JOB_STOP); |
422 | - TEST_EQ (job->state, JOB_POST_STOP); |
423 | + TEST_EQ (job->state, JOB_POST_STOP_SETUP); |
424 | |
425 | TEST_GT (job->pid[PROCESS_POST_STOP], 0); |
426 | waitpid (job->pid[PROCESS_POST_STOP], NULL, 0); |
427 | @@ -1621,7 +1621,7 @@ |
428 | job = (Job *)nih_hash_lookup (class->instances, ""); |
429 | |
430 | TEST_EQ (job->goal, JOB_STOP); |
431 | - TEST_EQ (job->state, JOB_POST_STOP); |
432 | + TEST_EQ (job->state, JOB_POST_STOP_SETUP); |
433 | |
434 | TEST_GT (job->pid[PROCESS_POST_STOP], 0); |
435 | waitpid (job->pid[PROCESS_POST_STOP], NULL, 0); |
436 | @@ -1980,7 +1980,7 @@ |
437 | event_poll (); |
438 | |
439 | TEST_EQ (job->goal, JOB_STOP); |
440 | - TEST_EQ (job->state, JOB_POST_STOP); |
441 | + TEST_EQ (job->state, JOB_POST_STOP_SETUP); |
442 | TEST_GT (job->pid[PROCESS_POST_STOP], 0); |
443 | TEST_EQ_P (job->blocker, NULL); |
444 | |
445 | @@ -2026,7 +2026,7 @@ |
446 | event_poll (); |
447 | |
448 | TEST_EQ (job->goal, JOB_START); |
449 | - TEST_EQ (job->state, JOB_PRE_START); |
450 | + TEST_EQ (job->state, JOB_PRE_START_SETUP); |
451 | TEST_GT (job->pid[PROCESS_PRE_START], 0); |
452 | TEST_EQ_P (job->blocker, NULL); |
453 | |
454 | |
455 | === modified file 'init/tests/test_job.c' |
456 | --- init/tests/test_job.c 2013-11-18 16:38:32 +0000 |
457 | +++ init/tests/test_job.c 2014-04-08 20:51:56 +0000 |
458 | @@ -1059,10 +1059,10 @@ |
459 | job->failed_process = PROCESS_INVALID; |
460 | job->exit_status = 0; |
461 | |
462 | - job_change_state (job, JOB_PRE_START); |
463 | + job_change_state (job, JOB_PRE_START_SETUP); |
464 | |
465 | TEST_EQ (job->goal, JOB_START); |
466 | - TEST_EQ (job->state, JOB_PRE_START); |
467 | + TEST_EQ (job->state, JOB_PRE_START_SETUP); |
468 | TEST_NE (job->pid[PROCESS_PRE_START], 0); |
469 | |
470 | waitpid (job->pid[PROCESS_PRE_START], &status, 0); |
471 | @@ -1125,7 +1125,7 @@ |
472 | job->failed_process = PROCESS_INVALID; |
473 | job->exit_status = 0; |
474 | |
475 | - job_change_state (job, JOB_PRE_START); |
476 | + job_change_state (job, JOB_PRE_START_SETUP); |
477 | |
478 | TEST_EQ (job->goal, JOB_START); |
479 | TEST_EQ (job->state, JOB_RUNNING); |
480 | @@ -1200,7 +1200,7 @@ |
481 | job->exit_status = 0; |
482 | |
483 | TEST_DIVERT_STDERR (output) { |
484 | - job_change_state (job, JOB_PRE_START); |
485 | + job_change_state (job, JOB_PRE_START_SETUP); |
486 | } |
487 | rewind (output); |
488 | |
489 | @@ -1284,7 +1284,7 @@ |
490 | job->failed_process = PROCESS_INVALID; |
491 | job->exit_status = 0; |
492 | |
493 | - job_change_state (job, JOB_SPAWNED); |
494 | + job_change_state (job, JOB_SETUP); |
495 | |
496 | TEST_EQ (job->goal, JOB_START); |
497 | TEST_EQ (job->state, JOB_RUNNING); |
498 | @@ -1352,7 +1352,7 @@ |
499 | job->failed_process = PROCESS_INVALID; |
500 | job->exit_status = 0; |
501 | |
502 | - job_change_state (job, JOB_SPAWNED); |
503 | + job_change_state (job, JOB_SETUP); |
504 | |
505 | TEST_EQ (job->goal, JOB_START); |
506 | TEST_EQ (job->state, JOB_RUNNING); |
507 | @@ -1432,7 +1432,7 @@ |
508 | job->failed_process = PROCESS_INVALID; |
509 | job->exit_status = 0; |
510 | |
511 | - job_change_state (job, JOB_SPAWNED); |
512 | + job_change_state (job, JOB_SETUP); |
513 | |
514 | TEST_EQ (job->goal, JOB_START); |
515 | TEST_EQ (job->state, JOB_RUNNING); |
516 | @@ -1507,7 +1507,7 @@ |
517 | job->failed_process = PROCESS_INVALID; |
518 | job->exit_status = 0; |
519 | |
520 | - job_change_state (job, JOB_SPAWNED); |
521 | + job_change_state (job, JOB_SETUP); |
522 | |
523 | TEST_EQ (job->goal, JOB_START); |
524 | TEST_EQ (job->state, JOB_RUNNING); |
525 | @@ -1572,7 +1572,7 @@ |
526 | job->exit_status = 0; |
527 | |
528 | TEST_DIVERT_STDERR (output) { |
529 | - job_change_state (job, JOB_SPAWNED); |
530 | + job_change_state (job, JOB_SETUP); |
531 | } |
532 | rewind (output); |
533 | |
534 | @@ -1658,10 +1658,10 @@ |
535 | job->failed_process = PROCESS_INVALID; |
536 | job->exit_status = 0; |
537 | |
538 | - job_change_state (job, JOB_SPAWNED); |
539 | + job_change_state (job, JOB_SETUP); |
540 | |
541 | TEST_EQ (job->goal, JOB_START); |
542 | - TEST_EQ (job->state, JOB_SPAWNED); |
543 | + TEST_EQ (job->state, JOB_SETUP); |
544 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
545 | |
546 | waitpid (job->pid[PROCESS_MAIN], &status, 0); |
547 | @@ -1727,10 +1727,10 @@ |
548 | job->failed_process = PROCESS_INVALID; |
549 | job->exit_status = 0; |
550 | |
551 | - job_change_state (job, JOB_POST_START); |
552 | + job_change_state (job, JOB_POST_START_SETUP); |
553 | |
554 | TEST_EQ (job->goal, JOB_START); |
555 | - TEST_EQ (job->state, JOB_POST_START); |
556 | + TEST_EQ (job->state, JOB_POST_START_SETUP); |
557 | TEST_EQ (job->pid[PROCESS_MAIN], 1); |
558 | TEST_NE (job->pid[PROCESS_POST_START], 0); |
559 | |
560 | @@ -1794,7 +1794,7 @@ |
561 | job->failed_process = PROCESS_INVALID; |
562 | job->exit_status = 0; |
563 | |
564 | - job_change_state (job, JOB_POST_START); |
565 | + job_change_state (job, JOB_POST_START_SETUP); |
566 | |
567 | TEST_EQ (job->goal, JOB_START); |
568 | TEST_EQ (job->state, JOB_RUNNING); |
569 | @@ -1858,7 +1858,7 @@ |
570 | job->exit_status = 0; |
571 | |
572 | TEST_DIVERT_STDERR (output) { |
573 | - job_change_state (job, JOB_POST_START); |
574 | + job_change_state (job, JOB_POST_START_SETUP); |
575 | } |
576 | rewind (output); |
577 | |
578 | @@ -2058,10 +2058,10 @@ |
579 | job->failed_process = PROCESS_INVALID; |
580 | job->exit_status = 0; |
581 | |
582 | - job_change_state (job, JOB_PRE_STOP); |
583 | + job_change_state (job, JOB_PRE_STOP_SETUP); |
584 | |
585 | TEST_EQ (job->goal, JOB_STOP); |
586 | - TEST_EQ (job->state, JOB_PRE_STOP); |
587 | + TEST_EQ (job->state, JOB_PRE_STOP_SETUP); |
588 | TEST_EQ (job->pid[PROCESS_MAIN], 1); |
589 | TEST_NE (job->pid[PROCESS_PRE_STOP], 0); |
590 | |
591 | @@ -2125,7 +2125,7 @@ |
592 | job->failed_process = PROCESS_INVALID; |
593 | job->exit_status = 0; |
594 | |
595 | - job_change_state (job, JOB_PRE_STOP); |
596 | + job_change_state (job, JOB_PRE_STOP_SETUP); |
597 | |
598 | TEST_EQ (job->goal, JOB_STOP); |
599 | TEST_EQ (job->state, JOB_STOPPING); |
600 | @@ -2198,7 +2198,7 @@ |
601 | job->failed_process = PROCESS_INVALID; |
602 | job->exit_status = 0; |
603 | |
604 | - job_change_state (job, JOB_PRE_STOP); |
605 | + job_change_state (job, JOB_PRE_STOP_SETUP); |
606 | |
607 | TEST_EQ (job->goal, JOB_STOP); |
608 | TEST_EQ (job->state, JOB_STOPPING); |
609 | @@ -2283,7 +2283,7 @@ |
610 | job->failed_process = PROCESS_INVALID; |
611 | job->exit_status = 0; |
612 | |
613 | - job_change_state (job, JOB_PRE_STOP); |
614 | + job_change_state (job, JOB_PRE_STOP_SETUP); |
615 | |
616 | TEST_EQ (job->goal, JOB_STOP); |
617 | TEST_EQ (job->state, JOB_STOPPING); |
618 | @@ -2364,7 +2364,7 @@ |
619 | job->exit_status = 0; |
620 | |
621 | TEST_DIVERT_STDERR (output) { |
622 | - job_change_state (job, JOB_PRE_STOP); |
623 | + job_change_state (job, JOB_PRE_STOP_SETUP); |
624 | } |
625 | rewind (output); |
626 | |
627 | @@ -3039,7 +3039,7 @@ |
628 | job_change_state (job, JOB_KILLED); |
629 | |
630 | TEST_EQ (job->goal, JOB_STOP); |
631 | - TEST_EQ (job->state, JOB_POST_STOP); |
632 | + TEST_EQ (job->state, JOB_POST_STOP_SETUP); |
633 | TEST_NE (job->pid[PROCESS_POST_STOP], 0); |
634 | |
635 | waitpid (job->pid[PROCESS_POST_STOP], &status, 0); |
636 | @@ -3100,10 +3100,10 @@ |
637 | job->failed_process = PROCESS_INVALID; |
638 | job->exit_status = 0; |
639 | |
640 | - job_change_state (job, JOB_POST_STOP); |
641 | + job_change_state (job, JOB_POST_STOP_SETUP); |
642 | |
643 | TEST_EQ (job->goal, JOB_STOP); |
644 | - TEST_EQ (job->state, JOB_POST_STOP); |
645 | + TEST_EQ (job->state, JOB_POST_STOP_SETUP); |
646 | TEST_NE (job->pid[PROCESS_POST_STOP], 0); |
647 | |
648 | waitpid (job->pid[PROCESS_POST_STOP], &status, 0); |
649 | @@ -3168,7 +3168,7 @@ |
650 | |
651 | TEST_FREE_TAG (job); |
652 | |
653 | - job_change_state (job, JOB_POST_STOP); |
654 | + job_change_state (job, JOB_POST_STOP_SETUP); |
655 | |
656 | TEST_FREE (job); |
657 | |
658 | @@ -3228,7 +3228,7 @@ |
659 | TEST_FREE_TAG (job); |
660 | |
661 | TEST_DIVERT_STDERR (output) { |
662 | - job_change_state (job, JOB_POST_STOP); |
663 | + job_change_state (job, JOB_POST_STOP_SETUP); |
664 | } |
665 | rewind (output); |
666 | |
667 | @@ -4000,11 +4000,20 @@ |
668 | |
669 | |
670 | /* Check that the next state if we're starting a starting job is |
671 | + * security setup. |
672 | + */ |
673 | + TEST_FEATURE ("with starting job and a goal of start"); |
674 | + job->goal = JOB_START; |
675 | + job->state = JOB_STARTING; |
676 | + |
677 | + TEST_EQ (job_next_state (job), JOB_SECURITY_SETUP); |
678 | + |
679 | + /* Check that the next state if we're starting a security job is |
680 | * security. |
681 | */ |
682 | - TEST_FEATURE ("with starting job and a goal of start"); |
683 | + TEST_FEATURE ("with security job and a goal of start"); |
684 | job->goal = JOB_START; |
685 | - job->state = JOB_STARTING; |
686 | + job->state = JOB_SECURITY_SETUP; |
687 | |
688 | TEST_EQ (job_next_state (job), JOB_SECURITY); |
689 | |
690 | @@ -4015,7 +4024,7 @@ |
691 | job->goal = JOB_START; |
692 | job->state = JOB_SECURITY; |
693 | |
694 | - TEST_EQ (job_next_state (job), JOB_PRE_START); |
695 | + TEST_EQ (job_next_state (job), JOB_PRE_START_SETUP); |
696 | |
697 | /* Check that the next state if we're stopping an security job is |
698 | * stopping. |
699 | @@ -4037,11 +4046,20 @@ |
700 | |
701 | |
702 | /* Check that the next state if we're starting a pre-start job is |
703 | + * setup. |
704 | + */ |
705 | + TEST_FEATURE ("with pre-start job and a goal of start"); |
706 | + job->goal = JOB_START; |
707 | + job->state = JOB_PRE_START; |
708 | + |
709 | + TEST_EQ (job_next_state (job), JOB_SETUP); |
710 | + |
711 | + /* Check that the next state if we're starting a pre-start job is |
712 | * spawned. |
713 | */ |
714 | TEST_FEATURE ("with pre-start job and a goal of start"); |
715 | job->goal = JOB_START; |
716 | - job->state = JOB_PRE_START; |
717 | + job->state = JOB_SETUP; |
718 | |
719 | TEST_EQ (job_next_state (job), JOB_SPAWNED); |
720 | |
721 | @@ -4057,11 +4075,20 @@ |
722 | |
723 | |
724 | /* Check that the next state if we're starting a spawned job is |
725 | + * post-start setup. |
726 | + */ |
727 | + TEST_FEATURE ("with spawned job and a goal of start"); |
728 | + job->goal = JOB_START; |
729 | + job->state = JOB_SPAWNED; |
730 | + |
731 | + TEST_EQ (job_next_state (job), JOB_POST_START_SETUP); |
732 | + |
733 | + /* Check that the next state if we're starting a spawned job is |
734 | * post-start. |
735 | */ |
736 | TEST_FEATURE ("with spawned job and a goal of start"); |
737 | job->goal = JOB_START; |
738 | - job->state = JOB_SPAWNED; |
739 | + job->state = JOB_POST_START_SETUP; |
740 | |
741 | TEST_EQ (job_next_state (job), JOB_POST_START); |
742 | |
743 | @@ -4098,7 +4125,7 @@ |
744 | |
745 | |
746 | /* Check that the next state if we're stopping a running job is |
747 | - * pre-stop. This is the "normal" stop process, as called from the |
748 | + * pre-stop setup. This is the "normal" stop process, as called from the |
749 | * goal change event. |
750 | */ |
751 | TEST_FEATURE ("with running job and a goal of stop"); |
752 | @@ -4106,6 +4133,17 @@ |
753 | job->state = JOB_RUNNING; |
754 | job->pid[PROCESS_MAIN] = 1; |
755 | |
756 | + TEST_EQ (job_next_state (job), JOB_PRE_STOP_SETUP); |
757 | + |
758 | + /* Check that the next state if we're stopping a running job is |
759 | + * pre-stop. |
760 | + */ |
761 | + TEST_FEATURE ("with running job and a goal of stop"); |
762 | + job->goal = JOB_STOP; |
763 | + job->state = JOB_PRE_STOP_SETUP; |
764 | + job->pid[PROCESS_MAIN] = 1; |
765 | + job->pid[PROCESS_PRE_STOP] = 2; |
766 | + |
767 | TEST_EQ (job_next_state (job), JOB_PRE_STOP); |
768 | |
769 | |
770 | @@ -4193,7 +4231,7 @@ |
771 | job->goal = JOB_START; |
772 | job->state = JOB_KILLED; |
773 | |
774 | - TEST_EQ (job_next_state (job), JOB_POST_STOP); |
775 | + TEST_EQ (job_next_state (job), JOB_POST_STOP_SETUP); |
776 | |
777 | |
778 | /* Check that the next state if we're stopping a killed job is |
779 | @@ -4203,7 +4241,7 @@ |
780 | job->goal = JOB_STOP; |
781 | job->state = JOB_KILLED; |
782 | |
783 | - TEST_EQ (job_next_state (job), JOB_POST_STOP); |
784 | + TEST_EQ (job_next_state (job), JOB_POST_STOP_SETUP); |
785 | |
786 | |
787 | /* Check that the next state if we're starting a post-stop job is |
788 | |
789 | === modified file 'scripts/Makefile.am' |
790 | --- scripts/Makefile.am 2013-11-14 11:42:05 +0000 |
791 | +++ scripts/Makefile.am 2014-04-08 20:51:56 +0000 |
792 | @@ -12,24 +12,24 @@ |
793 | upstart-monitor.py |
794 | |
795 | noinst_SCRIPTS = \ |
796 | - pyupstart.py |
797 | + pyupstart.py \ |
798 | + pyupstartvars.py |
799 | |
800 | CLEANFILES = \ |
801 | - pyupstart.py |
802 | + pyupstartvars.py pyupstartvars.py.tmp |
803 | |
804 | EXTRA_DIST = \ |
805 | $(install_scripts) \ |
806 | - pyupstart.py.in \ |
807 | + pyupstart.py \ |
808 | tests/__init__.py \ |
809 | tests/test_pyupstart_session_init.py \ |
810 | tests/test_pyupstart_system_init.py |
811 | |
812 | -pyupstart.py: pyupstart.py.in Makefile |
813 | - sed -e 's|[@]built_init_binary[@]|$(UPSTART_BINARY)|g' \ |
814 | - -e 's|[@]built_initctl_binary[@]|$(INITCTL_BINARY)|g' \ |
815 | - -e 's|[@]built_file_bridge_binary[@]|$(FILE_BRIDGE_BINARY)|g' \ |
816 | - $< > $@ |
817 | - chmod +x $@ |
818 | +pyupstartvars.py: Makefile |
819 | + echo "BUILT_UPSTART = '$(UPSTART_BINARY)'" > pyupstartvars.py.tmp |
820 | + echo "BUILT_INITCTL = '$(INITCTL_BINARY)'" >> pyupstartvars.py.tmp |
821 | + echo "BUILT_FILE_BRIDGE = '$(FILE_BRIDGE_BINARY)'" >> pyupstartvars.py.tmp |
822 | + mv pyupstartvars.py.tmp pyupstartvars.py |
823 | |
824 | dist_man_MANS = \ |
825 | man/initctl2dot.8 \ |
826 | |
827 | === renamed file 'scripts/pyupstart.py.in' => 'scripts/pyupstart.py' |
828 | --- scripts/pyupstart.py.in 2014-03-05 10:41:18 +0000 |
829 | +++ scripts/pyupstart.py 2014-04-08 20:51:56 +0000 |
830 | @@ -20,6 +20,8 @@ |
831 | import pyinotify |
832 | import subprocess |
833 | import shutil |
834 | +import sys |
835 | +import unittest |
836 | import dbus |
837 | import dbus.service |
838 | import dbus.mainloop.glib |
839 | @@ -28,6 +30,11 @@ |
840 | from datetime import datetime, timedelta |
841 | from gi.repository import GLib |
842 | |
843 | +try: |
844 | + from pyupstartvars import * |
845 | +except: |
846 | + pass |
847 | + |
848 | VERSION = '0.1' |
849 | NAME = 'TestUpstart' |
850 | |
851 | @@ -36,10 +43,6 @@ |
852 | SYSTEM_INITCTL = '/sbin/initctl' |
853 | SYSTEM_FILE_BRIDGE = '/sbin/upstart-file-bridge' |
854 | |
855 | -BUILT_UPSTART = '@built_init_binary@' |
856 | -BUILT_INITCTL = '@built_initctl_binary@' |
857 | -BUILT_FILE_BRIDGE = '@built_file_bridge_binary@' |
858 | - |
859 | UPSTART_SESSION_ENV = 'UPSTART_SESSION' |
860 | USE_SYSTEM_BINARIES_ENV = 'UPSTART_TEST_USE_SYSTEM_BINARIES' |
861 | |
862 | @@ -64,6 +67,10 @@ |
863 | OBJECT_PATH = '/com/ubuntu/Upstart' |
864 | FREEDESKTOP_PROPERTIES = 'org.freedesktop.DBus.Properties' |
865 | |
866 | +CGM_SOCKET = 'unix:path=/sys/fs/cgroup/cgmanager/sock' |
867 | +CGM_INTERFACE_NAME = 'org.linuxcontainers.cgmanager0_0' |
868 | +CGM_OBJECT_PATH = '/org/linuxcontainers/cgmanager' |
869 | + |
870 | # Maximum number of seconds to wait for Upstart to detect a new job |
871 | # has been created |
872 | JOB_WAIT_SECS = 5 |
873 | @@ -83,6 +90,7 @@ |
874 | |
875 | #--------------------------------------------------------------------- |
876 | |
877 | + |
878 | def get_init(): |
879 | """ |
880 | Return full path to an appropriate init daemon binary. |
881 | @@ -95,6 +103,7 @@ |
882 | assert (os.path.exists(binary)) |
883 | return binary |
884 | |
885 | + |
886 | def get_initctl(): |
887 | """ |
888 | Return full path to an appropriate initctl binary. |
889 | @@ -107,6 +116,7 @@ |
890 | assert (os.path.exists(binary)) |
891 | return binary |
892 | |
893 | + |
894 | def get_file_bridge(): |
895 | """ |
896 | Return full path to an appropriate upstart-file-bridge binary. |
897 | @@ -119,6 +129,7 @@ |
898 | assert (os.path.exists(binary)) |
899 | return binary |
900 | |
901 | + |
902 | def dbus_encode(str): |
903 | """ |
904 | Simulate nih_dbus_path() which Upstart uses to convert |
905 | @@ -195,6 +206,13 @@ |
906 | pass |
907 | |
908 | |
909 | +class CGMException(Exception): |
910 | + """ |
911 | + An Upstart Exception. |
912 | + """ |
913 | + pass |
914 | + |
915 | + |
916 | class Upstart: |
917 | """ |
918 | Upstart Class. |
919 | @@ -972,6 +990,7 @@ |
920 | self.stop() |
921 | self.logfile.destroy() |
922 | |
923 | + |
924 | class SystemInit(Upstart): |
925 | |
926 | def __init__(self): |
927 | @@ -991,6 +1010,59 @@ |
928 | os.system('telinit u') |
929 | |
930 | |
931 | +class CGManager(): |
932 | + |
933 | + def __init__(self, socket=CGM_SOCKET): |
934 | + self.socket = socket |
935 | + self.connection = None |
936 | + self.remote_object = None |
937 | + self.proxy = None |
938 | + self.connect() |
939 | + with open('/proc/cgroups') as f: |
940 | + self.all_cgroups = [l.split('\t')[0] for l in |
941 | + f.readlines() if not l.startswith('#')] |
942 | + |
943 | + def connect(self, force=False): |
944 | + """ |
945 | + Connect to CGManager. |
946 | + |
947 | + @force: if True, connect regardless of whether already |
948 | + connected. |
949 | + |
950 | + Notes: |
951 | + - Raises an CGMException() if already connected. |
952 | + """ |
953 | + if self.connection and not force: |
954 | + raise CGMException('Already connected') |
955 | + |
956 | + # Create appropriate D-Bus connection |
957 | + self.connection = dbus.connection.Connection(self.socket) |
958 | + self.remote_object = self.connection.get_object( |
959 | + object_path=CGM_OBJECT_PATH) |
960 | + self.proxy = dbus.Interface(self.remote_object, CGM_INTERFACE_NAME) |
961 | + self.Ping(0) |
962 | + |
963 | + def api_version(self): |
964 | + """ |
965 | + Determine api-version of running CGManager. |
966 | + |
967 | + Returns: API Version as a string. |
968 | + |
969 | + """ |
970 | + properties = dbus.Interface(self.remote_object, FREEDESKTOP_PROPERTIES) |
971 | + return int(properties.Get(CGM_INTERFACE_NAME, 'api_version')) |
972 | + |
973 | + def setup_sandbox(self, sandbox, pid): |
974 | + for controller in self.all_cgroups: |
975 | + if sandbox: |
976 | + self.Create(controller, sandbox) |
977 | + self.RemoveOnEmpty(controller, sandbox) |
978 | + self.MovePid(controller, sandbox, pid) |
979 | + |
980 | + def __getattr__(self, name): |
981 | + return getattr(self.proxy, name) |
982 | + |
983 | + |
984 | class SessionInit(Upstart): |
985 | """ |
986 | Create a new Upstart Session or join an existing one. |
987 | @@ -1164,3 +1236,29 @@ |
988 | |
989 | self.logger.debug("Restarting Session Init") |
990 | self.proxy.Restart() |
991 | + |
992 | +def main(): |
993 | + kwargs = {} |
994 | + format = \ |
995 | + '%(asctime)s:' \ |
996 | + '%(filename)s:' \ |
997 | + '%(name)s:' \ |
998 | + '%(funcName)s:' \ |
999 | + '%(levelname)s:' \ |
1000 | + '%(message)s' |
1001 | + |
1002 | + kwargs['format'] = format |
1003 | + |
1004 | + # We want to see what's happening |
1005 | + kwargs['level'] = logging.DEBUG |
1006 | + |
1007 | + logging.basicConfig(**kwargs) |
1008 | + |
1009 | + unittest.main( |
1010 | + testRunner=unittest.TextTestRunner( |
1011 | + stream=sys.stdout, |
1012 | + verbosity=2 |
1013 | + ) |
1014 | + ) |
1015 | + |
1016 | + sys.exit(0) |
1017 | |
1018 | === added file 'scripts/tests/test_pyupstart_cgmanager.py' |
1019 | --- scripts/tests/test_pyupstart_cgmanager.py 1970-01-01 00:00:00 +0000 |
1020 | +++ scripts/tests/test_pyupstart_cgmanager.py 2014-04-08 20:51:56 +0000 |
1021 | @@ -0,0 +1,63 @@ |
1022 | +#!/usr/bin/python3 |
1023 | +# -*- coding: utf-8 -*- |
1024 | +#--------------------------------------------------------------------- |
1025 | +# Copyright © 2014 Canonical Ltd. |
1026 | +# |
1027 | +# Author: Dimitri John Ledkov <xnox@ubuntu.com> |
1028 | +# |
1029 | +# This program is free software; you can redistribute it and/or modify |
1030 | +# it under the terms of the GNU General Public License version 2, as |
1031 | +# published by the Free Software Foundation. |
1032 | +# |
1033 | +# This program is distributed in the hope that it will be useful, |
1034 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1035 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1036 | +# GNU General Public License for more details. |
1037 | +# |
1038 | +# You should have received a copy of the GNU General Public License along |
1039 | +# with this program; if not, write to the Free Software Foundation, Inc., |
1040 | +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
1041 | +#--------------------------------------------------------------------- |
1042 | + |
1043 | +#--------------------------------------------------------------------- |
1044 | +# Description: unit-tests for the CGManager() object |
1045 | +# |
1046 | +#--------------------------------------------------------------------- |
1047 | + |
1048 | +import os |
1049 | +import sys |
1050 | +import tempfile |
1051 | +import unittest |
1052 | + |
1053 | +base_dir = os.path.abspath(os.path.dirname(__file__)) |
1054 | +module_dir = os.path.normpath(os.path.realpath(base_dir + os.sep + '..')) |
1055 | + |
1056 | +# top-level unpacked source directory |
1057 | +top_srcdir = os.path.normpath(os.path.realpath(module_dir + os.sep + '..')) |
1058 | + |
1059 | +# Tell Python where the uninstalled module lives in the source tree |
1060 | +sys.path.append(module_dir) |
1061 | +from pyupstart import * |
1062 | + |
1063 | +class TestCGManager(unittest.TestCase): |
1064 | + def setUp(self): |
1065 | + self.cg = CGManager() |
1066 | + self.tempfile = tempfile.NamedTemporaryFile(prefix='TestCGManager') |
1067 | + self.tempname = os.path.split(self.tempfile.name)[-1] |
1068 | + |
1069 | + def test_init(self): |
1070 | + self.assertRaises(CGMException, self.cg.connect, ()) |
1071 | + |
1072 | + def test_api_version(self): |
1073 | + self.assertEqual(self.cg.api_version(), 2) |
1074 | + |
1075 | + def test_setup_sandbox(self): |
1076 | + pid = os.getpid() |
1077 | + self.cg.setup_sandbox(self.tempname, pid) |
1078 | + with open('/proc/self/cgroup') as f: |
1079 | + missing = [l for l in f.readlines() if self.tempname not in l] |
1080 | + self.assertEqual(len(missing), 1) |
1081 | + self.assertTrue("name=systemd" in missing[0]) |
1082 | + |
1083 | +if __name__ == '__main__': |
1084 | + main() |
1085 | |
1086 | === modified file 'scripts/tests/test_pyupstart_session_init.py' |
1087 | --- scripts/tests/test_pyupstart_session_init.py 2014-03-05 10:41:18 +0000 |
1088 | +++ scripts/tests/test_pyupstart_session_init.py 2014-04-08 20:51:56 +0000 |
1089 | @@ -539,31 +539,5 @@ |
1090 | self.assertEqual(path, full_job_path) |
1091 | self.stop_session_init() |
1092 | |
1093 | -def main(): |
1094 | - kwargs = {} |
1095 | - format = \ |
1096 | - '%(asctime)s:' \ |
1097 | - '%(filename)s:' \ |
1098 | - '%(name)s:' \ |
1099 | - '%(funcName)s:' \ |
1100 | - '%(levelname)s:' \ |
1101 | - '%(message)s' |
1102 | - |
1103 | - kwargs['format'] = format |
1104 | - |
1105 | - # We want to see what's happening |
1106 | - kwargs['level'] = logging.DEBUG |
1107 | - |
1108 | - logging.basicConfig(**kwargs) |
1109 | - |
1110 | - unittest.main( |
1111 | - testRunner=unittest.TextTestRunner( |
1112 | - stream=sys.stdout, |
1113 | - verbosity=2 |
1114 | - ) |
1115 | - ) |
1116 | - |
1117 | - sys.exit(0) |
1118 | - |
1119 | if __name__ == '__main__': |
1120 | main() |
1121 | |
1122 | === added file 'scripts/tests/test_pyupstart_system_cgroups.py' |
1123 | --- scripts/tests/test_pyupstart_system_cgroups.py 1970-01-01 00:00:00 +0000 |
1124 | +++ scripts/tests/test_pyupstart_system_cgroups.py 2014-04-08 20:51:56 +0000 |
1125 | @@ -0,0 +1,73 @@ |
1126 | +#!/usr/bin/python3 |
1127 | +# -*- coding: utf-8 -*- |
1128 | +#--------------------------------------------------------------------- |
1129 | +# Copyright © 2014 Canonical Ltd. |
1130 | +# |
1131 | +# Author: Dimitri John Ledkov <xnox@ubuntu.com> |
1132 | +# |
1133 | +# This program is free software; you can redistribute it and/or modify |
1134 | +# it under the terms of the GNU General Public License version 2, as |
1135 | +# published by the Free Software Foundation. |
1136 | +# |
1137 | +# This program is distributed in the hope that it will be useful, |
1138 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1139 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1140 | +# GNU General Public License for more details. |
1141 | +# |
1142 | +# You should have received a copy of the GNU General Public License along |
1143 | +# with this program; if not, write to the Free Software Foundation, Inc., |
1144 | +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
1145 | +#--------------------------------------------------------------------- |
1146 | + |
1147 | +#--------------------------------------------------------------------- |
1148 | +# Description: unit-tests for the CGManager() object |
1149 | +# |
1150 | +#--------------------------------------------------------------------- |
1151 | + |
1152 | +import os |
1153 | +import sys |
1154 | +import tempfile |
1155 | +import unittest |
1156 | + |
1157 | +base_dir = os.path.abspath(os.path.dirname(__file__)) |
1158 | +module_dir = os.path.normpath(os.path.realpath(base_dir + os.sep + '..')) |
1159 | + |
1160 | +# top-level unpacked source directory |
1161 | +top_srcdir = os.path.normpath(os.path.realpath(module_dir + os.sep + '..')) |
1162 | + |
1163 | +# Tell Python where the uninstalled module lives in the source tree |
1164 | +sys.path.append(module_dir) |
1165 | +from pyupstart import * |
1166 | +from tests.test_pyupstart_system_init import TestSystemUpstart |
1167 | + |
1168 | +class TestSystemCGManager(TestSystemUpstart): |
1169 | + def setUp(self): |
1170 | + self.cg = CGManager() |
1171 | + self.tempfile = tempfile.NamedTemporaryFile(prefix='TestSystemCGManager') |
1172 | + self.tempname = os.path.split(self.tempfile.name)[-1] |
1173 | + self.cg.setup_sandbox(self.tempname, 1) |
1174 | + self.sample_job = [ "cgroup {} {}".format(cgroup, self.tempname) |
1175 | + for cgroup in self.cg.all_cgroups ] |
1176 | + self.sample_job.append('exec upstart-udev-bridge') |
1177 | + super().setUp() |
1178 | + |
1179 | + def test_main(self): |
1180 | + job = self.upstart.job_create('main', self.sample_job) |
1181 | + job.start(wait=True) |
1182 | + self._assert_all_match(job.pids()['main']) |
1183 | + |
1184 | + def test_pre_start(self): |
1185 | + self.sample_job.append('pre-start exec cat /proc/self/cgroup') |
1186 | + job = self.upstart.job_create('pre-start', self.sample_job) |
1187 | + job.start() |
1188 | + print(job.logfile_name()) |
1189 | + # Kaboom! |
1190 | + |
1191 | + def _assert_all_match(self, pid): |
1192 | + for c in self.cg.all_cgroups: |
1193 | + self.assertEqual( |
1194 | + self.cg.GetPidCgroup(c, pid), |
1195 | + self.tempname) |
1196 | + |
1197 | +if __name__ == '__main__': |
1198 | + main() |
1199 | |
1200 | === modified file 'scripts/tests/test_pyupstart_system_init.py' |
1201 | --- scripts/tests/test_pyupstart_system_init.py 2014-03-10 13:43:50 +0000 |
1202 | +++ scripts/tests/test_pyupstart_system_init.py 2014-04-08 20:51:56 +0000 |
1203 | @@ -167,31 +167,6 @@ |
1204 | self.upstart.polling_connect(force=True) |
1205 | self.assertTrue(self.upstart.version()) |
1206 | |
1207 | -def main(): |
1208 | - kwargs = {} |
1209 | - format = \ |
1210 | - '%(asctime)s:' \ |
1211 | - '%(filename)s:' \ |
1212 | - '%(name)s:' \ |
1213 | - '%(funcName)s:' \ |
1214 | - '%(levelname)s:' \ |
1215 | - '%(message)s' |
1216 | - |
1217 | - kwargs['format'] = format |
1218 | - |
1219 | - # We want to see what's happening |
1220 | - kwargs['level'] = logging.DEBUG |
1221 | - |
1222 | - logging.basicConfig(**kwargs) |
1223 | - |
1224 | - unittest.main( |
1225 | - testRunner=unittest.TextTestRunner( |
1226 | - stream=sys.stdout, |
1227 | - verbosity=2 |
1228 | - ) |
1229 | - ) |
1230 | - |
1231 | - sys.exit(0) |
1232 | |
1233 | if __name__ == '__main__': |
1234 | main() |
This fixes a bunch of test_job and test_job_process test suite failures. Mostly it's adjusting state expectations in the test-suite, but also fixes JOB_PRE_STOP_SETUP -> JOB_PRE_STOP transition and updates the asserts in the job_process (once we are in the process failure handler, the relevant process has completed the setup and thus is in the "full" state, as far as I understand it)