Skip to content

Commit

Permalink
E2e to verify lighthouse return cluster-ip from healthy service
Browse files Browse the repository at this point in the history
E2e to verify lighthouse return cluster-ip from healthy service

Fixes: submariner-io/submariner#1041

Signed-off-by: Aswin Surayanarayanan <[email protected]>
  • Loading branch information
aswinsuryan authored Jan 15, 2021
1 parent 004455e commit 9be744d
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 0 deletions.
74 changes: 74 additions & 0 deletions test/e2e/discovery/service_discovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,29 @@ var _ = Describe("[discovery] Test Service Discovery Across Clusters", func() {
RunServiceDiscoveryRoundRobinTest(f)
})
})

When("one of the clusters with a service is not healthy", func() {
var healthCheckIP, endpointName string

BeforeEach(func() {
if len(framework.TestContext.ClusterIDs) < 3 {
Skip("Only two clusters are deployed and hence skipping the test")
return
}

randomIP := "192.168.1.5"
endpointName, healthCheckIP = f.GetHealthCheckIPInfo(framework.ClusterC)
f.SetHealthCheckIP(framework.ClusterC, randomIP, endpointName)
})

It("should not resolve that cluster's service IP", func() {
RunServicesClusterAvailabilityMutliClusterTest(f)
})

AfterEach(func() {
f.SetHealthCheckIP(framework.ClusterC, healthCheckIP, endpointName)
})
})
})

