tests

package
v0.9.15-beta-15 Latest Latest
Warning

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

Go to latest
Published: May 7, 2024 License: MIT Imports: 18 Imported by: 0

README

Technical Details for SlogTestSuite

Testing Suite

The core code for verifying slog handlers is in verify/tests/SlogTestSuite. This type uses (and is composed with) stretchr/testify/suite.Suite. All the features of testify/suite are accessible to any SlogTestSuite or derivative.

The verify/tests directory contains, at this time (2024-01-15), nothing but the code for SlogTestSuite. 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 SlogTestSuite and a few top-level methods.
  • documented.go
    Tests based on slog documentation. Comments for the tests include links to referenced statements therein.
  • slogtest.go
    Tests based on slogtest/slogtest, a test harness (presumably) developed along with log/slog. Comments for the tests reference the original slogtest tests as well as a few links to documentation.
  • checks.go
    Subtest methods that are called from multiple tests or are really long. Think of these as complex assertions.
  • complex.go
    Algorithmically generated test cases.
  • duplicate.go
    Duplicate testing, which isn't currently regarded as an error. The status of this issue is currently under discussion.
  • other.go
    Tests that don't seem to fit into any other category. These include log level functionality and log record time format.
  • slogtest.go
    Verification tests that mimic those defined in slogtest.go and a test that actually executes the slogtest tests.
  • replace.go
  • 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 verify/tests package.
  • data.go
    A few data items that are used in multiple places in the test suite.
  • valuer.go
    A struct that implements the slog.LogValuer interface for testing.
  • warnings.go
    Warnings specific to the test suite.

Warnings

The verification test suite is based on stretchr/testify/suite.Suite. Running that code without the -useWarnings flag will result in error messages generated by the test suite. These messages can be confusing and difficult to parse.

In order to provide a more consistent, easy to understand output a secondary mechanism using "warnings" is used. The code that manages verification warnings is currently located in the infra package.

Usage

The following is a basic format for adding a warning to a pre-existing test:

	if !suite.HasWarning(warning.SomeWarning) {
		// Standard test assertions.
		// Failure here results in the usual test errors.
	} else if /* tests succeeds */ {
		// Warning is redundant, mark with AddUnused()
		suite.AddUnused(warning.SomeWarning, suite.Buffer.String())
	} else {
		// Warning not redundant, standard test assertions would fail,
		// Add the warning to the warning.Manager.
		suite.AddWarning(warning.SomeWarning, suite.Buffer.String(), "")
	}

More complex code will sometimes be required.

Notes:

  • The warning.Manager is embedded in the SlogTestSuite, so HasWarning, AddUnused, and AddWarning are all directly accessible.

Documentation

Overview

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

Index

Constants

This section is empty.

Variables

View Source
var Attributes = map[byte][]slog.Attr{
	'A': {
		slog.String("string", "value"),
		slog.Int("int", -13),
		slog.Uint64("uint", 23),
	},
	'B': {
		slog.String("aTime", time.Now().Format(time.RFC3339)),
		slog.Bool("bool", true),
		slog.Duration("duration", time.Hour+3*time.Minute+22*time.Second),
	},
	'C': {
		slog.Group("groupC",
			"name", "Goober Snoofus",
			"skidoo", 23,
			"pi", math.Pi),
		slog.Bool("bool", false),
		slog.Any("valuer", &hiddenValuer{"Big Tree"}),
		slog.Duration("duration", 23*time.Minute+49*time.Second),
	},
	'D': {
		slog.Float64("E", math.E),
		slog.Uint64("uint64", 79),
	},
}

Attributes are the attribute collections passed to logging methods, each referenced in test definition strings by a single character. Made public in case it is good to show in the web browser.

Functions

func NewWarningManager

func NewWarningManager(name string) *warning.Manager

NewWarningManager generates an infra.Manager configured for SlogTestSuite.

Types

type SlogTestSuite

type SlogTestSuite struct {
	suite.Suite
	*warning.Manager

	// Creator creates a slog.Handler to be used in creating a slog.Logger for a test.
	// This field must be configured by test suites and shouldn't be changed later.
	Creator infra.Creator

	*bytes.Buffer
}

SlogTestSuite provides various tests for a specified log/slog.Handler.

func NewSlogTestSuite

func NewSlogTestSuite(creator infra.Creator) *SlogTestSuite

func (*SlogTestSuite) Logger

