101 lines
2.8 KiB
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)
|
|
}
|
|
}
|