diff --git a/test/e2e/framework/pod/exec_util.go b/test/e2e/framework/pod/exec_util.go index 95a4d70b23c..dbfed28e48e 100644 --- a/test/e2e/framework/pod/exec_util.go +++ b/test/e2e/framework/pod/exec_util.go @@ -20,6 +20,7 @@ import ( "bytes" "context" "errors" + "fmt" "io" "net/url" "strings" @@ -144,40 +145,40 @@ func ExecShellInPodWithFullOutput(ctx context.Context, f *framework.Framework, p } // VerifyExecInPodSucceed verifies shell cmd in target pod succeed -func VerifyExecInPodSucceed(ctx context.Context, f *framework.Framework, pod *v1.Pod, shExec string) { +func VerifyExecInPodSucceed(ctx context.Context, f *framework.Framework, pod *v1.Pod, shExec string) error { stdout, stderr, err := ExecShellInPodWithFullOutput(ctx, f, pod.Name, shExec) if err != nil { var exitError clientexec.CodeExitError if errors.As(err, &exitError) { exitCode := exitError.ExitStatus() - framework.ExpectNoError(err, - "%q should succeed, but failed with exit code %d and error message %q\nstdout: %s\nstderr: %s", + return fmt.Errorf("%q should succeed, but failed with exit code %d and error message %w\nstdout: %s\nstderr: %s", shExec, exitCode, exitError, stdout, stderr) } else { - framework.ExpectNoError(err, - "%q should succeed, but failed with error message %q\nstdout: %s\nstderr: %s", + return fmt.Errorf("%q should succeed, but failed with error message %w\nstdout: %s\nstderr: %s", shExec, err, stdout, stderr) } } + return nil } // VerifyExecInPodFail verifies shell cmd in target pod fail with certain exit code -func VerifyExecInPodFail(ctx context.Context, f *framework.Framework, pod *v1.Pod, shExec string, exitCode int) { +func VerifyExecInPodFail(ctx context.Context, f *framework.Framework, pod *v1.Pod, shExec string, exitCode int) error { stdout, stderr, err := ExecShellInPodWithFullOutput(ctx, f, pod.Name, shExec) if err != nil { var exitError clientexec.CodeExitError if errors.As(err, &exitError) { actualExitCode := exitError.ExitStatus() - gomega.Expect(actualExitCode).To(gomega.Equal(exitCode), - "%q should fail with exit code %d, but failed with exit code %d and error message %q\nstdout: %s\nstderr: %s", + if actualExitCode == exitCode { + return nil + } + return fmt.Errorf("%q should fail with exit code %d, but failed with exit code %d and error message %w\nstdout: %s\nstderr: %s", shExec, exitCode, actualExitCode, exitError, stdout, stderr) } else { - framework.ExpectNoError(err, - "%q should fail with exit code %d, but failed with error message %q\nstdout: %s\nstderr: %s", + return fmt.Errorf("%q should fail with exit code %d, but failed with error message %w\nstdout: %s\nstderr: %s", shExec, exitCode, err, stdout, stderr) } } - gomega.Expect(err).To(gomega.HaveOccurred(), "%q should fail with exit code %d, but exit without error", shExec, exitCode) + return fmt.Errorf("%q should fail with exit code %d, but exit without error", shExec, exitCode) } func execute(ctx context.Context, method string, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool) error { diff --git a/test/e2e/framework/volume/fixtures.go b/test/e2e/framework/volume/fixtures.go index 01f0f17acc6..830ec08f2b5 100644 --- a/test/e2e/framework/volume/fixtures.go +++ b/test/e2e/framework/volume/fixtures.go @@ -510,7 +510,8 @@ func testVolumeContent(ctx context.Context, f *framework.Framework, pod *v1.Pod, framework.ExpectNoError(err, "failed: finding the contents of the block device %s.", deviceName) // Check that it's a real block device - CheckVolumeModeOfPath(ctx, f, pod, test.Mode, deviceName) + err = CheckVolumeModeOfPath(ctx, f, pod, test.Mode, deviceName) + framework.ExpectNoError(err, "failed: getting the right privileges in the block device %v", deviceName) } else { // Filesystem: check content fileName := fmt.Sprintf("/opt/%d/%s", i, test.File) @@ -520,7 +521,8 @@ func testVolumeContent(ctx context.Context, f *framework.Framework, pod *v1.Pod, // Check that a directory has been mounted dirName := filepath.Dir(fileName) - CheckVolumeModeOfPath(ctx, f, pod, test.Mode, dirName) + err = CheckVolumeModeOfPath(ctx, f, pod, test.Mode, dirName) + framework.ExpectNoError(err, "failed: getting the right privileges in the directory %v", dirName) if !framework.NodeOSDistroIs("windows") { // Filesystem: check fsgroup @@ -663,18 +665,27 @@ func generateWriteFileCmd(content, fullPath string) []string { } // CheckVolumeModeOfPath check mode of volume -func CheckVolumeModeOfPath(ctx context.Context, f *framework.Framework, pod *v1.Pod, volMode v1.PersistentVolumeMode, path string) { +func CheckVolumeModeOfPath(ctx context.Context, f *framework.Framework, pod *v1.Pod, volMode v1.PersistentVolumeMode, path string) error { if volMode == v1.PersistentVolumeBlock { // Check if block exists - e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("test -b %s", path)) + if err := e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("test -b %s", path)); err != nil { + return err + } // Double check that it's not directory - e2epod.VerifyExecInPodFail(ctx, f, pod, fmt.Sprintf("test -d %s", path), 1) + if err := e2epod.VerifyExecInPodFail(ctx, f, pod, fmt.Sprintf("test -d %s", path), 1); err != nil { + return err + } } else { // Check if directory exists - e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("test -d %s", path)) + if err := e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("test -d %s", path)); err != nil { + return err + } // Double check that it's not block - e2epod.VerifyExecInPodFail(ctx, f, pod, fmt.Sprintf("test -b %s", path), 1) + if err := e2epod.VerifyExecInPodFail(ctx, f, pod, fmt.Sprintf("test -b %s", path), 1); err != nil { + return err + } } + return nil } diff --git a/test/e2e/storage/testsuites/ephemeral.go b/test/e2e/storage/testsuites/ephemeral.go index d851329805a..42637c43c04 100644 --- a/test/e2e/storage/testsuites/ephemeral.go +++ b/test/e2e/storage/testsuites/ephemeral.go @@ -194,7 +194,8 @@ func (p *ephemeralTestSuite) DefineTests(driver storageframework.TestDriver, pat // attempt to create a dummy file and expect for it not to be created command = "ls /mnt/test* && (touch /mnt/test-0/hello-world || true) && [ ! -f /mnt/test-0/hello-world ]" } - e2epod.VerifyExecInPodSucceed(ctx, f, pod, command) + err := e2epod.VerifyExecInPodSucceed(ctx, f, pod, command) + framework.ExpectNoError(err, "while checking read-only mount") return nil } l.testCase.TestEphemeral(ctx) @@ -214,7 +215,8 @@ func (p *ephemeralTestSuite) DefineTests(driver storageframework.TestDriver, pat if pattern.VolMode == v1.PersistentVolumeBlock { command = "if ! [ -b /mnt/test-0 ]; then echo /mnt/test-0 is not a block device; exit 1; fi" } - e2epod.VerifyExecInPodSucceed(ctx, f, pod, command) + err := e2epod.VerifyExecInPodSucceed(ctx, f, pod, command) + framework.ExpectNoError(err, "while checking read/write mount") return nil } l.testCase.TestEphemeral(ctx) @@ -308,8 +310,10 @@ func (p *ephemeralTestSuite) DefineTests(driver storageframework.TestDriver, pat // visible in the other. if pattern.VolMode != v1.PersistentVolumeBlock && !readOnly && !shared { ginkgo.By("writing data in one pod and checking the second does not see it (it should get its own volume)") - e2epod.VerifyExecInPodSucceed(ctx, f, pod, "touch /mnt/test-0/hello-world") - e2epod.VerifyExecInPodSucceed(ctx, f, pod2, "[ ! -f /mnt/test-0/hello-world ]") + err := e2epod.VerifyExecInPodSucceed(ctx, f, pod, "touch /mnt/test-0/hello-world") + framework.ExpectNoError(err, "while writing data in first pod") + err = e2epod.VerifyExecInPodSucceed(ctx, f, pod2, "[ ! -f /mnt/test-0/hello-world ]") + framework.ExpectNoError(err, "while checking data in second pod") } // TestEphemeral expects the pod to be fully deleted diff --git a/test/e2e/storage/testsuites/multivolume.go b/test/e2e/storage/testsuites/multivolume.go index d54cb454e8c..1efd5fa5064 100644 --- a/test/e2e/storage/testsuites/multivolume.go +++ b/test/e2e/storage/testsuites/multivolume.go @@ -499,7 +499,8 @@ func testAccessMultipleVolumes(ctx context.Context, f *framework.Framework, cs c index := i + 1 path := fmt.Sprintf("/mnt/volume%d", index) ginkgo.By(fmt.Sprintf("Checking if the volume%d exists as expected volume mode (%s)", index, *pvc.Spec.VolumeMode)) - e2evolume.CheckVolumeModeOfPath(ctx, f, pod, *pvc.Spec.VolumeMode, path) + err = e2evolume.CheckVolumeModeOfPath(ctx, f, pod, *pvc.Spec.VolumeMode, path) + framework.ExpectNoError(err) if readSeedBase > 0 { ginkgo.By(fmt.Sprintf("Checking if read from the volume%d works properly", index)) @@ -607,7 +608,8 @@ func TestConcurrentAccessToSingleVolume(ctx context.Context, f *framework.Framew for i, pod := range pods { index := i + 1 ginkgo.By(fmt.Sprintf("Checking if the volume in pod%d exists as expected volume mode (%s)", index, *pvc.Spec.VolumeMode)) - e2evolume.CheckVolumeModeOfPath(ctx, f, pod, *pvc.Spec.VolumeMode, path) + err := e2evolume.CheckVolumeModeOfPath(ctx, f, pod, *pvc.Spec.VolumeMode, path) + framework.ExpectNoError(err) if readOnly { ginkgo.By("Skipping volume content checks, volume is read-only") @@ -643,7 +645,8 @@ func TestConcurrentAccessToSingleVolume(ctx context.Context, f *framework.Framew index := i + 1 // index of pod and index of pvc match, because pods are created above way ginkgo.By(fmt.Sprintf("Rechecking if the volume in pod%d exists as expected volume mode (%s)", index, *pvc.Spec.VolumeMode)) - e2evolume.CheckVolumeModeOfPath(ctx, f, pod, *pvc.Spec.VolumeMode, "/mnt/volume1") + err := e2evolume.CheckVolumeModeOfPath(ctx, f, pod, *pvc.Spec.VolumeMode, "/mnt/volume1") + framework.ExpectNoError(err) if readOnly { ginkgo.By("Skipping volume content checks, volume is read-only") diff --git a/test/e2e/storage/utils/utils.go b/test/e2e/storage/utils/utils.go index ef1257ea67b..37dd26c1ce2 100644 --- a/test/e2e/storage/utils/utils.go +++ b/test/e2e/storage/utils/utils.go @@ -449,25 +449,34 @@ func isSudoPresent(ctx context.Context, nodeIP string, provider string) bool { func CheckReadWriteToPath(ctx context.Context, f *framework.Framework, pod *v1.Pod, volMode v1.PersistentVolumeMode, path string) { if volMode == v1.PersistentVolumeBlock { // random -> file1 - e2epod.VerifyExecInPodSucceed(ctx, f, pod, "dd if=/dev/urandom of=/tmp/file1 bs=64 count=1") + err := e2epod.VerifyExecInPodSucceed(ctx, f, pod, "dd if=/dev/urandom of=/tmp/file1 bs=64 count=1") + framework.ExpectNoError(err, "Failed to write to file1") // file1 -> dev (write to dev) - e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("dd if=/tmp/file1 of=%s bs=64 count=1", path)) + err = e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("dd if=/tmp/file1 of=%s bs=64 count=1", path)) + framework.ExpectNoError(err, "Failed to write to block volume") // dev -> file2 (read from dev) - e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("dd if=%s of=/tmp/file2 bs=64 count=1", path)) + err = e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("dd if=%s of=/tmp/file2 bs=64 count=1", path)) + framework.ExpectNoError(err, "Failed to read from block volume") // file1 == file2 (check contents) - e2epod.VerifyExecInPodSucceed(ctx, f, pod, "diff /tmp/file1 /tmp/file2") + err = e2epod.VerifyExecInPodSucceed(ctx, f, pod, "diff /tmp/file1 /tmp/file2") + framework.ExpectNoError(err, "Failed to compare file1 and file2") // Clean up temp files - e2epod.VerifyExecInPodSucceed(ctx, f, pod, "rm -f /tmp/file1 /tmp/file2") + err = e2epod.VerifyExecInPodSucceed(ctx, f, pod, "rm -f /tmp/file1 /tmp/file2") + framework.ExpectNoError(err, "Failed to clean up temp files") // Check that writing file to block volume fails - e2epod.VerifyExecInPodFail(ctx, f, pod, fmt.Sprintf("echo 'Hello world.' > %s/file1.txt", path), 1) + err = e2epod.VerifyExecInPodFail(ctx, f, pod, fmt.Sprintf("echo 'Hello world.' > %s/file1.txt", path), 1) + framework.ExpectNoError(err, "Expected write to block volume to fail") } else { // text -> file1 (write to file) - e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("echo 'Hello world.' > %s/file1.txt", path)) + err := e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("echo 'Hello world.' > %s/file1.txt", path)) + framework.ExpectNoError(err, "Failed to write to file1") // grep file1 (read from file and check contents) - e2epod.VerifyExecInPodSucceed(ctx, f, pod, readFile("Hello word.", path)) + err = e2epod.VerifyExecInPodSucceed(ctx, f, pod, readFile("Hello word.", path)) + framework.ExpectNoError(err, "Failed to read from file1") // Check that writing to directory as block volume fails - e2epod.VerifyExecInPodFail(ctx, f, pod, fmt.Sprintf("dd if=/dev/urandom of=%s bs=64 count=1", path), 1) + err = e2epod.VerifyExecInPodFail(ctx, f, pod, fmt.Sprintf("dd if=/dev/urandom of=%s bs=64 count=1", path), 1) + framework.ExpectNoError(err, "Expected write to directory to fail") } } @@ -513,8 +522,10 @@ func CheckReadFromPath(ctx context.Context, f *framework.Framework, pod *v1.Pod, sum := sha256.Sum256(genBinDataFromSeed(len, seed)) - e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("dd if=%s %s bs=%d count=1 | sha256sum", pathForVolMode, iflag, len)) - e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("dd if=%s %s bs=%d count=1 | sha256sum | grep -Fq %x", pathForVolMode, iflag, len, sum)) + err := e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("dd if=%s %s bs=%d count=1 | sha256sum", pathForVolMode, iflag, len)) + framework.ExpectNoError(err, "Failed to read from %s", pathForVolMode) + err = e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("dd if=%s %s bs=%d count=1 | sha256sum | grep -Fq %x", pathForVolMode, iflag, len, sum)) + framework.ExpectNoError(err, "Failed to read from %s", pathForVolMode) } // CheckWriteToPath that file can be properly written. @@ -538,8 +549,10 @@ func CheckWriteToPath(ctx context.Context, f *framework.Framework, pod *v1.Pod, encoded := base64.StdEncoding.EncodeToString(genBinDataFromSeed(len, seed)) - e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("echo %s | base64 -d | sha256sum", encoded)) - e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("echo %s | base64 -d | dd of=%s %s bs=%d count=1", encoded, pathForVolMode, oflag, len)) + err := e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("echo %s | base64 -d | sha256sum", encoded)) + framework.ExpectNoError(err, "Failed to generate sha256sum of encoded data") + err = e2epod.VerifyExecInPodSucceed(ctx, f, pod, fmt.Sprintf("echo %s | base64 -d | dd of=%s %s bs=%d count=1", encoded, pathForVolMode, oflag, len)) + framework.ExpectNoError(err, "Failed to write to %s", pathForVolMode) } // GetSectorSize returns the sector size of the device. diff --git a/test/e2e/upgrades/storage/volume_mode.go b/test/e2e/upgrades/storage/volume_mode.go index 6bea0776c80..aabb94a063c 100644 --- a/test/e2e/upgrades/storage/volume_mode.go +++ b/test/e2e/upgrades/storage/volume_mode.go @@ -105,7 +105,8 @@ func (t *VolumeModeDowngradeTest) Setup(ctx context.Context, f *framework.Framew framework.ExpectNoError(err) ginkgo.By("Checking if PV exists as expected volume mode") - e2evolume.CheckVolumeModeOfPath(ctx, f, t.pod, block, devicePath) + err = e2evolume.CheckVolumeModeOfPath(ctx, f, t.pod, block, devicePath) + framework.ExpectNoError(err) ginkgo.By("Checking if read/write to PV works properly") storageutils.CheckReadWriteToPath(ctx, f, t.pod, block, devicePath) @@ -118,7 +119,8 @@ func (t *VolumeModeDowngradeTest) Test(ctx context.Context, f *framework.Framewo <-done ginkgo.By("Verifying that nothing exists at the device path in the pod") - e2epod.VerifyExecInPodFail(ctx, f, t.pod, fmt.Sprintf("test -e %s", devicePath), 1) + err := e2epod.VerifyExecInPodFail(ctx, f, t.pod, fmt.Sprintf("test -e %s", devicePath), 1) + framework.ExpectNoError(err) } // Teardown cleans up any remaining resources.