Files
elmprodvpn/selective-vpn-api/app/transport_handlers_policy_ownership_test.go

101 lines
2.8 KiB
Go

package app
import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
)
func TestHandleTransportOwnershipRebuildsOnPlanDigestDrift(t *testing.T) {
withTransportPolicyMutationTestPaths(t)
policy := TransportPolicyState{
Version: transportStateVersion,
Revision: 17,
Intents: []TransportPolicyIntent{
{SelectorType: "domain", SelectorValue: "demo.invalid", ClientID: "sg-a", Priority: 100, Mode: "strict"},
},
}
if err := saveTransportPolicyState(policy); err != nil {
t.Fatalf("save policy: %v", err)
}
clients := transportClientsState{
Version: transportStateVersion,
Items: []TransportClient{
{
ID: "sg-a",
Kind: TransportClientSingBox,
IfaceID: "shared",
RoutingTable: "agvpn_sg_a",
MarkHex: "0x110",
PriorityBase: 13250,
Enabled: true,
Status: TransportClientUp,
},
},
}
if err := saveTransportClientsState(clients); err != nil {
t.Fatalf("save clients: %v", err)
}
plan, conflicts := compileTransportPolicyPlan(policy.Intents, clients.Items, policy.Revision)
if len(conflicts) > 0 {
t.Fatalf("unexpected compile conflicts: %#v", conflicts)
}
if err := saveTransportPolicyCompilePlan(plan); err != nil {
t.Fatalf("save plan: %v", err)
}
legacyOwners := TransportOwnershipState{
Version: transportStateVersion,
PolicyRevision: policy.Revision,
PlanDigest: "legacy-digest",
Items: []TransportOwnershipRecord{
{
Key: "domain:demo.invalid",
SelectorType: "domain",
SelectorValue: "demo.invalid",
ClientID: "sg-a",
IfaceID: "shared",
},
},
}
if err := saveTransportOwnershipState(legacyOwners); err != nil {
t.Fatalf("save owners: %v", err)
}
req := httptest.NewRequest(http.MethodGet, "/api/v1/transport/owners", nil)
rec := httptest.NewRecorder()
handleTransportOwnership(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("unexpected status: %d body=%s", rec.Code, rec.Body.String())
}
var resp TransportOwnershipResponse
if err := json.Unmarshal(rec.Body.Bytes(), &resp); err != nil {
t.Fatalf("decode response: %v", err)
}
expectedDigest := digestTransportPolicyCompilePlan(plan)
if resp.PlanDigest != expectedDigest {
t.Fatalf("unexpected response plan_digest: got=%q want=%q", resp.PlanDigest, expectedDigest)
}
if len(resp.Items) != 1 {
t.Fatalf("unexpected ownership response items: %d", len(resp.Items))
}
if resp.Items[0].OwnerScope == "" {
t.Fatalf("expected owner_scope in response item: %#v", resp.Items[0])
}
rebuilt := loadTransportOwnershipState()
if rebuilt.PlanDigest != expectedDigest {
t.Fatalf("ownership state plan_digest not rebuilt: got=%q want=%q", rebuilt.PlanDigest, expectedDigest)
}
if len(rebuilt.Items) != 1 || rebuilt.Items[0].OwnerScope == "" {
t.Fatalf("ownership state did not rebuild owner_scope: %#v", rebuilt.Items)
}
}