Documentation
¶
Overview ¶
Package conformance defines the shared result and configuration vocabulary used by the conformance runner and per-format modules.
Exported in this package: Status, Priority, TestCase, Detail, HTTPDetail, CLIDetail, Credential, CredentialType, the convenience constructors (Pass, Fail, FailWithHTTPDetail, FailWithCLIDetail, FailWithDetail, Skip, SkipWithDetail, SkipAfterSeeding), Config, and Report. Per-format protocol logic lives under pkg/conformance/{maven,npm,oci}; per-format HTTP clients live under pkg/client/{maven,npm,oci}.
Index ¶
- Constants
- Variables
- func CanonicalHost(host string) string
- func ContextWithLogger(ctx context.Context, log *slog.Logger) context.Context
- func GenerateRunID() (string, error)
- func LoggerFromContext(ctx context.Context) *slog.Logger
- func PreflightFailureMessage(registryURL, upstreamURL, observed string) string
- func SeedAndSettle(ctx context.Context, spec SeedSpec) (SeedResult, *SeedError)
- type CLIDetail
- type CLIEnv
- type CLIExecutor
- type CLIResult
- type Config
- type ConfigError
- type Credential
- type CredentialType
- type Detail
- type Env
- type FilterNoMatchError
- type HTTPDetail
- type Module
- type Priority
- type PriorityNoMatchError
- type Report
- type RepositoryKind
- type RunOpts
- type SeedCallback
- type SeedError
- type SeedResult
- type SeedSpec
- type Status
- type TestCase
- func Fail(name, message string) TestCase
- func FailWithCLIDetail(name, message string, d CLIDetail) TestCase
- func FailWithDetail(name, message string, d Detail) TestCase
- func FailWithHTTPDetail(name, message string, d HTTPDetail) TestCase
- func NewSeedFailureCase(name string, e *SeedError) TestCase
- func Pass(name string) TestCase
- func Skip(name, reason string) TestCase
- func SkipAfterSeeding(name, reason string) TestCase
- func SkipWithDetail(name, reason string, d Detail) TestCase
- type TestDescriptor
- type UpstreamEnv
Constants ¶
const ( // SeedAttempts is the initial attempt plus the one re-attempt // §Preflight's transient row allows ("one more attempt, then exit 2 // if it fails too"). The derived --timeout budgets one settle window // per attempt per settling row on exactly this count (S08 AC #30), so // raising it overruns that budget unless the budget moves with it. // // Exported for that reason: internal/cli builds the floor from this // constant, so the two halves of the pairing cannot drift. SeedAttempts = 2 )
Variables ¶
var ErrNothingEstablished = errors.New("no seeding row completed")
ErrNothingEstablished reports that a run completed but established no fixture, so it validated nothing (S08 AC #36). RunModule returns it wrapped, with Report.Interrupted set to that same wrapped error, under a resolved remote RepositoryKind, when the run's Env exposes an upstream (UpstreamEnv answering true) and no selected NeedsUpstream descriptor got the run's fixture onto the upstream.
The question is about the seeding and not about the Status: a row can seed and then skip, on the arm S07 §Pluggable behavior gives it, and such a row established its fixture. A row that skips before it writes anything did not, whether because the write was refused or because a driver gate or a probe turned it back. Only SkipAfterSeeding tells the runner the first case apart from the second.
A run whose catalog holds at least one NeedsUpstream descriptor and whose Filter or Priorities removed them all is exempt: it established what it selected. A run whose m.TestCatalog(cfg) holds none to begin with is not, because nothing the operator did produced that empty set.
The kind is read, but the upstream question is answered from the Env and never from the Config: a caller whose Config.UpstreamURL is set but whose Env does not expose an upstream exits 0 with every seeding row skipped by the upstream gate.
Its own message is "no seeding row completed". RunModule wraps it with the branch that applies, so errors.Is still matches this value while the operator reads one of the two diagnoses S04 §Entry points pins verbatim: one sending the operator to the row reasons, which is where each row's own cause lives, one naming a catalog that registers no remote row that seeds.
The recovery contract is on this value rather than on the message, because that is what an errors.Is caller reads (S08 §Preflight): it means the run's environment needs reconfiguration, not retry as-is. It is neither a target verdict (StatusFail would be) nor a transport abort (ctx.Err()), because a caller that retries on either would loop or page the wrong team.
Exported so a library caller can errors.Is it apart from a transport abort.
Functions ¶
func CanonicalHost ¶ added in v1.69.1
CanonicalHost returns the form of a URL hostname that two hosts are compared in when deciding whether a redirect stays on the same host: the trailing root-label dot stripped, then the name mapped to ASCII through idna.Lookup.ToASCII. That is the profile net/http itself uses (idnaASCII, src/net/http/request.go), so the comparison sees the name the dial will resolve rather than the bytes the Location happened to carry.
Callers still compare two results case-insensitively. ToASCII lower-cases what it maps, but the error path below does not, and the compare this replaces was an RFC 4343 case-insensitive one that must keep behaving that way.
A bare case fold of url.URL.Hostname() is not sufficient, and it is wrong in both directions. strings.EqualFold folds Unicode case, but UTS-46 keeps several fold-equal pairs distinct: final-ς (U+03C2) maps to xn--3xa, while both σ (U+03C3) and Σ (U+03A3) map to xn--4xa. A fold-only compare calls each of those pairs the same host, which keeps a credential on a hop to a different DNS name. It errs the other way too: registry.test. and registry.test, example.com and example.com, faß.de and xn--fa-hia.de are one name each, and a fold-only compare reads them as different hosts.
Which pairs stay distinct is not fixed. x/net/idna selects its UTS-46 tables by Go release, so a toolchain bump can merge a pair that used to be two names: ß (U+00DF) and ẞ (U+1E9E) were distinct through Unicode 15, where ẞ mapped to ss, and are one name from Unicode 17 on. Tracking the toolchain is the correct behaviour rather than a defect, because net/http normalizes the dial through this same profile, so the comparison keeps seeing the name that will actually be resolved. It does mean a test may only pin a pair whose verdict is stable, which is why ς is the one deviation character the tests name.
An input ToASCII refuses is returned dot-trimmed and otherwise unchanged, so the comparison degrades to the fold-only one rather than declaring two hosts different because neither could be mapped. The case that reaches this is an IPv6 literal: url.URL.Hostname() strips the brackets and ToASCII rejects the colons. Two spellings of one IPv6 address therefore still compare as different hosts, unchanged from before and in the conservative direction — a credential is dropped, never kept.
func ContextWithLogger ¶
ContextWithLogger returns a derived context carrying log. A later call to LoggerFromContext on the returned context (or any context derived from it) returns log, unless another ContextWithLogger call shadows it.
func GenerateRunID ¶
GenerateRunID returns 16 lowercase hex characters from 8 crypto/rand bytes per S04 §Run-ID resolution, which also fixes the exported signature so AR integration harnesses can call it without a reader argument; the random source is the unexported generateRunID seam, which tests substitute via export_test.go.
The width is 64 bits rather than 32 because run-ID collisions are not self-healing: fixtures are never cleaned up, so the birthday bound runs against every run that ever executed against the registry rather than against the concurrent ones. S04 §Run-ID resolution and S08 §Fixture seeding model carry the full reason, including why a collision against a remote repository is worse than a repeat.
The same never-cleaned-up property makes the widening one-way in effect: reverting this function to 4 bytes restores 8-character generation, but every fixture already created under a 16-character ID stays in the target registry, so both widths remain live there. A consumer that must recognize suite-created fixtures has to accept either width from here on, whichever way the code goes.
On failure the error is wrapped with this function's own operation context ("read random bytes"), not the caller's. Run / RunModule add the "generate run id" prefix per S04 §Run-ID resolution, so a failure surfaced through Run reads "generate run id: read random bytes: ...", with each layer naming what it was doing and no duplicated prefix.
func LoggerFromContext ¶
LoggerFromContext returns the logger previously stashed on ctx by ContextWithLogger. When no logger is present, it returns a non-nil fallback logger that discards every record. The fallback never returns nil and never panics when used by callers.
func PreflightFailureMessage ¶ added in v1.66.0
PreflightFailureMessage formats the message S08 §Preflight pins verbatim and requires to be identical across the three format modules: "remote repository at <registry-url> did not serve the fixture seeded at <upstream-url>: <observed>".
observed is the read-back's status and error body, or the transport error when no response arrived. Both URLs render through redact.RedactURLUserinfo and observed through redact.RedactURLUserinfo(redact.ScanContent(...)), inside the formatter rather than in each Fn, so a third-party module cannot skip the scrub (S08 AC #24).
func SeedAndSettle ¶ added in v1.66.0
func SeedAndSettle(ctx context.Context, spec SeedSpec) (SeedResult, *SeedError)
SeedAndSettle seeds one row's fixture on the upstream and confirms it readable there, then classifies any failure per S08 §Preflight's cause table. It owns the settle poll (S05 §Async metadata sync polling's loop, with S08's SettleTimeout == 0 carve-out of exactly one read-back and one added post-poll cancellation check), the single re-attempt that resumes rather than restarts, AC #37's content-identity check on a resumed settle, and the scrub and bound on the detail a *SeedError carries.
A nil *SeedError means either that the fixture is readable on the upstream, in which case the returned SeedResult is the read-back that satisfied the settle, or that the context was cancelled, in which case it is whatever the last leg observed.
Callers must re-check ctx.Err() after a nil *SeedError. A cancelled context is not a seeding failure: a ctx.Err() from either callback or from the settle loop takes no re-attempt and produces no *SeedError, so the two returns cannot distinguish it from success. An Fn that reads nil as "seeded" then asserts against a coordinate this run never wrote and reports StatusFail for it, which is a compliance verdict on a run that was merely interrupted. On a cancellation the Fn reports a plain StatusSkip and the runner keeps ownership of the exit. Widening the signature is deferred to the first preflight caller (plan Step 5a).
Types ¶
type CLIDetail ¶
type CLIDetail struct {
Driver string
Version string
Argv []string
ExitCode int
Signal string
Duration time.Duration
Stdout string
Stderr string
}
CLIDetail carries driver-level context for a failing TestCase per S04 §581-595. Field order matches the canonical render order used by the output layer.
type CLIEnv ¶
type CLIEnv interface {
// HasCLI reports whether a CLI executor is available in this env.
HasCLI() bool
// CLI returns the executor for driver-using tests. Valid only
// when HasCLI() is true; nil otherwise. See S04 §CLI drivers for
// the CLIExecutor contract.
CLI() CLIExecutor
// CLIVersion returns the resolved driver version captured at
// NewEnv time. Equal to the value CLI().Version() returns. Empty
// when HasCLI() is false. See S04 §CLI drivers / Version pinning.
CLIVersion() string
}
CLIEnv is implemented by envs that expose an external CLI driver per S04 §479-497. Driver-using tests type-assert to this interface and emit StatusSkip when HasCLI returns false. Modules with no driver support do not need to implement it. CLIEnv and Env are declared as separate interfaces in the spec; the runner holds Env and reaches CLIEnv only by type assertion at call sites that need driver methods (see S04 §499-504 for the smallest-interface rationale).
type CLIExecutor ¶
type CLIExecutor interface {
// Name reports the driver identifier used in CLIDetail.Driver
// and in skip / failure messages. Stable across invocations.
Name() string
// Version reports the resolved driver version. Resolved exactly
// once during Module.NewEnv (see S04 §Version pinning) and
// returned verbatim on every call thereafter. Empty only when
// version resolution failed and HasCLI() returned false.
Version() string
// Run invokes the driver with the supplied argv. The runner
// passes ctx for cancellation; the implementation MUST honor it
// via exec.CommandContext per S04 §Invocation contract.
//
// Returns CLIResult on every outcome where the process started.
// Returns a non-nil error only when the process could not be
// spawned at all (binary not found, permission denied, fork
// failure). Non-zero exit codes and signals are NOT returned as
// errors — they are conveyed via CLIResult so the test function
// can interpret them.
Run(ctx context.Context, argv []string, opts RunOpts) (CLIResult, error)
}
CLIExecutor invokes an external CLI with a fixed contract per S04 §1126-1159. One implementation per driver per format (e.g. pkg/client/npm/cli.go implements CLIExecutor for the npm CLI). The runner sees only the interface.
type CLIResult ¶
type CLIResult struct {
// Argv is the invocation argv with secret-flag values redacted: the
// built-in --password/--auth/--token set plus any flags the executor
// declared via WithSecretFlags. A caller building a CLIDetail must
// populate CLIDetail.Argv from this, not from the raw argv passed to
// Run, so a secret-bearing flag value never reaches the report
// (S04 §Secret-bearing argv). Empty when the driver was unavailable
// and no invocation was attempted.
Argv []string
// ExitCode is the process exit code; 0 on success; -1 if killed
// by a signal.
ExitCode int
// Signal is empty unless the process was killed by a signal
// (e.g. "killed", "terminated").
Signal string
// Duration is the wall-clock time the process ran.
Duration time.Duration
// Stdout is tail-truncated to 4 KiB with a "... [truncated]"
// marker on truncation.
Stdout string
// Stderr is tail-truncated to 4 KiB with a "... [truncated]"
// marker on truncation.
Stderr string
}
CLIResult is the structured outcome of a driver invocation per S04 §1173-1181. Every field is populated by the executor.
type Config ¶
type Config struct {
// Format selects the per-format module: "maven" | "npm" | "oci".
Format string
// RegistryURL is the base URL of the registry under test.
RegistryURL string
// Credential is the user-supplied secret carried into protocol
// requests. Zero value (empty Type, all halves empty) means
// unauthenticated.
Credential Credential
// Filter is a path.Match glob pattern. Empty means no filtering;
// otherwise only TestDescriptor.Name matching the glob runs.
Filter string
// Priorities is a non-empty allow-list of priorities to run. nil
// or empty means no priority filtering. AND-composes with Filter.
Priorities []Priority
// RunID is the per-invocation identifier. Empty triggers
// auto-generation inside Run / RunModule.
RunID string
// SettleTimeout is the per-write polling cap for async
// registries. Zero disables polling.
//
// Forward-looking, not yet implemented: S08 §Seeding and
// asynchronous upstreams gives the field a remote carve-out, under
// which a resolved RepositoryKindRemote makes zero still perform
// exactly one read-back rather than skipping it. Skipping it would
// hand the proxy a coordinate the upstream may not serve yet, and
// that hazard does not go away because the operator declared the
// registry synchronous. The carve-out arrives with the shared
// seed-and-settle helper (plan Step 5a); until then every reader
// branches on "> 0" and the field carries only the meaning above.
SettleTimeout time.Duration
// HTTPClient is the HTTP client tests use. nil triggers the
// library default client.
HTTPClient *http.Client
// Logger is the structured logger the library derives child
// loggers from. nil triggers a JSON handler over io.Discard.
Logger *slog.Logger
// AllowRedirectHosts is the per-host glob allow-list consulted by
// the library-default CheckRedirect before following a cross-host
// redirect. nil or empty preserves strict cross-host rejection.
AllowRedirectHosts []string
// RepositoryKind is the kind of repository under test per S08
// §Configuration. Empty resolves to RepositoryKindHosted.
RepositoryKind RepositoryKind
// OCINamePrefix is prepended to every OCI conformance repository
// name, per S07 §Repository naming / Configurable name prefix.
// Empty, the default, leaves the name at
// conformance/{runID}/{slug-mapped}.
//
// It is OCI-only because OCI is the one format whose repository name
// is not expressible through RegistryURL: the /v2/ literal is
// inserted between the base URL and the name, so a prefix that has
// to live inside the name cannot be carried on the base URL. Maven
// and npm address their repository root through RegistryURL alone,
// which is why neither needs an equivalent.
//
// A non-empty value under any Format other than "oci" is rejected by
// Config.Validate with *ConfigError{Field: "oci-name-prefix"}: the
// field is OCI-only, and a value that is accepted and discarded
// teaches the operator it took effect. That rule needs only a Format
// comparison, so this layer owns it.
//
// The value's OCI <name> grammar is checked elsewhere. It is protocol
// knowledge the runner layer does not carry, so the OCI module's
// NewEnv checks it with pkg/client/oci.ValidateName and returns the
// same *ConfigError field before any request.
//
// Total length is unchecked. ValidateName enforces the per-segment
// grammar but no overall cap, and the conformance-owned suffix runs
// to roughly 120 characters at a 64-character RunID, so a prefix past
// roughly 135 characters can push a generated name over a registry's
// 255-character limit. The registry's NAME_INVALID then surfaces as a
// conformance failure rather than as a configuration error.
OCINamePrefix string
// OCIUpstreamNamePrefix is prepended to every OCI conformance
// repository name addressed through UpstreamURL, in place of
// OCINamePrefix. Empty, the default, means the upstream is addressed
// under OCINamePrefix like every other name.
//
// It exists for the one registry shape OCINamePrefix alone cannot
// address: a remote repository and the upstream it proxies living on
// one host, as two repositories distinguished only by name. OCI puts
// /v2/ first in the path, so the base URL can only be the host, which
// leaves RegistryURL and UpstreamURL identical and the name as the
// only thing that can tell the two repositories apart. Maven and npm
// carry the repository in the base URL, so neither has the shape.
//
// Setting it is also what admits an otherwise-rejected pair: a
// non-empty value differing from OCINamePrefix lifts the
// UpstreamURL-must-differ-from-RegistryURL rule, because the two
// names then address two repositories. See
// compareUpstreamAgainstRegistry in validate.go.
//
// A non-empty value is rejected by Config.Validate with
// *ConfigError{Field: "oci-upstream-name-prefix"} under any Format
// other than "oci" and under any resolved RepositoryKind other than
// remote, for the reason OCINamePrefix states: a value accepted and
// discarded teaches the operator it took effect. Both rules need only
// field comparisons, so this layer owns them. Neither reaches a remote
// run declaring UpstreamFreeOnly, which also has no upstream for a
// second name to address; see validateOCIUpstreamNamePrefix for why
// that case is left accepted.
//
// Its OCI <name> grammar and total length are unchecked here, exactly
// as OCINamePrefix's are, and for the same reasons.
OCIUpstreamNamePrefix string
// UpstreamURL is the base URL of the writable repository the
// repository under test proxies. Empty means no upstream is
// available; only a remote kind may set it.
UpstreamURL string
// UpstreamFreeOnly declares that no writable upstream is
// available, so a remote run's fixture-seeding rows skip. Only a
// remote kind may set it.
UpstreamFreeOnly bool
}
Config is the library-facing configuration value per S04 §645-657. Plain exported fields; callers literal-initialize.
func (Config) Validate ¶
Validate enforces the rules in S04 §Config.Validate. It performs no I/O and is called from the top of Run / RunModule before any module method is invoked. The CLI may also call it to pre-flight an invalid config at startup.
On the first rule failure Validate returns *ConfigError with the kebab-case Field name from S04 §Error Cases / Library layer; rules are checked in the order they appear in the spec so the error surfaced is deterministic. Permissive zero values (empty RunID, nil Priorities, empty Filter, nil AllowRedirectHosts, zero SettleTimeout, zero Credential, empty RepositoryKind, empty UpstreamURL, false UpstreamFreeOnly) are accepted.
type ConfigError ¶
ConfigError is returned by Config.Validate and by Run/RunModule when validation fails. Callers use errors.As. Field is the kebab-case flag name (e.g. "registry-url"); Reason is the human-readable cause. See S04 §Config.Validate and §Error Cases / Library layer.
func (*ConfigError) Error ¶
func (e *ConfigError) Error() string
Error returns the wire-format message documented at S04 §Error Cases / Output layer (runtime): "<Field>: <Reason>" (single line). The CLI prints err.Error() verbatim to stderr, so this format also satisfies the Output layer contract that maps *ConfigError to the "<Field>: <Reason>" stderr line.
type Credential ¶
type Credential struct {
Type CredentialType
Token string
Username string
Password string
}
Credential is the user-supplied secret carried into protocol requests per S04 §628-633. The zero value (empty Type, all halves empty) represents unauthenticated.
func (Credential) String ¶ added in v1.57.0
func (c Credential) String() string
String implements fmt.Stringer so that formatting a Credential never prints its secret halves verbatim. Type and Username are identifiers, not secrets, so they print as-is; a non-empty Token or Password collapses to redact.Sentinel. This covers the "%v", "%s", and "%+v" verbs applied to a Credential value directly, and to a Credential held in an *exported* field of another struct — fmt invokes String() in both cases. It does NOT cover a Credential reached through an *unexported* field (e.g. a package-local struct's lowercased credential field under "%+v"): fmt cannot call methods on values it cannot interface, so it prints such fields by reflection instead. Keep secret-bearing values out of format strings regardless; this method is a backstop, not a licence to format credentials.
type CredentialType ¶
type CredentialType string
CredentialType is the credential kind per S04 §621-626.
const ( // CredentialBearer is a single-string token credential (npm Bearer, // GitLab Maven Private-Token). CredentialBearer CredentialType = "bearer" // CredentialBasic is a two-half user+password credential (OCI, // non-GitLab Maven). CredentialBasic CredentialType = "basic" )
type Detail ¶
type Detail struct {
// HTTP is populated when the failure is HTTP-shaped.
HTTP *HTTPDetail
// CLI is populated when the failure is driver-shaped.
CLI *CLIDetail
}
Detail carries failure context for diagnosis per S04 §556-563. At most one of HTTP or CLI is populated. FailWithHTTPDetail and FailWithCLIDetail enforce this at the signature level; FailWithDetail and SkipWithDetail are the whole-envelope constructors that panic only when both branches are populated and preserve an empty envelope as-given.
type Env ¶
type Env interface {
// Close releases resources held by the env (temp dirs,
// executors).
Close() error
}
Env is the per-credential environment a Module constructs in NewEnv per S04 §471-477. The runner only ever sees Env; per-format envs hold a live *Client and, when applicable, a CLIExecutor.
Format tests should depend on the smallest interface they need (e.g. CLIEnv for driver-using tests, or a package-local client-bearing interface for protocol tests) rather than type-asserting to concrete env internals — see S04 §499-504.
NewEnv MUST NOT return a typed-nil pointer in a non-nil Env together with a nil error: it must return either a usable Env or an error. The runner discovers the optional capabilities below (CLIEnv, UpstreamEnv) by type assertion, and a typed nil satisfies the assertion, so the capability call would dereference nil outside runOne's recover and take the process down rather than failing one row.
type FilterNoMatchError ¶
type FilterNoMatchError struct {
Pattern string
}
FilterNoMatchError is returned by Run/RunModule when cfg.Filter is non-empty but no TestDescriptor.Name in the catalog matches the pattern per S04 §851-855. Returned before any I/O beyond catalog construction.
func (*FilterNoMatchError) Error ¶
func (e *FilterNoMatchError) Error() string
Error reports the no-match condition with the offending pattern.
type HTTPDetail ¶
type HTTPDetail struct {
RequestMethod string
RequestURL string
StatusCode int
// ResponseBody preserves the START of the response body up to 4
// KiB; the END is truncated and a literal "... [truncated]" marker
// is appended when truncation occurs. The start is preferred
// because diagnostic content for HTTP errors (status code, error
// message, structured envelope) typically lives at the beginning.
// See S04 §570-578. The bound is the producer's: FailWithHTTPDetail
// and SkipWithDetail take whatever string they are handed. Callers
// inside this package that source a body themselves apply
// truncateDetailBody; the format clients apply their own copy at
// read time, because they cap the body before it is ever buffered;
// pkg/conformance/{maven,npm,oci} pass an already-capped
// HTTPError.ResponseBody straight through.
ResponseBody string
}
HTTPDetail carries HTTP-level context for a failing TestCase per S04 §565-579.
type Module ¶
type Module interface {
// TestCatalog returns the full set of tests this module declares.
// The runner owns filtering, prefixing, and skip dispatch.
//
// Implementations MUST be pure and idempotent per S04 §439-445:
// TestCatalog may be called more than once per process (e.g. by
// the `list` subcommand ahead of `run`, or by tests that
// introspect the catalog). The returned slice and the descriptors
// within it should be equivalent across calls for the same
// Config. Do not perform network I/O, filesystem I/O, environment
// reads, process execution, or shared state mutation inside
// TestCatalog.
TestCatalog(cfg Config) []TestDescriptor
// NewEnv constructs the per-credential environment per S04
// §448-450. Called once per credential. Returns an error if
// environment setup fails (tool error).
NewEnv(ctx context.Context, cfg Config, cred Credential) (Env, error)
// NegativeAuthTests returns descriptors for auth-failure tests
// that run outside the credential loop per S04 §452-462 — e.g.,
// an unauthenticated probe expected to 401. The runner executes
// each one through the same runOne wrapper as positive
// descriptors (panic recovery, ctx cancellation, name-format
// checks), and appends the resulting cases to
// Report.Cases. A descriptor's Fn is responsible for issuing
// requests without the env's authenticated client (e.g. by
// constructing a fresh client or stripping the Authorization
// header).
NegativeAuthTests(cfg Config) []TestDescriptor
}
Module is the cross-format extension boundary per S04 §432-464. Each supported registry format (maven, npm, oci) provides exactly one implementation; the runner never inspects cfg.Format for dispatch — that knowledge lives entirely in the Module implementation.
Adding a new format means supplying a new Module; the runner is unchanged.
type Priority ¶
type Priority string
Priority is the declared importance of a TestDescriptor per S04 §523-530, used by the runner's cfg.Priorities filter.
const ( // PriorityCritical marks tests that must pass for the registry to // be considered minimally functional. PriorityCritical Priority = "critical" // PriorityHigh marks tests covering the core protocol surface. PriorityHigh Priority = "high" // PriorityMedium marks tests covering common but non-essential // protocol features. PriorityMedium Priority = "medium" // PriorityLow marks tests covering edge cases and optional // behaviors. PriorityLow Priority = "low" )
type PriorityNoMatchError ¶
type PriorityNoMatchError struct {
Priorities []Priority
}
PriorityNoMatchError is returned by Run/RunModule when cfg.Priorities is non-empty but no descriptor in the (already filter-narrowed) catalog declares a Priority in the allow-list. Returned before any I/O beyond catalog construction.
func (*PriorityNoMatchError) Error ¶
func (e *PriorityNoMatchError) Error() string
Error reports the no-match condition with the offending priority allow-list.
type Report ¶
type Report struct {
RunID string
Format string
StartedAt time.Time
Duration time.Duration
Cases []TestCase
// Interrupted is the reason the run did not complete, per S04
// §Report struct. Nil on a completed run. Three values reach it,
// all set by the runner: ctx.Err() on a cancellation path (S04
// §Execution order inside RunModule, steps 7 and 8), the
// TestCase.SetupFailure of a row that could not establish the
// run's fixture source (step 8), and the wrapped
// ErrNothingEstablished of a remote run that established nothing
// (step 9, S08 AC #36). The last two are not cancellations, which
// is why this is no longer "always ctx.Err()". The JUnit renderer
// emits an <error> element with the reason so CI consumers can
// distinguish a truncated run from a legitimately empty one.
Interrupted error
}
Report is the aggregate result returned by Run / RunModule per S04 §869-883.
func Run ¶
Run is the binary-facing entry point per S04 §1038-1057. Looks up a Module from cfg.Format via formatFactories then delegates to RunModule. Returns *ConfigError on validation failure (cfg.Format invalid, credential shape invalid, etc.) without performing any network I/O. See S04 §1038-1057.
func RunModule ¶
RunModule is the library-facing entry point per S04 §1064-1103. Pure orchestration: validate → resolve RunID / Logger → enumerate descriptors → newEnv → runOne loop. Returns *ConfigError on validation failure, *FilterNoMatchError / *PriorityNoMatchError on narrowing failure, (partialReport, ctx.Err()) when ctx is cancelled mid-run (per S04 §Context propagation), (partialReport, that row's TestCase.SetupFailure) when a row could not establish the run's fixture source (S04 §Execution order inside RunModule, step 8), (report, wrapped ErrNothingEstablished) when a remote run completed having established nothing (step 9, S08 AC #36), or (report, nil) on a completed run (including runs where every test case is fail). See S04 §1064-1103.
func (*Report) Counts ¶
Counts returns the number of pass, fail, and skip cases in r.Cases per S04 §882-883. Panics on a non-canonical Status (anything other than StatusPass / StatusFail / StatusSkip): the constructors enforce canonical values, but every TestCase field a Status consumer reads is exported and Config permits literal init per S04 §698-699, so an external library consumer can construct one by hand. Only the seeded marker is unexported, which makes a keyed literal the one form that compiles outside this package, not a barrier to building a case with a Status the constructors would never produce. Silently skipping the unknown value would make `pass+fail+skip < len(Cases)` and let Failed misclassify the run, so the boundary fails fast instead.
func (*Report) Failed ¶
Failed reports whether any TestCase in r.Cases has StatusFail. Per S04 §878-880, skipped cases do not constitute failure. Panics on a non-canonical Status — see Counts for the rationale. Walks the full slice so the fail-fast boundary holds even when a StatusFail precedes the non-canonical value: a consumer that gates exit code on Failed() and then renders via Counts() never observes a clean fail verdict followed by a panic trace.
type RepositoryKind ¶ added in v1.65.0
type RepositoryKind string
RepositoryKind is the kind of repository under test per S08 §Configuration. The zero value is empty and resolves to RepositoryKindHosted, so a Config that never names a kind behaves exactly as it did before S08 (S08 AC #2).
const ( // RepositoryKindHosted is a repository that stores its own // artifacts. It is also the resolved value of an empty // RepositoryKind. RepositoryKindHosted RepositoryKind = "hosted" // RepositoryKindRemote is a caching proxy of a writable upstream // repository. RepositoryKindRemote RepositoryKind = "remote" )
type RunOpts ¶
type RunOpts struct {
// Dir is the absolute path of the working directory the driver runs
// in — the per-test temp directory the S04 §Invocation contract
// working-directory clause requires. The calling test creates it and
// removes it in its own deferred cleanup. A relative path is resolved
// against the runner's own working directory by os/exec, which defeats
// the point, so pass an absolute one.
//
// Empty means the driver inherits the runner's working directory,
// which the clause forbids. Every driver-invoking test should set it.
// Dir alone does not confine a driver that resolves its own root by
// walking up from the working directory; see the S04 §Invocation
// contract working-directory bullet.
Dir string
// Stdin is fed to the driver's stdin. nil = /dev/null.
Stdin io.Reader
// ExtraEnv is appended to the env-var allow-list (see S04
// §Invocation contract). Use for per-test secrets that must be
// passed through (e.g. an npm auth token written to a tmp
// .npmrc by the test). A value whose key matches a recognized
// secret-name pattern (password, token, secret, api_key,
// authorization; case-insensitive) is scrubbed from the captured
// streams the executor records in CLIDetail; a value under any
// other key is NOT scrubbed, so callers must not place a secret
// under an unrecognized key.
ExtraEnv []string
}
RunOpts is the per-invocation override surface for CLIExecutor.Run per S04 §1161-1171. All fields are optional; the zero value is the documented default.
type SeedCallback ¶ added in v1.66.0
type SeedCallback func(context.Context) (SeedResult, error)
SeedCallback is one leg of a seeding attempt: the format's write, or its read-back against the upstream. Both are per-format HTTP client operations and never a CLI driver (S08 §Preflight).
The returned SeedResult is transport-neutral rather than *http.Response-shaped: no exported method in pkg/client/{maven,npm,oci} returns an *http.Response, pkg/conformance may not import those packages (docs/dev/architecture.md), and npm.Publish returns a bare error that discards the status. A non-nil error means the leg failed; the SeedResult still carries whatever the format observed, including Status == 0 for a failure that never got a response.
type SeedError ¶ added in v1.66.0
type SeedError struct {
// RunAttributable is true for the run-attributable row of
// §Preflight's cause table and for a transient failure that
// survived its one re-attempt; false for the row-attributable
// residue.
RunAttributable bool
// Result is the response the classification was drawn from: the
// refused write's on the row-attributable and run-attributable
// rows, and the second attempt's on a transient failure that
// exhausted its re-attempt.
Result SeedResult
// contains filtered or unexported fields
}
SeedError is a classified seeding failure. RunAttributable is what NewSeedFailureCase keys TestCase.SetupFailure on, so a run-attributable or transient-exhausted failure ends the run with exit 2 while a row-attributable refusal is only that row's skip (S08 §Preflight, AC #15, AC #33).
It carries a whole SeedResult so the detail can be lifted into an HTTPDetail, which needs four of its fields. Result.Body is already scrubbed when the helper returns it.
func (*SeedError) Error ¶ added in v1.66.0
Error implements error so a *SeedError can ride TestCase.SetupFailure.
A *SeedError a caller assembled itself carries no classified message, so the status the classification was drawn from is the fallback: an empty error string would reach the exit-2 stderr line as a blank.
type SeedResult ¶ added in v1.66.0
type SeedResult struct {
// Status is the terminal request's HTTP status. Zero means no
// status arrived, exactly as HTTPError.StatusCode already
// documents; the cause sort reads it for every failure and never
// as a success signal.
Status int
// Stored is the write callback's "means stored" verdict: the
// format's own status rule on the terminal request. The shared
// helper holds no 2xx range check and no 202 case of its own, so a
// terminal 202 a callback reports not-stored is reissued
// (S08 §Preflight).
Stored bool
// DuplicateRefusal is the write callback's second verdict: this
// status is this format's refusal of an already-published
// coordinate. The set is 409 for Maven, 409 or 403 for npm, and
// empty for OCI, whose push is idempotent, so the helper must
// never classify a duplicate from a status literal.
DuplicateRefusal bool
// Preexisting reports that the write's per-artifact existence
// check found an artifact already at the coordinate rather than
// writing it. It is what keeps AC #37's comparison reachable: with
// the existence check in place a landed first write draws no 409
// on the re-attempt, so a 409-keyed content check would never run.
Preexisting bool
// Method is the terminal request's verb. The sort compares it
// against SeedSpec.WriteVerb, because a followed 301, 302 or 303
// is replayed as a GET with the body dropped (S04 §HTTP client
// policy) and its 200 would otherwise satisfy npm's and Maven's
// status rule for a coordinate this run never wrote. An empty
// Method reads as a method switch: no format is exempt from
// filling it.
Method string
// URL is the terminal request's URL, lifted into HTTPDetail by
// NewSeedFailureCase.
URL string
// Body is the served bytes on a read-back's success path, and the
// error body otherwise. SeedAndSettle scrubs it with
// redact.RedactURLUserinfo(redact.ScanContent(...)) and then bounds
// it at detailBodyCap before it reaches a SeedError, because the
// surfaces the detail lands on are not failure_detail fields and
// nothing downstream re-truncates (S08 AC #24, §Preflight; S04
// AC #33). Neither bound applies to the Body returned on the
// success path, which is the served fixture the caller compares.
Body []byte
}
SeedResult is what a format's write or read-back observed, filled by the format from its own typed *HTTPError (plan §Naming Conventions).
type SeedSpec ¶ added in v1.66.0
type SeedSpec struct {
// Write issues every artifact this row seeds, in one call, against
// the upstream. It reports the completion request per artifact,
// surfaces the first artifact its format's verdict calls
// not-stored, and must be idempotent per artifact and
// content-deterministic: it checks existence before writing and
// reports through SeedResult.Preexisting whether any artifact was
// found rather than written.
Write SeedCallback
// ReadBack polls the upstream, not the repository under test, and
// returns the served bytes on success. Establishing readability on
// the upstream before the row reads through the proxy is the whole
// point of the poll (S08 §Seeding and asynchronous upstreams).
ReadBack SeedCallback
// Fixture is this run's expected bytes, a pure function of (run ID,
// slug) per S08 §Fixture seeding model. AC #37 compares a resumed
// settle's read-back against it.
Fixture []byte
// WriteVerb is the format's write method, which the cause sort
// compares SeedResult.Method against. No callback verdict can
// supply it, and a verb is not a status, so it keeps the
// no-format-status-literal rule intact.
WriteVerb string
// SettleTimeout is the resolved cfg.SettleTimeout, passed
// explicitly because it is not derivable from ctx, whose deadline
// is the root 2n x d + 5m rather than the per-settle cap. Zero
// means exactly one read-back and no polling loop, which is
// AC #14's carve-out; the read-back is never skipped.
SettleTimeout time.Duration
}
SeedSpec is one row's whole seeding contract. Every member is the row's to fill; the helper supplies none of them.
type Status ¶
type Status string
Status is the outcome of a TestCase per S04 §532-538.
const ( // StatusPass marks a TestCase whose assertion held. StatusPass Status = "pass" // StatusFail marks a TestCase whose assertion failed, or that // surfaced a transport or panic outcome the runner converted into // a failure per the spec's failure-prefix conventions. StatusFail Status = "fail" // StatusSkip marks a TestCase the test author chose not to run // (driver unavailable, environment missing, etc.). StatusSkip Status = "skip" )
type TestCase ¶
type TestCase struct {
// Name is the canonical test identifier. Set by the test author at
// construction time (Pass(name), Fail(name, message), etc.); the
// runner preserves it on output.
Name string
// Status is the outcome.
Status Status
// Message is the human-readable diagnostic. Empty for pass;
// carries the skip reason for StatusSkip; carries the
// panic/failure message for StatusFail.
Message string
// StartedAt is the wall-clock UTC start timestamp; set by the
// runner, not by test authors (S04 AC #54).
StartedAt time.Time
// Duration is the wall-clock duration the test ran. Zero means
// not measured.
Duration time.Duration
// Detail is the optional failure context. Nil for pass, and for
// every skip but the seeding-refusal one, which carries the
// refused write's own response for library consumers (S04
// §TestDescriptor, TestCase, Status, Detail; S08 AC #15).
// SkipWithDetail is the only constructor that populates it on a
// non-failing case.
Detail *Detail
// SetupFailure is non-nil when the row could not establish the
// run's fixture source, as opposed to failing an assertion about
// the registry under test (S04 §TestDescriptor, TestCase, Status,
// Detail). The runner reads it after runOne and stops the loop,
// carrying it into Report.Interrupted and the returned error, so
// S04 §Exit codes maps it to 2 rather than 1.
//
// It is a field and not a Status value because the enum is
// switched exhaustively by renderers and by external consumers; a
// new value would break them, an ignored field does not. Being
// additive, it never replaces Status: a row that sets it still
// reports a canonical Status, StatusSkip for a seeding failure,
// because every Status consumer panics on a non-canonical value.
//
// Nothing populates this field yet. The only sanctioned producer is
// the shared seed-and-settle helper landing as pkg/conformance/seed.go
// (plan Step 5a), which MUST scrub the detail before it populates
// this field, with redact.RedactURLUserinfo(redact.ScanContent(...)):
// the surfaces it reaches are not failure_detail fields and so are
// outside S04 AC #74's render-boundary scan, and ScanContent alone
// would miss a body echoing scheme://user:pass@host. Naming the
// helper and not "whoever populates it" is what makes the rule hold,
// since this is a plain error on an exported struct.
//
// Until that helper lands, an Fn that sets this field must scrub it
// itself, because no layer downstream will. The three surfaces the
// value reaches all apply strictly less than the failure_detail path:
// internal/report's stdout "Interrupted:" line and JUnit <error
// message> apply RedactURLUserinfo alone (redactMessage), and the
// exit-2 stderr write applies stripControl and no redaction at all
// (S08 §Preflight). The keyword scan belongs to the producer, not to
// those boundaries, because it corrupts curated prose.
SetupFailure error
// contains filtered or unexported fields
}
TestCase is the result of executing one test per S04 §540-554.
func Fail ¶
Fail constructs a failing TestCase with no detail per S04 §599. Detail is nil; use FailWithHTTPDetail or FailWithCLIDetail for the shaped variants.
func FailWithCLIDetail ¶
FailWithCLIDetail constructs a failing TestCase with a CLI-only detail envelope per S04 §601 / §606-608. The mutually-exclusive shape is enforced by the signature: callers cannot supply an HTTP branch.
func FailWithDetail ¶
FailWithDetail constructs a failing TestCase with a caller-supplied detail envelope per S04 §602 / §606-613. Panics only when both HTTP and CLI branches are populated; the runner's runOne wrapper converts that panic into a failing TestCase. The envelope is stored as-given: an empty envelope (both branches nil) is preserved, not normalized to a nil Detail.
Detail aliasing: Detail is taken by value, but its HTTP and CLI fields are pointers. The returned TestCase's Detail.HTTP and Detail.CLI alias the same HTTPDetail/CLIDetail values the caller passed in, so a caller that mutates *d.HTTP after the call observes the mutation in the returned TestCase. This differs from FailWithHTTPDetail and FailWithCLIDetail, which take the inner struct by value and isolate it from caller mutations. Use the typed constructors for the isolation guarantee; reach for FailWithDetail only when both branches must remain nil or when the caller is shutting the value down at construction.
func FailWithHTTPDetail ¶
func FailWithHTTPDetail(name, message string, d HTTPDetail) TestCase
FailWithHTTPDetail constructs a failing TestCase with an HTTP-only detail envelope per S04 §600 / §606-608. The mutually-exclusive shape is enforced by the signature: callers cannot supply a CLI branch.
func NewSeedFailureCase ¶ added in v1.66.0
NewSeedFailureCase is the only way a row turns a *SeedError into a TestCase. It reports StatusSkip, AC #15's reason naming --upstream-url and the refusing status, the Detail through SkipWithDetail, and SetupFailure iff e.RunAttributable.
The mapping cannot be left to the ~20 row Fns: a row that forgets it demotes a revoked credential to a plain skip that neither AC #33 nor AC #36 can see, and the run then exits 0 having validated nothing.
The Detail is set on every classification, which is wider than AC #15's pin of the refused-write skip: the field is also the library consumer's channel on the run-ending classifications, and it costs nothing downstream, because internal/report's stdout and JUnit renderers read Detail only in their StatusFail branch.
Both scrub passes, and the detailBodyCap bound, run here as well as in SeedAndSettle. The passes are idempotent and the bound is monotonic, and this is the boundary a third-party row reaches with a *SeedError of its own making, so the two fields that reach an output channel, Message and Detail.HTTP, are defended here rather than on the strength of an upstream contract.
SetupFailure is deliberately e itself and not a defended copy: no renderer reads Result off it, because a third-party *SeedError has no classified message and Error() falls back to the status phrase, so the only reader is a library consumer doing errors.As on an error it built. Copying would also silently stop copying the day SeedError gains a field.
func Pass ¶
Pass constructs a passing TestCase per S04 §598. Message is empty and Detail is nil per S04 §540-554. StartedAt is left zero; runOne overlays the wall-clock UTC start timestamp (S04 §615-617).
func Skip ¶
Skip constructs a skipped TestCase per S04 §603. Message carries the skip reason (S04 §540-554); Detail is nil.
func SkipAfterSeeding ¶ added in v1.70.0
SkipAfterSeeding constructs a skipped TestCase for a row that got the run's fixture onto the upstream and then skipped for a reason of its own. S07 §Pluggable behavior calls that an arm: the target answered conformantly by not implementing an optional behavior, so there is nothing to assert and nothing to report against it.
Message carries the skip reason and Detail is nil, exactly as Skip leaves them. The one difference is invisible in the report: it records that the row seeded, which is the question S08 AC #36 asks after the last row.
A remote row that seeds and then skips must use this constructor, and a row that skips before it writes anything must use Skip. Getting it backwards costs a verdict error in one direction each: Skip on a post-seed arm exits 2 on a conformant target, and this constructor on a pre-seed gate exits 0 on a run that relayed nothing. Only rows carrying TestDescriptor.NeedsUpstream are read this way, so the choice is inert on a hosted row and either constructor is correct there.
One carve-out: a row that skips because the run was cancelled sits outside the rule and uses Skip, whatever it had written by then. Two reasons, and the second is what makes it safe rather than merely convenient. A cancelled seed may never have written at all, so the affirmative marker would be a claim the row cannot support. And the verdict never reads the case anyway: runDescriptors returns the context's error, RunModule carries that into runErr, and step 9's check runs only when runErr is nil, so a cancelled run reports the cancellation rather than this verdict. Marking such a row would therefore change nothing today and would state something false if the ordering ever moved. pkg/conformance/oci/remote_preflight.go's two ctx.Err() arms are the tree's only instances.
func SkipWithDetail ¶ added in v1.65.0
SkipWithDetail constructs a skipped TestCase carrying a caller-supplied detail envelope, the signature S04 §TestDescriptor, TestCase, Status, Detail pins in its constructor list. Message carries the skip reason; Detail is stored as-given, so an empty envelope (both branches nil) is preserved rather than normalized to a nil Detail, exactly as FailWithDetail preserves it.
It is the only constructor that puts a Detail on a non-failing TestCase. It exists for the seeding-refusal skip, whose Detail carries the refused write's own response for library consumers (S08 AC #15): Skip cannot set it and FailWithDetail is fail-only. Skip stays the constructor for every other skip, which has no detail to carry. No renderer changes, because internal/report's stdout and JUnit renderers read Detail only in their StatusFail branch.
It carries FailWithDetail's panic rule, since the envelope shape is the same: it panics when both d.HTTP and d.CLI are non-nil, and the runner's runOne wrapper converts that panic into a failing TestCase.
Detail aliasing matches FailWithDetail: Detail is taken by value but its HTTP and CLI fields are pointers, so the returned TestCase aliases the values the caller passed in.
type TestDescriptor ¶
type TestDescriptor struct {
// Name is the canonical test identifier per S04 §510-512 and the
// naming convention at S04 §1066-1079. Format:
// <format>.<category>.<slug> — lowercase, dot-separated, no
// spaces.
Name string
// Priority is the test's declared importance per S04 §513-517,
// taken verbatim from the priority column of the test case
// tables. The runner uses this for cfg.Priorities filtering;
// rendering of priority counts in summaries is the output
// layer's concern.
Priority Priority
// NeedsUpstream declares that the test cannot run without a
// fixture upstream, per S04 §TestDescriptor, TestCase, Status,
// Detail. False for every hosted row, so a descriptor literal
// that omits it keeps its current meaning.
//
// The runner reads it to skip the row when the Env carries no
// upstream (S08 §Upstream gate), and for AC #36's post-loop verdict,
// which asks it three questions: whether the selection holds a
// seeding row, whether the pre-narrowing catalog holds one, and
// whether any selected seeding row got the run's fixture onto the
// upstream. That verdict is the field's largest consequence, since it
// turns a remote run that established nothing into exit 2. The third
// question is about the seeding and not about the Status: a row that
// seeds and then skips on a pluggable arm established its fixture and
// must say so through SkipAfterSeeding, and a row that skips before
// it writes anything must use Skip.
//
// A further read lives outside this package: internal/cli counts the
// rows a run will settle against to size the derived --timeout (S08
// §Seeding and asynchronous upstreams), off SelectDescriptors rather
// than off the catalog; S08 §S04 amendments attributes it to
// internal/cli. Declaring the field here rather than deciding it
// inside Fn is what makes every one of them readable without
// executing anything.
NeedsUpstream bool
// Fn executes the test per S04 §518-520. Must not panic; the
// runner wraps each call in a recover. Must not write to stdout
// or stderr.
Fn func(ctx context.Context, env Env, runID string) TestCase
}
TestDescriptor declares one test per S04 §509-521. The runner invokes Fn under a panic-recovering wrapper (runOne); test authors MUST NOT panic from Fn directly and MUST NOT write to stdout or stderr.
func SelectDescriptors ¶ added in v1.65.0
func SelectDescriptors(m Module, cfg Config) ([]TestDescriptor, error)
SelectDescriptors returns the descriptors a run with cfg would execute, in execution order, after cfg.Filter and cfg.Priorities narrowing (S04 §Entry points).
It performs no I/O and calls no Fn. It reads cfg.Filter and cfg.Priorities directly for the narrowing, and forwards cfg whole to m.TestCatalog and m.NegativeAuthTests, so cfg.RepositoryKind affects the result through them rather than being read here.
It never validates its argument: internal/cli sizes a remote run's --timeout with a selection-only Config that Config.Validate would reject (S08 §Seeding and asynchronous upstreams), so a validation guard here would break every remote default.
It is m.TestCatalog followed by m.NegativeAuthTests, concatenated with positives first, then the same narrowing RunModule applies. Both go through selectFromCatalog rather than either repeating the logic, so this stays the one narrowing implementation. It exists so a caller that must size something against the executed set (internal/cli deriving a remote run's --timeout default) reads the same set the runner will, instead of reimplementing path.Match and the priority allow-list.
Errors are *FilterNoMatchError and *PriorityNoMatchError, the same values RunModule would return for the same cfg, plus the *ConfigError{Field: "filter"} filterByPattern raises on path.ErrBadPattern. RunModule never returns that third value: step 2's Config.Validate rejects the pattern first, with its own Reason ("must be a valid path.Match pattern" rather than path.ErrBadPattern's text) and before any Module method (S04 AC #40), while this function does not validate and reaches the narrowing after m.TestCatalog(cfg). S04 §Entry points states the same split.
type UpstreamEnv ¶ added in v1.65.0
type UpstreamEnv interface {
// HasUpstream reports whether a writable fixture upstream is
// available in this env.
HasUpstream() bool
}
UpstreamEnv is implemented by an Env whose Config carried an --upstream-url, per S08 §Upstream gate. It mirrors the CLIEnv / HasCLI shape S04 already uses for the same problem: an optional capability the runner discovers by type assertion rather than a method every Env must carry.
The runner type-asserts for it before executing a descriptor whose NeedsUpstream is true, and again after the descriptor loop for S08 AC #36's post-loop verdict. Both reads answer the run's upstream question from the Env alone and never from Config.UpstreamURL: a library caller may set the field and still hand RunModule an Env that does not implement this interface or answers false.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package cliexec provides the concrete Executor that implements the conformance.CLIExecutor contract: it resolves an external driver binary on PATH, pins the driver version at construction time, and invokes the driver through real exec.CommandContext with the fixed invocation contract from S04 §CLI drivers (closed env allow-list, RunOpts.Dir working directory, RunOpts.Stdin policy, argv prefixing with the resolved binary path, a SIGTERM→5s→SIGKILL grace window, 16 KiB capture caps with 4 KiB tail truncation, and argv/stream scrubbing of secret-bearing values).
|
Package cliexec provides the concrete Executor that implements the conformance.CLIExecutor contract: it resolves an external driver binary on PATH, pins the driver version at construction time, and invokes the driver through real exec.CommandContext with the fixed invocation contract from S04 §CLI drivers (closed env allow-list, RunOpts.Dir working directory, RunOpts.Stdin policy, argv prefixing with the resolved binary path, a SIGTERM→5s→SIGKILL grace window, 16 KiB capture caps with 4 KiB tail truncation, and argv/stream scrubbing of secret-bearing values). |
|
internal/echodriver
command
Command echodriver is a test fixture for pkg/conformance/cliexec.
|
Command echodriver is a test fixture for pkg/conformance/cliexec. |
|
internal
|
|
|
catalogparse
Package catalogparse parses a per-format catalog markdown document (the byte contents of one docs/catalog/<format>.md file) into the set of slug values whose Status is not "optional".
|
Package catalogparse parses a per-format catalog markdown document (the byte contents of one docs/catalog/<format>.md file) into the set of slug values whose Status is not "optional". |
|
inventorytest
Package inventorytest holds the catalog-inventory guard helpers shared by the maven, npm, and oci format packages.
|
Package inventorytest holds the catalog-inventory guard helpers shared by the maven, npm, and oci format packages. |
|
remotefake
Package remotefake is the caching-proxy test double the S08 remote rows are verified against: a format-agnostic pair of http.Handlers modelling an upstream repository (the origin) and a remote repository that proxies it (the remote).
|
Package remotefake is the caching-proxy test double the S08 remote rows are verified against: a format-agnostic pair of http.Handlers modelling an upstream repository (the origin) and a remote repository that proxies it (the remote). |
|
testfake
Package testfake provides shared test fixtures for the pkg/conformance test suite.
|
Package testfake provides shared test fixtures for the pkg/conformance test suite. |
|
Package maven provides the Maven format implementation of the conformance Module interface defined in S04 §Module interface (§432-464).
|
Package maven provides the Maven format implementation of the conformance Module interface defined in S04 §Module interface (§432-464). |
|
internal/fixture
Package fixture builds the Maven artifacts every release-publish test ships: a POM, a settings.xml, a synthetic JAR, and a maven-metadata.xml document for either metadata level.
|
Package fixture builds the Maven artifacts every release-publish test ships: a POM, a settings.xml, a synthetic JAR, and a maven-metadata.xml document for either metadata level. |
|
internal/mvnfake
command
Command mvnfake is a test fixture for pkg/conformance/maven's cliExec wrapper.
|
Command mvnfake is a test fixture for pkg/conformance/maven's cliExec wrapper. |
|
Package npm provides the npm format implementation of the conformance Module interface defined in S04 §Module interface (§432-464).
|
Package npm provides the npm format implementation of the conformance Module interface defined in S04 §Module interface (§432-464). |
|
internal/fixture
Package fixture holds internal, driver-only fixture builders for pkg/conformance/npm.
|
Package fixture holds internal, driver-only fixture builders for pkg/conformance/npm. |
|
Package oci provides the OCI format implementation of the conformance Module interface defined in S04 §Module interface (§432-464).
|
Package oci provides the OCI format implementation of the conformance Module interface defined in S04 §Module interface (§432-464). |
|
internal/cranefake
command
Command cranefake is a test fixture for pkg/conformance/oci's cliExec wrapper.
|
Command cranefake is a test fixture for pkg/conformance/oci's cliExec wrapper. |
|
internal/fixture
Package fixture builds the synthetic OCI artifacts every push test ships: a config blob, zero or more layer blobs (as gzipped tarballs), an optional subject descriptor, and an image manifest referencing them (S07 OCI plan §Research Findings / Manifest, config, and blob fixtures).
|
Package fixture builds the synthetic OCI artifacts every push test ships: a config blob, zero or more layer blobs (as gzipped tarballs), an optional subject descriptor, and an image manifest referencing them (S07 OCI plan §Research Findings / Manifest, config, and blob fixtures). |
|
Package redact implements the field-name, content-scan, and argv scrubbing primitives that enforce S04 §Security Considerations: secret-bearing values must be replaced with the literal sentinel "[REDACTED]" before any log entry, failure-detail field, or captured argv element can reach a consumer.
|
Package redact implements the field-name, content-scan, and argv scrubbing primitives that enforce S04 §Security Considerations: secret-bearing values must be replaced with the literal sentinel "[REDACTED]" before any log entry, failure-detail field, or captured argv element can reach a consumer. |