watchertest

package
v0.0.0-...-c116a84 Latest Latest
Warning

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

Go to latest
Published: Dec 20, 2024 License: AGPL-3.0 Imports: 10 Imported by: 1

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CleanKill

func CleanKill[T any](c *gc.C, w watcher.Watcher[T])

CleanKill calls CheckKill with the supplied arguments, and Checks that the returned error is nil. It's particularly suitable for deferring:

someWatcher, err := some.NewWatcher()
c.Assert(err, jc.ErrorIsNil)
watchertest.CleanKill(c, someWatcher)

...in the large number (majority?) of situations where a worker is expected to run successfully; and it doesn't Assert, and is therefore suitable for use from any goroutine.

func DirtyKill

func DirtyKill[T any](c *gc.C, w watcher.Watcher[T])

DirtyKill calls CheckKill with the supplied arguments, and logs the returned error. It's particularly suitable for deferring:

someWatcher, err := some.NewWatcher()
c.Assert(err, jc.ErrorIsNil)
defer watchertest.DirtyKill(c, someWatcher)

...in the cases where we expect a worker to fail, but aren't specifically testing that failure; and it doesn't Assert, and is therefore suitable for use from any goroutine.

Types

type Harness

type Harness[T any] struct {
	// contains filtered or unexported fields
}

Harness is a test harness for testing watchers. The harness is created to ensure that for every watcher, they have a predictable lifecycle. This means that every watcher must adhere to the following:

  1. Empty an initial event.
  2. The change stream should become idle.
  3. Run the setup for the test.
  4. The change stream should become idle.
  5. Assert the changes.
  6. The watcher should not emit any more changes.
  7. The change stream should be idle, or become idle.

Steps from 3 to 5 are repeated for each test added to the harness. Once the tests are run, the harness ensures that there are no more changes before checking that the change stream is idle.

By ensuring that the change stream is idle, we can guarantee that the

  1. The watcher has processed all the changes.
  2. There are no more changes to be processed.

This isolation technique allows us to test the watcher in a predictable manner.

func NewHarness

func NewHarness[T any](idler Idler, watcher WatcherC[T]) *Harness[T]

NewHarness creates a new Harness. The idler is used to ensure that the change stream is idle. The watcher is used to assert the changes against. Normally this should be a NotifyWatcherC or a StringsWatcherC.

func (*Harness[T]) AddTest

func (h *Harness[T]) AddTest(setup func(*gc.C), assert func(WatcherC[T]))

AddTest adds the setup for the test and also the assertion for the setup. This is split into two functions to allow for the checking of the assert change stream idle call in between the setup and the assertion. Run must be called after all the tests have been added.

func (*Harness[T]) Run

func (h *Harness[T]) Run(c *gc.C, initial ...T)

Run runs all the tests added to the harness.

type Idler

type Idler interface {
	AssertChangeStreamIdle(c *gc.C)
}

Idler is an interface that ensures that the change stream is idle.

type MockNotifyWatcher

type MockNotifyWatcher struct {
	// contains filtered or unexported fields
}

func NewMockNotifyWatcher

func NewMockNotifyWatcher(ch <-chan struct{}) *MockNotifyWatcher

func (*MockNotifyWatcher) Changes

func (w *MockNotifyWatcher) Changes() <-chan struct{}

func (*MockNotifyWatcher) Err

func (w *MockNotifyWatcher) Err() error

func (*MockNotifyWatcher) Kill

func (w *MockNotifyWatcher) Kill()

func (*MockNotifyWatcher) KillErr

func (w *MockNotifyWatcher) KillErr(err error)

KillErr can be used to kill the worker with an error, to simulate a failing watcher.

func (*MockNotifyWatcher) Stop

func (w *MockNotifyWatcher) Stop() error

func (*MockNotifyWatcher) Wait

func (w *MockNotifyWatcher) Wait() error

type MockStringsWatcher

type MockStringsWatcher struct {
	// contains filtered or unexported fields
}

func NewMockStringsWatcher

func NewMockStringsWatcher(ch <-chan []string) *MockStringsWatcher

func (*MockStringsWatcher) Changes

func (w *MockStringsWatcher) Changes() <-chan []string

func (*MockStringsWatcher) Err

func (w *MockStringsWatcher) Err() error

func (*MockStringsWatcher) Kill

func (w *MockStringsWatcher) Kill()

func (*MockStringsWatcher) KillErr

func (w *MockStringsWatcher) KillErr(err error)

KillErr can be used to kill the worker with an error, to simulate a failing watcher.

func (*MockStringsWatcher) Stop

func (w *MockStringsWatcher) Stop() error

func (*MockStringsWatcher) Wait

func (w *MockStringsWatcher) Wait() error

type NotifyWatcherC

type NotifyWatcherC struct {
	*gc.C
	Watcher watcher.NotifyWatcher
}

