Skip to content

Commit bbd90b9

Browse files
Sowmya viswamSowmya viswam
authored andcommitted
Adding tests for syncing service endpoint and endpointslice to host
1 parent 1752433 commit bbd90b9

File tree

1 file changed

+133
-5
lines changed

1 file changed

+133
-5
lines changed

test/e2e/servicesync/servicesync.go

Lines changed: 133 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,84 @@ package servicesync
22

33
import (
44
"context"
5+
"fmt"
56
"time"
67

78
"github.com/loft-sh/vcluster/pkg/util/translate"
89
"github.com/loft-sh/vcluster/test/framework"
910
"github.com/onsi/ginkgo/v2"
11+
"github.com/onsi/gomega"
1012
appsv1 "k8s.io/api/apps/v1"
1113
corev1 "k8s.io/api/core/v1"
1214
kerrors "k8s.io/apimachinery/pkg/api/errors"
1315
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
16+
"k8s.io/apimachinery/pkg/util/intstr"
1417
"k8s.io/apimachinery/pkg/util/wait"
1518
"k8s.io/client-go/kubernetes"
1619
)
1720

18-
var _ = ginkgo.Describe("map services from host to virtual cluster and vice versa", func() {
19-
var f *framework.Framework
20-
21-
ginkgo.JustBeforeEach(func() {
22-
// use default framework
21+
var _ = ginkgo.Describe("Verify mapping and syncing of services and endpoints", ginkgo.Ordered, func() {
22+
var (
23+
f *framework.Framework
24+
testService *corev1.Service
25+
//nolint:staticcheck // SA1019: corev1.Endpoints is deprecated, but still required for compatibility
26+
testEndpoint *corev1.Endpoints
27+
serviceName = "test-service-sync"
28+
serviceNamespace = "default"
29+
endpointName = "test-service-sync"
30+
)
31+
ginkgo.BeforeAll(func() {
2332
f = framework.DefaultFramework
33+
testService = &corev1.Service{
34+
ObjectMeta: metav1.ObjectMeta{
35+
Name: serviceName,
36+
Namespace: serviceNamespace,
37+
},
38+
Spec: corev1.ServiceSpec{
39+
ClusterIP: "None",
40+
Ports: []corev1.ServicePort{
41+
{
42+
Name: "custom-port",
43+
Port: 8080,
44+
Protocol: corev1.ProtocolTCP,
45+
TargetPort: intstr.FromInt(5000),
46+
},
47+
},
48+
},
49+
}
50+
//nolint:staticcheck // SA1019: corev1.Endpoints is deprecated, but still required for compatibility
51+
testEndpoint = &corev1.Endpoints{
52+
ObjectMeta: metav1.ObjectMeta{
53+
Name: endpointName,
54+
Namespace: serviceNamespace,
55+
},
56+
//nolint:staticcheck // SA1019: corev1.Endpoints is deprecated, but still required for compatibility
57+
Subsets: []corev1.EndpointSubset{
58+
{
59+
Addresses: []corev1.EndpointAddress{
60+
{
61+
IP: "1.1.1.1",
62+
},
63+
},
64+
Ports: []corev1.EndpointPort{
65+
{
66+
Port: 5000,
67+
},
68+
},
69+
},
70+
},
71+
}
72+
})
73+
74+
ginkgo.AfterAll(func() {
75+
err := f.VClusterClient.CoreV1().Endpoints(serviceNamespace).Delete(f.Context, endpointName, metav1.DeleteOptions{})
76+
if err != nil && !kerrors.IsNotFound(err) {
77+
gomega.Expect(err).NotTo(gomega.HaveOccurred())
78+
}
79+
err = f.VClusterClient.CoreV1().Services(serviceNamespace).Delete(f.Context, serviceName, metav1.DeleteOptions{})
80+
if err != nil && !kerrors.IsNotFound(err) {
81+
gomega.Expect(err).NotTo(gomega.HaveOccurred())
82+
}
2483
})
2584

2685
ginkgo.It("Test service mapping", func() {
@@ -54,6 +113,75 @@ var _ = ginkgo.Describe("map services from host to virtual cluster and vice vers
54113
checkEndpointsSync(f.Context, f.VClusterClient, "test", "nginx", f.HostClient, f.VClusterNamespace, "nginx")
55114
})
56115
})
116+
117+
ginkgo.Context("Verify endpoint sync when endpoint is deployed before service", func() {
118+
ginkgo.It("Should sync Service, Endpoints, and EndpointSlice from vCluster to host cluster", func() {
119+
ginkgo.By("Create Service Endpoint in vCluster")
120+
_, err := f.VClusterClient.CoreV1().Endpoints(serviceNamespace).Create(f.Context, testEndpoint, metav1.CreateOptions{})
121+
framework.ExpectNoError(err)
122+
123+
ginkgo.By("Create Service in vCluster")
124+
_, err = f.VClusterClient.CoreV1().Services(serviceNamespace).Create(f.Context, testService, metav1.CreateOptions{})
125+
framework.ExpectNoError(err)
126+
127+
ginkgo.By("Verify Endpoint exists in vCluster")
128+
_, err = f.VClusterClient.CoreV1().Endpoints(serviceNamespace).Get(f.Context, endpointName, metav1.GetOptions{})
129+
framework.ExpectNoError(err)
130+
131+
ginkgo.By("Verify Service exists in vCluster")
132+
_, err = f.VClusterClient.CoreV1().Services(serviceNamespace).Get(f.Context, serviceName, metav1.GetOptions{})
133+
framework.ExpectNoError(err)
134+
135+
ginkgo.By("Verify EndpointSlice exists in vCluster")
136+
gomega.Eventually(func(g gomega.Gomega) {
137+
vclusterEndpointSlice, err := f.VClusterClient.DiscoveryV1().EndpointSlices(serviceNamespace).List(f.Context, metav1.ListOptions{
138+
LabelSelector: fmt.Sprintf("kubernetes.io/service-name=%s", serviceName),
139+
})
140+
g.Expect(err).NotTo(gomega.HaveOccurred())
141+
g.Expect(vclusterEndpointSlice.Items).To(gomega.HaveLen(1))
142+
}).WithPolling(time.Second).WithTimeout(framework.PollTimeout).Should(gomega.Succeed())
143+
144+
translatedServiceName := translate.SingleNamespaceHostName(serviceName, serviceNamespace, translate.VClusterName)
145+
146+
ginkgo.By("Verify Service exists in Host Cluster")
147+
gomega.Eventually(func(g gomega.Gomega) {
148+
hostService, err := f.HostClient.CoreV1().Services(f.VClusterNamespace).Get(f.Context, translatedServiceName, metav1.GetOptions{})
149+
g.Expect(err).NotTo(gomega.HaveOccurred())
150+
g.Expect(hostService.Spec.Ports).To(gomega.HaveLen(1))
151+
if len(hostService.Spec.Ports) > 0 {
152+
g.Expect(hostService.Spec.Ports[0].Name).To(gomega.Equal("custom-port"))
153+
g.Expect(hostService.Spec.Ports[0].Port).To(gomega.Equal(int32(8080)))
154+
}
155+
}).WithPolling(time.Second).WithTimeout(framework.PollTimeout).Should(gomega.Succeed())
156+
157+
ginkgo.By("Verify Endpoint exists in Host Cluster")
158+
gomega.Eventually(func(g gomega.Gomega) {
159+
hostEndpoint, err := f.HostClient.CoreV1().Endpoints(f.VClusterNamespace).Get(f.Context, translatedServiceName, metav1.GetOptions{})
160+
g.Expect(err).NotTo(gomega.HaveOccurred())
161+
g.Expect(hostEndpoint.Subsets).To(gomega.HaveLen(1))
162+
if len(hostEndpoint.Subsets) > 0 {
163+
g.Expect(hostEndpoint.Subsets[0].Addresses).To(gomega.HaveLen(1))
164+
if len(hostEndpoint.Subsets[0].Addresses) > 0 {
165+
g.Expect(hostEndpoint.Subsets[0].Addresses[0].IP).To(gomega.Equal("1.1.1.1"))
166+
}
167+
g.Expect(hostEndpoint.Subsets[0].Ports).To(gomega.HaveLen(1))
168+
if len(hostEndpoint.Subsets[0].Ports) > 0 {
169+
g.Expect(hostEndpoint.Subsets[0].Ports[0].Port).To(gomega.Equal(int32(5000)))
170+
}
171+
}
172+
}).WithPolling(time.Second).WithTimeout(framework.PollTimeout).Should(gomega.Succeed())
173+
174+
ginkgo.By("Verify EndpointSlice exists in Host Cluster")
175+
gomega.Eventually(func(g gomega.Gomega) {
176+
hostEndpointSlice, err := f.HostClient.DiscoveryV1().EndpointSlices(f.VClusterNamespace).List(f.Context, metav1.ListOptions{
177+
LabelSelector: fmt.Sprintf("kubernetes.io/service-name=%s", translatedServiceName),
178+
})
179+
g.Expect(err).NotTo(gomega.HaveOccurred())
180+
g.Expect(hostEndpointSlice.Items).To(gomega.HaveLen(1))
181+
}).WithPolling(time.Second).WithTimeout(framework.PollTimeout).Should(gomega.Succeed())
182+
183+
})
184+
})
57185
})
58186

59187
func testMapping(ctx context.Context, fromClient kubernetes.Interface, fromNamespace, fromName string, toClient kubernetes.Interface, toNamespace, toName string, checkEndpoints bool) {

0 commit comments

Comments
 (0)