Skip to content

Commit

Permalink
internal/log: Improve API for testing (#916)
Browse files Browse the repository at this point in the history
internal/log: Improve API for testing

I just noticed that d9472a0 caused the profiler package to always emit
some log output, regardless of `go test -v` being used or not. I'm very
sorry about this. IMO tests should never print to stdout unless
requested.

This patch is my attempt to fix this by making it easy for individual
tests to capture the log output (see UseLogger, RecordLogger). I've also
added DiscardLogger since it can be very convenient for tests that want
to ignore log output without capturing it. Arguably RecordLogger could
be used for this as well, but that would do a poor job of capturing the
intend of such code.
  • Loading branch information
felixge authored May 4, 2021
1 parent b74a5df commit 91fbc34
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 2 deletions.
37 changes: 35 additions & 2 deletions internal/log/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,17 @@ var (
logger ddtrace.Logger = &defaultLogger{l: log.New(os.Stderr, "", log.LstdFlags)}
)

// UseLogger sets l as the active logger.
func UseLogger(l ddtrace.Logger) {
// UseLogger sets l as the active logger and returns a function to restore the
// previous logger. The return value is mostly useful when testing.
func UseLogger(l ddtrace.Logger) (undo func()) {
Flush()
mu.Lock()
defer mu.Unlock()
old := logger
logger = l
return func() {
logger = old
}
}

// SetLevel sets the given lvl for logging.
Expand Down Expand Up @@ -172,3 +177,31 @@ func printMsg(lvl, format string, a ...interface{}) {
type defaultLogger struct{ l *log.Logger }

func (p *defaultLogger) Log(msg string) { p.l.Print(msg) }

// DiscardLogger discards every call to Log().
type DiscardLogger struct{}

// Log implements ddtrace.Logger.
func (d DiscardLogger) Log(msg string) {}

// RecordLogger records every call to Log() and makes it available via Logs().
type RecordLogger struct {
m sync.Mutex
logs []string
}

// Log implements ddtrace.Logger.
func (r *RecordLogger) Log(msg string) {
r.m.Lock()
defer r.m.Unlock()
r.logs = append(r.logs, msg)
}

// Logs returns the ordered list of logs recorded by the logger.
func (r *RecordLogger) Logs() []string {
r.m.Lock()
defer r.m.Unlock()
copied := make([]string, len(r.logs))
copy(copied, r.logs)
return copied
}
12 changes: 12 additions & 0 deletions profiler/profiler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (
"testing"
"time"

"gopkg.in/DataDog/dd-trace-go.v1/internal/log"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -59,20 +61,30 @@ func TestStart(t *testing.T) {
})

t.Run("options/GoodAPIKey/Agent", func(t *testing.T) {
rl := &log.RecordLogger{}
defer log.UseLogger(rl)()

err := Start(WithAPIKey("12345678901234567890123456789012"))
defer Stop()
assert.Nil(t, err)
assert.Equal(t, activeProfiler.cfg.agentURL, activeProfiler.cfg.targetURL)
assert.Equal(t, 1, len(rl.Logs()))
assert.Contains(t, rl.Logs()[0], "profiler.WithAPIKey")
})

t.Run("options/GoodAPIKey/Agentless", func(t *testing.T) {
rl := &log.RecordLogger{}
defer log.UseLogger(rl)()

err := Start(
WithAPIKey("12345678901234567890123456789012"),
WithAgentlessUpload(),
)
defer Stop()
assert.Nil(t, err)
assert.Equal(t, activeProfiler.cfg.apiURL, activeProfiler.cfg.targetURL)
assert.Equal(t, 1, len(rl.Logs()))
assert.Contains(t, rl.Logs()[0], "profiler.WithAgentlessUpload")
})

t.Run("options/BadAPIKey", func(t *testing.T) {
Expand Down

0 comments on commit 91fbc34

Please sign in to comment.