ktest

package
v0.16.0 Latest Latest
Warning

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

Go to latest
Published: Sep 21, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package ktest provides high-level test helpers for the kernel action runtime.

Mirrors xtest:

Require*  Fatal. Calls tb.Fatalf and stops the current test (or subtest).
Assert*   Soft. Calls tb.Errorf and continues. Only AssertContracts uses
          this form today (reports every structural problem in one run).
Run(...)  Fluent chain. Every terminal method is fatal.

Parameters of type testing.TB are named tb (not t).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AssertContracts

func AssertContracts(t *testing.T, actions []action.AnyAction)

AssertContracts checks structural invariants across every action and is intentionally soft: each action is validated in its own subtest using t.Errorf so that one bad action does not hide the rest.

func BenchAction

func BenchAction[Req, Res any](b *testing.B, act *action.BuiltAction[Req, Res], req Req)

BenchAction benchmarks a built action's pure execution speed without transport overhead. Use it to lock in the zero-allocation hot path on Do/DoAny: a regression shows up in allocs/op immediately.

func Ctx

Ctx returns a fresh request scope bound to context.Background() and registered with tb.Cleanup so it is released back to the pool when the test ends.

func CtxWithAuth

func CtxWithAuth(tb testing.TB, userID, tenantID string, roles ...string) context.Context

CtxWithAuth is the common composite: user + tenant + roles in a single call.

func CtxWithPerm

func CtxWithPerm(tb testing.TB, perm string) context.Context

CtxWithPerm returns a context carrying a scope with the given permission.

func CtxWithRole

func CtxWithRole(tb testing.TB, role string) context.Context

CtxWithRole returns a context carrying a scope with the given role.

func CtxWithTenant

func CtxWithTenant(tb testing.TB, tenantID string) context.Context

CtxWithTenant returns a context carrying a scope with the tenant ID.

func CtxWithUser

func CtxWithUser(tb testing.TB, userID string) context.Context

CtxWithUser returns a context carrying a scope with the user ID.

func Echo

func Echo[T any](name string) *action.Builder[T, T]

Echo returns a typed action that returns its request unchanged.

func Fails

func Fails[Req, Res any](name string, err error) *action.Builder[Req, Res]

Fails returns a typed action that always returns err and the zero response.

func Fake

func Fake(name string, res any) action.AnyAction

Fake returns an untyped action that always succeeds with res. Prefer Returns when the request and response types are known.

func FakeErr

func FakeErr(name string, err error) action.AnyAction

FakeErr returns an untyped action that always fails with err. Prefer Fails when the request and response types are known.

func FakeSeq

func FakeSeq(name string, values ...any) action.AnyAction

FakeSeq returns an untyped action that yields each value in order, then repeats the last one. Prefer Sequence when the response type is known.

func Flaky

func Flaky[Req, Res any](name string, failures int, err error, value Res) *action.Builder[Req, Res]

Flaky returns err for the first failures executions and then returns value. It is deterministic and safe for concurrent action execution.

func MustError

func MustError[Req, Res any](tb testing.TB, fn action.Fn[Req, Res], req Req, want error)

func MustExecute

func MustExecute[Req, Res any](tb testing.TB, fn action.Fn[Req, Res], req Req) Res

func NewErrAction

func NewErrAction(name string, err error) *action.Builder[struct{}, string]

NewErrAction returns a new action builder that accepts struct{} and returns ("", err).

func NewOkAction

func NewOkAction(name string) *action.Builder[struct{}, string]

NewOkAction returns a new action builder that accepts struct{} and returns ("ok", nil).

func RequestContext

func RequestContext(tb testing.TB, requestID string) context.Context

RequestContext returns the test context carrying requestID. The request ID is the idempotency key used by action middleware; cancellation and timeout remain explicit with context.WithCancel/WithTimeout at the call site.

func RequireCondition

func RequireCondition(tb testing.TB, condition bool, format string, args ...any)

RequireCondition fails the test when condition is false.

func RequireEqual

func RequireEqual[T any](tb testing.TB, got, want T)

RequireEqual fails the test when got and want differ.

func RequireErrorContains

func RequireErrorContains(tb testing.TB, err error, substr string)

RequireErrorContains fails the test when err is nil or lacks substr.

func RequireErrorIs

func RequireErrorIs(tb testing.TB, err, target error)

RequireErrorIs fails the test when err does not wrap target.

func RequireErrorKind

func RequireErrorKind(tb testing.TB, err error, want xerr.Kind)

RequireErrorKind fails the test unless err is an *xerr.AppError with the given kind. It prints the full error on failure so the caller does not need a second assertion to see what actually happened.

func RequireNoError

func RequireNoError(tb testing.TB, err error)

RequireNoError fails the test when err is non-nil.

func RequirePermanent

func RequirePermanent(tb testing.TB, err error)

RequirePermanent fails the test unless err is permanent by xerr rules (must not be retried).

func RequireStringContains

func RequireStringContains(tb testing.TB, value, substr string)

RequireStringContains fails the test when value lacks substr.

func RequireTransient

func RequireTransient(tb testing.TB, err error)

RequireTransient fails the test unless err is transient by xerr rules (safe to retry).

func Returns

func Returns[Req, Res any](name string, value Res) *action.Builder[Req, Res]

