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