tests

package
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 31, 2024 License: MIT Imports: 28 Imported by: 0

README

Technical Details for SlogBenchmarkSuite

Benchmark Suite

The core code for verifying slog handlers is in bench/tests/SlogBenchmarkSuite, which was generated from scratch for this repository in the absence of usable preexisting alternatives.

The bench/tests directory contains, at this time (2024-01-16), nothing but the code for SlogBenchmarkSuite. Since there are a lot of tests they have been broken up into separate files by category or functionality.

The main files are:

  • suite.go
    Declares SlogBenchmarkSuite and a few top-level methods.
  • benchmarks.go
    Actual benchmark tests.
  • checks.go
    Common checks used by various benchmark tests.
  • logging.go
    Code to load test data cases from logging.txt
  • utility.go
    SlogTestSuite utility methods used in multiple places in the test suite.

Supporting files:

  • README.md
    The file you are currently reading.
  • doc.go
    Source code documentation for the bench/tests package.
  • data.go
    A few data items that are used in multiple places in the test suite.
  • warnings.go
    Custom internal/warning.Manager for the benchmark test suite.

Inherited:

  • infra/warning.Manager
    The code that manages benchmark warnings is currently located in the internal/test package.

Benchmark Tests

Benchmark tests are defined by the Benchmark structure.

Test Execution

