package frombus import ( "context" "strings" "testing" "git.novox.be/novox/mesh-sdk/go/delivery" ) // aNode is a bus with n1 the hub, each of manifests placed on it and held at the indexer, in the order given. func aNode(t *testing.T, manifests ...string) (*bus, map[string]string) { t.Helper() p := delivery.Placement{Node: "n1", Decided: delivery.NodeDecided{Hub: true, Address: "10.77.0.1"}} b := &bus{records: map[string]delivery.NodeRecord{"n1": {Node: "n1", TunnelKey: publicKey(t), SealingKey: "sk", Capabilities: []string{"systemd"}}}, modules: map[string]delivery.Module{}, manifests: map[string][]byte{}, builds: map[string]*delivery.BuilderBuild{}} fps := map[string]string{} for i, raw := range manifests { module := strings.SplitN(strings.TrimPrefix(raw, `{"module":"`), `"`, 2)[0] p.Modules = append(p.Modules, delivery.PlacedModule{Module: module}) b.modules[module] = delivery.Module{Manifest: delivery.ManifestDigest([]byte(raw))} b.manifests[delivery.ManifestDigest([]byte(raw))] = []byte(raw) fps[module] = "src2:" + strings.Repeat(string(rune('1'+i)), 64) } b.placements = map[string]delivery.Placement{"n1": p} return b, fps } // Issue 774, 2026-10-30 19:30: a node refused whole after holding a module says what it held and why, since the last // refusal can be of the held module's stub (node-tools held, then "its build produced 0 bundle(s)", its own why unsaid). func aNodeRefusedWholeSaysWhatItHeld(t *testing.T) { refused := `{"module":"power","version":"1","items":[{"collection":"contribution:node-bar:block","attributes":{"shows":"state"},"template":"files/a"}]}` needs := `{"module":"lamp","version":"1","requires":["nothing-provides-this"]}` b, fps := aNode(t, refused, needs) _, _, held, err := Compose(context.Background(), b, Mesh{}, Scope{Node: "n1"}, fps) if err == nil || !strings.Contains(err.Error(), "nothing provides") || !strings.Contains(err.Error(), `held before: power: `) || !strings.Contains(err.Error(), `"shows" is none of them`) { t.Errorf("the node refused whole with %v (held %v), want lamp's refusal and power held before, with its why", err, held) } }