github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/daemon/logger/loggerutils/logfile_race_test.go (about) 1 //go:build race 2 // +build race 3 4 package loggerutils // import "github.com/docker/docker/daemon/logger/loggerutils" 5 6 import ( 7 "context" 8 "fmt" 9 "io" 10 "path/filepath" 11 "testing" 12 "time" 13 14 "github.com/docker/docker/api/types/backend" 15 "github.com/docker/docker/daemon/logger" 16 "github.com/docker/docker/pkg/tailfile" 17 "golang.org/x/sync/errgroup" 18 "gotest.tools/v3/assert" 19 ) 20 21 func TestConcurrentLogging(t *testing.T) { 22 const ( 23 containers = 5 24 loggers = 3 // loggers per container 25 messages = 50 // messages per logger 26 27 capacity = 256 28 maxFiles = 3 29 compress = true 30 ) 31 getTailReader := func(ctx context.Context, r SizeReaderAt, lines int) (io.Reader, int, error) { 32 return tailfile.NewTailReader(ctx, r, lines) 33 } 34 createDecoder := func(io.Reader) Decoder { 35 return dummyDecoder{} 36 } 37 marshal := func(msg *logger.Message) []byte { 38 return []byte(fmt.Sprintf( 39 "Line=%q Source=%q Timestamp=%v Attrs=%v PLogMetaData=%#v Err=%v", 40 msg.Line, msg.Source, msg.Timestamp, msg.Attrs, msg.PLogMetaData, msg.Err, 41 )) 42 } 43 g, ctx := errgroup.WithContext(context.Background()) 44 for ct := 0; ct < containers; ct++ { 45 ct := ct 46 dir := t.TempDir() 47 g.Go(func() (err error) { 48 logfile, err := NewLogFile(filepath.Join(dir, "log.log"), capacity, maxFiles, compress, createDecoder, 0644, getTailReader) 49 if err != nil { 50 return err 51 } 52 defer func() { 53 if cErr := logfile.Close(); cErr != nil && err == nil { 54 err = cErr 55 } 56 }() 57 lg, ctx := errgroup.WithContext(ctx) 58 for ln := 0; ln < loggers; ln++ { 59 ln := ln 60 lg.Go(func() error { 61 for m := 0; m < messages; m++ { 62 select { 63 case <-ctx.Done(): 64 return ctx.Err() 65 default: 66 } 67 timestamp := time.Now() 68 msg := logger.NewMessage() 69 msg.Line = append(msg.Line, fmt.Sprintf("container=%v logger=%v msg=%v", ct, ln, m)...) 70 msg.Source = "stdout" 71 msg.Timestamp = timestamp 72 msg.Attrs = append(msg.Attrs, backend.LogAttr{Key: "foo", Value: "bar"}) 73 msg.PLogMetaData = &backend.PartialLogMetaData{ID: fmt.Sprintf("%v %v %v", ct, ln, m), Ordinal: 1, Last: true} 74 marshalled := marshal(msg) 75 logger.PutMessage(msg) 76 if err := logfile.WriteLogEntry(timestamp, marshalled); err != nil { 77 return err 78 } 79 } 80 return nil 81 }) 82 } 83 return lg.Wait() 84 }) 85 } 86 assert.NilError(t, g.Wait()) 87 }