Merge lp:~xnox/upstart/async-no-process-run into lp:upstart/async

Proposed by Dimitri John Ledkov
Status: Merged
Merged at revision: 1652
Proposed branch: lp:~xnox/upstart/async-no-process-run
Merge into: lp:upstart/async
Prerequisite: lp:~xnox/upstart/async-failed-pid-to-zero
Diff against target: 1307 lines (+177/-428)
5 files modified
init/job_process.c (+0/-228)
init/job_process.h (+1/-5)
init/tests/test_job.c (+2/-15)
init/tests/test_job_process.c (+139/-180)
test/test_util_common.h (+35/-0)
To merge this branch: bzr merge lp:~xnox/upstart/async-no-process-run
Reviewer Review Type Date Requested Status
James Hunt Pending
Review via email: mp+220540@code.launchpad.net

This proposal supersedes a proposal from 2014-05-21.

To post a comment you must log in.
Revision history for this message
Dimitri John Ledkov (xnox) wrote : Posted in a previous version of this proposal

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'init/job_process.c'
2--- init/job_process.c 2014-05-21 16:52:42 +0000
3+++ init/job_process.c 2014-05-21 22:55:26 +0000
4@@ -149,234 +149,6 @@
5 extern int session_end;
6 extern time_t quiesce_phase_time;
7
8-/**
9- * job_process_run:
10- * @job: job context for process to be run in,
11- * @process: job process to run.
12- *
13- * This function looks up @process in the job's process table and uses
14- * the information there to spawn a new process for the @job, storing the
15- * pid in that table entry.
16- *
17- * The process is normally executed using the system shell, unless the
18- * script member of @process is FALSE and there are no typical shell
19- * characters within the command member, in which case it is executed
20- * directly using exec after splitting on whitespace.
21- *
22- * When executed with the shell, if the command (which may be an entire
23- * script) is reasonably small (less than 1KB) it is passed to the
24- * shell using the POSIX-specified -c option. Otherwise the shell is told
25- * to read commands from one of the special /proc/self/fd/NN devices and NihIo
26- * used to feed the script into that device. A pointer to the NihIo object
27- * is not kept or stored because it will automatically clean itself up should
28- * the script go away as the other end of the pipe will be closed.
29- *
30- * In either case the shell is run with the -e option so that commands will
31- * fail if their exit status is not checked.
32- *
33- * This function will block until the job_process_spawn() call succeeds or
34- * a non-temporary error occurs (such as file not found). It is up to the
35- * called to decide whether non-temporary errors are a reason to change the
36- * job state or not.
37- *
38- * Returns: zero on success, negative value on non-temporary error.
39- **/
40-int
41-job_process_run (Job *job,
42- ProcessType process)
43-{
44- Process *proc;
45- nih_local char **argv = NULL;
46- nih_local char **env = NULL;
47- nih_local char *script = NULL;
48- char **e;
49- size_t argc, envc;
50- int fds[2] = { -1, -1 };
51- int error = FALSE, trace = FALSE, shell = FALSE;
52-
53- nih_assert (job != NULL);
54-
55- proc = job->class->process[process];
56- nih_assert (proc != NULL);
57- nih_assert (proc->command != NULL);
58-
59- /* We run the process using a shell if it says it wants to be run
60- * as such, or if it contains any shell-like characters; since that's
61- * the best way to deal with things like variables.
62- */
63- if ((proc->script) || strpbrk (proc->command, SHELL_CHARS)) {
64- char *nl, *p;
65-
66- argc = 0;
67- argv = NIH_MUST (nih_str_array_new (NULL));
68-
69- NIH_MUST (nih_str_array_add (&argv, NULL, &argc, SHELL));
70- NIH_MUST (nih_str_array_add (&argv, NULL, &argc, "-e"));
71-
72- /* If the process wasn't originally marked to be run through
73- * a shell, prepend exec to the script so that the shell
74- * gets out of the way after parsing.
75- */
76- if (proc->script) {
77- script = NIH_MUST (nih_strdup (NULL, proc->command));
78- } else {
79- script = NIH_MUST (nih_sprintf (NULL, "exec %s",
80- proc->command));
81- }
82-
83- /* Don't pipe single-line scripts into the shell using
84- * /proc/self/fd/NNN, instead just pass them over the
85- * command-line (taking care to strip off the trailing
86- * newlines).
87- */
88- p = nl = strchr (script, '\n');
89- while (p && (*p == '\n'))
90- p++;
91-
92- if ((! nl) || (! *p)) {
93- /* Strip off the newline(s) */
94- if (nl)
95- *nl = '\0';
96-
97- NIH_MUST (nih_str_array_add (&argv, NULL,
98- &argc, "-c"));
99- NIH_MUST (nih_str_array_addp (&argv, NULL,
100- &argc, script));
101-
102- /* Next argument is argv[0]; just pass the shell */
103- NIH_MUST (nih_str_array_add (&argv, NULL,
104- &argc, SHELL));
105- } else {
106- nih_local char *cmd = NULL;
107-
108- /* Close the writing end when the child is exec'd */
109- NIH_ZERO (pipe (fds));
110- nih_io_set_cloexec (fds[1]);
111-
112- shell = TRUE;
113-
114- cmd = NIH_MUST (nih_sprintf (argv, "%s/%d",
115- "/proc/self/fd",
116- JOB_PROCESS_SCRIPT_FD));
117- NIH_MUST (nih_str_array_addp (&argv, NULL,
118- &argc, cmd));
119- }
120- } else {
121- /* Split the command on whitespace to produce a list of
122- * arguments that we can exec directly.
123- */
124- argv = NIH_MUST (nih_str_split (NULL, proc->command,
125- " \t\r\n", TRUE));
126- }
127-
128- /* We provide the standard job environment to all of its processes,
129- * except for pre-stop which also has the stop event environment,
130- * adding special variables that indicate which job it was -- mostly
131- * so that initctl can have clever behaviour when called within them.
132- */
133- envc = 0;
134- env = NIH_MUST (nih_str_array_new (NULL));
135-
136- if (job->env)
137- NIH_MUST (environ_append (&env, NULL, &envc, TRUE, job->env));
138-
139- if (job->stop_env
140- && ((process == PROCESS_PRE_STOP)
141- || (process == PROCESS_POST_STOP)))
142- for (e = job->stop_env; *e; e++)
143- NIH_MUST (environ_set (&env, NULL, &envc, TRUE, *e));
144-
145- NIH_MUST (environ_set (&env, NULL, &envc, TRUE,
146- "UPSTART_JOB=%s", job->class->name));
147- NIH_MUST (environ_set (&env, NULL, &envc, TRUE,
148- "UPSTART_INSTANCE=%s", job->name));
149- if (user_mode)
150- NIH_MUST (environ_set (&env, NULL, &envc, TRUE,
151- "UPSTART_SESSION=%s", control_server_address));
152-
153- /* If we're about to spawn the main job and we expect it to become
154- * a daemon or fork before we can move out of spawned, we need to
155- * set a trace on it.
156- */
157- if ((process == PROCESS_MAIN)
158- && ((job->class->expect == EXPECT_DAEMON)
159- || (job->class->expect == EXPECT_FORK)))
160- trace = TRUE;
161-
162- /* Spawn the process, repeat until fork() works */
163- while ((job->pid[process] = job_process_spawn (job, argv, env,
164- trace, fds[0], process)) < 0) {
165- NihError *err;
166-
167- err = nih_error_get ();
168- if (err->number == JOB_PROCESS_ERROR) {
169- /* Non-temporary error condition, we're not going
170- * to be able to spawn this process. Clean up after
171- * ourselves before returning.
172- */
173- if (shell) {
174- close (fds[0]);
175- close (fds[1]);
176- }
177-
178- job->pid[process] = 0;
179-
180- /* Return non-temporary error condition */
181- nih_warn (_("Failed to spawn %s %s process: %s"),
182- job_name (job), process_name (process),
183- err->message);
184- nih_free (err);
185- return -1;
186- } else if (! error)
187- nih_warn ("%s: %s", _("Temporary process spawn error"),
188- err->message);
189- nih_free (err);
190-
191- error = TRUE;
192- }
193-
194- nih_info (_("%s %s process (%d)"),
195- job_name (job), process_name (process), job->pid[process]);
196-
197- job->trace_forks = 0;
198- job->trace_state = trace ? TRACE_NEW : TRACE_NONE;
199-
200- /* Feed the script to the child process */
201- if (shell) {
202- NihIo *io;
203-
204- /* Clean up and close the reading end (we don't need it) */
205- close (fds[0]);
206-
207- /* Put the entire script into an NihIo send buffer and
208- * then mark it for closure so that the shell gets EOF
209- * and the structure gets cleaned up automatically.
210- */
211- while (! (io = nih_io_reopen (job, fds[1], NIH_IO_STREAM,
212- NULL, NULL, NULL, NULL))) {
213- NihError *err;
214-
215- err = nih_error_get ();
216- if (err->number != ENOMEM)
217- nih_assert_not_reached ();
218- nih_free (err);
219- }
220-
221- /* We're feeding using a pipe, which has a file descriptor
222- * on the child end even though it open()s it again using
223- * a path. Instruct the shell to close this extra fd and
224- * not to leak it.
225- */
226- NIH_ZERO (nih_io_printf (io, "exec %d<&-\n",
227- JOB_PROCESS_SCRIPT_FD));
228-
229- NIH_ZERO (nih_io_write (io, script, strlen (script)));
230- nih_io_shutdown (io);
231- }
232-
233- return 0;
234-}
235-
236
237 /**
238 * job_process_spawn:
239
240=== modified file 'init/job_process.h'
241--- init/job_process.h 2014-05-15 09:43:13 +0000
242+++ init/job_process.h 2014-05-21 22:55:26 +0000
243@@ -138,11 +138,7 @@
244
245 NIH_BEGIN_EXTERN
246
247-int job_process_run (Job *job, ProcessType process);
248-void
249-job_process_start (Job *job,
250- ProcessType process);
251-
252+void job_process_start (Job *job, ProcessType process);
253 void job_process_run_bottom (JobProcessData *handler_data);
254
255 void job_process_child_reader (JobProcessData *handler_data, NihIo *io,
256
257=== modified file 'init/tests/test_job.c'
258--- init/tests/test_job.c 2014-05-21 22:55:26 +0000
259+++ init/tests/test_job.c 2014-05-21 22:55:26 +0000
260@@ -60,6 +60,7 @@
261 #include "conf.h"
262 #include "control.h"
263 #include "state.h"
264+#include "test_util_common.h"
265
266 void
267 job_quit_with_state (void *data, NihMainLoopFunc *loop)
268@@ -69,12 +70,6 @@
269 nih_main_loop_exit (job->state);
270 }
271
272-void
273-timeout_quit_zero (void *data, NihTimerCb *timer)
274-{
275- nih_main_loop_exit (0);
276-}
277-
278 char *argv0;
279
280 static int state_fd = -1;
281@@ -3244,10 +3239,7 @@
282 TEST_FEATURE ("killed to post-stop for failed process");
283 tmp = class->process[PROCESS_POST_STOP];
284 class->process[PROCESS_POST_STOP] = fail;
285- NihTimer * timer;
286
287- /* FIXME this is very slow, as we wait 1s per TEST_ALLOC_FAIL itteration... */
288- nih_message (" Running. Respect the timer.");
289 TEST_ALLOC_FAIL {
290 TEST_ALLOC_SAFE {
291 job = job_new (class, "");
292@@ -3255,7 +3247,6 @@
293 blocked = blocked_new (job, BLOCKED_EVENT, cause);
294 event_block (cause);
295 nih_list_add (&job->blocking, &blocked->entry);
296- timer = nih_timer_add_timeout (NULL, 1, (NihTimerCb)timeout_quit_zero, NULL);
297 }
298
299 job->goal = JOB_START;
300@@ -3272,16 +3263,12 @@
301
302 TEST_FREE_TAG (job);
303
304- TEST_FREE_TAG (timer);
305-
306 TEST_DIVERT_STDERR (output) {
307 job_change_state (job, JOB_POST_STOPPING);
308- nih_main_loop ();
309+ TEST_WATCH_LOOP ();
310 }
311 rewind (output);
312
313- TEST_FREE (timer);
314-
315 TEST_FREE (job);
316
317 TEST_EQ (cause->blockers, 0);
318
319=== modified file 'init/tests/test_job_process.c'
320--- init/tests/test_job_process.c 2014-05-19 17:21:16 +0000
321+++ init/tests/test_job_process.c 2014-05-21 22:55:26 +0000
322@@ -385,7 +385,7 @@
323 * (Such tests are handled in the bundled test_user_sessions.sh script).
324 */
325 void
326-test_run (void)
327+test_start (void)
328 {
329 char dirname[PATH_MAX];
330 JobClass *class = NULL;
331@@ -394,7 +394,7 @@
332 struct stat statbuf;
333 char filename[PATH_MAX], buf[80];
334 char function[PATH_MAX];
335- int ret = -1, status, first;
336+ int status;
337 siginfo_t info;
338 char filebuf[1024];
339 struct passwd *pwd;
340@@ -409,7 +409,7 @@
341 log_unflushed_init ();
342 job_class_init ();
343
344- TEST_FUNCTION ("job_process_run");
345+ TEST_FUNCTION ("job_process_start");
346
347 TEST_FILENAME (filename);
348 program_name = "test";
349@@ -443,8 +443,7 @@
350 job->state = JOB_SPAWNED;
351 }
352
353- ret = job_process_run (job, PROCESS_MAIN);
354- TEST_EQ (ret, 0);
355+ job_process_start (job, PROCESS_MAIN);
356
357 TEST_NE (job->pid[PROCESS_MAIN], 0);
358
359@@ -478,8 +477,7 @@
360 job->state = JOB_SPAWNED;
361 }
362
363- ret = job_process_run (job, PROCESS_MAIN);
364- TEST_EQ (ret, 0);
365+ job_process_start (job, PROCESS_MAIN);
366
367 TEST_NE (job->pid[PROCESS_MAIN], 0);
368
369@@ -520,8 +518,7 @@
370 job->state = JOB_SPAWNED;
371 }
372
373- ret = job_process_run (job, PROCESS_MAIN);
374- TEST_EQ (ret, 0);
375+ job_process_start (job, PROCESS_MAIN);
376
377 TEST_NE (job->pid[PROCESS_MAIN], 0);
378
379@@ -560,8 +557,7 @@
380 job->state = JOB_SPAWNED;
381 }
382
383- ret = job_process_run (job, PROCESS_MAIN);
384- TEST_EQ (ret, 0);
385+ job_process_start (job, PROCESS_MAIN);
386
387 TEST_NE (job->pid[PROCESS_MAIN], 0);
388
389@@ -601,8 +597,7 @@
390 job->state = JOB_SPAWNED;
391 }
392
393- ret = job_process_run (job, PROCESS_MAIN);
394- TEST_EQ (ret, 0);
395+ job_process_start (job, PROCESS_MAIN);
396
397 TEST_NE (job->pid[PROCESS_MAIN], 0);
398
399@@ -648,8 +643,7 @@
400 "CRACKLE=FIZZ"));
401 }
402
403- ret = job_process_run (job, PROCESS_MAIN);
404- TEST_EQ (ret, 0);
405+ job_process_start (job, PROCESS_MAIN);
406
407 TEST_NE (job->pid[PROCESS_MAIN], 0);
408
409@@ -704,8 +698,7 @@
410 "CRACKLE=FIZZ"));
411 }
412
413- ret = job_process_run (job, PROCESS_MAIN);
414- TEST_EQ (ret, 0);
415+ job_process_start (job, PROCESS_MAIN);
416
417 TEST_NE (job->pid[PROCESS_MAIN], 0);
418
419@@ -761,8 +754,7 @@
420 "CRACKLE=FIZZ"));
421 }
422
423- ret = job_process_run (job, PROCESS_PRE_STOP);
424- TEST_EQ (ret, 0);
425+ job_process_start (job, PROCESS_PRE_STOP);
426
427 TEST_NE (job->pid[PROCESS_PRE_STOP], 0);
428
429@@ -819,8 +811,7 @@
430 "CRACKLE=FIZZ"));
431 }
432
433- ret = job_process_run (job, PROCESS_POST_STOP);
434- TEST_EQ (ret, 0);
435+ job_process_start (job, PROCESS_POST_STOP);
436
437 TEST_NE (job->pid[PROCESS_POST_STOP], 0);
438
439@@ -870,36 +861,11 @@
440 job->state = JOB_SPAWNED;
441 }
442
443- ret = job_process_run (job, PROCESS_MAIN);
444- TEST_EQ (ret, 0);
445+ job_process_start (job, PROCESS_MAIN);
446
447 TEST_NE (job->pid[PROCESS_MAIN], 0);
448
449- /* Loop until we've fed all of the data. */
450- first = TRUE;
451- for (;;) {
452- fd_set readfds, writefds, exceptfds;
453- int nfds;
454-
455- nfds = 0;
456- FD_ZERO (&readfds);
457- FD_ZERO (&writefds);
458- FD_ZERO (&exceptfds);
459-
460- nih_io_select_fds (&nfds, &readfds,
461- &writefds, &exceptfds);
462- if (! nfds) {
463- if (first)
464- TEST_FAILED ("expected to have "
465- "data to feed.");
466- break;
467- }
468- first = FALSE;
469-
470- select (nfds, &readfds, &writefds, &exceptfds, NULL);
471-
472- nih_io_handle_fds (&readfds, &writefds, &exceptfds);
473- }
474+ TEST_WATCH_LOOP ();
475
476 waitpid (job->pid[PROCESS_MAIN], &status, 0);
477 TEST_TRUE (WIFEXITED (status));
478@@ -938,8 +904,7 @@
479 job->trace_state = TRACE_NORMAL;
480 }
481
482- ret = job_process_run (job, PROCESS_MAIN);
483- TEST_EQ (ret, 0);
484+ job_process_start (job, PROCESS_MAIN);
485
486 TEST_EQ (job->trace_forks, 0);
487 TEST_EQ (job->trace_state, TRACE_NONE);
488@@ -978,8 +943,7 @@
489 job->trace_state = TRACE_NORMAL;
490 }
491
492- ret = job_process_run (job, PROCESS_PRE_START);
493- TEST_EQ (ret, 0);
494+ job_process_start (job, PROCESS_PRE_START);
495
496 TEST_EQ (job->trace_forks, 0);
497 TEST_EQ (job->trace_state, TRACE_NONE);
498@@ -1020,8 +984,7 @@
499 job->trace_state = TRACE_NORMAL;
500 }
501
502- ret = job_process_run (job, PROCESS_MAIN);
503- TEST_EQ (ret, 0);
504+ job_process_start (job, PROCESS_MAIN);
505
506 TEST_EQ (job->trace_forks, 0);
507 TEST_EQ (job->trace_state, TRACE_NEW);
508@@ -1071,8 +1034,7 @@
509 job->trace_state = TRACE_NORMAL;
510 }
511
512- ret = job_process_run (job, PROCESS_MAIN);
513- TEST_EQ (ret, 0);
514+ job_process_start (job, PROCESS_MAIN);
515
516 TEST_EQ (job->trace_forks, 0);
517 TEST_EQ (job->trace_state, TRACE_NEW);
518@@ -1098,7 +1060,7 @@
519 }
520
521 /* Check that if we try and run a command that doesn't exist,
522- * job_process_run() raises a ProcessError and the command doesn't
523+ * job_process_start() raises a ProcessError and the command doesn't
524 * have any stored process id for it.
525 */
526 TEST_FEATURE ("with no such file");
527@@ -1120,11 +1082,12 @@
528 }
529
530 TEST_DIVERT_STDERR (output) {
531- ret = job_process_run (job, PROCESS_MAIN);
532+ job_process_start (job, PROCESS_MAIN);
533+ TEST_WATCH_LOOP ();
534+ event_poll ();
535 }
536 rewind (output);
537- TEST_LT (ret, 0);
538-
539+
540 TEST_EQ (job->pid[PROCESS_MAIN], 0);
541
542 TEST_FILE_EQ (output, ("test: Failed to spawn test (foo) main "
543@@ -1171,8 +1134,7 @@
544 job->goal = JOB_START;
545 job->state = JOB_SPAWNED;
546
547- ret = job_process_run (job, PROCESS_MAIN);
548- TEST_EQ (ret, 0);
549+ job_process_start (job, PROCESS_MAIN);
550
551 TEST_NE (job->pid[PROCESS_MAIN], 0);
552
553@@ -1239,8 +1201,7 @@
554 job->goal = JOB_START;
555 job->state = JOB_SPAWNED;
556
557- ret = job_process_run (job, PROCESS_MAIN);
558- TEST_EQ (ret, 0);
559+ job_process_start (job, PROCESS_MAIN);
560
561 TEST_NE (job->pid[PROCESS_MAIN], 0);
562
563@@ -1307,8 +1268,7 @@
564 job->goal = JOB_START;
565 job->state = JOB_SPAWNED;
566
567- ret = job_process_run (job, PROCESS_MAIN);
568- TEST_EQ (ret, 0);
569+ job_process_start (job, PROCESS_MAIN);
570
571 TEST_NE (job->pid[PROCESS_MAIN], 0);
572
573@@ -1375,8 +1335,7 @@
574 job->goal = JOB_START;
575 job->state = JOB_SPAWNED;
576
577- ret = job_process_run (job, PROCESS_MAIN);
578- TEST_EQ (ret, 0);
579+ job_process_start (job, PROCESS_MAIN);
580
581 TEST_NE (job->pid[PROCESS_MAIN], 0);
582
583@@ -1438,8 +1397,7 @@
584 job->goal = JOB_START;
585 job->state = JOB_SPAWNED;
586
587- ret = job_process_run (job, PROCESS_MAIN);
588- TEST_EQ (ret, 0);
589+ job_process_start (job, PROCESS_MAIN);
590
591 TEST_NE (job->pid[PROCESS_MAIN], 0);
592
593@@ -1475,8 +1433,7 @@
594 job->goal = JOB_START;
595 job->state = JOB_SPAWNED;
596
597- ret = job_process_run (job, PROCESS_MAIN);
598- TEST_EQ (ret, 0);
599+ job_process_start (job, PROCESS_MAIN);
600
601 TEST_NE (job->pid[PROCESS_MAIN], 0);
602
603@@ -1512,8 +1469,7 @@
604 job->goal = JOB_START;
605 job->state = JOB_SPAWNED;
606
607- ret = job_process_run (job, PROCESS_MAIN);
608- TEST_EQ (ret, 0);
609+ job_process_start (job, PROCESS_MAIN);
610
611 TEST_NE (job->pid[PROCESS_MAIN], 0);
612
613@@ -1559,11 +1515,13 @@
614 job->goal = JOB_START;
615 job->state = JOB_SPAWNED;
616
617- ret = job_process_run (job, PROCESS_MAIN);
618- TEST_EQ (ret, 0);
619+ job_process_start (job, PROCESS_MAIN);
620
621 TEST_NE (job->pid[PROCESS_MAIN], 0);
622
623+ /* XXX: call 0: async process setup */
624+ TEST_WATCH_UPDATE ();
625+
626 /* XXX: call 1: wait for script write to child shell */
627 TEST_WATCH_UPDATE ();
628
629@@ -1589,10 +1547,10 @@
630
631 /* Note we can't use TEST_ALLOC_FAIL() for this test since on
632 * the ENOMEM loop all we could do is discard the error and
633- * continue since job_process_run() calls job_process_spawn()
634+ * continue since job_process_start() calls job_process_spawn()
635 * repeatedly until it works, but the alloc fails in log_new()
636 * invoked by job_process_spawn() such that when we've left
637- * job_process_run(), it's too late.
638+ * job_process_start(), it's too late.
639 *
640 * However, we test this scenario in test_spawn() so all is not
641 * lost.
642@@ -1613,8 +1571,7 @@
643 job->goal = JOB_START;
644 job->state = JOB_SPAWNED;
645
646- ret = job_process_run (job, PROCESS_MAIN);
647- TEST_EQ (ret, 0);
648+ job_process_start (job, PROCESS_MAIN);
649
650 TEST_NE (job->pid[PROCESS_MAIN], 0);
651
652@@ -1671,11 +1628,13 @@
653 job->goal = JOB_START;
654 job->state = JOB_SPAWNED;
655
656- ret = job_process_run (job, PROCESS_MAIN);
657- TEST_EQ (ret, 0);
658+ job_process_start (job, PROCESS_MAIN);
659
660 TEST_NE (job->pid[PROCESS_MAIN], 0);
661
662+ /* wait for process to setup */
663+ TEST_WATCH_UPDATE ();
664+
665 /* wait for read from pty allowing logger to write to log file */
666 TEST_WATCH_UPDATE ();
667
668@@ -1755,11 +1714,13 @@
669 job->goal = JOB_START;
670 job->state = JOB_SPAWNED;
671
672- ret = job_process_run (job, PROCESS_MAIN);
673- TEST_EQ (ret, 0);
674+ job_process_start (job, PROCESS_MAIN);
675
676 TEST_NE (job->pid[PROCESS_MAIN], 0);
677
678+ /* wait for process to setup */
679+ TEST_WATCH_UPDATE ();
680+
681 /* wait for read from pty allowing logger to write to log file */
682 TEST_WATCH_UPDATE ();
683
684@@ -1837,10 +1798,10 @@
685
686 /* Note we can't use TEST_ALLOC_FAIL() for this test since on
687 * the ENOMEM loop all we could do is discard the error and
688- * continue since job_process_run() calls job_process_spawn()
689+ * continue since job_process_start() calls job_process_spawn()
690 * repeatedly until it works, but the alloc fails in log_new()
691 * invoked by job_process_spawn() such that when we've left
692- * job_process_run(), it's too late.
693+ * job_process_start(), it's too late.
694 *
695 * However, we test this scenario in test_spawn() so all is not
696 * lost.
697@@ -1861,11 +1822,13 @@
698 job->goal = JOB_START;
699 job->state = JOB_SPAWNED;
700
701- ret = job_process_run (job, PROCESS_MAIN);
702- TEST_EQ (ret, 0);
703+ job_process_start (job, PROCESS_MAIN);
704
705 TEST_NE (job->pid[PROCESS_MAIN], 0);
706
707+ /* wait for process to setup */
708+ TEST_WATCH_UPDATE ();
709+
710 /* XXX: call 1: wait for script write to child shell */
711 TEST_WATCH_UPDATE ();
712
713@@ -1924,11 +1887,13 @@
714 job->goal = JOB_START;
715 job->state = JOB_SPAWNED;
716
717- ret = job_process_run (job, PROCESS_MAIN);
718- TEST_EQ (ret, 0);
719+ job_process_start (job, PROCESS_MAIN);
720
721 TEST_NE (job->pid[PROCESS_MAIN], 0);
722
723+ /* wait for process to setup */
724+ TEST_WATCH_UPDATE ();
725+
726 /* wait for read from pty allowing logger to write to log file */
727 TEST_WATCH_UPDATE ();
728
729@@ -1993,11 +1958,13 @@
730 job->goal = JOB_START;
731 job->state = JOB_SPAWNED;
732
733- ret = job_process_run (job, PROCESS_MAIN);
734- TEST_EQ (ret, 0);
735+ job_process_start (job, PROCESS_MAIN);
736
737 TEST_NE (job->pid[PROCESS_MAIN], 0);
738
739+ /* wait for process to setup */
740+ TEST_WATCH_UPDATE ();
741+
742 /* XXX: call 1: wait for script write to child shell */
743 TEST_WATCH_UPDATE ();
744
745@@ -2040,10 +2007,10 @@
746
747 /* Note we can't use TEST_ALLOC_FAIL() for this test since on
748 * the ENOMEM loop all we could do is discard the error and
749- * continue since job_process_run() calls job_process_spawn()
750+ * continue since job_process_start() calls job_process_spawn()
751 * repeatedly until it works, but the alloc fails in log_new()
752 * invoked by job_process_spawn() such that when we've left
753- * job_process_run(), it's too late.
754+ * job_process_start(), it's too late.
755 *
756 * However, we test this scenario in test_spawn() so all is not
757 * lost.
758@@ -2064,8 +2031,7 @@
759 job->goal = JOB_START;
760 job->state = JOB_SPAWNED;
761
762- ret = job_process_run (job, PROCESS_MAIN);
763- TEST_EQ (ret, 0);
764+ job_process_start (job, PROCESS_MAIN);
765
766 TEST_NE (job->pid[PROCESS_MAIN], 0);
767
768@@ -2111,7 +2077,7 @@
769 * XXX: TEST_WATCH_UPDATE() *TWICE* to ensure select(2) is
770 * XXX: called twice.
771 *
772- * This is required since job_process_run() uses an NihIo object
773+ * This is required since job_process_start() uses an NihIo object
774 * to squirt the script to the shell sub-process and this
775 * triggers select to return when the data is written to the shell.
776 * However, we don't care about that directly - we care more about
777@@ -2120,7 +2086,7 @@
778 * written.
779 *
780 * Note that the 2nd call to TEST_WATCH_UPDATE would not be
781- * required should job_process_run() simple invoke write(2) to
782+ * required should job_process_start() simple invoke write(2) to
783 * send the data.
784 */
785
786@@ -2141,11 +2107,13 @@
787 job->goal = JOB_START;
788 job->state = JOB_SPAWNED;
789
790- ret = job_process_run (job, PROCESS_MAIN);
791- TEST_EQ (ret, 0);
792+ job_process_start (job, PROCESS_MAIN);
793
794 TEST_NE (job->pid[PROCESS_MAIN], 0);
795
796+ /* wait for process to setup */
797+ TEST_WATCH_UPDATE ();
798+
799 /* XXX: call 1: wait for script write to child shell */
800 TEST_WATCH_UPDATE ();
801
802@@ -2203,8 +2171,7 @@
803 job->goal = JOB_START;
804 job->state = JOB_SPAWNED;
805
806- ret = job_process_run (job, PROCESS_MAIN);
807- TEST_EQ (ret, 0);
808+ job_process_start (job, PROCESS_MAIN);
809
810 TEST_NE (job->pid[PROCESS_MAIN], 0);
811
812@@ -2263,8 +2230,7 @@
813 job->goal = JOB_START;
814 job->state = JOB_SPAWNED;
815
816- ret = job_process_run (job, PROCESS_MAIN);
817- TEST_EQ (ret, 0);
818+ job_process_start (job, PROCESS_MAIN);
819
820 TEST_NE (job->pid[PROCESS_MAIN], 0);
821
822@@ -2328,8 +2294,7 @@
823 job->goal = JOB_START;
824 job->state = JOB_SPAWNED;
825
826- ret = job_process_run (job, PROCESS_MAIN);
827- TEST_EQ (ret, 0);
828+ job_process_start (job, PROCESS_MAIN);
829
830 TEST_NE (job->pid[PROCESS_MAIN], 0);
831
832@@ -2390,12 +2355,12 @@
833 job->goal = JOB_START;
834 job->state = JOB_SPAWNED;
835
836- ret = job_process_run (job, PROCESS_MAIN);
837- TEST_EQ (ret, 0);
838+ job_process_start (job, PROCESS_MAIN);
839
840 TEST_NE (job->pid[PROCESS_MAIN], 0);
841
842 TEST_WATCH_UPDATE ();
843+ TEST_WATCH_UPDATE ();
844 waitpid (job->pid[PROCESS_MAIN], &status, 0);
845 TEST_TRUE (WIFEXITED (status));
846 TEST_EQ (WEXITSTATUS (status), 0);
847@@ -2450,8 +2415,7 @@
848 job->goal = JOB_START;
849 job->state = JOB_SPAWNED;
850
851- ret = job_process_run (job, PROCESS_MAIN);
852- TEST_EQ (ret, 0);
853+ job_process_start (job, PROCESS_MAIN);
854
855 TEST_NE (job->pid[PROCESS_MAIN], 0);
856
857@@ -2513,8 +2477,7 @@
858 job->goal = JOB_START;
859 job->state = JOB_SPAWNED;
860
861- ret = job_process_run (job, PROCESS_MAIN);
862- TEST_EQ (ret, 0);
863+ job_process_start (job, PROCESS_MAIN);
864
865 TEST_NE (job->pid[PROCESS_MAIN], 0);
866
867@@ -2573,12 +2536,12 @@
868 job->goal = JOB_START;
869 job->state = JOB_SPAWNED;
870
871- ret = job_process_run (job, PROCESS_MAIN);
872- TEST_EQ (ret, 0);
873+ job_process_start (job, PROCESS_MAIN);
874
875 TEST_NE (job->pid[PROCESS_MAIN], 0);
876
877 TEST_WATCH_UPDATE ();
878+ TEST_WATCH_UPDATE ();
879
880 waitpid (job->pid[PROCESS_MAIN], &status, 0);
881 TEST_TRUE (WIFEXITED (status));
882@@ -2635,8 +2598,7 @@
883 job->goal = JOB_START;
884 job->state = JOB_SPAWNED;
885
886- ret = job_process_run (job, PROCESS_MAIN);
887- TEST_EQ (ret, 0);
888+ job_process_start (job, PROCESS_MAIN);
889
890 TEST_NE (job->pid[PROCESS_MAIN], 0);
891
892@@ -2701,8 +2663,7 @@
893 job->goal = JOB_START;
894 job->state = JOB_SPAWNED;
895
896- ret = job_process_run (job, PROCESS_MAIN);
897- TEST_EQ (ret, 0);
898+ job_process_start (job, PROCESS_MAIN);
899
900 TEST_NE (job->pid[PROCESS_MAIN], 0);
901
902@@ -2763,12 +2724,12 @@
903 job->goal = JOB_START;
904 job->state = JOB_SPAWNED;
905
906- ret = job_process_run (job, PROCESS_MAIN);
907- TEST_EQ (ret, 0);
908+ job_process_start (job, PROCESS_MAIN);
909
910 TEST_NE (job->pid[PROCESS_MAIN], 0);
911
912 TEST_WATCH_UPDATE ();
913+ TEST_WATCH_UPDATE ();
914
915 waitpid (job->pid[PROCESS_MAIN], &status, 0);
916 TEST_TRUE (WIFEXITED (status));
917@@ -2827,8 +2788,7 @@
918 job->goal = JOB_START;
919 job->state = JOB_SPAWNED;
920
921- ret = job_process_run (job, PROCESS_MAIN);
922- TEST_EQ (ret, 0);
923+ job_process_start (job, PROCESS_MAIN);
924
925 TEST_NE (job->pid[PROCESS_MAIN], 0);
926
927@@ -2889,8 +2849,7 @@
928 job->goal = JOB_START;
929 job->state = JOB_SPAWNED;
930
931- ret = job_process_run (job, PROCESS_MAIN);
932- TEST_EQ (ret, 0);
933+ job_process_start (job, PROCESS_MAIN);
934
935 TEST_NE (job->pid[PROCESS_MAIN], 0);
936
937@@ -2949,8 +2908,7 @@
938 job->goal = JOB_START;
939 job->state = JOB_SPAWNED;
940
941- ret = job_process_run (job, PROCESS_MAIN);
942- TEST_EQ (ret, 0);
943+ job_process_start (job, PROCESS_MAIN);
944
945 TEST_NE (job->pid[PROCESS_MAIN], 0);
946
947@@ -3013,8 +2971,7 @@
948 job->goal = JOB_START;
949 job->state = JOB_SPAWNED;
950
951- ret = job_process_run (job, PROCESS_MAIN);
952- TEST_EQ (ret, 0);
953+ job_process_start (job, PROCESS_MAIN);
954
955 TEST_NE (job->pid[PROCESS_MAIN], 0);
956
957@@ -3088,8 +3045,9 @@
958 output = tmpfile ();
959 TEST_NE_P (output, NULL);
960 TEST_DIVERT_STDERR (output) {
961- ret = job_process_run (job, PROCESS_MAIN);
962- TEST_LT (ret, 0);
963+ job_process_start (job, PROCESS_MAIN);
964+ TEST_WATCH_UPDATE ();
965+ event_poll ();
966 }
967 fclose (output);
968
969@@ -3137,8 +3095,8 @@
970 job->goal = JOB_START;
971 job->state = JOB_SPAWNED;
972
973- ret = job_process_run (job, PROCESS_MAIN);
974- TEST_LT (ret, 0);
975+ job_process_start (job, PROCESS_MAIN);
976+ TEST_WATCH_UPDATE ();
977
978 /* We don't expect a logfile to be written since there is no
979 * accompanying shell to write the error.
980@@ -3149,10 +3107,10 @@
981 job->goal = JOB_STOP;
982 job->state = JOB_POST_STOP;
983
984- ret = job_process_run (job, PROCESS_POST_STOP);
985- TEST_EQ (ret, 0);
986+ job_process_start (job, PROCESS_POST_STOP);
987
988 TEST_NE (job->pid[PROCESS_POST_STOP], 0);
989+ TEST_WATCH_UPDATE ();
990
991 /* Flush the io so that the shell on the client side
992 * gets the data (the script to execute).
993@@ -3163,8 +3121,11 @@
994 TEST_TRUE (WIFEXITED (status));
995 TEST_EQ (WEXITSTATUS (status), 0);
996
997+ TEST_WATCH_UPDATE ();
998+
999 /* .. but the post stop should have written data */
1000 TEST_EQ (stat (filename, &statbuf), 0);
1001+ event_poll ();
1002 }
1003 fclose (output);
1004
1005@@ -3217,8 +3178,9 @@
1006 job->goal = JOB_START;
1007 job->state = JOB_SPAWNED;
1008
1009- ret = job_process_run (job, PROCESS_MAIN);
1010- TEST_LT (ret, 0);
1011+ job_process_start (job, PROCESS_MAIN);
1012+ TEST_WATCH_UPDATE ();
1013+ TEST_WATCH_UPDATE ();
1014
1015 /* We don't expect a logfile to be written since there is no
1016 * accompanying shell to write the error.
1017@@ -3229,8 +3191,8 @@
1018 job->goal = JOB_STOP;
1019 job->state = JOB_POST_STOP;
1020
1021- ret = job_process_run (job, PROCESS_POST_STOP);
1022- TEST_EQ (ret, 0);
1023+ job_process_start (job, PROCESS_POST_STOP);
1024+ TEST_WATCH_UPDATE ();
1025
1026 TEST_NE (job->pid[PROCESS_POST_STOP], 0);
1027
1028@@ -3248,6 +3210,7 @@
1029
1030 /* .. but the post stop should have written data */
1031 TEST_EQ (stat (filename, &statbuf), 0);
1032+ event_poll ();
1033 }
1034 fclose (output);
1035
1036@@ -3301,8 +3264,8 @@
1037 job->goal = JOB_START;
1038 job->state = JOB_SPAWNED;
1039
1040- ret = job_process_run (job, PROCESS_MAIN);
1041- TEST_LT (ret, 0);
1042+ job_process_start (job, PROCESS_MAIN);
1043+ TEST_WATCH_UPDATE ();
1044
1045 /* We don't expect a logfile to be written since there is no
1046 * accompanying shell to write the error.
1047@@ -3313,8 +3276,8 @@
1048 job->goal = JOB_STOP;
1049 job->state = JOB_POST_STOP;
1050
1051- ret = job_process_run (job, PROCESS_POST_STOP);
1052- TEST_EQ (ret, 0);
1053+ job_process_start (job, PROCESS_POST_STOP);
1054+ TEST_WATCH_UPDATE ();
1055
1056 TEST_NE (job->pid[PROCESS_POST_STOP], 0);
1057
1058@@ -3327,8 +3290,11 @@
1059 TEST_TRUE (WIFEXITED (status));
1060 TEST_EQ (WEXITSTATUS (status), 0);
1061
1062+ TEST_WATCH_UPDATE ();
1063+
1064 /* .. but the post stop should have written data */
1065 TEST_EQ (stat (filename, &statbuf), 0);
1066+ event_poll ();
1067 }
1068 fclose (output);
1069
1070@@ -3381,8 +3347,8 @@
1071 job->goal = JOB_START;
1072 job->state = JOB_SPAWNED;
1073
1074- ret = job_process_run (job, PROCESS_MAIN);
1075- TEST_LT (ret, 0);
1076+ job_process_start (job, PROCESS_MAIN);
1077+ TEST_WATCH_UPDATE ();
1078
1079 /* We don't expect a logfile to be written since there is no
1080 * accompanying shell to write the error.
1081@@ -3393,12 +3359,13 @@
1082 job->goal = JOB_STOP;
1083 job->state = JOB_POST_STOP;
1084
1085- ret = job_process_run (job, PROCESS_POST_STOP);
1086- TEST_LT (ret, 0);
1087+ job_process_start (job, PROCESS_POST_STOP);
1088+ TEST_WATCH_UPDATE ();
1089
1090 /* Again, no file expected */
1091 TEST_EQ (stat (filename, &statbuf), -1);
1092 TEST_EQ (errno, ENOENT);
1093+ event_poll ();
1094 }
1095 fclose (output);
1096 nih_free (class);
1097@@ -3439,8 +3406,7 @@
1098 job->goal = JOB_START;
1099 job->state = JOB_SPAWNED;
1100
1101- ret = job_process_run (job, PROCESS_MAIN);
1102- TEST_EQ (ret, 0);
1103+ job_process_start (job, PROCESS_MAIN);
1104
1105 TEST_NE (job->pid[PROCESS_MAIN], 0);
1106
1107@@ -3459,8 +3425,8 @@
1108 job->goal = JOB_STOP;
1109 job->state = JOB_POST_STOP;
1110
1111- ret = job_process_run (job, PROCESS_POST_STOP);
1112- TEST_LT (ret, 0);
1113+ job_process_start (job, PROCESS_POST_STOP);
1114+ TEST_WATCH_UPDATE ();
1115
1116 TEST_EQ (job->pid[PROCESS_POST_STOP], 0);
1117 }
1118@@ -3500,8 +3466,8 @@
1119 job->goal = JOB_START;
1120 job->state = JOB_SPAWNED;
1121
1122- ret = job_process_run (job, PROCESS_MAIN);
1123- TEST_EQ (ret, 0);
1124+ job_process_start (job, PROCESS_MAIN);
1125+ TEST_WATCH_UPDATE ();
1126
1127 TEST_NE (job->pid[PROCESS_MAIN], 0);
1128
1129@@ -3561,8 +3527,8 @@
1130 job->goal = JOB_START;
1131 job->state = JOB_SPAWNED;
1132
1133- ret = job_process_run (job, PROCESS_MAIN);
1134- TEST_EQ (ret, 0);
1135+ job_process_start (job, PROCESS_MAIN);
1136+ TEST_WATCH_UPDATE ();
1137
1138 TEST_NE (job->pid[PROCESS_MAIN], 0);
1139
1140@@ -3624,8 +3590,8 @@
1141 job->goal = JOB_START;
1142 job->state = JOB_SPAWNED;
1143
1144- ret = job_process_run (job, PROCESS_MAIN);
1145- TEST_EQ (ret, 0);
1146+ job_process_start (job, PROCESS_MAIN);
1147+ TEST_WATCH_UPDATE ();
1148
1149 TEST_NE (job->pid[PROCESS_MAIN], 0);
1150
1151@@ -3704,8 +3670,7 @@
1152 job->goal = JOB_START;
1153 job->state = JOB_SPAWNED;
1154
1155- ret = job_process_run (job, PROCESS_MAIN);
1156- TEST_EQ (ret, 0);
1157+ job_process_start (job, PROCESS_MAIN);
1158
1159 /* Wait for process to avoid any possibility of EAGAIN in
1160 * log_read_watch().
1161@@ -3778,8 +3743,9 @@
1162 job->goal = JOB_START;
1163 job->state = JOB_SPAWNED;
1164
1165- ret = job_process_run (job, PROCESS_MAIN);
1166- TEST_EQ (ret, 0);
1167+ job_process_start (job, PROCESS_MAIN);
1168+ TEST_WATCH_UPDATE ();
1169+ TEST_WATCH_UPDATE ();
1170
1171 pid = job->pid[PROCESS_MAIN];
1172
1173@@ -3909,8 +3875,8 @@
1174 TEST_EQ_P (job->log[i], NULL);
1175 }
1176
1177- ret = job_process_run (job, PROCESS_MAIN);
1178- TEST_EQ (ret, 0);
1179+ job_process_start (job, PROCESS_MAIN);
1180+ TEST_WATCH_UPDATE ();
1181
1182 pid = job->pid[PROCESS_MAIN];
1183
1184@@ -3982,8 +3948,7 @@
1185 }
1186
1187 TEST_DIVERT_STDERR (output) {
1188- ret = job_process_run (job, PROCESS_MAIN);
1189- TEST_EQ (ret, 0);
1190+ job_process_start (job, PROCESS_MAIN);
1191 }
1192 fclose (output);
1193
1194@@ -4040,13 +4005,8 @@
1195 }
1196
1197 TEST_DIVERT_STDERR (output) {
1198- ret = job_process_run (job, PROCESS_MAIN);
1199- if (geteuid() == 0 || getuid() == pwd->pw_uid) {
1200- TEST_EQ (ret, 0);
1201- }
1202- else {
1203- TEST_EQ (ret, -1);
1204- }
1205+ job_process_start (job, PROCESS_MAIN);
1206+ TEST_WATCH_UPDATE ();
1207 }
1208
1209 if (geteuid() == 0 || getuid() == pwd->pw_uid) {
1210@@ -4057,11 +4017,11 @@
1211 }
1212 else {
1213 TEST_EQ (stat (filename, &statbuf), -1);
1214+ event_poll ();
1215 }
1216
1217 unlink (filename);
1218 nih_free (class);
1219-
1220 }
1221
1222 /************************************************************/
1223@@ -4104,14 +4064,13 @@
1224 job->goal = JOB_START;
1225 job->state = JOB_SPAWNED;
1226
1227- ret = job_process_run (job, PROCESS_MAIN);
1228- TEST_EQ (ret, 0);
1229-
1230+ job_process_start (job, PROCESS_MAIN);
1231+ while (stat (filename, &statbuf) != 0) {
1232+ TEST_WATCH_UPDATE ();
1233+ }
1234 pid = job->pid[PROCESS_MAIN];
1235 TEST_GT (pid, 0);
1236
1237- TEST_WATCH_UPDATE ();
1238-
1239 TEST_EQ (stat (filename, &statbuf), 0);
1240
1241 output = fopen (filename, "r");
1242@@ -4124,8 +4083,8 @@
1243
1244 TEST_EQ (fclose (output), 0);
1245
1246- ret = job_process_run (job, PROCESS_POST_START);
1247- TEST_EQ (ret, 0);
1248+ job_process_start (job, PROCESS_POST_START);
1249+ TEST_WATCH_UPDATE ();
1250
1251 pid = job->pid[PROCESS_POST_START];
1252 TEST_GT (pid, 0);
1253@@ -9159,7 +9118,7 @@
1254 void
1255 run_tests (void)
1256 {
1257- test_run ();
1258+ test_start ();
1259 test_spawn ();
1260 test_log_path ();
1261 test_kill ();
1262
1263=== modified file 'test/test_util_common.h'
1264--- test/test_util_common.h 2014-05-08 11:44:11 +0000
1265+++ test/test_util_common.h 2014-05-21 22:55:26 +0000
1266@@ -88,6 +88,41 @@
1267 }
1268
1269 /**
1270+ * TEST_WATCH_LOOP:
1271+ *
1272+ * Loop for NihIo object Updates, and process them until no watches
1273+ * left.
1274+ */
1275+#define TEST_WATCH_LOOP() \
1276+{ \
1277+ /* Loop until we've fed all of the data. */ \
1278+ int first = TRUE; \
1279+ for (;;) { \
1280+ fd_set readfds, writefds, exceptfds; \
1281+ int nfds; \
1282+ \
1283+ nfds = 0; \
1284+ FD_ZERO (&readfds); \
1285+ FD_ZERO (&writefds); \
1286+ FD_ZERO (&exceptfds); \
1287+ \
1288+ nih_io_select_fds (&nfds, &readfds, \
1289+ &writefds, &exceptfds); \
1290+ if (! nfds) { \
1291+ if (first) \
1292+ TEST_FAILED ("expected to have " \
1293+ "data to feed."); \
1294+ break; \
1295+ } \
1296+ first = FALSE; \
1297+ \
1298+ select (nfds, &readfds, &writefds, &exceptfds, NULL); \
1299+ \
1300+ nih_io_handle_fds (&readfds, &writefds, &exceptfds); \
1301+ } \
1302+}
1303+
1304+/**
1305 * _TEST_WATCH_UPDATE:
1306 * @force: if TRUE, force an update,
1307 * @timeout: struct timeval pointer, or NULL if no timeout required.

Subscribers

People subscribed via source and target branches