A want that names a node in kept-on, for an artifact its parts name, is fetched through kept-artifact of that node's build seat and read as an object on the bus, checked against the digest; with no kept-on it is fetched from the store, and the builder's builds are read no more (the apply hook, the fetch and the object read from bc8fbc7, its node and fingerprint from the want). Builds: design 47 G §271, §526, §421 (A-50) Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
74 lines
2.8 KiB
Go
74 lines
2.8 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// A module's done build that kept its artifact on a build node is fetched through that node's build seat (design 47).
|
|
func TestAKeptArtifactIsFetchedThroughTheBuildSeatOfItsNode(t *testing.T) {
|
|
hex := strings.Repeat("a", 64)
|
|
stored := func(string) (json.RawMessage, error) {
|
|
return json.RawMessage(`{"module":"distribution","fp":"f1","digest":"` + hex + `","size":5,"store":"kept-builds","object":"` + hex + `"}`), nil
|
|
}
|
|
for _, row := range []struct {
|
|
name string
|
|
kept bool
|
|
answer func(seat string) (json.RawMessage, error)
|
|
object error
|
|
wantKept bool
|
|
wantErr string
|
|
wantSeat string
|
|
}{
|
|
{"a build kept nothing is not asked", false, nil, nil, false, "", ""},
|
|
{"the seat of the language answers", true, func(seat string) (json.RawMessage, error) {
|
|
if seat != "node-build-node" {
|
|
return nil, errors.New("no responder")
|
|
}
|
|
return stored(seat)
|
|
}, nil, true, "", "node-build-node"},
|
|
{"no build seat of the node answers", true, func(string) (json.RawMessage, error) { return nil, errors.New("no responder") },
|
|
nil, true, "novox keeps the build of distribution", ""},
|
|
{"the seat refuses it", true, func(string) (json.RawMessage, error) {
|
|
return json.RawMessage(`{"module":"distribution","fp":"f1","refused":"not kept","words":"swept"}`), nil
|
|
}, nil, true, "refuses the kept build of distribution: not kept", ""},
|
|
{"the object cannot be read", true, stored, errors.New("no object"), true, "could not be read from kept-builds", "node-build-go"},
|
|
} {
|
|
t.Run(row.name, func(t *testing.T) {
|
|
var seats []string
|
|
fetch := keptArtifactFetch(
|
|
func(context.Context, string, string) (string, string, bool, error) { return "novox", "f1", row.kept, nil },
|
|
func(_ context.Context, node, seat, verb string, _ any, _ time.Duration) (json.RawMessage, error) {
|
|
if node != "novox" || verb != "kept-artifact" {
|
|
t.Errorf("asked %s of %s on %s", verb, seat, node)
|
|
}
|
|
seats = append(seats, seat)
|
|
return row.answer(seat)
|
|
},
|
|
func(_ context.Context, store, name string, limit int64) ([]byte, error) {
|
|
if store != "kept-builds" || name != hex || limit < 5 {
|
|
t.Errorf("read %s/%s up to %d", store, name, limit)
|
|
}
|
|
return []byte("bytes"), row.object
|
|
})
|
|
body, kept, err := fetch(context.Background(), "distribution", "sha256:"+hex)
|
|
if kept != row.wantKept {
|
|
t.Fatalf("kept = %v", kept)
|
|
}
|
|
if row.wantErr == "" && (err != nil || (kept && string(body) != "bytes")) {
|
|
t.Fatalf("got %q, %v", body, err)
|
|
}
|
|
if row.wantErr != "" && (err == nil || !strings.Contains(err.Error(), row.wantErr)) {
|
|
t.Fatalf("the error is %v, want %q", err, row.wantErr)
|
|
}
|
|
if !row.kept && len(seats) > 0 {
|
|
t.Errorf("a build that kept nothing asked %v", seats)
|
|
}
|
|
})
|
|
}
|
|
}
|