148 lines
5.3 KiB
Go
148 lines
5.3 KiB
Go
package delivery
|
|
|
|
import (
|
|
"errors"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
const askCommit = "0123456789abcdef0123456789abcdef01234567"
|
|
|
|
func buildAsk() StepAsk {
|
|
return StepAsk{ID: "mh3k2x9qa1b2c3", Kind: AskDelivery, Language: AskGo, Asker: "mesh-delivery-builder",
|
|
At: time.Date(2026, 10, 23, 13, 0, 0, 0, time.UTC),
|
|
Build: &BuildJob{Module: "mesh-delivery-view", Path: "modules/mesh-delivery-view", FP: "ab12",
|
|
Fetch: map[string]any{"repository": "novox/mesh-delivery", "commit": askCommit, "dir": "modules/mesh-delivery-view", "paths": []any{"cmd"}},
|
|
Artifacts: []AskArtifact{{Artifact: "bundle"}, {Artifact: "base", From: "registry/x@sha256:00"}},
|
|
Publish: true, Toolchain: &ToolchainUsed{Version: "go1.26.0", Recipe: "3"}}}
|
|
}
|
|
|
|
func checkAsk() StepAsk {
|
|
return StepAsk{ID: "mh3k2x9qa1b2c4", Kind: AskCheck, Language: AskNode, Asker: "mesh-delivery-checker",
|
|
At: time.Date(2026, 10, 23, 13, 0, 0, 0, time.UTC),
|
|
Check: &CheckJob{Fetch: map[string]any{"repository": "novox/mesh-catalog", "commit": askCommit, "ref": "refs/pull/3/head", "base": askCommit},
|
|
Level: LevelUnit, Kept: true, Runner: "workspace", RunnerWhen: "modules/mesh-build-go/", Run: ""}}
|
|
}
|
|
|
|
// 1887/A1a: an ask encodes and decodes with every field.
|
|
func TestAskRoundTrips(t *testing.T) {
|
|
for _, a := range []StepAsk{buildAsk(), checkAsk()} {
|
|
raw, err := EncodeStepAsk(a)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
got, err := DecodeStepAsk(raw)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
a.V = StepAskVersion
|
|
if !reflect.DeepEqual(got, a) {
|
|
t.Fatalf("round trip:\n got %+v\nwant %+v", got, a)
|
|
}
|
|
}
|
|
}
|
|
|
|
// 1887/A1a: an ask with an unknown kind or language is refused.
|
|
func TestAskRefusesUnknownKindAndLanguage(t *testing.T) {
|
|
cases := map[string]func(*StepAsk){
|
|
"kind": func(a *StepAsk) { a.Kind = "build" },
|
|
"language": func(a *StepAsk) { a.Language = "typescript" },
|
|
"id": func(a *StepAsk) { a.ID = "postgres" },
|
|
"neither": func(a *StepAsk) { a.Build = nil },
|
|
"both": func(a *StepAsk) { a.Check = &CheckJob{Level: LevelUnit, Fetch: a.Build.Fetch} },
|
|
"recheck": func(a *StepAsk) { a.Kind = AskRecheck },
|
|
"commit": func(a *StepAsk) { a.Build.Fetch = map[string]any{"repository": "novox/x", "commit": "main"} },
|
|
"path": func(a *StepAsk) { a.Build.Path = "" },
|
|
}
|
|
for name, change := range cases {
|
|
a := buildAsk()
|
|
change(&a)
|
|
if _, err := EncodeStepAsk(a); err == nil {
|
|
t.Errorf("%s: encoded", name)
|
|
}
|
|
}
|
|
// A copy alone fetches nothing and needs no path.
|
|
a := buildAsk()
|
|
a.Build.Fetch, a.Build.Path, a.Build.Artifacts = nil, "", []AskArtifact{{Artifact: "base", From: "registry/x@sha256:00"}}
|
|
if _, err := EncodeStepAsk(a); err != nil {
|
|
t.Errorf("a copy alone: %v", err)
|
|
}
|
|
c := checkAsk()
|
|
c.Kind = AskDelivery
|
|
if _, err := EncodeStepAsk(c); err == nil {
|
|
t.Error("a check on the delivery stream encoded")
|
|
}
|
|
c = checkAsk()
|
|
c.Language = AskImage
|
|
if _, err := EncodeStepAsk(c); err == nil {
|
|
t.Error("a check of an image encoded")
|
|
}
|
|
raw, _ := EncodeStepAsk(buildAsk())
|
|
for _, bad := range []string{
|
|
strings.Replace(string(raw), `"kind":"delivery"`, `"kind":"queue"`, 1),
|
|
strings.Replace(string(raw), `"language":"go"`, `"language":"rust"`, 1),
|
|
} {
|
|
if _, err := DecodeStepAsk([]byte(bad)); err == nil {
|
|
t.Errorf("decoded %s", bad)
|
|
}
|
|
}
|
|
if _, err := DecodeStepAsk([]byte(strings.Replace(string(raw), `"v":1`, `"v":2`, 1))); !errors.Is(err, ErrUnknownVersion) {
|
|
t.Errorf("version 2: %v", err)
|
|
}
|
|
}
|
|
|
|
// 1887/A1a: the subjects, stream and workers are the seat's, as the broker derives them.
|
|
func TestAskSubjects(t *testing.T) {
|
|
s, err := AskSubject(AskGo, AskCheck)
|
|
if err != nil || s != "mesh.seat.node-build-go.accept.check" {
|
|
t.Fatalf("AskSubject = %q, %v", s, err)
|
|
}
|
|
language, kind, err := ParseAskSubject("mesh.seat.node-build-image.accept.delivery")
|
|
if err != nil || language != AskImage || kind != AskDelivery {
|
|
t.Fatalf("ParseAskSubject = %q %q %v", language, kind, err)
|
|
}
|
|
for _, bad := range []string{"mesh.seat.node-build-agent.accept.build", "mesh.seat.node-build-go.accept.queue", "mesh.seat.node-build-go.event.x"} {
|
|
if _, _, err := ParseAskSubject(bad); err == nil {
|
|
t.Errorf("parsed %s", bad)
|
|
}
|
|
}
|
|
if st, _ := AskStream(AskNode); st != "SEAT_NODE_BUILD_NODE" {
|
|
t.Errorf("AskStream = %q", st)
|
|
}
|
|
if w, _ := AskWorker(AskGo, AskRecheck); w != "SEAT_NODE_BUILD_GO_RECHECK_worker" {
|
|
t.Errorf("AskWorker = %q", w)
|
|
}
|
|
if seat, _ := BuildSeat(AskImage); seat != "node-build-image" {
|
|
t.Errorf("BuildSeat = %q", seat)
|
|
}
|
|
if m, _ := BuildModuleOf(AskNode); m != "mesh-build-node" {
|
|
t.Errorf("BuildModuleOf = %q", m)
|
|
}
|
|
if _, err := BuildSeat("agent"); err == nil {
|
|
t.Error("BuildSeat(agent)")
|
|
}
|
|
}
|
|
|
|
// 1887/A4b: a building key names the asks put for it; a done key or a name that is no ask id is refused.
|
|
func TestABuildingKeyNamesItsAsks(t *testing.T) {
|
|
b := BuilderBuild{State: BuildBuilding, By: "novox.builder", Asks: []string{"mh3k2x9qa1b2c3"}}
|
|
raw, err := EncodeBuilderBuild(b)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
got, err := DecodeBuilderBuild(raw)
|
|
if err != nil || len(got.Asks) != 1 || got.Asks[0] != "mh3k2x9qa1b2c3" {
|
|
t.Fatalf("decoded %+v, %v", got, err)
|
|
}
|
|
for _, bad := range []BuilderBuild{
|
|
{State: BuildBuilding, Asks: []string{"postgres"}},
|
|
{State: BuildFailed, Error: "x", Asks: []string{"mh3k2x9qa1b2c3"}},
|
|
} {
|
|
if _, err := EncodeBuilderBuild(bad); err == nil {
|
|
t.Errorf("encoded %+v", bad)
|
|
}
|
|
}
|
|
}
|