Help us shape the future of Go! Take the 2026 Go Developer Survey

testharness

package
v0.2.43 Latest Latest
Warning

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

Go to latest
Published: Jul 26, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package testharness provides in-process test scaffolding for the permission system. It exists so unit tests of guards, interceptors, and plugin code can assert PDP behavior WITHOUT spinning up a real saas-starter (which lives in a separate repo and needs Postgres).

What's here:

  • FakePDP: programmable decisions + a recorded call log. Use this when a unit test needs "PDP says allow on action X, deny on action Y" without caring how the decisions are made.

  • PrincipalBuilder: ergonomic construction of test Principals (humans, services, agents) for stamping into context.

  • DelegationBuilder: build delegation chains for tests of escalation / sub-agent flows.

What's NOT here (yet):

  • SaaSFixture: a Postgres + saas-starter API harness. Lives in M0 phase 2 once the saas-starter Principal/Decide RPCs land. For now, integration tests against saas-starter live alongside the saas-starter codebase, not here.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type FakeCall

type FakeCall struct {
	Toolbox  string
	Tool     string
	Args     map[string]any
	Identity map[string]any
	Decision policy.PDPDecision // what the FakePDP returned
}

FakeCall is one recorded Evaluate. The fields are immutable snapshots — callers can hold them safely after Calls() returns.

type FakePDP

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

FakePDP is a programmable PDP for unit tests. It records every call so tests can assert what was asked, AND it returns a decision determined by either:

  1. An exact-match rule (Tool == request.Tool AND Toolbox == request.Toolbox)
  2. A toolbox-match rule (Toolbox == request.Toolbox, Tool == "")
  3. The default decision (set by NewFakePDP)

First match in the rules slice wins, in the order rules were added.

Concurrency: safe. Tests that fire goroutines at the PDP can read Calls() after the fact to assert what happened.

func NewFakeAllow

func NewFakeAllow() *FakePDP

NewFakeAllow returns a FakePDP whose default is allow. Use when the test cares about specific denies; everything else is permitted.

func NewFakeDeny

func NewFakeDeny() *FakePDP

NewFakeDeny returns a FakePDP whose default is deny with a recognizable reason. Use when the test cares about specific allows; everything else is refused. Reason includes "fake-pdp" substring so failure messages clearly show the gate is the test fixture, not a misconfigured production PDP.

func NewFakePDP

func NewFakePDP(defaultDecision policy.PDPDecision) *FakePDP

NewFakePDP returns a FakePDP whose default (when no rule matches) is the supplied decision. Most tests use NewFakeAllow or NewFakeDeny rather than this directly.

func (*FakePDP) AllowTool

func (f *FakePDP) AllowTool(toolbox, tool string) *FakePDP

AllowTool installs a rule allowing a specific tool on the named toolbox. Both must match exactly. Wildcards are not supported in the fake — tests that need pattern matching should configure multiple explicit rules.

func (*FakePDP) AllowToolbox

func (f *FakePDP) AllowToolbox(toolbox string) *FakePDP

AllowToolbox installs a rule allowing all tools on the named toolbox. Returns the receiver for chaining.

func (*FakePDP) CallCount

func (f *FakePDP) CallCount() int

CallCount returns the number of Evaluate calls observed. Cheaper than Calls() when the test only needs a count.

func (*FakePDP) Calls

func (f *FakePDP) Calls() []FakeCall

Calls returns a snapshot of every Evaluate call observed so far. Returned slice is safe to retain — it's a copy.

func (*FakePDP) DenyTool

func (f *FakePDP) DenyTool(toolbox, tool, reason string) *FakePDP

DenyTool installs a rule denying a specific tool with a reason. Reason MUST be non-empty — silent denials are a debugging nightmare; force the test author to write what they're asserting.

func (*FakePDP) DenyToolbox

func (f *FakePDP) DenyToolbox(toolbox, reason string) *FakePDP

DenyToolbox installs a rule denying all tools on the named toolbox with the given reason. Empty reason gets a defaulted message.

func (*FakePDP) Evaluate

func (f *FakePDP) Evaluate(_ context.Context, req *policy.PDPRequest) policy.PDPDecision

Evaluate implements policy.PDP. Records the call, returns the matched decision (or default).

func (*FakePDP) LastCall

func (f *FakePDP) LastCall() FakeCall

