package catalogue import ( "strings" "testing" ) // Defends novox/hq ADR 0247: a machine's own resolver is a node seat, held only where something requires // `split-dns`; where it is held it writes the resolver file and the uplink's holder steps back from it. // The seat: node-scoped, decided by ADR 0247, and its three verbs required of every holder — a holder // exists only once the module serving them does, so nothing has to be optional while it catches up. func TestTheMachinesOwnResolverIsANodeSeatWithItsVerbs(t *testing.T) { s, ok := SeatNamed(ResolverSeat) if !ok { t.Fatalf("%s is not in the mesh's set", ResolverSeat) } if s.Scope != ScopeNode || s.Decision != "novox/hq ADR 0247" || s.Delivers != "" || s.Replicated { t.Errorf("%s is %+v; a node seat under ADR 0247 that delivers nothing", ResolverSeat, 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", ResolverSeat, 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", ResolverSeat, v.Name) } } if strings.Join(got, " ") != "routes route unroute" { t.Errorf("%s serves %v, not routes, route and unroute", ResolverSeat, got) } // The verbs name a link, domains and servers, and never a VPN: the resolver knows nothing of one. for _, v := range s.Serves { if strings.Contains(strings.ToLower(v.Description), "forti") { t.Errorf("%s.%s names a VPN client: %s", ResolverSeat, v.Name, v.Description) } } }