Skip to content

Commit 9ae05f0

Browse files
committed
Ensure first cluster exports service before second cluster
...in two cluster conformance tests. Previously, the tests exported the first cluster in JustBeforeEach but that was executed after the JustBeforeEach in the twoClusterTestDriver so the second cluster was actually exported first. In addition, the verification of service type was put back in for the service type conflict conformance test. This had been removed by #119. To make the conflict resolution deterministic for an implementation that uses the first observed ServiceExport, the test setup now ensures the ServiceImport is created before deploying on the second cluster. Signed-off-by: Tom Pantelis <tompantelis@gmail.com>
1 parent 398bcaa commit 9ae05f0

File tree

6 files changed

+32
-42
lines changed

6 files changed

+32
-42
lines changed

conformance/clusterip_service_dns.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,6 @@ import (
3232
var _ = Describe("", Label(OptionalLabel, DNSLabel, ClusterIPLabel), func() {
3333
t := newTestDriver()
3434

35-
JustBeforeEach(func() {
36-
t.createServiceExport(&clients[0], newHelloServiceExport())
37-
})
38-
3935
Specify("A DNS lookup of the <service>.<ns>.svc.clusterset.local domain for a ClusterIP service should resolve to the "+
4036
"clusterset IP", func() {
4137
AddReportEntry(SpecRefReportEntry, "https://github.com/kubernetes/enhancements/tree/master/keps/sig-multicluster/1645-multi-cluster-services-api#dns")

conformance/conformance_suite.go

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,11 @@ func setupClients() error {
144144
}
145145

146146
type testDriver struct {
147-
namespace string
148-
helloService *corev1.Service
149-
helloDeployment *appsv1.Deployment
150-
requestPod *corev1.Pod
147+
namespace string
148+
helloService *corev1.Service
149+
helloDeployment *appsv1.Deployment
150+
requestPod *corev1.Pod
151+
autoExportService bool
151152
}
152153

153154
func newTestDriver() *testDriver {
@@ -158,6 +159,7 @@ func newTestDriver() *testDriver {
158159
t.helloService = newHelloService()
159160
t.helloDeployment = newHelloDeployment()
160161
t.requestPod = newRequestPod()
162+
t.autoExportService = true
161163
})
162164

163165
JustBeforeEach(func() {
@@ -178,6 +180,10 @@ func newTestDriver() *testDriver {
178180
for _, client := range clients {
179181
t.startRequestPod(ctx, client)
180182
}
183+
184+
if t.autoExportService {
185+
t.createServiceExport(&clients[0], newHelloServiceExport())
186+
}
181187
})
182188

183189
AfterEach(func() {
@@ -353,11 +359,21 @@ func newTwoClusterTestDriver(t *testDriver) *twoClusterTestDriver {
353359

354360
tt.helloService2 = newHelloService()
355361
tt.helloServiceExport2 = newHelloServiceExport()
362+
t.autoExportService = false
356363
})
357364

358365
JustBeforeEach(func() {
366+
t.createServiceExport(&clients[0], newHelloServiceExport())
367+
368+
// The conflict resolution policy in the MCS spec (KEP 1645) allows an implementation to favor maintaining
369+
// service continuity and avoiding potentially disruptive changes, as such, an implementation may choose the
370+
// first observed exported service when resolving conflicts. To support this, verify the ServiceImport is
371+
// created on the first cluster prior to deploying on the second cluster.
372+
t.awaitServiceImport(&clients[0], helloServiceName, false, nil)
373+
359374
// Delay a little before deploying on the second cluster to ensure the first cluster's ServiceExport timestamp
360-
// is older so conflict checking is deterministic. Make the delay at least 1 sec as creation timestamps have seconds granularity.
375+
// is older so conflict checking is deterministic for implementations that use the timestamp when resolving conflicts.
376+
// Make the delay at least 1 sec as creation timestamps have seconds granularity.
361377
time.Sleep(1100 * time.Millisecond)
362378

363379
t.deployHelloService(&clients[1], tt.helloService2)

conformance/connectivity.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ import (
2929
var _ = Describe("", func() {
3030
t := newTestDriver()
3131

32+
BeforeEach(func() {
33+
t.autoExportService = false
34+
})
35+
3236
Context("Connectivity to a service that is not exported", func() {
3337
It("should be inaccessible", Label(RequiredLabel), func() {
3438
AddReportEntry(SpecRefReportEntry, "https://github.com/kubernetes/enhancements/tree/master/keps/sig-multicluster/1645-multi-cluster-services-api#exporting-services")

conformance/endpoint_slice.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,6 @@ const K8sEndpointSliceManagedByName = "endpointslice-controller.k8s.io"
3434
var _ = Describe("", Label(OptionalLabel, EndpointSliceLabel), func() {
3535
t := newTestDriver()
3636

37-
JustBeforeEach(func() {
38-
t.createServiceExport(&clients[0], newHelloServiceExport())
39-
})
40-
4137
Specify("Exporting a service should create an MCS EndpointSlice in the service's namespace in each cluster with the "+
4238
"required MCS labels. Unexporting should delete the EndpointSlice.", func() {
4339
AddReportEntry(SpecRefReportEntry, "https://github.com/kubernetes/enhancements/tree/master/keps/sig-multicluster/1645-multi-cluster-services-api#using-endpointslice-objects-to-track-endpoints")

conformance/headless_service_dns.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,6 @@ var _ = Describe("", Label(OptionalLabel, DNSLabel, HeadlessLabel), func() {
4545
t.helloDeployment.Spec.Replicas = ptr.To(int32(replicas))
4646
})
4747

48-
JustBeforeEach(func() {
49-
t.createServiceExport(&clients[0], newHelloServiceExport())
50-
})
51-
5248
Specify("A DNS query of the <service>.<ns>.svc.clusterset.local domain for a headless service should return the "+
5349
"ready endpoint addresses of all the backing pods", func() {
5450
AddReportEntry(SpecRefReportEntry, "https://github.com/kubernetes/enhancements/tree/master/keps/sig-multicluster/1645-multi-cluster-services-api#dns")

conformance/service_import.go

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,6 @@ func testGeneralServiceImport() {
4444
helloServiceExport = newHelloServiceExport()
4545
})
4646

47-
JustBeforeEach(func() {
48-
t.createServiceExport(&clients[0], helloServiceExport)
49-
})
50-
5147
assertHasKeyValues := func(g Gomega, actual, expected map[string]string) {
5248
for k, v := range expected {
5349
g.Expect(actual).To(HaveKeyWithValue(k, v), reportNonConformant(""))
@@ -148,17 +144,8 @@ func testGeneralServiceImport() {
148144
}
149145

150146
func testClusterIPServiceImport() {
151-
var helloServiceExport *v1alpha1.ServiceExport
152147
t := newTestDriver()
153148

154-
BeforeEach(func() {
155-
helloServiceExport = newHelloServiceExport()
156-
})
157-
158-
JustBeforeEach(func() {
159-
t.createServiceExport(&clients[0], helloServiceExport)
160-
})
161-
162149
Specify("Exporting a ClusterIP service should create a ServiceImport of type ClusterSetIP in the service's namespace in each cluster. "+
163150
"Unexporting should delete the ServiceImport", Label(RequiredLabel), func() {
164151
AddReportEntry(SpecRefReportEntry, "https://github.com/kubernetes/enhancements/tree/master/keps/sig-multicluster/1645-multi-cluster-services-api#importing-services")
@@ -267,10 +254,6 @@ func testHeadlessServiceImport() {
267254
t.helloService.Spec.ClusterIP = corev1.ClusterIPNone
268255
})
269256

270-
JustBeforeEach(func() {
271-
t.createServiceExport(&clients[0], newHelloServiceExport())
272-
})
273-
274257
Specify("Exporting a headless service should create a ServiceImport of type Headless in the service's namespace in each cluster. "+
275258
"Unexporting should delete the ServiceImport", Label(RequiredLabel), func() {
276259
AddReportEntry(SpecRefReportEntry, "https://github.com/kubernetes/enhancements/tree/master/keps/sig-multicluster/1645-multi-cluster-services-api#service-types")
@@ -309,10 +292,6 @@ func testExternalNameService() {
309292
t.helloService.Spec.ExternalName = "example.com"
310293
})
311294

312-
JustBeforeEach(func() {
313-
t.createServiceExport(&clients[0], newHelloServiceExport())
314-
})
315-
316295
Specify("Exporting an ExternalName service should set ServiceExport Valid condition to False", Label(RequiredLabel), func() {
317296
AddReportEntry(SpecRefReportEntry, "https://github.com/kubernetes/enhancements/blob/master/keps/sig-multicluster/1645-multi-cluster-services-api/README.md#service-types")
318297

@@ -329,15 +308,18 @@ func testServiceTypeConflict() {
329308
t.helloService2.Spec.ClusterIP = corev1.ClusterIPNone
330309
})
331310

332-
JustBeforeEach(func() {
333-
t.createServiceExport(&clients[0], newHelloServiceExport())
334-
})
335-
336311
Specify("A service exported on two clusters with conflicting headlessness should apply the conflict resolution policy and "+
337312
"report a Conflict condition on the ServiceExport", Label(RequiredLabel), func() {
338313
AddReportEntry(SpecRefReportEntry, "https://github.com/kubernetes/enhancements/tree/master/keps/sig-multicluster/1645-multi-cluster-services-api#headlessness")
339314

340315
t.awaitServiceExportCondition(&clients[0], v1alpha1.ServiceExportConditionConflict, metav1.ConditionTrue)
341316
t.awaitServiceExportCondition(&clients[1], v1alpha1.ServiceExportConditionConflict, metav1.ConditionTrue)
317+
318+
for i := range clients {
319+
serviceImport := t.awaitServiceImport(&clients[i], helloServiceName, true, nil)
320+
321+
Expect(serviceImport.Spec.Type).To(Equal(v1alpha1.ClusterSetIP), reportNonConformant(
322+
fmt.Sprintf("ServiceImport on cluster %q has type %q", clients[i].name, serviceImport.Spec.Type)))
323+
}
342324
})
343325
}

0 commit comments

Comments
 (0)