From fb95ec76dc3b4900137cc92a8807882f155b75ed Mon Sep 17 00:00:00 2001 From: Doug Lauder Date: Tue, 24 Aug 2021 17:36:56 -0300 Subject: [PATCH] added test logger support (#26) --- buffer.go | 28 ++++++++++++++++ targets/testing.go | 72 +++++++++++++++++++++++++++++++++++++++++ targets/testing_test.go | 20 ++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 buffer.go create mode 100644 targets/testing.go create mode 100644 targets/testing_test.go diff --git a/buffer.go b/buffer.go new file mode 100644 index 0000000..42bf525 --- /dev/null +++ b/buffer.go @@ -0,0 +1,28 @@ +package logr + +import ( + "bytes" + "sync" +) + +// Buffer provides a thread-safe buffer useful for logging to memory in unit tests. +type Buffer struct { + buf bytes.Buffer + mux sync.Mutex +} + +func (b *Buffer) Read(p []byte) (n int, err error) { + b.mux.Lock() + defer b.mux.Unlock() + return b.buf.Read(p) +} +func (b *Buffer) Write(p []byte) (n int, err error) { + b.mux.Lock() + defer b.mux.Unlock() + return b.buf.Write(p) +} +func (b *Buffer) String() string { + b.mux.Lock() + defer b.mux.Unlock() + return b.buf.String() +} diff --git a/targets/testing.go b/targets/testing.go new file mode 100644 index 0000000..ea3df70 --- /dev/null +++ b/targets/testing.go @@ -0,0 +1,72 @@ +package targets + +import ( + "strings" + "sync" + "testing" + + "github.com/mattermost/logr/v2" + "github.com/mattermost/logr/v2/formatters" +) + +// Testing is a simple log target that writes to a (*testing.T) log. +type Testing struct { + mux sync.Mutex + t *testing.T +} + +func NewTestingTarget(t *testing.T) *Testing { + return &Testing{ + t: t, + } +} + +// Init is called once to initialize the target. +func (tt *Testing) Init() error { + return nil +} + +// Write outputs bytes to this file target. +func (tt *Testing) Write(p []byte, rec *logr.LogRec) (int, error) { + tt.mux.Lock() + defer tt.mux.Unlock() + + if tt.t != nil { + s := strings.TrimSpace(string(p)) + tt.t.Log(s) + } + return len(p), nil +} + +// Shutdown is called once to free/close any resources. +// Target queue is already drained when this is called. +func (tt *Testing) Shutdown() error { + tt.mux.Lock() + defer tt.mux.Unlock() + + tt.t = nil + return nil +} + +// CreateTestLogger creates a logger for unit tests. Log records are output to `(*testing.T).Log`. +// A new logger is returned along with a method to shutdown the new logger. +func CreateTestLogger(t *testing.T, levels ...logr.Level) (logger logr.Logger, shutdown func() error) { + lgr, _ := logr.New() + filter := logr.NewCustomFilter(levels...) + formatter := &formatters.Plain{EnableCaller: true} + target := NewTestingTarget(t) + + if err := lgr.AddTarget(target, "test", filter, formatter, 1000); err != nil { + t.Fail() + } + shutdown = func() error { + err := lgr.Shutdown() + if err != nil { + target.mux.Lock() + target.t.Error("error shutting down test logger", err) + target.mux.Unlock() + } + return err + } + return lgr.NewLogger(), shutdown +} diff --git a/targets/testing_test.go b/targets/testing_test.go new file mode 100644 index 0000000..9e39718 --- /dev/null +++ b/targets/testing_test.go @@ -0,0 +1,20 @@ +package targets + +import ( + "testing" + + "github.com/mattermost/logr/v2" +) + +func TestCreateTestLogger(t *testing.T) { + logger, shutdown := CreateTestLogger(t, logr.Debug, logr.Info) + defer shutdown() + + for i := 0; i < 10; i++ { + if i%2 == 0 { + logger.Debug("counting even", logr.Int("count", i)) + } else { + logger.Info("counting odd", logr.Int("count", i)) + } + } +}