From 25bd4815e06df6132663a7801533748f93beb43f Mon Sep 17 00:00:00 2001 From: xunpan Date: Sat, 10 Apr 2021 12:21:33 -0400 Subject: [PATCH] add test case for RSP placement intersection --- test/e2e/scheduling.go | 63 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 5 deletions(-) diff --git a/test/e2e/scheduling.go b/test/e2e/scheduling.go index 32f0496a6c..cbf049d630 100644 --- a/test/e2e/scheduling.go +++ b/test/e2e/scheduling.go @@ -88,6 +88,7 @@ var _ = Describe("Scheduling", func() { cluster1 int32 cluster2 int32 noPreferences bool + intersection bool }{ "replicas spread equally in clusters with no explicit per cluster preferences": { total: int32(4), @@ -113,6 +114,15 @@ var _ = Describe("Scheduling", func() { cluster1: int32(3), cluster2: int32(3), }, + "target clusters are the intersection of the RSP clusters and federated resource placement": { + intersection: true, + total: int32(6), + weight1: int64(2), + weight2: int64(1), + min1: int64(3), + min2: int64(3), + cluster1: int32(6), + }, } for key := range schedulingTypes { @@ -144,12 +154,27 @@ var _ = Describe("Scheduling", func() { clusterNames[1]: tc.cluster2, } - name, err := createTestObjs(tl, genericClient, typeConfig, kubeConfig, rspSpec, namespace) + if tc.intersection { + rspSpec.PlacementIntersection = true + fedNamespace := f.EnsureTestFederatedNamespace(true) + + // Ensure the removal of the namespace placement to avoid affecting other tests. + defer func() { + fedNamespaceKey := util.NewQualifiedName(fedNamespace).String() + + err := genericClient.Delete(context.Background(), fedNamespace, fedNamespace.GetNamespace(), fedNamespace.GetName()) + if err != nil && !apierrors.IsNotFound(err) { + tl.Fatalf("Error deleting FederatedNamespace %q: %v", fedNamespaceKey, err) + } + }() + } + + name, err := createTestObjs(tl, genericClient, typeConfig, kubeConfig, rspSpec, namespace, clusterNames) if err != nil { tl.Fatalf("Creation of test objects in the host cluster failed: %v", err) } - err = waitForMatchingFederatedObject(tl, typeConfig, kubeConfig, name, namespace, expected) + err = waitForMatchingFederatedObject(tl, typeConfig, kubeConfig, name, namespace, expected, rspSpec.PlacementIntersection) if err != nil { tl.Fatalf("Failed waiting for matching federated object: %v", err) } @@ -190,7 +215,7 @@ func rspSpecWithClusterList(total int32, w1, w2, min1, min2 int64, clusters []st return rspSpec } -func createTestObjs(tl common.TestLogger, client genericclient.Client, typeConfig typeconfig.Interface, kubeConfig *restclient.Config, rspSpec fedschedulingv1a1.ReplicaSchedulingPreferenceSpec, namespace string) (string, error) { +func createTestObjs(tl common.TestLogger, client genericclient.Client, typeConfig typeconfig.Interface, kubeConfig *restclient.Config, rspSpec fedschedulingv1a1.ReplicaSchedulingPreferenceSpec, namespace string, fedClusters []string) (string, error) { federatedTypeAPIResource := typeConfig.GetFederatedType() federatedTypeClient, err := util.NewResourceClient(kubeConfig, &federatedTypeAPIResource) if err != nil { @@ -202,10 +227,21 @@ func createTestObjs(tl common.TestLogger, client genericclient.Client, typeConfi if !ok { return "", errors.Errorf("Unable to find fixture for %q", typeConfigName) } - fedObject, err := common.NewTestObject(typeConfig, namespace, []string{}, fixture) + + clusters := []string{} + fedObject, err := common.NewTestObject(typeConfig, namespace, clusters, fixture) if err != nil { return "", err } + + if rspSpec.PlacementIntersection { + clusters = append(clusters, fedClusters[0]) + err = util.SetClusterNames(fedObject, clusters) + if err != nil { + return "", err + } + } + createdFedObject, err := federatedTypeClient.Resources(namespace).Create(context.Background(), fedObject, metav1.CreateOptions{}) if err != nil { return "", err @@ -242,7 +278,7 @@ func deleteTestObj(typeConfig typeconfig.Interface, kubeConfig *restclient.Confi return nil } -func waitForMatchingFederatedObject(tl common.TestLogger, typeConfig typeconfig.Interface, kubeConfig *restclient.Config, name, namespace string, expected32 map[string]int32) error { +func waitForMatchingFederatedObject(tl common.TestLogger, typeConfig typeconfig.Interface, kubeConfig *restclient.Config, name, namespace string, expected32 map[string]int32, isIntersection bool) error { apiResource := typeConfig.GetFederatedType() kind := apiResource.Kind client, err := util.NewResourceClient(kubeConfig, &apiResource) @@ -271,6 +307,23 @@ func waitForMatchingFederatedObject(tl common.TestLogger, typeConfig typeconfig. tl.Errorf("An error occurred while retrieving cluster names for override %s %s/%s: %v", kind, namespace, name, err) return false, nil } + + if isIntersection { + if schedulingtypes.PlacementUpdateNeeded(clusterNames, expectedClusterNames[:1]) { + return false, nil + } + + overridesMap, err := util.GetOverrides(fedObject) + if err != nil { + tl.Errorf("Error reading cluster overrides for %s %s/%s: %v", kind, namespace, name, err) + return false, nil + } + + expectedResult := make(map[string]int64) + expectedResult[expectedClusterNames[0]] = expected64[expectedClusterNames[0]] + return !schedulingtypes.OverrideUpdateNeeded(overridesMap, expectedResult), nil + } + if schedulingtypes.PlacementUpdateNeeded(clusterNames, expectedClusterNames) { return false, nil }