@@ -77,6 +77,7 @@ const (
77
77
createNamespacesOpcode operationCode = "createNamespaces"
78
78
createPodsOpcode operationCode = "createPods"
79
79
createPodSetsOpcode operationCode = "createPodSets"
80
+ deletePodsOpcode operationCode = "deletePods"
80
81
createResourceClaimsOpcode operationCode = "createResourceClaims"
81
82
createResourceDriverOpcode operationCode = "createResourceDriver"
82
83
churnOpcode operationCode = "churn"
@@ -407,6 +408,7 @@ func (op *op) UnmarshalJSON(b []byte) error {
407
408
& createNamespacesOp {},
408
409
& createPodsOp {},
409
410
& createPodSetsOp {},
411
+ & deletePodsOp {},
410
412
& createResourceClaimsOp {},
411
413
& createResourceDriverOp {},
412
414
& churnOp {},
@@ -586,9 +588,6 @@ type createPodsOp struct {
586
588
// Optional
587
589
PersistentVolumeTemplatePath * string
588
590
PersistentVolumeClaimTemplatePath * string
589
- // Number of pods to be deleted per second after they were scheduled. If set to 0, pods are not deleted.
590
- // Optional
591
- DeletePodsPerSecond int
592
591
}
593
592
594
593
func (cpo * createPodsOp ) isValid (allowParameterization bool ) error {
@@ -604,9 +603,6 @@ func (cpo *createPodsOp) isValid(allowParameterization bool) error {
604
603
// use-cases right now.
605
604
return fmt .Errorf ("collectMetrics and skipWaitToCompletion cannot be true at the same time" )
606
605
}
607
- if cpo .DeletePodsPerSecond < 0 {
608
- return fmt .Errorf ("invalid DeletePodsPerSecond=%d; should be non-negative" , cpo .DeletePodsPerSecond )
609
- }
610
606
return nil
611
607
}
612
608
@@ -665,6 +661,46 @@ func (cpso createPodSetsOp) patchParams(w *workload) (realOp, error) {
665
661
return & cpso , (& cpso ).isValid (true )
666
662
}
667
663
664
+ // deletePodsOp defines an op where previously created pods are deleted.
665
+ // The test can block on the completion of this op before moving forward or
666
+ // continue asynchronously.
667
+ type deletePodsOp struct {
668
+ // Must be "deletePods".
669
+ Opcode operationCode
670
+ // Namespace the pods should be deleted from.
671
+ Namespace string
672
+ // Labels used to filter the pods to delete.
673
+ // If empty, it will delete all Pods in the namespace.
674
+ // Optional.
675
+ LabelSelector map [string ]string
676
+ // Whether or not to wait for all pods in this op to be deleted.
677
+ // Defaults to false if not specified.
678
+ // Optional
679
+ SkipWaitToCompletion bool
680
+ // Number of pods to be deleted per second.
681
+ // If zero, all pods are deleted at once.
682
+ // Optional
683
+ DeletePodsPerSecond int
684
+ }
685
+
686
+ func (dpo * deletePodsOp ) isValid (allowParameterization bool ) error {
687
+ if dpo .Opcode != deletePodsOpcode {
688
+ return fmt .Errorf ("invalid opcode %q; expected %q" , dpo .Opcode , deletePodsOpcode )
689
+ }
690
+ if dpo .DeletePodsPerSecond < 0 {
691
+ return fmt .Errorf ("invalid DeletePodsPerSecond=%d; should be non-negative" , dpo .DeletePodsPerSecond )
692
+ }
693
+ return nil
694
+ }
695
+
696
+ func (dpo * deletePodsOp ) collectsMetrics () bool {
697
+ return false
698
+ }
699
+
700
+ func (dpo deletePodsOp ) patchParams (w * workload ) (realOp , error ) {
701
+ return & dpo , nil
702
+ }
703
+
668
704
// churnOp defines an op where services are created as a part of a workload.
669
705
type churnOp struct {
670
706
// Must be "churnOp".
@@ -1227,32 +1263,53 @@ func runWorkload(tCtx ktesting.TContext, tc *testCase, w *workload, informerFact
1227
1263
mu .Unlock ()
1228
1264
}
1229
1265
1230
- if concreteOp .DeletePodsPerSecond > 0 {
1231
- pods , err := podInformer .Lister ().Pods (namespace ).List (labels .Everything ())
1232
- if err != nil {
1233
- tCtx .Fatalf ("op %d: error in listing scheduled pods in the namespace: %v" , opIndex , err )
1234
- }
1266
+ case * deletePodsOp :
1267
+ labelSelector := labels .ValidatedSetSelector (concreteOp .LabelSelector )
1235
1268
1236
- ticker := time .NewTicker (time .Second / time .Duration (concreteOp .DeletePodsPerSecond ))
1237
- defer ticker .Stop ()
1269
+ podsToDelete , err := podInformer .Lister ().Pods (concreteOp .Namespace ).List (labelSelector )
1270
+ if err != nil {
1271
+ tCtx .Fatalf ("op %d: error in listing pods in the namespace %s: %v" , opIndex , concreteOp .Namespace , err )
1272
+ }
1238
1273
1239
- wg .Add (1 )
1240
- go func (opIndex int ) {
1241
- defer wg .Done ()
1242
- for i := 0 ; i < len (pods ); i ++ {
1274
+ deletePods := func (opIndex int ) {
1275
+ if concreteOp .DeletePodsPerSecond > 0 {
1276
+ ticker := time .NewTicker (time .Second / time .Duration (concreteOp .DeletePodsPerSecond ))
1277
+ defer ticker .Stop ()
1278
+
1279
+ for i := 0 ; i < len (podsToDelete ); i ++ {
1243
1280
select {
1244
1281
case <- ticker .C :
1245
- if err := tCtx .Client ().CoreV1 ().Pods (namespace ).Delete (tCtx , pods [i ].Name , metav1.DeleteOptions {}); err != nil {
1282
+ if err := tCtx .Client ().CoreV1 ().Pods (concreteOp . Namespace ).Delete (tCtx , podsToDelete [i ].Name , metav1.DeleteOptions {}); err != nil {
1246
1283
if errors .Is (err , context .Canceled ) {
1247
1284
return
1248
1285
}
1249
- tCtx .Errorf ("op %d: unable to delete pod %v: %v" , opIndex , pods [i ].Name , err )
1286
+ tCtx .Errorf ("op %d: unable to delete pod %v: %v" , opIndex , podsToDelete [i ].Name , err )
1250
1287
}
1251
1288
case <- tCtx .Done ():
1252
1289
return
1253
1290
}
1254
1291
}
1292
+ return
1293
+ }
1294
+ listOpts := metav1.ListOptions {
1295
+ LabelSelector : labelSelector .String (),
1296
+ }
1297
+ if err := tCtx .Client ().CoreV1 ().Pods (concreteOp .Namespace ).DeleteCollection (tCtx , metav1.DeleteOptions {}, listOpts ); err != nil {
1298
+ if errors .Is (err , context .Canceled ) {
1299
+ return
1300
+ }
1301
+ tCtx .Errorf ("op %d: unable to delete pods in namespace %v: %v" , opIndex , concreteOp .Namespace , err )
1302
+ }
1303
+ }
1304
+
1305
+ if concreteOp .SkipWaitToCompletion {
1306
+ wg .Add (1 )
1307
+ go func (opIndex int ) {
1308
+ defer wg .Done ()
1309
+ deletePods (opIndex )
1255
1310
}(opIndex )
1311
+ } else {
1312
+ deletePods (opIndex )
1256
1313
}
1257
1314
1258
1315
case * churnOp :
0 commit comments