Files
mesh-catalog/modules/mesh-build-image/cmd/mesh-build-image/asks_test.go
T
jschoubben 9c57f7afb3 mesh-build-go publishes the build runner as its own package, so the other build modules share it without mesh-sdk (ADR 0593 §1)
The runner, the toolchain guard, the fetch, the parsers, buildcpu, the conformance kit and mesh-pack move from mesh-sdk's
buildstep into modules/mesh-build-go/buildstep (own go.mod). mesh-build-go, mesh-build-node and mesh-build-image require it
by a same-repository replace; what the delivery parts read (the failure contract, the fetch request, the stale sweep, the
module tree shape, NewID, CapacitySetting) stays imported from mesh-sdk as sdkstep.

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-02 18:22:41 +01:00

89 lines
3.5 KiB
Go

package main
import (
"context"
"strings"
"testing"
"time"
"git.novox.be/novox/mesh-catalog/modules/mesh-build-go/buildstep"
sdkstep "git.novox.be/novox/mesh-sdk/go/buildstep"
"git.novox.be/novox/mesh-sdk/go/delivery"
)
const askCommit = "0123456789abcdef0123456789abcdef01234567"
// 1887/A3image: a pulled image ask copies a pinned image with no fetch, then fetches and builds the module's own, and its
// key <node>.<ask id> names each reference; the seat's verbs are served.
func TestAPulledImageAskCopiesThenBuilds(t *testing.T) {
states := newStates()
m := moduleWith(t, newFake(t), states)
m.Capacity = func() int { return 1 }
var calls []string
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
}}
}
steps := []StepTool{
answer("build_image_fetch", map[string]any{"workspace": "ws1"}),
answer("build_image_build", map[string]any{"digest": "sha256:cc", "reference": "registry/m/server@sha256:cc"}),
answer("build_image_copy", map[string]any{"digest": "sha256:dd", "reference": "registry/m/base@sha256:dd"}),
}
src := buildstep.NewFakeAsks()
a := delivery.StepAsk{ID: sdkstep.NewID(), Kind: delivery.AskDelivery, Language: delivery.AskImage, Asker: "mesh-delivery-builder",
At: time.Now(), Build: &delivery.BuildJob{Module: "m", Path: "modules/m", Publish: true,
Fetch: map[string]any{"repository": "novox/mesh-catalog", "commit": askCommit},
Artifacts: []delivery.AskArtifact{{Artifact: "base", From: "docker.io/library/alpine@sha256:00"}, {Artifact: "server"}}}}
_ = src.PublishAsk(a)
p := m.Puller(steps, src)
p.PullWait = 10 * time.Millisecond
ctx, stop := context.WithCancel(context.Background())
defer stop()
go p.Pull(ctx)
key, _ := delivery.AskStepKey("ace", a.ID)
var step delivery.Step
for deadline := time.Now().Add(3 * time.Second); ; time.Sleep(5 * time.Millisecond) {
states.mu.Lock()
v := states.steps[key]
states.mu.Unlock()
if len(v) > 0 && v[len(v)-1].State != delivery.StepRunning {
step = v[len(v)-1]
break
}
if time.Now().After(deadline) {
t.Fatalf("the ask's step never ended: calls %v", calls)
}
}
if step.State != delivery.StepPassed || !strings.Contains(string(step.Result), "registry/m/server@sha256:cc") ||
!strings.Contains(string(step.Result), "registry/m/base@sha256:dd") {
t.Fatalf("the step = %+v", step)
}
if got := strings.Join(calls, ","); got != "build_image_copy,build_image_fetch,build_image_build" {
t.Errorf("calls = %s", got)
}
served := map[string]bool{}
for _, tool := range m.SeatTools(p) {
served[tool.Name] = true
}
for _, verb := range []string{"current", "pause", "resume"} {
if !served[Seat+"."+verb] {
t.Errorf("%s.%s is not served", Seat, verb)
}
}
// A node without /dev/net/tun (a build node, 2026-10-28) takes no ask: its capacity is 0 and says why, so the ask goes to a node
// that can build it instead of failing in buildah's network setup; once it is there again, the capacity is back.
tun := m.Tun
m.Tun = t.TempDir() + "/none"
_ = m.Check(context.Background())
if c := p.CapacityDetail(); c.Effective != 0 || !strings.Contains(c.Why, "not eligible: "+m.Tun+" cannot be opened") {
t.Errorf("without /dev/net/tun the capacity = %+v", c)
}
m.Tun = tun
_ = m.Check(context.Background())
if c := p.CapacityDetail(); c.Effective != 1 || c.Ineligible != "" {
t.Errorf("with /dev/net/tun again the capacity = %+v", c)
}
}