func (suite *SlogTestSuite) Logger(options *slog.HandlerOptions) *slog.Logger

Logger returns a new slog.Logger with the specified options.

func (*SlogTestSuite) SetupSuite

func (suite *SlogTestSuite) SetupSuite()

func (*SlogTestSuite) SetupTest

func (suite *SlogTestSuite) SetupTest()

func (*SlogTestSuite) TestAnyMap

func (suite *SlogTestSuite) TestAnyMap()

func (*SlogTestSuite) TestAttributeDuplicate

func (suite *SlogTestSuite) TestAttributeDuplicate()

TestAttributeDuplicate tests whether duplicate attributes are logged properly.

func (*SlogTestSuite) TestAttributeEmptyName

func (suite *SlogTestSuite) TestAttributeEmptyName()

TestAttributeEmptyName tests whether attributes with empty names are logged properly.

  • Based on the existing behavior of log/slog the field is created with a blank name.
  • Extension of slogtest "empty-attr" test.

func (*SlogTestSuite) TestAttributeNil

func (suite *SlogTestSuite) TestAttributeNil()

TestAttributeNil tests whether attributes with nil values are logged properly.

  • Based on the existing behavior of log/slog the field is created with a nil/null value.
  • Extension of slogtest "empty-attr" test.

func (*SlogTestSuite) TestAttributeWithDuplicate

func (suite *SlogTestSuite) TestAttributeWithDuplicate()

TestAttributeWithDuplicate tests whether duplicate attributes are logged properly when the duplicate is introduced by With() and then the main call.

func (*SlogTestSuite) TestAttributeWithEmpty

func (suite *SlogTestSuite) TestAttributeWithEmpty()

TestAttributeWithEmpty tests whether attributes with empty names and nil values specified in With() are logged properly.

  • Based on the existing behavior of log/slog the field is not created.
  • Extension of slogtest "WithAttrs" test.

func (*SlogTestSuite) TestAttributeWithEmptyName

func (suite *SlogTestSuite) TestAttributeWithEmptyName()

TestAttributeWithEmptyName tests whether With() attributes with empty names are logged properly.

  • Based on the existing behavior of log/slog the field is created with a blank name.
  • Extension of slogtest "WithAttrs" test.

func (*SlogTestSuite) TestAttributeWithNil

func (suite *SlogTestSuite) TestAttributeWithNil()

TestAttributeWithNil tests whether With() attributes with nil values are logged properly.

  • Based on the existing behavior of log/slog the field is created with a nil/null value.
  • Extension of slogtest "WithAttrs" test.

func (*SlogTestSuite) TestAttributes

func (suite *SlogTestSuite) TestAttributes()

TestAttributes tests whether attributes are logged properly.

  • Implements slogtest "attrs" test.

func (*SlogTestSuite) TestAttributesEmpty

func (suite *SlogTestSuite) TestAttributesEmpty()

TestAttributesEmpty tests whether attributes with empty names and nil values are ignored.

func (*SlogTestSuite) TestAttributesNotEmpty

func (suite *SlogTestSuite) TestAttributesNotEmpty()

TestAttributesNotEmpty tests whether attributes with empty names and non-nil values are logged properly.

func (*SlogTestSuite) TestAttributesWith

func (suite *SlogTestSuite) TestAttributesWith()

TestAttributesWith tests whether attributes in With() are logged properly.

  • Implements slogtest "WithAttrs" test.

func (*SlogTestSuite) TestAttributesWithEmpty

func (suite *SlogTestSuite) TestAttributesWithEmpty()

TestAttributesWithEmpty tests whether empty attributes in With() are ignored.

func (*SlogTestSuite) TestAttributesWithNotEmpty

func (suite *SlogTestSuite) TestAttributesWithNotEmpty()

TestAttributesWithNotEmpty tests whether attribute with empty names but non-nil value in With() are properly logged.

func (*SlogTestSuite) TestCanceledContext

func (suite *SlogTestSuite) TestCanceledContext()

TestCanceledContext verifies that a cancelled context will not affect logging.

func (*SlogTestSuite) TestComplexCases

func (suite *SlogTestSuite) TestComplexCases()

TestComplexCases executes a series of algorithmically generated test cases. Each test case is represented by a sequence of characters that is a 'program'. For each test case three things are done:

  • a JSON log statement and
  • a string showing the method calls used to make the log statement are generated and
  • an expected data structure of nested map[string]any is generated.

