package app import "testing" func TestDetectTransportDestinationLockConflicts(t *testing.T) { current := []TransportPolicyIntent{ {SelectorType: "cidr", SelectorValue: "10.1.0.0/24", ClientID: "c1"}, } next := []TransportPolicyIntent{ {SelectorType: "cidr", SelectorValue: "10.1.0.0/24", ClientID: "c2"}, } locks := TransportOwnerLockState{ Items: []TransportOwnerLockRecord{ {DestinationIP: "10.1.0.11", ClientID: "c1"}, {DestinationIP: "10.9.0.11", ClientID: "c1"}, }, } conflicts := detectTransportDestinationLockConflicts(current, next, locks) if len(conflicts) != 1 { t.Fatalf("expected 1 conflict, got %d (%#v)", len(conflicts), conflicts) } if conflicts[0].Type != "destination_lock" { t.Fatalf("unexpected conflict type: %q", conflicts[0].Type) } } func TestDetectTransportDestinationLockConflictsDomainFromCache(t *testing.T) { prevLoader := transportPolicyLoadDomainCacheState t.Cleanup(func() { transportPolicyLoadDomainCacheState = prevLoader }) cache := newDomainCacheState() cache.set("example.com", domainCacheSourceDirect, []string{"1.1.1.1"}, 1) transportPolicyLoadDomainCacheState = func(path string, logf func(string, ...any)) domainCacheState { return cache } current := []TransportPolicyIntent{ {SelectorType: "domain", SelectorValue: "example.com", ClientID: "c1"}, } next := []TransportPolicyIntent{ {SelectorType: "domain", SelectorValue: "example.com", ClientID: "c2"}, } locks := TransportOwnerLockState{ Items: []TransportOwnerLockRecord{ {DestinationIP: "1.1.1.1", ClientID: "c1"}, }, } conflicts := detectTransportDestinationLockConflicts(current, next, locks) if len(conflicts) != 1 { t.Fatalf("expected 1 conflict for domain selector, got %#v", conflicts) } if conflicts[0].Type != "destination_lock" { t.Fatalf("unexpected conflict type: %q", conflicts[0].Type) } } func TestDetectTransportDestinationLockConflictsWildcardDomainFromCache(t *testing.T) { prevLoader := transportPolicyLoadDomainCacheState t.Cleanup(func() { transportPolicyLoadDomainCacheState = prevLoader }) cache := newDomainCacheState() cache.set("api.example.com", domainCacheSourceWildcard, []string{"2.2.2.2"}, 1) cache.set("cdn.example.com", domainCacheSourceDirect, []string{"2.2.2.3"}, 1) transportPolicyLoadDomainCacheState = func(path string, logf func(string, ...any)) domainCacheState { return cache } current := []TransportPolicyIntent{ {SelectorType: "domain", SelectorValue: "*.example.com", ClientID: "c1"}, } next := []TransportPolicyIntent{ {SelectorType: "domain", SelectorValue: "*.example.com", ClientID: "c2"}, } locks := TransportOwnerLockState{ Items: []TransportOwnerLockRecord{ {DestinationIP: "2.2.2.2", ClientID: "c1"}, }, } conflicts := detectTransportDestinationLockConflicts(current, next, locks) if len(conflicts) != 1 { t.Fatalf("expected wildcard conflict, got %#v", conflicts) } } func TestDetectTransportDestinationLockConflictsSkipsDomainWithoutCacheHit(t *testing.T) { prevLoader := transportPolicyLoadDomainCacheState t.Cleanup(func() { transportPolicyLoadDomainCacheState = prevLoader }) cache := newDomainCacheState() cache.set("example.com", domainCacheSourceDirect, []string{"9.9.9.9"}, 1) transportPolicyLoadDomainCacheState = func(path string, logf func(string, ...any)) domainCacheState { return cache } current := []TransportPolicyIntent{ {SelectorType: "domain", SelectorValue: "example.com", ClientID: "c1"}, } next := []TransportPolicyIntent{ {SelectorType: "domain", SelectorValue: "example.com", ClientID: "c2"}, } locks := TransportOwnerLockState{ Items: []TransportOwnerLockRecord{ {DestinationIP: "1.1.1.1", ClientID: "c1"}, }, } conflicts := detectTransportDestinationLockConflicts(current, next, locks) if len(conflicts) != 0 { t.Fatalf("expected no conflicts for domain selector without cache hit, got %#v", conflicts) } }