testutil

package
v0.5.1 Latest Latest
Warning

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

Go to latest
Published: Mar 16, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package testutil provides testing utilities for daemon functionality. It enables dual-mode testing where commands can be tested both with a running daemon and in direct mode (no daemon).

Index

Examples

Constants

View Source
const (
	FaultNone                   = faultdaemon.FaultNone
	FaultHangOnAccept           = faultdaemon.FaultHangOnAccept
	FaultHangBeforeResponse     = faultdaemon.FaultHangBeforeResponse
	FaultSlowResponse           = faultdaemon.FaultSlowResponse
	FaultCorruptResponse        = faultdaemon.FaultCorruptResponse
	FaultPartialResponse        = faultdaemon.FaultPartialResponse
	FaultCloseImmediately       = faultdaemon.FaultCloseImmediately
	FaultCloseAfterRead         = faultdaemon.FaultCloseAfterRead
	FaultDropConnection         = faultdaemon.FaultDropConnection
	FaultPanicInHandler         = faultdaemon.FaultPanicInHandler
	FaultDeadlock               = faultdaemon.FaultDeadlock
	FaultMultipleResponses      = faultdaemon.FaultMultipleResponses
	FaultResponseWithoutNewline = faultdaemon.FaultResponseWithoutNewline
	FaultChunkedResponse        = faultdaemon.FaultChunkedResponse
	FaultSlowAccept             = faultdaemon.FaultSlowAccept
	FaultRefuseAfterAccept      = faultdaemon.FaultRefuseAfterAccept
	FaultVerySlowResponse       = faultdaemon.FaultVerySlowResponse
	FaultResponseTooLarge       = faultdaemon.FaultResponseTooLarge
	FaultInvalidJSON            = faultdaemon.FaultInvalidJSON
	FaultEmbeddedNewlines       = faultdaemon.FaultEmbeddedNewlines
	FaultWriteHalfThenHang      = faultdaemon.FaultWriteHalfThenHang
)

Fault constant aliases

Variables

This section is empty.

Functions

func IsDaemonMode

func IsDaemonMode() bool

IsDaemonMode returns true if we're running in daemon mode. Useful for tests that need to behave differently based on daemon availability.

func NewTestClient

func NewTestClient() *daemon.Client

NewTestClient creates a daemon client with test-appropriate timeout. Uses 500ms (vs 50ms production default) for test stability under load.

func RequireDaemon

func RequireDaemon(t *testing.T)

RequireDaemon skips the test if no daemon is running.

func RequireNoDaemon

func RequireNoDaemon(t *testing.T)

RequireNoDaemon skips the test if a daemon is running.

func RunDualMode

func RunDualMode(t *testing.T, tests []DualModeTest)

RunDualMode executes tests in both daemon and direct modes. Each test runs twice: once with a daemon and once without. Note: Tests do not run in parallel because daemon mode requires modifying environment variables, which conflicts with t.Parallel().

func StartTestDaemon

func StartTestDaemon(t *testing.T, tmpDir string) (cleanup func())

StartTestDaemon starts a real daemon in a temp directory for testing. Returns a cleanup function that must be called to stop the daemon.

Usage:

cleanup := StartTestDaemon(t, tmpDir)
defer cleanup()
// ... run tests that interact with daemon ...

func TestDaemonConfig

func TestDaemonConfig(tmpDir string) *daemon.Config

TestDaemonConfig returns a daemon config suitable for testing.

func WaitForDaemon

func WaitForDaemon(t *testing.T, timeout time.Duration) error

WaitForDaemon waits for the daemon to become available.

Types

type DualModeTest

type DualModeTest struct {
	// Name is the test name (will have mode suffix appended).
	Name string

	// Test is the test function. Mode indicates whether the daemon is running.
	// Test should use mode to determine how to execute the command.
	Test func(t *testing.T, mode Mode)

	// SkipDaemon skips daemon mode test if true.
	SkipDaemon bool

	// SkipDirect skips direct mode test if true.
	SkipDirect bool
}

DualModeTest defines a test that should work in both daemon and direct modes. This ensures commands function correctly regardless of daemon availability.

Example

ExampleDualModeTest demonstrates how to use DualModeTest.

// define tests that work in both modes
tests := []DualModeTest{
	{
		Name: "command_works_with_and_without_daemon",
		Test: func(t *testing.T, mode Mode) {
			// your command logic here
			// use mode to check which mode we're in
			if mode == ModeDaemon {
				// daemon-specific assertions
			} else {
				// direct mode assertions
			}
		},
	},
}