Returns returns a typed action that always returns value.

func Script

func Script[Req, Res any](results ...Result[Res]) action.Fn[Req, Res]

func Sequence

func Sequence[Req, Res any](name string, values ...Res) *action.Builder[Req, Res]

Sequence returns values in order and repeats the final value thereafter. The sequence is safe for concurrent action execution.

func Simulate

func Simulate[Req, Res any](
	tb testing.TB,
	act *action.BuiltAction[Req, Res],
	req Req,
	concurrency int,
	assertFn func(tb testing.TB, res Res, err error),
)

Types

type Call

type Call struct {
	Seq      uint64
	Action   string
	Request  any
	Response any
	Err      error
	Duration time.Duration
	When     time.Time
}

type Counter

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

Counter records action executions without requiring a custom atomic in each test.

func NewCounter

func NewCounter() *Counter

NewCounter returns an empty execution counter.

func (*Counter) Inc

func (c *Counter) Inc()

Inc records one execution.

func (*Counter) Load

func (c *Counter) Load() int64

Load returns the number of recorded executions.

func (*Counter) Require

func (c *Counter) Require(tb testing.TB, want int64)

Require fails unless the counter equals want.

type Recorder

type Recorder[Req, Res any] struct {
	Retries      []RetryEvent[Req]
	CacheHits    int
	CacheMisses  int
	Coalesced    int
	Deduplicated int
	// contains filtered or unexported fields
}

Recorder implements action.HookDispatcher with full goroutine concurrency safety.

func (*Recorder[Req, Res]) OnCacheHit

func (r *Recorder[Req, Res]) OnCacheHit(context.Context, Req, Res)

func (*Recorder[Req, Res]) OnCacheMiss

func (r *Recorder[Req, Res]) OnCacheMiss(context.Context, Req)

func (*Recorder[Req, Res]) OnCoalesced

func (r *Recorder[Req, Res]) OnCoalesced(context.Context, Req)

func (*Recorder[Req, Res]) OnDeduplicated

func (r *Recorder[Req, Res]) OnDeduplicated(context.Context, Req)

func (*Recorder[Req, Res]) OnRetry

func (r *Recorder[Req, Res]) OnRetry(_ context.Context, req Req, attempt int, err error)

type Result

type Result[Res any] struct {
	Value Res
	Err   error
}

func Failure

func Failure[Res any](err error) Result[Res]

func Success

func Success[Res any](value Res) Result[Res]

type RetryEvent

type RetryEvent[Req any] struct {
	Request Req
	Attempt int
	Err     error
}

RetryEvent records one retry attempt.

type RunResult

type RunResult[Res any] struct {
	// contains filtered or unexported fields
}

RunResult is a chainable assertion wrapper. Every terminal method is fatal.

func Run

func Run[Req, Res any](
	tb testing.TB,
	act *action.BuiltAction[Req, Res],
	ctx context.Context,
	req Req,
) *RunResult[Res]

func (*RunResult[Res]) Contains

func (r *RunResult[Res]) Contains(substr string) *RunResult[Res]

func (*RunResult[Res]) Equals

func (r *RunResult[Res]) Equals(want Res) *RunResult[Res]

func (*RunResult[Res]) ErrorContains

func (r *RunResult[Res]) ErrorContains(substr string) *RunResult[Res]

func (*RunResult[Res]) ErrorKind

func (r *RunResult[Res]) ErrorKind(kind xerr.Kind) *RunResult[Res]

func (*RunResult[Res]) IsError

func (r *RunResult[Res]) IsError(target error) *RunResult[Res]

func (*RunResult[Res]) NoError

func (r *RunResult[Res]) NoError() *RunResult[Res]

func (*RunResult[Res]) Satisfies

func (r *RunResult[Res]) Satisfies(fn func(res Res) bool, msgAndArgs ...any) *RunResult[Res]

func (*RunResult[Res]) Value

func (r *RunResult[Res]) Value() Res

type Trace

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

func NewTrace

func NewTrace() *Trace

func (*Trace) Calls

func (t *Trace) Calls() []Call

func (*Trace) Count

func (t *Trace) Count(name string) int

func (*Trace) Dump

func (t *Trace) Dump(tb testing.TB)

func (*Trace) Hook

func (t *Trace) Hook() action.AnyHook

func (*Trace) Names

func (t *Trace) Names() []string

func (*Trace) RequireAllSucceeded

func (t *Trace) RequireAllSucceeded(tb testing.TB)

func (*Trace) RequireCalled

func (t *Trace) RequireCalled(tb testing.TB, name string)

func (*Trace) RequireErrorsAt

func (t *Trace) RequireErrorsAt(tb testing.TB, want ...string)

func (*Trace) RequireNotCalled

func (t *Trace) RequireNotCalled(tb testing.TB, name string)

func (*Trace) RequireOrder

func (t *Trace) RequireOrder(tb testing.TB, first, second string)

func (*Trace) RequireSequence

func (t *Trace) RequireSequence(tb testing.TB, want ...string)

func (*Trace) RequireSubsequence

func (t *Trace) RequireSubsequence(tb testing.TB, want ...string)

func (*Trace) Reset

func (t *Trace) Reset()

Jump to

Keyboard shortcuts

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