@@ -29,12 +29,14 @@ import (
29
29
storage "k8s.io/api/storage/v1"
30
30
"k8s.io/apimachinery/pkg/api/resource"
31
31
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
32
+ "k8s.io/apimachinery/pkg/util/wait"
32
33
"k8s.io/apimachinery/pkg/watch"
33
34
utilfeature "k8s.io/apiserver/pkg/util/feature"
34
35
"k8s.io/client-go/informers"
35
36
clientset "k8s.io/client-go/kubernetes"
36
37
restclient "k8s.io/client-go/rest"
37
38
ref "k8s.io/client-go/tools/reference"
39
+ "k8s.io/client-go/util/retry"
38
40
featuregatetesting "k8s.io/component-base/featuregate/testing"
39
41
kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing"
40
42
"k8s.io/kubernetes/pkg/api/legacyscheme"
@@ -284,7 +286,9 @@ func TestPersistentVolumeBindRace(t *testing.T) {
284
286
285
287
waitForPersistentVolumePhase (testClient , pv .Name , watchPV , v1 .VolumeBound )
286
288
klog .V (2 ).Infof ("TestPersistentVolumeBindRace pv bound" )
287
- waitForAnyPersistentVolumeClaimPhase (watchPVC , v1 .ClaimBound )
289
+ if err := waitForAnyPersistentVolumeClaimPhase (watchPVC , v1 .ClaimBound ); err != nil {
290
+ t .Fatalf ("Unexpected error waiting for any pvc to be bound: %v" , err )
291
+ }
288
292
klog .V (2 ).Infof ("TestPersistentVolumeBindRace pvc bound" )
289
293
290
294
pv , err = testClient .CoreV1 ().PersistentVolumes ().Get (context .TODO (), pv .Name , metav1.GetOptions {})
@@ -871,10 +875,11 @@ func TestPersistentVolumeMultiPVsPVCs(t *testing.T) {
871
875
}()
872
876
873
877
// wait until the binder pairs all claims
874
- for i := 0 ; i < objCount ; i ++ {
875
- waitForAnyPersistentVolumeClaimPhase ( watchPVC , v1 . ClaimBound )
876
- klog . V ( 1 ). Infof ( "%d claims bound" , i + 1 )
878
+ err := waitForSomePersistentVolumeClaimPhase ( tCtx , testClient , namespaceName , objCount , watchPVC , v1 . ClaimBound )
879
+ if err != nil {
880
+ t . Fatalf ( "Failed to wait for all claims to be bound: %v " , err )
877
881
}
882
+
878
883
// wait until the binder pairs all volumes
879
884
for i := 0 ; i < objCount ; i ++ {
880
885
waitForPersistentVolumePhase (testClient , pvs [i ].Name , watchPV , v1 .VolumeBound )
@@ -952,7 +957,9 @@ func TestPersistentVolumeControllerStartup(t *testing.T) {
952
957
// Drain watchPVC with all events generated by the PVC until it's bound
953
958
// We don't want to catch "PVC created with Status.Phase == Pending"
954
959
// later in this test.
955
- waitForAnyPersistentVolumeClaimPhase (watchPVC , v1 .ClaimBound )
960
+ if err := waitForAnyPersistentVolumeClaimPhase (watchPVC , v1 .ClaimBound ); err != nil {
961
+ t .Fatalf ("Unexpected error waiting for any pvc to be bound: %v" , err )
962
+ }
956
963
957
964
pv := createPV (pvName , "/tmp/foo" + strconv .Itoa (i ), "1G" ,
958
965
[]v1.PersistentVolumeAccessMode {v1 .ReadWriteOnce }, v1 .PersistentVolumeReclaimRetain )
@@ -1058,34 +1065,6 @@ func TestPersistentVolumeProvisionMultiPVCs(t *testing.T) {
1058
1065
defer testClient .CoreV1 ().PersistentVolumes ().DeleteCollection (context .TODO (), metav1.DeleteOptions {}, metav1.ListOptions {})
1059
1066
defer testClient .StorageV1 ().StorageClasses ().DeleteCollection (context .TODO (), metav1.DeleteOptions {}, metav1.ListOptions {})
1060
1067
1061
- // Watch all events in the namespace, and save them to artifacts for debugging.
1062
- // TODO: This is a temporary solution to debug flaky tests `panic: test timed out after 10m0s`.
1063
- // We should remove this once https://github.com/kubernetes/kubernetes/issues/124136 is fixed.
1064
- go func () {
1065
- w , err := testClient .EventsV1 ().Events (ns .Name ).Watch (tCtx , metav1.ListOptions {})
1066
- if err != nil {
1067
- return
1068
- }
1069
- for {
1070
- select {
1071
- case event , ok := <- w .ResultChan ():
1072
- if ! ok {
1073
- klog .Info ("Event watch channel closed" )
1074
- w , err = testClient .EventsV1 ().Events (ns .Name ).Watch (tCtx , metav1.ListOptions {})
1075
- if err != nil {
1076
- klog .ErrorS (err , "Failed to restart event watch" )
1077
- return
1078
- }
1079
- continue
1080
- }
1081
- reportToArtifacts (t .Name ()+ "-events.text" , event .Object )
1082
- case <- tCtx .Done ():
1083
- w .Stop ()
1084
- return
1085
- }
1086
- }
1087
- }()
1088
-
1089
1068
storageClass := storage.StorageClass {
1090
1069
TypeMeta : metav1.TypeMeta {
1091
1070
Kind : "StorageClass" ,
@@ -1117,9 +1096,9 @@ func TestPersistentVolumeProvisionMultiPVCs(t *testing.T) {
1117
1096
}()
1118
1097
1119
1098
// Wait until the controller provisions and binds all of them
1120
- for i := 0 ; i < objCount ; i ++ {
1121
- waitForAnyPersistentVolumeClaimPhaseAndReportIt ( t , watchPVC , v1 . ClaimBound )
1122
- klog . V ( 1 ). Infof ( "%d claims bound" , i + 1 )
1099
+ err := waitForSomePersistentVolumeClaimPhase ( tCtx , testClient , namespaceName , objCount , watchPVC , v1 . ClaimBound )
1100
+ if err != nil {
1101
+ t . Fatalf ( "Failed to wait for all claims to be bound: %v " , err )
1123
1102
}
1124
1103
klog .V (2 ).Infof ("TestPersistentVolumeProvisionMultiPVCs: claims are bound" )
1125
1104
@@ -1488,31 +1467,40 @@ func waitForAnyPersistentVolumePhase(w watch.Interface, phase v1.PersistentVolum
1488
1467
}
1489
1468
}
1490
1469
1491
- func waitForAnyPersistentVolumeClaimPhase (w watch.Interface , phase v1.PersistentVolumeClaimPhase ) {
1492
- for {
1493
- event := <- w .ResultChan ()
1494
- claim , ok := event .Object .(* v1.PersistentVolumeClaim )
1495
- if ! ok {
1496
- continue
1497
- }
1498
- if claim .Status .Phase == phase {
1499
- klog .V (2 ).Infof ("claim %q is %s" , claim .Name , phase )
1500
- break
1470
+ func waitForSomePersistentVolumeClaimPhase (ctx context.Context , testClient clientset.Interface , namespace string , objCount int , watchPVC watch.Interface , phase v1.PersistentVolumeClaimPhase ) error {
1471
+ return wait .ExponentialBackoffWithContext (ctx , retry .DefaultBackoff , func (ctx context.Context ) (bool , error ) {
1472
+ for i := 0 ; i < objCount ; i ++ {
1473
+ waitErr := waitForAnyPersistentVolumeClaimPhase (watchPVC , v1 .ClaimBound )
1474
+ if waitErr != nil {
1475
+ klog .Errorf ("Failed to wait for a claim (%d/%d) to be bound: %v" , i + 1 , objCount , waitErr )
1476
+ klog .Info ("Recreating a watch for claims and re-checking the count of bound claims" )
1477
+ newWatchPVC , err := testClient .CoreV1 ().PersistentVolumeClaims (namespace ).Watch (ctx , metav1.ListOptions {})
1478
+ if err != nil {
1479
+ return false , err
1480
+ }
1481
+ watchPVC .Stop ()
1482
+ watchPVC = newWatchPVC
1483
+ return false , waitErr
1484
+ }
1485
+ klog .V (1 ).Infof ("%d claims bound" , i + 1 )
1501
1486
}
1502
- }
1487
+ return true , nil
1488
+ })
1503
1489
}
1504
1490
1505
- func waitForAnyPersistentVolumeClaimPhaseAndReportIt ( t * testing. T , w watch.Interface , phase v1.PersistentVolumeClaimPhase ) {
1491
+ func waitForAnyPersistentVolumeClaimPhase ( w watch.Interface , phase v1.PersistentVolumeClaimPhase ) error {
1506
1492
for {
1507
- event := <- w .ResultChan ()
1508
- reportToArtifacts (t .Name ()+ "-watched-pvcs.text" , event )
1493
+ event , ok := <- w .ResultChan ()
1494
+ if ! ok {
1495
+ return fmt .Errorf ("watch closed" )
1496
+ }
1509
1497
claim , ok := event .Object .(* v1.PersistentVolumeClaim )
1510
1498
if ! ok {
1511
1499
continue
1512
1500
}
1513
1501
if claim .Status .Phase == phase {
1514
1502
klog .V (2 ).Infof ("claim %q is %s" , claim .Name , phase )
1515
- break
1503
+ return nil
1516
1504
}
1517
1505
}
1518
1506
}
0 commit comments