@@ -38,17 +38,34 @@ var _ = Describe("AppWrapper Controller", func() {
3838 var awReconciler * AppWrapperReconciler
3939 var awName types.NamespacedName
4040 markerPodSet := podset.PodSetInfo {
41- Labels : map [string ]string {"testkey1" : "value1" },
42- Annotations : map [string ]string {"test2" : "test2" },
41+ Labels : map [string ]string {"testkey1" : "value1" },
42+ Annotations : map [string ]string {"test2" : "test2" },
43+ NodeSelector : map [string ]string {"nodeName" : "myNode" },
44+ Tolerations : []v1.Toleration {{Key : "aKey" , Operator : "Exists" , Effect : "NoSchedule" }},
4345 }
4446 var kueuePodSets []kueue.PodSet
4547
46- advanceToRunning := func () {
48+ advanceToResuming := func (components ... workloadv1beta2.AppWrapperComponent ) {
49+ By ("Create an AppWrapper" )
50+ aw := toAppWrapper (components ... )
51+ aw .Spec .Suspend = true
52+ Expect (k8sClient .Create (ctx , aw )).To (Succeed ())
53+ awName = types.NamespacedName {
54+ Name : aw .Name ,
55+ Namespace : aw .Namespace ,
56+ }
57+ awReconciler = & AppWrapperReconciler {
58+ Client : k8sClient ,
59+ Scheme : k8sClient .Scheme (),
60+ Config : & config.AppWrapperConfig {ManageJobsWithoutQueueName : true , StandaloneMode : false },
61+ }
62+ kueuePodSets = (* workload .AppWrapper )(aw ).PodSets ()
63+
4764 By ("Reconciling: Empty -> Suspended" )
4865 _ , err := awReconciler .Reconcile (ctx , reconcile.Request {NamespacedName : awName })
4966 Expect (err ).NotTo (HaveOccurred ())
5067
51- aw : = getAppWrapper (awName )
68+ aw = getAppWrapper (awName )
5269 Expect (aw .Status .Phase ).Should (Equal (workloadv1beta2 .AppWrapperSuspended ))
5370 Expect (controllerutil .ContainsFinalizer (aw , AppWrapperFinalizer )).Should (BeTrue ())
5471
@@ -67,12 +84,14 @@ var _ = Describe("AppWrapper Controller", func() {
6784 Expect (meta .IsStatusConditionTrue (aw .Status .Conditions , string (workloadv1beta2 .QuotaReserved ))).Should (BeTrue ())
6885 Expect ((* workload .AppWrapper )(aw ).IsActive ()).Should (BeTrue ())
6986 Expect ((* workload .AppWrapper )(aw ).IsSuspended ()).Should (BeFalse ())
87+ }
7088
89+ beginRunning := func () {
7190 By ("Reconciling: Resuming -> Running" )
72- _ , err = awReconciler .Reconcile (ctx , reconcile.Request {NamespacedName : awName })
91+ _ , err : = awReconciler .Reconcile (ctx , reconcile.Request {NamespacedName : awName })
7392 Expect (err ).NotTo (HaveOccurred ())
7493
75- aw = getAppWrapper (awName )
94+ aw : = getAppWrapper (awName )
7695 Expect (aw .Status .Phase ).Should (Equal (workloadv1beta2 .AppWrapperRunning ))
7796 Expect (meta .IsStatusConditionTrue (aw .Status .Conditions , string (workloadv1beta2 .ResourcesDeployed ))).Should (BeTrue ())
7897 Expect (meta .IsStatusConditionTrue (aw .Status .Conditions , string (workloadv1beta2 .QuotaReserved ))).Should (BeTrue ())
@@ -83,10 +102,30 @@ var _ = Describe("AppWrapper Controller", func() {
83102 Expect (err ).NotTo (HaveOccurred ())
84103 Expect (podStatus .pending ).Should (Equal (utils .ExpectedPodCount (aw )))
85104
105+ By ("Simulating first Pod Running" )
106+ Expect (setPodStatus (aw , v1 .PodRunning , 1 )).To (Succeed ())
107+ By ("Reconciling: Running -> Running" )
108+ _ , err = awReconciler .Reconcile (ctx , reconcile.Request {NamespacedName : awName })
109+ Expect (err ).NotTo (HaveOccurred ())
110+
111+ aw = getAppWrapper (awName )
112+ Expect (aw .Status .Phase ).Should (Equal (workloadv1beta2 .AppWrapperRunning ))
113+ Expect (meta .IsStatusConditionTrue (aw .Status .Conditions , string (workloadv1beta2 .ResourcesDeployed ))).Should (BeTrue ())
114+ Expect (meta .IsStatusConditionTrue (aw .Status .Conditions , string (workloadv1beta2 .QuotaReserved ))).Should (BeTrue ())
115+ Expect (meta .IsStatusConditionTrue (aw .Status .Conditions , string (workloadv1beta2 .PodsReady ))).Should (BeFalse ())
116+ Expect ((* workload .AppWrapper )(aw ).IsActive ()).Should (BeTrue ())
117+ Expect ((* workload .AppWrapper )(aw ).IsSuspended ()).Should (BeFalse ())
118+ podStatus , err = awReconciler .workloadStatus (ctx , aw )
119+ Expect (err ).NotTo (HaveOccurred ())
120+ Expect (podStatus .pending ).Should (Equal (utils .ExpectedPodCount (aw ) - 1 ))
121+ }
122+
123+ fullyRunning := func () {
124+ aw := getAppWrapper (awName )
86125 By ("Simulating all Pods Running" )
87126 Expect (setPodStatus (aw , v1 .PodRunning , utils .ExpectedPodCount (aw ))).To (Succeed ())
88127 By ("Reconciling: Running -> Running" )
89- _ , err = awReconciler .Reconcile (ctx , reconcile.Request {NamespacedName : awName })
128+ _ , err : = awReconciler .Reconcile (ctx , reconcile.Request {NamespacedName : awName })
90129 Expect (err ).NotTo (HaveOccurred ())
91130
92131 aw = getAppWrapper (awName )
@@ -97,30 +136,13 @@ var _ = Describe("AppWrapper Controller", func() {
97136 Expect ((* workload .AppWrapper )(aw ).IsActive ()).Should (BeTrue ())
98137 Expect ((* workload .AppWrapper )(aw ).IsSuspended ()).Should (BeFalse ())
99138 Expect ((* workload .AppWrapper )(aw ).PodsReady ()).Should (BeTrue ())
100- podStatus , err = awReconciler .workloadStatus (ctx , aw )
139+ podStatus , err : = awReconciler .workloadStatus (ctx , aw )
101140 Expect (err ).NotTo (HaveOccurred ())
102141 Expect (podStatus .running ).Should (Equal (utils .ExpectedPodCount (aw )))
103142 _ , finished := (* workload .AppWrapper )(aw ).Finished ()
104143 Expect (finished ).Should (BeFalse ())
105144 }
106145
107- BeforeEach (func () {
108- By ("Create an AppWrapper containing two Pods" )
109- aw := toAppWrapper (pod (100 ), pod (100 ))
110- aw .Spec .Suspend = true
111- Expect (k8sClient .Create (ctx , aw )).To (Succeed ())
112- awName = types.NamespacedName {
113- Name : aw .Name ,
114- Namespace : aw .Namespace ,
115- }
116- awReconciler = & AppWrapperReconciler {
117- Client : k8sClient ,
118- Scheme : k8sClient .Scheme (),
119- Config : & config.AppWrapperConfig {ManageJobsWithoutQueueName : true , StandaloneMode : false },
120- }
121- kueuePodSets = (* workload .AppWrapper )(aw ).PodSets ()
122- })
123-
124146 AfterEach (func () {
125147 By ("Cleanup the AppWrapper and ensure no Pods remain" )
126148 aw := & workloadv1beta2.AppWrapper {}
@@ -139,7 +161,9 @@ var _ = Describe("AppWrapper Controller", func() {
139161 })
140162
141163 It ("Happy Path Lifecycle" , func () {
142- advanceToRunning ()
164+ advanceToResuming (pod (100 ), pod (100 ))
165+ beginRunning ()
166+ fullyRunning ()
143167
144168 By ("Simulating one Pod Completing" )
145169 aw := getAppWrapper (awName )
@@ -176,9 +200,11 @@ var _ = Describe("AppWrapper Controller", func() {
176200 })
177201
178202 It ("Running Workloads can be Suspended" , func () {
179- advanceToRunning ()
203+ advanceToResuming (pod (100 ), pod (100 ))
204+ beginRunning ()
205+ fullyRunning ()
180206
181- By ("Updating aw.Spec by invoking RunWithPodSetsInfo " )
207+ By ("Inoking Suspend and RestorePodSetsInfo " )
182208 aw := getAppWrapper (awName )
183209 (* workload .AppWrapper )(aw ).Suspend ()
184210 Expect ((* workload .AppWrapper )(aw ).RestorePodSetsInfo (utilslices .Map (kueuePodSets , podset .FromPodSet ))).To (BeTrue ())
@@ -212,8 +238,10 @@ var _ = Describe("AppWrapper Controller", func() {
212238 Expect (podStatus .failed + podStatus .succeeded + podStatus .running + podStatus .pending ).Should (Equal (int32 (0 )))
213239 })
214240
215- It ("A Pod Failure leads to a failed AppWrappers" , func () {
216- advanceToRunning ()
241+ It ("A Pod Failure leads to a failed AppWrapper" , func () {
242+ advanceToResuming (pod (100 ), pod (100 ))
243+ beginRunning ()
244+ fullyRunning ()
217245
218246 By ("Simulating one Pod Failing" )
219247 aw := getAppWrapper (awName )
@@ -248,4 +276,23 @@ var _ = Describe("AppWrapper Controller", func() {
248276 Expect (finished ).Should (BeTrue ())
249277 })
250278
279+ It ("Failure during resource creation leads to a failed AppWrapper" , func () {
280+ advanceToResuming (pod (100 ), malformedPod (100 ))
281+
282+ By ("Reconciling: Resuming -> Failed" )
283+ _ , err := awReconciler .Reconcile (ctx , reconcile.Request {NamespacedName : awName })
284+ Expect (err ).NotTo (HaveOccurred ())
285+
286+ aw := getAppWrapper (awName )
287+ Expect (aw .Status .Phase ).Should (Equal (workloadv1beta2 .AppWrapperFailed ))
288+ Expect (meta .IsStatusConditionTrue (aw .Status .Conditions , string (workloadv1beta2 .ResourcesDeployed ))).Should (BeTrue ())
289+ Expect (meta .IsStatusConditionTrue (aw .Status .Conditions , string (workloadv1beta2 .QuotaReserved ))).Should (BeTrue ())
290+ Expect (meta .IsStatusConditionTrue (aw .Status .Conditions , string (workloadv1beta2 .PodsReady ))).Should (BeFalse ())
291+ Expect ((* workload .AppWrapper )(aw ).IsActive ()).Should (BeTrue ())
292+ Expect ((* workload .AppWrapper )(aw ).IsSuspended ()).Should (BeFalse ())
293+ podStatus , err := awReconciler .workloadStatus (ctx , aw )
294+ Expect (err ).NotTo (HaveOccurred ())
295+ Expect (podStatus .pending ).Should (Equal (int32 (1 )))
296+ })
297+
251298})
0 commit comments