@@ -393,3 +393,261 @@ def test_HierarchicalTimer_longNames(self):
393
393
'=' * 79 )).splitlines ()
394
394
for l , r in zip (str (timer ).splitlines (), ref ):
395
395
self .assertRegex (l , r )
396
+
397
+ def test_clear_except_base_timer (self ):
398
+ timer = HierarchicalTimer ()
399
+ timer .start ("a" )
400
+ timer .start ("b" )
401
+ timer .stop ("b" )
402
+ timer .stop ("a" )
403
+ timer .start ("c" )
404
+ timer .stop ("c" )
405
+ timer .start ("d" )
406
+ timer .stop ("d" )
407
+ timer .clear_except ("b" , "c" )
408
+ key_set = set (timer .timers .keys ())
409
+ self .assertEqual (key_set , {"c" })
410
+
411
+ def test_clear_except_subtimer (self ):
412
+ # Testing this method on "sub-timers" exercises different code
413
+ # as while the base timer is a HierarchicalTimer, the sub-timers
414
+ # are _HierarchicalHelpers
415
+ timer = HierarchicalTimer ()
416
+ timer .start ("root" )
417
+ timer .start ("a" )
418
+ timer .start ("b" )
419
+ timer .stop ("b" )
420
+ timer .stop ("a" )
421
+ timer .start ("c" )
422
+ timer .stop ("c" )
423
+ timer .start ("d" )
424
+ timer .stop ("d" )
425
+ timer .stop ("root" )
426
+ root = timer .timers ["root" ]
427
+ root .clear_except ("b" , "c" )
428
+ key_set = set (root .timers .keys ())
429
+ self .assertEqual (key_set , {"c" })
430
+
431
+
432
+ class TestFlattenHierarchicalTimer (unittest .TestCase ):
433
+
434
+ #
435
+ # The following methods create some hierarchical timers, then
436
+ # hand-code the total time of each timer in the data structure.
437
+ # This is so we can assert that total_time fields of flattened
438
+ # timers are computed correctly without relying on the actual
439
+ # time spent.
440
+ #
441
+ def make_singleton_timer (self ):
442
+ timer = HierarchicalTimer ()
443
+ timer .start ("root" )
444
+ timer .stop ("root" )
445
+ timer .timers ["root" ].total_time = 5.0
446
+ return timer
447
+
448
+ def make_flat_timer (self ):
449
+ timer = HierarchicalTimer ()
450
+ timer .start ("root" )
451
+ timer .start ("a" )
452
+ timer .stop ("a" )
453
+ timer .start ("b" )
454
+ timer .stop ("b" )
455
+ timer .stop ("root" )
456
+ timer .timers ["root" ].total_time = 5.0
457
+ timer .timers ["root" ].timers ["a" ].total_time = 1.0
458
+ timer .timers ["root" ].timers ["b" ].total_time = 2.5
459
+ return timer
460
+
461
+ def make_timer_depth_2_one_child (self ):
462
+ timer = HierarchicalTimer ()
463
+ timer .start ("root" )
464
+ timer .start ("a" )
465
+ timer .start ("b" )
466
+ timer .stop ("b" )
467
+ timer .start ("c" )
468
+ timer .stop ("c" )
469
+ timer .stop ("a" )
470
+ timer .stop ("root" )
471
+ timer .timers ["root" ].total_time = 5.0
472
+ timer .timers ["root" ].timers ["a" ].total_time = 4.0
473
+ timer .timers ["root" ].timers ["a" ].timers ["b" ].total_time = 1.1
474
+ timer .timers ["root" ].timers ["a" ].timers ["c" ].total_time = 2.2
475
+ return timer
476
+
477
+ def make_timer_depth_2_with_name_collision (self ):
478
+ timer = HierarchicalTimer ()
479
+ timer .start ("root" )
480
+ timer .start ("a" )
481
+ timer .start ("b" )
482
+ timer .stop ("b" )
483
+ timer .start ("c" )
484
+ timer .stop ("c" )
485
+ timer .stop ("a" )
486
+ timer .start ("b" )
487
+ timer .stop ("b" )
488
+ timer .stop ("root" )
489
+ timer .timers ["root" ].total_time = 5.0
490
+ timer .timers ["root" ].timers ["a" ].total_time = 4.0
491
+ timer .timers ["root" ].timers ["a" ].timers ["b" ].total_time = 1.1
492
+ timer .timers ["root" ].timers ["a" ].timers ["c" ].total_time = 2.2
493
+ timer .timers ["root" ].timers ["b" ].total_time = 0.11
494
+ return timer
495
+
496
+ def make_timer_depth_2_two_children (self ):
497
+ timer = HierarchicalTimer ()
498
+ timer .start ("root" )
499
+ timer .start ("a" )
500
+ timer .start ("b" )
501
+ timer .stop ("b" )
502
+ timer .start ("c" )
503
+ timer .stop ("c" )
504
+ timer .stop ("a" )
505
+ timer .start ("b" )
506
+ timer .start ("c" )
507
+ timer .stop ("c" )
508
+ timer .start ("d" )
509
+ timer .stop ("d" )
510
+ timer .stop ("b" )
511
+ timer .stop ("root" )
512
+ timer .timers ["root" ].total_time = 5.0
513
+ timer .timers ["root" ].timers ["a" ].total_time = 4.0
514
+ timer .timers ["root" ].timers ["a" ].timers ["b" ].total_time = 1.1
515
+ timer .timers ["root" ].timers ["a" ].timers ["c" ].total_time = 2.2
516
+ timer .timers ["root" ].timers ["b" ].total_time = 0.88
517
+ timer .timers ["root" ].timers ["b" ].timers ["c" ].total_time = 0.07
518
+ timer .timers ["root" ].timers ["b" ].timers ["d" ].total_time = 0.05
519
+ return timer
520
+
521
+ def make_timer_depth_4 (self ):
522
+ timer = HierarchicalTimer ()
523
+ timer .start ("root" )
524
+ timer .start ("a" )
525
+ timer .start ("b" )
526
+ timer .stop ("b" )
527
+ timer .start ("c" )
528
+ timer .start ("d" )
529
+ timer .start ("e" )
530
+ timer .stop ("e" )
531
+ timer .stop ("d" )
532
+ timer .stop ("c" )
533
+ timer .stop ("a" )
534
+ timer .start ("b" )
535
+ timer .start ("c" )
536
+ timer .start ("e" )
537
+ timer .stop ("e" )
538
+ timer .stop ("c" )
539
+ timer .start ("d" )
540
+ timer .stop ("d" )
541
+ timer .stop ("b" )
542
+ timer .stop ("root" )
543
+ timer .timers ["root" ].total_time = 5.0
544
+ timer .timers ["root" ].timers ["a" ].total_time = 4.0
545
+ timer .timers ["root" ].timers ["a" ].timers ["b" ].total_time = 1.1
546
+ timer .timers ["root" ].timers ["a" ].timers ["c" ].total_time = 2.2
547
+ timer .timers ["root" ].timers ["a" ].timers ["c" ].timers ["d" ].total_time = 0.9
548
+ timer .timers ["root" ].timers ["a" ].timers ["c" ].timers ["d" ].timers ["e" ].total_time = 0.6
549
+ timer .timers ["root" ].timers ["b" ].total_time = 0.88
550
+ timer .timers ["root" ].timers ["b" ].timers ["c" ].total_time = 0.07
551
+ timer .timers ["root" ].timers ["b" ].timers ["c" ].timers ["e" ].total_time = 0.04
552
+ timer .timers ["root" ].timers ["b" ].timers ["d" ].total_time = 0.05
553
+ return timer
554
+
555
+ def make_timer_depth_4_same_name (self ):
556
+ timer = HierarchicalTimer ()
557
+ timer .start ("root" )
558
+ timer .start ("a" )
559
+ timer .start ("a" )
560
+ timer .start ("a" )
561
+ timer .start ("a" )
562
+ timer .stop ("a" )
563
+ timer .stop ("a" )
564
+ timer .stop ("a" )
565
+ timer .stop ("a" )
566
+ timer .stop ("root" )
567
+ timer .timers ["root" ].total_time = 5.0
568
+ timer .timers ["root" ].timers ["a" ].total_time = 1.0
569
+ timer .timers ["root" ].timers ["a" ].timers ["a" ].total_time = 0.1
570
+ timer .timers ["root" ].timers ["a" ].timers ["a" ].timers ["a" ].total_time = 0.01
571
+ timer .timers ["root" ].timers ["a" ].timers ["a" ].timers ["a" ].timers ["a" ].total_time = 0.001
572
+ return timer
573
+
574
+ def test_singleton (self ):
575
+ timer = self .make_singleton_timer ()
576
+ root = timer .timers ["root" ]
577
+ root .flatten ()
578
+ self .assertAlmostEqual (root .total_time , 5.0 )
579
+
580
+ def test_already_flat (self ):
581
+ timer = self .make_flat_timer ()
582
+ root = timer .timers ["root" ]
583
+ root .flatten ()
584
+ self .assertAlmostEqual (root .total_time , 5.0 )
585
+ self .assertAlmostEqual (root .timers ["a" ].total_time , 1.0 )
586
+ self .assertAlmostEqual (root .timers ["b" ].total_time , 2.5 )
587
+
588
+ def test_depth_2_one_child (self ):
589
+ timer = self .make_timer_depth_2_one_child ()
590
+ root = timer .timers ["root" ]
591
+ root .flatten ()
592
+ self .assertAlmostEqual (root .total_time , 5.0 )
593
+ self .assertAlmostEqual (root .timers ["a" ].total_time , 0.7 )
594
+ self .assertAlmostEqual (root .timers ["b" ].total_time , 1.1 )
595
+ self .assertAlmostEqual (root .timers ["c" ].total_time , 2.2 )
596
+
597
+ def test_timer_depth_2_with_name_collision (self ):
598
+ timer = self .make_timer_depth_2_with_name_collision ()
599
+ root = timer .timers ["root" ]
600
+ root .flatten ()
601
+ self .assertAlmostEqual (root .total_time , 5.0 )
602
+ self .assertAlmostEqual (root .timers ["a" ].total_time , 0.700 )
603
+ self .assertAlmostEqual (root .timers ["b" ].total_time , 1.210 )
604
+ self .assertAlmostEqual (root .timers ["c" ].total_time , 2.200 )
605
+
606
+ def test_timer_depth_2_two_children (self ):
607
+ timer = self .make_timer_depth_2_two_children ()
608
+ root = timer .timers ["root" ]
609
+ root .flatten ()
610
+ self .assertAlmostEqual (root .total_time , 5.0 )
611
+ self .assertAlmostEqual (root .timers ["a" ].total_time , 0.700 )
612
+ self .assertAlmostEqual (root .timers ["b" ].total_time , 1.860 )
613
+ self .assertAlmostEqual (root .timers ["c" ].total_time , 2.270 )
614
+ self .assertAlmostEqual (root .timers ["d" ].total_time , 0.050 )
615
+
616
+ def test_timer_depth_4 (self ):
617
+ timer = self .make_timer_depth_4 ()
618
+ root = timer .timers ["root" ]
619
+ root .flatten ()
620
+ self .assertAlmostEqual (root .total_time , 5.0 )
621
+ self .assertAlmostEqual (root .timers ["a" ].total_time , 0.700 )
622
+ self .assertAlmostEqual (root .timers ["b" ].total_time , 1.860 )
623
+ self .assertAlmostEqual (root .timers ["c" ].total_time , 1.330 )
624
+ self .assertAlmostEqual (root .timers ["d" ].total_time , 0.350 )
625
+ self .assertAlmostEqual (root .timers ["e" ].total_time , 0.640 )
626
+
627
+ def test_timer_depth_4_same_name (self ):
628
+ timer = self .make_timer_depth_4_same_name ()
629
+ root = timer .timers ["root" ]
630
+ root .flatten ()
631
+ self .assertAlmostEqual (root .total_time , 5.0 )
632
+ self .assertAlmostEqual (root .timers ["a" ].total_time , 1.0 )
633
+
634
+ def test_base_timer_depth_3 (self ):
635
+ # This is depth 2 wrt the root, depth 3 wrt the
636
+ # "base timer"
637
+ timer = self .make_timer_depth_2_two_children ()
638
+ timer .flatten ()
639
+ self .assertAlmostEqual (timer .timers ["root" ].total_time , 0.120 )
640
+ self .assertAlmostEqual (timer .timers ["a" ].total_time , 0.700 )
641
+ self .assertAlmostEqual (timer .timers ["b" ].total_time , 1.860 )
642
+ self .assertAlmostEqual (timer .timers ["c" ].total_time , 2.270 )
643
+ self .assertAlmostEqual (timer .timers ["d" ].total_time , 0.050 )
644
+
645
+ def test_timer_still_active (self ):
646
+ timer = HierarchicalTimer ()
647
+ timer .start ("a" )
648
+ timer .stop ("a" )
649
+ timer .start ("b" )
650
+ msg = "Cannot flatten.*while any timers are active"
651
+ with self .assertRaisesRegex (RuntimeError , msg ):
652
+ timer .flatten ()
653
+ timer .stop ("b" )
0 commit comments