The expectation is that the logMap from the log statement matches the expected data. Various special code bits are used to handle discrepancies marked by warnings.

This may seem a bit like cheating as the log statement and expected result are generated from the same algorithm for each test case. However, once the algorithmic strings/programs were working it was really simple to generate a bunch of tests by pattern of characters. This in turn surfaced a bunch of new discrepancies between logger implementations, resulting in several new warnings.

func (*SlogTestSuite) TestDefaultLevel

func (suite *SlogTestSuite) TestDefaultLevel()

TestDefaultLevel tests whether the handler under test is created by default with slog.LevelInfo.

func (*SlogTestSuite) TestDerivedInvariantWith

func (suite *SlogTestSuite) TestDerivedInvariantWith()

TestDerivedInvariantWith tests to see if deriving another handler via With() changes the original handler.

func (*SlogTestSuite) TestDerivedInvariantWithGroup

func (suite *SlogTestSuite) TestDerivedInvariantWithGroup()

TestDerivedInvariantWithGroup tests to see if deriving another handler via WithGroup() changes the original handler.

func (*SlogTestSuite) TestDisabled

func (suite *SlogTestSuite) TestDisabled()

TestDisabled tests whether logging is disabled by level.

func (*SlogTestSuite) TestGroup

func (suite *SlogTestSuite) TestGroup()

TestGroup tests the use of a logging group.

  • Implements slogtest "groups" test.

func (*SlogTestSuite) TestGroupDuration

func (suite *SlogTestSuite) TestGroupDuration()

TestGroupDuration checks to see if time.Duration objects are logged the same whether they are in a Group or at the top level of the log item.

  • Based on common sense, duration objects should log the same everywhere.

func (*SlogTestSuite) TestGroupEmpty

func (suite *SlogTestSuite) TestGroupEmpty()

TestGroupEmpty tests logging an empty group added as a group attribute.

func (*SlogTestSuite) TestGroupInline

func (suite *SlogTestSuite) TestGroupInline()

TestGroupInline tests the use of a group with an empty name.

  • Based on the existing behavior of log/slog the group field is not logged and the fields within the group are moved to the top level.
  • Implements slogtest "inline-group" test.
  • From https://pkg.go.dev/log/slog@master#Handler

func (*SlogTestSuite) TestGroupWith

func (suite *SlogTestSuite) TestGroupWith()

TestGroupWith tests the use of a logging group specified using WithGroup.

  • Implements slogtest "WithGroup" test.

func (*SlogTestSuite) TestGroupWithMulti

func (suite *SlogTestSuite) TestGroupWithMulti()

TestGroupWithMulti tests the use of multiple logging groups.

  • Implements slogtest "multi-with" test.

func (*SlogTestSuite) TestGroupWithMultiSubEmpty

func (suite *SlogTestSuite) TestGroupWithMultiSubEmpty()

TestGroupWithMultiSubEmpty tests the use of multiple logging groups when the subgroup is empty.

func (*SlogTestSuite) TestGroupWithTop

func (suite *SlogTestSuite) TestGroupWithTop()

TestGroupWithTop tests for cases where attributes sent via WithGroup().With() don't go into the group but end up at the top level of the log record.

func (*SlogTestSuite) TestKeyCase

func (suite *SlogTestSuite) TestKeyCase()

TestKeyCase tests whether level keys are properly cased.

  • Based on the existing behavior of log/slog they should be uppercase.

func (*SlogTestSuite) TestKeys

func (suite *SlogTestSuite) TestKeys()

TestKeys tests whether the three basic keys are present as their defined constants.

  • Implements slogtest "built-ins" test.

func (*SlogTestSuite) TestLevelConfigured

func (suite *SlogTestSuite) TestLevelConfigured()

TestLevelConfigured tests whether the source logger is created by default in SimpleOptions() and SourceOptions() with slog.LevelInfo.

  • Other tests (e.g. TestDisabled) depend on this.

Note: this doesn't test the handler's default level but the one generated by the test suite functions mentioned above. The handler's default level is tested in TestDefaultLevel in documented.go.

func (*SlogTestSuite) TestLevelDifferent

func (suite *SlogTestSuite) TestLevelDifferent()

TestLevelDifferent tests whether the simple logger can be created with slog.LevelWarn. This verifies the test suite can change the level when creating a logger. It also verifies changing the level via the handler.

func (*SlogTestSuite) TestLevelVar

func (suite *SlogTestSuite) TestLevelVar()

