steps callers: the runner, the indexer, the operator and sessions (D-18); BLD12 builds in the fetch; BLD13 resolved and the toolchain digest; BLD14 the step key <asker>.<node>.<id> beside main's <node>.<id>; the events toolchain-reported and step-progress on the three build seats, and step-progress on mesh-wants. Builds: design 47 G §463, §480, §465, §466, §467, §481, §483, §492, §496 Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
121 lines
18 KiB
Go
121 lines
18 KiB
Go
// Code generated by seatgen from the seat definitions; DO NOT EDIT.
|
|
|
|
package nodebuildimage
|
|
|
|
import (
|
|
"encoding/json"
|
|
"reflect"
|
|
"regexp"
|
|
"testing"
|
|
)
|
|
|
|
// TestFixtures reads every fixture of seats/node-build-image/fixtures: each decodes into its type, a field the type does not
|
|
// know is dropped (ADR 0608 §6), and it reads back as its wire says; each subject named is the contract's.
|
|
func TestFixtures(t *testing.T) {
|
|
cases := []struct {
|
|
name, subject, given, wire string
|
|
decode func([]byte) (any, error)
|
|
subjectIs *regexp.Regexp
|
|
}{
|
|
{name: "a lint step ended passed on its node", subject: "mesh.seat.node-build-image.event.step-ended.ace", given: "{\"artifact\":\"nats:program\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"ended\":\"2026-11-10T10:02:00Z\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5e\",\"module\":\"nats\",\"node\":\"ace\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"started\":\"2026-11-10T10:00:00Z\",\"step\":\"lint\",\"v\":1}", wire: "{\"artifact\":\"nats:program\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"ended\":\"2026-11-10T10:02:00Z\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5e\",\"module\":\"nats\",\"node\":\"ace\",\"outcome\":\"passed\",\"pipeline\":\"main.12.nats\",\"started\":\"2026-11-10T10:00:00Z\",\"step\":\"lint\",\"v\":1}",
|
|
decode: func(b []byte) (any, error) { var v StepEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-image\\.event\\.step-ended\\.[^.*> ]+$")},
|
|
{name: "a lint step that could not run, naming the part not heard", subject: "mesh.seat.node-build-image.event.step-ended.g14", given: "{\"artifact\":\"nats:program\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5f\",\"module\":\"nats\",\"node\":\"g14\",\"outcome\":\"could not run\",\"output-object\":\"mesh-build-go_sent-objects/m2kx9a1b3c4d5f\",\"pipeline\":\"main.12.nats\",\"said\":\"the sandbox could not fetch novox/mesh-sdk\",\"step\":\"lint\",\"v\":1}", wire: "{\"artifact\":\"nats:program\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fingerprint\":\"fp-0123\",\"id\":\"m2kx9a1b3c4d5f\",\"module\":\"nats\",\"node\":\"g14\",\"outcome\":\"could not run\",\"output-object\":\"mesh-build-go_sent-objects/m2kx9a1b3c4d5f\",\"pipeline\":\"main.12.nats\",\"said\":\"the sandbox could not fetch novox/mesh-sdk\",\"step\":\"lint\",\"v\":1}",
|
|
decode: func(b []byte) (any, error) { var v StepEndedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-image\\.event\\.step-ended\\.[^.*> ]+$")},
|
|
{name: "a node's toolchain reported", subject: "mesh.seat.node-build-image.event.toolchain-reported.ace", given: "{\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"language\":\"go\",\"node\":\"ace\",\"recipe\":\"1\",\"version\":\"1.26.0\"}", wire: "{\"digest\":\"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\"language\":\"go\",\"node\":\"ace\",\"recipe\":\"1\",\"version\":\"1.26.0\"}",
|
|
decode: func(b []byte) (any, error) { var v ToolchainReportedEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-image\\.event\\.toolchain-reported\\.[^.*> ]+$")},
|
|
{name: "a running ask says its progress", subject: "mesh.seat.node-build-image.event.step-progress.ace", given: "{\"ask\":\"a1b2\",\"asker\":\"runner\",\"at\":\"2026-11-11T10:01:00Z\",\"phase\":\"fetch\"}", wire: "{\"ask\":\"a1b2\",\"asker\":\"runner\",\"at\":\"2026-11-11T10:01:00Z\",\"phase\":\"fetch\"}",
|
|
decode: func(b []byte) (any, error) { var v StepProgressEvent; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-image\\.event\\.step-progress\\.[^.*> ]+$")},
|
|
{name: "a running step", subject: "", given: "{\"id\":\"a1b2\",\"node\":\"ace\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}", wire: "{\"id\":\"a1b2\",\"node\":\"ace\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}",
|
|
decode: func(b []byte) (any, error) { var v StepsByNodeIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "a paused node", subject: "", given: "{\"at\":\"2026-11-05T10:00:00Z\",\"by\":\"operator@shanks\",\"paused\":true,\"v\":1}", wire: "{\"at\":\"2026-11-05T10:00:00Z\",\"by\":\"operator@shanks\",\"paused\":true,\"v\":1}",
|
|
decode: func(b []byte) (any, error) {
|
|
var v PausesByPausedNodeValue
|
|
err := json.Unmarshal(b, &v)
|
|
return v, err
|
|
}, subjectIs: nil},
|
|
{name: "a node's capacity", subject: "", given: "{\"configured\":2,\"effective\":2,\"v\":1,\"why\":\"the configured steps fit the cores\"}", wire: "{\"configured\":2,\"effective\":2,\"v\":1,\"why\":\"the configured steps fit the cores\"}",
|
|
decode: func(b []byte) (any, error) {
|
|
var v PausesByCapacityNodeValue
|
|
err := json.Unmarshal(b, &v)
|
|
return v, err
|
|
}, subjectIs: nil},
|
|
{name: "a node's toolchain", subject: "", given: "{\"language\":\"go\",\"recipe\":\"1\",\"v\":1,\"version\":\"1.26.0\"}", wire: "{\"language\":\"go\",\"recipe\":\"1\",\"v\":1,\"version\":\"1.26.0\"}",
|
|
decode: func(b []byte) (any, error) {
|
|
var v ToolchainsByNodeLanguageValue
|
|
err := json.Unmarshal(b, &v)
|
|
return v, err
|
|
}, subjectIs: nil},
|
|
{name: "a build ask", subject: "mesh.seat.node-build-image.accept.delivery", given: "{\"asker\":\"mesh-delivery-builder\",\"build\":{\"artifacts\":[{\"artifact\":\"go\"}],\"module\":\"nats\"},\"id\":\"a1b2\",\"kind\":\"build\",\"language\":\"go\"}", wire: "{\"asker\":\"mesh-delivery-builder\",\"build\":{\"artifacts\":[{\"artifact\":\"go\"}],\"module\":\"nats\"},\"id\":\"a1b2\",\"kind\":\"build\",\"language\":\"go\"}",
|
|
decode: func(b []byte) (any, error) { var v DeliveryAccept; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-image\\.accept\\.delivery$")},
|
|
{name: "a step ended on a transport fault, given again by the bus", subject: "", given: "{\"again-at\":\"2026-11-05T10:01:30Z\",\"ended\":\"2026-11-05T10:00:30Z\",\"id\":\"a1b2\",\"node\":\"ace\",\"passing\":true,\"reason\":\"fetching the commit: kex_exchange_identification: read: Connection reset by peer\",\"run\":1,\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"again\",\"tool\":\"build\",\"v\":1}", wire: "{\"again-at\":\"2026-11-05T10:01:30Z\",\"ended\":\"2026-11-05T10:00:30Z\",\"id\":\"a1b2\",\"node\":\"ace\",\"passing\":true,\"reason\":\"fetching the commit: kex_exchange_identification: read: Connection reset by peer\",\"run\":1,\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"again\",\"tool\":\"build\",\"v\":1}",
|
|
decode: func(b []byte) (any, error) { var v StepsByNodeIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "an ask dropped by the caller that no longer waits", subject: "", given: "{\"at\":\"2026-11-05T10:00:00Z\",\"by\":\"mesh-delivery-builder\",\"v\":1,\"why\":\"a newer fingerprint supersedes it\"}", wire: "{\"at\":\"2026-11-05T10:00:00Z\",\"by\":\"mesh-delivery-builder\",\"v\":1,\"why\":\"a newer fingerprint supersedes it\"}",
|
|
decode: func(b []byte) (any, error) { var v PausesByDroppedIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "a lint step ask of the runner with the names", subject: "mesh.seat.node-build-image.accept.check.step", given: "{\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:00:00Z\",\"id\":\"m2kx9a1b3c4d5e\",\"kind\":\"step\",\"language\":\"image\",\"step\":{\"artifact\":\"nats:program\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fetch\":{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"repository\":\"novox/mesh-catalog\"},\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"names\":{\"branches\":[\"main\"],\"modules\":[\"nats\",\"mesh-sdk\"],\"repositories\":[\"novox/mesh-catalog\",\"novox/mesh-sdk\"]},\"pipeline\":\"main.12.nats\",\"revision\":12,\"step\":\"lint\"},\"v\":1}", wire: "{\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:00:00Z\",\"id\":\"m2kx9a1b3c4d5e\",\"kind\":\"step\",\"language\":\"image\",\"step\":{\"artifact\":\"nats:program\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fetch\":{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"repository\":\"novox/mesh-catalog\"},\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"names\":{\"branches\":[\"main\"],\"modules\":[\"nats\",\"mesh-sdk\"],\"repositories\":[\"novox/mesh-catalog\",\"novox/mesh-sdk\"]},\"pipeline\":\"main.12.nats\",\"revision\":12,\"step\":\"lint\"},\"v\":1}",
|
|
decode: func(b []byte) (any, error) { var v CheckStepAccept; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-image\\.accept\\.check\\.step$")},
|
|
{name: "a recovery's step ask of the runner, on the stream delivery", subject: "mesh.seat.node-build-image.accept.delivery.step", given: "{\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:00:00Z\",\"id\":\"m2kx9a1b3c4d5e\",\"kind\":\"step\",\"language\":\"image\",\"step\":{\"artifact\":\"nats:program\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fetch\":{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"repository\":\"novox/mesh-catalog\"},\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"names\":{\"branches\":[\"main\"],\"modules\":[\"nats\",\"mesh-sdk\"],\"repositories\":[\"novox/mesh-catalog\",\"novox/mesh-sdk\"]},\"pipeline\":\"main.12.nats\",\"revision\":12,\"step\":\"lint\"},\"v\":1}", wire: "{\"asker\":\"mesh-delivery-pipeline\",\"at\":\"2026-11-10T10:00:00Z\",\"id\":\"m2kx9a1b3c4d5e\",\"kind\":\"step\",\"language\":\"image\",\"step\":{\"artifact\":\"nats:program\",\"branch\":\"main\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"fetch\":{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"repository\":\"novox/mesh-catalog\"},\"fingerprint\":\"fp-0123\",\"module\":\"nats\",\"names\":{\"branches\":[\"main\"],\"modules\":[\"nats\",\"mesh-sdk\"],\"repositories\":[\"novox/mesh-catalog\",\"novox/mesh-sdk\"]},\"pipeline\":\"main.12.nats\",\"revision\":12,\"step\":\"lint\"},\"v\":1}",
|
|
decode: func(b []byte) (any, error) { var v DeliveryStepAccept; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-image\\.accept\\.delivery\\.step$")},
|
|
{name: "an artifact's detected steps", subject: "", given: "{\"at\":\"2026-11-10T10:00:00Z\",\"fingerprint\":\"fp-0123\",\"steps\":[{\"step\":\"lint\"},{\"packages\":[\"./modules/nats/a\"],\"step\":\"unit\"}],\"v\":1}", wire: "{\"at\":\"2026-11-10T10:00:00Z\",\"fingerprint\":\"fp-0123\",\"steps\":[{\"step\":\"lint\"},{\"packages\":[\"./modules/nats/a\"],\"step\":\"unit\"}],\"v\":1}",
|
|
decode: func(b []byte) (any, error) {
|
|
var v DetectedStepsByModuleArtifactValue
|
|
err := json.Unmarshal(b, &v)
|
|
return v, err
|
|
}, subjectIs: nil},
|
|
{name: "a step keyed under its asker", subject: "", given: "{\"id\":\"a1b2\",\"node\":\"ace\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}", wire: "{\"id\":\"a1b2\",\"node\":\"ace\",\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"running\",\"tool\":\"build\",\"v\":1}",
|
|
decode: func(b []byte) (any, error) {
|
|
var v StepsByAskerNodeIDValue
|
|
err := json.Unmarshal(b, &v)
|
|
return v, err
|
|
}, subjectIs: nil},
|
|
{name: "drop names the ask and why", subject: "", given: "{\"by\":\"mesh-delivery-builder\",\"id\":\"a1b2\",\"why\":\"a newer fingerprint supersedes it\"}", wire: "{\"by\":\"mesh-delivery-builder\",\"id\":\"a1b2\",\"why\":\"a newer fingerprint supersedes it\"}",
|
|
decode: func(b []byte) (any, error) { var v DropInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "kept-artifact asks", subject: "", given: "{\"digest\":\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\",\"fp\":\"src2:1480985e\",\"module\":\"artifact-store\"}", wire: "{\"digest\":\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\",\"fp\":\"src2:1480985e\",\"module\":\"artifact-store\"}",
|
|
decode: func(b []byte) (any, error) { var v KeptArtifactInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "kept-artifact answers where the bytes are", subject: "", given: "{\"digest\":\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\",\"fp\":\"src2:1480985e\",\"module\":\"artifact-store\",\"object\":\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\",\"size\":18874368,\"store\":\"mesh-build-go-kept\"}", wire: "{\"digest\":\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\",\"fp\":\"src2:1480985e\",\"module\":\"artifact-store\",\"object\":\"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd\",\"size\":18874368,\"store\":\"mesh-build-go-kept\"}",
|
|
decode: func(b []byte) (any, error) { var v KeptArtifactAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "kept-artifact refuses a module that is claims no oci-artifact-registry", subject: "", given: "{\"fp\":\"src2:aaaaaaaa\",\"module\":\"mesh-delivery-gate\",\"refused\":\"claims no oci-artifact-registry\",\"words\":\"mesh-delivery-gate claims no oci-artifact-registry: its build is fetched from the store\"}", wire: "{\"fp\":\"src2:aaaaaaaa\",\"module\":\"mesh-delivery-gate\",\"refused\":\"claims no oci-artifact-registry\",\"words\":\"mesh-delivery-gate claims no oci-artifact-registry: its build is fetched from the store\"}",
|
|
decode: func(b []byte) (any, error) { var v KeptArtifactAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "kept-artifact refuses a build it no longer keeps", subject: "", given: "{\"fp\":\"src2:1480985e\",\"module\":\"artifact-store\",\"refused\":\"not kept\",\"words\":\"this node keeps no build of artifact-store at src2:1480985e\"}", wire: "{\"fp\":\"src2:1480985e\",\"module\":\"artifact-store\",\"refused\":\"not kept\",\"words\":\"this node keeps no build of artifact-store at src2:1480985e\"}",
|
|
decode: func(b []byte) (any, error) { var v KeptArtifactAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "kept-artifact refuses a build kept under another digest", subject: "", given: "{\"digest\":\"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\",\"fp\":\"src2:1480985e\",\"module\":\"artifact-store\",\"refused\":\"digest differs\",\"words\":\"artifact-store at src2:1480985e is kept as eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\"}", wire: "{\"digest\":\"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\",\"fp\":\"src2:1480985e\",\"module\":\"artifact-store\",\"refused\":\"digest differs\",\"words\":\"artifact-store at src2:1480985e is kept as eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\"}",
|
|
decode: func(b []byte) (any, error) { var v KeptArtifactAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "kept-artifact answers an error, never none", subject: "", given: "{\"error\":\"the kept builds could not be read\",\"fp\":\"src2:1480985e\",\"module\":\"artifact-store\"}", wire: "{\"error\":\"the kept builds could not be read\",\"fp\":\"src2:1480985e\",\"module\":\"artifact-store\"}",
|
|
decode: func(b []byte) (any, error) { var v KeptArtifactAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "steps asks an artifact's pipeline steps at a commit", subject: "", given: "{\"artifact\":\"nats:program\",\"fetch\":{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"repository\":\"novox/mesh-catalog\"},\"fingerprint\":\"fp-0123\",\"module\":\"nats\"}", wire: "{\"artifact\":\"nats:program\",\"fetch\":{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"repository\":\"novox/mesh-catalog\"},\"fingerprint\":\"fp-0123\",\"module\":\"nats\"}",
|
|
decode: func(b []byte) (any, error) { var v StepsInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "steps answers lint and unit tests", subject: "", given: "{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"steps\":[{\"step\":\"lint\"},{\"packages\":[\"./modules/nats\"],\"step\":\"unit\"}]}", wire: "{\"artifact\":\"nats:program\",\"fingerprint\":\"fp-0123\",\"steps\":[{\"step\":\"lint\"},{\"packages\":[\"./modules/nats\"],\"step\":\"unit\"}]}",
|
|
decode: func(b []byte) (any, error) { var v StepsAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "steps drops an artifact's kept steps with a reason", subject: "", given: "{\"artifact\":\"nats.program\",\"drop\":true,\"module\":\"nats\",\"why\":\"the detection was wrong\"}", wire: "{\"artifact\":\"nats.program\",\"drop\":true,\"module\":\"nats\",\"why\":\"the detection was wrong\"}",
|
|
decode: func(b []byte) (any, error) { var v StepsInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "steps answers a drop with the artifact", subject: "", given: "{\"dropped\":\"nats.program\"}", wire: "{\"dropped\":\"nats.program\"}",
|
|
decode: func(b []byte) (any, error) { var v StepsAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
{name: "steps answers a drop that the hand-act log refused", subject: "", given: "{\"error\":\"the hand-act log refused: nothing was deleted\"}", wire: "{\"error\":\"the hand-act log refused: nothing was deleted\"}",
|
|
decode: func(b []byte) (any, error) { var v StepsAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
|
}
|
|
for _, c := range cases {
|
|
v, err := c.decode([]byte(c.given))
|
|
if err != nil {
|
|
t.Errorf("%s: does not decode: %v", c.name, err)
|
|
continue
|
|
}
|
|
back, err := json.Marshal(v)
|
|
if err != nil {
|
|
t.Errorf("%s: does not encode: %v", c.name, err)
|
|
continue
|
|
}
|
|
var got, want any
|
|
if err := json.Unmarshal(back, &got); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := json.Unmarshal([]byte(c.wire), &want); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Errorf("%s: reads back as %s, want %s", c.name, back, c.wire)
|
|
}
|
|
if c.subjectIs != nil && !c.subjectIs.MatchString(c.subject) {
|
|
t.Errorf("%s: subject %q is not the contract's %s", c.name, c.subject, c.subjectIs)
|
|
}
|
|
}
|
|
}
|