// run in a test function:
// RunDualMode(t, tests)
_ = tests

type Fault

type Fault = faultdaemon.Fault

Fault type alias for backward compatibility

type FaultConfig

type FaultConfig struct {
	// Fault is the failure mode to inject.
	Fault Fault

	// SlowResponseDelay is the delay for slow response faults.
	SlowResponseDelay time.Duration

	// DropEveryN drops every Nth connection for drop connection fault.
	DropEveryN int

	// FaultOnMessageType restricts the fault to a specific message type.
	// Other message types respond normally.
	FaultOnMessageType string

	// StatusResponse overrides the daemon's status response.
	StatusResponse *daemon.StatusData

	// DoctorResponse overrides the daemon's doctor response.
	DoctorResponse *daemon.DoctorResponse

	// CheckoutResponse overrides the daemon's checkout response.
	CheckoutResponse *daemon.CheckoutResult

	// SyncError is the error to return for sync requests.
	SyncError error
}

FaultConfig is the backward-compatible config struct for tests. It mirrors the old API where fields were at the top level.

type MockDaemon deprecated

type MockDaemon struct {
	// Responses maps message types to their responses.
	// Key is the message type (e.g., "status", "sync").
	Responses map[string]any

	// StatusResponse is the status to return for status requests.
	StatusResponse *daemon.StatusData

	// SyncError is the error to return for sync requests (nil = success).
	SyncError error

	// Calls records all RPC calls made to the mock.
	Calls []RPCCall
	// contains filtered or unexported fields
}

MockDaemon provides a mock daemon for unit tests. It records all RPC calls and returns configurable responses.

Deprecated: Use OxFaultDaemon for new tests. It provides the same functionality plus fault injection capabilities.

Example

ExampleMockDaemon demonstrates how to use MockDaemon.

// in a test function:
// env := NewTestEnvironment(t)
// mock := env.StartMock()
//
// configure mock responses:
// mock.StatusResponse = &daemon.StatusData{Running: true}
// mock.SyncError = errors.New("test error")
//
// make assertions:
// client := daemon.NewClient()
// err := client.Ping()
// assert.NoError(t, err)
// assert.Equal(t, 1, mock.CallCount(daemon.MsgTypePing))

func NewMockDaemon

func NewMockDaemon() *MockDaemon

NewMockDaemon creates a new mock daemon.

func (*MockDaemon) CallCount

func (m *MockDaemon) CallCount(msgType string) int

CallCount returns the number of calls of a specific type.

func (*MockDaemon) GetCalls

func (m *MockDaemon) GetCalls() []RPCCall

GetCalls returns a copy of all recorded calls.

func (*MockDaemon) ResetCalls

func (m *MockDaemon) ResetCalls()

ResetCalls clears all recorded calls.

func (*MockDaemon) Start

func (m *MockDaemon) Start(t *testing.T)

Start starts the mock daemon on the default socket path. Call this after setting environment variables for XDG_RUNTIME_DIR.

func (*MockDaemon) Stop

func (m *MockDaemon) Stop()

Stop stops the mock daemon.

func (*MockDaemon) WithResponse

func (m *MockDaemon) WithResponse(msgType string, response any) *MockDaemon

WithResponse adds a custom response for a message type.

func (*MockDaemon) WithStatus

func (m *MockDaemon) WithStatus(status *daemon.StatusData) *MockDaemon

WithStatus configures the status response.

func (*MockDaemon) WithSyncError

func (m *MockDaemon) WithSyncError(err error) *MockDaemon

WithSyncError configures sync to return an error.

type Mode

type Mode string

Mode represents the execution mode for tests.

const (
	// ModeDaemon runs tests with a real daemon.
	ModeDaemon Mode = "daemon"

	// ModeDirect runs tests without a daemon (direct execution).
	ModeDirect Mode = "direct"
)

type OxFaultConfig

type OxFaultConfig struct {
	// Embedded generic config
	faultdaemon.Config

	// StatusResponse is returned for status requests.
	StatusResponse *daemon.StatusData

	// DoctorResponse is returned for doctor requests.
	DoctorResponse *daemon.DoctorResponse

	// CheckoutResponse is returned for checkout requests.
	CheckoutResponse *daemon.CheckoutResult

	// SyncError is the error to return for sync requests (nil = success).
	SyncError error

	// CustomResponses maps message types to custom response data.
	// Value will be marshaled to JSON and wrapped in daemon.Response.
	CustomResponses map[string]any
}

OxFaultConfig extends generic fault config with ox-specific responses.

type OxFaultDaemon