LastCall returns the most recent FakeCall, panicking if none have been recorded. Tests that assert on a single call use this for concise assertions: pdp.LastCall().Tool == "git.status".

func (*FakePDP) Reset

func (f *FakePDP) Reset()

Reset clears the call log without removing rules. Useful when a single test case spans multiple "phases" and wants to assert calls per phase.

type PrincipalBuilder

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

PrincipalBuilder constructs test Principals fluently. The default (zero-value Builder) gives a valid human principal in org "test-org" with a generated ID — useful when the test doesn't care who, just that there IS a principal.

Usage:

p := testharness.NewPrincipalBuilder().AsAgent("auto-merge", "0.1.0").Build()
ctx := policy.WithPrincipal(context.Background(), p)

func NewPrincipalBuilder

func NewPrincipalBuilder() *PrincipalBuilder

NewPrincipalBuilder returns a builder with sensible defaults: a human principal in "test-org" with a unique generated ID.

func (*PrincipalBuilder) AsAgent

func (b *PrincipalBuilder) AsAgent(name, version string) *PrincipalBuilder

AsAgent switches kind to agent and sets AgentID to the canonical "publisher/name:version" form. Tests should pass non-empty name + version; we fill in publisher as "test.codefly.dev" if not specified via WithAgentPublisher.

func (*PrincipalBuilder) AsHuman

func (b *PrincipalBuilder) AsHuman() *PrincipalBuilder

AsHuman switches kind to human, clearing any previously-set agent fields. Default; rarely called explicitly.

func (*PrincipalBuilder) AsService

func (b *PrincipalBuilder) AsService() *PrincipalBuilder

AsService switches kind to service. Use for test fixtures representing CI runners, deployment bots without per-version identity, etc.

func (*PrincipalBuilder) Build

func (b *PrincipalBuilder) Build() *policy.Principal

Build produces the Principal. Panics on Validate failure — tests should fail loud if the builder produced something nonsensical.

func (*PrincipalBuilder) DelegatedFrom

func (b *PrincipalBuilder) DelegatedFrom(principalID, kind, displayName, grantID string) *PrincipalBuilder

DelegatedFrom appends a link to the delegation chain. Multiple calls build a chain in the order they were called (oldest first).

Example: a sub-agent acting under user antoine's authority who herself delegated through Mind:

NewPrincipalBuilder().AsAgent("merger", "0.1.0").
    DelegatedFrom("user-antoine", policy.KindHuman, "antoine", "grant-1").
    DelegatedFrom("agent-mind", policy.KindAgent, "Mind", "grant-2").
    Build()

func (*PrincipalBuilder) ExpiringIn

func (b *PrincipalBuilder) ExpiringIn(d time.Duration) *PrincipalBuilder

ExpiringIn sets ExpiresAt to now+d. Use this rather than WithExpiresAt when the test only cares about "expires soon" / "expires far in the future" relative timing.

func (*PrincipalBuilder) WithAgentID

func (b *PrincipalBuilder) WithAgentID(id string) *PrincipalBuilder

WithAgentID overrides the auto-built AgentID. Use when the test needs an exact identifier (e.g. matching a real plugin manifest).

func (*PrincipalBuilder) WithDisplayName

func (b *PrincipalBuilder) WithDisplayName(name string) *PrincipalBuilder

WithDisplayName sets the human-readable name surfaced in audit / approval UI.

func (*PrincipalBuilder) WithExpiresAt

func (b *PrincipalBuilder) WithExpiresAt(t time.Time) *PrincipalBuilder

WithExpiresAt sets the absolute expiry. Used by tests that drive IsExpiredAt with a fixed clock.

func (*PrincipalBuilder) WithID

func (b *PrincipalBuilder) WithID(id string) *PrincipalBuilder

WithID overrides the auto-generated ID. Use when the test must assert a specific principal_id appearing in audit / PDP calls.

func (*PrincipalBuilder) WithOrg

func (b *PrincipalBuilder) WithOrg(orgID string) *PrincipalBuilder

WithOrg sets the organization. Defaults to "test-org".

func (*PrincipalBuilder) WithToken

func (b *PrincipalBuilder) WithToken(tok string) *PrincipalBuilder

WithToken sets the credential string. Tests of token-aware paths (PDP that re-verifies caveats, audit that logs the token id) need this to be a real-shaped token; tests of pure auth flow can leave it as the empty default.

Jump to

Keyboard shortcuts

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