2022-01-14 18:49:22 +00:00
|
|
|
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
|
2020-09-16 14:19:51 +00:00
|
|
|
// SPDX-License-Identifier: Apache-2.0
|
2020-09-14 17:57:07 +00:00
|
|
|
|
2021-12-10 22:22:36 +00:00
|
|
|
// Package testlogger wraps logr.Logger to allow for writing test assertions.
|
2020-09-14 17:57:07 +00:00
|
|
|
package testlogger
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2021-03-05 21:49:45 +00:00
|
|
|
"fmt"
|
2020-09-14 17:57:07 +00:00
|
|
|
"log"
|
|
|
|
"strings"
|
|
|
|
"sync"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/go-logr/logr"
|
|
|
|
"github.com/go-logr/stdr"
|
2021-03-05 21:49:45 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
2020-09-14 17:57:07 +00:00
|
|
|
)
|
|
|
|
|
2021-12-10 22:22:36 +00:00
|
|
|
// Logger wraps logr.Logger in a way that captures logs for test assertions.
|
2020-09-14 17:57:07 +00:00
|
|
|
type Logger struct {
|
2021-12-10 22:22:36 +00:00
|
|
|
Logger logr.Logger
|
2020-09-14 17:57:07 +00:00
|
|
|
t *testing.T
|
|
|
|
buffer syncBuffer
|
|
|
|
}
|
|
|
|
|
2022-04-16 02:43:53 +00:00
|
|
|
// Deprecated: Use plog.TestLogger or plog.TestZapr instead. This is meant for old tests only.
|
2020-09-14 17:57:07 +00:00
|
|
|
func New(t *testing.T) *Logger {
|
|
|
|
res := Logger{t: t}
|
|
|
|
res.Logger = stdr.New(log.New(&res.buffer, "", 0))
|
|
|
|
return &res
|
|
|
|
}
|
|
|
|
|
2022-04-16 02:43:53 +00:00
|
|
|
// Deprecated: Use plog.TestLogger or plog.TestZapr instead. This is meant for old tests only.
|
2021-12-10 22:22:36 +00:00
|
|
|
func NewLegacy(t *testing.T) *Logger {
|
|
|
|
res := New(t)
|
|
|
|
res.Logger = newStdLogger(log.New(&res.buffer, "", 0))
|
|
|
|
return res
|
|
|
|
}
|
|
|
|
|
2020-09-14 17:57:07 +00:00
|
|
|
// Lines returns the lines written to the test logger.
|
|
|
|
func (l *Logger) Lines() []string {
|
|
|
|
l.t.Helper()
|
|
|
|
l.buffer.mutex.Lock()
|
|
|
|
defer l.buffer.mutex.Unlock()
|
|
|
|
|
|
|
|
// Trim leading/trailing whitespace and omit empty lines.
|
|
|
|
var result []string
|
|
|
|
for _, line := range strings.Split(l.buffer.buffer.String(), "\n") {
|
|
|
|
line = strings.TrimSpace(line)
|
|
|
|
if line != "" {
|
|
|
|
result = append(result, line)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
2021-03-05 21:49:45 +00:00
|
|
|
// Expect the emitted lines to match known-good output.
|
|
|
|
func (l *Logger) Expect(expected []string) {
|
|
|
|
actual := l.Lines()
|
|
|
|
require.Equalf(l.t, expected, actual, "did not see expected log output, actual output:\n%#v", backtickStrings(actual))
|
|
|
|
}
|
|
|
|
|
2020-09-14 17:57:07 +00:00
|
|
|
// syncBuffer synchronizes access to a bytes.Buffer.
|
|
|
|
type syncBuffer struct {
|
|
|
|
mutex sync.Mutex
|
|
|
|
buffer bytes.Buffer
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *syncBuffer) Write(p []byte) (n int, err error) {
|
|
|
|
s.mutex.Lock()
|
|
|
|
defer s.mutex.Unlock()
|
|
|
|
return s.buffer.Write(p)
|
|
|
|
}
|
2021-03-05 21:49:45 +00:00
|
|
|
|
|
|
|
type backtickStrings []string
|
|
|
|
|
|
|
|
func (b backtickStrings) GoString() string {
|
|
|
|
lines := make([]string, 0, len(b))
|
|
|
|
for _, s := range b {
|
|
|
|
if strings.Contains(s, "`") {
|
|
|
|
s = fmt.Sprintf("%#v", s)
|
|
|
|
} else {
|
|
|
|
s = fmt.Sprintf("`%s`", s)
|
|
|
|
}
|
|
|
|
lines = append(lines, fmt.Sprintf("\t%s,", s))
|
|
|
|
}
|
|
|
|
return fmt.Sprintf("[]string{\n%s\n}", strings.Join(lines, "\n"))
|
|
|
|
}
|