package catalogue import ( "strings" "testing" ) // One account, several modules: the shell's module sets its shell, the container runtime's adds it // to a group. Groups are only ever added by the host, so they are contributed; a shell or a home is // one value, owned by one module per node. func userResource(fields map[string]any) map[string]any { r := map[string]any{"id": "operator", "type": "user", "name": "op"} for k, v := range fields { r[k] = v } return r } func TestAShellAndAGroupOnOneAccountFromTwoModulesResolve(t *testing.T) { zsh := Manifest{Module: "zsh", Resources: []map[string]any{userResource(map[string]any{"shell": "/usr/bin/zsh"})}} docker := Manifest{Module: "docker", Resources: []map[string]any{userResource(map[string]any{"groups": []any{"docker"}})}} other := Manifest{Module: "media", Resources: []map[string]any{userResource(map[string]any{"groups": []any{"video"}})}} if problems := checkResources([]Manifest{zsh, docker, other}); len(problems) != 0 { t.Fatalf("a shell and two modules' groups on one account were refused: %v", problems) } if _, err := Resolve(shelf(zsh, docker, other), []string{"zsh", "docker", "media"}, workstation(), World{}); err != nil { t.Fatalf("the three did not resolve together: %v", err) } } func TestTwoModulesSettingOneAccountsShellOrHomeAreRefused(t *testing.T) { for _, field := range []string{"shell", "home"} { a := Manifest{Module: "zsh", Resources: []map[string]any{userResource(map[string]any{field: "/one"})}} b := Manifest{Module: "fish", Resources: []map[string]any{userResource(map[string]any{field: "/two", "groups": []any{"x"}})}} problems := checkResources([]Manifest{a, b}) want := `zsh and fish both set the ` + field + ` of the user "op"` if len(problems) != 1 || !strings.Contains(problems[0], want) { t.Errorf("two modules setting %s gave %v, want %q", field, problems, want) } } }