Skip to content

Commit

Permalink
Unit tests prefixed SE and migration
Browse files Browse the repository at this point in the history
  • Loading branch information
Punakshi committed Sep 3, 2024
1 parent ab4f603 commit c97d693
Show file tree
Hide file tree
Showing 3 changed files with 277 additions and 2 deletions.
141 changes: 141 additions & 0 deletions admiral/pkg/clusters/configwriter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,62 @@ func createMockServiceEntry(env string, identity string, endpointAddress string,
return serviceEntry
}

func createMockServiceEntryWithTwoEndpoints(env string, identity string, endpointAddress string, endpointPort int, exportTo []string) networkingV1Alpha3.ServiceEntry {
serviceEntry := networkingV1Alpha3.ServiceEntry{
Hosts: []string{env + "." + strings.ToLower(identity) + ".mesh"},
Addresses: nil,
Ports: []*networkingV1Alpha3.ServicePort{{Number: uint32(common.DefaultServiceEntryPort), Name: util.Http, Protocol: util.Http}},
Location: 1,
Resolution: 2,
Endpoints: []*networkingV1Alpha3.WorkloadEntry{{Address: endpointAddress,
Locality: "us-west-2",
Ports: map[string]uint32{"http": uint32(endpointPort)},
Labels: map[string]string{"security.istio.io/tlsMode": "istio", "type": "rollout"}},
{
Address: "def-elb.us-east-2.elb.amazonaws.com.",
Locality: "us-east-2",
Ports: map[string]uint32{"http": uint32(15443)},
Labels: map[string]string{"security.istio.io/tlsMode": "istio", "type": "rollout"},
}},
WorkloadSelector: nil,
ExportTo: exportTo,
SubjectAltNames: []string{"spiffe://prefix/" + identity},
}
return serviceEntry
}

func createMockServiceEntryWithTwoLocalEndpoints(env string, identity string, endpointAddress1, endpointAddress2 string, endpointPort int, exportTo []string) networkingV1Alpha3.ServiceEntry {
serviceEntry := networkingV1Alpha3.ServiceEntry{
Hosts: []string{env + "." + strings.ToLower(identity) + ".mesh"},
Addresses: nil,
Ports: []*networkingV1Alpha3.ServicePort{{Number: uint32(common.DefaultServiceEntryPort), Name: util.Http, Protocol: util.Http}},
Location: 1,
Resolution: 2,
Endpoints: []*networkingV1Alpha3.WorkloadEntry{
{
Address: endpointAddress1,
Locality: "us-west-2",
Ports: map[string]uint32{"http": uint32(endpointPort)},
Labels: map[string]string{"security.istio.io/tlsMode": "istio", "type": "rollout"}},
{
Address: endpointAddress2,
Locality: "us-west-2",
Ports: map[string]uint32{"http": uint32(endpointPort)},
Labels: map[string]string{"security.istio.io/tlsMode": "istio", "type": "deployment"}},
{
Address: "def-elb.us-east-2.elb.amazonaws.com.",
Locality: "us-east-2",
Ports: map[string]uint32{"http": uint32(15443)},
Labels: map[string]string{"security.istio.io/tlsMode": "istio", "type": "rollout"},
}},
WorkloadSelector: nil,
ExportTo: exportTo,
SubjectAltNames: []string{"spiffe://prefix/" + identity},
}
sort.Sort(WorkloadEntrySorted(serviceEntry.Endpoints))
return serviceEntry
}

