@@ -19,6 +19,7 @@ package e2e
1919import (
2020 "fmt"
2121
22+ "github.com/google/go-cmp/cmp"
2223 . "github.com/onsi/ginkgo/v2"
2324 . "github.com/onsi/gomega"
2425 appsv1 "k8s.io/api/apps/v1"
@@ -37,12 +38,14 @@ var _ = Describe("placing workloads using a CRP with PickAll policy", Label("res
3738 var testDeployment appsv1.Deployment
3839 var testDaemonSet appsv1.DaemonSet
3940 var testJob batchv1.Job
41+ var testStatefulSet appsv1.StatefulSet
4042
4143 BeforeAll (func () {
4244 // Read the test manifests
4345 readDeploymentTestManifest (& testDeployment )
4446 readDaemonSetTestManifest (& testDaemonSet )
4547 readJobTestManifest (& testJob )
48+ readStatefulSetTestManifest (& testStatefulSet , StatefulSetWithStorage )
4649 workNamespace := appNamespace ()
4750
4851 // Create namespace and workloads
@@ -51,9 +54,11 @@ var _ = Describe("placing workloads using a CRP with PickAll policy", Label("res
5154 testDeployment .Namespace = workNamespace .Name
5255 testDaemonSet .Namespace = workNamespace .Name
5356 testJob .Namespace = workNamespace .Name
57+ testStatefulSet .Namespace = workNamespace .Name
5458 Expect (hubClient .Create (ctx , & testDeployment )).To (Succeed (), "Failed to create test deployment %s" , testDeployment .Name )
5559 Expect (hubClient .Create (ctx , & testDaemonSet )).To (Succeed (), "Failed to create test daemonset %s" , testDaemonSet .Name )
5660 Expect (hubClient .Create (ctx , & testJob )).To (Succeed (), "Failed to create test job %s" , testJob .Name )
61+ Expect (hubClient .Create (ctx , & testStatefulSet )).To (Succeed (), "Failed to create test statefulset %s" , testStatefulSet .Name )
5762
5863 // Create the CRP that selects the namespace
5964 By ("creating CRP that selects the namespace" )
@@ -105,9 +110,16 @@ var _ = Describe("placing workloads using a CRP with PickAll policy", Label("res
105110 Name : testJob .Name ,
106111 Namespace : workNamespace .Name ,
107112 },
113+ {
114+ Group : "apps" ,
115+ Version : "v1" ,
116+ Kind : "StatefulSet" ,
117+ Name : testStatefulSet .Name ,
118+ Namespace : workNamespace .Name ,
119+ },
108120 }
109121 // Use customizedPlacementStatusUpdatedActual with resourceIsTrackable=false
110- // because Jobs don't have availability tracking like Deployments/DaemonSets do
122+ // because Jobs don't have availability tracking like Deployments/DaemonSets/StatefulSets do
111123 crpKey := types.NamespacedName {Name : crpName }
112124 crpStatusUpdatedActual := customizedPlacementStatusUpdatedActual (crpKey , wantSelectedResources , allMemberClusterNames , nil , "0" , false )
113125 Eventually (crpStatusUpdatedActual , workloadEventuallyDuration , eventuallyInterval ).Should (Succeed (), "Failed to update CRP status as expected" )
@@ -170,6 +182,13 @@ var _ = Describe("placing workloads using a CRP with PickAll policy", Label("res
170182 "Hub job should complete successfully" )
171183 })
172184
185+ It ("should verify hub statefulset is ready" , func () {
186+ By ("checking hub statefulset status" )
187+ statefulSetReadyActual := waitForStatefulSetToBeReady (hubClient , & testStatefulSet )
188+ Eventually (statefulSetReadyActual , workloadEventuallyDuration , eventuallyInterval ).Should (Succeed (),
189+ "Hub statefulset should be ready before placement" )
190+ })
191+
173192 It ("should place the deployment on all member clusters" , func () {
174193 By ("verifying deployment is placed and ready on all member clusters" )
175194 for idx := range allMemberClusters {
@@ -206,6 +225,24 @@ var _ = Describe("placing workloads using a CRP with PickAll policy", Label("res
206225 }
207226 })
208227
228+ It ("should place the statefulset on all member clusters" , func () {
229+ By ("verifying statefulset is placed and ready on all member clusters" )
230+ for idx := range allMemberClusters {
231+ memberCluster := allMemberClusters [idx ]
232+ statefulsetPlacedActual := waitForStatefulSetPlacementToReady (memberCluster , & testStatefulSet )
233+ Eventually (statefulsetPlacedActual , workloadEventuallyDuration , eventuallyInterval ).Should (Succeed (), "Failed to place statefulset on member cluster %s" , memberCluster .ClusterName )
234+ }
235+ })
236+
237+ It ("should verify statefulset replicas are ready on all clusters" , func () {
238+ By ("checking statefulset status on each cluster" )
239+ for _ , cluster := range allMemberClusters {
240+ statefulSetReadyActual := waitForStatefulSetToBeReady (cluster .KubeClient , & testStatefulSet )
241+ Eventually (statefulSetReadyActual , workloadEventuallyDuration , eventuallyInterval ).Should (Succeed (),
242+ "StatefulSet should be ready on cluster %s" , cluster .ClusterName )
243+ }
244+ })
245+
209246 It ("should verify deployment replicas are ready on all clusters" , func () {
210247 By ("checking deployment status on each cluster" )
211248 for _ , cluster := range allMemberClusters {
@@ -232,6 +269,42 @@ var _ = Describe("placing workloads using a CRP with PickAll policy", Label("res
232269 })
233270})
234271
272+ func waitForStatefulSetToBeReady (kubeClient client.Client , testStatefulSet * appsv1.StatefulSet ) func () error {
273+ return func () error {
274+ var statefulSet appsv1.StatefulSet
275+ if err := kubeClient .Get (ctx , types.NamespacedName {
276+ Name : testStatefulSet .Name ,
277+ Namespace : testStatefulSet .Namespace ,
278+ }, & statefulSet ); err != nil {
279+ return err
280+ }
281+
282+ // Verify statefulset is ready
283+ requiredReplicas := int32 (1 )
284+ if statefulSet .Spec .Replicas != nil {
285+ requiredReplicas = * statefulSet .Spec .Replicas
286+ }
287+
288+ wantStatus := appsv1.StatefulSetStatus {
289+ ObservedGeneration : statefulSet .Generation ,
290+ CurrentReplicas : requiredReplicas ,
291+ UpdatedReplicas : requiredReplicas ,
292+ }
293+
294+ gotStatus := appsv1.StatefulSetStatus {
295+ ObservedGeneration : statefulSet .Status .ObservedGeneration ,
296+ CurrentReplicas : statefulSet .Status .CurrentReplicas ,
297+ UpdatedReplicas : statefulSet .Status .UpdatedReplicas ,
298+ }
299+
300+ if diff := cmp .Diff (wantStatus , gotStatus ); diff != "" {
301+ return fmt .Errorf ("statefulset not ready (-want +got):\n %s" , diff )
302+ }
303+
304+ return nil
305+ }
306+ }
307+
235308func waitForJobToComplete (kubeClient client.Client , testJob * batchv1.Job ) func () error {
236309 return func () error {
237310 var job batchv1.Job
0 commit comments