The main part of the test harness is in the bench/tests.Run function.

  • For each method name beginning with Benchmark:
    • Execute the method, returning an pointer to an object of class Benchmark.
    • If the Benchmark has a handler function[^1]
      then the Creator must be able to provide a Handler (some can't),
      or else a Warning is logged and the test is skipped.
    • If the Benchmark has a verify function to test the log output (or more accurately, to test the test itself) then:
      • Get a logger, using the handler function if present.
      • Run a single test using that logger.
      • Verify the output with the function.
    • If the -justTests flag is false (not set):
      • Get a logger, using the handler function if present.
      • The Go test harness is used to run the Benchmark test function in parallel in ever-larger batches until enough testing has been done.
      • The test harness emits a line of data with results of the test.

[^1]: A HandlerFn is used to adjust a newly created Handler prior to using it to create a custom Logger, instead of the normal mechanism which returns a generic Logger. Some Logger customisations must be done by manipulating the Handler in this fashion.

Documentation

Overview

Package tests defines the SlogBenchmarkSuite which runs various benchmark tests. A single large file has been broken up by category.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func BigGroup

func BigGroup() slog.Attr

BigGroup returns a nested group structure as an attribute.

func NewWarningManager

func NewWarningManager(name string) *warning.Manager

NewWarningManager generates an infra.Manager configured for SlogBenchmarkSuite.

func Run

func Run(b *testing.B, suite *SlogBenchmarkSuite)

Run all benchmark tests in the suite for the specified suite.

This is the core algorithm for the benchmark test harness. It handles running all tests using reflection.

Types

type Benchmark

type Benchmark struct {
	// Options is a required pointer to a preloaded slog.HandlerOptions object (e.g. infra.SimpleOptions).
	Options *slog.HandlerOptions

	// BenchmarkFn is a required BenchmarkFn which executes the actual benchmark test.
	BenchmarkFn

	// HandlerFn is an optional HandlerFn used to adjust the slog.Handler object
	// (if available from the infra.Creator for the benchmark) prior to using it to generate a slog.Logger object.
	HandlerFn

	// VerifyFn is an optional VerifyFn used to verify test log results.
	VerifyFn

	// DontCount is used to avoid double-checking the number of log lines written during the benchmark.
	// Normally a single line is generated for each benchmark execution,
	// so the log lines generated matches the number of executions of the BenchmarkFn,
	// but in some cases multiple lines are generated per execution.
	// This field is optional as its default value is false (number of lines/executions must match).
	DontCount bool
}

Benchmark objects are used to define benchmark tests.

Example
bm := &Benchmark{
	Options: infra.SimpleOptions(),
	BenchmarkFn: func(logger *slog.Logger) {
		logger.Info(message)
	},
	VerifyFn: matcher("Simple", expectedBasic()),
}
cr := slogjson.Creator()
var buffer bytes.Buffer
logger := slog.New(cr.NewHandler(&buffer, bm.Options))
bm.BenchmarkFn(logger)
var logMap map[string]any
_ = json.Unmarshal(buffer.Bytes(), &logMap)
fmt.Println(logMap["msg"])
Output:

This is a message

type BenchmarkFn

type BenchmarkFn func(logger *slog.Logger)

BenchmarkFn defines a function that executes a benchmark test.

type HandlerFn

type HandlerFn func(handler slog.Handler) slog.Handler

HandlerFn defines a function that adjusts a slog.Handler prior to using it to generate a slog.Logger. The general use for this is to apply WithAttrs and/or WithGroup methods to the handler.

type SlogBenchmarkSuite

type SlogBenchmarkSuite struct {
	infra.Creator
	*warning.Manager
	// contains filtered or unexported fields
}

SlogBenchmarkSuite implements the benchmark test harness.

func NewSlogBenchmarkSuite

func NewSlogBenchmarkSuite(creator infra.Creator) *SlogBenchmarkSuite

NewSlogBenchmarkSuite creates a new benchmark test suite for the specified Creator. The handler string must match the suffix of the name of the enclosing test. This is:

  • the string that will be matched from benchmark test output data,
  • the string that will be conveyed to the parser to match against warning data, and
  • the string that will be used as a tag for displaying server pages.

func (*SlogBenchmarkSuite) B

func (suite *SlogBenchmarkSuite) B() *testing.B

B retrieves the current *testing.B context.

func (*SlogBenchmarkSuite) BenchmarkAttributes

func (suite *SlogBenchmarkSuite) BenchmarkAttributes() *Benchmark

BenchmarkAttributes logs a message with a lot of attributes.

func (*SlogBenchmarkSuite) BenchmarkBigGroup

func (suite *SlogBenchmarkSuite) BenchmarkBigGroup() *Benchmark

BenchmarkBigGroup logs several levels of nested groups.

func (*SlogBenchmarkSuite) BenchmarkDisabled

func (suite *SlogBenchmarkSuite) BenchmarkDisabled() *Benchmark

BenchmarkDisabled logs at the wrong level and nothing comes out. The default logger is set to INFO, a DEBUG log message should be ignored.

func (*SlogBenchmarkSuite) BenchmarkKeyValues

func (suite *SlogBenchmarkSuite) BenchmarkKeyValues() *Benchmark

BenchmarkKeyValues logs a message with a lot of key value pairs.

func (*SlogBenchmarkSuite) BenchmarkLogging

func (suite *SlogBenchmarkSuite) BenchmarkLogging() *Benchmark

BenchmarkLogging logs a series of lines taken from Gin server output.

func (*SlogBenchmarkSuite) BenchmarkSimple

func (suite *SlogBenchmarkSuite) BenchmarkSimple() *Benchmark

BenchmarkSimple logs a simple line with just a message.

func (*SlogBenchmarkSuite) BenchmarkSimpleSource

func (suite *SlogBenchmarkSuite) BenchmarkSimpleSource() *Benchmark

BenchmarkSimpleSource logs a simple line with just a message and the AddSource option set so the slog.SourceKey group is created.

func (*SlogBenchmarkSuite) BenchmarkWithAttrsAttributes

func (suite *SlogBenchmarkSuite) BenchmarkWithAttrsAttributes() *Benchmark

BenchmarkWithAttrsAttributes logs a message and a lot of attributes to a logger created from a handler configure with a different lot of attributes.

func (*SlogBenchmarkSuite) BenchmarkWithAttrsKeyValues

func (suite *SlogBenchmarkSuite) BenchmarkWithAttrsKeyValues() *Benchmark

BenchmarkWithAttrsKeyValues logs a message and a lot of attributes to a logger created from a handler configure with a different lot of key value pairs.

func (*SlogBenchmarkSuite) BenchmarkWithAttrsSimple

func (suite *SlogBenchmarkSuite) BenchmarkWithAttrsSimple() *Benchmark

BenchmarkWithAttrsSimple logs a simple message to a logger created from a handler configure with a lot of attributes.

func (*SlogBenchmarkSuite) BenchmarkWithGroupAttributes

func (suite *SlogBenchmarkSuite) BenchmarkWithGroupAttributes() *Benchmark

BenchmarkWithGroupAttributes logs a message and a lot of attributes to a logger created from a handler configured with an open group.

func (*SlogBenchmarkSuite) BenchmarkWithGroupKeyValues

func (suite *SlogBenchmarkSuite) BenchmarkWithGroupKeyValues() *Benchmark

BenchmarkWithGroupKeyValues logs a message and a lot of key value pairs to a logger created from a handler configured with an open group.

func (*SlogBenchmarkSuite) SetB

func (suite *SlogBenchmarkSuite) SetB(b *testing.B)

SetB sets the current *testing.B context.

type Thing

type Thing struct {
	Name string
	Num  int
}

Thing is a test object used in logging tests. The struct and its fields are public since they must be accessible via reflection.

type VerifyFn

type VerifyFn func(captured []byte, logMap map[string]any, manager *warning.Manager) error

VerifyFn defines a function that is used to verify the functionality of a benchmark test. Verification makes certain that there is actually something happening in the benchmark (and that it is generating the expected output) to avoid having any zombie benchmarks that don't actually do anything.

Jump to

Keyboard shortcuts

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