testsuite

package module
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 31, 2023 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package testsuite provides a common test suite for logiface, which operates by means of parsing (and validating) the log output.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EventsDiff

func EventsDiff(expected, actual []Event) string

func EventsEqual

func EventsEqual(a, b []Event) bool

func TestLevelMethods

func TestLevelMethods[E logiface.Event](t *testing.T, cfg Config[E])

TestLevelMethods is part of TestSuite, it tests the level methods on the logger.

func TestLoggerLogMethod

func TestLoggerLogMethod[E logiface.Event](t *testing.T, cfg Config[E])

TestLoggerLogMethod is part of TestSuite, it tests logiface.Logger.Log.

func TestParallel

func TestParallel[E logiface.Event](t *testing.T, cfg Config[E])

TestParallel tests the integrity of parallel writes.

func TestSuite

func TestSuite[E logiface.Event](t *testing.T, cfg Config[E])

TestSuite runs the test suite, using the provided configuration.

Types

type Config

type Config[E logiface.Event] struct {
	// LoggerFactory implements initialization of a logger implementation.
	LoggerFactory func(cfg LoggerRequest[E]) LoggerResponse[E]

	// WriteTimeout is the max amount of time that tests should wait for a log to be written.
	WriteTimeout time.Duration

	// AlertCallsOsExit indicates that the logger implementation calls os.Exit, e.g. when mapped to "fatal"
	// (as recommended).
	AlertCallsOsExit bool

	// EmergencyPanics indicates that the logger implementation panics, e.g. when mapped to "panic"
	// (as recommended).
	EmergencyPanics bool

	// LogsEmptyMessage indicates that the logger implementation includes the relevant message field in events
	// even when the message is empty.
	LogsEmptyMessage bool
}

Config models the configuration used to initialize the test suite.

func (Config[E]) HandleEmergencyPanic

func (x Config[E]) HandleEmergencyPanic(t *testing.T, fn func())

func (Config[E]) RunTest

func (x Config[E]) RunTest(req TestRequest[E], test func(res TestResponse[E]))

RunTest initializes a logger, providing it to the test func. The logger will be torn down automatically, after the test func returns.

type Event

type Event struct {
	Level   logiface.Level
	Message *string
	Error   *string
	// Fields is a map of field names to values, and must be the same format encoding/json.Unmarshal.
	// It must include all fields added via the logiface.Event interface, except Message and Error.
	// It must not include any additional fields (e.g. added by the logger, such as timestamp).
	Fields map[string]interface{}
}

Event models a parsed log event

func (Event) Equal

func (x Event) Equal(ev Event) bool

func (Event) String

func (x Event) String() string

type LoggerRequest

type LoggerRequest[E logiface.Event] struct {
	// Writer that must be used
	Writer io.Writer

	// Options specified by the test
	Options []logiface.Option[E]
}

LoggerRequest models a request for a logger from a test.

type LoggerResponse

type LoggerResponse[E logiface.Event] struct {
	// Logger is the configured logger
	Logger *logiface.Logger[E]

	// LevelMapping returns the expected level mapping, after being munged through the logger's native
	// level implementation / configuration (where disabled indicates it won't be logged).
	LevelMapping func(lvl logiface.Level) logiface.Level

	// ParseEvent reads and parses the next event from the stream, returning any read but unused remainder.
	// Returning a nil event indicates EOF.
	ParseEvent func(r io.Reader) (remainder []byte, event *Event)

	// FormatTime is optional, and must be used if logiface.Event.AddTime is implemented
	FormatTime func(t time.Time) any

	// FormatDuration is optional, and must be used if logiface.Event.AddDuration is implemented
	FormatDuration func(d time.Duration) any

	// FormatBase64Bytes is optional, and must be used if logiface.Event.AddBase64Bytes is implemented
	FormatBase64Bytes func(b []byte, enc *base64.Encoding) any

	// FormatInt64 is optional, and must be used if logiface.Event.AddInt64 is implemented
	FormatInt64 func(i int64) any

	// FormatUint64 is optional, and must be used if logiface.Event.AddUint64 is implemented
	FormatUint64 func(u uint64) any
}

LoggerResponse models a response containing a logger for a test.

type TestRequest

type TestRequest[E logiface.Event] struct {
	// Level specifies the level that the logger should be configured with.
	Level logiface.Level
}

TestRequest models the input from a test case, when it requests a logger.

type TestResponse

type TestResponse[E logiface.Event] struct {
	// Logger is the configured logger
	Logger *logiface.Logger[E]

	// LevelMapping returns the expected level mapping, after being munged through the logger's native
	// level implementation / configuration (where disabled indicates it won't be logged).
	LevelMapping func(lvl logiface.Level) logiface.Level

	// Events is the output channel for log events. It is buffered, but may need to be read, for some tests
	// (no current tests require this). It is closed once the writer is closed.
	Events <-chan Event

	// SendEOF indicates that the writer has reached EOF (all logs have been written).
	// This will (indirectly) close Events.
	SendEOF func()

	// ReceiveTimeout is determined by Config.WriteTimeout
	ReceiveTimeout time.Duration

	// FormatTime is a normalizer, used by normalizeEvent.
	FormatTime func(t time.Time) any

	// FormatDuration is a normalizer, used by normalizeEvent.
	FormatDuration func(d time.Duration) any

	// FormatBase64Bytes is a normalizer, used by normalizeEvent.
	FormatBase64Bytes func(b []byte, enc *base64.Encoding) any

	// FormatInt64 is a normalizer, used by normalizeEvent.
	FormatInt64 func(i int64) any

	// FormatUint64 is a normalizer, used by normalizeEvent.
	FormatUint64 func(u uint64) any
}

TestResponse models the configured logger etc, provided to a test case.

func (TestResponse[E]) ReceiveEvent

func (x TestResponse[E]) ReceiveEvent() (ev Event, ok bool)

func (TestResponse[E]) SendEOFExpectNoEvents

func (x TestResponse[E]) SendEOFExpectNoEvents(t *testing.T) bool

SendEOFExpectNoEvents does what it says on the tin, calling SendEOF, then receiving from the Events channel, asserting that it is closed, returning false if it is not (if t is nil - if it's non-nil it will call t.Fatal).

WARNING: This may not be safe to defer, as exceptional / fatal cases could result in a deadlock, e.g. if the Events buffer is full.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL