@@ -32,8 +32,10 @@ package controller
3232
3333import (
3434 "context"
35+ "encoding/json"
3536 gerrors "errors"
3637 "fmt"
38+ "net"
3739 "reflect"
3840 "sync"
3941 "testing"
@@ -57,7 +59,9 @@ import (
5759 "k8s.io/apimachinery/pkg/util/rand"
5860 utilruntime "k8s.io/apimachinery/pkg/util/runtime"
5961 "k8s.io/client-go/tools/record"
62+ "k8s.io/client-go/util/retry"
6063 "k8s.io/utils/ptr"
64+ "k8s.io/utils/set"
6165 "sigs.k8s.io/controller-runtime/pkg/client"
6266 "sigs.k8s.io/controller-runtime/pkg/client/fake"
6367 "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
@@ -122,18 +126,49 @@ var _ = Describe("BatchSandbox Controller", func() {
122126 err := k8sClient .Get (ctx , typeNamespacedName , resource )
123127 if ! errors .IsNotFound (err ) {
124128 Expect (err ).NotTo (HaveOccurred ())
129+ } else {
130+ return
125131 }
126132 By (fmt .Sprintf ("Cleanup the specific resource instance BatchSandbox %s" , typeNamespacedName ))
127133 Expect (k8sClient .Delete (ctx , resource )).To (Succeed ())
128134 })
129- It ("should successfully update batch sandbox status" , func () {
135+ It ("should successfully create pod, update batch sandbox status, endpoints info" , func () {
136+ wantIPSet := make (set.Set [string ])
130137 Eventually (func (g Gomega ) {
131138 bs := & sandboxv1alpha1.BatchSandbox {}
132139 if err := k8sClient .Get (ctx , typeNamespacedName , bs ); err != nil {
133140 return
134141 }
142+ allPods := & corev1.PodList {}
143+ g .Expect (k8sClient .List (ctx , allPods , & client.ListOptions {Namespace : bs .Namespace })).Should (Succeed ())
144+ pods := []* corev1.Pod {}
145+ for i := range allPods .Items {
146+ po := & allPods .Items [i ]
147+ if metav1 .IsControlledBy (po , bs ) {
148+ pods = append (pods , po )
149+ if po .Status .PodIP != "" {
150+ continue
151+ }
152+ // patch status to make pod Scheduled
153+ mockIP := randomIPv4 ().String ()
154+ wantIPSet .Insert (mockIP )
155+ po .Status .PodIP = mockIP
156+ po .Status .Phase = corev1 .PodRunning
157+ po .Status .Conditions = []corev1.PodCondition {{Type : corev1 .PodReady , Status : corev1 .ConditionTrue }}
158+ Expect (k8sClient .Status ().Update (context .Background (), po )).To (Succeed ())
159+ }
160+ }
161+ g .Expect (len (pods )).To (Equal (int (* bs .Spec .Replicas )))
135162 g .Expect (bs .Status .ObservedGeneration ).To (Equal (bs .Generation ))
136163 g .Expect (bs .Status .Replicas ).To (Equal (* bs .Spec .Replicas ))
164+ g .Expect (bs .Status .Allocated ).To (Equal (* bs .Spec .Replicas ))
165+ g .Expect (bs .Status .Ready ).To (Equal (* bs .Spec .Replicas ))
166+
167+ gotIPs := []string {}
168+ if raw := bs .Annotations [AnnotationSandboxEndpoints ]; raw != "" {
169+ json .Unmarshal ([]byte (raw ), & gotIPs )
170+ }
171+ g .Expect (wantIPSet .Equal (set .New (gotIPs ... ))).To (BeTrue (), fmt .Sprintf ("wantIPSet %v, gotIPs %v" , wantIPSet .SortedList (), gotIPs ))
137172 }, timeout , interval ).Should (Succeed ())
138173 })
139174 It ("should successfully correctly create new Pod and update batch sandbox status when user scale out" , func () {
@@ -190,6 +225,33 @@ var _ = Describe("BatchSandbox Controller", func() {
190225 g .Expect (newPod .CreationTimestamp ).NotTo (Equal (oldPod .CreationTimestamp ))
191226 }, timeout , interval ).Should (Succeed ())
192227 })
228+ It ("should delete batch sandbox and related Pods for expired batch sandbox" , func () {
229+ Expect (retry .RetryOnConflict (retry .DefaultRetry , func () error {
230+ bs := & sandboxv1alpha1.BatchSandbox {}
231+ if err := k8sClient .Get (ctx , typeNamespacedName , bs ); err != nil {
232+ return err
233+ }
234+ bs .Spec .ExpireTime = & metav1.Time {Time : time .Now ().Add (3 * time .Second )}
235+ return k8sClient .Update (ctx , bs )
236+ })).Should (Succeed ())
237+
238+ Eventually (
239+ func (g Gomega ) {
240+ bs := & sandboxv1alpha1.BatchSandbox {}
241+ g .Expect (errors .IsNotFound (k8sClient .Get (ctx , typeNamespacedName , bs ))).To (BeTrue ())
242+ allPods := & corev1.PodList {}
243+ g .Expect (k8sClient .List (ctx , allPods , & client.ListOptions {Namespace : bs .Namespace })).Should (Succeed ())
244+ pods := []* corev1.Pod {}
245+ for i := range allPods .Items {
246+ po := & allPods .Items [i ]
247+ if metav1 .IsControlledBy (po , bs ) {
248+ pods = append (pods , po )
249+ }
250+ }
251+ g .Expect (len (pods )).To (BeZero ())
252+ },
253+ timeout , interval ).Should (Succeed ())
254+ })
193255 })
194256
195257 // Pooling Mode
@@ -233,7 +295,7 @@ var _ = Describe("BatchSandbox Controller", func() {
233295 Expect (k8sClient .Delete (ctx , resource )).To (Succeed ())
234296 })
235297
236- It ("should successfully update batch sandbox status when get pod from pool alloc" , func () {
298+ It ("should successfully update batch sandbox status, sbx endpoints info when get pod from pool alloc" , func () {
237299 // mock pool allocation
238300 mockPods := []string {}
239301 for i := range replicas {
@@ -256,10 +318,14 @@ var _ = Describe("BatchSandbox Controller", func() {
256318 po .Status .Conditions = []corev1.PodCondition {{Type : corev1 .PodReady , Status : corev1 .ConditionTrue }}
257319 Expect (k8sClient .Status ().Update (context .Background (), po )).To (Succeed ())
258320 }
259- bs := & sandboxv1alpha1.BatchSandbox {}
260- Expect (k8sClient .Get (ctx , typeNamespacedName , bs )).To (Succeed ())
261- setSandboxAllocation (bs , SandboxAllocation {Pods : mockPods })
262- Expect (k8sClient .Update (ctx , bs )).To (Succeed ())
321+ Expect (retry .RetryOnConflict (retry .DefaultRetry , func () error {
322+ bs := & sandboxv1alpha1.BatchSandbox {}
323+ if err := k8sClient .Get (ctx , typeNamespacedName , bs ); err != nil {
324+ return err
325+ }
326+ setSandboxAllocation (bs , SandboxAllocation {Pods : mockPods })
327+ return k8sClient .Update (ctx , bs )
328+ })).Should (Succeed ())
263329 By (fmt .Sprintf ("Mock pool allocate Pod %v for BatchSandbox %s" , mockPods , typeNamespacedName ))
264330
265331 Eventually (func (g Gomega ) {
@@ -271,11 +337,22 @@ var _ = Describe("BatchSandbox Controller", func() {
271337 g .Expect (bs .Status .Replicas ).To (Equal (* bs .Spec .Replicas ))
272338 g .Expect (bs .Status .Allocated ).To (Equal (* bs .Spec .Replicas ))
273339 g .Expect (bs .Status .Ready ).To (Equal (* bs .Spec .Replicas ))
340+
341+ g .Expect (bs .Annotations [AnnotationSandboxEndpoints ]).To (Equal ("[\" 1.2.3.4\" ]" ))
274342 }, timeout , interval ).Should (Succeed ())
275343 })
276344 })
277345})
278346
347+ func randomIPv4 () net.IP {
348+ rand .Seed (time .Now ().UnixNano ())
349+ ip := make (net.IP , 4 )
350+ for i := range ip {
351+ ip [i ] = byte (rand .Intn (256 ))
352+ }
353+ return ip
354+ }
355+
279356var _ = Describe ("BatchSandbox Task Scheduler" , func () {
280357 var (
281358 timeout = 30 * time .Second
0 commit comments