Files
mesh-delivery/modules/mesh-delivery-assigner/asks/asks_test.go
T
jschoubben 42c3db1d5b B2h AS17 (2a): the assigner's ask of a held revert has its kind and key
The asks state gains the kind revert, keyed revert.<node>.<module>.<hex>
after the reverted build's fingerprint; like the backup ask it needs no
proof of who answered, so the view may answer it, and an asking that ends
unanswered while the hold stands is written again.

Builds: design 47 G §710, §300

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
2026-11-12 09:24:04 +01:00

90 lines
3.8 KiB
Go

package asks
import (
"errors"
"strings"
"testing"
"git.novox.be/novox/mesh-sdk/go/keys"
)
// The keys equal what the assigner has always written (the expected strings are the trunk's own output for the same input),
// and each reads back to its parts.
func TestTheAssignersAskKeysKeepTheirFormsAndTheValueItsRules(t *testing.T) {
fp := "src2:" + strings.Repeat("ab", 32)
hex := strings.Repeat("ab", 32)
digest := "sha256:" + strings.Repeat("cd", 32)
hold, _ := HoldAskKey("gitea", fp)
restore, _ := RestoreAskKey("n1", "gitea", fp)
backup, _ := BackupAskKey("n1", "novox.be", fp)
assignments, _ := AssignmentsAskKey("p-20261028t183000-1a2b3c")
record, _ := RecordAskKey("n1", "gitea", digest)
revert, _ := RevertAskKey("n1", "nats", fp)
for key, want := range map[string]struct {
got string
back AskKey
}{
"hold": {hold, AskKey{Kind: "hold", Module: "gitea", FP: fp}},
"restore": {restore, AskKey{Kind: "restore", Node: "n1", Module: "gitea", FP: fp}},
"backup": {backup, AskKey{Kind: "backup", Node: "n1", Module: "novox.be", FP: fp}},
"assignments": {assignments, AskKey{Kind: "assignments", Proposal: "p-20261028t183000-1a2b3c"}},
"record": {record, AskKey{Kind: "record", Node: "n1", Module: "gitea", Composed: digest}},
"revert": {revert, AskKey{Kind: "revert", Node: "n1", Module: "nats", FP: fp}},
} {
back, err := ParseAnyAskKey(want.got)
if err != nil || back != want.back {
t.Errorf("%s: ParseAnyAskKey(%q) = %+v, %v; want %+v", key, want.got, back, err, want.back)
}
}
for got, want := range map[string]string{hold: "hold.gitea." + hex, restore: "restore.n1.gitea." + hex, backup: "backup.n1.novox=2ebe." + hex,
assignments: "assignments.p-20261028t183000-1a2b3c", record: "record.n1.gitea." + strings.Repeat("cd", 32), revert: "revert.n1.nats." + hex} {
if got != want {
t.Errorf("key %q, want %q", got, want)
}
}
merge, err := ParseAnyAskKey("merge.fix/1=2e2.d106c7950d28")
if err != nil || merge.Kind != "merge" || merge.Group != "fix/1.2" || merge.Hash != "d106c7950d28" {
t.Errorf("a merge ask key: %+v, %v", merge, err)
}
for _, bad := range []string{"", "other.x", "hold.gitea", "hold.gitea.src2:" + hex, "restore.n1", "backup.n1.node", "backup.n1.gitea." + hex[:60],
"assignment.AB", "record.n1.gitea." + hex[:10], "record.n1.node." + hex, "merge.g", "revert.n1.node", "revert.n1.nats." + hex[:60]} {
if _, err := ParseAnyAskKey(bad); err == nil {
t.Errorf("ParseAnyAskKey(%q) reads a wrong key", bad)
}
}
if proof, err := AskNeedsProof("merge"); err != nil || !proof {
t.Error("a merge ask needs proof")
}
for _, kind := range []string{"hold", "revert"} {
if proof, err := AskNeedsProof(kind); err != nil || proof {
t.Errorf("a %s ask needs no proof", kind)
}
}
if _, err := AskNeedsProof("view"); err == nil {
t.Error("an unknown kind of ask is taken")
}
// The value: the router's ask whole; an ask of a kind that needs proof, a negative asking and no ask are refused.
good := Ask{Ask: []byte(`{"id":"x"}`), Asking: 2}
data, err := EncodeAsk(hold, good)
if err != nil {
t.Fatalf("EncodeAsk: %v", err)
}
back, err := DecodeAsk(hold, data)
if err != nil || !SameAsk(back, Ask{V: keys.Version, Ask: []byte(` {"id": "x"} `), Asking: 2}) {
t.Errorf("DecodeAsk = %+v, %v", back, err)
}
for name, c := range map[string]struct {
key string
a Ask
}{"a merge ask": {"merge.g.d106c7950d28", good}, "a negative asking": {hold, Ask{Ask: good.Ask, Asking: -1}}, "no ask": {hold, Ask{}},
"a null ask": {hold, Ask{Ask: []byte("null")}}, "an unknown kind": {"other.x", good}} {
if _, err := EncodeAsk(c.key, c.a); err == nil {
t.Errorf("EncodeAsk takes %s", name)
}
}
if _, err := DecodeAsk(hold, []byte(`{"v":2,"ask":{}}`)); !errors.Is(err, keys.ErrUnknownVersion) {
t.Errorf("DecodeAsk of another version = %v", err)
}
}