Files
log/helper_test.go
T

180 lines
4.2 KiB
Go

package log
import (
"os"
"path/filepath"
"strings"
"testing"
"time"
)
// Assertion helpers replacing testify.
// must* variants abort via Fatal and are restricted to the test goroutine.
// Non-fatal variants are safe to call from spawned goroutines.
func equal[T comparable](tb testing.TB, got, want T, ctx string) bool {
tb.Helper()
if got != want {
tb.Errorf("%s: got %#v, want %#v", ctx, got, want)
return false
}
return true
}
func mustEqual[T comparable](tb testing.TB, got, want T, ctx string) {
tb.Helper()
if got != want {
tb.Fatalf("%s: got %#v, want %#v", ctx, got, want)
}
}
func isTrue(tb testing.TB, cond bool, ctx string) bool {
tb.Helper()
if !cond {
tb.Errorf("%s: expected true", ctx)
return false
}
return true
}
func isFalse(tb testing.TB, cond bool, ctx string) bool {
tb.Helper()
if cond {
tb.Errorf("%s: expected false", ctx)
return false
}
return true
}
func noErr(tb testing.TB, err error, ctx string) {
tb.Helper()
if err != nil {
tb.Errorf("%s: unexpected error: %v", ctx, err)
}
}
func mustNoErr(tb testing.TB, err error, ctx string) {
tb.Helper()
if err != nil {
tb.Fatalf("%s: unexpected error: %v", ctx, err)
}
}
// errContains requires a non-nil error whose message contains sub.
func errContains(tb testing.TB, err error, sub, ctx string) {
tb.Helper()
switch {
case err == nil:
tb.Errorf("%s: expected error containing %q, got nil", ctx, sub)
case !strings.Contains(err.Error(), sub):
tb.Errorf("%s: error %q does not contain %q", ctx, err, sub)
}
}
func mustErr(tb testing.TB, err error, ctx string) {
tb.Helper()
if err == nil {
tb.Fatalf("%s: expected error, got nil", ctx)
}
}
func contains(tb testing.TB, haystack, needle, ctx string) {
tb.Helper()
if !strings.Contains(haystack, needle) {
tb.Errorf("%s: %q not found in:\n%s", ctx, needle, haystack)
}
}
func notContains(tb testing.TB, haystack, needle, ctx string) {
tb.Helper()
if strings.Contains(haystack, needle) {
tb.Errorf("%s: %q unexpectedly present in:\n%s", ctx, needle, haystack)
}
}
// mustEventually polls cond until true or timeout. Replaces sleep-and-check loops
// against the asynchronous processor.
func mustEventually(tb testing.TB, timeout time.Duration, ctx string, cond func() bool) {
tb.Helper()
deadline := time.Now().Add(timeout)
for {
if cond() {
return
}
if time.Now().After(deadline) {
tb.Fatalf("%s: condition not met within %v", ctx, timeout)
}
time.Sleep(5 * time.Millisecond)
}
}
// newTestLogger returns a started file-backed logger in a per-test temp directory.
// Shutdown is registered as cleanup, ordered before temp dir removal.
func newTestLogger(tb testing.TB) (*Logger, string) {
tb.Helper()
dir := tb.TempDir()
logger := NewLogger()
cfg := DefaultConfig()
cfg.EnableConsole = false
cfg.EnableFile = true
cfg.Directory = dir
cfg.BufferSize = 1000
cfg.FlushIntervalMs = 10
mustNoErr(tb, logger.ApplyConfig(cfg), "ApplyConfig")
mustNoErr(tb, logger.Start(), "Start")
tb.Cleanup(func() { _ = logger.Shutdown() })
return logger, dir
}
// readLog returns the contents of the active log file.
func readLog(tb testing.TB, dir string) string {
tb.Helper()
data, err := os.ReadFile(filepath.Join(dir, "log.log"))
if err != nil {
tb.Fatalf("read log file: %v", err)
}
return string(data)
}
// readAllLogs concatenates every *.log file in dir. Required wherever rotation
// may split output across files. Directory order, not chronological; use only
// for substring assertions.
func readAllLogs(tb testing.TB, dir string) string {
tb.Helper()
entries, err := os.ReadDir(dir)
if err != nil {
tb.Fatalf("read dir %s: %v", dir, err)
}
var sb strings.Builder
for _, e := range entries {
if e.IsDir() || !strings.HasSuffix(e.Name(), ".log") {
continue
}
data, err := os.ReadFile(filepath.Join(dir, e.Name()))
if err != nil {
tb.Fatalf("read %s: %v", e.Name(), err)
}
sb.Write(data)
}
return sb.String()
}
// countLogFiles returns the number of *.log entries in dir.
func countLogFiles(tb testing.TB, dir string) int {
tb.Helper()
entries, err := os.ReadDir(dir)
if err != nil {
tb.Fatalf("read dir %s: %v", dir, err)
}
n := 0
for _, e := range entries {
if !e.IsDir() && strings.HasSuffix(e.Name(), ".log") {
n++
}
}
return n
}