testutil

package
v0.1.0-alpha.9 Latest Latest
Warning

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

Go to latest
Published: Dec 30, 2025 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package testutil provides shared test helpers for controller package tests. These helpers reduce code duplication across test files by providing: - Standard EventBus and Logger creation - Event waiting utilities with timeout - Component lifecycle testing helpers - Timing constants to replace magic numbers

Index

Constants

View Source
const (
	// StartupDelay is the time to wait for components to initialize after starting.
	StartupDelay = 50 * time.Millisecond

	// DebounceWait is the time to wait for debounce timers to fire.
	DebounceWait = 100 * time.Millisecond

	// EventTimeout is the default timeout for waiting on a single event.
	EventTimeout = 500 * time.Millisecond

	// LongTimeout is used for operations that may take longer (e.g., component stop).
	LongTimeout = 1 * time.Second

	// VeryLongTimeout is used for integration-style tests within unit test files.
	VeryLongTimeout = 2 * time.Second

	// NoEventTimeout is a shorter timeout for verifying no event is received.
	NoEventTimeout = 200 * time.Millisecond
)

Timing constants to replace magic numbers in tests. These provide consistent, documented values for test synchronization.

View Source
const ValidHAProxyConfigTemplate = `` /* 266-byte string literal not displayed */

ValidHAProxyConfigTemplate is a minimal valid HAProxy configuration template that passes HAProxy syntax validation. Use this in tests that need to render and validate HAProxy configurations.

Variables

This section is empty.

Functions

func AssertNoEvent

func AssertNoEvent[T any](t *testing.T, eventChan <-chan busevents.Event, timeout time.Duration)

AssertNoEvent verifies that no event of type T is received within the timeout. This is useful for testing that certain events are NOT published.

Example:

testutil.AssertNoEvent[*events.ConfigParsedEvent](t, eventChan, testutil.NoEventTimeout)

func ComponentStopTest

func ComponentStopTest(t *testing.T, bus *busevents.EventBus, startFunc, stopFunc func())

ComponentStopTest tests that a component stops cleanly when Stop() is called. This is a common pattern across controller components.

The startFunc should start the component in blocking mode (e.g., component.Start(ctx)). The stopFunc should trigger the component to stop (e.g., component.Stop()).

Example:

testutil.ComponentStopTest(t, bus,
    func(ctx context.Context) { component.Start(ctx) },
    func() { component.Stop() })

func CreateTestConfigMap

func CreateTestConfigMap(name, namespace, resourceVersion string, data map[string]string) *unstructured.Unstructured

CreateTestConfigMap creates an unstructured ConfigMap for testing.

Example:

cm := testutil.CreateTestConfigMap("my-config", "default", "12345",
    map[string]string{"key": "value"})

func CreateTestSecret

func CreateTestSecret(name, namespace, resourceVersion string, data map[string]interface{}) *unstructured.Unstructured

CreateTestSecret creates an unstructured Secret for testing. This is a common fixture used by multiple loader components.

Example:

secret := testutil.CreateTestSecret("test-secret", "test-ns", "12345", map[string]interface{}{
    "username": "admin",
    "password": "secret",
})

func CreateTestSecretWithStringData

func CreateTestSecretWithStringData(name, namespace, resourceVersion string, data map[string]string) *unstructured.Unstructured

CreateTestSecretWithStringData creates an unstructured Secret with string data. This is useful for credentials secrets that don't need base64 encoding in tests.

Example:

secret := testutil.CreateTestSecretWithStringData("creds", "default", "12345",
    map[string]string{"username": "admin", "password": "secret"})

func CreateTestSecretWithTLS

func CreateTestSecretWithTLS(name, namespace, resourceVersion string, certPEM, keyPEM []byte) *unstructured.Unstructured

CreateTestSecretWithTLS creates an unstructured TLS Secret for testing. The cert and key are base64-encoded as Kubernetes expects for Secret data.

Example:

secret := testutil.CreateTestSecretWithTLS("my-tls", "default", "12345",
    []byte("-----BEGIN CERTIFICATE-----\n..."),
    []byte("-----BEGIN PRIVATE KEY-----\n..."))

func DrainChannel

func DrainChannel(eventChan <-chan busevents.Event)

DrainChannel empties all pending events from the channel without blocking. Useful for clearing events between test phases.

func NewTestBus

func NewTestBus() *busevents.EventBus

NewTestBus creates an EventBus with a standard buffer size for tests.

func NewTestBusAndLogger

func NewTestBusAndLogger() (*busevents.EventBus, *slog.Logger)

NewTestBusAndLogger creates both an EventBus and Logger for tests. This is the most common setup pattern across controller tests.

func NewTestLogger

func NewTestLogger() *slog.Logger

NewTestLogger creates a logger that writes to stderr with error level. This minimizes noise in test output while still capturing errors.

func RunComponentContextCancel

func RunComponentContextCancel(t *testing.T, bus *busevents.EventBus, startFunc func(context.Context) error)

RunComponentContextCancel tests that a component stops cleanly when context is cancelled. This reduces boilerplate for the common test pattern in controller components.

Example:

func TestCertLoaderComponent_StartWithContextCancel(t *testing.T) {
    bus, logger := testutil.NewTestBusAndLogger()
    component := NewCertLoaderComponent(bus, logger)
    testutil.RunComponentContextCancel(t, bus, component.Start)
}

func RunComponentStartStop

func RunComponentStartStop(t *testing.T, bus *busevents.EventBus, startFunc func(context.Context) error, stopFunc func())

RunComponentStartStop tests that a component starts and stops cleanly. This reduces boilerplate for the common test pattern in controller components.

Example:

func TestCertLoaderComponent_StartAndStop(t *testing.T) {
    bus, logger := testutil.NewTestBusAndLogger()
    component := NewCertLoaderComponent(bus, logger)
    testutil.RunComponentStartStop(t, bus, component.Start, component.Stop)
}

func WaitForEvent

func WaitForEvent[T any](t *testing.T, eventChan <-chan busevents.Event, timeout time.Duration) T

WaitForEvent waits for an event of type T on the channel, failing the test on timeout. It skips over events of other types until finding a matching one.

Example:

event := testutil.WaitForEvent[*events.ConfigParsedEvent](t, eventChan, testutil.EventTimeout)
assert.Equal(t, "v1", event.Version)

func WaitForEventWithPredicate

func WaitForEventWithPredicate[T any](t *testing.T, eventChan <-chan busevents.Event, timeout time.Duration, predicate func(T) bool) T

WaitForEventWithPredicate waits for an event of type T that satisfies the predicate. Useful when you need to match on event fields, not just type.

Example:

event := testutil.WaitForEventWithPredicate(t, eventChan, testutil.EventTimeout,
    func(e *events.ConfigParsedEvent) bool { return e.Version == "v2" })

Types

This section is empty.

Jump to

Keyboard shortcuts

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