Merge remote-tracking branch 'origin/main' into feat/47-G-join11

# Conflicts:
#	modules/distribution/internal/holder/holder_test.go
This commit is contained in:
2026-11-12 10:25:58 +01:00
13 changed files with 470 additions and 87 deletions
@@ -223,7 +223,6 @@ const builder = "ace.mesh-build-go"
// TestTheHolderOfTheTwoImageSeats holds design 51's holder cases at the unit level (CAT-D1, D2, D3, D3b, D4, D4b, D5):
// one table or case per rule, the caller list and the store front's.
func TestTheHolderOfTheTwoImageSeats(t *testing.T) {
t.Run("a publish is checked against the builder's reservation", reservedChecksAPublishAgainstTheReservation)
blob := []byte(strings.Repeat("a", 3000))
part := Part{Digest: digestOf(blob), Size: int64(len(blob))}
req := func(id string) PublishRequest {
@@ -243,14 +242,14 @@ func TestTheHolderOfTheTwoImageSeats(t *testing.T) {
if a, _ := b.h.Publish(ArtifactSeat, builder, req("t1")); !reflect.DeepEqual(a.Missing, []string{part.Digest}) {
t.Errorf("resumed publish = %+v", a)
}
// A chunk 0 again starts the part afresh (it travels whole again, design 51 Publishing); a chunk that is neither the
// cursor nor 0 is refused, naming the cursor.
if _, err := b.h.PublishPart(ArtifactSeat, builder, PartRequest{Transfer: "t1", Digest: part.Digest, Sequence: 0, Data: blob[:1000]}); err != nil {
t.Errorf("a chunk 0 sent again was refused: %v", err)
}
// A chunk that is neither the cursor nor 0 is refused; a chunk 0 again is a part lacked travelling whole again
// (mesh-delivery's parts.Receiver.Take, 1966/AC203-1, AC203-2): its earlier chunks are dropped and it is taken.
if _, err := b.h.PublishPart(ArtifactSeat, builder, PartRequest{Transfer: "t1", Digest: part.Digest, Sequence: 2, Data: blob[:1000]}); err == nil {
t.Error("a chunk out of sequence was taken: the transfer goes on from the chunks held")
}
if _, err := b.h.PublishPart(ArtifactSeat, builder, PartRequest{Transfer: "t1", Digest: part.Digest, Sequence: 0, Data: blob[:1000]}); err != nil {
t.Errorf("a chunk 0 again was refused: %v", err)
}
a, err = b.h.PublishPart(ArtifactSeat, builder, PartRequest{Transfer: "t1", Digest: part.Digest, Sequence: 1, Last: true, Data: blob[1000:]})
if err != nil || !a.Ended || len(b.said) != 1 || b.said[0].event != EventPublished || b.said[0].body.Reference == "" {
t.Fatalf("last chunk = %+v, %v; said %+v", a, err, b.said)
@@ -292,12 +291,12 @@ func TestTheHolderOfTheTwoImageSeats(t *testing.T) {
_, err := b.h.Publish(ArtifactSeat, builder, req("t"))
return err
}, "at their cap"},
{"a version the builder did not reserve", func(b *bed) error {
{"a version the builder did not number", func(b *bed) error {
b.h.Builder = fakeBuilder{ok: false}
b.store.has[part.Digest] = true // held already: the publish ends at once
_, err := b.h.Publish(ArtifactSeat, builder, req("t"))
return err
}, "the builder did not reserve it"},
}, "the builder did not number it"},
{"an image on the artifact seat", func(b *bed) error {
r := req("t")
r.Kind = KindImage
@@ -849,9 +848,9 @@ func TestTheHolderOfTheTwoImageSeats(t *testing.T) {
if err := json.Unmarshal(raw, &m); err != nil {
t.Fatal(err)
}
// The reservation is asked through the seat mesh-builds, so the manifest takes no package of the builder (design 47 §381).
if len(m.Packages) != 0 {
t.Errorf("packages %v: want none", m.Packages)
// The builder's question is its published package, taken by its series (ADR 0634 §1).
if m.Packages["git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds"] != "0.1" {
t.Errorf("packages %v: want builds of series 0.1", m.Packages)
}
// E15: the provision artifact-store retires (ADR 0632 §3); the bootstrap keeps it as an alias on port 5100 while
// the running node-engines still find the store by it (issue 1966), and nothing else is provided or served.
@@ -870,7 +869,7 @@ func TestTheHolderOfTheTwoImageSeats(t *testing.T) {
if _, ok := claims[OldSeat]; !ok {
t.Error("the old seat mesh-artifact-store is no longer claimed while its window is open")
}
if !reflect.DeepEqual(m.Consumes, []string{"mesh-delivery-view.delivered", "node-engine.manifest-reads-changed", "mesh-conditions.findings-asked"}) {
if !reflect.DeepEqual(m.Consumes, []string{"mesh-delivery-view.delivered", "node-engine.manifest-reads-changed"}) {
t.Errorf("consumes = %v, want delivered and manifest-reads-changed (the windows' wakes)", m.Consumes)
}
// E14: the registry container, on the loopback, is listed before the program, so the port is free when it starts.
@@ -916,34 +915,19 @@ func TestTheHolderOfTheTwoImageSeats(t *testing.T) {
// Running review F2: incoming asks the bus 8 GiB, the most the objects template allows, equal to IncomingCap
// (said only where no binding is read); transfers keeps for good, the holder dropping an idle one by its key
// in idle, a state of keys with their own time to live.
// The image registry is a foundation part (design 47 G §584): its bus state is in its old sections, incoming in
// `objects`, the others in `state`.
var req struct {
Objects []struct {
Name string `json:"name"`
MaxMiB uint64 `json:"max-mib"`
} `json:"objects"`
State []json.RawMessage `json:"state"`
Requires []struct {
Name string `json:"name"`
Options map[string]any `json:"options"`
} `json:"requires"`
}
_ = json.Unmarshal(raw, &req)
opts := map[string]map[string]any{}
for _, e := range req.State {
var o map[string]any
if json.Unmarshal(e, &o) != nil {
var name string
_ = json.Unmarshal(e, &name)
o = map[string]any{"name": name}
}
opts[fmt.Sprint(o["name"])] = o
for _, r := range req.Requires {
opts[r.Name] = r.Options
}
var incoming uint64
for _, o := range req.Objects {
if o.Name == IncomingObjects {
incoming = o.MaxMiB
}
}
if incoming<<20 != IncomingCap {
t.Errorf("incoming asks %v MiB, IncomingCap is %d bytes: want them equal", incoming, uint64(IncomingCap))
if mib, _ := opts[IncomingObjects]["max-mib"].(float64); uint64(mib)<<20 != IncomingCap {
t.Errorf("incoming asks %v MiB, IncomingCap is %d bytes: want them equal", opts[IncomingObjects]["max-mib"], uint64(IncomingCap))
}
if _, ok := opts[TransfersState]["ttl-seconds"]; ok {
t.Errorf("transfers has a lifetime %v: the bus would drop a transfer's key and leave its parts", opts[TransfersState])