~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-05-20 12:09:17 UTC
  • Revision ID: scott@netsplit.com-20070520120917-6yanaj1t0a1ej3zd
* init/event.c (event_ref, event_unref): Reference counting of events
so we don't free those we still need.
(event_block, event_unblock): Blocker counting that replaces the
previous jobs member.
(event_new): Initialise refs and blockers fields.
(event_emit_finished): Remove this function.
(event_poll): Handle the new done state, and deal with the blockers
and references counts; turns out that we can fall all the way through
this switch if these are zero without needing to check again.
(event_pending): Remove call to event_emit_finished, the event_poll()
loop handles this case now.
(event_finished): Set progress to done on the way out.
* init/event.h (EventProgress): Add new done state
(Event): Add refs and blockers members, replacing jobs
* init/tests/test_event.c (test_new): Check refs and blockers are
initialised to zero.
(test_ref, test_unref, test_block, test_unblock): Check the ref
counting function behaviours.
(test_emit_finished): Drop this function since it's not used
* init/job.c (job_change_cause): Reference and block the event,
and unblock and unreference before changing.
(job_emit_event): Reference the event that blocks the job from
continuing.
(job_handle_event_finished): Unreference the blocking event again.
(job_change_state): Make sure that blocked has been cleared before
allowing a state change.
* init/tests/test_job.c: Change tests to use refs/blockers on the
cause event when counting, and also to follow the status of blocked
since that is now ref-counted as well.

Show diffs side-by-side

added added

removed removed

Lines of Context:
241
241
                last_id = event->id;
242
242
 
243
243
                TEST_EQ (event->progress, EVENT_PENDING);
244
 
                TEST_EQ (event->jobs, 0);
245
244
                TEST_EQ (event->failed, FALSE);
246
245
 
 
246
                TEST_EQ (event->refs, 0);
 
247
                TEST_EQ (event->blockers, 0);
 
248
 
247
249
                TEST_EQ_STR (event->info.name, "test");
248
250
                TEST_ALLOC_PARENT (event->info.name, event);
249
251
 
286
288
        TEST_EQ_P (ret, NULL);
287
289
}
288
290
 
289
 
void
290
 
test_emit_finished (void)
291
 