func NewNotifyWatcherC

func NewNotifyWatcherC(c *gc.C, watcher watcher.NotifyWatcher) NotifyWatcherC

func (NotifyWatcherC) AssertAtLeastOneChange

func (c NotifyWatcherC) AssertAtLeastOneChange()

AssertAtLeastOneChange fails if no change is sent before a long time has passed.

func (NotifyWatcherC) AssertChanges

func (c NotifyWatcherC) AssertChanges(duration time.Duration)

AssertChanges asserts that there was a series of changes for a given duration. If there are any more changes after that period, then it will fail.

func (NotifyWatcherC) AssertKilled

func (c NotifyWatcherC) AssertKilled()

AssertKilled Kills the watcher and asserts that Wait completes without error before a long time has passed.

func (NotifyWatcherC) AssertNChanges

func (c NotifyWatcherC) AssertNChanges(n int)

AssertNChanges fails if it does not receive n changes before a long time has passed.

func (NotifyWatcherC) AssertNoChange

func (c NotifyWatcherC) AssertNoChange()

AssertNoChange fails if it manages to read a value from Changes before a short time has passed.

func (NotifyWatcherC) AssertOneChange

func (c NotifyWatcherC) AssertOneChange()

AssertOneChange fails if no change is sent before a long time has passed; or if, subsequent to that, any further change is sent before a short time has passed.

func (NotifyWatcherC) AssertStops

func (c NotifyWatcherC) AssertStops()

AssertStops Kills the watcher and asserts (1) that Wait completes without error before a long time has passed; and (2) that Changes remains open but no values are being sent.

type RelationUnitsWatcherC

type RelationUnitsWatcherC struct {
	*gc.C
	Watcher   watcher.RelationUnitsWatcher
	PreAssert func()
	// contains filtered or unexported fields
}

func NewRelationUnitsWatcherC

func NewRelationUnitsWatcherC(c *gc.C, w watcher.RelationUnitsWatcher) RelationUnitsWatcherC

NewRelationUnitsWatcherC returns a RelationUnitsWatcherC that checks for aggressive event coalescence.

func (RelationUnitsWatcherC) AssertChange

func (c RelationUnitsWatcherC) AssertChange(changed []string, appChanged []string, departed []string)

AssertChange asserts the given changes was reported by the watcher, but does not assume there are no following changes.

func (RelationUnitsWatcherC) AssertNoChange

func (c RelationUnitsWatcherC) AssertNoChange()

func (RelationUnitsWatcherC) AssertStops

func (c RelationUnitsWatcherC) AssertStops()

AssertStops Kills the watcher and asserts (1) that Wait completes without error before a long time has passed; and (2) that Changes remains open but no values are being sent.

type SecretBackendRotateWatcherC

type SecretBackendRotateWatcherC struct {
	*gc.C
	Watcher watcher.SecretBackendRotateWatcher
}

SecretBackendRotateWatcherC embeds a gocheck.C and adds methods to help verify the behaviour of any watcher that uses a <-chan []SecretBackendRotateChange

func NewSecretBackendRotateWatcherC

func NewSecretBackendRotateWatcherC(c *gc.C, w watcher.SecretBackendRotateWatcher) SecretBackendRotateWatcherC

NewSecretBackendRotateWatcherC returns a SecretBackendRotateWatcherC that checks for aggressive event coalescence.

func (SecretBackendRotateWatcherC) AssertChanges

AssertChanges asserts the given changes was reported by the watcher, but does not assume there are no following changes.

func (SecretBackendRotateWatcherC) AssertClosed

func (c SecretBackendRotateWatcherC) AssertClosed()

func (SecretBackendRotateWatcherC) AssertNoChange

func (c SecretBackendRotateWatcherC) AssertNoChange()

type SecretsTriggerWatcherC

type SecretsTriggerWatcherC struct {
	*gc.C
	Watcher watcher.SecretTriggerWatcher
}

SecretsTriggerWatcherC embeds a gocheck.C and adds methods to help verify the behaviour of any watcher that uses a <-chan []SecretTriggerChange

func NewSecretsTriggerWatcherC

func NewSecretsTriggerWatcherC(c *gc.C, w watcher.SecretTriggerWatcher) SecretsTriggerWatcherC

NewSecretsTriggerWatcherC returns a SecretsTriggerWatcherC that checks for aggressive event coalescence.

func (SecretsTriggerWatcherC) AssertChange

func (c SecretsTriggerWatcherC) AssertChange(expect ...watcher.SecretTriggerChange)

AssertChange asserts the given changes was reported by the watcher, but does not assume there are no following changes.

func (SecretsTriggerWatcherC) AssertClosed

func (c SecretsTriggerWatcherC) AssertClosed()

func (SecretsTriggerWatcherC) AssertNoChange

