Skip to content

Commit 80e9f29

Browse files
Wei WengWei Weng
authored andcommitted
place deployment e2e test
Signed-off-by: Wei Weng <Wei.Weng@microsoft.com>
1 parent 3c22870 commit 80e9f29

File tree

1 file changed

+162
-0
lines changed

1 file changed

+162
-0
lines changed
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
/*
2+
Copyright 2025 The KubeFleet Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package e2e
18+
19+
import (
20+
"fmt"
21+
22+
. "github.com/onsi/ginkgo/v2"
23+
. "github.com/onsi/gomega"
24+
appsv1 "k8s.io/api/apps/v1"
25+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26+
"k8s.io/apimachinery/pkg/types"
27+
"k8s.io/utils/ptr"
28+
29+
placementv1beta1 "github.com/kubefleet-dev/kubefleet/apis/placement/v1beta1"
30+
"github.com/kubefleet-dev/kubefleet/pkg/utils"
31+
)
32+
33+
var _ = Describe("placing a Deployment using a RP with PickAll policy", Label("resourceplacement"), Ordered, func() {
34+
crpName := fmt.Sprintf(crpNameTemplate, GinkgoParallelProcess())
35+
rpName := fmt.Sprintf(rpNameTemplate, GinkgoParallelProcess())
36+
var testDeployment appsv1.Deployment
37+
38+
BeforeAll(func() {
39+
// Read the test deployment manifest
40+
readDeploymentTestManifest(&testDeployment)
41+
workNamespace := appNamespace()
42+
43+
// Create namespace and deployment
44+
By("creating namespace and deployment")
45+
Expect(hubClient.Create(ctx, &workNamespace)).To(Succeed(), "Failed to create namespace %s", workNamespace.Name)
46+
testDeployment.Namespace = workNamespace.Name
47+
Expect(hubClient.Create(ctx, &testDeployment)).To(Succeed(), "Failed to create test deployment %s", testDeployment.Name)
48+
49+
// Create the CRP with namespace-only selector
50+
By("creating CRP with namespace selector")
51+
crp := &placementv1beta1.ClusterResourcePlacement{
52+
ObjectMeta: metav1.ObjectMeta{
53+
Name: crpName,
54+
Finalizers: []string{customDeletionBlockerFinalizer},
55+
},
56+
Spec: placementv1beta1.PlacementSpec{
57+
ResourceSelectors: namespaceOnlySelector(),
58+
Policy: &placementv1beta1.PlacementPolicy{
59+
PlacementType: placementv1beta1.PickAllPlacementType,
60+
},
61+
Strategy: placementv1beta1.RolloutStrategy{
62+
Type: placementv1beta1.RollingUpdateRolloutStrategyType,
63+
RollingUpdate: &placementv1beta1.RollingUpdateConfig{
64+
UnavailablePeriodSeconds: ptr.To(2),
65+
},
66+
},
67+
},
68+
}
69+
Expect(hubClient.Create(ctx, crp)).To(Succeed(), "Failed to create CRP")
70+
71+
By("waiting for CRP status to update")
72+
crpStatusUpdatedActual := crpStatusUpdatedActual(workNamespaceIdentifiers(), allMemberClusterNames, nil, "0")
73+
Eventually(crpStatusUpdatedActual, eventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to update CRP status as expected")
74+
})
75+
76+
AfterAll(func() {
77+
By("cleaning up resources")
78+
ensureRPAndRelatedResourcesDeleted(types.NamespacedName{Name: rpName, Namespace: testDeployment.Namespace}, allMemberClusters, &testDeployment)
79+
ensureCRPAndRelatedResourcesDeleted(crpName, allMemberClusters)
80+
})
81+
82+
Context("with PickAll placement type", Ordered, func() {
83+
It("creating the RP should succeed", func() {
84+
By("creating RP that selects the deployment")
85+
rp := &placementv1beta1.ResourcePlacement{
86+
ObjectMeta: metav1.ObjectMeta{
87+
Name: rpName,
88+
Namespace: testDeployment.Namespace,
89+
Finalizers: []string{customDeletionBlockerFinalizer},
90+
},
91+
Spec: placementv1beta1.PlacementSpec{
92+
ResourceSelectors: []placementv1beta1.ResourceSelectorTerm{
93+
{
94+
Group: appsv1.SchemeGroupVersion.Group,
95+
Version: appsv1.SchemeGroupVersion.Version,
96+
Kind: utils.DeploymentKind,
97+
Name: testDeployment.Name,
98+
},
99+
},
100+
Policy: &placementv1beta1.PlacementPolicy{
101+
PlacementType: placementv1beta1.PickAllPlacementType,
102+
},
103+
Strategy: placementv1beta1.RolloutStrategy{
104+
Type: placementv1beta1.RollingUpdateRolloutStrategyType,
105+
RollingUpdate: &placementv1beta1.RollingUpdateConfig{
106+
UnavailablePeriodSeconds: ptr.To(2),
107+
},
108+
},
109+
},
110+
}
111+
Expect(hubClient.Create(ctx, rp)).To(Succeed(), "Failed to create RP")
112+
})
113+
114+
It("should update RP status as expected", func() {
115+
By("verifying RP status update")
116+
wantSelectedResources := []placementv1beta1.ResourceIdentifier{
117+
{
118+
Group: appsv1.SchemeGroupVersion.Group,
119+
Version: appsv1.SchemeGroupVersion.Version,
120+
Kind: utils.DeploymentKind,
121+
Name: testDeployment.Name,
122+
Namespace: testDeployment.Namespace,
123+
},
124+
}
125+
rpStatusUpdatedActual := rpStatusUpdatedActual(wantSelectedResources, allMemberClusterNames, nil, "0")
126+
Eventually(rpStatusUpdatedActual, workloadEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to update RP status as expected")
127+
})
128+
129+
It("should place the deployment on all member clusters", func() {
130+
By("verifying deployment is placed and ready on all member clusters")
131+
for idx := range allMemberClusters {
132+
memberCluster := allMemberClusters[idx]
133+
deploymentPlacedActual := waitForDeploymentPlacementToReady(memberCluster, &testDeployment)
134+
Eventually(deploymentPlacedActual, workloadEventuallyDuration, eventuallyInterval).Should(Succeed(), "Failed to place deployment on member cluster %s", memberCluster.ClusterName)
135+
}
136+
})
137+
138+
It("should verify deployment replicas are ready on all clusters", func() {
139+
By("checking deployment status on each cluster")
140+
for _, cluster := range allMemberClusters {
141+
Eventually(func() error {
142+
var deployed appsv1.Deployment
143+
if err := cluster.KubeClient.Get(ctx, types.NamespacedName{
144+
Name: testDeployment.Name,
145+
Namespace: testDeployment.Namespace,
146+
}, &deployed); err != nil {
147+
return err
148+
}
149+
// Verify deployment is ready
150+
if deployed.Status.ReadyReplicas != *deployed.Spec.Replicas {
151+
return fmt.Errorf("deployment not ready: %d/%d replicas ready", deployed.Status.ReadyReplicas, *deployed.Spec.Replicas)
152+
}
153+
if deployed.Status.UpdatedReplicas != *deployed.Spec.Replicas {
154+
return fmt.Errorf("deployment not updated: %d/%d replicas updated", deployed.Status.UpdatedReplicas, *deployed.Spec.Replicas)
155+
}
156+
return nil
157+
}, workloadEventuallyDuration, eventuallyInterval).Should(Succeed(),
158+
"Deployment should be ready on cluster %s", cluster.ClusterName)
159+
}
160+
})
161+
})
162+
})

0 commit comments

Comments
 (0)