type OxFaultDaemon struct {
	*faultdaemon.FaultDaemon
	// contains filtered or unexported fields
}

OxFaultDaemon wraps the generic FaultDaemon with ox protocol knowledge. It generates ox-specific responses (daemon.Response) for incoming messages.

func NewCorruptDaemon

func NewCorruptDaemon(t *testing.T) *OxFaultDaemon

NewCorruptDaemon creates a daemon that sends garbage responses.

func NewCrashingDaemon

func NewCrashingDaemon(t *testing.T) *OxFaultDaemon

NewCrashingDaemon creates a daemon that closes connections immediately.

func NewFaultDaemon

func NewFaultDaemon(t *testing.T, config FaultConfig) *OxFaultDaemon

NewFaultDaemon creates an ox fault daemon with the given config.

func NewFlakyDaemon

func NewFlakyDaemon(t *testing.T, dropEveryN int) *OxFaultDaemon

NewFlakyDaemon creates a daemon that drops every Nth connection.

func NewHealthyFaultDaemon

func NewHealthyFaultDaemon(t *testing.T) *OxFaultDaemon

NewHealthyFaultDaemon creates a fault daemon with no faults.

func NewHungDaemon

func NewHungDaemon(t *testing.T) *OxFaultDaemon

NewHungDaemon creates a daemon that accepts connections but never responds.

func NewOxCorruptDaemon

func NewOxCorruptDaemon(t *testing.T) *OxFaultDaemon

NewOxCorruptDaemon creates a daemon that sends garbage responses.

func NewOxCrashingDaemon

func NewOxCrashingDaemon(t *testing.T) *OxFaultDaemon

NewOxCrashingDaemon creates a daemon that closes connections immediately.

func NewOxFaultDaemon

func NewOxFaultDaemon(t *testing.T, config OxFaultConfig) *OxFaultDaemon

NewOxFaultDaemon creates an ox-specific fault daemon for testing. It understands ox IPC protocol and generates appropriate responses.

func NewOxFlakyDaemon

func NewOxFlakyDaemon(t *testing.T, dropEveryN int) *OxFaultDaemon

NewOxFlakyDaemon creates a daemon that drops every Nth connection.

func NewOxHealthyFaultDaemon

func NewOxHealthyFaultDaemon(t *testing.T) *OxFaultDaemon

NewOxHealthyFaultDaemon creates a fault daemon with no faults (for baseline testing).

func NewOxHungDaemon

func NewOxHungDaemon(t *testing.T) *OxFaultDaemon

NewOxHungDaemon creates a daemon that accepts connections but never responds.

func NewOxSlowDaemon

func NewOxSlowDaemon(t *testing.T, delay time.Duration) *OxFaultDaemon

NewOxSlowDaemon creates a daemon that responds after a delay.

func NewSlowDaemon

func NewSlowDaemon(t *testing.T, delay time.Duration) *OxFaultDaemon

NewSlowDaemon creates a daemon that responds after a delay.

func (*OxFaultDaemon) SetOxConfig

func (d *OxFaultDaemon) SetOxConfig(config OxFaultConfig)

SetOxConfig updates the ox-specific configuration.

func (*OxFaultDaemon) Start

func (d *OxFaultDaemon) Start()

Start starts the ox fault daemon.

type RPCCall

type RPCCall struct {
	Type      string
	Payload   json.RawMessage
	Timestamp time.Time
}

RPCCall records an RPC call made to the mock daemon.

type TestEnvironment

type TestEnvironment struct {
	TmpDir     string
	LedgerDir  string
	ProjectDir string
	// contains filtered or unexported fields
}

TestEnvironment sets up an isolated test environment for daemon tests. Returns a cleanup function that must be called to restore the environment.

func NewTestEnvironment

func NewTestEnvironment(t *testing.T) *TestEnvironment

NewTestEnvironment creates a new isolated test environment. Sets up XDG directories to isolate tests from user's real config.

func (*TestEnvironment) StartDaemon

func (e *TestEnvironment) StartDaemon() func()

StartDaemon starts a test daemon using this environment.

func (*TestEnvironment) StartFault

func (e *TestEnvironment) StartFault(config OxFaultConfig) *OxFaultDaemon

StartFault starts an ox fault daemon using this environment. This provides access to all fault injection modes while understanding ox protocol.

func (*TestEnvironment) StartMock

func (e *TestEnvironment) StartMock() *MockDaemon

StartMock starts a mock daemon using this environment. Deprecated: Use StartFault for new tests.

Jump to

Keyboard shortcuts

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