package resolution import ( "reflect" "strings" "testing" mcat "git.novox.be/novox/mesh-sdk/go/catalogue" ) func displayServer(name, display string, claims ...string) mcat.Manifest { m := mcat.Manifest{Module: name, Provides: []mcat.Offer{{Name: display, Reach: mcat.ReachMachine}}} for _, c := range claims { m.Claims = append(m.Claims, mcat.Claim{Name: c}) } return m } func windowManager() mcat.Manifest { return mcat.Manifest{Module: "i3", Requires: []string{"x11-display"}} } // §3: a display is resolved on the requiring module's own node. func TestAMachineReachRequirementResolvesToTheProviderOnItsOwnNode(t *testing.T) { cat := shelf(windowManager(), displayServer("xorg", "x11-display", mcat.DisplayServerSeat)) got, err := Resolve(cat, []string{"xorg", "i3"}, workstation(), mcat.World{}) if err != nil { t.Fatalf("i3 beside xorg did not resolve: %v", err) } if !reflect.DeepEqual(names(got), []string{"xorg", "i3"}) && !reflect.DeepEqual(names(got), []string{"i3", "xorg"}) { t.Errorf("resolved %v", names(got)) } } // §3: never answered by installing a provider, and never by another machine's. func TestAMachineReachRequirementIsNotPulledInNorAnsweredFromAnotherNode(t *testing.T) { cat := shelf(windowManager(), displayServer("xorg", "x11-display", mcat.DisplayServerSeat), displayServer("xwayland", "x11-display")) // Another machine runs xorg and says so to the world; it does not count. world := mcat.World{Offered: map[string][]mcat.Provider{ "x11-display": {{Node: "laptop", At: "laptop.mesh", Module: "xorg"}}}} _, err := Resolve(cat, []string{"i3"}, workstation(), world) if err == nil { t.Fatal("i3 resolved on a machine with no display of its own") } for _, want := range []string{ `"x11-display" is wanted by i3`, "usable only on the machine that provides it", "assign one to workstation", "xorg (holds node-display-server)", "xwayland", } { if !strings.Contains(err.Error(), want) { t.Errorf("the refusal does not say %q:\n%v", want, err) } } // With a single provider in the catalogue too: one candidate is still not a choice to make // for somebody, unlike a node-scoped provision without the machine's reach. _, err = Resolve(shelf(windowManager(), displayServer("xorg", "x11-display", mcat.DisplayServerSeat)), []string{"i3"}, workstation(), mcat.World{}) if err == nil { t.Fatal("xorg was pulled in for i3") } // Not in the first pass, whose refusals take the machine off the network. if _, err := Resolve(cat, []string{"i3"}, workstation(), mcat.World{Unchecked: true}); err != nil { t.Errorf("the first pass refused: %v", err) } } func TestACatalogueDisagreeingAboutAProvisionsReachIsRefused(t *testing.T) { cat := shelf(windowManager(), displayServer("xorg", "x11-display"), mcat.Manifest{Module: "fake-x", Provides: mcat.Offers("x11-display")}) _, err := Resolve(cat, []string{"xorg", "i3"}, workstation(), mcat.World{}) if err == nil || !strings.Contains(err.Error(), `the catalogue disagrees about "x11-display"`) { t.Fatalf("a provision with and without the machine's reach gave %v", err) } }