@@ -521,21 +521,24 @@ func logAtVariousLevels() {
521
521
522
522
func TestRollover (t * testing.T ) {
523
523
setFlags ()
524
+ defer func (previous func () time.Time ) { timeNow = previous }(timeNow )
525
+
526
+ // Initialize a fake clock that can be advanced with the tick func.
527
+ fakeNow := time .Date (2024 , 12 , 23 , 1 , 23 , 45 , 0 , time .Local )
528
+ timeNow = func () time.Time {
529
+ return fakeNow
530
+ }
531
+
532
+ tick := func (d time.Duration ) {
533
+ fakeNow = fakeNow .Add (d )
534
+ }
524
535
525
536
Info ("x" ) // Be sure we have a file.
526
537
info , ok := sinks .file .file [logsink .Info ].(* syncBuffer )
527
538
if ! ok {
528
539
t .Fatal ("info wasn't created" )
529
540
}
530
541
531
- // Make sure the next log file gets a file name with a different
532
- // time stamp.
533
- //
534
- // TODO: determine whether we need to support subsecond log
535
- // rotation. C++ does not appear to handle this case (nor does it
536
- // handle Daylight Savings Time properly).
537
- time .Sleep (1 * time .Second )
538
-
539
542
// Measure the current size of the log file.
540
543
info .Flush ()
541
544
fi , err := info .file .Stat ()
@@ -550,7 +553,9 @@ func TestRollover(t *testing.T) {
550
553
551
554
fname0 := info .file .Name ()
552
555
553
- // Force a rotation.
556
+ // Advance clock by 1.5 seconds to force rotation by size.
557
+ // (The .5 will be important for the last test as well).
558
+ tick (1500 * time .Millisecond )
554
559
Info (longMessage )
555
560
Info (longMessage )
556
561
info .Flush ()
@@ -610,14 +615,49 @@ func TestRollover(t *testing.T) {
610
615
611
616
// Make sure Names returned the right names.
612
617
n , err := Names ("INFO" )
613
- if len (n ) != 2 && err != nil && n [0 ] != fname0 && n [1 ] != fname1 {
618
+ if ( len (n ) != 2 || err != nil ) && n [0 ] != fname0 && n [1 ] != fname1 {
614
619
t .Errorf ("Names(INFO) wanted [%s, %s]/nil, got %v/%v" , fname0 , fname1 , n , err )
615
620
}
616
621
622
+ // The following tests assume that previous test left clock at .5 seconds.
623
+ if fakeNow .Nanosecond () != 5e8 {
624
+ t .Fatalf ("BUG: fake clock should be exactly at .5 seconds" )
625
+ }
626
+
627
+ // Same second would create conflicting filename, no rotation expected.
628
+ tick (499 * time .Millisecond )
629
+ Info (longMessage )
630
+ Info (longMessage )
631
+ n , err = Names ("INFO" )
632
+ if got , want := len (n ), 2 ; got != want || err != nil {
633
+ t .Errorf ("Names(INFO) = %v (len=%v), %v, want %d names: expected no rotation within same second" , n , got , err , want )
634
+ }
635
+
636
+ // Trigger a subsecond rotation in next fakeClock second.
637
+ tick (1 * time .Millisecond )
638
+ Info (longMessage )
639
+ Info (longMessage )
640
+ n , err = Names ("INFO" )
641
+ if got , want := len (n ), 3 ; got != want || err != nil {
642
+ t .Errorf ("Names(INFO) = %v (len=%v), %v, want %d names: expected a rotation after under a second when filename does not conflict" , n , got , err , want )
643
+ }
644
+
645
+ // Trigger a rotation within a minute since the last rotation.
646
+ tick (time .Minute )
647
+ Info (longMessage )
648
+ Info (longMessage )
649
+ n , err = Names ("INFO" )
650
+ if got , want := len (n ), 4 ; got != want || err != nil {
651
+ t .Errorf ("Names(INFO) = %v (len=%v), %v, want %d names: expected a rotation after one minute since last rotation" , n , got , err , want )
652
+ }
653
+
617
654
if t .Failed () {
618
- t .Logf ("%v:\n %q" , fname0 , f0 )
619
- t .Logf ("%v:\n %q" , fname1 , f1 )
655
+ t .Logf ("========================================================" )
656
+ t .Logf ("%s:\n %s" , fname0 , f0 )
657
+ t .Logf ("========================================================" )
658
+ t .Logf ("%s:\n %s" , fname1 , f1 )
620
659
}
660
+
621
661
}
622
662
623
663
func TestLogBacktraceAt (t * testing.T ) {
0 commit comments