func RunServiceDiscoveryTest(f *lhframework.Framework) {
Expand Down Expand Up @@ -441,6 +464,57 @@ func RunServiceDiscoveryRoundRobinTest(f *lhframework.Framework) {
verifyRoundRobinWithDig(f.Framework, framework.ClusterA, nginxServiceClusterB.Name, serviceIPList, netshootPodList, checkedDomains)
}

func RunServicesClusterAvailabilityMutliClusterTest(f *lhframework.Framework) {
clusterBName := framework.TestContext.ClusterIDs[framework.ClusterB]
clusterCName := framework.TestContext.ClusterIDs[framework.ClusterC]

By(fmt.Sprintf("Creating an Nginx Deployment on on %q", clusterBName))
f.NewNginxDeployment(framework.ClusterB)
By(fmt.Sprintf("Creating a Nginx Service on %q", clusterBName))

nginxServiceClusterB := f.NewNginxService(framework.ClusterB)

f.AwaitGlobalnetIP(framework.ClusterB, nginxServiceClusterB.Name, nginxServiceClusterB.Namespace)
f.NewServiceExport(framework.ClusterB, nginxServiceClusterB.Name, nginxServiceClusterB.Namespace)

f.AwaitServiceExportedStatusCondition(framework.ClusterB, nginxServiceClusterB.Name, nginxServiceClusterB.Namespace)

By(fmt.Sprintf("Creating a Netshoot Deployment on %q", clusterCName))

netshootPodList := f.NewNetShootDeployment(framework.ClusterA)

svc, err := f.GetService(framework.ClusterB, nginxServiceClusterB.Name, nginxServiceClusterB.Namespace)
Expect(err).NotTo(HaveOccurred())

nginxServiceClusterB = svc
f.AwaitServiceImportIP(framework.ClusterA, nginxServiceClusterB)
f.AwaitEndpointSlices(framework.ClusterB, nginxServiceClusterB.Name, nginxServiceClusterB.Namespace, 1, 1)
f.AwaitEndpointSlices(framework.ClusterA, nginxServiceClusterB.Name, nginxServiceClusterB.Namespace, 1, 1)

By(fmt.Sprintf("Creating an Nginx Deployment on on %q", clusterCName))
f.NewNginxDeployment(framework.ClusterC)
By(fmt.Sprintf("Creating a Nginx Service on %q", clusterCName))

nginxServiceClusterC := f.NewNginxService(framework.ClusterC)

f.AwaitGlobalnetIP(framework.ClusterC, nginxServiceClusterC.Name, nginxServiceClusterC.Namespace)
f.NewServiceExport(framework.ClusterC, nginxServiceClusterC.Name, nginxServiceClusterC.Namespace)

f.AwaitServiceExportedStatusCondition(framework.ClusterC, nginxServiceClusterC.Name, nginxServiceClusterC.Namespace)

svc, err = f.GetService(framework.ClusterC, nginxServiceClusterC.Name, nginxServiceClusterC.Namespace)
Expect(err).NotTo(HaveOccurred())

nginxServiceClusterC = svc
f.AwaitServiceImportIP(framework.ClusterA, nginxServiceClusterC)
f.AwaitEndpointSlices(framework.ClusterA, nginxServiceClusterC.Name, nginxServiceClusterC.Namespace, 2, 2)

verifyServiceIpWithDig(f.Framework, framework.ClusterA, framework.ClusterB, nginxServiceClusterB, netshootPodList,
checkedDomains, "", true)
verifyServiceIpWithDig(f.Framework, framework.ClusterA, framework.ClusterC, nginxServiceClusterC, netshootPodList,
checkedDomains, "", false)
}

func verifyServiceIpWithDig(f *framework.Framework, srcCluster, targetCluster framework.ClusterIndex, service *corev1.Service,
targetPod *corev1.PodList, domains []string, clusterName string, shouldContain bool) {
var serviceIP string
Expand Down
60 changes: 60 additions & 0 deletions test/e2e/framework/framework.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ import (
"fmt"
"strings"

"k8s.io/client-go/dynamic"

"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
lhconstants "github.com/submariner-io/lighthouse/pkg/constants"
Expand Down Expand Up @@ -49,6 +54,7 @@ type Framework struct {
}

var MCSClients []*mcsClientset.Clientset
var EndpointClients []dynamic.ResourceInterface

func init() {
framework.AddBeforeSuite(beforeSuite)
Expand Down Expand Up @@ -76,6 +82,7 @@ func beforeSuite() {

for _, restConfig := range framework.RestConfigs {
MCSClients = append(MCSClients, createLighthouseClient(restConfig))
EndpointClients = append(EndpointClients, createEndpointClientSet(restConfig))
}

framework.DetectGlobalnet()
Expand All @@ -88,6 +95,18 @@ func createLighthouseClient(restConfig *rest.Config) *mcsClientset.Clientset {
return clientSet
}

func createEndpointClientSet(restConfig *rest.Config) dynamic.ResourceInterface {
clientSet, err := dynamic.NewForConfig(restConfig)
Expect(err).To(Not(HaveOccurred()))

gvr, _ := schema.ParseResourceArg("endpoints.v1.submariner.io")
endpointsClient := clientSet.Resource(*gvr).Namespace("submariner-operator")
_, err = endpointsClient.List(metav1.ListOptions{})
Expect(err).To(Not(HaveOccurred()))

return endpointsClient
}

func (f *Framework) NewServiceExport(cluster framework.ClusterIndex, name, namespace string) *mcsv1a1.ServiceExport {
nginxServiceExport := mcsv1a1.ServiceExport{
ObjectMeta: metav1.ObjectMeta{
Expand Down Expand Up @@ -416,3 +435,44 @@ func (f *Framework) SetNginxStatefulSetReplicas(cluster framework.ClusterIndex,

return result
}

func (f *Framework) GetHealthCheckIPInfo(cluster framework.ClusterIndex) (endpointName, healthCheckIP string) {
framework.AwaitUntil("Get healthCheckIP", func() (interface{}, error) {
unstructuredEndpointList, err := EndpointClients[cluster].List(metav1.ListOptions{})
return unstructuredEndpointList, err
}, func(result interface{}) (bool, string, error) {
unstructuredEndpointList := result.(*unstructured.UnstructuredList)
for _, endpoint := range unstructuredEndpointList.Items {
By(fmt.Sprintf("Getting the endpoint %s, for cluster %s", endpoint.GetName(), framework.TestContext.ClusterIDs[cluster]))

if strings.Contains(endpoint.GetName(), framework.TestContext.ClusterIDs[cluster]) {
endpointName = endpoint.GetName()

var found bool
var err error
healthCheckIP, found, err = unstructured.NestedString(endpoint.Object, "spec", "healthCheckIP")

if err != nil {
return false, "", err
}

if !found {
return false, fmt.Sprintf("HealthcheckIP not found in %#v ", endpoint), nil
}
}
}
return true, "", nil
})

return endpointName, healthCheckIP
}

func (f *Framework) SetHealthCheckIP(cluster framework.ClusterIndex, ip, endpointName string) {
By(fmt.Sprintf("Setting health check IP cluster %q to %v", framework.TestContext.ClusterIDs[cluster], ip))
patch := fmt.Sprintf(`{"spec":{"healthCheckIP":%q}}`, ip)

framework.AwaitUntil("set healthCheckIP", func() (interface{}, error) {
endpoint, err := EndpointClients[cluster].Patch(endpointName, types.MergePatchType, []byte(patch), metav1.PatchOptions{})
return endpoint, err
}, framework.NoopCheckResult)
}

0 comments on commit 9be744d

Please sign in to comment.