{
292
 
        Event *event;
293
 
 
294
 
        TEST_FUNCTION ("event_emit_finished");
295
 
        event = event_new (NULL, "test", NULL, NULL);
296
 
        event->progress = EVENT_HANDLING;
297
 
 
298
 
        /* Check that if an event has jobs remaining, the progress isn't
299
 
         * changed.
300
 
         */
301
 
        TEST_FEATURE ("with remaining jobs");
302
 
        event->jobs = 1;
303
 
        event_emit_finished (event);
304
 
 
305
 
        TEST_EQ (event->progress, EVENT_HANDLING);
306
 
 
307
 
 
308
 
        /* Check that if an event has no jobs remaining, the progress is
309
 
         * changed to finished.
310
 
         */
311
 
        TEST_FEATURE ("with no remaining jobs");
312
 
        event->jobs = 0;
313
 
        event_emit_finished (event);
314
 
 
315
 
        TEST_EQ (event->progress, EVENT_FINISHED);
316
 
 
 
291
 
 
292
void
 
293
test_ref (void)
 
294
{
 
295
        Event *event;
 
296
 
 
297
        /* Check that calling event_ref increments the number of references
 
298
         * that the event has, while leaving the blockers at zero.
 
299
         */
 
300
        TEST_FUNCTION ("event_ref");
 
301
        event = event_new (NULL, "test", NULL, NULL);
 
302
        event->refs = 4;
 
303
 
 
304
        event_ref (event);
 
305
 
 
306
        TEST_EQ (event->refs, 5);
 
307
        TEST_EQ (event->blockers, 0);
 
308
 
 
309
        nih_list_free (&event->entry);
 
310
}
 
311
 
 
312
void
 
313
test_unref (void)
 
314
{
 
315
        Event *event;
 
316
 
 
317
        /* Check that calling event_unref decrements the number of references
 
318
         * that the event has, while leaving the blockers at zero.
 
319
         */
 
320
        TEST_FUNCTION ("event_unref");
 
321
        event = event_new (NULL, "test", NULL, NULL);
 
322
        event->refs = 4;
 
323
 
 
324
        event_unref (event);
 
325
 
 
326
        TEST_EQ (event->refs, 3);
 
327
        TEST_EQ (event->blockers, 0);
 
328
 
 
329
        nih_list_free (&event->entry);
 
330
}
 
331
 
 
332
void
 
333
test_block (void)
 
334
{
 
335
        Event *event;
 
336
 
 
337
        /* Check that calling event_block increments the number of blockers
 
338
         * that the event has, while leaving the references at zero.
 
339
         */
 
340
        TEST_FUNCTION ("event_block");
 
341
        event = event_new (NULL, "test", NULL, NULL);
 
342
        event->blockers = 4;
 
343
 
 
344
        event_block (event);
 
345
 
 
346
        TEST_EQ (event->blockers, 5);
 
347
        TEST_EQ (event->refs, 0);
 
348
 
 
349
        nih_list_free (&event->entry);
 
350
}
 
351
 
 
352
void
 
353
test_unblock (void)
 
354
{
 
355
        Event *event;
 
356
 
 
357
        /* Check that calling event_unblock increments the number of blockers
 
358
         * that the event has, while leaving the references at zero.
 
359
         */
 
360
        TEST_FUNCTION ("event_unblock");
 
361
        event = event_new (NULL, "test", NULL, NULL);
 
362
        event->blockers = 4;
 
363
 
 
364
        event_unblock (event);
 
365
 
 
366
        TEST_EQ (event->blockers, 3);
 
367
        TEST_EQ (event->refs, 0);
317
368
 
318
369
        nih_list_free (&event->entry);
319
370
}
389
440
 
390
441
        /* Check that a pending event in the queue is handled, with any
391
442
         * subscribed processes being notified of the event and any
392
 
         * jobs started or stopped as a result.
 
443
         * jobs started or stopped as a result.  The event should remain
 
444
         * in the handling state while the job is blocking it.
393
445
         */
394
446
        TEST_FEATURE ("with pending event");
395
447
        fflush (stdout);
435
487
        TEST_EQ (WEXITSTATUS (status), 0);
436
488
 
437
489
        TEST_EQ (event->progress, EVENT_HANDLING);
438
 
        TEST_EQ (event->jobs, 1);
 
490
        TEST_EQ (event->refs, 1);
 
491
        TEST_EQ (event->blockers, 1);
439
492
 
440
493
        TEST_EQ (job->goal, JOB_START);
441
494
        TEST_EQ (job->state, JOB_RUNNING);
449
502
        nih_list_free (&event->entry);
450
503
 
451
504
 
452
 
        /* Check that having a handling event in the queue doesn't cause
453
 
         * any problem.
 
505
        /* Check that having a handling event in the queue which has blockers
 
506
         * doesn't cause any problem.
454
507
         */
455
 
        TEST_FEATURE ("with handling event");
 
508
        TEST_FEATURE ("with blocked handling event");
456
509
        TEST_ALLOC_FAIL {
457
510
                event = event_new (NULL, "test", NULL, NULL);
458
511
                event->progress = EVENT_HANDLING;
 
512
                event->blockers = 1;
459
513
 
460
514
                event_poll ();
461
515
 
464
518
        }
465
519
 
466
520
 
467
 
        /* Check that events in the finished state are consumed, leaving
468
 
         * the list empty.  Subscribed processes should be notified, blocked
469
 
         * jobs should be releaed and the event should be freed.
 
521
        /* Check that we finish unblocked handling events, leaving the list
 
522
         * empty.  Subscribed processes should be notified, blocked jobs
 
523
         * should be releaed and the event should be freed.
470
524
         */
471
525
        TEST_FEATURE ("with finished event");
472
526
        fflush (stdout);
492
546
 
493
547
        event = event_new (NULL, "test", NULL, NULL);
494
548
        event->id = 0xdeafbeef;
 
549
        event->progress = EVENT_HANDLING;
495
550
 
496
551
        job = job_new (NULL, "test");
497
552
        job->goal = JOB_START;
500
555
        job->process[PROCESS_MAIN] = job_process_new (job->process);
501
556
        job->process[PROCESS_MAIN]->command = "echo";
502
557
 
503
 
        event_emit_finished (event);
 
558
        event_ref (job->blocked);
504
559
 
505
560
        destructor_called = 0;
506
561
        nih_alloc_set_destructor (event, my_destructor);
531
586
        TEST_LIST_EMPTY (subscriptions);
532
587
 
533
588
 
 
589
        /* Check that a finished event with remaining references is held
 
590
         * in the done state, and not freed immediately.
 
591
         */
 
592
        TEST_FEATURE ("with referenced event");
 
593
        TEST_ALLOC_FAIL {
 
594
                event = event_new (NULL, "test", NULL, NULL);
 
595
                event->progress = EVENT_DONE;
 
596
                event->refs = 1;
 
597
 
 
598
                event_poll ();
 
599
 
 
600
                TEST_LIST_NOT_EMPTY (&event->entry);
 
601
                nih_list_free (&event->entry);
 
602
        }
 
603
 
 
604
 
534
605
        /* Check that a pending event which doesn't cause any jobs to be
535
 
         * changed goes straight into the finished state, thus getting
 
606
         * changed goes straight into the done state, thus getting
536
607
         * destroyed.
537
608
         */
538
609
        TEST_FEATURE ("with no-op pending event");
580
651
 
581
652
        TEST_EQ_STR (job->cause->info.name, "test/failed");
582
653
 
583
 
        event_emit_finished (job->cause);
584
654
        event_poll ();
585
655
 
586
656
        nih_list_free (&job->entry);
632
702
        test_match ();
633
703
        test_new ();
634
704
        test_find_by_id ();
635
 
        test_emit_finished ();
 
705
        test_ref ();
 
706
        test_unref ();
 
707
        test_block ();
 
708
        test_unblock ();
636
709
        test_poll ();
637
710
 
638
711
        return 0;