package web import ( "log" "net/http" "net/url" "strings" "testing" "gitea.dooplex.hu/admin/felhom-hub/internal/store" ) // R-276 (hub half): deleting a host removes its WireGuard peer row AND asks the peer-sync reconciler for // an immediate full-list push (the seam is SetWGPeerSync — no SSH, no ep0), so the endpoint stops // accepting the uninstalled box's tunnel now. The log says the push was REQUESTED, never "removed". // RED-PROOF: drop s.requestWGPeerPush() from handleHostDelete → triggers = 0 → FAIL. func TestR276_HostDeleteRemovesPeerAndPushes(t *testing.T) { s, st := newTestServer(t) var logBuf strings.Builder s.logger = log.New(&logBuf, "", 0) triggers := 0 s.SetWGPeerSync(func() { triggers++ }) if err := st.UpsertHost(&store.Host{HostID: "gone-1", CustomerID: "c9", APIKey: "k"}); err != nil { t.Fatal(err) } if err := st.SetWGEndpoint(&store.WGEndpoint{EndpointID: "ep0", DNSName: "ep0.example", WGPort: 51820, ServerPubkey: "srv", TunnelSubnet: "10.77.0.0/24", PBSTunnelIP: "10.77.0.1"}); err != nil { t.Fatal(err) } if _, _, err := st.AddWGPeer("pk-gone-1", "gone-1", "test"); err != nil { t.Fatal(err) } rr := postHostDelete(t, s, "gone-1", url.Values{"confirm_host_id": {"gone-1"}}) if rr.Code != http.StatusSeeOther { t.Fatalf("delete = %d (%s)", rr.Code, rr.Body.String()) } peers, err := st.ListWGPeers() if err != nil { t.Fatal(err) } for _, p := range peers { if p.HostID == "gone-1" || p.Pubkey == "pk-gone-1" { t.Fatal("the deleted host's WireGuard peer is still registered") } } if triggers != 1 { t.Fatalf("WG peer-sync triggers = %d, want 1 (the endpoint must drop the peer now, not on the next tick)", triggers) } if !strings.Contains(logBuf.String(), "WG peer removal push requested") { t.Errorf("the delete line must name the pending push:\n%s", logBuf.String()) } }