The pass that answers *what does this node offer* takes a failed resolution to mean it learned nothing about that node. So refusing an unanswerable requirement there made the machine disappear — and every other machine was then told, wrongly, that the two of them shared no private network. A wrong answer about a machine nobody asked about, caused by a fault on a third. The lab found it: one module needing a licence that had not been added yet made two unrelated machines look disconnected. The second pass still refuses it, where the question is actually being asked.
188 lines
7.1 KiB
Go
188 lines
7.1 KiB
Go
package catalogue
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func aModelUser() Manifest {
|
|
return Manifest{Module: "assistant", Requires: []string{"model-access"},
|
|
Binds: map[string]string{"model-access": "/etc/assistant/model.json"},
|
|
Secrets: map[string]string{"model-access": "/etc/assistant/key"}}
|
|
}
|
|
|
|
// A provision answered by a record rather than a node.
|
|
//
|
|
// novox/hq ADR 0024: a hosted model is on nobody's machine and is reached over the public
|
|
// internet, so the rule that refuses two ends sharing no private network must not apply. This
|
|
// node is deliberately not on the private network at all — under the old rule that alone would
|
|
// refuse it.
|
|
func TestAProvisionAnsweredByARecordDoesNotNeedAPrivateNetwork(t *testing.T) {
|
|
got, err := Resolve(
|
|
map[string]Manifest{"assistant": aModelUser()},
|
|
[]string{"assistant"},
|
|
Node{Name: "workstation"},
|
|
World{
|
|
Licences: map[string][]Record{"model-access": {{Name: "personal",
|
|
Serves: map[string]any{"model": "a-model"}}}},
|
|
Using: map[string]map[string]Record{"assistant": {"model-access": {Name: "personal",
|
|
Serves: map[string]any{"model": "a-model"}}}},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("a machine off the private network could not be given model access: %v", err)
|
|
}
|
|
if len(got.Needs) != 1 {
|
|
t.Fatalf("the licence was not recorded as something this node takes: %+v", got.Needs)
|
|
}
|
|
if !got.Needs[0].ByRecord {
|
|
t.Fatal("the licence was treated as a machine, so the reachability rule would apply to it")
|
|
}
|
|
if got.Needs[0].From != "personal" {
|
|
t.Fatalf("the licence is not named by what a person calls it: %+v", got.Needs[0])
|
|
}
|
|
}
|
|
|
|
// Refused when the consumer has not said which — and the refusal names the candidates and the
|
|
// command, because ADR 0024 warns this will be felt: a mesh holding three ways to reach a model
|
|
// refuses every consumer that has not chosen.
|
|
func TestAConsumerThatHasNotSaidWhichLicenceIsRefusedWithTheCandidates(t *testing.T) {
|
|
_, err := Resolve(
|
|
map[string]Manifest{"assistant": aModelUser()},
|
|
[]string{"assistant"},
|
|
Node{Name: "workstation"},
|
|
World{Licences: map[string][]Record{"model-access": {
|
|
{Name: "personal"}, {Name: "the-organisation"},
|
|
}}})
|
|
if err == nil {
|
|
t.Fatal("a consumer was given model access without anybody saying which")
|
|
}
|
|
said := err.Error()
|
|
for _, want := range []string{"personal", "the-organisation", "licence use"} {
|
|
if !strings.Contains(said, want) {
|
|
t.Fatalf("the refusal does not name %q, so it is correct and unusable:\n%s", want, said)
|
|
}
|
|
}
|
|
}
|
|
|
|
// A model the mesh runs itself answers it locally, and a record is not consulted.
|
|
func TestAModelInTheMeshsOwnSetAnswersItWithoutALicence(t *testing.T) {
|
|
got, err := Resolve(
|
|
map[string]Manifest{
|
|
"assistant": aModelUser(),
|
|
"ollama": {Module: "ollama",
|
|
Provides: []Offer{{Name: "model-access", Scope: ScopeNode}}},
|
|
},
|
|
[]string{"assistant", "ollama"},
|
|
Node{Name: "workstation"},
|
|
World{Licences: map[string][]Record{"model-access": {{Name: "personal"}}}})
|
|
if err != nil {
|
|
t.Fatalf("a machine running its own model was asked to choose a licence: %v", err)
|
|
}
|
|
for _, n := range got.Needs {
|
|
if n.ByRecord {
|
|
t.Fatal("a record was used although the answer was on this machine")
|
|
}
|
|
}
|
|
}
|
|
|
|
// A key that was never supplied is refused by name rather than silently not written.
|
|
//
|
|
// The mesh discarded the plaintext when the key was accepted and cannot seal another, so a
|
|
// machine that resolved cleanly would receive no file and fail at whatever read it.
|
|
func TestAModuleOnALicenceWithNoKeyIsRefusedRatherThanLeftEmpty(t *testing.T) {
|
|
r := Resolution{
|
|
Node: "workstation",
|
|
Modules: []Manifest{aModelUser()},
|
|
Needs: []Needed{{Name: "model-access", From: "personal", ByRecord: true, For: "assistant"}},
|
|
}
|
|
_, err := r.Declaration(Rendering{})
|
|
if err == nil {
|
|
t.Fatal("a module was given a licence with no key, so it receives nothing and fails later")
|
|
}
|
|
if !strings.Contains(err.Error(), "licence key personal") {
|
|
t.Fatalf("the refusal does not say how to fix it: %v", err)
|
|
}
|
|
}
|
|
|
|
// And with a key, both files arrive: what is public, and what is not.
|
|
func TestALicenceDeliversWhatIsPublicAndWhatIsSealed(t *testing.T) {
|
|
r := Resolution{
|
|
Node: "workstation",
|
|
Modules: []Manifest{aModelUser()},
|
|
Needs: []Needed{{Name: "model-access", From: "personal", ByRecord: true, For: "assistant",
|
|
Serves: map[string]any{"model": "a-model"}, Sealed: "sealed-blob"}},
|
|
}
|
|
out, err := r.Declaration(Rendering{})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
files := map[string]map[string]any{}
|
|
for _, res := range out {
|
|
if path, ok := res["path"].(string); ok {
|
|
files[path] = res
|
|
}
|
|
}
|
|
bound, given := files["/etc/assistant/model.json"]
|
|
if !given {
|
|
t.Fatal("the consumer was not told what it needs to know that is not secret")
|
|
}
|
|
content, _ := bound["content"].(string)
|
|
if !strings.Contains(content, "a-model") {
|
|
t.Fatalf("the binding does not carry what the licence serves:\n%s", content)
|
|
}
|
|
// The binding says it is a record rather than leaving an empty address, which a reader would
|
|
// take for something the mesh failed to fill in.
|
|
if !strings.Contains(content, "not a machine") {
|
|
t.Fatalf("the binding leaves an empty address with no explanation:\n%s", content)
|
|
}
|
|
key, delivered := files["/etc/assistant/key"]
|
|
if !delivered {
|
|
t.Fatal("the key was not delivered")
|
|
}
|
|
if key["sealed"] != "sealed-blob" {
|
|
t.Fatalf("the key is not the sealed one: %+v", key)
|
|
}
|
|
// And never in the open. The whole arrangement is that what travels is unreadable by
|
|
// everything between here and the machine.
|
|
if strings.Contains(content, "sealed-blob") {
|
|
t.Fatal("the key was written into the public file as well")
|
|
}
|
|
}
|
|
|
|
// One machine's unresolvable module must not remove it from the private network.
|
|
//
|
|
// The pass that answers *what does this node offer* takes a failed resolution to mean it learned
|
|
// nothing — so refusing an unanswerable requirement there makes the machine disappear, and every
|
|
// other machine is then told, wrongly, that the two of them share no network. A wrong answer about
|
|
// a machine nobody asked about, caused by a fault on a third.
|
|
func TestAnUnanswerableRequirementDoesNotRemoveAMachineFromTheMesh(t *testing.T) {
|
|
shelf := map[string]Manifest{
|
|
"assistant": aModelUser(),
|
|
"networking": {Module: "networking",
|
|
Provides: []Offer{{Name: "mesh-network", Scope: ScopeNode}}},
|
|
}
|
|
// The first pass: what does this machine offer? It is assigned something nothing answers.
|
|
got, err := Resolve(shelf, []string{"assistant", "networking"},
|
|
Node{Name: "laptop"}, World{Unchecked: true})
|
|
if err != nil {
|
|
t.Fatalf("a machine with one unanswerable requirement was lost entirely: %v", err)
|
|
}
|
|
var offers bool
|
|
for _, m := range got.Modules {
|
|
for _, o := range m.Offers() {
|
|
if o == "mesh-network" {
|
|
offers = true
|
|
}
|
|
}
|
|
}
|
|
if !offers {
|
|
t.Fatal("the machine's own network module was not seen, so it looks off the network")
|
|
}
|
|
|
|
// And the second pass, where the question is actually being asked, still refuses it.
|
|
if _, err := Resolve(shelf, []string{"assistant", "networking"},
|
|
Node{Name: "laptop"}, World{}); err == nil {
|
|
t.Fatal("the requirement nothing answers was accepted when it was actually asked")
|
|
}
|
|
}
|