diff --git a/cmd/csi-sanity/main.go b/cmd/csi-sanity/main.go index 7c3235c0..06f21ff1 100644 --- a/cmd/csi-sanity/main.go +++ b/cmd/csi-sanity/main.go @@ -22,7 +22,7 @@ import ( "strings" "time" - "github.com/kubernetes-csi/csi-test/v3/pkg/sanity" + "github.com/kubernetes-csi/csi-test/v4/pkg/sanity" ) const ( diff --git a/cmd/mock-driver/main.go b/cmd/mock-driver/main.go index b8a4302b..7b496f12 100644 --- a/cmd/mock-driver/main.go +++ b/cmd/mock-driver/main.go @@ -25,8 +25,8 @@ import ( "strings" "syscall" - "github.com/kubernetes-csi/csi-test/v3/driver" - "github.com/kubernetes-csi/csi-test/v3/mock/service" + "github.com/kubernetes-csi/csi-test/v4/driver" + "github.com/kubernetes-csi/csi-test/v4/mock/service" "gopkg.in/yaml.v2" ) diff --git a/driver/mock.go b/driver/mock.go index 53414d7e..7e2b5020 100644 --- a/driver/mock.go +++ b/driver/mock.go @@ -19,7 +19,7 @@ package driver import ( "net" - "github.com/kubernetes-csi/csi-test/v3/utils" + "github.com/kubernetes-csi/csi-test/v4/utils" "google.golang.org/grpc" ) diff --git a/go.mod b/go.mod index 6827286a..c19e0726 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/kubernetes-csi/csi-test/v3 +module github.com/kubernetes-csi/csi-test/v4 go 1.12 diff --git a/go.sum b/go.sum index 840d3ff5..a9d0d4b4 100644 --- a/go.sum +++ b/go.sum @@ -23,6 +23,7 @@ github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -60,6 +61,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056 h1:dHtDnRWQtSx0Hjq9kvKFpBh9uPPKfQN70NZZmvssGwk= golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -76,6 +78,7 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20191114150713-6bbd007550de h1:dFEMUWudT9iV1JMk6i6NwbfIw2V/2VDFyDYCZFypRxE= google.golang.org/genproto v0.0.0-20191114150713-6bbd007550de/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= diff --git a/hack/_apitest/api_test.go b/hack/_apitest/api_test.go index 7dac2769..e56e28ae 100644 --- a/hack/_apitest/api_test.go +++ b/hack/_apitest/api_test.go @@ -3,7 +3,7 @@ package apitest import ( "testing" - "github.com/kubernetes-csi/csi-test/v3/pkg/sanity" + "github.com/kubernetes-csi/csi-test/v4/pkg/sanity" ) func TestMyDriver(t *testing.T) { diff --git a/hack/_apitest2/api_test.go b/hack/_apitest2/api_test.go index 211bb11b..23136bc6 100644 --- a/hack/_apitest2/api_test.go +++ b/hack/_apitest2/api_test.go @@ -6,7 +6,7 @@ import ( "path" "testing" - "github.com/kubernetes-csi/csi-test/v3/pkg/sanity" + "github.com/kubernetes-csi/csi-test/v4/pkg/sanity" ) // TestMyDriverWithCustomTargetPaths verifies that CreateTargetDir and diff --git a/hack/_embedded/embedded_test.go b/hack/_embedded/embedded_test.go index ceb08d82..03421c29 100644 --- a/hack/_embedded/embedded_test.go +++ b/hack/_embedded/embedded_test.go @@ -3,7 +3,7 @@ package embedded import ( "testing" - "github.com/kubernetes-csi/csi-test/v3/pkg/sanity" + "github.com/kubernetes-csi/csi-test/v4/pkg/sanity" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) diff --git a/mock/service/service.go b/mock/service/service.go index 9c118540..e881dac1 100644 --- a/mock/service/service.go +++ b/mock/service/service.go @@ -9,7 +9,7 @@ import ( "sync/atomic" "github.com/container-storage-interface/spec/lib/go/csi" - "github.com/kubernetes-csi/csi-test/v3/mock/cache" + "github.com/kubernetes-csi/csi-test/v4/mock/cache" "golang.org/x/net/context" "google.golang.org/grpc/codes" diff --git a/pkg/sanity/cleanup.go b/pkg/sanity/cleanup.go deleted file mode 100644 index 0322233e..00000000 --- a/pkg/sanity/cleanup.go +++ /dev/null @@ -1,145 +0,0 @@ -/* -Copyright 2018 Intel Corporation - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package sanity - -import ( - "context" - "log" - "sync" - - "github.com/container-storage-interface/spec/lib/go/csi" - - . "github.com/onsi/ginkgo" -) - -// VolumeInfo keeps track of the information needed to delete a volume. -type VolumeInfo struct { - // Node on which the volume was published, empty if none - // or publishing is not supported. - NodeID string - - // Volume ID assigned by CreateVolume. - VolumeID string -} - -// Cleanup keeps track of resources, in particular volumes, which need -// to be freed when testing is done. All methods can be called concurrently. -type Cleanup struct { - Context *TestContext - ControllerClient csi.ControllerClient - NodeClient csi.NodeClient - ControllerPublishSupported bool - NodeStageSupported bool - - // Maps from volume name to the node ID for which the volume - // is published and the volume ID. - volumes map[string]VolumeInfo - mutex sync.Mutex -} - -// RegisterVolume adds or updates an entry for the volume with the -// given name. -func (cl *Cleanup) RegisterVolume(name string, info VolumeInfo) { - cl.mutex.Lock() - defer cl.mutex.Unlock() - if cl.volumes == nil { - cl.volumes = make(map[string]VolumeInfo) - } - cl.volumes[name] = info -} - -// MaybeRegisterVolume adds or updates an entry for the volume with -// the given name if CreateVolume was successful. -func (cl *Cleanup) MaybeRegisterVolume(name string, vol *csi.CreateVolumeResponse, err error) { - if err == nil && vol.GetVolume().GetVolumeId() != "" { - cl.RegisterVolume(name, VolumeInfo{VolumeID: vol.GetVolume().GetVolumeId()}) - } -} - -// UnregisterVolume removes the entry for the volume with the -// given name, thus preventing all cleanup operations for it. -func (cl *Cleanup) UnregisterVolume(name string) { - cl.mutex.Lock() - defer cl.mutex.Unlock() - cl.unregisterVolume(name) -} -func (cl *Cleanup) unregisterVolume(name string) { - if cl.volumes != nil { - delete(cl.volumes, name) - } -} - -// DeleteVolumes stops using the registered volumes and tries to delete all of them. -func (cl *Cleanup) DeleteVolumes() { - cl.mutex.Lock() - defer cl.mutex.Unlock() - if cl.volumes == nil { - return - } - logger := log.New(GinkgoWriter, "cleanup: ", 0) - ctx := context.Background() - - for name, info := range cl.volumes { - logger.Printf("deleting %s = %s", name, info.VolumeID) - if _, err := cl.NodeClient.NodeUnpublishVolume( - ctx, - &csi.NodeUnpublishVolumeRequest{ - VolumeId: info.VolumeID, - TargetPath: cl.Context.TargetPath + "/target", - }, - ); err != nil { - logger.Printf("warning: NodeUnpublishVolume: %s", err) - } - - if cl.NodeStageSupported { - if _, err := cl.NodeClient.NodeUnstageVolume( - ctx, - &csi.NodeUnstageVolumeRequest{ - VolumeId: info.VolumeID, - StagingTargetPath: cl.Context.StagingPath, - }, - ); err != nil { - logger.Printf("warning: NodeUnstageVolume: %s", err) - } - } - - if cl.ControllerPublishSupported && info.NodeID != "" { - if _, err := cl.ControllerClient.ControllerUnpublishVolume( - ctx, - &csi.ControllerUnpublishVolumeRequest{ - VolumeId: info.VolumeID, - NodeId: info.NodeID, - Secrets: cl.Context.Secrets.ControllerUnpublishVolumeSecret, - }, - ); err != nil { - logger.Printf("warning: ControllerUnpublishVolume: %s", err) - } - } - - if _, err := cl.ControllerClient.DeleteVolume( - ctx, - &csi.DeleteVolumeRequest{ - VolumeId: info.VolumeID, - Secrets: cl.Context.Secrets.DeleteVolumeSecret, - }, - ); err != nil { - logger.Printf("error: DeleteVolume: %s", err) - } - - cl.unregisterVolume(name) - } -} diff --git a/pkg/sanity/controller.go b/pkg/sanity/controller.go index 9ddb7027..755984c5 100644 --- a/pkg/sanity/controller.go +++ b/pkg/sanity/controller.go @@ -74,10 +74,14 @@ func verifyVolumeInfo(v *csi.Volume) { } func verifySnapshotInfo(snapshot *csi.Snapshot) { - Expect(snapshot).NotTo(BeNil()) - Expect(snapshot.GetSnapshotId()).NotTo(BeEmpty()) - Expect(snapshot.GetSourceVolumeId()).NotTo(BeEmpty()) - Expect(snapshot.GetCreationTime()).NotTo(BeZero()) + verifySnapshotInfoWithOffset(2, snapshot) +} + +func verifySnapshotInfoWithOffset(offset int, snapshot *csi.Snapshot) { + ExpectWithOffset(offset, snapshot).NotTo(BeNil()) + ExpectWithOffset(offset, snapshot.GetSnapshotId()).NotTo(BeEmpty()) + ExpectWithOffset(offset, snapshot.GetSourceVolumeId()).NotTo(BeEmpty()) + ExpectWithOffset(offset, snapshot.GetCreationTime()).NotTo(BeZero()) } func isControllerCapabilitySupported( @@ -102,31 +106,23 @@ func isControllerCapabilitySupported( } var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestContext) { - var ( - c csi.ControllerClient - n csi.NodeClient - - cl *Cleanup - ) + var r *Resources BeforeEach(func() { - c = csi.NewControllerClient(sc.ControllerConn) - n = csi.NewNodeClient(sc.Conn) - - cl = &Cleanup{ - NodeClient: n, - ControllerClient: c, + r = &Resources{ Context: sc, + ControllerClient: csi.NewControllerClient(sc.ControllerConn), + NodeClient: csi.NewNodeClient(sc.Conn), } }) AfterEach(func() { - cl.DeleteVolumes() + r.Cleanup() }) Describe("ControllerGetCapabilities", func() { It("should return appropriate capabilities", func() { - caps, err := c.ControllerGetCapabilities( + caps, err := r.ControllerGetCapabilities( context.Background(), &csi.ControllerGetCapabilitiesRequest{}) @@ -160,13 +156,13 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo Describe("GetCapacity", func() { BeforeEach(func() { - if !isControllerCapabilitySupported(c, csi.ControllerServiceCapability_RPC_GET_CAPACITY) { + if !isControllerCapabilitySupported(r, csi.ControllerServiceCapability_RPC_GET_CAPACITY) { Skip("GetCapacity not supported") } }) It("should return capacity (no optional values added)", func() { - _, err := c.GetCapacity( + _, err := r.GetCapacity( context.Background(), &csi.GetCapacityRequest{}) Expect(err).NotTo(HaveOccurred()) @@ -177,13 +173,13 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo }) Describe("ListVolumes", func() { BeforeEach(func() { - if !isControllerCapabilitySupported(c, csi.ControllerServiceCapability_RPC_LIST_VOLUMES) { + if !isControllerCapabilitySupported(r, csi.ControllerServiceCapability_RPC_LIST_VOLUMES) { Skip("ListVolumes not supported") } }) It("should return appropriate values (no optional values added)", func() { - vols, err := c.ListVolumes( + vols, err := r.ListVolumes( context.Background(), &csi.ListVolumesRequest{}) Expect(err).NotTo(HaveOccurred()) @@ -195,7 +191,7 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo }) It("should fail when an invalid starting_token is passed", func() { - vols, err := c.ListVolumes( + vols, err := r.ListVolumes( context.Background(), &csi.ListVolumesRequest{ StartingToken: "invalid-token", @@ -211,7 +207,7 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo It("check the presence of new volumes and absence of deleted ones in the volume list", func() { // List Volumes before creating new volume. - vols, err := c.ListVolumes( + vols, err := r.ListVolumes( context.Background(), &csi.ListVolumesRequest{}) Expect(err).NotTo(HaveOccurred()) @@ -231,32 +227,28 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo Secrets: sc.Secrets.CreateVolumeSecret, } - vol, err := c.CreateVolume(context.Background(), req) - Expect(err).NotTo(HaveOccurred()) - Expect(vol).NotTo(BeNil()) - Expect(vol.GetVolume()).NotTo(BeNil()) - Expect(vol.GetVolume().GetVolumeId()).NotTo(BeEmpty()) + vol := r.MustCreateVolume(context.Background(), req) // List volumes and check for the newly created volume. - vols, err = c.ListVolumes( + vols, err = r.ListVolumes( context.Background(), &csi.ListVolumesRequest{}) Expect(err).NotTo(HaveOccurred()) Expect(vols).NotTo(BeNil()) Expect(len(vols.GetEntries())).To(Equal(totalVols + 1)) - By("cleaning up deleting the volume") + By("deleting the volume") delReq := &csi.DeleteVolumeRequest{ VolumeId: vol.GetVolume().GetVolumeId(), Secrets: sc.Secrets.DeleteVolumeSecret, } - _, err = c.DeleteVolume(context.Background(), delReq) + _, err = r.DeleteVolume(context.Background(), delReq) Expect(err).NotTo(HaveOccurred()) // List volumes and check if the deleted volume exists in the volume list. - vols, err = c.ListVolumes( + vols, err = r.ListVolumes( context.Background(), &csi.ListVolumesRequest{}) Expect(err).NotTo(HaveOccurred()) @@ -281,7 +273,7 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo existing_vols := map[string]bool{} // Get the number of existing volumes. - vols, err := c.ListVolumes( + vols, err := r.ListVolumes( context.Background(), &csi.ListVolumesRequest{}) Expect(err).NotTo(HaveOccurred()) @@ -308,17 +300,16 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo Secrets: sc.Secrets.CreateVolumeSecret, } - vol, err := c.CreateVolume(context.Background(), req) + vol, err := r.CreateVolume(context.Background(), req) Expect(err).NotTo(HaveOccurred()) Expect(vol).NotTo(BeNil()) // Register the volume so it's automatically cleaned - cl.RegisterVolume(vol.Volume.VolumeId, VolumeInfo{VolumeID: vol.Volume.VolumeId}) existing_vols[vol.Volume.VolumeId] = true } } // Request list volumes with max entries maxEntries. - vols, err = c.ListVolumes( + vols, err = r.ListVolumes( context.Background(), &csi.ListVolumesRequest{ MaxEntries: int32(maxEntries), @@ -337,11 +328,10 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo Secrets: sc.Secrets.DeleteVolumeSecret, } - _, err := c.DeleteVolume(context.Background(), delReq) + _, err := r.DeleteVolume(context.Background(), delReq) Expect(err).NotTo(HaveOccurred()) vol_id := vol.Volume.VolumeId existing_vols[vol_id] = false - cl.UnregisterVolume(vol_id) } By("creating a new volume") @@ -352,15 +342,10 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo }, Secrets: sc.Secrets.CreateVolumeSecret, } - vol, err := c.CreateVolume(context.Background(), req) - Expect(err).NotTo(HaveOccurred()) - Expect(vol).NotTo(BeNil()) - Expect(vol.Volume).NotTo(BeNil()) - // Register the volume so it's automatically cleaned - cl.RegisterVolume(vol.Volume.VolumeId, VolumeInfo{VolumeID: vol.Volume.VolumeId}) + vol := r.MustCreateVolume(context.Background(), req) existing_vols[vol.Volume.VolumeId] = true - vols, err = c.ListVolumes( + vols, err = r.ListVolumes( context.Background(), &csi.ListVolumesRequest{ StartingToken: nextToken, @@ -379,20 +364,19 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo Describe("CreateVolume", func() { BeforeEach(func() { - if !isControllerCapabilitySupported(c, csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME) { + if !isControllerCapabilitySupported(r, csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME) { Skip("CreateVolume not supported") } }) It("should fail when no name is provided", func() { - vol, err := c.CreateVolume( + _, err := r.CreateVolume( context.Background(), &csi.CreateVolumeRequest{ Secrets: sc.Secrets.CreateVolumeSecret, Parameters: sc.Config.TestVolumeParameters, }, ) - cl.MaybeRegisterVolume("", vol, err) Expect(err).To(HaveOccurred()) serverError, ok := status.FromError(err) @@ -402,7 +386,7 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo It("should fail when no volume capabilities are provided", func() { name := UniqueString("sanity-controller-create-no-volume-capabilities") - vol, err := c.CreateVolume( + _, err := r.CreateVolume( context.Background(), &csi.CreateVolumeRequest{ Name: name, @@ -410,7 +394,6 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo Parameters: sc.Config.TestVolumeParameters, }, ) - cl.MaybeRegisterVolume(name, vol, err) Expect(err).To(HaveOccurred()) serverError, ok := status.FromError(err) @@ -424,7 +407,7 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo By("creating a volume") name := UniqueString("sanity-controller-create-single-no-capacity") - vol, err := c.CreateVolume( + r.MustCreateVolume( context.Background(), &csi.CreateVolumeRequest{ Name: name, @@ -438,23 +421,6 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo Parameters: sc.Config.TestVolumeParameters, }, ) - Expect(err).NotTo(HaveOccurred()) - Expect(vol).NotTo(BeNil()) - Expect(vol.GetVolume()).NotTo(BeNil()) - Expect(vol.GetVolume().GetVolumeId()).NotTo(BeEmpty()) - cl.RegisterVolume(name, VolumeInfo{VolumeID: vol.GetVolume().GetVolumeId()}) - - By("cleaning up deleting the volume") - - _, err = c.DeleteVolume( - context.Background(), - &csi.DeleteVolumeRequest{ - VolumeId: vol.GetVolume().GetVolumeId(), - Secrets: sc.Secrets.DeleteVolumeSecret, - }, - ) - Expect(err).NotTo(HaveOccurred()) - cl.UnregisterVolume(name) }) It("should return appropriate values SingleNodeWriter WithCapacity 1Gi", func() { @@ -462,7 +428,7 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo By("creating a volume") name := UniqueString("sanity-controller-create-single-with-capacity") - vol, err := c.CreateVolume( + vol, err := r.CreateVolume( context.Background(), &csi.CreateVolumeRequest{ Name: name, @@ -484,28 +450,16 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo Expect(vol).NotTo(BeNil()) Expect(vol.GetVolume()).NotTo(BeNil()) Expect(vol.GetVolume().GetVolumeId()).NotTo(BeEmpty()) - cl.RegisterVolume(name, VolumeInfo{VolumeID: vol.GetVolume().GetVolumeId()}) Expect(vol.GetVolume().GetCapacityBytes()).To(Or(BeNumerically(">=", TestVolumeSize(sc)), BeZero())) - - By("cleaning up deleting the volume") - - _, err = c.DeleteVolume( - context.Background(), - &csi.DeleteVolumeRequest{ - VolumeId: vol.GetVolume().GetVolumeId(), - Secrets: sc.Secrets.DeleteVolumeSecret, - }, - ) - Expect(err).NotTo(HaveOccurred()) - cl.UnregisterVolume(name) }) - It("should not fail when requesting to create a volume with already existing name and same capacity.", func() { + + It("should not fail when requesting to create a volume with already existing name and same capacity", func() { By("creating a volume") name := UniqueString("sanity-controller-create-twice") size := TestVolumeSize(sc) - vol1, err := c.CreateVolume( + vol1 := r.MustCreateVolume( context.Background(), &csi.CreateVolumeRequest{ Name: name, @@ -519,14 +473,10 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo Parameters: sc.Config.TestVolumeParameters, }, ) - Expect(err).NotTo(HaveOccurred()) - Expect(vol1).NotTo(BeNil()) - Expect(vol1.GetVolume()).NotTo(BeNil()) - Expect(vol1.GetVolume().GetVolumeId()).NotTo(BeEmpty()) - cl.RegisterVolume(name, VolumeInfo{VolumeID: vol1.GetVolume().GetVolumeId()}) + Expect(vol1.GetVolume().GetCapacityBytes()).To(Or(BeNumerically(">=", size), BeZero())) - vol2, err := c.CreateVolume( + vol2 := r.MustCreateVolume( context.Background(), &csi.CreateVolumeRequest{ Name: name, @@ -540,32 +490,17 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo Parameters: sc.Config.TestVolumeParameters, }, ) - Expect(err).NotTo(HaveOccurred()) - Expect(vol2).NotTo(BeNil()) - Expect(vol2.GetVolume()).NotTo(BeNil()) - Expect(vol2.GetVolume().GetVolumeId()).NotTo(BeEmpty()) Expect(vol2.GetVolume().GetCapacityBytes()).To(Or(BeNumerically(">=", size), BeZero())) Expect(vol1.GetVolume().GetVolumeId()).To(Equal(vol2.GetVolume().GetVolumeId())) - - By("cleaning up deleting the volume") - - _, err = c.DeleteVolume( - context.Background(), - &csi.DeleteVolumeRequest{ - VolumeId: vol1.GetVolume().GetVolumeId(), - Secrets: sc.Secrets.DeleteVolumeSecret, - }, - ) - Expect(err).NotTo(HaveOccurred()) - cl.UnregisterVolume(name) }) - It("should fail when requesting to create a volume with already existing name and different capacity.", func() { + + It("should fail when requesting to create a volume with already existing name and different capacity", func() { By("creating a volume") name := UniqueString("sanity-controller-create-twice-different") size1 := TestVolumeSize(sc) - vol1, err := c.CreateVolume( + r.MustCreateVolume( context.Background(), &csi.CreateVolumeRequest{ Name: name, @@ -580,14 +515,9 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo Parameters: sc.Config.TestVolumeParameters, }, ) - Expect(err).ToNot(HaveOccurred()) - Expect(vol1).NotTo(BeNil()) - Expect(vol1.GetVolume()).NotTo(BeNil()) - Expect(vol1.GetVolume().GetVolumeId()).NotTo(BeEmpty()) - cl.RegisterVolume(name, VolumeInfo{VolumeID: vol1.GetVolume().GetVolumeId()}) size2 := 2 * TestVolumeSize(sc) - _, err = c.CreateVolume( + _, err := r.CreateVolume( context.Background(), &csi.CreateVolumeRequest{ Name: name, @@ -606,18 +536,6 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo serverError, ok := status.FromError(err) Expect(ok).To(BeTrue()) Expect(serverError.Code()).To(Equal(codes.AlreadyExists)) - - By("cleaning up deleting the volume") - - _, err = c.DeleteVolume( - context.Background(), - &csi.DeleteVolumeRequest{ - VolumeId: vol1.GetVolume().GetVolumeId(), - Secrets: sc.Secrets.DeleteVolumeSecret, - }, - ) - Expect(err).NotTo(HaveOccurred()) - cl.UnregisterVolume(name) }) It("should not fail when creating volume with maximum-length name", func() { @@ -630,7 +548,7 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo By("creating a volume") size := TestVolumeSize(sc) - vol, err := c.CreateVolume( + vol := r.MustCreateVolume( context.Background(), &csi.CreateVolumeRequest{ Name: name, @@ -644,44 +562,17 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo Parameters: sc.Config.TestVolumeParameters, }, ) - Expect(err).NotTo(HaveOccurred()) - Expect(vol).NotTo(BeNil()) - Expect(vol.GetVolume()).NotTo(BeNil()) - Expect(vol.GetVolume().GetVolumeId()).NotTo(BeEmpty()) - cl.RegisterVolume(name, VolumeInfo{VolumeID: vol.GetVolume().GetVolumeId()}) Expect(vol.GetVolume().GetCapacityBytes()).To(Or(BeNumerically(">=", size), BeZero())) - - By("cleaning up deleting the volume") - - _, err = c.DeleteVolume( - context.Background(), - &csi.DeleteVolumeRequest{ - VolumeId: vol.GetVolume().GetVolumeId(), - Secrets: sc.Secrets.DeleteVolumeSecret, - }, - ) - Expect(err).NotTo(HaveOccurred()) - cl.UnregisterVolume(name) }) It("should create volume from an existing source snapshot", func() { - if !isControllerCapabilitySupported(c, csi.ControllerServiceCapability_RPC_CREATE_DELETE_SNAPSHOT) { + if !isControllerCapabilitySupported(r, csi.ControllerServiceCapability_RPC_CREATE_DELETE_SNAPSHOT) { Skip("Snapshot not supported") } - By("creating a volume") - vol1Name := UniqueString("sanity-controller-source-vol") - vol1Req := MakeCreateVolumeReq(sc, vol1Name) - volume1, err := c.CreateVolume(context.Background(), vol1Req) - Expect(err).NotTo(HaveOccurred()) - By("creating a snapshot") - snapName := UniqueString("sanity-controller-snap-from-vol") - snapReq := MakeCreateSnapshotReq(sc, snapName, volume1.GetVolume().GetVolumeId()) - snap, err := c.CreateSnapshot(context.Background(), snapReq) - Expect(err).NotTo(HaveOccurred()) - Expect(snap).NotTo(BeNil()) - verifySnapshotInfo(snap.GetSnapshot()) + vol1Req := MakeCreateVolumeReq(sc, UniqueString("sanity-controller-source-vol")) + snap, _ := r.MustCreateSnapshotFromVolumeRequest(context.Background(), vol1Req, UniqueString("sanity-controller-snap-from-vol")) By("creating a volume from source snapshot") vol2Name := UniqueString("sanity-controller-vol-from-snap") @@ -693,27 +584,12 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo }, }, } - volume2, err := c.CreateVolume(context.Background(), vol2Req) - Expect(err).NotTo(HaveOccurred()) - - By("cleaning up deleting the volume created from snapshot") - delVol2Req := MakeDeleteVolumeReq(sc, volume2.GetVolume().GetVolumeId()) - _, err = c.DeleteVolume(context.Background(), delVol2Req) - Expect(err).NotTo(HaveOccurred()) - - By("cleaning up deleting the snapshot") - delSnapReq := MakeDeleteSnapshotReq(sc, snap.GetSnapshot().GetSnapshotId()) - _, err = c.DeleteSnapshot(context.Background(), delSnapReq) - Expect(err).NotTo(HaveOccurred()) - - By("cleaning up deleting the source volume") - delVol1Req := MakeDeleteVolumeReq(sc, volume1.GetVolume().GetVolumeId()) - _, err = c.DeleteVolume(context.Background(), delVol1Req) + _, err := r.CreateVolume(context.Background(), vol2Req) Expect(err).NotTo(HaveOccurred()) }) It("should fail when the volume source snapshot is not found", func() { - if !isControllerCapabilitySupported(c, csi.ControllerServiceCapability_RPC_CREATE_DELETE_SNAPSHOT) { + if !isControllerCapabilitySupported(r, csi.ControllerServiceCapability_RPC_CREATE_DELETE_SNAPSHOT) { Skip("Snapshot not supported") } @@ -727,7 +603,7 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo }, }, } - _, err := c.CreateVolume(context.Background(), volReq) + _, err := r.CreateVolume(context.Background(), volReq) Expect(err).To(HaveOccurred()) serverError, ok := status.FromError(err) Expect(ok).To(BeTrue()) @@ -735,15 +611,14 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo }) It("should create volume from an existing source volume", func() { - if !isControllerCapabilitySupported(c, csi.ControllerServiceCapability_RPC_CLONE_VOLUME) { + if !isControllerCapabilitySupported(r, csi.ControllerServiceCapability_RPC_CLONE_VOLUME) { Skip("Volume Cloning not supported") } By("creating a volume") vol1Name := UniqueString("sanity-controller-source-vol") vol1Req := MakeCreateVolumeReq(sc, vol1Name) - volume1, err := c.CreateVolume(context.Background(), vol1Req) - Expect(err).NotTo(HaveOccurred()) + volume1 := r.MustCreateVolume(context.Background(), vol1Req) By("creating a volume from source volume") vol2Name := UniqueString("sanity-controller-vol-from-vol") @@ -755,22 +630,12 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo }, }, } - volume2, err := c.CreateVolume(context.Background(), vol2Req) - Expect(err).NotTo(HaveOccurred()) - - By("cleaning up deleting the volume created from source volume") - delVol2Req := MakeDeleteVolumeReq(sc, volume2.GetVolume().GetVolumeId()) - _, err = c.DeleteVolume(context.Background(), delVol2Req) - Expect(err).NotTo(HaveOccurred()) - - By("cleaning up deleting the source volume") - delVol1Req := MakeDeleteVolumeReq(sc, volume1.GetVolume().GetVolumeId()) - _, err = c.DeleteVolume(context.Background(), delVol1Req) + _, err := r.CreateVolume(context.Background(), vol2Req) Expect(err).NotTo(HaveOccurred()) }) It("should fail when the volume source volume is not found", func() { - if !isControllerCapabilitySupported(c, csi.ControllerServiceCapability_RPC_CLONE_VOLUME) { + if !isControllerCapabilitySupported(r, csi.ControllerServiceCapability_RPC_CLONE_VOLUME) { Skip("Volume Cloning not supported") } @@ -784,7 +649,7 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo }, }, } - _, err := c.CreateVolume(context.Background(), volReq) + _, err := r.CreateVolume(context.Background(), volReq) Expect(err).To(HaveOccurred()) serverError, ok := status.FromError(err) Expect(ok).To(BeTrue()) @@ -794,14 +659,14 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo Describe("DeleteVolume", func() { BeforeEach(func() { - if !isControllerCapabilitySupported(c, csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME) { + if !isControllerCapabilitySupported(r, csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME) { Skip("DeleteVolume not supported") } }) It("should fail when no volume id is provided", func() { - _, err := c.DeleteVolume( + _, err := r.DeleteVolume( context.Background(), &csi.DeleteVolumeRequest{ Secrets: sc.Secrets.DeleteVolumeSecret, @@ -816,7 +681,7 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo It("should succeed when an invalid volume id is used", func() { - _, err := c.DeleteVolume( + _, err := r.DeleteVolume( context.Background(), &csi.DeleteVolumeRequest{ VolumeId: sc.Config.IDGen.GenerateInvalidVolumeID(), @@ -832,7 +697,7 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo By("creating a volume") name := UniqueString("sanity-controller-create-appropriate") - vol, err := c.CreateVolume( + vol := r.MustCreateVolume( context.Background(), &csi.CreateVolumeRequest{ Name: name, @@ -846,16 +711,11 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo Parameters: sc.Config.TestVolumeParameters, }, ) - Expect(err).NotTo(HaveOccurred()) - Expect(vol).NotTo(BeNil()) - Expect(vol.GetVolume()).NotTo(BeNil()) - Expect(vol.GetVolume().GetVolumeId()).NotTo(BeEmpty()) - cl.RegisterVolume(name, VolumeInfo{VolumeID: vol.GetVolume().GetVolumeId()}) // Delete Volume By("deleting a volume") - _, err = c.DeleteVolume( + _, err := r.DeleteVolume( context.Background(), &csi.DeleteVolumeRequest{ VolumeId: vol.GetVolume().GetVolumeId(), @@ -863,14 +723,13 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo }, ) Expect(err).NotTo(HaveOccurred()) - cl.UnregisterVolume(name) }) }) Describe("ValidateVolumeCapabilities", func() { It("should fail when no volume id is provided", func() { - _, err := c.ValidateVolumeCapabilities( + _, err := r.ValidateVolumeCapabilities( context.Background(), &csi.ValidateVolumeCapabilitiesRequest{ Secrets: sc.Secrets.ControllerValidateVolumeCapabilitiesSecret, @@ -888,7 +747,7 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo By("creating a single node writer volume") name := UniqueString("sanity-controller-validate-nocaps") - vol, err := c.CreateVolume( + vol := r.MustCreateVolume( context.Background(), &csi.CreateVolumeRequest{ Name: name, @@ -902,13 +761,8 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo Parameters: sc.Config.TestVolumeParameters, }, ) - Expect(err).NotTo(HaveOccurred()) - Expect(vol).NotTo(BeNil()) - Expect(vol.GetVolume()).NotTo(BeNil()) - Expect(vol.GetVolume().GetVolumeId()).NotTo(BeEmpty()) - cl.RegisterVolume(name, VolumeInfo{VolumeID: vol.GetVolume().GetVolumeId()}) - _, err = c.ValidateVolumeCapabilities( + _, err := r.ValidateVolumeCapabilities( context.Background(), &csi.ValidateVolumeCapabilitiesRequest{ VolumeId: vol.GetVolume().GetVolumeId(), @@ -920,18 +774,6 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo serverError, ok := status.FromError(err) Expect(ok).To(BeTrue()) Expect(serverError.Code()).To(Equal(codes.InvalidArgument)) - - By("cleaning up deleting the volume") - - _, err = c.DeleteVolume( - context.Background(), - &csi.DeleteVolumeRequest{ - VolumeId: vol.GetVolume().GetVolumeId(), - Secrets: sc.Secrets.DeleteVolumeSecret, - }, - ) - Expect(err).NotTo(HaveOccurred()) - cl.UnregisterVolume(name) }) It("should return appropriate values (no optional values added)", func() { @@ -940,7 +782,7 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo By("creating a single node writer volume") name := UniqueString("sanity-controller-validate") - vol, err := c.CreateVolume( + vol := r.MustCreateVolume( context.Background(), &csi.CreateVolumeRequest{ Name: name, @@ -954,15 +796,10 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo Parameters: sc.Config.TestVolumeParameters, }, ) - Expect(err).NotTo(HaveOccurred()) - Expect(vol).NotTo(BeNil()) - Expect(vol.GetVolume()).NotTo(BeNil()) - Expect(vol.GetVolume().GetVolumeId()).NotTo(BeEmpty()) - cl.RegisterVolume(name, VolumeInfo{VolumeID: vol.GetVolume().GetVolumeId()}) // ValidateVolumeCapabilities By("validating volume capabilities") - valivolcap, err := c.ValidateVolumeCapabilities( + valivolcap, err := r.ValidateVolumeCapabilities( context.Background(), &csi.ValidateVolumeCapabilitiesRequest{ VolumeId: vol.GetVolume().GetVolumeId(), @@ -979,23 +816,11 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo if valivolcap.GetConfirmed() != nil { Expect(valivolcap.GetConfirmed().GetVolumeCapabilities()).NotTo(BeEmpty()) } - - By("cleaning up deleting the volume") - - _, err = c.DeleteVolume( - context.Background(), - &csi.DeleteVolumeRequest{ - VolumeId: vol.GetVolume().GetVolumeId(), - Secrets: sc.Secrets.DeleteVolumeSecret, - }, - ) - Expect(err).NotTo(HaveOccurred()) - cl.UnregisterVolume(name) }) It("should fail when the requested volume does not exist", func() { - _, err := c.ValidateVolumeCapabilities( + _, err := r.ValidateVolumeCapabilities( context.Background(), &csi.ValidateVolumeCapabilitiesRequest{ VolumeId: sc.Config.IDGen.GenerateUniqueValidVolumeID(), @@ -1015,14 +840,14 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo Describe("ControllerPublishVolume", func() { BeforeEach(func() { - if !isControllerCapabilitySupported(c, csi.ControllerServiceCapability_RPC_PUBLISH_UNPUBLISH_VOLUME) { + if !isControllerCapabilitySupported(r, csi.ControllerServiceCapability_RPC_PUBLISH_UNPUBLISH_VOLUME) { Skip("ControllerPublishVolume not supported") } }) It("should fail when no volume id is provided", func() { - _, err := c.ControllerPublishVolume( + _, err := r.ControllerPublishVolume( context.Background(), &csi.ControllerPublishVolumeRequest{ Secrets: sc.Secrets.ControllerPublishVolumeSecret, @@ -1037,7 +862,7 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo It("should fail when no node id is provided", func() { - _, err := c.ControllerPublishVolume( + _, err := r.ControllerPublishVolume( context.Background(), &csi.ControllerPublishVolumeRequest{ VolumeId: sc.Config.IDGen.GenerateUniqueValidVolumeID(), @@ -1053,7 +878,7 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo It("should fail when no volume capability is provided", func() { - _, err := c.ControllerPublishVolume( + _, err := r.ControllerPublishVolume( context.Background(), &csi.ControllerPublishVolumeRequest{ VolumeId: sc.Config.IDGen.GenerateUniqueValidVolumeID(), @@ -1074,7 +899,7 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo } By("getting node info") - nodeInfo, err := n.NodeGetInfo( + nodeInfo, err := r.NodeGetInfo( context.Background(), &csi.NodeGetInfoRequest{}) Expect(err).NotTo(HaveOccurred()) @@ -1087,34 +912,32 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo nid := nodeInfo.GetNodeId() Expect(nid).NotTo(BeEmpty()) - // Store the volume name and volume ID for later cleanup. - createdVols := map[string]string{} - By("creating volumes") + By("publishing volumes") for i := int64(0); i < nodeInfo.MaxVolumesPerNode; i++ { name := UniqueString(fmt.Sprintf("sanity-max-attach-limit-vol-%d", i)) - volID, err := CreateAndControllerPublishVolume(sc, c, name, nid) - Expect(err).NotTo(HaveOccurred()) - cl.RegisterVolume(name, VolumeInfo{VolumeID: volID, NodeID: nid}) - createdVols[name] = volID + vol := r.MustCreateVolume(context.Background(), MakeCreateVolumeReq(sc, name)) + volID := vol.GetVolume().GetVolumeId() + r.MustControllerPublishVolume( + context.Background(), + MakeControllerPublishVolumeReq(sc, volID, nid), + ) } extraVolName := UniqueString("sanity-max-attach-limit-vol+1") - _, err = CreateAndControllerPublishVolume(sc, c, extraVolName, nid) - Expect(err).To(HaveOccurred()) + vol := r.MustCreateVolume(context.Background(), MakeCreateVolumeReq(sc, extraVolName)) - By("cleaning up") - for volName, volID := range createdVols { - err = ControllerUnpublishAndDeleteVolume(sc, c, volID, nid) - Expect(err).NotTo(HaveOccurred()) - cl.UnregisterVolume(volName) - } + _, err = r.ControllerPublishVolume( + context.Background(), + MakeControllerPublishVolumeReq(sc, vol.Volume.VolumeId, nid), + ) + Expect(err).To(HaveOccurred()) }) It("should fail when the volume does not exist", func() { By("calling controller publish on a non-existent volume") - conpubvol, err := c.ControllerPublishVolume( + conpubvol, err := r.ControllerPublishVolume( context.Background(), &csi.ControllerPublishVolumeRequest{ VolumeId: sc.Config.IDGen.GenerateUniqueValidVolumeID(), @@ -1138,7 +961,7 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo By("creating a single node writer volume") name := UniqueString("sanity-controller-wrong-node") - vol, err := c.CreateVolume( + vol := r.MustCreateVolume( context.Background(), &csi.CreateVolumeRequest{ Name: name, @@ -1149,16 +972,11 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo Parameters: sc.Config.TestVolumeParameters, }, ) - Expect(err).NotTo(HaveOccurred()) - Expect(vol).NotTo(BeNil()) - Expect(vol.GetVolume()).NotTo(BeNil()) - Expect(vol.GetVolume().GetVolumeId()).NotTo(BeEmpty()) - cl.RegisterVolume(name, VolumeInfo{VolumeID: vol.GetVolume().GetVolumeId()}) // ControllerPublishVolume By("calling controllerpublish on that volume") - conpubvol, err := c.ControllerPublishVolume( + conpubvol, err := r.ControllerPublishVolume( context.Background(), &csi.ControllerPublishVolumeRequest{ VolumeId: vol.GetVolume().GetVolumeId(), @@ -1174,22 +992,10 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo serverError, ok := status.FromError(err) Expect(ok).To(BeTrue()) Expect(serverError.Code()).To(Equal(codes.NotFound)) - - By("cleaning up deleting the volume") - - _, err = c.DeleteVolume( - context.Background(), - &csi.DeleteVolumeRequest{ - VolumeId: vol.GetVolume().GetVolumeId(), - Secrets: sc.Secrets.DeleteVolumeSecret, - }, - ) - Expect(err).NotTo(HaveOccurred()) - cl.UnregisterVolume(name) }) It("should fail when the volume is already published but is incompatible", func() { - if !isControllerCapabilitySupported(c, csi.ControllerServiceCapability_RPC_PUBLISH_READONLY) { + if !isControllerCapabilitySupported(r, csi.ControllerServiceCapability_RPC_PUBLISH_READONLY) { Skip("ControllerPublishVolume.readonly field not supported") } @@ -1197,7 +1003,7 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo By("creating a single node writer volume") name := UniqueString("sanity-controller-published-incompatible") - vol, err := c.CreateVolume( + vol := r.MustCreateVolume( context.Background(), &csi.CreateVolumeRequest{ Name: name, @@ -1208,14 +1014,9 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo Parameters: sc.Config.TestVolumeParameters, }, ) - Expect(err).NotTo(HaveOccurred()) - Expect(vol).NotTo(BeNil()) - Expect(vol.GetVolume()).NotTo(BeNil()) - Expect(vol.GetVolume().GetVolumeId()).NotTo(BeEmpty()) - cl.RegisterVolume(name, VolumeInfo{VolumeID: vol.GetVolume().GetVolumeId()}) By("getting a node id") - nid, err := n.NodeGetInfo( + nid, err := r.NodeGetInfo( context.Background(), &csi.NodeGetInfoRequest{}) Expect(err).NotTo(HaveOccurred()) @@ -1233,76 +1034,47 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo Secrets: sc.Secrets.ControllerPublishVolumeSecret, } - conpubvol, err := c.ControllerPublishVolume(context.Background(), pubReq) - Expect(err).NotTo(HaveOccurred()) - Expect(conpubvol).NotTo(BeNil()) + conpubvol := r.MustControllerPublishVolume(context.Background(), pubReq) // Publish again with different attributes. pubReq.Readonly = true - conpubvol, err = c.ControllerPublishVolume(context.Background(), pubReq) + conpubvol, err = r.ControllerPublishVolume(context.Background(), pubReq) Expect(err).To(HaveOccurred()) Expect(conpubvol).To(BeNil()) serverError, ok := status.FromError(err) Expect(ok).To(BeTrue()) Expect(serverError.Code()).To(Equal(codes.AlreadyExists)) - - By("cleaning up unpublishing the volume") - - conunpubvol, err := c.ControllerUnpublishVolume( - context.Background(), - &csi.ControllerUnpublishVolumeRequest{ - VolumeId: vol.GetVolume().GetVolumeId(), - // NodeID is optional in ControllerUnpublishVolume - NodeId: nid.GetNodeId(), - Secrets: sc.Secrets.ControllerUnpublishVolumeSecret, - }, - ) - - Expect(err).NotTo(HaveOccurred()) - Expect(conunpubvol).NotTo(BeNil()) - - By("cleaning up deleting the volume") - - _, err = c.DeleteVolume( - context.Background(), - &csi.DeleteVolumeRequest{ - VolumeId: vol.GetVolume().GetVolumeId(), - Secrets: sc.Secrets.DeleteVolumeSecret, - }, - ) - Expect(err).NotTo(HaveOccurred()) - cl.UnregisterVolume(name) }) }) Describe("volume lifecycle", func() { BeforeEach(func() { - if !isControllerCapabilitySupported(c, csi.ControllerServiceCapability_RPC_PUBLISH_UNPUBLISH_VOLUME) { + if !isControllerCapabilitySupported(r, csi.ControllerServiceCapability_RPC_PUBLISH_UNPUBLISH_VOLUME) { Skip("Controller Publish, UnpublishVolume not supported") } }) It("should work", func() { - VolumeLifecycle(n, c, sc, cl, 1) + VolumeLifecycle(r, sc, 1) }) It("should be idempotent", func() { - VolumeLifecycle(n, c, sc, cl, sc.Config.IdempotentCount) + VolumeLifecycle(r, sc, sc.Config.IdempotentCount) }) }) Describe("ControllerUnpublishVolume", func() { BeforeEach(func() { - if !isControllerCapabilitySupported(c, csi.ControllerServiceCapability_RPC_PUBLISH_UNPUBLISH_VOLUME) { + if !isControllerCapabilitySupported(r, csi.ControllerServiceCapability_RPC_PUBLISH_UNPUBLISH_VOLUME) { Skip("ControllerUnpublishVolume not supported") } }) It("should fail when no volume id is provided", func() { - _, err := c.ControllerUnpublishVolume( + _, err := r.ControllerUnpublishVolume( context.Background(), &csi.ControllerUnpublishVolumeRequest{ Secrets: sc.Secrets.ControllerUnpublishVolumeSecret, @@ -1318,20 +1090,26 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo }) var _ = DescribeSanity("ListSnapshots [Controller Server]", func(sc *TestContext) { - var ( - c csi.ControllerClient - ) + var r *Resources BeforeEach(func() { - c = csi.NewControllerClient(sc.ControllerConn) + r = &Resources{ + Context: sc, + ControllerClient: csi.NewControllerClient(sc.ControllerConn), + NodeClient: csi.NewNodeClient(sc.Conn), + } - if !isControllerCapabilitySupported(c, csi.ControllerServiceCapability_RPC_LIST_SNAPSHOTS) { + if !isControllerCapabilitySupported(r, csi.ControllerServiceCapability_RPC_LIST_SNAPSHOTS) { Skip("ListSnapshots not supported") } }) + AfterEach(func() { + r.Cleanup() + }) + It("should return appropriate values (no optional values added)", func() { - snapshots, err := c.ListSnapshots( + snapshots, err := r.ListSnapshots( context.Background(), &csi.ListSnapshotsRequest{}) Expect(err).NotTo(HaveOccurred()) @@ -1350,69 +1128,32 @@ var _ = DescribeSanity("ListSnapshots [Controller Server]", func(sc *TestContext By("creating first unrelated snapshot") // Create volume source and afterwards the first unrelated snapshot. volReq := MakeCreateVolumeReq(sc, "listSnapshots-volume-unrelated1") - volumeUnrelated1, err := c.CreateVolume(context.Background(), volReq) - Expect(err).NotTo(HaveOccurred()) - - snapshotReq := MakeCreateSnapshotReq(sc, "listSnapshots-snapshot-unrelated1", volumeUnrelated1.GetVolume().GetVolumeId()) - snapshotUnrelated1, err := c.CreateSnapshot(context.Background(), snapshotReq) - Expect(err).NotTo(HaveOccurred()) + r.MustCreateSnapshotFromVolumeRequest(context.Background(), volReq, "listSnapshots-snapshot-unrelated1") By("creating target snapshot") // Create volume source and afterwards the target snapshot. volReq = MakeCreateVolumeReq(sc, "listSnapshots-volume-target") - volumeTarget, err := c.CreateVolume(context.Background(), volReq) - Expect(err).NotTo(HaveOccurred()) - - snapshotReq = MakeCreateSnapshotReq(sc, "listSnapshots-snapshot-target", volumeTarget.GetVolume().GetVolumeId()) - snapshotTarget, err := c.CreateSnapshot(context.Background(), snapshotReq) - Expect(err).NotTo(HaveOccurred()) + snapshotTarget, _ := r.MustCreateSnapshotFromVolumeRequest(context.Background(), volReq, "listSnapshots-snapshot-target") By("creating second unrelated snapshot") // Create volume source and afterwards the second unrelated snapshot. volReq = MakeCreateVolumeReq(sc, "listSnapshots-volume-unrelated2") - volumeUnrelated2, err := c.CreateVolume(context.Background(), volReq) - Expect(err).NotTo(HaveOccurred()) - - snapshotReq = MakeCreateSnapshotReq(sc, "listSnapshots-snapshot-unrelated2", volumeUnrelated2.GetVolume().GetVolumeId()) - snapshotUnrelated2, err := c.CreateSnapshot(context.Background(), snapshotReq) - Expect(err).NotTo(HaveOccurred()) + r.MustCreateSnapshotFromVolumeRequest(context.Background(), volReq, "listSnapshots-snapshot-unrelated2") By("listing snapshots") - snapshots, err := c.ListSnapshots( + snapshots, err := r.ListSnapshots( context.Background(), &csi.ListSnapshotsRequest{SnapshotId: snapshotTarget.GetSnapshot().GetSnapshotId()}) Expect(err).NotTo(HaveOccurred()) Expect(snapshots).NotTo(BeNil()) - Expect(len(snapshots.GetEntries())).To(BeNumerically("==", 1)) + Expect(snapshots.GetEntries()).To(HaveLen(1)) verifySnapshotInfo(snapshots.GetEntries()[0].GetSnapshot()) Expect(snapshots.GetEntries()[0].GetSnapshot().GetSnapshotId()).To(Equal(snapshotTarget.GetSnapshot().GetSnapshotId())) - - By("deleting snapshots") - for _, snapshot := range []*csi.CreateSnapshotResponse{ - snapshotUnrelated1, - snapshotTarget, - snapshotUnrelated2, - } { - delSnapReq := MakeDeleteSnapshotReq(sc, snapshot.GetSnapshot().GetSnapshotId()) - _, err = c.DeleteSnapshot(context.Background(), delSnapReq) - Expect(err).NotTo(HaveOccurred()) - } - - By("deleting volumes") - for _, volume := range []*csi.CreateVolumeResponse{ - volumeUnrelated1, - volumeTarget, - volumeUnrelated2, - } { - delVolReq := MakeDeleteVolumeReq(sc, volume.GetVolume().GetVolumeId()) - _, err = c.DeleteVolume(context.Background(), delVolReq) - Expect(err).NotTo(HaveOccurred()) - } }) It("should return empty when the specified snapshot id does not exist", func() { - snapshots, err := c.ListSnapshots( + snapshots, err := r.ListSnapshots( context.Background(), &csi.ListSnapshotsRequest{SnapshotId: "none-exist-id"}) Expect(err).NotTo(HaveOccurred()) @@ -1429,35 +1170,20 @@ var _ = DescribeSanity("ListSnapshots [Controller Server]", func(sc *TestContext By("creating first unrelated snapshot") // Create volume source and afterwards the first unrelated snapshot. volReq := MakeCreateVolumeReq(sc, "listSnapshots-volume-unrelated1") - volumeUnrelated1, err := c.CreateVolume(context.Background(), volReq) - Expect(err).NotTo(HaveOccurred()) - - snapshotReq := MakeCreateSnapshotReq(sc, "listSnapshots-snapshot-unrelated1", volumeUnrelated1.GetVolume().GetVolumeId()) - snapshotUnrelated1, err := c.CreateSnapshot(context.Background(), snapshotReq) - Expect(err).NotTo(HaveOccurred()) + r.MustCreateSnapshotFromVolumeRequest(context.Background(), volReq, "listSnapshots-snapshot-unrelated1") By("creating target snapshot") // Create volume source and afterwards the target snapshot. volReq = MakeCreateVolumeReq(sc, "listSnapshots-volume-target") - volumeTarget, err := c.CreateVolume(context.Background(), volReq) - Expect(err).NotTo(HaveOccurred()) - - snapshotReq = MakeCreateSnapshotReq(sc, "listSnapshots-snapshot-target", volumeTarget.GetVolume().GetVolumeId()) - snapshotTarget, err := c.CreateSnapshot(context.Background(), snapshotReq) - Expect(err).NotTo(HaveOccurred()) + snapshotTarget, _ := r.MustCreateSnapshotFromVolumeRequest(context.Background(), volReq, "listSnapshots-snapshot-target") By("creating second unrelated snapshot") // Create volume source and afterwards the second unrelated snapshot. volReq = MakeCreateVolumeReq(sc, "listSnapshots-volume-unrelated2") - volumeUnrelated2, err := c.CreateVolume(context.Background(), volReq) - Expect(err).NotTo(HaveOccurred()) - - snapshotReq = MakeCreateSnapshotReq(sc, "listSnapshots-snapshot-unrelated2", volumeUnrelated2.GetVolume().GetVolumeId()) - snapshotUnrelated2, err := c.CreateSnapshot(context.Background(), snapshotReq) - Expect(err).NotTo(HaveOccurred()) + r.MustCreateSnapshotFromVolumeRequest(context.Background(), volReq, "listSnapshots-snapshot-unrelated2") By("listing snapshots") - snapshots, err := c.ListSnapshots( + snapshots, err := r.ListSnapshots( context.Background(), &csi.ListSnapshotsRequest{SourceVolumeId: snapshotTarget.GetSnapshot().GetSourceVolumeId()}) Expect(err).NotTo(HaveOccurred()) @@ -1466,33 +1192,11 @@ var _ = DescribeSanity("ListSnapshots [Controller Server]", func(sc *TestContext snapshot := snapshots.GetEntries()[0].GetSnapshot() verifySnapshotInfo(snapshot) Expect(snapshot.GetSourceVolumeId()).To(Equal(snapshotTarget.GetSnapshot().GetSourceVolumeId())) - - By("deleting snapshots") - for _, snapshot := range []*csi.CreateSnapshotResponse{ - snapshotUnrelated1, - snapshotTarget, - snapshotUnrelated2, - } { - delSnapReq := MakeDeleteSnapshotReq(sc, snapshot.GetSnapshot().GetSnapshotId()) - _, err = c.DeleteSnapshot(context.Background(), delSnapReq) - Expect(err).NotTo(HaveOccurred()) - } - - By("deleting volumes") - for _, volume := range []*csi.CreateVolumeResponse{ - volumeUnrelated1, - volumeTarget, - volumeUnrelated2, - } { - delVolReq := MakeDeleteVolumeReq(sc, volume.GetVolume().GetVolumeId()) - _, err = c.DeleteVolume(context.Background(), delVolReq) - Expect(err).NotTo(HaveOccurred()) - } }) It("should return empty when the specified source volume id does not exist", func() { - snapshots, err := c.ListSnapshots( + snapshots, err := r.ListSnapshots( context.Background(), &csi.ListSnapshotsRequest{SourceVolumeId: sc.Config.IDGen.GenerateUniqueValidVolumeID()}) Expect(err).NotTo(HaveOccurred()) @@ -1502,7 +1206,7 @@ var _ = DescribeSanity("ListSnapshots [Controller Server]", func(sc *TestContext It("check the presence of new snapshots in the snapshot list", func() { // List Snapshots before creating new snapshots. - snapshots, err := c.ListSnapshots( + snapshots, err := r.ListSnapshots( context.Background(), &csi.ListSnapshotsRequest{}) Expect(err).NotTo(HaveOccurred()) @@ -1510,42 +1214,29 @@ var _ = DescribeSanity("ListSnapshots [Controller Server]", func(sc *TestContext totalSnapshots := len(snapshots.GetEntries()) - By("creating a volume") - volReq := MakeCreateVolumeReq(sc, "listSnapshots-volume-3") - volume, err := c.CreateVolume(context.Background(), volReq) - Expect(err).NotTo(HaveOccurred()) - By("creating a snapshot") - snapReq := MakeCreateSnapshotReq(sc, "listSnapshots-snapshot-3", volume.GetVolume().GetVolumeId()) - snapshot, err := c.CreateSnapshot(context.Background(), snapReq) - Expect(err).NotTo(HaveOccurred()) - Expect(snapshot).NotTo(BeNil()) + volReq := MakeCreateVolumeReq(sc, "listSnapshots-volume-3") + snapshot, _ := r.MustCreateSnapshotFromVolumeRequest(context.Background(), volReq, "listSnapshots-snapshot-3") verifySnapshotInfo(snapshot.GetSnapshot()) - snapshots, err = c.ListSnapshots( + snapshots, err = r.ListSnapshots( context.Background(), &csi.ListSnapshotsRequest{}) Expect(err).NotTo(HaveOccurred()) Expect(snapshots).NotTo(BeNil()) - Expect(len(snapshots.GetEntries())).To(Equal(totalSnapshots + 1)) + Expect(snapshots.GetEntries()).To(HaveLen(totalSnapshots + 1)) - By("cleaning up deleting the snapshot") - delSnapReq := MakeDeleteSnapshotReq(sc, snapshot.GetSnapshot().GetSnapshotId()) - _, err = c.DeleteSnapshot(context.Background(), delSnapReq) + By("deleting the snapshot") + _, err = r.DeleteSnapshot(context.Background(), &csi.DeleteSnapshotRequest{SnapshotId: snapshot.Snapshot.SnapshotId}) Expect(err).NotTo(HaveOccurred()) - By("cleaning up deleting the volume") - delVolReq := MakeDeleteVolumeReq(sc, volume.GetVolume().GetVolumeId()) - _, err = c.DeleteVolume(context.Background(), delVolReq) - Expect(err).NotTo(HaveOccurred()) - - // List snapshots and check if the deleted snapshot exists in the snapshot list. - snapshots, err = c.ListSnapshots( + By("checking if deleted snapshot is omitted") + snapshots, err = r.ListSnapshots( context.Background(), &csi.ListSnapshotsRequest{}) Expect(err).NotTo(HaveOccurred()) Expect(snapshots).NotTo(BeNil()) - Expect(len(snapshots.GetEntries())).To(Equal(totalSnapshots)) + Expect(snapshots.GetEntries()).To(HaveLen(totalSnapshots)) }) It("should return next token when a limited number of entries are requested", func() { @@ -1559,7 +1250,7 @@ var _ = DescribeSanity("ListSnapshots [Controller Server]", func(sc *TestContext currentTotalSnapshots := 0 // Get the number of existing volumes. - snapshots, err := c.ListSnapshots( + snapshots, err := r.ListSnapshots( context.Background(), &csi.ListSnapshotsRequest{}) Expect(err).NotTo(HaveOccurred()) @@ -1568,9 +1259,6 @@ var _ = DescribeSanity("ListSnapshots [Controller Server]", func(sc *TestContext initialTotalSnapshots := len(snapshots.GetEntries()) currentTotalSnapshots = initialTotalSnapshots - createVols := make([]*csi.Volume, 0) - createSnapshots := make([]*csi.Snapshot, 0) - // Ensure minimum minVolCount volumes exist. if initialTotalSnapshots < minSnapshotCount { @@ -1579,17 +1267,8 @@ var _ = DescribeSanity("ListSnapshots [Controller Server]", func(sc *TestContext for i := 1; i <= requiredSnapshots; i++ { volReq := MakeCreateVolumeReq(sc, "volume"+strconv.Itoa(i)) - volume, err := c.CreateVolume(context.Background(), volReq) - Expect(err).NotTo(HaveOccurred()) - Expect(volume).NotTo(BeNil()) - createVols = append(createVols, volume.GetVolume()) - - snapReq := MakeCreateSnapshotReq(sc, "snapshot"+strconv.Itoa(i), volume.GetVolume().GetVolumeId()) - snapshot, err := c.CreateSnapshot(context.Background(), snapReq) - Expect(err).NotTo(HaveOccurred()) - Expect(snapshot).NotTo(BeNil()) + snapshot, _ := r.MustCreateSnapshotFromVolumeRequest(context.Background(), volReq, "snapshot"+strconv.Itoa(i)) verifySnapshotInfo(snapshot.GetSnapshot()) - createSnapshots = append(createSnapshots, snapshot.GetSnapshot()) } // Update the current total snapshots count. @@ -1597,7 +1276,7 @@ var _ = DescribeSanity("ListSnapshots [Controller Server]", func(sc *TestContext } // Request list snapshots with max entries maxEntries. - snapshots, err = c.ListSnapshots( + snapshots, err = r.ListSnapshots( context.Background(), &csi.ListSnapshotsRequest{ MaxEntries: int32(maxEntries), @@ -1607,10 +1286,10 @@ var _ = DescribeSanity("ListSnapshots [Controller Server]", func(sc *TestContext nextToken := snapshots.GetNextToken() - Expect(len(snapshots.GetEntries())).To(Equal(maxEntries)) + Expect(snapshots.GetEntries()).To(HaveLen(maxEntries)) // Request list snapshots with starting_token and no max entries. - snapshots, err = c.ListSnapshots( + snapshots, err = r.ListSnapshots( context.Background(), &csi.ListSnapshotsRequest{ StartingToken: nextToken, @@ -1619,43 +1298,29 @@ var _ = DescribeSanity("ListSnapshots [Controller Server]", func(sc *TestContext Expect(snapshots).NotTo(BeNil()) // Ensure that all the remaining entries are returned at once. - Expect(len(snapshots.GetEntries())).To(Equal(currentTotalSnapshots - maxEntries)) - - if initialTotalSnapshots < minSnapshotCount { - - By("cleaning up deleting the snapshots") - - for _, snap := range createSnapshots { - delSnapReq := MakeDeleteSnapshotReq(sc, snap.GetSnapshotId()) - _, err = c.DeleteSnapshot(context.Background(), delSnapReq) - Expect(err).NotTo(HaveOccurred()) - } - - By("cleaning up deleting the volumes") - - for _, vol := range createVols { - delVolReq := MakeDeleteVolumeReq(sc, vol.GetVolumeId()) - _, err = c.DeleteVolume(context.Background(), delVolReq) - Expect(err).NotTo(HaveOccurred()) - } - } + Expect(snapshots.GetEntries()).To(HaveLen(currentTotalSnapshots - maxEntries)) }) - }) var _ = DescribeSanity("DeleteSnapshot [Controller Server]", func(sc *TestContext) { - var ( - c csi.ControllerClient - ) + var r *Resources BeforeEach(func() { - c = csi.NewControllerClient(sc.ControllerConn) + r = &Resources{ + Context: sc, + ControllerClient: csi.NewControllerClient(sc.ControllerConn), + NodeClient: csi.NewNodeClient(sc.Conn), + } - if !isControllerCapabilitySupported(c, csi.ControllerServiceCapability_RPC_CREATE_DELETE_SNAPSHOT) { + if !isControllerCapabilitySupported(r, csi.ControllerServiceCapability_RPC_CREATE_DELETE_SNAPSHOT) { Skip("DeleteSnapshot not supported") } }) + AfterEach(func() { + r.Cleanup() + }) + It("should fail when no snapshot id is provided", func() { req := &csi.DeleteSnapshotRequest{} @@ -1664,7 +1329,7 @@ var _ = DescribeSanity("DeleteSnapshot [Controller Server]", func(sc *TestContex req.Secrets = sc.Secrets.DeleteSnapshotSecret } - _, err := c.DeleteSnapshot(context.Background(), req) + _, err := r.DeleteSnapshot(context.Background(), req) Expect(err).To(HaveOccurred()) serverError, ok := status.FromError(err) @@ -1675,7 +1340,7 @@ var _ = DescribeSanity("DeleteSnapshot [Controller Server]", func(sc *TestContex It("should succeed when an invalid snapshot id is used", func() { req := MakeDeleteSnapshotReq(sc, "reallyfakesnapshotid") - _, err := c.DeleteSnapshot(context.Background(), req) + _, err := r.DeleteSnapshot(context.Background(), req) Expect(err).NotTo(HaveOccurred()) }) @@ -1683,42 +1348,35 @@ var _ = DescribeSanity("DeleteSnapshot [Controller Server]", func(sc *TestContex By("creating a volume") volReq := MakeCreateVolumeReq(sc, "DeleteSnapshot-volume-1") - volume, err := c.CreateVolume(context.Background(), volReq) + volume, err := r.CreateVolume(context.Background(), volReq) Expect(err).NotTo(HaveOccurred()) // Create Snapshot First By("creating a snapshot") snapshotReq := MakeCreateSnapshotReq(sc, "DeleteSnapshot-snapshot-1", volume.GetVolume().GetVolumeId()) - snapshot, err := c.CreateSnapshot(context.Background(), snapshotReq) - Expect(err).NotTo(HaveOccurred()) - Expect(snapshot).NotTo(BeNil()) - verifySnapshotInfo(snapshot.GetSnapshot()) - - By("cleaning up deleting the snapshot") - delSnapReq := MakeDeleteSnapshotReq(sc, snapshot.GetSnapshot().GetSnapshotId()) - _, err = c.DeleteSnapshot(context.Background(), delSnapReq) - Expect(err).NotTo(HaveOccurred()) - - By("cleaning up deleting the volume") - delVolReq := MakeDeleteVolumeReq(sc, volume.GetVolume().GetVolumeId()) - _, err = c.DeleteVolume(context.Background(), delVolReq) - Expect(err).NotTo(HaveOccurred()) + r.MustCreateSnapshot(context.Background(), snapshotReq) }) }) var _ = DescribeSanity("CreateSnapshot [Controller Server]", func(sc *TestContext) { - var ( - c csi.ControllerClient - ) + var r *Resources BeforeEach(func() { - c = csi.NewControllerClient(sc.ControllerConn) + r = &Resources{ + Context: sc, + ControllerClient: csi.NewControllerClient(sc.ControllerConn), + NodeClient: csi.NewNodeClient(sc.Conn), + } - if !isControllerCapabilitySupported(c, csi.ControllerServiceCapability_RPC_CREATE_DELETE_SNAPSHOT) { + if !isControllerCapabilitySupported(r, csi.ControllerServiceCapability_RPC_CREATE_DELETE_SNAPSHOT) { Skip("CreateSnapshot not supported") } }) + AfterEach(func() { + r.Cleanup() + }) + It("should fail when no name is provided", func() { req := &csi.CreateSnapshotRequest{ @@ -1729,7 +1387,7 @@ var _ = DescribeSanity("CreateSnapshot [Controller Server]", func(sc *TestContex req.Secrets = sc.Secrets.CreateSnapshotSecret } - _, err := c.CreateSnapshot(context.Background(), req) + _, err := r.CreateSnapshot(context.Background(), req) Expect(err).To(HaveOccurred()) serverError, ok := status.FromError(err) Expect(ok).To(BeTrue()) @@ -1746,84 +1404,51 @@ var _ = DescribeSanity("CreateSnapshot [Controller Server]", func(sc *TestContex req.Secrets = sc.Secrets.CreateSnapshotSecret } - _, err := c.CreateSnapshot(context.Background(), req) + _, err := r.CreateSnapshot(context.Background(), req) Expect(err).To(HaveOccurred()) serverError, ok := status.FromError(err) Expect(ok).To(BeTrue()) Expect(serverError.Code()).To(Equal(codes.InvalidArgument)) }) - It("should not fail when requesting to create a snapshot with already existing name and same SourceVolumeId.", func() { + It("should succeed when requesting to create a snapshot with already existing name and same source volume ID", func() { By("creating a volume") volReq := MakeCreateVolumeReq(sc, "CreateSnapshot-volume-1") - volume, err := c.CreateVolume(context.Background(), volReq) - Expect(err).NotTo(HaveOccurred()) + volume := r.MustCreateVolume(context.Background(), volReq) By("creating a snapshot") snapReq1 := MakeCreateSnapshotReq(sc, "CreateSnapshot-snapshot-1", volume.GetVolume().GetVolumeId()) - snap1, err := c.CreateSnapshot(context.Background(), snapReq1) - Expect(err).NotTo(HaveOccurred()) - Expect(snap1).NotTo(BeNil()) - verifySnapshotInfo(snap1.GetSnapshot()) - - snap2, err := c.CreateSnapshot(context.Background(), snapReq1) - Expect(err).NotTo(HaveOccurred()) - Expect(snap2).NotTo(BeNil()) - verifySnapshotInfo(snap2.GetSnapshot()) - - By("cleaning up deleting the snapshot") - delSnapReq := MakeDeleteSnapshotReq(sc, snap1.GetSnapshot().GetSnapshotId()) - _, err = c.DeleteSnapshot(context.Background(), delSnapReq) - Expect(err).NotTo(HaveOccurred()) + r.MustCreateSnapshot(context.Background(), snapReq1) - By("cleaning up deleting the volume") - delVolReq := MakeDeleteVolumeReq(sc, volume.GetVolume().GetVolumeId()) - _, err = c.DeleteVolume(context.Background(), delVolReq) - Expect(err).NotTo(HaveOccurred()) + By("creating a snapshot with the same name and source volume ID") + r.MustCreateSnapshot(context.Background(), snapReq1) }) - It("should fail when requesting to create a snapshot with already existing name and different SourceVolumeId.", func() { + It("should fail when requesting to create a snapshot with already existing name and different source volume ID", func() { - By("creating a volume") - volume, err := c.CreateVolume(context.Background(), MakeCreateVolumeReq(sc, "CreateSnapshot-volume-2")) - Expect(err).ToNot(HaveOccurred()) - - By("creating a snapshot with the created volume source id") - req1 := MakeCreateSnapshotReq(sc, "CreateSnapshot-snapshot-2", volume.GetVolume().GetVolumeId()) - snap1, err := c.CreateSnapshot(context.Background(), req1) - Expect(err).NotTo(HaveOccurred()) - Expect(snap1).NotTo(BeNil()) - verifySnapshotInfo(snap1.GetSnapshot()) + By("creating a snapshot") + volReq := MakeCreateVolumeReq(sc, "CreateSnapshot-volume-2") + r.MustCreateSnapshotFromVolumeRequest(context.Background(), volReq, "CreateSnapshot-snapshot-2") - volume2, err := c.CreateVolume(context.Background(), MakeCreateVolumeReq(sc, "CreateSnapshot-volume-3")) - Expect(err).ToNot(HaveOccurred()) + By("creating a new source volume") + volReq = MakeCreateVolumeReq(sc, "CreateSnapshot-volume-3") + volume2 := r.MustCreateVolume(context.Background(), volReq) - By("creating a snapshot with the same name but different volume source id") - req2 := MakeCreateSnapshotReq(sc, "CreateSnapshot-snapshot-2", volume2.GetVolume().GetVolumeId()) - _, err = c.CreateSnapshot(context.Background(), req2) + By("creating a snapshot with the same name but different source volume ID") + req := MakeCreateSnapshotReq(sc, "CreateSnapshot-snapshot-2", volume2.GetVolume().GetVolumeId()) + _, err := r.CreateSnapshot(context.Background(), req) Expect(err).To(HaveOccurred()) serverError, ok := status.FromError(err) Expect(ok).To(BeTrue()) Expect(serverError.Code()).To(Equal(codes.AlreadyExists)) - - By("cleaning up deleting the snapshot") - delSnapReq := MakeDeleteSnapshotReq(sc, snap1.GetSnapshot().GetSnapshotId()) - _, err = c.DeleteSnapshot(context.Background(), delSnapReq) - Expect(err).NotTo(HaveOccurred()) - - By("cleaning up deleting the volume") - delVolReq := MakeDeleteVolumeReq(sc, volume.GetVolume().GetVolumeId()) - _, err = c.DeleteVolume(context.Background(), delVolReq) - Expect(err).NotTo(HaveOccurred()) }) - It("should not fail when creating snapshot with maximum-length name", func() { + It("should succeed when creating snapshot with maximum-length name", func() { By("creating a volume") volReq := MakeCreateVolumeReq(sc, "CreateSnapshot-volume-3") - volume, err := c.CreateVolume(context.Background(), volReq) - Expect(err).NotTo(HaveOccurred()) + volume := r.MustCreateVolume(context.Background(), volReq) nameBytes := make([]byte, MaxNameLength) for i := 0; i < MaxNameLength; i++ { @@ -1833,47 +1458,31 @@ var _ = DescribeSanity("CreateSnapshot [Controller Server]", func(sc *TestContex By("creating a snapshot") snapReq1 := MakeCreateSnapshotReq(sc, name, volume.GetVolume().GetVolumeId()) - snap1, err := c.CreateSnapshot(context.Background(), snapReq1) - Expect(err).NotTo(HaveOccurred()) - Expect(snap1).NotTo(BeNil()) - verifySnapshotInfo(snap1.GetSnapshot()) - - snap2, err := c.CreateSnapshot(context.Background(), snapReq1) - Expect(err).NotTo(HaveOccurred()) - Expect(snap2).NotTo(BeNil()) - verifySnapshotInfo(snap2.GetSnapshot()) - - By("cleaning up deleting the snapshot") - delSnapReq := MakeDeleteSnapshotReq(sc, snap1.GetSnapshot().GetSnapshotId()) - _, err = c.DeleteSnapshot(context.Background(), delSnapReq) - Expect(err).NotTo(HaveOccurred()) + r.MustCreateSnapshot(context.Background(), snapReq1) - By("cleaning up deleting the volume") - delVolReq := MakeDeleteVolumeReq(sc, volume.GetVolume().GetVolumeId()) - _, err = c.DeleteVolume(context.Background(), delVolReq) - Expect(err).NotTo(HaveOccurred()) + // TODO: review if the second snapshot create is really necessary + r.MustCreateSnapshot(context.Background(), snapReq1) }) }) var _ = DescribeSanity("ExpandVolume [Controller Server]", func(sc *TestContext) { - var ( - c csi.ControllerClient - cl *Cleanup - ) + var r *Resources BeforeEach(func() { - c = csi.NewControllerClient(sc.ControllerConn) - if !isControllerCapabilitySupported(c, csi.ControllerServiceCapability_RPC_EXPAND_VOLUME) { - Skip("ControllerExpandVolume not supported") - } - cl = &Cleanup{ - ControllerClient: c, + r = &Resources{ + ControllerClient: csi.NewControllerClient(sc.ControllerConn), Context: sc, } + + if !isControllerCapabilitySupported(r, csi.ControllerServiceCapability_RPC_EXPAND_VOLUME) { + Skip("ControllerExpandVolume not supported") + } }) + AfterEach(func() { - cl.DeleteVolumes() + r.Cleanup() }) + It("should fail if no volume id is given", func() { expReq := &csi.ControllerExpandVolumeRequest{ VolumeId: "", @@ -1882,7 +1491,7 @@ var _ = DescribeSanity("ExpandVolume [Controller Server]", func(sc *TestContext) }, Secrets: sc.Secrets.ControllerExpandVolumeSecret, } - rsp, err := c.ControllerExpandVolume(context.Background(), expReq) + rsp, err := r.ControllerExpandVolume(context.Background(), expReq) Expect(err).To(HaveOccurred()) Expect(rsp).To(BeNil()) @@ -1896,7 +1505,7 @@ var _ = DescribeSanity("ExpandVolume [Controller Server]", func(sc *TestContext) VolumeId: "", Secrets: sc.Secrets.ControllerExpandVolumeSecret, } - rsp, err := c.ControllerExpandVolume(context.Background(), expReq) + rsp, err := r.ControllerExpandVolume(context.Background(), expReq) Expect(err).To(HaveOccurred()) Expect(rsp).To(BeNil()) @@ -1922,13 +1531,8 @@ var _ = DescribeSanity("ExpandVolume [Controller Server]", func(sc *TestContext) RequiredBytes: TestVolumeSize(sc), }, } + vol := r.MustCreateVolume(context.Background(), req) - vol, err := c.CreateVolume(context.Background(), req) - Expect(err).NotTo(HaveOccurred()) - Expect(vol).NotTo(BeNil()) - Expect(vol.GetVolume()).NotTo(BeNil()) - Expect(vol.GetVolume().GetVolumeId()).NotTo(BeEmpty()) - cl.RegisterVolume(name, VolumeInfo{VolumeID: vol.GetVolume().GetVolumeId()}) By("expanding the volume") expReq := &csi.ControllerExpandVolumeRequest{ VolumeId: vol.GetVolume().GetVolumeId(), @@ -1938,21 +1542,10 @@ var _ = DescribeSanity("ExpandVolume [Controller Server]", func(sc *TestContext) Secrets: sc.Secrets.ControllerExpandVolumeSecret, VolumeCapability: TestVolumeCapabilityWithAccessType(sc, csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER), } - rsp, err := c.ControllerExpandVolume(context.Background(), expReq) + rsp, err := r.ControllerExpandVolume(context.Background(), expReq) Expect(err).NotTo(HaveOccurred()) Expect(rsp).NotTo(BeNil()) Expect(rsp.GetCapacityBytes()).To(Equal(TestVolumeExpandSize(sc))) - - By("cleaning up deleting the volume") - _, err = c.DeleteVolume( - context.Background(), - &csi.DeleteVolumeRequest{ - VolumeId: vol.GetVolume().GetVolumeId(), - Secrets: sc.Secrets.DeleteVolumeSecret, - }, - ) - Expect(err).NotTo(HaveOccurred()) - cl.UnregisterVolume(name) }) }) @@ -2036,43 +1629,12 @@ func MakeControllerUnpublishVolumeReq(sc *TestContext, volID, nodeID string) *cs } } -// CreateAndControllerPublishVolume creates and controller publishes a volume given a volume name and node ID. -func CreateAndControllerPublishVolume(sc *TestContext, c csi.ControllerClient, volName, nodeID string) (volID string, err error) { - vol, err := c.CreateVolume(context.Background(), MakeCreateVolumeReq(sc, volName)) - Expect(err).NotTo(HaveOccurred()) - Expect(vol).NotTo(BeNil()) - Expect(vol.GetVolume()).NotTo(BeNil()) - Expect(vol.GetVolume().GetVolumeId()).NotTo(BeEmpty()) - - _, err = c.ControllerPublishVolume( - context.Background(), - MakeControllerPublishVolumeReq(sc, vol.GetVolume().GetVolumeId(), nodeID), - ) - return vol.GetVolume().GetVolumeId(), err -} - -// ControllerUnpublishAndDeleteVolume controller unpublishes and deletes a volume, given volume ID and node ID. -func ControllerUnpublishAndDeleteVolume(sc *TestContext, c csi.ControllerClient, volID, nodeID string) error { - _, err := c.ControllerUnpublishVolume( - context.Background(), - MakeControllerUnpublishVolumeReq(sc, volID, nodeID), - ) - Expect(err).NotTo(HaveOccurred()) - - _, err = c.DeleteVolume( - context.Background(), - MakeDeleteVolumeReq(sc, volID), - ) - Expect(err).NotTo(HaveOccurred()) - return err -} - // VolumeLifecycle performs Create-Publish-Unpublish-Delete, with optional repeat count to test idempotency. -func VolumeLifecycle(n csi.NodeClient, c csi.ControllerClient, sc *TestContext, cl *Cleanup, count int) { +func VolumeLifecycle(r *Resources, sc *TestContext, count int) { // CSI spec poses no specific requirements for the cluster/storage setups that a SP MUST support. To perform // meaningful checks the following test assumes that topology-aware provisioning on a single node setup is supported By("getting node information") - ni, err := n.NodeGetInfo( + ni, err := r.NodeGetInfo( context.Background(), &csi.NodeGetInfoRequest{}) Expect(err).NotTo(HaveOccurred()) @@ -2091,7 +1653,7 @@ func VolumeLifecycle(n csi.NodeClient, c csi.ControllerClient, sc *TestContext, By("creating a single node writer volume") name := UniqueString("sanity-controller-publish") - vol, err := c.CreateVolume( + vol := r.MustCreateVolume( context.Background(), &csi.CreateVolumeRequest{ Name: name, @@ -2103,16 +1665,11 @@ func VolumeLifecycle(n csi.NodeClient, c csi.ControllerClient, sc *TestContext, AccessibilityRequirements: accReqs, }, ) - Expect(err).NotTo(HaveOccurred()) - Expect(vol).NotTo(BeNil()) - Expect(vol.GetVolume()).NotTo(BeNil()) - Expect(vol.GetVolume().GetVolumeId()).NotTo(BeEmpty()) - cl.RegisterVolume(name, VolumeInfo{VolumeID: vol.GetVolume().GetVolumeId()}) // ControllerPublishVolume for i := 0; i < count; i++ { By("calling controllerpublish on that volume") - conpubvol, err := c.ControllerPublishVolume( + r.MustControllerPublishVolume( context.Background(), &csi.ControllerPublishVolumeRequest{ VolumeId: vol.GetVolume().GetVolumeId(), @@ -2122,36 +1679,5 @@ func VolumeLifecycle(n csi.NodeClient, c csi.ControllerClient, sc *TestContext, Secrets: sc.Secrets.ControllerPublishVolumeSecret, }, ) - Expect(err).NotTo(HaveOccurred()) - Expect(conpubvol).NotTo(BeNil()) - } - cl.RegisterVolume(name, VolumeInfo{VolumeID: vol.GetVolume().GetVolumeId(), NodeID: ni.GetNodeId()}) - - for i := 0; i < count; i++ { - By("cleaning up unpublishing the volume") - conunpubvol, err := c.ControllerUnpublishVolume( - context.Background(), - &csi.ControllerUnpublishVolumeRequest{ - VolumeId: vol.GetVolume().GetVolumeId(), - // NodeID is optional in ControllerUnpublishVolume - NodeId: ni.GetNodeId(), - Secrets: sc.Secrets.ControllerUnpublishVolumeSecret, - }, - ) - Expect(err).NotTo(HaveOccurred()) - Expect(conunpubvol).NotTo(BeNil()) - } - - for i := 0; i < count; i++ { - By("cleaning up deleting the volume") - _, err = c.DeleteVolume( - context.Background(), - &csi.DeleteVolumeRequest{ - VolumeId: vol.GetVolume().GetVolumeId(), - Secrets: sc.Secrets.DeleteVolumeSecret, - }, - ) - Expect(err).NotTo(HaveOccurred()) } - cl.UnregisterVolume(name) } diff --git a/pkg/sanity/logger.go b/pkg/sanity/logger.go new file mode 100644 index 00000000..0f61ab51 --- /dev/null +++ b/pkg/sanity/logger.go @@ -0,0 +1,61 @@ +/* +Copyright 2020 Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package sanity + +import ( + "fmt" + "log" + + . "github.com/onsi/ginkgo" +) + +type logger struct { + l *log.Logger + numFailed int +} + +func newLogger(prefix string) *logger { + return &logger{ + l: log.New(GinkgoWriter, prefix+" ", 0), + } +} + +// Infof logs a message without marking the test as failed. +func (l *logger) Infof(format string, v ...interface{}) { + l.l.Printf(format, v...) +} + +// Info logs a message without marking the test as failed. +func (l *logger) Info(v ...interface{}) { + l.l.Print(v...) +} + +// Errorf logs a message and marks the test as failed. +func (l *logger) Errorf(err error, format string, v ...interface{}) { + if err == nil { + return + } + l.numFailed++ + l.l.Printf(format, v...) +} + +// ExpectNoErrors fails the spec if any error was logged. +func (l *logger) ExpectNoErrors(offset int) { + if l.numFailed > 0 { + Fail(fmt.Sprintf("recorded %d failure(s)", l.numFailed), offset+1) + } +} diff --git a/pkg/sanity/node.go b/pkg/sanity/node.go index 7cb60e53..0a138580 100644 --- a/pkg/sanity/node.go +++ b/pkg/sanity/node.go @@ -66,12 +66,12 @@ func isPluginCapabilitySupported(c csi.IdentityClient, return false } -func runControllerTest(sc *TestContext, c csi.NodeClient, s csi.ControllerClient, cl *Cleanup, controllerPublishSupported bool, nodeStageSupported bool, nodeVolumeStatsSupported bool, count int) { +func runControllerTest(sc *TestContext, r *Resources, controllerPublishSupported bool, nodeStageSupported bool, nodeVolumeStatsSupported bool, count int) { name := UniqueString("sanity-node-full") By("getting node information") - ni, err := c.NodeGetInfo( + ni, err := r.NodeGetInfo( context.Background(), &csi.NodeGetInfoRequest{}) Expect(err).NotTo(HaveOccurred()) @@ -88,7 +88,7 @@ func runControllerTest(sc *TestContext, c csi.NodeClient, s csi.ControllerClient // Create Volume First By("creating a single node writer volume") - vol, err := s.CreateVolume( + vol := r.MustCreateVolume( context.Background(), &csi.CreateVolumeRequest{ Name: name, @@ -103,17 +103,12 @@ func runControllerTest(sc *TestContext, c csi.NodeClient, s csi.ControllerClient AccessibilityRequirements: accReqs, }, ) - Expect(err).NotTo(HaveOccurred()) - Expect(vol).NotTo(BeNil()) - Expect(vol.GetVolume()).NotTo(BeNil()) - Expect(vol.GetVolume().GetVolumeId()).NotTo(BeEmpty()) - cl.RegisterVolume(name, VolumeInfo{VolumeID: vol.GetVolume().GetVolumeId()}) var conpubvol *csi.ControllerPublishVolumeResponse if controllerPublishSupported { By("controller publishing volume") - conpubvol, err = s.ControllerPublishVolume( + conpubvol, err = r.ControllerPublishVolume( context.Background(), &csi.ControllerPublishVolumeRequest{ VolumeId: vol.GetVolume().GetVolumeId(), @@ -125,14 +120,13 @@ func runControllerTest(sc *TestContext, c csi.NodeClient, s csi.ControllerClient }, ) Expect(err).NotTo(HaveOccurred()) - cl.RegisterVolume(name, VolumeInfo{VolumeID: vol.GetVolume().GetVolumeId(), NodeID: ni.GetNodeId()}) Expect(conpubvol).NotTo(BeNil()) } // NodeStageVolume if nodeStageSupported { for i := 0; i < count; i++ { By("node staging volume") - nodestagevol, err := c.NodeStageVolume( + nodestagevol, err := r.NodeStageVolume( context.Background(), &csi.NodeStageVolumeRequest{ VolumeId: vol.GetVolume().GetVolumeId(), @@ -154,7 +148,7 @@ func runControllerTest(sc *TestContext, c csi.NodeClient, s csi.ControllerClient } for i := 0; i < count; i++ { By("publishing the volume on a node") - nodepubvol, err := c.NodePublishVolume( + nodepubvol, err := r.NodePublishVolume( context.Background(), &csi.NodePublishVolumeRequest{ VolumeId: vol.GetVolume().GetVolumeId(), @@ -173,7 +167,7 @@ func runControllerTest(sc *TestContext, c csi.NodeClient, s csi.ControllerClient // NodeGetVolumeStats if nodeVolumeStatsSupported { By("Get node volume stats") - statsResp, err := c.NodeGetVolumeStats( + statsResp, err := r.NodeGetVolumeStats( context.Background(), &csi.NodeGetVolumeStatsRequest{ VolumeId: vol.GetVolume().GetVolumeId(), @@ -183,71 +177,11 @@ func runControllerTest(sc *TestContext, c csi.NodeClient, s csi.ControllerClient Expect(err).ToNot(HaveOccurred()) Expect(statsResp.GetUsage()).ToNot(BeNil()) } - - // NodeUnpublishVolume - for i := 0; i < count; i++ { - By("cleaning up calling nodeunpublish") - nodeunpubvol, err := c.NodeUnpublishVolume( - context.Background(), - &csi.NodeUnpublishVolumeRequest{ - VolumeId: vol.GetVolume().GetVolumeId(), - TargetPath: sc.TargetPath + "/target", - }) - Expect(err).NotTo(HaveOccurred()) - Expect(nodeunpubvol).NotTo(BeNil()) - } - - if nodeStageSupported { - for i := 0; i < count; i++ { - By("cleaning up calling nodeunstage") - nodeunstagevol, err := c.NodeUnstageVolume( - context.Background(), - &csi.NodeUnstageVolumeRequest{ - VolumeId: vol.GetVolume().GetVolumeId(), - StagingTargetPath: sc.StagingPath, - }, - ) - Expect(err).NotTo(HaveOccurred()) - Expect(nodeunstagevol).NotTo(BeNil()) - } - } - - if controllerPublishSupported { - for i := 0; i < count; i++ { - By("cleaning up calling controllerunpublishing") - - controllerunpubvol, err := s.ControllerUnpublishVolume( - context.Background(), - &csi.ControllerUnpublishVolumeRequest{ - VolumeId: vol.GetVolume().GetVolumeId(), - NodeId: ni.GetNodeId(), - Secrets: sc.Secrets.ControllerUnpublishVolumeSecret, - }, - ) - Expect(err).NotTo(HaveOccurred()) - Expect(controllerunpubvol).NotTo(BeNil()) - } - } - - for i := 0; i < count; i++ { - By("cleaning up deleting the volume") - - _, err = s.DeleteVolume( - context.Background(), - &csi.DeleteVolumeRequest{ - VolumeId: vol.GetVolume().GetVolumeId(), - Secrets: sc.Secrets.DeleteVolumeSecret, - }, - ) - Expect(err).NotTo(HaveOccurred()) - } } var _ = DescribeSanity("Node Service", func(sc *TestContext) { var ( - cl *Cleanup - c csi.NodeClient - s csi.ControllerClient + r *Resources providesControllerService bool controllerPublishSupported bool @@ -259,7 +193,7 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { createVolume := func(volumeName string) *csi.CreateVolumeResponse { By("creating a single node writer volume for expansion") - vol, err := s.CreateVolume( + return r.MustCreateVolume( context.Background(), &csi.CreateVolumeRequest{ Name: volumeName, @@ -273,21 +207,14 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { Parameters: sc.Config.TestVolumeParameters, }, ) - Expect(err).NotTo(HaveOccurred()) - Expect(vol).NotTo(BeNil()) - Expect(vol.GetVolume()).NotTo(BeNil()) - Expect(vol.GetVolume().GetVolumeId()).NotTo(BeEmpty()) - cl.RegisterVolume(volumeName, VolumeInfo{VolumeID: vol.GetVolume().GetVolumeId()}) - return vol } controllerPublishVolume := func(volumeName string, vol *csi.CreateVolumeResponse, nid *csi.NodeGetInfoResponse) *csi.ControllerPublishVolumeResponse { var conpubvol *csi.ControllerPublishVolumeResponse - var err error if controllerPublishSupported { By("controller publishing volume") - conpubvol, err = s.ControllerPublishVolume( + conpubvol = r.MustControllerPublishVolume( context.Background(), &csi.ControllerPublishVolumeRequest{ VolumeId: vol.GetVolume().GetVolumeId(), @@ -298,9 +225,6 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { Secrets: sc.Secrets.ControllerPublishVolumeSecret, }, ) - Expect(err).NotTo(HaveOccurred()) - cl.RegisterVolume(volumeName, VolumeInfo{VolumeID: vol.GetVolume().GetVolumeId(), NodeID: nid.GetNodeId()}) - Expect(conpubvol).NotTo(BeNil()) } return conpubvol } @@ -319,7 +243,7 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { if conpubvol != nil { nodeStageRequest.PublishContext = conpubvol.GetPublishContext() } - nodestagevol, err := c.NodeStageVolume( + nodestagevol, err := r.NodeStageVolume( context.Background(), nodeStageRequest, ) @@ -349,7 +273,7 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { nodePublishRequest.PublishContext = conpubvol.GetPublishContext() } - nodepubvol, err := c.NodePublishVolume( + nodepubvol, err := r.NodePublishVolume( context.Background(), nodePublishRequest, ) @@ -359,8 +283,8 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { } BeforeEach(func() { - c = csi.NewNodeClient(sc.Conn) - s = csi.NewControllerClient(sc.ControllerConn) + cl := csi.NewControllerClient(sc.ControllerConn) + n := csi.NewNodeClient(sc.Conn) i := csi.NewIdentityClient(sc.Conn) req := &csi.GetPluginCapabilitiesRequest{} @@ -378,29 +302,29 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { } if providesControllerService { controllerPublishSupported = isControllerCapabilitySupported( - s, + cl, csi.ControllerServiceCapability_RPC_PUBLISH_UNPUBLISH_VOLUME) } - nodeStageSupported = isNodeCapabilitySupported(c, csi.NodeServiceCapability_RPC_STAGE_UNSTAGE_VOLUME) - nodeVolumeStatsSupported = isNodeCapabilitySupported(c, csi.NodeServiceCapability_RPC_GET_VOLUME_STATS) - nodeExpansionSupported = isNodeCapabilitySupported(c, csi.NodeServiceCapability_RPC_EXPAND_VOLUME) - controllerExpansionSupported = isControllerCapabilitySupported(s, csi.ControllerServiceCapability_RPC_EXPAND_VOLUME) - cl = &Cleanup{ + nodeStageSupported = isNodeCapabilitySupported(n, csi.NodeServiceCapability_RPC_STAGE_UNSTAGE_VOLUME) + nodeVolumeStatsSupported = isNodeCapabilitySupported(n, csi.NodeServiceCapability_RPC_GET_VOLUME_STATS) + nodeExpansionSupported = isNodeCapabilitySupported(n, csi.NodeServiceCapability_RPC_EXPAND_VOLUME) + controllerExpansionSupported = isControllerCapabilitySupported(cl, csi.ControllerServiceCapability_RPC_EXPAND_VOLUME) + r = &Resources{ Context: sc, - NodeClient: c, - ControllerClient: s, + ControllerClient: cl, + NodeClient: n, ControllerPublishSupported: controllerPublishSupported, NodeStageSupported: nodeStageSupported, } }) AfterEach(func() { - cl.DeleteVolumes() + r.Cleanup() }) Describe("NodeGetCapabilities", func() { It("should return appropriate capabilities", func() { - caps, err := c.NodeGetCapabilities( + caps, err := r.NodeGetCapabilities( context.Background(), &csi.NodeGetCapabilitiesRequest{}) @@ -436,7 +360,7 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { }) It("should return appropriate values", func() { - ninfo, err := c.NodeGetInfo( + ninfo, err := r.NodeGetInfo( context.Background(), &csi.NodeGetInfoRequest{}) @@ -453,7 +377,7 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { Describe("NodePublishVolume", func() { It("should fail when no volume id is provided", func() { - _, err := c.NodePublishVolume( + _, err := r.NodePublishVolume( context.Background(), &csi.NodePublishVolumeRequest{ Secrets: sc.Secrets.NodePublishVolumeSecret, @@ -467,7 +391,7 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { }) It("should fail when no target path is provided", func() { - _, err := c.NodePublishVolume( + _, err := r.NodePublishVolume( context.Background(), &csi.NodePublishVolumeRequest{ VolumeId: sc.Config.IDGen.GenerateUniqueValidVolumeID(), @@ -482,7 +406,7 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { }) It("should fail when no volume capability is provided", func() { - _, err := c.NodePublishVolume( + _, err := r.NodePublishVolume( context.Background(), &csi.NodePublishVolumeRequest{ VolumeId: sc.Config.IDGen.GenerateUniqueValidVolumeID(), @@ -502,7 +426,7 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { Describe("NodeUnpublishVolume", func() { It("should fail when no volume id is provided", func() { - _, err := c.NodeUnpublishVolume( + _, err := r.NodeUnpublishVolume( context.Background(), &csi.NodeUnpublishVolumeRequest{}) Expect(err).To(HaveOccurred()) @@ -514,7 +438,7 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { It("should fail when no target path is provided", func() { - _, err := c.NodeUnpublishVolume( + _, err := r.NodeUnpublishVolume( context.Background(), &csi.NodeUnpublishVolumeRequest{ VolumeId: sc.Config.IDGen.GenerateUniqueValidVolumeID(), @@ -541,7 +465,7 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { }) It("should fail when no volume id is provided", func() { - _, err := c.NodeStageVolume( + _, err := r.NodeStageVolume( context.Background(), &csi.NodeStageVolumeRequest{ StagingTargetPath: sc.StagingPath, @@ -560,7 +484,7 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { }) It("should fail when no staging target path is provided", func() { - _, err := c.NodeStageVolume( + _, err := r.NodeStageVolume( context.Background(), &csi.NodeStageVolumeRequest{ VolumeId: sc.Config.IDGen.GenerateUniqueValidVolumeID(), @@ -584,7 +508,7 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { By("creating a single node writer volume") name := UniqueString("sanity-node-stage-nocaps") - vol, err := s.CreateVolume( + vol := r.MustCreateVolume( context.Background(), &csi.CreateVolumeRequest{ Name: name, @@ -602,13 +526,8 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { Parameters: sc.Config.TestVolumeParameters, }, ) - Expect(err).NotTo(HaveOccurred()) - Expect(vol).NotTo(BeNil()) - Expect(vol.GetVolume()).NotTo(BeNil()) - Expect(vol.GetVolume().GetVolumeId()).NotTo(BeEmpty()) - cl.RegisterVolume(name, VolumeInfo{VolumeID: vol.GetVolume().GetVolumeId()}) - _, err = c.NodeStageVolume( + _, err := r.NodeStageVolume( context.Background(), &csi.NodeStageVolumeRequest{ VolumeId: vol.GetVolume().GetVolumeId(), @@ -624,18 +543,6 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { serverError, ok := status.FromError(err) Expect(ok).To(BeTrue()) Expect(serverError.Code()).To(Equal(codes.InvalidArgument)) - - By("cleaning up deleting the volume") - - _, err = s.DeleteVolume( - context.Background(), - &csi.DeleteVolumeRequest{ - VolumeId: vol.GetVolume().GetVolumeId(), - Secrets: sc.Secrets.DeleteVolumeSecret, - }, - ) - Expect(err).NotTo(HaveOccurred()) - cl.UnregisterVolume(name) }) }) @@ -648,7 +555,7 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { It("should fail when no volume id is provided", func() { - _, err := c.NodeUnstageVolume( + _, err := r.NodeUnstageVolume( context.Background(), &csi.NodeUnstageVolumeRequest{ StagingTargetPath: sc.StagingPath, @@ -662,7 +569,7 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { It("should fail when no staging target path is provided", func() { - _, err := c.NodeUnstageVolume( + _, err := r.NodeUnstageVolume( context.Background(), &csi.NodeUnstageVolumeRequest{ VolumeId: sc.Config.IDGen.GenerateUniqueValidVolumeID(), @@ -683,7 +590,7 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { }) It("should fail when no volume id is provided", func() { - _, err := c.NodeGetVolumeStats( + _, err := r.NodeGetVolumeStats( context.Background(), &csi.NodeGetVolumeStatsRequest{ VolumePath: "some/path", @@ -697,7 +604,7 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { }) It("should fail when no volume path is provided", func() { - _, err := c.NodeGetVolumeStats( + _, err := r.NodeGetVolumeStats( context.Background(), &csi.NodeGetVolumeStatsRequest{ VolumeId: sc.Config.IDGen.GenerateUniqueValidVolumeID(), @@ -711,7 +618,7 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { }) It("should fail when volume is not found", func() { - _, err := c.NodeGetVolumeStats( + _, err := r.NodeGetVolumeStats( context.Background(), &csi.NodeGetVolumeStatsRequest{ VolumeId: sc.Config.IDGen.GenerateUniqueValidVolumeID(), @@ -731,7 +638,7 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { vol := createVolume(name) By("getting a node id") - nid, err := c.NodeGetInfo( + nid, err := r.NodeGetInfo( context.Background(), &csi.NodeGetInfoRequest{}) Expect(err).NotTo(HaveOccurred()) @@ -748,7 +655,7 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { // NodeGetVolumeStats By("Get node volume stats") - _, err = c.NodeGetVolumeStats( + _, err = r.NodeGetVolumeStats( context.Background(), &csi.NodeGetVolumeStatsRequest{ VolumeId: vol.GetVolume().GetVolumeId(), @@ -773,7 +680,7 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { }) It("should fail when no volume id is provided", func() { - _, err := c.NodeExpandVolume( + _, err := r.NodeExpandVolume( context.Background(), &csi.NodeExpandVolumeRequest{ VolumePath: sc.TargetPath, @@ -792,7 +699,7 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { vol := createVolume(name) - _, err := c.NodeExpandVolume( + _, err := r.NodeExpandVolume( context.Background(), &csi.NodeExpandVolumeRequest{ VolumeId: vol.GetVolume().VolumeId, @@ -807,7 +714,7 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { }) It("should fail when volume is not found", func() { - _, err := c.NodeExpandVolume( + _, err := r.NodeExpandVolume( context.Background(), &csi.NodeExpandVolumeRequest{ VolumeId: sc.Config.IDGen.GenerateUniqueValidVolumeID(), @@ -836,14 +743,14 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { }, Secrets: sc.Secrets.ControllerExpandVolumeSecret, } - rsp, err := s.ControllerExpandVolume(context.Background(), expReq) + rsp, err := r.ControllerExpandVolume(context.Background(), expReq) Expect(err).NotTo(HaveOccurred()) Expect(rsp).NotTo(BeNil()) Expect(rsp.GetCapacityBytes()).To(Equal(TestVolumeExpandSize(sc))) } By("getting a node id") - nid, err := c.NodeGetInfo( + nid, err := r.NodeGetInfo( context.Background(), &csi.NodeGetInfoRequest{}) Expect(err).NotTo(HaveOccurred()) @@ -859,7 +766,7 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { _ = nodePublishVolume(name, vol, conpubvol) By("expanding the volume on a node") - _, err = c.NodeExpandVolume( + _, err = r.NodeExpandVolume( context.Background(), &csi.NodeExpandVolumeRequest{ VolumeId: vol.GetVolume().GetVolumeId(), @@ -880,7 +787,7 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { Skip("Controller Service not provided: CreateVolume not supported") } By("runControllerTest") - runControllerTest(sc, c, s, cl, controllerPublishSupported, nodeStageSupported, nodeVolumeStatsSupported, 1) + runControllerTest(sc, r, controllerPublishSupported, nodeStageSupported, nodeVolumeStatsSupported, 1) }) It("should be idempotent", func() { if !providesControllerService { @@ -891,6 +798,6 @@ var _ = DescribeSanity("Node Service", func(sc *TestContext) { } count := sc.Config.IdempotentCount By("runControllerTest with Idempotent count") - runControllerTest(sc, c, s, cl, controllerPublishSupported, nodeStageSupported, nodeVolumeStatsSupported, count) + runControllerTest(sc, r, controllerPublishSupported, nodeStageSupported, nodeVolumeStatsSupported, count) }) }) diff --git a/pkg/sanity/resources.go b/pkg/sanity/resources.go new file mode 100644 index 00000000..12a72a5e --- /dev/null +++ b/pkg/sanity/resources.go @@ -0,0 +1,328 @@ +/* +Copyright 2018 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package sanity + +import ( + "context" + "sync" + + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + "github.com/container-storage-interface/spec/lib/go/csi" + + . "github.com/onsi/gomega" +) + +// VolumeInfo keeps track of the information needed to delete a volume. +type VolumeInfo struct { + // Node on which the volume was published, empty if none + // or publishing is not supported. + NodeID string + + // Volume ID assigned by CreateVolume. + VolumeID string +} + +// Resources keeps track of resources, in particular volumes and snapshots, that +// need to be freed when testing is done. It implements both ControllerClient +// and NodeClient and should be used as the only interaction point to either +// APIs. That way, Resources can ensure that resources are marked for cleanup as +// necessary. +// All methods can be called concurrently. +type Resources struct { + Context *TestContext + // ControllerClient is meant for struct-internal usage. It should only be + // invoked directly if automatic cleanup is not desired and cannot be + // avoided otherwise. + csi.ControllerClient + // NodeClient is meant for struct-internal usage. It should only be invoked + // directly if automatic cleanup is not desired and cannot be avoided + // otherwise. + csi.NodeClient + ControllerPublishSupported bool + NodeStageSupported bool + + // mutex protects access to the volumes and snapshots maps. + mutex sync.Mutex + // volumes maps from volume IDs to VolumeInfo structs and records if a given + // volume must be cleaned up. + volumes map[string]*VolumeInfo + // snapshots is keyed by snapshot IDs and records if a given snapshot must + // be cleaned up. + snapshots map[string]bool +} + +// ControllerClient interface wrappers + +// CreateVolume proxies to a Controller service implementation and registers the +// volume for cleanup. +func (cl *Resources) CreateVolume(ctx context.Context, in *csi.CreateVolumeRequest, _ ...grpc.CallOption) (*csi.CreateVolumeResponse, error) { + return cl.createVolume(ctx, 2, in) +} + +// DeleteVolume proxies to a Controller service implementation and unregisters +// the volume from cleanup. +func (cl *Resources) DeleteVolume(ctx context.Context, in *csi.DeleteVolumeRequest, _ ...grpc.CallOption) (*csi.DeleteVolumeResponse, error) { + return cl.deleteVolume(ctx, 2, in) +} + +// ControllerPublishVolume proxies to a Controller service implementation and +// adds the node ID to the corresponding volume for cleanup. +func (cl *Resources) ControllerPublishVolume(ctx context.Context, in *csi.ControllerPublishVolumeRequest, _ ...grpc.CallOption) (*csi.ControllerPublishVolumeResponse, error) { + return cl.controllerPublishVolume(ctx, 2, in) +} + +// CreateSnapshot proxies to a Controller service implementation and registers +// the snapshot for cleanup. +func (cl *Resources) CreateSnapshot(ctx context.Context, in *csi.CreateSnapshotRequest, _ ...grpc.CallOption) (*csi.CreateSnapshotResponse, error) { + return cl.createSnapshot(ctx, 2, in) +} + +// DeleteSnapshot proxies to a Controller service implementation and unregisters +// the snapshot from cleanup. +func (cl *Resources) DeleteSnapshot(ctx context.Context, in *csi.DeleteSnapshotRequest, _ ...grpc.CallOption) (*csi.DeleteSnapshotResponse, error) { + return cl.deleteSnapshot(ctx, 2, in) +} + +// MustCreateVolume is like CreateVolume but asserts that the volume was +// successfully created. +func (cl *Resources) MustCreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) *csi.CreateVolumeResponse { + return cl.mustCreateVolumeWithOffset(ctx, 2, req) +} + +func (cl *Resources) mustCreateVolumeWithOffset(ctx context.Context, offset int, req *csi.CreateVolumeRequest) *csi.CreateVolumeResponse { + vol, err := cl.createVolume(ctx, offset+1, req) + ExpectWithOffset(offset, err).NotTo(HaveOccurred(), "volume create failed") + ExpectWithOffset(offset, vol).NotTo(BeNil(), "volume response is nil") + ExpectWithOffset(offset, vol.GetVolume()).NotTo(BeNil(), "volume in response is nil") + ExpectWithOffset(offset, vol.GetVolume().GetVolumeId()).NotTo(BeEmpty(), "volume ID in response is missing") + return vol +} + +func (cl *Resources) createVolume(ctx context.Context, offset int, req *csi.CreateVolumeRequest) (*csi.CreateVolumeResponse, error) { + vol, err := cl.ControllerClient.CreateVolume(ctx, req) + if err == nil && vol != nil && vol.GetVolume().GetVolumeId() != "" { + cl.registerVolume(offset+1, VolumeInfo{VolumeID: vol.GetVolume().GetVolumeId()}) + } + return vol, err +} + +func (cl *Resources) deleteVolume(ctx context.Context, offset int, req *csi.DeleteVolumeRequest) (*csi.DeleteVolumeResponse, error) { + vol, err := cl.ControllerClient.DeleteVolume(ctx, req) + if err == nil { + cl.unregisterVolume(offset+1, req.VolumeId) + } + return vol, err +} + +// MustControllerPublishVolume is like ControllerPublishVolume but asserts that +// the volume was successfully controller-published. +func (cl *Resources) MustControllerPublishVolume(ctx context.Context, req *csi.ControllerPublishVolumeRequest) *csi.ControllerPublishVolumeResponse { + conpubvol, err := cl.controllerPublishVolume(ctx, 2, req) + ExpectWithOffset(1, err).NotTo(HaveOccurred(), "controller publish volume failed") + ExpectWithOffset(1, conpubvol).NotTo(BeNil(), "controller publish volume response is nil") + return conpubvol +} + +func (cl *Resources) controllerPublishVolume(ctx context.Context, offset int, req *csi.ControllerPublishVolumeRequest) (*csi.ControllerPublishVolumeResponse, error) { + conpubvol, err := cl.ControllerClient.ControllerPublishVolume(ctx, req) + if err == nil && req.VolumeId != "" && req.NodeId != "" { + cl.registerVolume(offset+1, VolumeInfo{VolumeID: req.VolumeId, NodeID: req.NodeId}) + } + return conpubvol, err +} + +// registerVolume adds or updates an entry for given volume. +func (cl *Resources) registerVolume(offset int, info VolumeInfo) { + ExpectWithOffset(offset, info).NotTo(BeNil(), "volume info is nil") + ExpectWithOffset(offset, info.VolumeID).NotTo(BeEmpty(), "volume ID in volume info is empty") + cl.mutex.Lock() + defer cl.mutex.Unlock() + if cl.volumes == nil { + cl.volumes = make(map[string]*VolumeInfo) + } + cl.volumes[info.VolumeID] = &info +} + +// unregisterVolume removes the entry for the volume with the +// given ID, thus preventing all cleanup operations for it. +func (cl *Resources) unregisterVolume(offset int, id string) { + cl.mutex.Lock() + defer cl.mutex.Unlock() + cl.unregisterVolumeNoLock(offset+1, id) +} + +func (cl *Resources) unregisterVolumeNoLock(offset int, id string) { + ExpectWithOffset(offset, id).NotTo(BeEmpty(), "ID for unregister volume is missing") + if cl.volumes != nil { + delete(cl.volumes, id) + } +} + +// MustCreateSnapshot is like CreateSnapshot but asserts that the snapshot was +// successfully created. +func (cl *Resources) MustCreateSnapshot(ctx context.Context, req *csi.CreateSnapshotRequest) *csi.CreateSnapshotResponse { + return cl.mustCreateSnapshotWithOffset(ctx, 2, req) +} + +func (cl *Resources) mustCreateSnapshotWithOffset(ctx context.Context, offset int, req *csi.CreateSnapshotRequest) *csi.CreateSnapshotResponse { + snap, err := cl.createSnapshot(ctx, offset+1, req) + ExpectWithOffset(offset, err).NotTo(HaveOccurred(), "create snapshot failed") + ExpectWithOffset(offset, snap).NotTo(BeNil(), "create snasphot response is nil") + verifySnapshotInfoWithOffset(offset+1, snap.GetSnapshot()) + return snap +} + +// MustCreateSnapshotFromVolumeRequest creates a volume from the given +// CreateVolumeRequest and a snapshot subsequently. It registers the volume and +// snapshot and asserts that both were created successfully. +func (cl *Resources) MustCreateSnapshotFromVolumeRequest(ctx context.Context, req *csi.CreateVolumeRequest, snapshotName string) (*csi.CreateSnapshotResponse, *csi.CreateVolumeResponse) { + vol := cl.mustCreateVolumeWithOffset(ctx, 2, req) + snap := cl.mustCreateSnapshotWithOffset(ctx, 2, MakeCreateSnapshotReq(cl.Context, snapshotName, vol.Volume.VolumeId)) + return snap, vol +} + +func (cl *Resources) createSnapshot(ctx context.Context, offset int, req *csi.CreateSnapshotRequest) (*csi.CreateSnapshotResponse, error) { + snap, err := cl.ControllerClient.CreateSnapshot(ctx, req) + if err == nil && snap.GetSnapshot().GetSnapshotId() != "" { + cl.registerSnapshot(offset+1, snap.Snapshot.SnapshotId) + } + return snap, err +} + +func (cl *Resources) deleteSnapshot(ctx context.Context, offset int, req *csi.DeleteSnapshotRequest) (*csi.DeleteSnapshotResponse, error) { + snap, err := cl.ControllerClient.DeleteSnapshot(ctx, req) + if err == nil && req.SnapshotId != "" { + cl.unregisterSnapshot(offset+1, req.SnapshotId) + } + return snap, err +} + +func (cl *Resources) registerSnapshot(offset int, id string) { + cl.mutex.Lock() + defer cl.mutex.Unlock() + cl.registerSnapshotNoLock(offset+1, id) +} + +func (cl *Resources) registerSnapshotNoLock(offset int, id string) { + ExpectWithOffset(offset, id).NotTo(BeEmpty(), "ID for register snapshot is missing") + if cl.snapshots == nil { + cl.snapshots = make(map[string]bool) + } + cl.snapshots[id] = true +} + +func (cl *Resources) unregisterSnapshot(offset int, id string) { + cl.mutex.Lock() + defer cl.mutex.Unlock() + cl.unregisterSnapshotNoLock(offset+1, id) +} + +func (cl *Resources) unregisterSnapshotNoLock(offset int, id string) { + ExpectWithOffset(offset, id).NotTo(BeEmpty(), "ID for unregister snapshot is missing") + if cl.snapshots != nil { + delete(cl.snapshots, id) + } +} + +// Cleanup calls unpublish methods as needed and deletes all volumes and +// snapshots. +func (cl *Resources) Cleanup() { + cl.mutex.Lock() + defer cl.mutex.Unlock() + ctx := context.Background() + + cl.deleteVolumes(ctx, 2) + cl.deleteSnapshots(ctx, 2) +} + +func (cl *Resources) deleteVolumes(ctx context.Context, offset int) { + logger := newLogger("cleanup volumes:") + defer logger.ExpectNoErrors(offset + 1) + + for volumeID, info := range cl.volumes { + logger.Infof("deleting %s", volumeID) + if cl.NodeClient != nil { + if _, err := cl.NodeUnpublishVolume( + ctx, + &csi.NodeUnpublishVolumeRequest{ + VolumeId: volumeID, + TargetPath: cl.Context.TargetPath + "/target", + }, + ); err != nil && status.Code(err) != codes.NotFound { + logger.Errorf(err, "NodeUnpublishVolume failed: %s", err) + } + + if cl.NodeStageSupported { + if _, err := cl.NodeUnstageVolume( + ctx, + &csi.NodeUnstageVolumeRequest{ + VolumeId: volumeID, + StagingTargetPath: cl.Context.StagingPath, + }, + ); err != nil && status.Code(err) != codes.NotFound { + logger.Errorf(err, "NodeUnstageVolume failed: %s", err) + } + } + } + + if cl.ControllerPublishSupported && info.NodeID != "" { + _, err := cl.ControllerClient.ControllerUnpublishVolume( + ctx, + &csi.ControllerUnpublishVolumeRequest{ + VolumeId: volumeID, + NodeId: info.NodeID, + Secrets: cl.Context.Secrets.ControllerUnpublishVolumeSecret, + }, + ) + logger.Errorf(err, "ControllerUnpublishVolume failed: %s", err) + } + + if _, err := cl.ControllerClient.DeleteVolume( + ctx, + &csi.DeleteVolumeRequest{ + VolumeId: volumeID, + Secrets: cl.Context.Secrets.DeleteVolumeSecret, + }, + ); err != nil && status.Code(err) != codes.NotFound { + logger.Errorf(err, "DeleteVolume failed: %s", err) + } + + cl.unregisterVolumeNoLock(offset+1, volumeID) + } +} + +func (cl *Resources) deleteSnapshots(ctx context.Context, offset int) { + logger := newLogger("cleanup snapshots:") + defer logger.ExpectNoErrors(offset + 1) + + for id := range cl.snapshots { + logger.Infof("deleting %s", id) + _, err := cl.ControllerClient.DeleteSnapshot( + ctx, + &csi.DeleteSnapshotRequest{ + SnapshotId: id, + Secrets: cl.Context.Secrets.DeleteSnapshotSecret, + }, + ) + logger.Errorf(err, "DeleteSnapshot failed: %s", err) + + cl.unregisterSnapshotNoLock(offset+1, id) + } +} diff --git a/pkg/sanity/sanity.go b/pkg/sanity/sanity.go index 06047e14..49d82d42 100644 --- a/pkg/sanity/sanity.go +++ b/pkg/sanity/sanity.go @@ -26,7 +26,7 @@ import ( "strings" "time" - "github.com/kubernetes-csi/csi-test/v3/utils" + "github.com/kubernetes-csi/csi-test/v4/utils" yaml "gopkg.in/yaml.v2" "google.golang.org/grpc" diff --git a/test/co_test.go b/test/co_test.go index 5c12b364..cbf63fbe 100644 --- a/test/co_test.go +++ b/test/co_test.go @@ -24,8 +24,8 @@ import ( "github.com/container-storage-interface/spec/lib/go/csi" "github.com/golang/mock/gomock" "github.com/golang/protobuf/proto" - mock_driver "github.com/kubernetes-csi/csi-test/v3/driver" - mock_utils "github.com/kubernetes-csi/csi-test/v3/utils" + mock_driver "github.com/kubernetes-csi/csi-test/v4/driver" + mock_utils "github.com/kubernetes-csi/csi-test/v4/utils" ) func TestPluginInfoResponse(t *testing.T) { diff --git a/test/driver_test.go b/test/driver_test.go index 2a0d23c1..8d35cdda 100644 --- a/test/driver_test.go +++ b/test/driver_test.go @@ -22,7 +22,7 @@ import ( "testing" "github.com/container-storage-interface/spec/lib/go/csi" - "github.com/kubernetes-csi/csi-test/v3/utils" + "github.com/kubernetes-csi/csi-test/v4/utils" "google.golang.org/grpc" "google.golang.org/grpc/reflection" ) diff --git a/v3/pkg/sanity/cleanup.go b/v3/pkg/sanity/cleanup.go deleted file mode 120000 index 6e6c0375..00000000 --- a/v3/pkg/sanity/cleanup.go +++ /dev/null @@ -1 +0,0 @@ -../../../pkg/sanity/cleanup.go \ No newline at end of file diff --git a/v3/README.md b/v4/README.md similarity index 100% rename from v3/README.md rename to v4/README.md diff --git a/v3/driver/driver-controller.go b/v4/driver/driver-controller.go similarity index 100% rename from v3/driver/driver-controller.go rename to v4/driver/driver-controller.go diff --git a/v3/driver/driver-node.go b/v4/driver/driver-node.go similarity index 100% rename from v3/driver/driver-node.go rename to v4/driver/driver-node.go diff --git a/v3/driver/driver.go b/v4/driver/driver.go similarity index 100% rename from v3/driver/driver.go rename to v4/driver/driver.go diff --git a/v3/driver/driver.mock.go b/v4/driver/driver.mock.go similarity index 100% rename from v3/driver/driver.mock.go rename to v4/driver/driver.mock.go diff --git a/v3/driver/mock.go b/v4/driver/mock.go similarity index 100% rename from v3/driver/mock.go rename to v4/driver/mock.go diff --git a/v3/mock/cache/SnapshotCache.go b/v4/mock/cache/SnapshotCache.go similarity index 100% rename from v3/mock/cache/SnapshotCache.go rename to v4/mock/cache/SnapshotCache.go diff --git a/v3/mock/service/controller.go b/v4/mock/service/controller.go similarity index 100% rename from v3/mock/service/controller.go rename to v4/mock/service/controller.go diff --git a/v3/mock/service/hooks-const.go b/v4/mock/service/hooks-const.go similarity index 100% rename from v3/mock/service/hooks-const.go rename to v4/mock/service/hooks-const.go diff --git a/v3/mock/service/identity.go b/v4/mock/service/identity.go similarity index 100% rename from v3/mock/service/identity.go rename to v4/mock/service/identity.go diff --git a/v3/mock/service/node.go b/v4/mock/service/node.go similarity index 100% rename from v3/mock/service/node.go rename to v4/mock/service/node.go diff --git a/v3/mock/service/service.go b/v4/mock/service/service.go similarity index 100% rename from v3/mock/service/service.go rename to v4/mock/service/service.go diff --git a/v3/pkg/sanity/controller.go b/v4/pkg/sanity/controller.go similarity index 100% rename from v3/pkg/sanity/controller.go rename to v4/pkg/sanity/controller.go diff --git a/v3/pkg/sanity/identity.go b/v4/pkg/sanity/identity.go similarity index 100% rename from v3/pkg/sanity/identity.go rename to v4/pkg/sanity/identity.go diff --git a/v4/pkg/sanity/logger.go b/v4/pkg/sanity/logger.go new file mode 120000 index 00000000..36a80fb4 --- /dev/null +++ b/v4/pkg/sanity/logger.go @@ -0,0 +1 @@ +../../../pkg/sanity/logger.go \ No newline at end of file diff --git a/v3/pkg/sanity/node.go b/v4/pkg/sanity/node.go similarity index 100% rename from v3/pkg/sanity/node.go rename to v4/pkg/sanity/node.go diff --git a/v4/pkg/sanity/resources.go b/v4/pkg/sanity/resources.go new file mode 120000 index 00000000..869fd453 --- /dev/null +++ b/v4/pkg/sanity/resources.go @@ -0,0 +1 @@ +../../../pkg/sanity/resources.go \ No newline at end of file diff --git a/v3/pkg/sanity/sanity.go b/v4/pkg/sanity/sanity.go similarity index 100% rename from v3/pkg/sanity/sanity.go rename to v4/pkg/sanity/sanity.go diff --git a/v3/pkg/sanity/tests.go b/v4/pkg/sanity/tests.go similarity index 100% rename from v3/pkg/sanity/tests.go rename to v4/pkg/sanity/tests.go diff --git a/v3/pkg/sanity/util.go b/v4/pkg/sanity/util.go similarity index 100% rename from v3/pkg/sanity/util.go rename to v4/pkg/sanity/util.go diff --git a/v3/utils/grpcutil.go b/v4/utils/grpcutil.go similarity index 100% rename from v3/utils/grpcutil.go rename to v4/utils/grpcutil.go diff --git a/v3/utils/safegoroutinetester.go b/v4/utils/safegoroutinetester.go similarity index 100% rename from v3/utils/safegoroutinetester.go rename to v4/utils/safegoroutinetester.go