mesh/delivery checking
mesh/merge-gate out of date: judged against trunk 1826b68a22b5, the trunk is now 404b4409e70e; judged again on a recheck or when it is merged
mesh/repo-check out of date: judged against trunk 1826b68a22b5, the trunk is now 404b4409e70e; judged again on a recheck or when it is merged
nfs-server's exports and adopt now say the local-network grant, and that sharenfs is cleared only once the mesh's export covers every client the property exported to.
96 lines
3.7 KiB
Go
96 lines
3.7 KiB
Go
package catalogue
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// Defends novox/hq ADR 0341: a machine's SMB shares are one node seat, node-smb-server, with its verbs
|
|
// required of every holder, delivering nothing — its clients are devices that are not nodes.
|
|
|
|
func TestTheSMBServerIsANodeSeatWithItsVerbs(t *testing.T) {
|
|
s, ok := SeatNamed(SMBServerSeat)
|
|
if !ok {
|
|
t.Fatalf("%s is not in the mesh's set", SMBServerSeat)
|
|
}
|
|
if s.Scope != ScopeNode || s.Decision != "novox/hq ADR 0341" || s.Delivers != "" || s.Replicated {
|
|
t.Errorf("%s is %+v; a node seat under ADR 0341 that delivers nothing", SMBServerSeat, s)
|
|
}
|
|
var got []string
|
|
for _, v := range s.Serves {
|
|
got = append(got, v.Name)
|
|
if v.Optional {
|
|
t.Errorf("%s.%s is optional; its first holder serves it", SMBServerSeat, v.Name)
|
|
}
|
|
if v.Description == "" || v.Input["type"] != "object" || len(v.Replaces) == 0 {
|
|
t.Errorf("%s.%s has no description, no object schema or says it replaces nothing", SMBServerSeat, v.Name)
|
|
}
|
|
}
|
|
if strings.Join(got, " ") != "shares sessions test reload adopt" {
|
|
t.Errorf("%s serves %v", SMBServerSeat, got)
|
|
}
|
|
}
|
|
|
|
// Taking over the hand-written configuration is a person's act (ADR 0341 clause 7): a dry run unless the
|
|
// string switch says "true", and it says it keeps a dated copy and refuses to drop a share.
|
|
func TestTheSMBAdoptIsADryRunUnlessConfirmed(t *testing.T) {
|
|
s, _ := SeatNamed(SMBServerSeat)
|
|
for _, v := range s.Serves {
|
|
if v.Name != "adopt" {
|
|
continue
|
|
}
|
|
props, _ := v.Input["properties"].(map[string]any)
|
|
confirm, _ := props["confirm"].(map[string]any)
|
|
if confirm == nil || confirm["enum"] == nil || confirm["type"] != "string" {
|
|
t.Errorf("adopt has no string confirm switch: %v", v.Input)
|
|
}
|
|
for _, says := range []string{"Without confirm, says what it would do and changes nothing", "dated copy", "no share disappears"} {
|
|
if !strings.Contains(v.Description, says) {
|
|
t.Errorf("adopt does not say %q: %s", says, v.Description)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
t.Error("node-smb-server has no adopt")
|
|
}
|
|
|
|
// A holder serving every verb holds the seat; a verb too many, one too few or the mesh's scope is refused,
|
|
// as the catalogue's smb-server module claims it.
|
|
func TestAHolderOfTheSMBSeatServesEveryVerbAndNothingElse(t *testing.T) {
|
|
seat, _ := SeatNamed(SMBServerSeat)
|
|
verbs := []string{"shares", "sessions", "test", "reload", "adopt"}
|
|
holder := Manifest{Module: "smb-server", Version: "1",
|
|
Claims: []Claim{{Name: SMBServerSeat, Scope: ScopeNode, Serves: verbs}}}
|
|
if err := CanHold(holder, seat); err != nil {
|
|
t.Errorf("smb-server serving every verb is refused: %v", err)
|
|
}
|
|
short := holder
|
|
short.Claims = []Claim{{Name: SMBServerSeat, Scope: ScopeNode, Serves: verbs[:4]}}
|
|
if err := CanHold(short, seat); err == nil || !strings.Contains(err.Error(), "adopt") {
|
|
t.Errorf("leaving adopt out was accepted: %v", err)
|
|
}
|
|
mesh := holder
|
|
mesh.Claims = []Claim{{Name: SMBServerSeat, Scope: ScopeMesh, Serves: verbs}}
|
|
if err := CanHold(mesh, seat); err == nil {
|
|
t.Error("claiming a node seat at the mesh's scope was accepted")
|
|
}
|
|
}
|
|
|
|
// node-nfs-server's adopt clears sharenfs only once the mesh's export covers every client the property
|
|
// exported to, the local network included (ADR 0341 clause 10), and exports names the local-network grant.
|
|
func TestTheNFSVerbsSayTheLocalNetworkGrant(t *testing.T) {
|
|
s, _ := SeatNamed(NFSServerSeat)
|
|
for _, v := range s.Serves {
|
|
switch v.Name {
|
|
case "adopt":
|
|
if !strings.Contains(v.Description, "covers every client the property exported to") {
|
|
t.Errorf("nfs adopt does not wait for the export to cover every client: %s", v.Description)
|
|
}
|
|
case "exports":
|
|
if !strings.Contains(v.Description, "local-network") {
|
|
t.Errorf("nfs exports does not say the local-network grant: %s", v.Description)
|
|
}
|
|
}
|
|
}
|
|
}
|