mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 22:56:43 +00:00
internal/testlog: refactor test-case to be table-driven. adapt the test-logger to take T as an interface to enable log output capture in the unit test.
This commit is contained in:
parent
8f1a56bb4e
commit
8c2236e586
3 changed files with 73 additions and 13 deletions
|
|
@ -21,23 +21,30 @@ import (
|
|||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"log/slog"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
)
|
||||
|
||||
const (
|
||||
termTimeFormat = "01-02|15:04:05.000"
|
||||
)
|
||||
|
||||
// T wraps methods from testing.T used by the test logger into an interface.
|
||||
// It is specified so that unit tests can instantiate the logger with an
|
||||
// implementation of T which can capture the output of logging statements
|
||||
// from T.Logf, as this cannot be using testing.T.
|
||||
type T interface {
|
||||
Logf(format string, args ...any)
|
||||
Helper()
|
||||
}
|
||||
|
||||
// logger implements log.Logger such that all output goes to the unit test log via
|
||||
// t.Logf(). All methods in between logger.Trace, logger.Debug, etc. are marked as test
|
||||
// helpers, so the file and line number in unit test output correspond to the call site
|
||||
// which emitted the log message.
|
||||
type logger struct {
|
||||
t *testing.T
|
||||
t T
|
||||
l log.Logger
|
||||
mu *sync.Mutex
|
||||
h *bufHandler
|
||||
|
|
@ -78,7 +85,7 @@ func (h *bufHandler) WithGroup(_ string) slog.Handler {
|
|||
}
|
||||
|
||||
// Logger returns a logger which logs to the unit test log of t.
|
||||
func Logger(t *testing.T, level slog.Level) log.Logger {
|
||||
func Logger(t T, level slog.Level) log.Logger {
|
||||
handler := bufHandler{
|
||||
buf: []slog.Record{},
|
||||
attrs: []slog.Attr{},
|
||||
|
|
|
|||
|
|
@ -1,16 +1,69 @@
|
|||
package testlog
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
)
|
||||
|
||||
func TestLogging(t *testing.T) {
|
||||
l := Logger(t, log.LevelInfo)
|
||||
subLogger := l.New("foobar", 123)
|
||||
|
||||
l.Info("Visible")
|
||||
subLogger.Info("Hide and seek") // this log is erroneously hidden in master, but fixed with this PR
|
||||
l.Info("Also visible")
|
||||
type mockT struct {
|
||||
out io.Writer
|
||||
}
|
||||
|
||||
func (t *mockT) Helper() {
|
||||
// noop for the purposes of unit tests
|
||||
}
|
||||
|
||||
func (t *mockT) Logf(format string, args ...any) {
|
||||
// we could gate this operation in a mutex, but because testlogger
|
||||
// only calls Logf with its internal mutex held, we just write output here
|
||||
var lineBuf bytes.Buffer
|
||||
if _, err := fmt.Fprintf(&lineBuf, fmt.Sprintf(format, args...)); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
sanitized := strings.Split(lineBuf.String(), "]")[1]
|
||||
if _, err := t.out.Write([]byte(sanitized)); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLogging(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
expected string
|
||||
run func(t *mockT)
|
||||
}{
|
||||
{
|
||||
"SubLogger",
|
||||
` Visible
|
||||
Hide and seek foobar=123
|
||||
Also visible
|
||||
`,
|
||||
func(t *mockT) {
|
||||
l := Logger(t, log.LevelInfo)
|
||||
subLogger := l.New("foobar", 123)
|
||||
|
||||
l.Info("Visible")
|
||||
subLogger.Info("Hide and seek")
|
||||
l.Info("Also visible")
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
outp := bytes.Buffer{}
|
||||
mock := mockT{&outp}
|
||||
tc.run(&mock)
|
||||
if outp.String() != tc.expected {
|
||||
fmt.Println("mismatch")
|
||||
fmt.Printf("'%s'\n", outp.String())
|
||||
fmt.Println("----")
|
||||
fmt.Printf("'%s'\n", tc.expected)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 81862e4848585a438d64f911a19b3825f0f4cd95
|
||||
Subproject commit faf33b471465d3c6cdc3d04fbd690895f78d33f2
|
||||
Loading…
Reference in a new issue