package inventory // A carried peer is nameable (novox/hq issue 112): the operator states which machine a carried // address is, the mesh answers for the name until the machine enrols, and enrolment verifies the // statement rather than silently renaming it. import ( "strings" "testing" ) func TestACarriedPeerIsNamedAndTheRegistrySaysSo(t *testing.T) { inv := fresh(t) anAdoptedHub(t, inv) if err := inv.NamePeer(t.Context(), "192.0.2.2", "home-server"); err != nil { t.Fatal(err) } carried, err := inv.CarriedPeers(t.Context()) if err != nil { t.Fatal(err) } byKey := map[string]CarriedPeer{} for _, c := range carried { byKey[c.PublicKey] = c } if byKey[peerTwo].Named != "home-server" || byKey[peerThree].Named != "" { t.Fatalf("the statement was not recorded where it was made: %+v", carried) } } func TestNamingRefusesWhatWouldCollide(t *testing.T) { inv := fresh(t) anAdoptedHub(t, inv) if err := inv.NamePeer(t.Context(), "192.0.2.9", "ghost"); err == nil || !strings.Contains(err.Error(), "no carried peer") { t.Fatalf("naming an address nothing carries must refuse; got %v", err) } if err := inv.NamePeer(t.Context(), "192.0.2.2", "anchor"); err == nil || !strings.Contains(err.Error(), "node of this mesh") { t.Fatalf("naming a peer after a node must refuse; got %v", err) } if err := inv.NamePeer(t.Context(), "192.0.2.2", "home-server"); err != nil { t.Fatal(err) } if err := inv.NamePeer(t.Context(), "192.0.2.3", "home-server"); err == nil || !strings.Contains(err.Error(), "already named") { t.Fatalf("one machine per name; got %v", err) } } func TestEnrolmentUnderANamedKeyMustUseTheName(t *testing.T) { inv := fresh(t) anAdoptedHub(t, inv) if err := inv.NamePeer(t.Context(), "192.0.2.3", "home-server"); err != nil { t.Fatal(err) } // The wrong name is refused where the operator can read it… imposter, err := inv.AddNode(t.Context(), "some-other-name") if err != nil { t.Fatal(err) } if err := inv.RecordOverlayKey(t.Context(), imposter.ID, peerThree); err != nil { t.Fatal(err) } if _, err := inv.AssignAddress(t.Context(), imposter.ID, "192.0.2.0/24"); err == nil || !strings.Contains(err.Error(), `named "home-server"`) { t.Fatalf("enrolling a named peer under another name must refuse; got %v", err) } // …and the stated name enrols cleanly, keeping the carried address. named, err := inv.AddNode(t.Context(), "home-server") if err != nil { t.Fatal(err) } if err := inv.RecordOverlayKey(t.Context(), named.ID, peerThree); err != nil { t.Fatal(err) } address, err := inv.AssignAddress(t.Context(), named.ID, "192.0.2.0/24") if err != nil { t.Fatal(err) } if address != "192.0.2.3" { t.Fatalf("the named peer keeps its carried address; got %s", address) } if err := inv.NamePeer(t.Context(), "192.0.2.3", "renamed"); err == nil || !strings.Contains(err.Error(), "enrolled as") { t.Fatalf("an enrolled peer's name is the node's; got %v", err) } }