func (c SecretsTriggerWatcherC) AssertNoChange()

type StringsWatcherC

type StringsWatcherC struct {
	*gc.C
	Watcher watcher.StringsWatcher
}

func NewStringsWatcherC

func NewStringsWatcherC(c *gc.C, watcher watcher.StringsWatcher) StringsWatcherC

func (StringsWatcherC) AssertAtLeastOneChange

func (c StringsWatcherC) AssertAtLeastOneChange()

AssertAtLeastOneChange fails if no change is sent before a long time has passed.

func (StringsWatcherC) AssertChange

func (c StringsWatcherC) AssertChange(expect ...string)

func (StringsWatcherC) AssertChangeInSingleEvent

func (c StringsWatcherC) AssertChangeInSingleEvent(expect ...string)

func (StringsWatcherC) AssertChangeMaybeIncluding

func (c StringsWatcherC) AssertChangeMaybeIncluding(expect ...string)

AssertChangeMaybeIncluding verifies that there is a change that may contain zero to all of the passed in strings, and no other changes.

func (StringsWatcherC) AssertChanges

func (c StringsWatcherC) AssertChanges()

AssertChanges fails if it cannot read a value from Changes despite waiting a long time. It logs, but does not check, the received changes; but will fail if the Changes chan is closed.

func (StringsWatcherC) AssertKilled

func (c StringsWatcherC) AssertKilled()

AssertKilled Kills the watcher and asserts that Wait completes without error before a long time has passed.

func (StringsWatcherC) AssertNoChange

func (c StringsWatcherC) AssertNoChange()

AssertNoChange fails if it manages to read a value from Changes before a short time has passed.

func (StringsWatcherC) AssertOneChange

func (c StringsWatcherC) AssertOneChange()

AssertOneChange fails if no change is sent before a long time has passed; or if, subsequent to that, any further change is sent before a short time has passed.

func (StringsWatcherC) AssertStops

func (c StringsWatcherC) AssertStops()

AssertStops Kills the watcher and asserts (1) that Wait completes without error before a long time has passed; and (2) that Changes remains open but no values are being sent.

type TestHelper

type TestHelper interface {
	TestReporter
	Helper()
}

TestHelper is a TestReporter that has the Helper method. It is satisfied by the standard library's *testing.T.

type TestReporter

type TestReporter interface {
	Errorf(format string, args ...any)
	Fatalf(format string, args ...any)
}

A TestReporter is something that can be used to report test failures. It is satisfied by the standard library's *testing.T.

type WatcherAssert

type WatcherAssert[T any] func(c *gc.C, changes []T) bool

WatcherAssert is a function that asserts the changes received by a watcher.

func SecretTriggerSliceAssert

func SecretTriggerSliceAssert[T watcher.SecretTriggerChange](expect ...T) WatcherAssert[[]T]

SecretTriggerSliceAssert returns a WatcherAssert that checks that the watcher has received at least the given []watcher.SecretTriggerChange changes. The changes are concatenated before the assertion, order doesn't matter during assertion.

func SliceAssert

func SliceAssert[T any](expect ...T) WatcherAssert[T]

SliceAssert returns a WatcherAssert that checks that the watcher has received at least the given changes.

func StringSliceAssert

func StringSliceAssert[T string](expect ...T) WatcherAssert[[]T]

StringSliceAssert returns a WatcherAssert that checks that the watcher has received at least the given []string changes. The changes are concatenated before the assertion, order doesn't matter during assertion.

type WatcherC

type WatcherC[T any] struct {
	Watcher watcher.Watcher[T]
	// contains filtered or unexported fields
}

WatcherC embeds a gocheck.C and adds methods to help verify the behaviour of generic watchers.

func NewWatcherC

func NewWatcherC[T any](c *gc.C, w watcher.Watcher[T]) WatcherC[T]

NewWatcherC() returns a WatcherC[T].

func (*WatcherC[T]) AssertChange

func (w *WatcherC[T]) AssertChange()

AssertChange asserts that the watcher sends at least one change before the test times out.

func (*WatcherC[T]) AssertKilled

func (w *WatcherC[T]) AssertKilled()

AssertKilled Kills the watcher and asserts that Wait completes without error before a long time has passed.

func (WatcherC[T]) AssertNChanges

func (w WatcherC[T]) AssertNChanges(n int)

AssertNChanges fails if it does not receive n changes before a long time has passed.

func (*WatcherC[T]) AssertNoChange

func (w *WatcherC[T]) AssertNoChange()

AssertNoChange verifies that no changes are received from the watcher during a testing.ShortWait time.

func (*WatcherC[T]) Check

func (w *WatcherC[T]) Check(assertion WatcherAssert[T])

Check asserts that the watcher sends the expected changes. The assertion function is called repeatedly until it returns true, or the test times out.

Jump to

Keyboard shortcuts

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