~vorlon/ubuntu/raring/upstart/lp.1199778

« back to all changes in this revision

Viewing changes to init/tests/test_event.c

  • Committer: Scott James Remnant
  • Date: 2007-02-08 00:49:40 UTC
  • Revision ID: scott@netsplit.com-20070208004940-joe4t7wr1ga1i7j6
Rewrite the notification subsystem quite significantly; now we
have individual functions to subscribe to different types of
notification, and can even subscribe to individual jobs or events.
* init/notify.c (notify_subscribe_job, notify_subscribe_event) 
(notify_unsubscribe): New subscription and unsubscription functions
that assume one record per subscription, not process.
(notify_subscription_find): Function to find a subscription.
(notify_job): Send a message to anything subscribed to the goal event
as well.
(notify_event): Use EventEmission and include the id in the event.
(notify_event_finished): New function, sends a finished message and
includes both the id and whether the event failed.
* init/notify.h (NotifySubscribe): New notify structure that is
once per subscription, rather than per-process; and allows
subscription to individual jobs or events.
* init/tests/test_notify.c (test_subscribe_job) 
(test_subscribe_event, test_unsubscribe): Test the new subscription
functions, replacing the old
(test_subscribe): tests.
(test_subscription_find): Check finding works
(check_event, test_event): Update to use emissions, and check that the
id is correct.
(test_event_finished): Check this one works too
(check_event_job_status, test_job): Make sure processes subscribed
via the goal event are notified too.
* init/event.c (event_pending): Pass the emission directly.
(event_finished): Notify subscribers that the event has finished.
* init/control.c (control_error_handler): Call notify_unsubscribe
(control_watch_jobs, control_unwatch_jobs, control_watch_events) 
(control_unwatch_events): Update to the new subscription API.
* init/tests/test_control.c (test_error_handler): Use new API
(test_watch_jobs, test_unwatch_jobs, test_watch_events)
(test_unwatch_events): Also update these to the new API; use a
destructor to make sure the subscription is freed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
272
272
check_event (void               *data,
273
273
             pid_t               pid,
274
274
             UpstartMessageType  type,
 
275
             uint32_t            id,
275
276
             const char         *name,
276
277
             char * const       *args,
277
278
             char * const       *env)
278
279
{
279
280
        TEST_EQ (pid, getppid ());
280
281
        TEST_EQ (type, UPSTART_EVENT);
 
282
        TEST_EQ_U (id, 0xdeafbeef);
 
283
        TEST_EQ_STR (name, "test");
 
284
        TEST_EQ_P (args, NULL);
 
285
        TEST_EQ_P (env, NULL);
 
286
 
 
287
        return 0;
 
288
}
 
289
 
 
290
static int
 
291
check_event_finished (void               *data,
 
292
                      pid_t               pid,
 
293
                      UpstartMessageType  type,
 
294
                      uint32_t            id,
 
295
                      int                 failed,
 
296
                      const char         *name,
 
297
                      char * const       *args,
 
298
                      char * const       *env)
 
299
{
 
300
        TEST_EQ (pid, getppid ());
 
301
        TEST_EQ (type, UPSTART_EVENT_FINISHED);
 
302
        TEST_EQ_U (id, 0xdeafbeef);
 
303
        TEST_EQ (failed, FALSE);
281
304
        TEST_EQ_STR (name, "test");
282
305
        TEST_EQ_P (args, NULL);
283
306
        TEST_EQ_P (env, NULL);
336
359
                exit (0);
337
360
        }
338
361
 
339
 
        sub = notify_subscribe (pid, NOTIFY_EVENTS, TRUE);
340
 
 
341
362
        job = job_new (NULL, "test");
342
363
        job->command = nih_strdup (job, "echo");
343
364
 
345
366
        nih_list_add (&job->start_events, &event->entry);
346
367
 
347
368
        em1 = event_emit ("test", NULL, NULL, my_emission_cb, &em1);
 
369
        em1->id = 0xdeafbeef;
 
370
 
 
371
        sub = notify_subscribe_event (NULL, pid, em1);
348
372
 
349
373
        event_poll ();
350
374
 
368
392
        nih_list_free (&job->entry);
369
393
        nih_list_free (&em1->event.entry);
370
394
 
371
 
        control_close ();
372
 
 
373
395
 
374
396
        /* Check that having a handling event in the queue doesn't cause
375
397
         * any problem.
387
409
 
388
410
 
389
411
        /* Check that events in the finished state are consumed, leaving
390
 
         * the list empty.  The callback for the event should be run and
391
 
         * the event should be freed.
 
412
         * the list empty.  Subscribed processes should be notified and
 
413
         * the callback for the event should be run and the event should
 
414
         * be freed.
392
415
         */
393
416
        TEST_FEATURE ("with finished event");
394
 
        TEST_ALLOC_FAIL {
395
 
                em1 = event_emit ("test", NULL, NULL, my_emission_cb, &em1);
396
 
                event_emit_finished (em1);
397
 
 
398
 
                destructor_called = 0;
399
 
                nih_alloc_set_destructor (em1, my_destructor);
400
 
 
401
 
                emission_called = 0;
402
 
 
403
 
                event_poll ();
404
 
 
405
 
                TEST_TRUE (emission_called);
406
 
                TEST_TRUE (destructor_called);
 
417
        fflush (stdout);
 
418
        TEST_CHILD_WAIT (pid, wait_fd) {
 
419
                NihIoMessage *message;
 
420
                int           sock;
 
421
                size_t        len;
 
422
 
 
423
                sock = upstart_open ();
 
424
 
 
425
                TEST_CHILD_RELEASE (wait_fd);
 
426
 
 
427
                message = nih_io_message_recv (NULL, sock, &len);
 
428
                assert0 (upstart_message_handle_using (message, message,
 
429
                                                       (UpstartMessageHandler)
 
430
                                                       check_event_finished,
 
431
                                                       NULL));
 
432
 
 
433
                nih_free (message);
 
434
 
 
435
                exit (0);
407
436
        }
408
437
 
 
438
        em1 = event_emit ("test", NULL, NULL, my_emission_cb, &em1);
 
439
        em1->id = 0xdeafbeef;
 
440
 
 
441
        destructor_called = 0;
 
442
        nih_alloc_set_destructor (em1, my_destructor);
 
443
 
 
444
        sub = notify_subscribe_event (NULL, pid, em1);
 
445
 
 
446
        emission_called = 0;
 
447
        event_emit_finished (em1);
 
448
 
 
449
        event_poll ();
 
450
 
 
451
        io->watch->watcher (io, io->watch, NIH_IO_READ | NIH_IO_WRITE);
 
452
 
 
453
        waitpid (pid, &status, 0);
 
454
        TEST_TRUE (WIFEXITED (status));
 
455
        TEST_EQ (WEXITSTATUS (status), 0);
 
456
 
 
457
        TEST_TRUE (emission_called);
 
458
        TEST_TRUE (destructor_called);
 
459
 
 
460
        nih_list_free (&sub->entry);
 
461
 
409
462
 
410
463
        /* Check that a pending event which doesn't cause any jobs to be
411
464
         * changed goes straight into the finished state, thus getting
502
555
        nih_list_free (&job->entry);
503
556
 
504
557
 
 
558
        control_close ();
505
559
        upstart_disable_safeties = FALSE;
506
560
}
507
561