TestLevelVar tests the use of a slog.LevelVar.

func (*SlogTestSuite) TestLogAttributes

func (suite *SlogTestSuite) TestLogAttributes()

TestLogAttributes tests the LogAttrs call with all attribute objects.

func (*SlogTestSuite) TestReplaceAttr

func (suite *SlogTestSuite) TestReplaceAttr()

TestReplaceAttr tests the use of HandlerOptions.ReplaceAttr.

func (*SlogTestSuite) TestReplaceAttrBasic

func (suite *SlogTestSuite) TestReplaceAttrBasic()

TestReplaceAttrBasic tests the use of HandlerOptions.ReplaceAttr on basic attributes (time, level, message, source).

func (*SlogTestSuite) TestReplaceAttrFnChangeKey

func (suite *SlogTestSuite) TestReplaceAttrFnChangeKey()

TestReplaceAttrFnChangeKey tests the ChangeKey function.

func (*SlogTestSuite) TestReplaceAttrFnLevelCase

func (suite *SlogTestSuite) TestReplaceAttrFnLevelCase()

TestReplaceAttrFnLevelCase tests the ChangeCase function as a replacement for the Level[Lower,Upper]Case functions.

func (*SlogTestSuite) TestReplaceAttrFnMulti

func (suite *SlogTestSuite) TestReplaceAttrFnMulti()

TestReplaceAttrFnMulti tests the replace.Multiple ReplaceAttr function as well as the TopCheck and Replace.Current functions.

func (*SlogTestSuite) TestReplaceAttrFnRemoveEmptyKey

func (suite *SlogTestSuite) TestReplaceAttrFnRemoveEmptyKey()

TestReplaceAttrFnRemoveEmptyKey tests the RemoveKey function as a replacement for the RemoveEmptyKey function.

func (*SlogTestSuite) TestReplaceAttrFnRemoveTime

func (suite *SlogTestSuite) TestReplaceAttrFnRemoveTime()

TestReplaceAttrFnRemoveTime tests the RemoveKey function as a replacement for the RemoveTime function.

func (*SlogTestSuite) TestReplaceAttrGroup

func (suite *SlogTestSuite) TestReplaceAttrGroup()

TestReplaceAttrGroup tests the groups argument passed to a HandlerOptions.ReplaceAttr function. This checks to see if group names are properly tracked and passed.

func (*SlogTestSuite) TestResolveGroup

func (suite *SlogTestSuite) TestResolveGroup()

TestResolveGroup tests logging LogValuer objects within a group.

func (*SlogTestSuite) TestResolveGroupWith

func (suite *SlogTestSuite) TestResolveGroupWith()

TestResolveGroupWith tests logging LogValuer objects within a group within a With().

func (*SlogTestSuite) TestResolveValuer

func (suite *SlogTestSuite) TestResolveValuer()

TestResolveValuer tests logging LogValuer objects.

func (*SlogTestSuite) TestResolveWith

func (suite *SlogTestSuite) TestResolveWith()

TestResolveWith tests logging LogValuer objects within a With().

func (*SlogTestSuite) TestSlogTest

func (suite *SlogTestSuite) TestSlogTest()

func (*SlogTestSuite) TestSourceKey

func (suite *SlogTestSuite) TestSourceKey()

TestSourceKey tests generation of a source key.

func (*SlogTestSuite) TestStringEscape

func (suite *SlogTestSuite) TestStringEscape()

func (*SlogTestSuite) TestTimestampFormat

func (suite *SlogTestSuite) TestTimestampFormat()

TestTimestampFormat tests whether a timestamp can be parsed.

  • Based on the existing behavior of log/slog the timestamp format is RFC3339.

func (*SlogTestSuite) TestWithGroupEmpty

func (suite *SlogTestSuite) TestWithGroupEmpty()

TestWithGroupEmpty tests logging an empty group added using WithGroup.

func (*SlogTestSuite) TestWithGroupInline

func (suite *SlogTestSuite) TestWithGroupInline()

TestWithGroupInline tests the use of WithGroup() with an empty name.

func (*SlogTestSuite) TestZeroPC

func (suite *SlogTestSuite) TestZeroPC()

TestZeroPC tests generation of a source key.

func (*SlogTestSuite) TestZeroTime

func (suite *SlogTestSuite) TestZeroTime()

TestZeroTime tests whether a zero time in a slog.Record is output.

Jump to

Keyboard shortcuts

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