Documentation
¶
Overview ¶
Package gatewaytest is the test harness for the gateway: it builds the gateway, fixture and demo programs once per test binary, runs each test's gateway as its own process with a disposable deployment (database, security log, configuration file, listeners and upstream receivers), and gives tests clients for the data plane and the Admin API, readers for the security log and the database, and the policies the tests share.
It is test support only: no production package may import it, which the layer test enforces. Binary-driven tests in internal/integration and the in-process tests of internal/gateway both use it; TestMain in each calls Main.
Index ¶
- Constants
- Variables
- func Bearer(t *testing.T, subject string) []string
- func CatalogueRoles(c fixture.Catalogue) map[string]string
- func ChunkedBody(body string, size int) string
- func Count(t *testing.T, db *sql.DB, query string, args ...any) int
- func CountKind(events []map[string]any, kind string) int
- func DemoCommand(t *testing.T, args ...string) (string, int)
- func DemoTestAddress(t *testing.T, base string) string
- func Dialable(addr string) bool
- func EnrolmentSecret(t *testing.T, output string) string
- func ExpectedStages(passed []string, terminal, result string) map[string]any
- func FileSHA256(t *testing.T, path string) string
- func FindEvent(events []map[string]any, kind, requestID string) map[string]any
- func FixturePolicy(fixtures map[string]*FixtureProcess) policy.Policy
- func FreeAddr(t *testing.T) string
- func HasKinds(events []map[string]any, kinds ...string) bool
- func Inspect(t *testing.T, path string) *sql.DB
- func Interrupt(t *testing.T, cmd *exec.Cmd)
- func JSONBody(maxBytes int64, schema string) *policy.BodyRule
- func ListeningPorts(t *testing.T, pid int) []string
- func LoadCatalogue(t *testing.T) fixture.Catalogue
- func Main(m *testing.M, first, last int)
- func MustJSON(v any) json.RawMessage
- func OperationContainment(operation string, seconds int64) controller.OverrideRequest
- func ParseAudit(data []byte, file string) ([]map[string]any, error)
- func Port(addr string) string
- func Public(stages map[string]any) map[string]any
- func QueryInt(t *testing.T, path, query string, args ...any) int
- func QueryRows(t *testing.T, path, query string) []string
- func QueryString(t *testing.T, path, query string, args ...any) string
- func Rate(count, windowSeconds int64) *policy.RateRule
- func ReceiptCounts(fixtures map[string]*FixtureProcess) map[string]int
- func RequestID(resp *http.Response, body string) (int, string)
- func RevisionTag(revision int64) string
- func SameStages(got any, want map[string]any) bool
- func Section(settings map[string]any, name string) map[string]any
- func Seed(t *testing.T, path string, policy policy.Policy, opts SeedOptions)
- func SizeRefusal(framing string, size, global int) (string, string)
- func SizedBody(tag string, size int) string
- func StartFixtureSet(t *testing.T, binary string, extraEnv ...string) map[string]*FixtureProcess
- func StartFixtures(t *testing.T) map[string]*FixtureProcess
- func TestTrust(issuer, audience, file string) pipeline.TrustConfig
- func WSLDataAddress(t *testing.T, host string) string
- func WaitFor(t *testing.T, limit time.Time, what string, cond func() bool)
- func WithSubject(p policy.Policy, s issuertest.Subject) json.RawMessage
- type AdminSession
- type AuditLine
- type ConfigOptions
- type Env
- func (e *Env) Activate(s AdminSession, c store.CandidateRecord, seconds int64, ifMatch, key string) (int, controller.Outcome, string)
- func (e *Env) AdminOrigin() string
- func (e *Env) AdminRaw(method, path, body string) (int, string)
- func (e *Env) AdminSend(method, path, body string, header ...string) (int, string, http.Header)
- func (e *Env) As(s AdminSession, method, path, body string, header ...string) (int, string, http.Header)
- func (e *Env) AssertReceipts(a, b, c int)
- func (e *Env) AuditEvents() []map[string]any
- func (e *Env) CpaCandidate() policy.Policy
- func (e *Env) CreateOverride(s AdminSession, request any, ifMatch, key string) (int, controller.Outcome, string)
- func (e *Env) EventsWhen(done func([]map[string]any) bool) []map[string]any
- func (e *Env) Exchange(method, path, contentType, body string, header ...string) (*http.Response, string)
- func (e *Env) Get(path string, header ...string) (int, string)
- func (e *Env) HarnessCall(method, path, body string, header ...string) (int, string, http.Header)
- func (e *Env) Health() string
- func (e *Env) KeywordPolicy() policy.Policy
- func (e *Env) Launch(binary string, args []string, extraEnv ...string)
- func (e *Env) Login(name, password string) (AdminSession, int)
- func (e *Env) MustLogin(name, password string) AdminSession
- func (e *Env) MustOverride(s AdminSession, request controller.OverrideRequest, ifMatch, key string) controller.Outcome
- func (e *Env) NativeSettings() map[string]any
- func (e *Env) OpenResponse(request string) (*http.Response, net.Conn)
- func (e *Env) Policy(aTarget *Receiver, withB bool) policy.Policy
- func (e *Env) PolicyWithUpstream(dial string) policy.Policy
- func (e *Env) ProtectedPolicy() policy.Policy
- func (e *Env) ProvisionalFrom(s AdminSession, policy policy.Policy, parent, seconds int64, key string) (store.CandidateRecord, controller.Outcome)
- func (e *Env) Publish(change controller.Change) (controller.Outcome, int)
- func (e *Env) Raw(request string) (int, string)
- func (e *Env) RawExchange(request string, halfClose bool) (int, string)
- func (e *Env) RawResponse(request string) (*http.Response, string)
- func (e *Env) Request(method, path, contentType, body string, header ...string) (int, string)
- func (e *Env) RequestEvents(requestID string, want int) []map[string]any
- func (e *Env) ResetReceivers()
- func (e *Env) Resolve(s AdminSession, action string, revision int64, ifMatch, key string) (int, controller.Outcome, string)
- func (e *Env) Run(binary string, extraEnv ...string)
- func (e *Env) RunOperator(binary string, extraEnv []string, command string, args ...string) (string, int)
- func (e *Env) SendBody(framing, path, body string, header ...string) (int, string)
- func (e *Env) Stage(s AdminSession, policy any, ifMatch, key string) (int, StagedCandidate, string)
- func (e *Env) Start(binary string, extraEnv ...string)
- func (e *Env) Status() Status
- func (e *Env) Stop()
- func (e *Env) UnavailableReason() string
- func (e *Env) WaitExit() int
- func (e *Env) WaitOutput(text string)
- func (e *Env) WriteConfig(opts ConfigOptions)
- func (e *Env) WriteNative(settings map[string]any)
- func (e *Env) WriteNativeFile(content []byte)
- type FixtureProcess
- type LogBuffer
- type Receipt
- type Receiver
- type SeedOptions
- type StagedCandidate
- type Status
- type StepResult
Constants ¶
const ( OrdersCreateSchema = `{"type":"object","additionalProperties":false,"required":["customer","item","quantity"],"properties":{` + `"customer":{"type":"string","minLength":1,"maxLength":64},` + `"item":{"type":"string","minLength":1,"maxLength":64},` + `"quantity":{"type":"integer"}}}` InventoryAdjustSchema = `{"type":"object","additionalProperties":false,"required":["delta"],"properties":{` + `"delta":{"type":"integer","minimum":-100,"maximum":100}}}` )
Body schemas of the fixture writes. They state the request shape the fixtures accept; business rules such as known items, ownership and the quantity range stay with the fixtures.
const ( ExitStopped = 0 // stopped gracefully and completely ExitFailed = 1 // could not start, or the data plane failed ExitForced = 2 // a second signal ended the graceful stop ExitIncomplete = 3 // the graceful stop did not complete ConfigVersion = 1 )
The gateway process's exit codes and the configuration file version it reads: the command-line contract the harness checks the binary against.
const ( AdminCookie = "__Host-gateway-admin" AdminCSRF = "X-CSRF-Token" NameLimit = 5 // failed sign-ins per name before it is throttled WindowLimit = 50 // failed sign-ins per window before all are throttled HistoryKinds = 16 // kinds one history filter may name // PasswordPrefix starts every stored password: argon2id, 19 MiB, 2 passes, // 1 thread. PasswordPrefix = "$argon2id$v=19$m=19456,t=2,p=1$" )
const AnyObject = `{"type":"object","additionalProperties":true}`
AnyObject is a body schema that accepts any JSON object.
const HarnessAdmin = "harness"
The harness administrator holds every permission. Its password exists only in this test process.
Variables ¶
var Binaries struct { Plain, Fault, Fixture, FixtureFault, Demo, Services, Accounts string // contains filtered or unexported fields }
Integration tests run the real gateway binary as a separate process, so a crash can be injected by terminating it and the database is exercised across real restarts. The binaries include: the gateway and the fixture APIs, each also with fault-injection points compiled in, and the demo tool.
var HarnessHash = sync.OnceValue(func() string { salt := make([]byte, 16) rand.Read(salt) key := argon2.IDKey([]byte(HarnessPassword), salt, 2, 19*1024, 1, 32) return PasswordPrefix + base64.RawStdEncoding.EncodeToString(salt) + "$" + base64.RawStdEncoding.EncodeToString(key) })
HarnessHash is HarnessPassword stored as the Admin API stores a password.
var HarnessPassword = "harness-" + session.NewToken()
HarnessPassword is the harness administrator's password, random per run.
var Issuer = issuertest.New(2048)
Issuer signs the tokens of every test. Its public key is the trust anchor of every test gateway unless a test configures another.
Functions ¶
func CatalogueRoles ¶
CatalogueRoles gives each catalogue subject's roles in the form the gateway forwards them: sorted and comma-separated.
func ChunkedBody ¶
ChunkedBody encodes body in chunks of at most size bytes, followed by the last chunk.
func DemoCommand ¶
DemoCommand runs the demo program with args and returns its combined output and exit code; the output, which may hold credentials, is not logged.
func DemoTestAddress ¶
DemoTestAddress is a demo base address moved by EAT_PORT_OFFSET.
func EnrolmentSecret ¶
EnrolmentSecret extracts the secret from an install or enrol command's output line "enrolment secret for <name>...: <secret>".
func ExpectedStages ¶
ExpectedStages builds the full stage map for a request event: the listed stages passed, the terminal stage has the given result, and every other stage was not evaluated.
func FileSHA256 ¶
FileSHA256 is the hex SHA-256 of a file's content.
func FixturePolicy ¶
func FixturePolicy(fixtures map[string]*FixtureProcess) policy.Policy
FixturePolicy is the gateway policy for the three fixtures. It is written here by hand from the fixture contract, not generated from the catalogue, so a comparison between the two is meaningful.
func FreeAddr ¶
FreeAddr returns a loopback address that was free when checked, for a gateway to bind later. Ports come from the package's block of 20000-29999, below the ranges Linux (32768-60999) and Windows (49152-65535) give to outgoing connections, so a connection the tests open cannot take the port in the meantime. Test packages run at the same time, so each has its own block, and no port is returned twice.
func ListeningPorts ¶
ListeningPorts lists the TCP ports a process listens on, using ss from iproute2; a socket can show several owners, so the pid is matched exactly.
func LoadCatalogue ¶
LoadCatalogue reads the fixture operation catalogue.
func Main ¶
Main builds the binaries, runs the tests and removes the binaries. Each test package's TestMain calls it with its own block of test ports, first-last within 20000-29999, apart from every other package's block.
func MustJSON ¶
func MustJSON(v any) json.RawMessage
MustJSON encodes v, panicking if it cannot be encoded.
func OperationContainment ¶
func OperationContainment(operation string, seconds int64) controller.OverrideRequest
OperationContainment is a request to contain one operation for seconds.
func ParseAudit ¶
ParseAudit decodes the records of the audit file named file. The gateway may be appending while it is read, so an unterminated tail is a record still being written and is skipped. A record a crash cut short stays in the file, ended by the next start, which names its offset in an audit.recovered record; only such a line may fail to decode.
func Public ¶
Public marks the authentication and rate stages of a public operation as not applicable: it reads no token and cannot carry a rate rule.
func QueryInt ¶
QueryInt runs one query against a stopped gateway's database and closes it again, so the next gateway start can take its exclusive lock.
func QueryRows ¶
QueryRows runs one query against a stopped gateway's database and returns every result row in Go syntax, so rows compare exactly, NULL included.
func QueryString ¶
QueryString is QueryInt for a text result.
func ReceiptCounts ¶
func ReceiptCounts(fixtures map[string]*FixtureProcess) map[string]int
ReceiptCounts is the number of receipts each fixture holds.
func RequestID ¶
RequestID returns a data-plane response's status and the request_id its JSON body names, empty when the body names none.
func RevisionTag ¶
RevisionTag is the entity tag of a confirmed policy revision.
func SameStages ¶
SameStages reports whether two stage maps encode to the same JSON.
func Seed ¶
Seed creates a disposable database whose confirmed revision 1 is policy, with the harness administrator enrolled.
func SizeRefusal ¶
SizeRefusal returns the stage and reason expected when a body one byte over the effective ceiling is refused: a declared length above the global ceiling is refused at ingress, before any policy work; every other excess when the body is read.
func SizedBody ¶
SizedBody returns a JSON object of exactly size bytes whose only member starts with tag, so that concurrent bodies can be told apart.
func StartFixtureSet ¶
StartFixtureSet starts one process of binary per fixture, each with its own control secret, and stops them when the test ends.
func StartFixtures ¶
func StartFixtures(t *testing.T) map[string]*FixtureProcess
StartFixtures runs the three fixture APIs on loopback, each with its own control secret, and stops them when the test ends.
func TestTrust ¶
func TestTrust(issuer, audience, file string) pipeline.TrustConfig
TestTrust trusts one issuer and audience with the single key "test-a" read from file.
func WSLDataAddress ¶
The separate-network probe also isolates its port by the configured offset. Its optional host firewall rule must match this address and the test binary.
func WithSubject ¶
func WithSubject(p policy.Policy, s issuertest.Subject) json.RawMessage
WithSubject is the JSON document of p with s as its only subject.
Types ¶
type AdminSession ¶
type AdminSession struct {
Cookie, CSRF string
}
AdminSession is an administrator's session cookie value and CSRF token.
func (AdminSession) Headers ¶
func (s AdminSession) Headers(e *Env) []string
Headers are what a session request carries: the cookie, the CSRF token and the admin origin.
type AuditLine ¶
type AuditLine struct {
Kind string `json:"kind"`
RequestID string `json:"request_id"`
Seq uint64 `json:"seq"`
Lost uint64 `json:"lost"`
}
AuditLine is what the restart tests read of one audit record.
type ConfigOptions ¶
type ConfigOptions struct {
HeaderTimeout string // upstream response-header timeout; default 5s
MaxBodyBytes int64 // global request body ceiling; default 16384
JWT any // trust configuration; default the test issuer
Audit map[string]any // extra gateway audit settings
Admin map[string]any // extra gateway admin session settings
}
ConfigOptions are the settings WriteConfig varies; a zero field takes the default its comment names.
type Env ¶
type Env struct {
T *testing.T
Dir string
Database string
AuditLog string
PublicKey string // the issuer's verification key file
DataAddr string
Admin string
Metrics string
Config string // the gateway's configuration file
Process *exec.Cmd
Output *LogBuffer // the process's output, readable while it runs
A, B, C *Receiver
// interruptible starts the gateway in its own process group, so that
// interrupt can reach it without reaching the test process.
Interruptible bool
// contains filtered or unexported fields
}
Env is one disposable gateway deployment.
func NewEnv ¶
NewEnv makes a deployment in a temporary directory: free listener addresses, the issuer's key file, three receivers and a configuration file. The gateway is stopped when the test ends.
func (*Env) Activate ¶
func (e *Env) Activate(s AdminSession, c store.CandidateRecord, seconds int64, ifMatch, key string) (int, controller.Outcome, string)
Activate asks for a staged candidate to become the provisional base.
func (*Env) AdminOrigin ¶
AdminOrigin is the Origin a browser on the admin listener sends.
func (*Env) AdminSend ¶
AdminSend sends one request to the admin listener exactly as given: a non-empty body is sent as JSON, and header holds name/value pairs. A transport failure, such as a gateway that exited, returns status 0.
func (*Env) As ¶
func (e *Env) As(s AdminSession, method, path, body string, header ...string) (int, string, http.Header)
As sends a request with an administrator's session, origin and CSRF token.
func (*Env) AssertReceipts ¶
AssertReceipts checks every receiver, not only the intended one.
func (*Env) AuditEvents ¶
AuditEvents reads every record of the deployment's audit log.
func (*Env) CpaCandidate ¶
CpaCandidate differs from ProtectedPolicy(alice, bob) in three ways: bob (READER) loses GET /b/* and gains POST /a/item, and API a moves from upstream A to upstream C.
func (*Env) CreateOverride ¶
func (e *Env) CreateOverride(s AdminSession, request any, ifMatch, key string) (int, controller.Outcome, string)
CreateOverride asks for a temporary override; request may be an OverrideRequest or raw JSON.
func (*Env) EventsWhen ¶
EventsWhen waits until the audit log satisfies done. Events that do not gate a decision are written asynchronously, so they may land shortly after the response.
func (*Env) Exchange ¶
func (e *Env) Exchange(method, path, contentType, body string, header ...string) (*http.Response, string)
Exchange sends one request to the data plane and returns the response, whose body has been read into the returned string.
func (*Env) HarnessCall ¶
HarnessCall sends a request as the harness administrator, logging in when there is no session and once more if the session has ended (a restart ends every session). Authentication is checked before anything else, so a request refused with 401 was never processed and is safe to resend.
func (*Env) KeywordPolicy ¶
KeywordPolicy is the receiver test policy with a richer schema and header schema on POST /a/item, a header-only bodyless operation, and a large-body operation for decoder limits.
func (*Env) Launch ¶
Launch stops any running gateway and starts binary with args, clearing the fault-injection variables so only extraEnv can set them.
func (*Env) Login ¶
func (e *Env) Login(name, password string) (AdminSession, int)
Login starts a session and returns it with the response status.
func (*Env) MustLogin ¶
func (e *Env) MustLogin(name, password string) AdminSession
MustLogin is Login that fails the test unless a session is created.
func (*Env) MustOverride ¶
func (e *Env) MustOverride(s AdminSession, request controller.OverrideRequest, ifMatch, key string) controller.Outcome
MustOverride creates an override, failing the test unless it is created.
func (*Env) NativeSettings ¶
NativeSettings is the configuration of e's deployment, as the JSON object WriteNative writes. A test may change it first.
func (*Env) OpenResponse ¶
OpenResponse sends request byte for byte and reads the response head, leaving the body to the caller. The connection closes when the test ends.
func (*Env) Policy ¶
Policy builds the standard test policy: /a/* and POST /a/item go to the given upstream, /d is denied, and /b/* exists only when withB is set. Every operation is public, so routing behaviour is tested without tokens.
func (*Env) PolicyWithUpstream ¶
PolicyWithUpstream adds operation GET /z, served by its own upstream.
func (*Env) ProtectedPolicy ¶
ProtectedPolicy is the standard test policy with authentication required on /a/*, /a/item and /b/*: READER may read /a/* and /b/*, WRITER may read and write /a/*. GET /d stays a denied public operation.
func (*Env) ProvisionalFrom ¶
func (e *Env) ProvisionalFrom(s AdminSession, policy policy.Policy, parent, seconds int64, key string) (store.CandidateRecord, controller.Outcome)
ProvisionalFrom stages policy against the confirmed revision parent and activates it, failing the test unless both succeed.
func (*Env) Publish ¶
func (e *Env) Publish(change controller.Change) (controller.Outcome, int)
Publish sends a whole policy through the test publication hook, which exists only in the fault-injection build.
func (*Env) RawExchange ¶
RawExchange sends a request exactly as given and returns the status and body of the reply. With halfClose the client then closes its sending side, so a body shorter than its declared length ends early.
func (*Env) RawResponse ¶
RawResponse is raw returning the whole response, whose body has been read into the returned string.
func (*Env) RequestEvents ¶
RequestEvents waits for and returns the events of one request.
func (*Env) ResetReceivers ¶
func (e *Env) ResetReceivers()
ResetReceivers forgets every receipt of the three receivers.
func (*Env) Resolve ¶
func (e *Env) Resolve(s AdminSession, action string, revision int64, ifMatch, key string) (int, controller.Outcome, string)
Resolve confirms ("confirm") or rolls back ("rollback") a provisional revision.
func (*Env) Run ¶
Run launches the gateway's run command with e's configuration, without waiting for it to start.
func (*Env) RunOperator ¶
func (e *Env) RunOperator(binary string, extraEnv []string, command string, args ...string) (string, int)
RunOperator runs a local operator command of the gateway binary against this environment's configuration. It returns the combined output, which holds any enrolment secret and any refusal message, and the exit code.
func (*Env) SendBody ¶
SendBody posts a JSON body to path with the named framing and returns the status and reply. "declared" and "chunked" are HTTP/1.1 requests written byte for byte, the chunked body in chunks of at most 4096 bytes. header holds name/value pairs.
func (*Env) Stage ¶
func (e *Env) Stage(s AdminSession, policy any, ifMatch, key string) (int, StagedCandidate, string)
Stage submits a complete policy candidate as an administrator.
func (*Env) Start ¶
Start launches the gateway and waits until both listeners accept and it has reported its protected admission.
func (*Env) Status ¶
Status reads the status as the harness administrator; any answer but 200 fails the test.
func (*Env) Stop ¶
func (e *Env) Stop()
Stop terminates the gateway abruptly. The design must tolerate this at any point, so tests never rely on a graceful shutdown.
func (*Env) UnavailableReason ¶
UnavailableReason returns the reason of the last controller.unavailable event, for states in which no administrator can log in to read the status.
func (*Env) WaitOutput ¶
WaitOutput waits until the running gateway has written text.
func (*Env) WriteConfig ¶
func (e *Env) WriteConfig(opts ConfigOptions)
WriteConfig writes the gateway configuration file for opts, filling the defaults ConfigOptions names.
func (*Env) WriteNative ¶
WriteNative writes settings as e's configuration file.
func (*Env) WriteNativeFile ¶
WriteNativeFile writes content, exactly as given, as e's configuration file.
type FixtureProcess ¶
type FixtureProcess struct {
T *testing.T
Name string
Addr string // API listener, reached only through the gateway
Control string // receipts, state and reset; requires the secret
Secret string
// contains filtered or unexported fields
}
FixtureProcess is one fixture API running as its own process.
func (*FixtureProcess) Call ¶
func (f *FixtureProcess) Call(method, path, secret string) (int, []byte)
Call sends a request to the fixture's control listener, with secret as its bearer token when not empty, and returns the status and body.
func (*FixtureProcess) DecodeState ¶
func (f *FixtureProcess) DecodeState(code int, data []byte) fixture.State
DecodeState decodes a state reply, failing the test on any other answer.
func (*FixtureProcess) Receipts ¶
func (f *FixtureProcess) Receipts() []fixture.Receipt
Receipts reads every request the fixture has received.
func (*FixtureProcess) State ¶
func (f *FixtureProcess) State() fixture.State
State reads the fixture's current state.
type LogBuffer ¶
type LogBuffer struct {
// contains filtered or unexported fields
}
LogBuffer collects a controller's log output.
type Receipt ¶
type Receipt struct {
Method string
Target string // raw request-target as received
Path string // decoded path
Host string // Host as received
RequestID string
Generation string
Authorization bool
Headers http.Header
Body string
Trailer http.Header // request trailers, known once the body is read
}
Receipt is what an upstream actually received.
type Receiver ¶
type Receiver struct {
Name string
Addr string
Server *http.Server
Handle func(w http.ResponseWriter, r *http.Request) bool
// contains filtered or unexported fields
}
Receiver is an owned upstream that records every request it receives. handle, when set, may take over the response; it returns true if it did.
func NewReceiver ¶
NewReceiver starts a receiver on a free loopback port until the test ends.
type SeedOptions ¶
type SeedOptions struct {
Mode string
HighWater time.Time
Provisional *policy.Policy
Deadline time.Time
Version int // database schema version; default the current one
}
SeedOptions vary a seed: the mode and clock high-water mark, a provisional revision with its deadline, and the schema version.
type StagedCandidate ¶
type StagedCandidate struct {
Receipt controller.Outcome `json:"receipt"`
Candidate struct {
store.CandidateRecord
Active *bool `json:"active"`
} `json:"candidate"`
}
StagedCandidate is the reply to a candidate submission.
type Status ¶
type Status struct {
State string `json:"state"`
Admission string `json:"admission"`
AuditFailed bool `json:"audit_failed"`
Revision int64 `json:"revision"`
Generation string `json:"generation"`
JWTKey string `json:"jwt_key_sha256"`
Confirmed int64 `json:"confirmed"`
Provisional int64 `json:"provisional"`
Deadline time.Time `json:"deadline"`
NotAfter time.Time `json:"not_after"`
Overrides []int64 `json:"overrides"`
}
Status is the Admin API status read: the state, admission and the revisions and deadline in force.
type StepResult ¶
StepResult is what one catalogue step produced, as seen by the client, the fixture and the audit log.
func RunScenarios ¶
func RunScenarios(t *testing.T, e *Env, fixtures map[string]*FixtureProcess, c fixture.Catalogue) []StepResult
RunScenarios replays the catalogue sequence through the gateway, each step with a genuine token for its subject, and checks every step against the catalogue's expected fixture outcome, the fixture's own receipt and the gateway's event for the same request.