package starlog import ( "context" "io" "sync" "testing" "time" ) type lockedWriter struct { mu sync.Mutex buf []byte } func (writer *lockedWriter) Write(data []byte) (int, error) { writer.mu.Lock() defer writer.mu.Unlock() writer.buf = append(writer.buf, data...) return len(data), nil } func TestConcurrentConfigAndLogging(t *testing.T) { writer := &lockedWriter{} logger := NewStarlog(writer) logger.SetShowStd(false) logger.SetShowColor(false) logger.SetShowOriginFile(false) logger.SetShowFuncName(false) logger.SetShowFlag(false) logger.SetPendingWriteLimit(256) stopCtx, cancel := context.WithTimeout(context.Background(), 300*time.Millisecond) defer cancel() var wait sync.WaitGroup wait.Add(4) go func() { defer wait.Done() for { select { case <-stopCtx.Done(): return default: logger.WithField("gid", 1).Info("hello") } } }() go func() { defer wait.Done() for { select { case <-stopCtx.Done(): return default: logger.SetColorMode(ColorModeOff) logger.SetColorMode(ColorModeLevelOnly) logger.SetColorMode(ColorModeFullLine) logger.SetShowFieldColor(true) logger.SetShowFieldColor(false) } } }() go func() { defer wait.Done() for { select { case <-stopCtx.Done(): return default: logger.SetFormatter(NewTextFormatter()) logger.SetFormatter(NewJSONFormatter()) logger.SetFormatter(nil) } } }() go func() { defer wait.Done() for { select { case <-stopCtx.Done(): return default: logger.StopWrite() logger.EnableWrite() logger.SetSwitching(true) logger.SetSwitching(false) } } }() wait.Wait() if logger.GetPendingDropCount() > 0 && logger.GetPendingWriteLimit() == 0 { t.Fatalf("pending drop count should not increase when limit disabled") } } func TestConcurrentSinkSwitchAndWrite(t *testing.T) { logger := NewStarlog(io.Discard) logger.SetShowStd(false) logger.SetShowColor(false) logger.SetPendingWriteLimit(64) logger.SetPendingDropPolicy(PendingDropOldest) stopCtx, cancel := context.WithTimeout(context.Background(), 250*time.Millisecond) defer cancel() var wait sync.WaitGroup wait.Add(3) go func() { defer wait.Done() for { select { case <-stopCtx.Done(): return default: logger.WithField("k", "v").Infoln("line") } } }() go func() { defer wait.Done() for { select { case <-stopCtx.Done(): return default: logger.SetWriter(io.Discard) logger.SetSink(nil) } } }() go func() { defer wait.Done() for { select { case <-stopCtx.Done(): return default: logger.SetSwitching(true) logger.SetSwitching(false) } } }() wait.Wait() } func TestConcurrentUpdateConfigAndLogging(t *testing.T) { writer := &lockedWriter{} logger := NewStarlog(writer) logger.SetShowStd(false) logger.SetShowColor(false) logger.SetShowOriginFile(false) logger.SetShowFuncName(false) logger.SetShowFlag(false) stopCtx, cancel := context.WithTimeout(context.Background(), 250*time.Millisecond) defer cancel() var wait sync.WaitGroup wait.Add(2) go func() { defer wait.Done() for { select { case <-stopCtx.Done(): return default: logger.WithField("k", "v").Info("line") } } }() go func() { defer wait.Done() for { select { case <-stopCtx.Done(): return default: logger.UpdateConfig(func(cfg *Config) { cfg.Level = LvDebug cfg.ShowColor = false cfg.OnlyColorLevel = false cfg.ShowFieldColor = false cfg.PendingWriteLimit = 128 cfg.PendingDropPolicy = PendingDropOldest }) } } }() wait.Wait() }