@@ -11,6 +11,7 @@ import (
1111 "time"
1212
1313 "github.com/docker/docker/daemon/logger"
14+ "github.com/docker/docker/pkg/pubsub"
1415 "github.com/docker/docker/pkg/tailfile"
1516 "gotest.tools/v3/assert"
1617)
@@ -235,3 +236,66 @@ func TestFollowLogsProducerGone(t *testing.T) {
235236 default :
236237 }
237238}
239+
240+ func TestCheckCapacityAndRotate (t * testing.T ) {
241+ dir , err := ioutil .TempDir ("" , t .Name ())
242+ assert .NilError (t , err )
243+ defer os .RemoveAll (dir )
244+
245+ f , err := ioutil .TempFile (dir , "log" )
246+ assert .NilError (t , err )
247+
248+ l := & LogFile {
249+ f : f ,
250+ capacity : 5 ,
251+ maxFiles : 3 ,
252+ compress : true ,
253+ notifyRotate : pubsub .NewPublisher (0 , 1 ),
254+ perms : 0600 ,
255+ marshal : func (msg * logger.Message ) ([]byte , error ) {
256+ return msg .Line , nil
257+ },
258+ }
259+ defer l .Close ()
260+
261+ assert .NilError (t , l .WriteLogEntry (& logger.Message {Line : []byte ("hello world!" )}))
262+
263+ dStringer := dirStringer {dir }
264+
265+ _ , err = os .Stat (f .Name () + ".1" )
266+ assert .Assert (t , os .IsNotExist (err ), dStringer )
267+
268+ assert .NilError (t , l .WriteLogEntry (& logger.Message {Line : []byte ("hello world!" )}))
269+ _ , err = os .Stat (f .Name () + ".1" )
270+ assert .NilError (t , err , dStringer )
271+
272+ assert .NilError (t , l .WriteLogEntry (& logger.Message {Line : []byte ("hello world!" )}))
273+ _ , err = os .Stat (f .Name () + ".1" )
274+ assert .NilError (t , err , dStringer )
275+ _ , err = os .Stat (f .Name () + ".2.gz" )
276+ assert .NilError (t , err , dStringer )
277+
278+ // Now let's simulate a failed rotation where the file was able to be closed but something else happened elsewhere
279+ // down the line.
280+ // We want to make sure that we can recover in the case that `l.f` was closed while attempting a rotation.
281+ l .f .Close ()
282+ assert .NilError (t , l .WriteLogEntry (& logger.Message {Line : []byte ("hello world!" )}))
283+ }
284+
285+ type dirStringer struct {
286+ d string
287+ }
288+
289+ func (d dirStringer ) String () string {
290+ ls , err := ioutil .ReadDir (d .d )
291+ if err != nil {
292+ return ""
293+ }
294+ var s strings.Builder
295+ s .WriteString ("\n " )
296+
297+ for _ , fi := range ls {
298+ s .WriteString (fi .Name () + "\n " )
299+ }
300+ return s .String ()
301+ }
0 commit comments