@@ -20,6 +20,7 @@ import (
2020 "context"
2121 "fmt"
2222 "math/rand"
23+ "strings"
2324 "time"
2425
2526 "sigs.k8s.io/blob-csi-driver/pkg/blob"
@@ -35,6 +36,8 @@ import (
3536 "k8s.io/apimachinery/pkg/api/resource"
3637 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3738 "k8s.io/apimachinery/pkg/fields"
39+ "k8s.io/apimachinery/pkg/util/errors"
40+ "k8s.io/apimachinery/pkg/util/wait"
3841 clientset "k8s.io/client-go/kubernetes"
3942 "k8s.io/kubernetes/pkg/kubelet/events"
4043 "k8s.io/kubernetes/test/e2e/framework"
@@ -54,8 +57,9 @@ const (
5457 // Description that will printed during tests
5558 failedConditionDescription = "Error status code"
5659
57- poll = 2 * time .Second
58- pollLongTimeout = 5 * time .Minute
60+ poll = 2 * time .Second
61+ pollLongTimeout = 5 * time .Minute
62+ pollForStringTimeout = 1 * time .Minute
5963)
6064
6165type TestStorageClass struct {
@@ -379,6 +383,10 @@ func (t *TestDeployment) Exec(command []string, expectedString string) {
379383 framework .ExpectNoError (err )
380384}
381385
386+ func (t * TestDeployment ) PollForStringInPodsExec (command []string , expectedString string ) {
387+ pollForStringInPodsExec (t .namespace .Name , []string {t .podName }, command , expectedString )
388+ }
389+
382390func (t * TestDeployment ) DeletePodAndWait () {
383391 e2elog .Logf ("Deleting pod %q in namespace %q" , t .podName , t .namespace .Name )
384392 err := t .client .CoreV1 ().Pods (t .namespace .Name ).Delete (context .TODO (), t .podName , metav1.DeleteOptions {})
@@ -629,3 +637,33 @@ func waitForPersistentVolumeClaimDeleted(c clientset.Interface, ns string, pvcNa
629637 }
630638 return fmt .Errorf ("PersistentVolumeClaim %s is not removed from the system within %v" , pvcName , timeout )
631639}
640+
641+ func pollForStringWorker (namespace string , pod string , command []string , expectedString string , ch chan <- error ) {
642+ args := append ([]string {"exec" , pod , "--" }, command ... )
643+ err := wait .PollImmediate (poll , pollForStringTimeout , func () (bool , error ) {
644+ stdout , err := framework .RunKubectl (namespace , args ... )
645+ if err != nil {
646+ framework .Logf ("Error waiting for output %q in pod %q: %v." , expectedString , pod , err )
647+ return false , nil
648+ }
649+ if ! strings .Contains (stdout , expectedString ) {
650+ framework .Logf ("The stdout did not contain output %q in pod %q, found: %q." , expectedString , pod , stdout )
651+ return false , nil
652+ }
653+ return true , nil
654+ })
655+ ch <- err
656+ }
657+
658+ // Execute the command for all pods in the namespace, looking for expectedString in stdout
659+ func pollForStringInPodsExec (namespace string , pods []string , command []string , expectedString string ) {
660+ ch := make (chan error , len (pods ))
661+ for _ , pod := range pods {
662+ go pollForStringWorker (namespace , pod , command , expectedString , ch )
663+ }
664+ errs := make ([]error , 0 , len (pods ))
665+ for range pods {
666+ errs = append (errs , <- ch )
667+ }
668+ framework .ExpectNoError (errors .NewAggregate (errs ), "Failed to find %q in at least one pod's output." , expectedString )
669+ }
0 commit comments