From 69a9ee91b754a306459b93d89b66753516b816d1 Mon Sep 17 00:00:00 2001 From: Tomas Tormo Date: Wed, 10 May 2023 09:48:38 +0200 Subject: [PATCH] Provide a generic function to wait and test if a PV is in a given status --- modules/k8s/errors.go | 17 +++++++++-------- modules/k8s/persistent_volume.go | 27 ++++++++++++++------------- modules/k8s/persistent_volume_test.go | 7 +++++-- 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/modules/k8s/errors.go b/modules/k8s/errors.go index 90a0dcdb7..9bd0d7a03 100644 --- a/modules/k8s/errors.go +++ b/modules/k8s/errors.go @@ -132,19 +132,20 @@ type UnknownServiceType struct { service *corev1.Service } -// PersistentVolumeNotAvailable is returned when a Kubernetes PersistentVolume is not available -type PersistentVolumeNotAvailable struct { - pv *corev1.PersistentVolume +// PersistentVolumeNotInStatus is returned when a Kubernetes PersistentVolume is not in the expected status phase +type PersistentVolumeNotInStatus struct { + pv *corev1.PersistentVolume + pvStatusPhase *corev1.PersistentVolumePhase } // Error is a simple function to return a formatted error message as a string -func (err PersistentVolumeNotAvailable) Error() string { - return fmt.Sprintf("Pv %s is not available", err.pv.Name) +func (err PersistentVolumeNotInStatus) Error() string { + return fmt.Sprintf("Pv %s is not '%s'", err.pv.Name, *err.pvStatusPhase) } -// NewPersistentVolumeNotAvailableError returns a PersistentVolumeNotAvailable struct when the given Persistent Volume is not available -func NewPersistentVolumeNotAvailableError(pv *corev1.PersistentVolume) PersistentVolumeNotAvailable { - return PersistentVolumeNotAvailable{pv} +// NewPersistentVolumeNotInStatusError returns a PersistentVolumeNotInStatus struct when the given Persistent Volume is not in the expected status phase +func NewPersistentVolumeNotInStatusError(pv *corev1.PersistentVolume, pvStatusPhase *corev1.PersistentVolumePhase) PersistentVolumeNotInStatus { + return PersistentVolumeNotInStatus{pv, pvStatusPhase} } // Error is a simple function to return a formatted error message as a string diff --git a/modules/k8s/persistent_volume.go b/modules/k8s/persistent_volume.go index ba1947842..dcab514a2 100644 --- a/modules/k8s/persistent_volume.go +++ b/modules/k8s/persistent_volume.go @@ -53,25 +53,26 @@ func GetPersistentVolumeE(t testing.TestingT, options *KubectlOptions, name stri return clientset.CoreV1().PersistentVolumes().Get(context.Background(), name, metav1.GetOptions{}) } -// WaitUntilPersistentVolumeAvailable waits until the given Persistent Volume is the 'Available' status, +// WaitUntilPersistentVolumeInStatus waits until the given Persistent Volume is the given status phase, // retrying the check for the specified amount of times, sleeping // for the provided duration between each try. // This will fail the test if there is an error. -func WaitUntilPersistentVolumeAvailable(t testing.TestingT, options *KubectlOptions, pvName string, retries int, sleepBetweenRetries time.Duration) { - require.NoError(t, WaitUntilPersistentVolumeAvailableE(t, options, pvName, retries, sleepBetweenRetries)) +func WaitUntilPersistentVolumeInStatus(t testing.TestingT, options *KubectlOptions, pvName string, pvStatusPhase *corev1.PersistentVolumePhase, retries int, sleepBetweenRetries time.Duration) { + require.NoError(t, WaitUntilPersistentVolumeInStatusE(t, options, pvName, pvStatusPhase, retries, sleepBetweenRetries)) } -// WaitUntilPersistentVolumeAvailableE waits until the given PersistentVolume is in the 'Available' status, +// WaitUntilPersistentVolumeInStatusE waits until the given PersistentVolume is in the given status phase, // retrying the check for the specified amount of times, sleeping // for the provided duration between each try. -func WaitUntilPersistentVolumeAvailableE( +func WaitUntilPersistentVolumeInStatusE( t testing.TestingT, options *KubectlOptions, pvName string, + pvStatusPhase *corev1.PersistentVolumePhase, retries int, sleepBetweenRetries time.Duration, ) error { - statusMsg := fmt.Sprintf("Wait for Persistent Volume %s to be available", pvName) + statusMsg := fmt.Sprintf("Wait for Persistent Volume %s to be '%s'", pvName, *pvStatusPhase) message, err := retry.DoWithRetryE( t, statusMsg, @@ -82,21 +83,21 @@ func WaitUntilPersistentVolumeAvailableE( if err != nil { return "", err } - if !IsPersistentVolumeAvailable(pv) { - return "", NewPersistentVolumeNotAvailableError(pv) + if !IsPersistentVolumeInStatus(pv, pvStatusPhase) { + return "", NewPersistentVolumeNotInStatusError(pv, pvStatusPhase) } - return "Persistent Volume is now available", nil + return fmt.Sprintf("Persistent Volume is now '%s'", *pvStatusPhase), nil }, ) if err != nil { - logger.Logf(t, "Timeout waiting for PersistentVolume to be available: %s", err) + logger.Logf(t, "Timeout waiting for PersistentVolume to be '%s': %s", *pvStatusPhase, err) return err } logger.Logf(t, message) return nil } -// IsPersistentVolumeAvailable returns true if the given PersistentVolume is available -func IsPersistentVolumeAvailable(pv *corev1.PersistentVolume) bool { - return pv != nil && pv.Status.Phase == corev1.VolumeAvailable +// IsPersistentVolumeInStatus returns true if the given PersistentVolume is in the given status phase +func IsPersistentVolumeInStatus(pv *corev1.PersistentVolume, pvStatusPhase *corev1.PersistentVolumePhase) bool { + return pv != nil && pv.Status.Phase == *pvStatusPhase } diff --git a/modules/k8s/persistent_volume_test.go b/modules/k8s/persistent_volume_test.go index 2048351e7..fd261c5e9 100644 --- a/modules/k8s/persistent_volume_test.go +++ b/modules/k8s/persistent_volume_test.go @@ -17,6 +17,7 @@ import ( "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" _ "k8s.io/client-go/plugin/pkg/client/auth" @@ -79,16 +80,18 @@ func TestGetPersistentVolumeReturnsCorrectPersistentVolume(t *testing.T) { require.Equal(t, pv.Name, pvName) } -func TestWaitUntilPersistentVolumeAvailable(t *testing.T) { +func TestWaitUntilPersistentVolumeInTheGivenStatusPhase(t *testing.T) { t.Parallel() pvName := strings.ToLower(random.UniqueId()) + pvAvailableStatusPhase := corev1.VolumeAvailable + options := NewKubectlOptions("", "", pvName) configData := fmt.Sprintf(PvFixtureYamlTemplate, pvName, pvName) KubectlApplyFromString(t, options, configData) defer KubectlDeleteFromString(t, options, configData) - WaitUntilPersistentVolumeAvailable(t, options, pvName, 60, 1*time.Second) + WaitUntilPersistentVolumeInStatus(t, options, pvName, &pvAvailableStatusPhase, 60, 1*time.Second) } const PvFixtureYamlTemplate = `---