From 4917df0165e70ef41c70373d24fb6881c71d3720 Mon Sep 17 00:00:00 2001 From: Fabio Bertinatto Date: Wed, 3 Oct 2018 15:06:37 +0200 Subject: [PATCH] Wait for volume status in e2e test --- tests/e2e/e2e_test.go | 92 +++++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 58832e0ac5..5c8984e344 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -18,13 +18,14 @@ import ( "context" "fmt" "io/ioutil" + "math/rand" "os" "path/filepath" "time" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/ec2" - "github.com/bertinatto/ebs-csi-driver/pkg/cloud" csi "github.com/container-storage-interface/spec/lib/go/csi/v0" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -48,10 +49,11 @@ var ( var _ = Describe("EBS CSI Driver", func() { - It("Should create->attach->stage->mount volume and check if it is writable, then unmount->unstage->detach->delete and check disk is deleted", func() { + It("Should create, attach, stage and mount volume, check if it's writable, unmount, unstage, detach, delete, and check if it's deleted", func() { + r1 := rand.New(rand.NewSource(time.Now().UnixNano())) req := &csi.CreateVolumeRequest{ - Name: "volume-name-e2e-test", + Name: fmt.Sprintf("volume-name-e2e-test-%d", r1.Uint64()), CapacityRange: stdCapRange, VolumeCapabilities: stdVolCap, Parameters: nil, @@ -62,37 +64,20 @@ var _ = Describe("EBS CSI Driver", func() { volume := resp.GetVolume() Expect(volume).NotTo(BeNil(), "Expected valid volume, got nil") - - // Verifying that volume was created ans is valid - descParams := &ec2.DescribeVolumesInput{ - Filters: []*ec2.Filter{ - { - Name: aws.String("tag:" + cloud.VolumeNameTagKey), - Values: []*string{aws.String(req.GetName())}, - }, - }, - } - waitForVolumes(descParams, 1 /* number of expected volumes */) + waitForVolumeState(volume.Id, "available") // Delete volume defer func() { _, err = csiClient.ctrl.DeleteVolume(context.Background(), &csi.DeleteVolumeRequest{VolumeId: volume.Id}) Expect(err).To(BeNil(), "Could not delete volume") - waitForVolumes(descParams, 0 /* number of expected volumes */) + waitForVolumes(volume.Id, 0 /* number of expected volumes */) // Deleting volume twice _, err = csiClient.ctrl.DeleteVolume(context.Background(), &csi.DeleteVolumeRequest{VolumeId: volume.Id}) Expect(err).To(BeNil(), "Error when trying to delete volume twice") - - // Trying to delete non-existent volume - nonexistentVolume := "vol-0f13f3ff21126cabf" - if nonexistentVolume != volume.Id { - _, err = csiClient.ctrl.DeleteVolume(context.Background(), &csi.DeleteVolumeRequest{VolumeId: nonexistentVolume}) - Expect(err).To(BeNil(), "Error deleting non-existing volume: %v", err) - } }() - // TODO: attach, stage, publish, unpublish, unstage, detach + // Attach, stage, publish, unpublish, unstage, detach nodeID := ebs.GetMetadata().GetInstanceID() testAttachWriteReadDetach(volume.Id, req.GetName(), nodeID, false) @@ -155,15 +140,17 @@ func testAttachWriteReadDetach(volumeID, volName, nodeID string, readOnly bool) VolumeCapability: stdVolCap[0], }) Expect(err).To(BeNil(), "NodePublishVolume failed with error") - //err = testutils.ForceChmod(instance, filepath.Join("/tmp/", volName), "777") - //Expect(err).To(BeNil(), "Chmod failed with error") - testFileContents := "test" + if !readOnly { // Write a file + testFileContents := []byte("sample content") testFile := filepath.Join(publishDir, "testfile") - //err = testutils.WriteFile(instance, testFile, testFileContents) - err := ioutil.WriteFile(testFile, []byte(testFileContents), 0644) + err := ioutil.WriteFile(testFile, testFileContents, 0644) Expect(err).To(BeNil(), "Failed to write file") + // Read the file and check if content is correct + data, err := ioutil.ReadFile(testFile) + Expect(err).To(BeNil(), "Failed to read file") + Expect(data).To(Equal(testFileContents), "File content is incorrect") } // Unmount Disk @@ -177,28 +164,40 @@ func testAttachWriteReadDetach(volumeID, volName, nodeID string, readOnly bool) } -func waitForVolumes(params *ec2.DescribeVolumesInput, nVolumes int) { +func waitForVolumeState(volumeID, state string) { backoff := wait.Backoff{ - Duration: 60 * time.Second, - Factor: 1.2, - Steps: 21, + Duration: 1 * time.Second, + Factor: 1.8, + Steps: 13, } verifyVolumeFunc := func() (bool, error) { + params := &ec2.DescribeVolumesInput{ + VolumeIds: []*string{aws.String(volumeID)}, + } volumes, err := describeVolumes(params) if err != nil { return false, err } - if len(volumes) != nVolumes { + if len(volumes) != 1 { + return false, fmt.Errorf("expected 1 volume, got %d", len(volumes)) + } + if aws.StringValue(volumes[0].State) != state { return false, nil } + // We need to check the atachment state when the volume is "in-use", + // as it might still be "attaching" rather than "attached". + if state == "in-use" { + if aws.StringValue(volumes[0].Attachments[0].State) != "attached" { + return false, nil + } + } return true, nil - } waitErr := wait.ExponentialBackoff(backoff, verifyVolumeFunc) - Expect(waitErr).To(BeNil(), "Timeout error when looking for volume: %v", waitErr) + Expect(waitErr).To(BeNil(), "Timeout error waiting for volume state %q: %v", waitErr, state) } -func waitForVolumeState(volumeID, state string) { +func waitForVolumes(volumeID string, nVolumes int) { backoff := wait.Backoff{ Duration: 1 * time.Second, Factor: 1.8, @@ -208,23 +207,24 @@ func waitForVolumeState(volumeID, state string) { params := &ec2.DescribeVolumesInput{ VolumeIds: []*string{aws.String(volumeID)}, } - // FIXME: for some reason this always returns the same state volumes, err := describeVolumes(params) if err != nil { + if nVolumes == 0 { + if awsErr, ok := err.(awserr.Error); ok { + if awsErr.Code() == "InvalidVolume.NotFound" { + return true, nil + } + } + } return false, err } - if len(volumes) < 1 { - return false, fmt.Errorf("expected 1 valid volume, got nothing") - } - for _, attachment := range volumes[0].Attachments { - if aws.StringValue(attachment.State) == state { - return true, nil - } + if len(volumes) != nVolumes { + return false, nil } - return false, nil + return true, nil } waitErr := wait.ExponentialBackoff(backoff, verifyVolumeFunc) - Expect(waitErr).To(BeNil(), "Timeout error waiting for volume state %q: %v", waitErr, state) + Expect(waitErr).To(BeNil(), "Timeout error when looking for volume %q: %v", volumeID, waitErr) } func describeVolumes(params *ec2.DescribeVolumesInput) ([]*ec2.Volume, error) {