mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-05 02:09:56 +00:00
return an error instead of recording a test failure
Signed-off-by: carlory <baofa.fan@daocloud.io>
This commit is contained in:
parent
aecf3238bf
commit
c68fc01b77
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user