func TestGetIngressEndpoints(t *testing.T) {
identityConfig := registry.GetSampleIdentityConfig("sample")
expectedIngressEndpoints := map[string]*networkingV1Alpha3.WorkloadEntry{
Expand Down Expand Up @@ -118,20 +174,23 @@ func TestGetServiceEntryEndpoints(t *testing.T) {
Ports: map[string]uint32{
"http": 8090,
},
Selectors: map[string]string{"app": "app1"},
},
"app-1-spk-desired-service": {
Name: "app-1-spk-desired-service",
Weight: 25,
Ports: map[string]uint32{
"http": 8090,
},
Selectors: map[string]string{"app": "app1"},
},
"app-1-spk-stable-service": {
Name: "app-1-spk-stable-service",
Weight: 75,
Ports: map[string]uint32{
"http": 8090,
},
Selectors: map[string]string{"app": "app1"},
},
}
weightedRollout := registry.GetSampleIdentityConfigEnvironment("e2e", "ns-1-usw2-e2e", "sample")
Expand Down Expand Up @@ -264,18 +323,21 @@ func TestGetServiceEntryEndpointsForCanaryAndBlueGreen(t *testing.T) {
Ports: map[string]uint32{
"http": 8090,
},
Selectors: map[string]string{"app": "app1"},
},
"desired": {
Name: "app-1-spk-desired-service",
Ports: map[string]uint32{
"http": 8090,
},
Selectors: map[string]string{"app": "app1"},
},
"stable": {
Name: "app-1-spk-stable-service",
Ports: map[string]uint32{
"http": 8090,
},
Selectors: map[string]string{"app": "app1"},
},
}
canaryRollout.Services = canaryServices
Expand All @@ -293,12 +355,14 @@ func TestGetServiceEntryEndpointsForCanaryAndBlueGreen(t *testing.T) {
Ports: map[string]uint32{
"http": 8090,
},
Selectors: map[string]string{"app": "app1"},
},
"active": {
Name: "app-1-spk-active-service",
Ports: map[string]uint32{
"http": 8090,
},
Selectors: map[string]string{"app": "app1"},
},
}
blueGreenRollout.Services = blueGreenServices
Expand Down Expand Up @@ -564,6 +628,83 @@ func TestBuildServiceEntriesFromIdentityConfig(t *testing.T) {
}
}

func TestBuildServiceEntriesFromIdentityConfig_MultipleEndpoints(t *testing.T) {
admiralParams := admiralParamsForConfigWriterTests()
common.ResetSync()
common.InitializeConfig(admiralParams)
rr, _ := InitAdmiralOperator(context.Background(), admiralParams)
ctxLogger := common.GetCtxLogger(context.Background(), "test", "")
identityConfig := registry.GetSampleIdentityConfigWithRemoteEndpoints("sample")
expectedLocalServiceEntryPRF := createMockServiceEntryWithTwoEndpoints("prf", "sample", "app-1-spk-root-service.ns-1-usw2-prf.svc.cluster.local.", 8090, []string{"istio-system", "ns-1-usw2-e2e", "ns-1-usw2-prf", "ns-1-usw2-qal"})
expectedLocalServiceEntryE2E := createMockServiceEntryWithTwoEndpoints("e2e", "sample", "app-1-spk-root-service.ns-1-usw2-e2e.svc.cluster.local.", 8090, []string{"istio-system", "ns-1-usw2-e2e", "ns-1-usw2-prf", "ns-1-usw2-qal"})
expectedLocalServiceEntryQAL := createMockServiceEntryWithTwoEndpoints("qal", "sample", "app-1-spk-root-service.ns-1-usw2-qal.svc.cluster.local.", 8090, []string{"istio-system", "ns-1-usw2-e2e", "ns-1-usw2-prf", "ns-1-usw2-qal"})
expectedLocalServiceEntries := []*networkingV1Alpha3.ServiceEntry{&expectedLocalServiceEntryQAL, &expectedLocalServiceEntryPRF, &expectedLocalServiceEntryE2E}

identityConfigForMigration := registry.GetSampleIdentityConfigWithRolloutAndDeployment("sample")
expectedLocalServiceEntryPRFForMigration := createMockServiceEntryWithTwoLocalEndpoints("prf", "sample", "app-1-spk-root-service.ns-1-usw2-prf.svc.cluster.local.", "app-1-spk-deploy-service.ns-1-usw2-prf.svc.cluster.local.", 8090, []string{"istio-system", "ns-1-usw2-e2e", "ns-1-usw2-prf", "ns-1-usw2-qal"})
expectedLocalServiceEntryE2EForMigration := createMockServiceEntryWithTwoLocalEndpoints("e2e", "sample", "app-1-spk-root-service.ns-1-usw2-e2e.svc.cluster.local.", "app-1-spk-deploy-service.ns-1-usw2-e2e.svc.cluster.local.", 8090, []string{"istio-system", "ns-1-usw2-e2e", "ns-1-usw2-prf", "ns-1-usw2-qal"})
expectedLocalServiceEntryQALForMigration := createMockServiceEntryWithTwoLocalEndpoints("qal", "sample", "app-1-spk-root-service.ns-1-usw2-qal.svc.cluster.local.", "app-1-spk-deploy-service.ns-1-usw2-qal.svc.cluster.local.", 8090, []string{"istio-system", "ns-1-usw2-e2e", "ns-1-usw2-prf", "ns-1-usw2-qal"})
expectedLocalServiceEntriesForMigration := []*networkingV1Alpha3.ServiceEntry{&expectedLocalServiceEntryQALForMigration, &expectedLocalServiceEntryPRFForMigration, &expectedLocalServiceEntryE2EForMigration}

testCases := []struct {
name string
clientCluster string
event admiral.EventType
identityConfig registry.IdentityConfig
expectedServiceEntries []*networkingV1Alpha3.ServiceEntry
expectedErr bool
}{
{
name: "Given information to build an se, " +
"When the client cluster is the same as the server cluster" +
"Then the constructed se should have local endpoint and a remote endpoint and istio-system in exportTo",
clientCluster: "cluster1",
event: admiral.Add,
identityConfig: identityConfig,
expectedServiceEntries: expectedLocalServiceEntries,
expectedErr: false,
},
{
name: "Given information to build an se has a rollout and deployment in the same namespace, " +
"When the client cluster is the same as the server cluster" +
"Then the constructed se should have 2 local endpoints and a remote endpoint and istio-system in exportTo",
clientCluster: "cluster1",
event: admiral.Add,
identityConfig: identityConfigForMigration,
expectedServiceEntries: expectedLocalServiceEntriesForMigration,
expectedErr: false,
},
}
for _, c := range testCases {
t.Run(c.name, func(t *testing.T) {
serviceEntryBuilder := ServiceEntryBuilder{ClientCluster: c.clientCluster, RemoteRegistry: rr}

serviceEntries, err := serviceEntryBuilder.BuildServiceEntriesFromIdentityConfig(ctxLogger, c.identityConfig)

if err != nil && !c.expectedErr {
t.Errorf("want=%v, \ngot=%v", nil, err)
}
opts := cmpopts.IgnoreUnexported(networkingV1Alpha3.ServiceEntry{}, networkingV1Alpha3.ServicePort{}, networkingV1Alpha3.WorkloadEntry{})
// sort the service entries by name
sort.Sort(ServiceEntryListSorterByHost(serviceEntries))
sort.Sort(ServiceEntryListSorterByHost(c.expectedServiceEntries))
if !cmp.Equal(serviceEntries, c.expectedServiceEntries, opts) {
t.Errorf("want=%v, \ngot=%v", c.expectedServiceEntries, serviceEntries)
}

})
}
}

