Pull the Node build seat's asks beside the tools, delivery first and at most the node's capacity (issue 1887 A3node, ADR 0525 §2-§6)
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.novox.be/novox/mesh-sdk/go/buildstep"
|
||||
"git.novox.be/novox/mesh-sdk/go/delivery"
|
||||
)
|
||||
|
||||
const askCommit = "0123456789abcdef0123456789abcdef01234567"
|
||||
|
||||
func fakeSteps(calls *[]string) []StepTool {
|
||||
answer := func(name string, out any) StepTool {
|
||||
return StepTool{Name: name, Run: func(ctx context.Context, args map[string]any) (any, error) {
|
||||
*calls = append(*calls, name)
|
||||
return out, nil
|
||||
}}
|
||||
}
|
||||
return []StepTool{
|
||||
answer("build_node_fetch", map[string]any{"workspace": "ws1", "modules": []string{"modules/gitea"}}),
|
||||
answer("build_node_build", map[string]any{"digest": "sha256:bb", "reference": "artifact-store://gitea/code@sha256:bb"}),
|
||||
answer("build_node_test", map[string]any{"passed": true}),
|
||||
}
|
||||
}
|
||||
|
||||
func nodeAsk(kind string) delivery.StepAsk {
|
||||
a := delivery.StepAsk{ID: buildstep.NewID(), Kind: kind, Language: delivery.AskNode, Asker: "mesh-delivery-checker", At: time.Now()}
|
||||
fetch := map[string]any{"repository": "novox/mesh-catalog", "commit": askCommit}
|
||||
if kind == delivery.AskDelivery {
|
||||
a.Asker = "mesh-delivery-builder"
|
||||
a.Build = &delivery.BuildJob{Module: "gitea", Path: "modules/gitea", Fetch: fetch, Artifacts: []delivery.AskArtifact{{Artifact: "code"}}}
|
||||
} else {
|
||||
a.Check = &delivery.CheckJob{Fetch: fetch, Level: delivery.LevelUnit}
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
// 1887/A3node: a pulled build ask runs fetch then build and its key names the reference; a check ask tests each module
|
||||
// directory the fetch named.
|
||||
func TestAPulledNodeAskRunsItsJob(t *testing.T) {
|
||||
states := newStates()
|
||||
m := moduleWith(states, "v26.10.0")
|
||||
m.Capacity = func() int { return 1 }
|
||||
var calls []string
|
||||
src := buildstep.NewFakeAsks()
|
||||
build, check := nodeAsk(delivery.AskDelivery), nodeAsk(delivery.AskCheck)
|
||||
_ = src.PublishAsk(check)
|
||||
_ = src.PublishAsk(build)
|
||||
p := m.Puller(fakeSteps(&calls), src)
|
||||
p.PullWait = 10 * time.Millisecond
|
||||
ctx, stop := context.WithCancel(context.Background())
|
||||
defer stop()
|
||||
go p.Pull(ctx)
|
||||
for deadline := time.Now().Add(3 * time.Second); ; time.Sleep(5 * time.Millisecond) {
|
||||
if acked, _, _ := src.Fates(); len(acked) == 2 {
|
||||
break
|
||||
}
|
||||
if time.Now().After(deadline) {
|
||||
t.Fatalf("the asks were not both acked: calls %v", calls)
|
||||
}
|
||||
}
|
||||
if got := strings.Join(calls, ","); got != "build_node_fetch,build_node_build,build_node_fetch,build_node_test" {
|
||||
t.Errorf("calls = %s, want the delivery ask's job first, then the check's", got)
|
||||
}
|
||||
key, _ := delivery.AskStepKey("ace", build.ID)
|
||||
states.mu.Lock()
|
||||
v := states.steps[key]
|
||||
states.mu.Unlock()
|
||||
if len(v) == 0 || !strings.Contains(string(v[len(v)-1].Result), "artifact-store://gitea/code@sha256:bb") {
|
||||
t.Fatalf("the step %s = %v", key, v)
|
||||
}
|
||||
}
|
||||
|
||||
// 1887/A3node, A7: the manifest takes the node's build capacity as a setting, with the builder's default, in a settings
|
||||
// file; the seat's verbs are served.
|
||||
func TestManifestTakesTheBuildCapacity(t *testing.T) {
|
||||
m := readManifest(t)
|
||||
raw, _ := os.ReadFile(moduleDir + "/module.json")
|
||||
var doc struct {
|
||||
Config map[string]struct {
|
||||
Default string `json:"default"`
|
||||
} `json:"config"`
|
||||
}
|
||||
_ = json.Unmarshal(raw, &doc)
|
||||
if doc.Config[buildstep.CapacitySetting].Default != buildstep.DefaultCapacities {
|
||||
t.Errorf("the capacity's default = %q", doc.Config[buildstep.CapacitySetting].Default)
|
||||
}
|
||||
if resource(t, m, "settings")["path"] != "${dir:state}/settings.json" {
|
||||
t.Error("no settings file")
|
||||
}
|
||||
m0 := &Module{Node: "ace", Capacity: func() int { return 0 }}
|
||||
served := map[string]bool{}
|
||||
for _, tool := range m0.SeatTools(m0.Puller(nil, buildstep.NewFakeAsks())) {
|
||||
served[tool.Name] = true
|
||||
}
|
||||
for _, verb := range []string{"current", "pause", "resume"} {
|
||||
if !served[Seat+"."+verb] {
|
||||
t.Errorf("%s.%s is not served", Seat, verb)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user