@@ -30,100 +30,155 @@ func TestSatisfiesIOCloser(t *testing.T) {
30
30
}
31
31
32
32
func TestLogRotate (t * testing.T ) {
33
- dir , err := ioutil .TempDir ("" , "file-rotatelogs-test" )
34
- if ! assert .NoError (t , err , "creating temporary directory should succeed" ) {
35
- return
36
- }
37
- defer os .RemoveAll (dir )
33
+ testCases := []struct {
34
+ Name string
35
+ FixArgs func ([]rotatelogs.Option , string ) []rotatelogs.Option
36
+ CheckExtras func (* testing.T , * rotatelogs.RotateLogs , string ) bool
37
+ }{
38
+ {
39
+ Name : "Basic Usage" ,
40
+ },
41
+ {
42
+ Name : "With Symlink" ,
43
+ FixArgs : func (options []rotatelogs.Option , dir string ) []rotatelogs.Option {
44
+ linkName := filepath .Join (dir , "log" )
45
+ return append (options , rotatelogs .WithLinkName (linkName ))
46
+ },
47
+ CheckExtras : func (t * testing.T , rl * rotatelogs.RotateLogs , dir string ) bool {
48
+ linkName := filepath .Join (dir , "log" )
49
+ linkDest , err := os .Readlink (linkName )
50
+ if ! assert .NoError (t , err , `os.Readlink(%#v) should succeed` , linkName ) {
51
+ return false
52
+ }
38
53
39
- // Change current time, so we can safely purge old logs
40
- dummyTime := time .Now ().Add (- 7 * 24 * time .Hour )
41
- dummyTime = dummyTime .Add (time .Duration (- 1 * dummyTime .Nanosecond ()))
42
- clock := clockwork .NewFakeClockAt (dummyTime )
43
- linkName := filepath .Join (dir , "log" )
44
- rl , err := rotatelogs .New (
45
- filepath .Join (dir , "log%Y%m%d%H%M%S" ),
46
- rotatelogs .WithClock (clock ),
47
- rotatelogs .WithMaxAge (24 * time .Hour ),
48
- rotatelogs .WithLinkName (linkName ),
49
- )
50
- if ! assert .NoError (t , err , `rotatelogs.New should succeed` ) {
51
- return
52
- }
53
- defer rl .Close ()
54
+ expectedLinkDest := filepath .Base (rl .CurrentFileName ())
55
+ t .Logf ("expecting relative link: %s" , expectedLinkDest )
56
+ if ! assert .Equal (t , linkDest , expectedLinkDest , `Symlink destination should match expected filename (%#v != %#v)` , expectedLinkDest , linkDest ) {
57
+ return false
58
+ }
59
+ return true
60
+ },
61
+ },
62
+ {
63
+ Name : "With Symlink (multiple levels)" ,
64
+ FixArgs : func (options []rotatelogs.Option , dir string ) []rotatelogs.Option {
65
+ linkName := filepath .Join (dir , "nest1" , "nest2" , "log" )
66
+ return append (options , rotatelogs .WithLinkName (linkName ))
67
+ },
68
+ CheckExtras : func (t * testing.T , rl * rotatelogs.RotateLogs , dir string ) bool {
69
+ linkName := filepath .Join (dir , "nest1" , "nest2" , "log" )
70
+ linkDest , err := os .Readlink (linkName )
71
+ if ! assert .NoError (t , err , `os.Readlink(%#v) should succeed` , linkName ) {
72
+ return false
73
+ }
54
74
55
- str := "Hello, World"
56
- n , err := rl .Write ([]byte (str ))
57
- if ! assert .NoError (t , err , "rl.Write should succeed" ) {
58
- return
75
+ expectedLinkDest := filepath .Join (".." , ".." , filepath .Base (rl .CurrentFileName ()))
76
+ t .Logf ("expecting relative link: %s" , expectedLinkDest )
77
+ if ! assert .Equal (t , linkDest , expectedLinkDest , `Symlink destination should match expected filename (%#v != %#v)` , expectedLinkDest , linkDest ) {
78
+ return false
79
+ }
80
+ return true
81
+ },
82
+ },
59
83
}
60
84
61
- if ! assert .Len (t , str , n , "rl.Write should succeed" ) {
62
- return
63
- }
85
+ for i , tc := range testCases {
86
+ i := i // avoid lint errors
87
+ tc := tc // avoid lint errors
88
+ t .Run (tc .Name , func (t * testing.T ) {
89
+ dir , err := ioutil .TempDir ("" , fmt .Sprintf ("file-rotatelogs-test%d" , i ))
90
+ if ! assert .NoError (t , err , "creating temporary directory should succeed" ) {
91
+ return
92
+ }
93
+ defer os .RemoveAll (dir )
64
94
65
- fn := rl . CurrentFileName ()
66
- if fn == "" {
67
- t . Errorf ( "Could not get filename %s" , fn )
68
- }
95
+ // Change current time, so we can safely purge old logs
96
+ dummyTime := time . Now (). Add ( - 7 * 24 * time . Hour )
97
+ dummyTime = dummyTime . Add ( time . Duration ( - 1 * dummyTime . Nanosecond ()) )
98
+ clock := clockwork . NewFakeClockAt ( dummyTime )
69
99
70
- content , err := ioutil . ReadFile ( fn )
71
- if err != nil {
72
- t . Errorf ( "Failed to read file %s: %s" , fn , err )
73
- }
100
+ options := []rotatelogs. Option { rotatelogs . WithClock ( clock ), rotatelogs . WithMaxAge ( 24 * time . Hour )}
101
+ if fn := tc . FixArgs ; fn != nil {
102
+ options = fn ( options , dir )
103
+ }
74
104
75
- if string (content ) != str {
76
- t .Errorf (`File content does not match (was "%s")` , content )
77
- }
105
+ rl , err := rotatelogs .New (filepath .Join (dir , "log%Y%m%d%H%M%S" ), options ... )
106
+ if ! assert .NoError (t , err , `rotatelogs.New should succeed` ) {
107
+ return
108
+ }
109
+ defer rl .Close ()
78
110
79
- err = os .Chtimes (fn , dummyTime , dummyTime )
80
- if err != nil {
81
- t .Errorf ("Failed to change access/modification times for %s: %s" , fn , err )
82
- }
111
+ str := "Hello, World"
112
+ n , err := rl .Write ([]byte (str ))
113
+ if ! assert .NoError (t , err , "rl.Write should succeed" ) {
114
+ return
115
+ }
83
116
84
- fi , err := os .Stat (fn )
85
- if err != nil {
86
- t .Errorf ("Failed to stat %s: %s" , fn , err )
87
- }
117
+ if ! assert .Len (t , str , n , "rl.Write should succeed" ) {
118
+ return
119
+ }
88
120
89
- if ! fi .ModTime ().Equal (dummyTime ) {
90
- t .Errorf ("Failed to chtime for %s (expected %s, got %s)" , fn , fi .ModTime (), dummyTime )
91
- }
121
+ fn := rl .CurrentFileName ()
122
+ if fn == "" {
123
+ t .Errorf ("Could not get filename %s" , fn )
124
+ }
92
125
93
- clock .Advance (time .Duration (7 * 24 * time .Hour ))
126
+ content , err := ioutil .ReadFile (fn )
127
+ if err != nil {
128
+ t .Errorf ("Failed to read file %s: %s" , fn , err )
129
+ }
94
130
95
- // This next Write() should trigger Rotate()
96
- rl .Write ([]byte (str ))
97
- newfn := rl .CurrentFileName ()
98
- if newfn == fn {
99
- t .Errorf (`New file name and old file name should not match ("%s" != "%s")` , fn , newfn )
100
- }
131
+ if string (content ) != str {
132
+ t .Errorf (`File content does not match (was "%s")` , content )
133
+ }
101
134
102
- content , err = ioutil . ReadFile ( newfn )
103
- if err != nil {
104
- t .Errorf ("Failed to read file %s: %s" , newfn , err )
105
- }
135
+ err = os . Chtimes ( fn , dummyTime , dummyTime )
136
+ if err != nil {
137
+ t .Errorf ("Failed to change access/modification times for %s: %s" , fn , err )
138
+ }
106
139
107
- if string (content ) != str {
108
- t .Errorf (`File content does not match (was "%s")` , content )
109
- }
140
+ fi , err := os .Stat (fn )
141
+ if err != nil {
142
+ t .Errorf ("Failed to stat %s: %s" , fn , err )
143
+ }
110
144
111
- time .Sleep (time .Second )
145
+ if ! fi .ModTime ().Equal (dummyTime ) {
146
+ t .Errorf ("Failed to chtime for %s (expected %s, got %s)" , fn , fi .ModTime (), dummyTime )
147
+ }
112
148
113
- // fn was declared above, before mocking CurrentTime
114
- // Old files should have been unlinked
115
- _ , err = os .Stat (fn )
116
- if ! assert .Error (t , err , "os.Stat should have failed" ) {
117
- return
118
- }
149
+ clock .Advance (time .Duration (7 * 24 * time .Hour ))
119
150
120
- linkDest , err := os .Readlink (linkName )
121
- if err != nil {
122
- t .Errorf ("Failed to readlink %s: %s" , linkName , err )
123
- }
151
+ // This next Write() should trigger Rotate()
152
+ rl .Write ([]byte (str ))
153
+ newfn := rl .CurrentFileName ()
154
+ if newfn == fn {
155
+ t .Errorf (`New file name and old file name should not match ("%s" != "%s")` , fn , newfn )
156
+ }
157
+
158
+ content , err = ioutil .ReadFile (newfn )
159
+ if err != nil {
160
+ t .Errorf ("Failed to read file %s: %s" , newfn , err )
161
+ }
162
+
163
+ if string (content ) != str {
164
+ t .Errorf (`File content does not match (was "%s")` , content )
165
+ }
166
+
167
+ time .Sleep (time .Second )
168
+
169
+ // fn was declared above, before mocking CurrentTime
170
+ // Old files should have been unlinked
171
+ _ , err = os .Stat (fn )
172
+ if ! assert .Error (t , err , "os.Stat should have failed" ) {
173
+ return
174
+ }
124
175
125
- if linkDest != newfn {
126
- t .Errorf (`Symlink destination does not match expected filename ("%s" != "%s")` , newfn , linkDest )
176
+ if fn := tc .CheckExtras ; fn != nil {
177
+ if ! fn (t , rl , dir ) {
178
+ return
179
+ }
180
+ }
181
+ })
127
182
}
128
183
}
129
184
@@ -396,13 +451,13 @@ func TestGHIssue23(t *testing.T) {
396
451
Clock rotatelogs.Clock
397
452
}{
398
453
{
399
- Expected : filepath .Join (dir , strings .ToLower (strings .Replace (locName , "/" , "_" , - 1 )) + ".201806010000.log" ),
454
+ Expected : filepath .Join (dir , strings .ToLower (strings .Replace (locName , "/" , "_" , - 1 ))+ ".201806010000.log" ),
400
455
Clock : ClockFunc (func () time.Time {
401
456
return time .Date (2018 , 6 , 1 , 3 , 18 , 0 , 0 , loc )
402
457
}),
403
458
},
404
459
{
405
- Expected : filepath .Join (dir , strings .ToLower (strings .Replace (locName , "/" , "_" , - 1 )) + ".201712310000.log" ),
460
+ Expected : filepath .Join (dir , strings .ToLower (strings .Replace (locName , "/" , "_" , - 1 ))+ ".201712310000.log" ),
406
461
Clock : ClockFunc (func () time.Time {
407
462
return time .Date (2017 , 12 , 31 , 23 , 52 , 0 , 0 , loc )
408
463
}),
@@ -487,7 +542,7 @@ func TestForceNewFile(t *testing.T) {
487
542
}
488
543
}
489
544
490
- })
545
+ })
491
546
492
547
t .Run ("Force a new file with Rotate" , func (t * testing.T ) {
493
548
@@ -506,7 +561,7 @@ func TestForceNewFile(t *testing.T) {
506
561
return
507
562
}
508
563
rl .Write ([]byte ("Hello, World" ))
509
- rl .Write ([]byte (fmt .Sprintf ("%d" , i )))
564
+ rl .Write ([]byte (fmt .Sprintf ("%d" , i )))
510
565
assert .FileExists (t , rl .CurrentFileName (), "file does not exist %s" , rl .CurrentFileName ())
511
566
content , err := ioutil .ReadFile (rl .CurrentFileName ())
512
567
if ! assert .NoError (t , err , "ioutil.ReadFile %s should succeed" , rl .CurrentFileName ()) {
@@ -528,4 +583,3 @@ func TestForceNewFile(t *testing.T) {
528
583
}
529
584
})
530
585
}
531
-
0 commit comments