// run the above test 100 times
func TestBenchmarkBuildServiceEntriesFromIdentityConfig(b *testing.T) {
sum := 1
for sum < 1000 {
TestBuildServiceEntriesFromIdentityConfig_MultipleEndpoints(b)
sum++
}
}

type ServiceEntryListSorterByHost []*networkingV1Alpha3.ServiceEntry

func (s ServiceEntryListSorterByHost) Len() int {
Expand Down
2 changes: 1 addition & 1 deletion admiral/pkg/controller/common/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func NewGaugeFrom(name string, help string) Gauge {
}
opts := prometheus.GaugeOpts{Name: name, Help: help}
g := prometheus.NewGauge(opts)
prometheus.MustRegister(g)
// prometheus.MustRegister(g) // https://github.com/prometheus/client_golang/issues/716
return &PromGauge{g}
}

Expand Down
136 changes: 135 additions & 1 deletion admiral/pkg/registry/testutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ func GetSampleIdentityConfigEnvironment(env string, namespace string, identity s
Namespace: namespace,
ServiceName: "app-1-spk-root-service",
Services: map[string]*RegistryServiceConfig{
"app-1-spk-root-service": {
"root": {
Name: "app-1-spk-root-service",
Weight: -1,
Ports: map[string]uint32{
"http": 8090,
},
Selectors: map[string]string{"app": "app1"},
},
},
Type: map[string]*TypeConfig{
Expand Down Expand Up @@ -119,3 +120,136 @@ func GetSampleIdentityConfig(identity string) IdentityConfig {
}
return identityConfig
}

func GetSampleIdentityConfigWithRemoteEndpoints(identity string) IdentityConfig {
prfEnv := GetSampleIdentityConfigEnvironment("prf", "ns-1-usw2-prf", identity)
e2eEnv := GetSampleIdentityConfigEnvironment("e2e", "ns-1-usw2-e2e", identity)
qalEnv := GetSampleIdentityConfigEnvironment("qal", "ns-1-usw2-qal", identity)
environments := map[string]*IdentityConfigEnvironment{
"prf": prfEnv,
"e2e": e2eEnv,
"qal": qalEnv,
}
clientAssets := map[string]string{
"sample": "sample",
}
cluster := IdentityConfigCluster{
Name: "cluster1",
Locality: "us-west-2",
IngressEndpoint: "abc-elb.us-west-2.elb.amazonaws.com.",
IngressPort: "15443",
IngressPortName: "http",
Environment: environments,
}
cluster2 := IdentityConfigCluster{
Name: "cluster2",
Locality: "us-east-2",
IngressEndpoint: "def-elb.us-east-2.elb.amazonaws.com.",
IngressPort: "15443",
IngressPortName: "http",
Environment: environments,
}
identityConfig := IdentityConfig{
IdentityName: identity,
Clusters: map[string]*IdentityConfigCluster{
"cluster1": &cluster,
"cluster2": &cluster2,
},
ClientAssets: clientAssets,
}
return identityConfig
}

func GetSampleIdentityConfigWithRolloutAndDeployment(identity string) IdentityConfig {
prfEnv := GetSampleIdentityConfigEnvironment("prf", "ns-1-usw2-prf", identity)
e2eEnv := GetSampleIdentityConfigEnvironment("e2e", "ns-1-usw2-e2e", identity)
qalEnv := GetSampleIdentityConfigEnvironment("qal", "ns-1-usw2-qal", identity)

prfEnv.Type["deployment"] = &TypeConfig{
Selectors: map[string]string{"deploy-app": "app1"},
}
prfEnv.Type["rollout"] = &TypeConfig{
Selectors: map[string]string{"app": "app1"},
}

e2eEnv.Type["deployment"] = &TypeConfig{
Selectors: map[string]string{"deploy-app": "app1"},
}
e2eEnv.Type["rollout"] = &TypeConfig{
Selectors: map[string]string{"app": "app1"},
}

qalEnv.Type["deployment"] = &TypeConfig{
Selectors: map[string]string{"deploy-app": "app1"},
}
qalEnv.Type["rollout"] = &TypeConfig{
Selectors: map[string]string{"app": "app1"},
}

services := map[string]*RegistryServiceConfig{
"deploysvc": {
Name: "app-1-spk-deploy-service",
Weight: -1,
Ports: map[string]uint32{
"http": 8090,
},
Selectors: map[string]string{"deploy-app": "app1"},
},
"root": {
Name: "app-1-spk-root-service",
Weight: -1,
Ports: map[string]uint32{
"http": 8090,
},
Selectors: map[string]string{"app": "app1"},
},
}

e2eEnv.Services = services
prfEnv.Services = services
qalEnv.Services = services
environments := map[string]*IdentityConfigEnvironment{
"prf": prfEnv,
"e2e": e2eEnv,
"qal": qalEnv,
}
clientAssets := map[string]string{
"sample": "sample",
}
cluster := IdentityConfigCluster{
Name: "cluster1",
Locality: "us-west-2",
IngressEndpoint: "abc-elb.us-west-2.elb.amazonaws.com.",
IngressPort: "15443",
IngressPortName: "http",
Environment: environments,
}

prfEnv1 := GetSampleIdentityConfigEnvironment("prf", "ns-1-usw2-prf", identity)
e2eEnv1 := GetSampleIdentityConfigEnvironment("e2e", "ns-1-usw2-e2e", identity)
qalEnv1 := GetSampleIdentityConfigEnvironment("qal", "ns-1-usw2-qal", identity)

environments1 := map[string]*IdentityConfigEnvironment{
"prf": prfEnv1,
"e2e": e2eEnv1,
"qal": qalEnv1,
}

cluster2 := IdentityConfigCluster{
Name: "cluster2",
Locality: "us-east-2",
IngressEndpoint: "def-elb.us-east-2.elb.amazonaws.com.",
IngressPort: "15443",
IngressPortName: "http",
Environment: environments1,
}
identityConfig := IdentityConfig{
IdentityName: identity,
Clusters: map[string]*IdentityConfigCluster{
"cluster1": &cluster,
"cluster2": &cluster2,
},
ClientAssets: clientAssets,
}
return identityConfig
}

0 comments on commit c97d693

Please sign in to comment.