open-cluster-management.io/governance-policy-propagator@v0.13.0/test/e2e/case10_policyset_propagation_test.go (about)

     1  // Copyright (c) 2020 Red Hat, Inc.
     2  // Copyright Contributors to the Open Cluster Management project
     3  
     4  package e2e
     5  
     6  import (
     7  	"context"
     8  
     9  	. "github.com/onsi/ginkgo/v2"
    10  	. "github.com/onsi/gomega"
    11  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    12  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    13  	"k8s.io/apimachinery/pkg/runtime"
    14  
    15  	policiesv1 "open-cluster-management.io/governance-policy-propagator/api/v1"
    16  	"open-cluster-management.io/governance-policy-propagator/controllers/common"
    17  	"open-cluster-management.io/governance-policy-propagator/test/utils"
    18  )
    19  
    20  var _ = Describe("Test policyset propagation", func() {
    21  	const (
    22  		path                               string = "../resources/case10_policyset_propagation/"
    23  		case10PolicyName                   string = "case10-test-policy"
    24  		case10PolicySetName                string = "case10-test-policyset"
    25  		case10PolicySetYaml                string = path + "case10-test-policyset.yaml"
    26  		case10PolicySetPlacementYaml       string = path + "case10-test-policyset-placement.yaml"
    27  		case10PolicySetPolicyYaml          string = path + "case10-test-policyset-policy.yaml"
    28  		case10PolicySetPolicyPlacementYaml string = path + "case10-test-policyset-policy-placement.yaml"
    29  	)
    30  
    31  	Describe("Test policy propagation through policyset placementbinding with placementrule", func() {
    32  		It("should be created in user ns", func() {
    33  			By("Creating " + case10PolicySetYaml)
    34  			_, err := utils.KubectlWithOutput("apply",
    35  				"-f", case10PolicySetYaml,
    36  				"-n", testNamespace,
    37  				"--kubeconfig="+kubeconfigHub)
    38  			Expect(err).ToNot(HaveOccurred())
    39  			plcSet := utils.GetWithTimeout(
    40  				clientHubDynamic, gvrPolicySet, case10PolicySetName, testNamespace, true, defaultTimeoutSeconds,
    41  			)
    42  			Expect(plcSet).NotTo(BeNil())
    43  		})
    44  		It("should propagate to cluster ns managed1", func() {
    45  			By("Patching test-policy-plr with decision of cluster managed1")
    46  			plr := utils.GetWithTimeout(
    47  				clientHubDynamic, gvrPlacementRule, case10PolicySetName+"-plr", testNamespace, true,
    48  				defaultTimeoutSeconds,
    49  			)
    50  			plr.Object["status"] = utils.GeneratePlrStatus("managed1")
    51  			_, err := clientHubDynamic.Resource(gvrPlacementRule).Namespace(testNamespace).UpdateStatus(
    52  				context.TODO(), plr, metav1.UpdateOptions{},
    53  			)
    54  			Expect(err).ToNot(HaveOccurred())
    55  			plc := utils.GetWithTimeout(
    56  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName, "managed1", true,
    57  				defaultTimeoutSeconds,
    58  			)
    59  			Expect(plc).ToNot(BeNil())
    60  			opt := metav1.ListOptions{
    61  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
    62  			}
    63  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 1, true, defaultTimeoutSeconds)
    64  		})
    65  		It("should propagate to cluster ns managed2", func() {
    66  			By("Patching test-policy-plr with decision of cluster managed2")
    67  			plr := utils.GetWithTimeout(
    68  				clientHubDynamic, gvrPlacementRule, case10PolicySetName+"-plr", testNamespace, true,
    69  				defaultTimeoutSeconds,
    70  			)
    71  			plr.Object["status"] = utils.GeneratePlrStatus("managed2")
    72  			_, err := clientHubDynamic.Resource(gvrPlacementRule).Namespace(testNamespace).UpdateStatus(
    73  				context.TODO(), plr, metav1.UpdateOptions{},
    74  			)
    75  			Expect(err).ToNot(HaveOccurred())
    76  			plc := utils.GetWithTimeout(
    77  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName, "managed2", true,
    78  				defaultTimeoutSeconds,
    79  			)
    80  			Expect(plc).ToNot(BeNil())
    81  			opt := metav1.ListOptions{
    82  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
    83  			}
    84  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 1, true, defaultTimeoutSeconds)
    85  		})
    86  		It("should propagate to cluster ns managed1 and managed2", func() {
    87  			By("Patching test-policy-plr with decision of both managed1 and managed2")
    88  			plr := utils.GetWithTimeout(
    89  				clientHubDynamic, gvrPlacementRule, case10PolicySetName+"-plr", testNamespace, true,
    90  				defaultTimeoutSeconds,
    91  			)
    92  			plr.Object["status"] = utils.GeneratePlrStatus("managed1", "managed2")
    93  			_, err := clientHubDynamic.Resource(gvrPlacementRule).Namespace(testNamespace).UpdateStatus(
    94  				context.TODO(), plr, metav1.UpdateOptions{},
    95  			)
    96  			Expect(err).ToNot(HaveOccurred())
    97  			opt := metav1.ListOptions{
    98  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
    99  			}
   100  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 2, true, defaultTimeoutSeconds)
   101  		})
   102  		It("should propagate to cluster ns managed1", func() {
   103  			By("Patching test-policy-plr with decision of cluster managed1")
   104  			plr := utils.GetWithTimeout(
   105  				clientHubDynamic, gvrPlacementRule, case10PolicySetName+"-plr", testNamespace, true,
   106  				defaultTimeoutSeconds,
   107  			)
   108  			plr.Object["status"] = utils.GeneratePlrStatus("managed1")
   109  			_, err := clientHubDynamic.Resource(gvrPlacementRule).Namespace(testNamespace).UpdateStatus(
   110  				context.TODO(), plr, metav1.UpdateOptions{},
   111  			)
   112  			Expect(err).ToNot(HaveOccurred())
   113  			plc := utils.GetWithTimeout(
   114  				clientHubDynamic,
   115  				gvrPolicy,
   116  				testNamespace+"."+case10PolicyName,
   117  				"managed1",
   118  				true,
   119  				defaultTimeoutSeconds,
   120  			)
   121  			Expect(plc).ToNot(BeNil())
   122  			plc = utils.GetWithTimeout(
   123  				clientHubDynamic,
   124  				gvrPolicy,
   125  				testNamespace+"."+case10PolicyName,
   126  				"managed2",
   127  				false,
   128  				defaultTimeoutSeconds,
   129  			)
   130  			Expect(plc).To(BeNil())
   131  			opt := metav1.ListOptions{
   132  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   133  			}
   134  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 1, true, defaultTimeoutSeconds)
   135  		})
   136  		It("should propagate to cluster ns managed1 and managed2", func() {
   137  			By("Patching test-policy-plr with decision of both managed1 and managed2")
   138  			plr := utils.GetWithTimeout(
   139  				clientHubDynamic, gvrPlacementRule, case10PolicySetName+"-plr", testNamespace, true,
   140  				defaultTimeoutSeconds,
   141  			)
   142  			plr.Object["status"] = utils.GeneratePlrStatus("managed1", "managed2")
   143  			_, err := clientHubDynamic.Resource(gvrPlacementRule).Namespace(testNamespace).UpdateStatus(
   144  				context.TODO(), plr, metav1.UpdateOptions{},
   145  			)
   146  			Expect(err).ToNot(HaveOccurred())
   147  			opt := metav1.ListOptions{
   148  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   149  			}
   150  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 2, true, defaultTimeoutSeconds)
   151  		})
   152  		It("should remove policy from ns managed1 and managed2", func() {
   153  			By("Deleting policyset")
   154  			_, err := utils.KubectlWithOutput("delete", "policyset",
   155  				case10PolicySetName, "-n", testNamespace, "--kubeconfig="+kubeconfigHub)
   156  			Expect(err).ToNot(HaveOccurred())
   157  			plcSet := utils.GetWithTimeout(
   158  				clientHubDynamic, gvrPolicySet, case10PolicySetName, testNamespace, false, defaultTimeoutSeconds,
   159  			)
   160  			Expect(plcSet).To(BeNil())
   161  			opt := metav1.ListOptions{
   162  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   163  			}
   164  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 0, true, defaultTimeoutSeconds)
   165  		})
   166  		It("should be created in user ns", func() {
   167  			By("Creating " + case10PolicySetYaml)
   168  			_, err := utils.KubectlWithOutput("apply",
   169  				"-f", case10PolicySetYaml,
   170  				"-n", testNamespace,
   171  				"--kubeconfig="+kubeconfigHub)
   172  			Expect(err).ToNot(HaveOccurred())
   173  			plcSet := utils.GetWithTimeout(
   174  				clientHubDynamic, gvrPolicySet, case10PolicySetName, testNamespace, true, defaultTimeoutSeconds,
   175  			)
   176  			Expect(plcSet).NotTo(BeNil())
   177  		})
   178  		It("should propagate to cluster ns managed1 and managed2", func() {
   179  			By("Patching test-policy-plr with decision of both managed1 and managed2")
   180  			plr := utils.GetWithTimeout(
   181  				clientHubDynamic, gvrPlacementRule, case10PolicySetName+"-plr", testNamespace, true,
   182  				defaultTimeoutSeconds,
   183  			)
   184  			plr.Object["status"] = utils.GeneratePlrStatus("managed1", "managed2")
   185  			_, err := clientHubDynamic.Resource(gvrPlacementRule).Namespace(testNamespace).UpdateStatus(
   186  				context.TODO(), plr, metav1.UpdateOptions{},
   187  			)
   188  			Expect(err).ToNot(HaveOccurred())
   189  			opt := metav1.ListOptions{
   190  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   191  			}
   192  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 2, true, defaultTimeoutSeconds)
   193  		})
   194  		It("should remove policy from ns managed1 and managed2", func() {
   195  			By("Deleting placementbinding")
   196  			_, err := utils.KubectlWithOutput("delete", "PlacementBinding", case10PolicySetName+"-pb", "-n",
   197  				testNamespace, "--kubeconfig="+kubeconfigHub)
   198  			Expect(err).ToNot(HaveOccurred())
   199  			opt := metav1.ListOptions{
   200  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   201  			}
   202  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 0, true, defaultTimeoutSeconds)
   203  		})
   204  		It("should be created in user ns", func() {
   205  			By("Creating " + case10PolicySetYaml)
   206  			_, err := utils.KubectlWithOutput("apply",
   207  				"-f", case10PolicySetYaml,
   208  				"-n", testNamespace,
   209  				"--kubeconfig="+kubeconfigHub)
   210  			Expect(err).ToNot(HaveOccurred())
   211  			plcSet := utils.GetWithTimeout(
   212  				clientHubDynamic, gvrPolicySet, case10PolicySetName, testNamespace, true, defaultTimeoutSeconds,
   213  			)
   214  			Expect(plcSet).NotTo(BeNil())
   215  		})
   216  		It("should propagate to cluster ns managed1 and managed2", func() {
   217  			By("Patching test-policy-plr with decision of both managed1 and managed2")
   218  			plr := utils.GetWithTimeout(
   219  				clientHubDynamic, gvrPlacementRule, case10PolicySetName+"-plr", testNamespace, true,
   220  				defaultTimeoutSeconds,
   221  			)
   222  			plr.Object["status"] = utils.GeneratePlrStatus("managed1", "managed2")
   223  			_, err := clientHubDynamic.Resource(gvrPlacementRule).Namespace(testNamespace).UpdateStatus(
   224  				context.TODO(), plr, metav1.UpdateOptions{},
   225  			)
   226  			Expect(err).ToNot(HaveOccurred())
   227  			opt := metav1.ListOptions{
   228  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   229  			}
   230  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 2, true, defaultTimeoutSeconds)
   231  		})
   232  		It("should remove policy from ns managed1 and managed2", func() {
   233  			By("Deleting placementrule")
   234  			_, err := utils.KubectlWithOutput("delete", "PlacementRule", case10PolicySetName+"-plr", "-n",
   235  				testNamespace, "--kubeconfig="+kubeconfigHub)
   236  			Expect(err).ToNot(HaveOccurred())
   237  			opt := metav1.ListOptions{
   238  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   239  			}
   240  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 0, true, defaultTimeoutSeconds)
   241  		})
   242  		It("should be created in user ns", func() {
   243  			By("Creating " + case10PolicySetYaml)
   244  			_, err := utils.KubectlWithOutput("apply",
   245  				"-f", case10PolicySetYaml,
   246  				"-n", testNamespace,
   247  				"--kubeconfig="+kubeconfigHub)
   248  			Expect(err).ToNot(HaveOccurred())
   249  			plcSet := utils.GetWithTimeout(
   250  				clientHubDynamic, gvrPolicySet, case10PolicySetName, testNamespace, true, defaultTimeoutSeconds,
   251  			)
   252  			Expect(plcSet).NotTo(BeNil())
   253  		})
   254  		It("should propagate to cluster ns managed1 and managed2", func() {
   255  			By("Patching test-policy-plr with decision of both managed1 and managed2")
   256  			plr := utils.GetWithTimeout(
   257  				clientHubDynamic, gvrPlacementRule, case10PolicySetName+"-plr", testNamespace, true,
   258  				defaultTimeoutSeconds,
   259  			)
   260  			plr.Object["status"] = utils.GeneratePlrStatus("managed1", "managed2")
   261  			_, err := clientHubDynamic.Resource(gvrPlacementRule).Namespace(testNamespace).UpdateStatus(
   262  				context.TODO(), plr, metav1.UpdateOptions{},
   263  			)
   264  			Expect(err).ToNot(HaveOccurred())
   265  			opt := metav1.ListOptions{
   266  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   267  			}
   268  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 2, true, defaultTimeoutSeconds)
   269  		})
   270  		It("should clean up", func() {
   271  			By("Deleting " + case10PolicySetYaml)
   272  			_, err := utils.KubectlWithOutput("delete",
   273  				"-f", case10PolicySetYaml,
   274  				"-n", testNamespace,
   275  				"--kubeconfig="+kubeconfigHub)
   276  			Expect(err).ToNot(HaveOccurred())
   277  			plcSet := utils.GetWithTimeout(
   278  				clientHubDynamic, gvrPolicySet, case10PolicySetName, testNamespace, false, defaultTimeoutSeconds,
   279  			)
   280  			Expect(plcSet).To(BeNil())
   281  			opt := metav1.ListOptions{
   282  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   283  			}
   284  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 0, true, defaultTimeoutSeconds)
   285  		})
   286  	})
   287  
   288  	Describe("Test policy propagation through both policy and policyset placementbinding with placementrule", func() {
   289  		It("should be created in user ns", func() {
   290  			By("Creating " + case10PolicySetYaml)
   291  			_, err := utils.KubectlWithOutput("apply",
   292  				"-f", case10PolicySetPolicyYaml,
   293  				"-n", testNamespace,
   294  				"--kubeconfig="+kubeconfigHub)
   295  			Expect(err).ToNot(HaveOccurred())
   296  			plcSet := utils.GetWithTimeout(
   297  				clientHubDynamic, gvrPolicySet, case10PolicySetName, testNamespace, true, defaultTimeoutSeconds,
   298  			)
   299  			Expect(plcSet).NotTo(BeNil())
   300  		})
   301  		It("should propagate to cluster ns managed1", func() {
   302  			By("Patching " + case10PolicySetName + "-plr with decision of cluster managed1")
   303  			plr := utils.GetWithTimeout(
   304  				clientHubDynamic, gvrPlacementRule, case10PolicySetName+"-plr", testNamespace, true,
   305  				defaultTimeoutSeconds,
   306  			)
   307  			plr.Object["status"] = utils.GeneratePlrStatus("managed1")
   308  			_, err := clientHubDynamic.Resource(gvrPlacementRule).Namespace(testNamespace).UpdateStatus(
   309  				context.TODO(), plr, metav1.UpdateOptions{},
   310  			)
   311  			Expect(err).ToNot(HaveOccurred())
   312  			plc := utils.GetWithTimeout(
   313  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName, "managed1", true,
   314  				defaultTimeoutSeconds,
   315  			)
   316  			Expect(plc).ToNot(BeNil())
   317  			opt := metav1.ListOptions{
   318  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   319  			}
   320  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 1, true, defaultTimeoutSeconds)
   321  		})
   322  		It("should propagate to cluster ns managed1 and managed2", func() {
   323  			By("Patching " + case10PolicyName + "-plr with decision of cluster managed1")
   324  			plr := utils.GetWithTimeout(
   325  				clientHubDynamic, gvrPlacementRule, case10PolicyName+"-plr", testNamespace, true,
   326  				defaultTimeoutSeconds,
   327  			)
   328  			plr.Object["status"] = utils.GeneratePlrStatus("managed2")
   329  			_, err := clientHubDynamic.Resource(gvrPlacementRule).Namespace(testNamespace).UpdateStatus(
   330  				context.TODO(), plr, metav1.UpdateOptions{},
   331  			)
   332  			Expect(err).ToNot(HaveOccurred())
   333  			plc := utils.GetWithTimeout(
   334  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName, "managed1", true,
   335  				defaultTimeoutSeconds,
   336  			)
   337  			Expect(plc).ToNot(BeNil())
   338  			plc = utils.GetWithTimeout(
   339  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName, "managed2", true,
   340  				defaultTimeoutSeconds,
   341  			)
   342  			Expect(plc).ToNot(BeNil())
   343  			opt := metav1.ListOptions{
   344  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   345  			}
   346  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 2, true, defaultTimeoutSeconds)
   347  		})
   348  		It("should propagate to cluster ns managed1", func() {
   349  			By("Patching " + case10PolicyName + "-plr with decision of cluster managed1")
   350  			plr := utils.GetWithTimeout(
   351  				clientHubDynamic, gvrPlacementRule, case10PolicyName+"-plr", testNamespace, true,
   352  				defaultTimeoutSeconds,
   353  			)
   354  			plr.Object["status"] = utils.GeneratePlrStatus("managed1")
   355  			_, err := clientHubDynamic.Resource(gvrPlacementRule).Namespace(testNamespace).UpdateStatus(
   356  				context.TODO(), plr, metav1.UpdateOptions{},
   357  			)
   358  			Expect(err).ToNot(HaveOccurred())
   359  			plc := utils.GetWithTimeout(
   360  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName, "managed1", true,
   361  				defaultTimeoutSeconds,
   362  			)
   363  			Expect(plc).ToNot(BeNil())
   364  			opt := metav1.ListOptions{
   365  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   366  			}
   367  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 1, true, defaultTimeoutSeconds)
   368  		})
   369  		It("should propagate to cluster ns managed1 and managed2", func() {
   370  			By("Patching " + case10PolicySetName + "-plr with decision of cluster managed2")
   371  			plr := utils.GetWithTimeout(
   372  				clientHubDynamic, gvrPlacementRule, case10PolicySetName+"-plr", testNamespace, true,
   373  				defaultTimeoutSeconds,
   374  			)
   375  			plr.Object["status"] = utils.GeneratePlrStatus("managed2")
   376  			_, err := clientHubDynamic.Resource(gvrPlacementRule).Namespace(testNamespace).UpdateStatus(
   377  				context.TODO(), plr, metav1.UpdateOptions{},
   378  			)
   379  			Expect(err).ToNot(HaveOccurred())
   380  			plc := utils.GetWithTimeout(
   381  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName, "managed2", true,
   382  				defaultTimeoutSeconds,
   383  			)
   384  			Expect(plc).ToNot(BeNil())
   385  			opt := metav1.ListOptions{
   386  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   387  			}
   388  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 2, true, defaultTimeoutSeconds)
   389  		})
   390  		It("should clean up", func() {
   391  			By("Deleting " + case10PolicySetYaml)
   392  			_, err := utils.KubectlWithOutput("delete",
   393  				"-f", case10PolicySetPolicyYaml,
   394  				"-n", testNamespace,
   395  				"--kubeconfig="+kubeconfigHub)
   396  			Expect(err).ToNot(HaveOccurred())
   397  			plcSet := utils.GetWithTimeout(
   398  				clientHubDynamic, gvrPolicySet, case10PolicySetName, testNamespace, false, defaultTimeoutSeconds,
   399  			)
   400  			Expect(plcSet).To(BeNil())
   401  			opt := metav1.ListOptions{
   402  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   403  			}
   404  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 0, true, defaultTimeoutSeconds)
   405  		})
   406  	})
   407  
   408  	Describe("Test policy propagation through policyset placementbinding with placement", func() {
   409  		It("should be created in user ns", func() {
   410  			By("Creating " + case10PolicySetPlacementYaml)
   411  			_, err := utils.KubectlWithOutput("apply",
   412  				"-f", case10PolicySetPlacementYaml,
   413  				"-n", testNamespace,
   414  				"--kubeconfig="+kubeconfigHub)
   415  			Expect(err).ToNot(HaveOccurred())
   416  			plcSet := utils.GetWithTimeout(
   417  				clientHubDynamic, gvrPolicySet, case10PolicySetName, testNamespace, true, defaultTimeoutSeconds,
   418  			)
   419  			Expect(plcSet).NotTo(BeNil())
   420  		})
   421  		It("should propagate to cluster ns managed1", func() {
   422  			By("Patching test-policy-plm with decision of cluster managed1")
   423  			plm := utils.GetWithTimeout(
   424  				clientHubDynamic, gvrPlacementDecision, case10PolicySetName+"-plm-decision", testNamespace, true,
   425  				defaultTimeoutSeconds,
   426  			)
   427  			plm.Object["status"] = utils.GeneratePldStatus(plm.GetName(), plm.GetNamespace(), "managed1")
   428  			_, err := clientHubDynamic.Resource(gvrPlacementDecision).Namespace(testNamespace).UpdateStatus(
   429  				context.TODO(), plm, metav1.UpdateOptions{},
   430  			)
   431  			Expect(err).ToNot(HaveOccurred())
   432  			plc := utils.GetWithTimeout(
   433  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName, "managed1", true,
   434  				defaultTimeoutSeconds,
   435  			)
   436  			Expect(plc).ToNot(BeNil())
   437  			opt := metav1.ListOptions{
   438  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   439  			}
   440  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 1, true, defaultTimeoutSeconds)
   441  		})
   442  		It("should propagate to cluster ns managed2", func() {
   443  			By("Patching test-policy-plm with decision of cluster managed2")
   444  			plm := utils.GetWithTimeout(
   445  				clientHubDynamic, gvrPlacementDecision, case10PolicySetName+"-plm-decision", testNamespace, true,
   446  				defaultTimeoutSeconds,
   447  			)
   448  			plm.Object["status"] = utils.GeneratePldStatus(plm.GetName(), plm.GetNamespace(), "managed2")
   449  			_, err := clientHubDynamic.Resource(gvrPlacementDecision).Namespace(testNamespace).UpdateStatus(
   450  				context.TODO(), plm, metav1.UpdateOptions{},
   451  			)
   452  			Expect(err).ToNot(HaveOccurred())
   453  			plc := utils.GetWithTimeout(
   454  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName, "managed2", true,
   455  				defaultTimeoutSeconds,
   456  			)
   457  			Expect(plc).ToNot(BeNil())
   458  			opt := metav1.ListOptions{
   459  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   460  			}
   461  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 1, true, defaultTimeoutSeconds)
   462  		})
   463  		It("should propagate to both cluster ns managed1 and managed2", func() {
   464  			By("Patching test-policy-plm with decision of cluster managed2")
   465  			plm := utils.GetWithTimeout(
   466  				clientHubDynamic, gvrPlacementDecision, case10PolicySetName+"-plm-decision", testNamespace, true,
   467  				defaultTimeoutSeconds,
   468  			)
   469  			plm.Object["status"] = utils.GeneratePldStatus(plm.GetName(), plm.GetNamespace(), "managed1", "managed2")
   470  			_, err := clientHubDynamic.Resource(gvrPlacementDecision).Namespace(testNamespace).UpdateStatus(
   471  				context.TODO(), plm, metav1.UpdateOptions{},
   472  			)
   473  			Expect(err).ToNot(HaveOccurred())
   474  			plc := utils.GetWithTimeout(
   475  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName, "managed1", true,
   476  				defaultTimeoutSeconds,
   477  			)
   478  			Expect(plc).ToNot(BeNil())
   479  			plc = utils.GetWithTimeout(
   480  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName, "managed2", true,
   481  				defaultTimeoutSeconds,
   482  			)
   483  			Expect(plc).ToNot(BeNil())
   484  			opt := metav1.ListOptions{
   485  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   486  			}
   487  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 2, true, defaultTimeoutSeconds)
   488  		})
   489  		It("should remove policy from ns managed1 and managed2", func() {
   490  			By("Deleting policyset")
   491  			_, err := utils.KubectlWithOutput("delete", "policyset", case10PolicySetName,
   492  				"-n", testNamespace, "--kubeconfig="+kubeconfigHub)
   493  			Expect(err).ToNot(HaveOccurred())
   494  			plcSet := utils.GetWithTimeout(
   495  				clientHubDynamic, gvrPolicySet, case10PolicySetName, testNamespace, false, defaultTimeoutSeconds,
   496  			)
   497  			Expect(plcSet).To(BeNil())
   498  			opt := metav1.ListOptions{
   499  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   500  			}
   501  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 0, true, defaultTimeoutSeconds)
   502  		})
   503  		It("should be created in user ns", func() {
   504  			By("Creating " + case10PolicySetPlacementYaml)
   505  			_, err := utils.KubectlWithOutput("apply",
   506  				"-f", case10PolicySetPlacementYaml,
   507  				"-n", testNamespace,
   508  				"--kubeconfig="+kubeconfigHub)
   509  			Expect(err).ToNot(HaveOccurred())
   510  			plcSet := utils.GetWithTimeout(
   511  				clientHubDynamic, gvrPolicySet, case10PolicySetName, testNamespace, true, defaultTimeoutSeconds,
   512  			)
   513  			Expect(plcSet).NotTo(BeNil())
   514  		})
   515  		It("should propagate to both cluster ns managed1 and managed2", func() {
   516  			By("Patching test-policy-plm with decision of cluster managed2")
   517  			plm := utils.GetWithTimeout(
   518  				clientHubDynamic, gvrPlacementDecision, case10PolicySetName+"-plm-decision", testNamespace, true,
   519  				defaultTimeoutSeconds,
   520  			)
   521  			plm.Object["status"] = utils.GeneratePldStatus(plm.GetName(), plm.GetNamespace(), "managed1", "managed2")
   522  			_, err := clientHubDynamic.Resource(gvrPlacementDecision).Namespace(testNamespace).UpdateStatus(
   523  				context.TODO(), plm, metav1.UpdateOptions{},
   524  			)
   525  			Expect(err).ToNot(HaveOccurred())
   526  			plc := utils.GetWithTimeout(
   527  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName, "managed1", true,
   528  				defaultTimeoutSeconds,
   529  			)
   530  			Expect(plc).ToNot(BeNil())
   531  			plc = utils.GetWithTimeout(
   532  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName, "managed2", true,
   533  				defaultTimeoutSeconds,
   534  			)
   535  			Expect(plc).ToNot(BeNil())
   536  			opt := metav1.ListOptions{
   537  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   538  			}
   539  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 2, true, defaultTimeoutSeconds)
   540  		})
   541  		It("should remove policy from ns managed1 and managed2", func() {
   542  			By("Deleting placementbinding")
   543  			_, err := utils.KubectlWithOutput("delete", "PlacementBinding", case10PolicySetName+"-pb", "-n",
   544  				testNamespace, "--kubeconfig="+kubeconfigHub)
   545  			Expect(err).ToNot(HaveOccurred())
   546  			opt := metav1.ListOptions{
   547  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   548  			}
   549  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 0, true, defaultTimeoutSeconds)
   550  		})
   551  		It("should be created in user ns", func() {
   552  			By("Creating " + case10PolicySetPlacementYaml)
   553  			_, err := utils.KubectlWithOutput("apply",
   554  				"-f", case10PolicySetPlacementYaml,
   555  				"-n", testNamespace,
   556  				"--kubeconfig="+kubeconfigHub)
   557  			Expect(err).ToNot(HaveOccurred())
   558  			plcSet := utils.GetWithTimeout(
   559  				clientHubDynamic, gvrPolicySet, case10PolicySetName, testNamespace, true, defaultTimeoutSeconds,
   560  			)
   561  			Expect(plcSet).NotTo(BeNil())
   562  		})
   563  		It("should propagate to both cluster ns managed1 and managed2", func() {
   564  			By("Patching test-policy-plm with decision of cluster managed2")
   565  			plm := utils.GetWithTimeout(
   566  				clientHubDynamic, gvrPlacementDecision, case10PolicySetName+"-plm-decision", testNamespace, true,
   567  				defaultTimeoutSeconds,
   568  			)
   569  			plm.Object["status"] = utils.GeneratePldStatus(plm.GetName(), plm.GetNamespace(), "managed1", "managed2")
   570  			_, err := clientHubDynamic.Resource(gvrPlacementDecision).Namespace(testNamespace).UpdateStatus(
   571  				context.TODO(), plm, metav1.UpdateOptions{},
   572  			)
   573  			Expect(err).ToNot(HaveOccurred())
   574  			plc := utils.GetWithTimeout(
   575  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName, "managed1", true,
   576  				defaultTimeoutSeconds,
   577  			)
   578  			Expect(plc).ToNot(BeNil())
   579  			plc = utils.GetWithTimeout(
   580  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName, "managed2", true,
   581  				defaultTimeoutSeconds,
   582  			)
   583  			Expect(plc).ToNot(BeNil())
   584  			opt := metav1.ListOptions{
   585  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   586  			}
   587  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 2, true, defaultTimeoutSeconds)
   588  		})
   589  		It("should remove policy from ns managed1 and managed2", func() {
   590  			By("Deleting placementDecision")
   591  			_, err := utils.KubectlWithOutput("delete", "PlacementDecision", case10PolicySetName+"-plm-decision", "-n",
   592  				testNamespace, "--kubeconfig="+kubeconfigHub)
   593  			Expect(err).ToNot(HaveOccurred())
   594  			opt := metav1.ListOptions{
   595  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   596  			}
   597  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 0, true, defaultTimeoutSeconds)
   598  		})
   599  		It("should be created in user ns", func() {
   600  			By("Creating " + case10PolicySetPlacementYaml)
   601  			_, err := utils.KubectlWithOutput("apply",
   602  				"-f", case10PolicySetPlacementYaml,
   603  				"-n", testNamespace,
   604  				"--kubeconfig="+kubeconfigHub)
   605  			Expect(err).ToNot(HaveOccurred())
   606  			plcSet := utils.GetWithTimeout(
   607  				clientHubDynamic, gvrPolicySet, case10PolicySetName, testNamespace, true, defaultTimeoutSeconds,
   608  			)
   609  			Expect(plcSet).NotTo(BeNil())
   610  		})
   611  		It("should cleanup", func() {
   612  			By("Deleting " + case10PolicySetPlacementYaml)
   613  			_, err := utils.KubectlWithOutput("delete",
   614  				"-f", case10PolicySetPlacementYaml,
   615  				"-n", testNamespace,
   616  				"--kubeconfig="+kubeconfigHub)
   617  			Expect(err).ToNot(HaveOccurred())
   618  			plcSet := utils.GetWithTimeout(
   619  				clientHubDynamic, gvrPolicySet, case10PolicySetName, testNamespace, false, defaultTimeoutSeconds,
   620  			)
   621  			Expect(plcSet).To(BeNil())
   622  			opt := metav1.ListOptions{
   623  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   624  			}
   625  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 0, true, defaultTimeoutSeconds)
   626  		})
   627  	})
   628  
   629  	Describe("Test policy propagation through both policy and policyset placementbinding with placement", func() {
   630  		It("should be created in user ns", func() {
   631  			By("Creating " + case10PolicySetPolicyPlacementYaml)
   632  			_, err := utils.KubectlWithOutput("apply",
   633  				"-f", case10PolicySetPolicyPlacementYaml,
   634  				"-n", testNamespace,
   635  				"--kubeconfig="+kubeconfigHub)
   636  			Expect(err).ToNot(HaveOccurred())
   637  			plcSet := utils.GetWithTimeout(
   638  				clientHubDynamic, gvrPolicySet, case10PolicySetName, testNamespace, true, defaultTimeoutSeconds,
   639  			)
   640  			Expect(plcSet).NotTo(BeNil())
   641  		})
   642  		It("should propagate to cluster ns managed1", func() {
   643  			By("Patching test-policy-plm with decision of cluster managed1")
   644  			plm := utils.GetWithTimeout(
   645  				clientHubDynamic, gvrPlacementDecision, case10PolicyName+"-plm-decision", testNamespace, true,
   646  				defaultTimeoutSeconds,
   647  			)
   648  			plm.Object["status"] = utils.GeneratePldStatus(plm.GetName(), plm.GetNamespace(), "managed1")
   649  			_, err := clientHubDynamic.Resource(gvrPlacementDecision).Namespace(testNamespace).UpdateStatus(
   650  				context.TODO(), plm, metav1.UpdateOptions{},
   651  			)
   652  			Expect(err).ToNot(HaveOccurred())
   653  			plc := utils.GetWithTimeout(
   654  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName, "managed1", true,
   655  				defaultTimeoutSeconds,
   656  			)
   657  			Expect(plc).ToNot(BeNil())
   658  			opt := metav1.ListOptions{
   659  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   660  			}
   661  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 1, true, defaultTimeoutSeconds)
   662  		})
   663  		It("should propagate to both cluster ns managed1 and managed2", func() {
   664  			By("Patching test-policyset-plm with decision of cluster managed2")
   665  			plm := utils.GetWithTimeout(
   666  				clientHubDynamic, gvrPlacementDecision, case10PolicySetName+"-plm-decision", testNamespace, true,
   667  				defaultTimeoutSeconds,
   668  			)
   669  			plm.Object["status"] = utils.GeneratePldStatus(plm.GetName(), plm.GetNamespace(), "managed2")
   670  			_, err := clientHubDynamic.Resource(gvrPlacementDecision).Namespace(testNamespace).UpdateStatus(
   671  				context.TODO(), plm, metav1.UpdateOptions{},
   672  			)
   673  			Expect(err).ToNot(HaveOccurred())
   674  			plc := utils.GetWithTimeout(
   675  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName, "managed1", true,
   676  				defaultTimeoutSeconds,
   677  			)
   678  			Expect(plc).ToNot(BeNil())
   679  			plc = utils.GetWithTimeout(
   680  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName, "managed2", true,
   681  				defaultTimeoutSeconds,
   682  			)
   683  			Expect(plc).ToNot(BeNil())
   684  			opt := metav1.ListOptions{
   685  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   686  			}
   687  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 2, true, defaultTimeoutSeconds)
   688  		})
   689  		It("should cleanup", func() {
   690  			By("Deleting " + case10PolicySetPolicyPlacementYaml)
   691  			_, err := utils.KubectlWithOutput("delete",
   692  				"-f", case10PolicySetPolicyPlacementYaml,
   693  				"-n", testNamespace,
   694  				"--kubeconfig="+kubeconfigHub)
   695  			Expect(err).ToNot(HaveOccurred())
   696  			plcSet := utils.GetWithTimeout(
   697  				clientHubDynamic, gvrPolicySet, case10PolicySetName, testNamespace, false, defaultTimeoutSeconds,
   698  			)
   699  			Expect(plcSet).To(BeNil())
   700  			opt := metav1.ListOptions{
   701  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   702  			}
   703  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 0, true, defaultTimeoutSeconds)
   704  		})
   705  	})
   706  
   707  	Describe("Test policy propagation with policyset modification", func() {
   708  		It("should be created in user ns", func() {
   709  			By("Creating " + case10PolicySetYaml)
   710  			_, err := utils.KubectlWithOutput("apply",
   711  				"-f", case10PolicySetPolicyYaml,
   712  				"-n", testNamespace,
   713  				"--kubeconfig="+kubeconfigHub)
   714  			Expect(err).ToNot(HaveOccurred())
   715  			plcSet := utils.GetWithTimeout(
   716  				clientHubDynamic, gvrPolicySet, case10PolicySetName, testNamespace, true, defaultTimeoutSeconds,
   717  			)
   718  			Expect(plcSet).NotTo(BeNil())
   719  		})
   720  		It("should propagate to cluster ns managed1", func() {
   721  			By("Patching " + case10PolicySetName + "-plr with decision of cluster managed1")
   722  			plr := utils.GetWithTimeout(
   723  				clientHubDynamic, gvrPlacementRule, case10PolicySetName+"-plr", testNamespace, true,
   724  				defaultTimeoutSeconds,
   725  			)
   726  			plr.Object["status"] = utils.GeneratePlrStatus("managed1")
   727  			_, err := clientHubDynamic.Resource(gvrPlacementRule).Namespace(testNamespace).UpdateStatus(
   728  				context.TODO(), plr, metav1.UpdateOptions{},
   729  			)
   730  			Expect(err).ToNot(HaveOccurred())
   731  			plc := utils.GetWithTimeout(
   732  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName, "managed1", true,
   733  				defaultTimeoutSeconds,
   734  			)
   735  			Expect(plc).ToNot(BeNil())
   736  			opt := metav1.ListOptions{
   737  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   738  			}
   739  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 1, true, defaultTimeoutSeconds)
   740  		})
   741  		It("should remove from managed1", func() {
   742  			By("Patching " + case10PolicySetName + " with empty policies fields")
   743  			plcSet := utils.GetWithTimeout(
   744  				clientHubDynamic, gvrPolicySet, case10PolicySetName, testNamespace, true, defaultTimeoutSeconds,
   745  			)
   746  			Expect(plcSet).NotTo(BeNil())
   747  			plcSet.Object["spec"].(map[string]interface{})["policies"] = []string{}
   748  			_, err := clientHubDynamic.Resource(gvrPolicySet).Namespace(testNamespace).Update(
   749  				context.TODO(), plcSet, metav1.UpdateOptions{},
   750  			)
   751  			Expect(err).ToNot(HaveOccurred())
   752  			plc := utils.GetWithTimeout(
   753  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName, "managed1", false,
   754  				defaultTimeoutSeconds,
   755  			)
   756  			Expect(plc).To(BeNil())
   757  			opt := metav1.ListOptions{
   758  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   759  			}
   760  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 0, true, defaultTimeoutSeconds)
   761  		})
   762  		It("should propagate to cluster ns managed1", func() {
   763  			By("Patching " + case10PolicySetName + " with " + case10PolicyName + " policies fields")
   764  			plcSet := utils.GetWithTimeout(
   765  				clientHubDynamic, gvrPolicySet, case10PolicySetName, testNamespace, true, defaultTimeoutSeconds,
   766  			)
   767  			Expect(plcSet).NotTo(BeNil())
   768  			plcSet.Object["spec"].(map[string]interface{})["policies"] = []string{case10PolicyName}
   769  			_, err := clientHubDynamic.Resource(gvrPolicySet).Namespace(testNamespace).Update(
   770  				context.TODO(), plcSet, metav1.UpdateOptions{},
   771  			)
   772  			Expect(err).ToNot(HaveOccurred())
   773  			plc := utils.GetWithTimeout(
   774  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName, "managed1", true,
   775  				defaultTimeoutSeconds,
   776  			)
   777  			Expect(plc).ToNot(BeNil())
   778  			opt := metav1.ListOptions{
   779  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   780  			}
   781  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 1, true, defaultTimeoutSeconds)
   782  		})
   783  		It("should still propagate to cluster ns managed1", func() {
   784  			By("Patching " + case10PolicySetName + " with " + case10PolicyName + " and non-exist policies fields")
   785  			plcSet := utils.GetWithTimeout(
   786  				clientHubDynamic, gvrPolicySet, case10PolicySetName, testNamespace, true, defaultTimeoutSeconds,
   787  			)
   788  			Expect(plcSet).NotTo(BeNil())
   789  			plcSet.Object["spec"].(map[string]interface{})["policies"] = []string{case10PolicyName, "policy-not-exists"}
   790  			_, err := clientHubDynamic.Resource(gvrPolicySet).Namespace(testNamespace).Update(
   791  				context.TODO(), plcSet, metav1.UpdateOptions{},
   792  			)
   793  			Expect(err).ToNot(HaveOccurred())
   794  			plc := utils.GetWithTimeout(
   795  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName, "managed1", true,
   796  				defaultTimeoutSeconds,
   797  			)
   798  			Expect(plc).ToNot(BeNil())
   799  			opt := metav1.ListOptions{
   800  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   801  			}
   802  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 1, true, defaultTimeoutSeconds)
   803  		})
   804  		It("should remove from managed1", func() {
   805  			By("Patching " + case10PolicySetName + " with empty policies fields")
   806  			plcSet := utils.GetWithTimeout(
   807  				clientHubDynamic, gvrPolicySet, case10PolicySetName, testNamespace, true, defaultTimeoutSeconds,
   808  			)
   809  			Expect(plcSet).NotTo(BeNil())
   810  			plcSet.Object["spec"].(map[string]interface{})["policies"] = []string{}
   811  			_, err := clientHubDynamic.Resource(gvrPolicySet).Namespace(testNamespace).Update(
   812  				context.TODO(), plcSet, metav1.UpdateOptions{},
   813  			)
   814  			Expect(err).ToNot(HaveOccurred())
   815  			plc := utils.GetWithTimeout(
   816  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName, "managed1", false,
   817  				defaultTimeoutSeconds,
   818  			)
   819  			Expect(plc).To(BeNil())
   820  			opt := metav1.ListOptions{
   821  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   822  			}
   823  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 0, true, defaultTimeoutSeconds)
   824  		})
   825  		It("should clean up", func() {
   826  			By("Deleting " + case10PolicySetYaml)
   827  			_, err := utils.KubectlWithOutput("delete",
   828  				"-f", case10PolicySetPolicyYaml,
   829  				"-n", testNamespace,
   830  				"--kubeconfig="+kubeconfigHub)
   831  			Expect(err).ToNot(HaveOccurred())
   832  			plcSet := utils.GetWithTimeout(
   833  				clientHubDynamic, gvrPolicySet, case10PolicySetName, testNamespace, false, defaultTimeoutSeconds,
   834  			)
   835  			Expect(plcSet).To(BeNil())
   836  			opt := metav1.ListOptions{
   837  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   838  			}
   839  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 0, true, defaultTimeoutSeconds)
   840  		})
   841  	})
   842  
   843  	Describe("Test policy propagation with multiple policysets", func() {
   844  		const case10PolicySetMultipleYaml string = path + "case10-test-multiple-policysets.yaml"
   845  		It("should be created in user ns", func() {
   846  			By("Creating " + case10PolicySetMultipleYaml)
   847  			_, err := utils.KubectlWithOutput("apply",
   848  				"-f", case10PolicySetMultipleYaml,
   849  				"-n", testNamespace,
   850  				"--kubeconfig="+kubeconfigHub)
   851  			Expect(err).ToNot(HaveOccurred())
   852  			plcSet1 := utils.GetWithTimeout(
   853  				clientHubDynamic, gvrPolicySet, case10PolicySetName+"1", testNamespace, true, defaultTimeoutSeconds,
   854  			)
   855  			Expect(plcSet1).NotTo(BeNil())
   856  			plcSet2 := utils.GetWithTimeout(
   857  				clientHubDynamic, gvrPolicySet, case10PolicySetName+"2", testNamespace, true, defaultTimeoutSeconds,
   858  			)
   859  			Expect(plcSet2).NotTo(BeNil())
   860  		})
   861  
   862  		It("should propagate to cluster ns managed1", func() {
   863  			By("Patching " + case10PolicySetName + "1-plm with decision of cluster managed1")
   864  			plm := utils.GetWithTimeout(
   865  				clientHubDynamic, gvrPlacementDecision, case10PolicySetName+"1-plm-decision", testNamespace, true,
   866  				defaultTimeoutSeconds,
   867  			)
   868  			plm.Object["status"] = utils.GeneratePldStatus(plm.GetName(), plm.GetNamespace(), "managed1")
   869  			_, err := clientHubDynamic.Resource(gvrPlacementDecision).Namespace(testNamespace).UpdateStatus(
   870  				context.TODO(), plm, metav1.UpdateOptions{},
   871  			)
   872  			Expect(err).ToNot(HaveOccurred())
   873  			plc := utils.GetWithTimeout(
   874  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName, "managed1", true,
   875  				defaultTimeoutSeconds,
   876  			)
   877  			Expect(plc).ToNot(BeNil())
   878  			opt := metav1.ListOptions{
   879  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   880  			}
   881  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 1, true, defaultTimeoutSeconds)
   882  		})
   883  		It("should propagate to both cluster ns managed1 and managed2", func() {
   884  			By("Patching " + case10PolicySetName + "2-plm with decision of cluster managed2")
   885  			plm := utils.GetWithTimeout(
   886  				clientHubDynamic, gvrPlacementDecision, case10PolicySetName+"2-plm-decision", testNamespace, true,
   887  				defaultTimeoutSeconds,
   888  			)
   889  			plm.Object["status"] = utils.GeneratePldStatus(plm.GetName(), plm.GetNamespace(), "managed2")
   890  			_, err := clientHubDynamic.Resource(gvrPlacementDecision).Namespace(testNamespace).UpdateStatus(
   891  				context.TODO(), plm, metav1.UpdateOptions{},
   892  			)
   893  			Expect(err).ToNot(HaveOccurred())
   894  			plc := utils.GetWithTimeout(
   895  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName, "managed2", true,
   896  				defaultTimeoutSeconds,
   897  			)
   898  			Expect(plc).ToNot(BeNil())
   899  			opt := metav1.ListOptions{
   900  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   901  			}
   902  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 2, true, defaultTimeoutSeconds)
   903  		})
   904  		It("should cleanup", func() {
   905  			By("Deleting " + case10PolicySetMultipleYaml)
   906  			_, err := utils.KubectlWithOutput("delete",
   907  				"-f", case10PolicySetMultipleYaml,
   908  				"-n", testNamespace,
   909  				"--kubeconfig="+kubeconfigHub)
   910  			Expect(err).ToNot(HaveOccurred())
   911  			plcSet1 := utils.GetWithTimeout(
   912  				clientHubDynamic, gvrPolicySet, case10PolicySetName+"1", testNamespace, false, defaultTimeoutSeconds,
   913  			)
   914  			Expect(plcSet1).To(BeNil())
   915  			plcSet2 := utils.GetWithTimeout(
   916  				clientHubDynamic, gvrPolicySet, case10PolicySetName+"2", testNamespace, false, defaultTimeoutSeconds,
   917  			)
   918  			Expect(plcSet2).To(BeNil())
   919  			opt := metav1.ListOptions{
   920  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
   921  			}
   922  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 0, true, defaultTimeoutSeconds)
   923  		})
   924  	})
   925  
   926  	Describe("Test policy propagation with multiple policysets with single placementbinding", func() {
   927  		const case10PolicySetMultipleSinglePBYaml string = path + "case10-test-multiple-policysets-single-pb.yaml"
   928  		It("should be created in user ns", func() {
   929  			By("Creating " + case10PolicySetMultipleSinglePBYaml)
   930  			_, err := utils.KubectlWithOutput("apply",
   931  				"-f", case10PolicySetMultipleSinglePBYaml,
   932  				"-n", testNamespace,
   933  				"--kubeconfig="+kubeconfigHub)
   934  			Expect(err).ToNot(HaveOccurred())
   935  			plcSet1 := utils.GetWithTimeout(
   936  				clientHubDynamic, gvrPolicySet, case10PolicySetName+"1", testNamespace, true, defaultTimeoutSeconds,
   937  			)
   938  			Expect(plcSet1).NotTo(BeNil())
   939  			plcSet2 := utils.GetWithTimeout(
   940  				clientHubDynamic, gvrPolicySet, case10PolicySetName+"2", testNamespace, true, defaultTimeoutSeconds,
   941  			)
   942  			Expect(plcSet2).NotTo(BeNil())
   943  		})
   944  		It(case10PolicyName+"1 should have "+case10PolicySetName+"1 placement", func() {
   945  			plc1 := utils.GetWithTimeout(
   946  				clientHubDynamic, gvrPolicy, case10PolicyName+"1", testNamespace, true, defaultTimeoutSeconds,
   947  			)
   948  			placement, found, err := unstructured.NestedSlice(plc1.Object, "status", "placement")
   949  			Expect(err).ShouldNot(HaveOccurred())
   950  			Expect(found).Should(BeTrue())
   951  			Expect(placement).To(HaveLen(1))
   952  			Expect(placement[0].(map[string]interface{})["policySet"]).Should(Equal(case10PolicySetName + "1"))
   953  		})
   954  		It(case10PolicyName+"2 should have "+case10PolicySetName+"2 placement", func() {
   955  			plc1 := utils.GetWithTimeout(
   956  				clientHubDynamic, gvrPolicy, case10PolicyName+"2", testNamespace, true, defaultTimeoutSeconds,
   957  			)
   958  			placement, found, err := unstructured.NestedSlice(plc1.Object, "status", "placement")
   959  			Expect(err).ShouldNot(HaveOccurred())
   960  			Expect(found).Should(BeTrue())
   961  			Expect(placement).To(HaveLen(1))
   962  			Expect(placement[0].(map[string]interface{})["policySet"]).Should(Equal(case10PolicySetName + "2"))
   963  		})
   964  		It("should propagate to cluster ns managed1", func() {
   965  			By("Patching " + case10PolicySetName + "-plm with decision of cluster managed1")
   966  			plm := utils.GetWithTimeout(
   967  				clientHubDynamic, gvrPlacementDecision, case10PolicySetName+"-plm-decision", testNamespace, true,
   968  				defaultTimeoutSeconds,
   969  			)
   970  			plm.Object["status"] = utils.GeneratePldStatus(plm.GetName(), plm.GetNamespace(), "managed1")
   971  			_, err := clientHubDynamic.Resource(gvrPlacementDecision).Namespace(testNamespace).UpdateStatus(
   972  				context.TODO(), plm, metav1.UpdateOptions{},
   973  			)
   974  			Expect(err).ToNot(HaveOccurred())
   975  			plc := utils.GetWithTimeout(
   976  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName+"1", "managed1", true,
   977  				defaultTimeoutSeconds,
   978  			)
   979  			Expect(plc).ToNot(BeNil())
   980  			opt := metav1.ListOptions{
   981  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName + "1",
   982  			}
   983  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 1, true, defaultTimeoutSeconds)
   984  			plc = utils.GetWithTimeout(
   985  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName+"2", "managed1", true,
   986  				defaultTimeoutSeconds,
   987  			)
   988  			Expect(plc).ToNot(BeNil())
   989  			opt = metav1.ListOptions{
   990  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName + "2",
   991  			}
   992  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 1, true, defaultTimeoutSeconds)
   993  		})
   994  		It("should propagate to cluster ns managed2", func() {
   995  			By("Patching " + case10PolicySetName + "-plm with decision of cluster managed2")
   996  			plm := utils.GetWithTimeout(
   997  				clientHubDynamic, gvrPlacementDecision, case10PolicySetName+"-plm-decision", testNamespace, true,
   998  				defaultTimeoutSeconds,
   999  			)
  1000  			plm.Object["status"] = utils.GeneratePldStatus(plm.GetName(), plm.GetNamespace(), "managed2")
  1001  			_, err := clientHubDynamic.Resource(gvrPlacementDecision).Namespace(testNamespace).UpdateStatus(
  1002  				context.TODO(), plm, metav1.UpdateOptions{},
  1003  			)
  1004  			Expect(err).ToNot(HaveOccurred())
  1005  			plc := utils.GetWithTimeout(
  1006  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName+"1", "managed1", false,
  1007  				defaultTimeoutSeconds,
  1008  			)
  1009  			Expect(plc).To(BeNil())
  1010  			plc = utils.GetWithTimeout(
  1011  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName+"1", "managed2", true,
  1012  				defaultTimeoutSeconds,
  1013  			)
  1014  			Expect(plc).NotTo(BeNil())
  1015  			plc = utils.GetWithTimeout(
  1016  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName+"2", "managed1", false,
  1017  				defaultTimeoutSeconds,
  1018  			)
  1019  			Expect(plc).To(BeNil())
  1020  			plc = utils.GetWithTimeout(
  1021  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName+"2", "managed2", true,
  1022  				defaultTimeoutSeconds,
  1023  			)
  1024  			Expect(plc).NotTo(BeNil())
  1025  		})
  1026  		It("should still work when pb contains non-existing policyset", func() {
  1027  			By("Patching " + case10PolicySetName + "-pb with non-existing policyset")
  1028  			unstructuredPb := utils.GetWithTimeout(
  1029  				clientHubDynamic, gvrPlacementBinding, case10PolicySetName+"-pb", testNamespace, true,
  1030  				defaultTimeoutSeconds,
  1031  			)
  1032  			var pb policiesv1.PlacementBinding
  1033  			err := runtime.DefaultUnstructuredConverter.
  1034  				FromUnstructured(unstructuredPb.UnstructuredContent(), &pb)
  1035  			Expect(err).ToNot(HaveOccurred())
  1036  			nonExistingSubject := []policiesv1.Subject{
  1037  				{
  1038  					APIGroup: "policy.open-cluster-management.io",
  1039  					Kind:     "PolicySet",
  1040  					Name:     case10PolicySetName,
  1041  				},
  1042  			}
  1043  			unstructuredPb.Object["subjects"] = append(nonExistingSubject, pb.Subjects[0], pb.Subjects[1])
  1044  			_, err = clientHubDynamic.Resource(gvrPlacementBinding).Namespace(testNamespace).Update(
  1045  				context.TODO(), unstructuredPb, metav1.UpdateOptions{},
  1046  			)
  1047  			Expect(err).ToNot(HaveOccurred())
  1048  		})
  1049  		It("should still propagate to cluster ns managed1", func() {
  1050  			By("Patching " + case10PolicySetName + "-plm with decision of cluster managed1")
  1051  			plm := utils.GetWithTimeout(
  1052  				clientHubDynamic, gvrPlacementDecision, case10PolicySetName+"-plm-decision", testNamespace, true,
  1053  				defaultTimeoutSeconds,
  1054  			)
  1055  			plm.Object["status"] = utils.GeneratePldStatus(plm.GetName(), plm.GetNamespace(), "managed1")
  1056  			_, err := clientHubDynamic.Resource(gvrPlacementDecision).Namespace(testNamespace).UpdateStatus(
  1057  				context.TODO(), plm, metav1.UpdateOptions{},
  1058  			)
  1059  			Expect(err).ToNot(HaveOccurred())
  1060  			plc := utils.GetWithTimeout(
  1061  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName+"1", "managed1", true,
  1062  				defaultTimeoutSeconds,
  1063  			)
  1064  			Expect(plc).ToNot(BeNil())
  1065  			opt := metav1.ListOptions{
  1066  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName + "1",
  1067  			}
  1068  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 1, true, defaultTimeoutSeconds)
  1069  			plc = utils.GetWithTimeout(
  1070  				clientHubDynamic, gvrPolicy, testNamespace+"."+case10PolicyName+"2", "managed1", true,
  1071  				defaultTimeoutSeconds,
  1072  			)
  1073  			Expect(plc).ToNot(BeNil())
  1074  			opt = metav1.ListOptions{
  1075  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName + "2",
  1076  			}
  1077  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 1, true, defaultTimeoutSeconds)
  1078  		})
  1079  		It("should cleanup", func() {
  1080  			By("Deleting " + case10PolicySetMultipleSinglePBYaml)
  1081  			_, err := utils.KubectlWithOutput("delete",
  1082  				"-f", case10PolicySetMultipleSinglePBYaml,
  1083  				"-n", testNamespace,
  1084  				"--kubeconfig="+kubeconfigHub)
  1085  			Expect(err).ToNot(HaveOccurred())
  1086  			plcSet1 := utils.GetWithTimeout(
  1087  				clientHubDynamic, gvrPolicySet, case10PolicySetName+"1", testNamespace, false, defaultTimeoutSeconds,
  1088  			)
  1089  			Expect(plcSet1).To(BeNil())
  1090  			plcSet2 := utils.GetWithTimeout(
  1091  				clientHubDynamic, gvrPolicySet, case10PolicySetName+"2", testNamespace, false, defaultTimeoutSeconds,
  1092  			)
  1093  			Expect(plcSet2).To(BeNil())
  1094  			opt := metav1.ListOptions{
  1095  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
  1096  			}
  1097  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 0, true, defaultTimeoutSeconds)
  1098  		})
  1099  	})
  1100  
  1101  	Describe("Test policy placement with multiple policies and policysets with single placementbinding", func() {
  1102  		case10PolicySetMultipleSinglePBYaml := path + "case10-test-multiple-policies-policysets-single-pb.yaml"
  1103  		It("should be created in user ns", func() {
  1104  			By("Creating " + case10PolicySetMultipleSinglePBYaml)
  1105  			_, err := utils.KubectlWithOutput("apply",
  1106  				"-f", case10PolicySetMultipleSinglePBYaml,
  1107  				"-n", testNamespace,
  1108  				"--kubeconfig="+kubeconfigHub)
  1109  			Expect(err).ToNot(HaveOccurred())
  1110  			plcSet1 := utils.GetWithTimeout(
  1111  				clientHubDynamic, gvrPolicySet, case10PolicySetName+"1", testNamespace, true, defaultTimeoutSeconds,
  1112  			)
  1113  			Expect(plcSet1).NotTo(BeNil())
  1114  			plcSet2 := utils.GetWithTimeout(
  1115  				clientHubDynamic, gvrPolicySet, case10PolicySetName+"2", testNamespace, true, defaultTimeoutSeconds,
  1116  			)
  1117  			Expect(plcSet2).NotTo(BeNil())
  1118  		})
  1119  		It(case10PolicyName+"1 should have 2 placement", func() {
  1120  			plc1 := utils.GetWithTimeout(
  1121  				clientHubDynamic, gvrPolicy, case10PolicyName+"1", testNamespace, true, defaultTimeoutSeconds,
  1122  			)
  1123  			placement, found, err := unstructured.NestedSlice(plc1.Object, "status", "placement")
  1124  			Expect(err).ShouldNot(HaveOccurred())
  1125  			Expect(found).Should(BeTrue())
  1126  			Expect(placement).To(HaveLen(2))
  1127  			Expect(placement[0].(map[string]interface{})["policySet"]).Should(BeNil())
  1128  			Expect(placement[1].(map[string]interface{})["policySet"]).Should(Equal(case10PolicySetName + "1"))
  1129  		})
  1130  		It(case10PolicyName+"2 should have 1 placement", func() {
  1131  			plc1 := utils.GetWithTimeout(
  1132  				clientHubDynamic, gvrPolicy, case10PolicyName+"2", testNamespace, true, defaultTimeoutSeconds,
  1133  			)
  1134  			placement, found, err := unstructured.NestedSlice(plc1.Object, "status", "placement")
  1135  			Expect(err).ShouldNot(HaveOccurred())
  1136  			Expect(found).Should(BeTrue())
  1137  			Expect(placement).To(HaveLen(1))
  1138  			Expect(placement[0].(map[string]interface{})["policySet"]).Should(Equal(case10PolicySetName + "2"))
  1139  		})
  1140  		It("should cleanup", func() {
  1141  			By("Deleting " + case10PolicySetMultipleSinglePBYaml)
  1142  			_, err := utils.KubectlWithOutput("delete",
  1143  				"-f", case10PolicySetMultipleSinglePBYaml,
  1144  				"-n", testNamespace,
  1145  				"--kubeconfig="+kubeconfigHub)
  1146  			Expect(err).ToNot(HaveOccurred())
  1147  			plcSet1 := utils.GetWithTimeout(
  1148  				clientHubDynamic, gvrPolicySet, case10PolicySetName+"1", testNamespace, false, defaultTimeoutSeconds,
  1149  			)
  1150  			Expect(plcSet1).To(BeNil())
  1151  			plcSet2 := utils.GetWithTimeout(
  1152  				clientHubDynamic, gvrPolicySet, case10PolicySetName+"2", testNamespace, false, defaultTimeoutSeconds,
  1153  			)
  1154  			Expect(plcSet2).To(BeNil())
  1155  			opt := metav1.ListOptions{
  1156  				LabelSelector: common.RootPolicyLabel + "=" + testNamespace + "." + case10PolicyName,
  1157  			}
  1158  			utils.ListWithTimeout(clientHubDynamic, gvrPolicy, opt, 0, true, defaultTimeoutSeconds)
  1159  		})
  1160  	})
  1161  })