@@ -123,6 +123,13 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo
123123 AfterEach (func () {
124124 cl .DeleteVolumes ()
125125 })
126+ idempotentcount := sc .Config .IdempotentCount
127+ // Negative value for Idempotency repeat count means "skip idempotency testing"
128+ // We also do not want zero as that would skip as well, so in special cases we
129+ // reset the loop count to 1 to make this happen as regular testing.
130+ if idempotentcount < 1 {
131+ idempotentcount = 1
132+ }
126133
127134 Describe ("ControllerGetCapabilities" , func () {
128135 It ("should return appropriate capabilities" , func () {
@@ -1065,90 +1072,14 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo
10651072 Expect (serverError .Code ()).To (Equal (codes .InvalidArgument ))
10661073 })
10671074
1068- // CSI spec poses no specific requirements for the cluster/storage setups that a SP MUST support. To perform
1069- // meaningful checks the following test assumes that topology-aware provisioning on a single node setup is supported
10701075 It ("should return appropriate values (no optional values added)" , func () {
1076+ By ("lifecycle once" )
1077+ VolumeLifecycle (n , c , sc , cl , 1 )
1078+ })
10711079
1072- By ("getting node information" )
1073- ni , err := n .NodeGetInfo (
1074- context .Background (),
1075- & csi.NodeGetInfoRequest {})
1076- Expect (err ).NotTo (HaveOccurred ())
1077- Expect (ni ).NotTo (BeNil ())
1078- Expect (ni .GetNodeId ()).NotTo (BeEmpty ())
1079-
1080- var accReqs * csi.TopologyRequirement
1081- if ni .AccessibleTopology != nil {
1082- // Topology requirements are honored if provided by the driver
1083- accReqs = & csi.TopologyRequirement {
1084- Requisite : []* csi.Topology {ni .AccessibleTopology },
1085- }
1086- }
1087-
1088- // Create Volume First
1089- By ("creating a single node writer volume" )
1090- name := UniqueString ("sanity-controller-publish" )
1091-
1092- vol , err := c .CreateVolume (
1093- context .Background (),
1094- & csi.CreateVolumeRequest {
1095- Name : name ,
1096- VolumeCapabilities : []* csi.VolumeCapability {
1097- TestVolumeCapabilityWithAccessType (sc , csi .VolumeCapability_AccessMode_SINGLE_NODE_WRITER ),
1098- },
1099- Secrets : sc .Secrets .CreateVolumeSecret ,
1100- Parameters : sc .Config .TestVolumeParameters ,
1101- AccessibilityRequirements : accReqs ,
1102- },
1103- )
1104- Expect (err ).NotTo (HaveOccurred ())
1105- Expect (vol ).NotTo (BeNil ())
1106- Expect (vol .GetVolume ()).NotTo (BeNil ())
1107- Expect (vol .GetVolume ().GetVolumeId ()).NotTo (BeEmpty ())
1108- cl .RegisterVolume (name , VolumeInfo {VolumeID : vol .GetVolume ().GetVolumeId ()})
1109-
1110- // ControllerPublishVolume
1111- By ("calling controllerpublish on that volume" )
1112-
1113- conpubvol , err := c .ControllerPublishVolume (
1114- context .Background (),
1115- & csi.ControllerPublishVolumeRequest {
1116- VolumeId : vol .GetVolume ().GetVolumeId (),
1117- NodeId : ni .GetNodeId (),
1118- VolumeCapability : TestVolumeCapabilityWithAccessType (sc , csi .VolumeCapability_AccessMode_SINGLE_NODE_WRITER ),
1119- Readonly : false ,
1120- Secrets : sc .Secrets .ControllerPublishVolumeSecret ,
1121- },
1122- )
1123- Expect (err ).NotTo (HaveOccurred ())
1124- cl .RegisterVolume (name , VolumeInfo {VolumeID : vol .GetVolume ().GetVolumeId (), NodeID : ni .GetNodeId ()})
1125- Expect (conpubvol ).NotTo (BeNil ())
1126-
1127- By ("cleaning up unpublishing the volume" )
1128-
1129- conunpubvol , err := c .ControllerUnpublishVolume (
1130- context .Background (),
1131- & csi.ControllerUnpublishVolumeRequest {
1132- VolumeId : vol .GetVolume ().GetVolumeId (),
1133- // NodeID is optional in ControllerUnpublishVolume
1134- NodeId : ni .GetNodeId (),
1135- Secrets : sc .Secrets .ControllerUnpublishVolumeSecret ,
1136- },
1137- )
1138- Expect (err ).NotTo (HaveOccurred ())
1139- Expect (conunpubvol ).NotTo (BeNil ())
1140-
1141- By ("cleaning up deleting the volume" )
1142-
1143- _ , err = c .DeleteVolume (
1144- context .Background (),
1145- & csi.DeleteVolumeRequest {
1146- VolumeId : vol .GetVolume ().GetVolumeId (),
1147- Secrets : sc .Secrets .DeleteVolumeSecret ,
1148- },
1149- )
1150- Expect (err ).NotTo (HaveOccurred ())
1151- cl .UnregisterVolume (name )
1080+ It ("should return appropriate values (no optional values added), with idempotency" , func () {
1081+ By ("lifecycle repeated" )
1082+ VolumeLifecycle (n , c , sc , cl , idempotentcount )
11521083 })
11531084
11541085 It ("should fail when publishing more volumes than the node max attach limit" , func () {
@@ -2065,3 +1996,92 @@ func ControllerUnpublishAndDeleteVolume(sc *TestContext, c csi.ControllerClient,
20651996 Expect (err ).NotTo (HaveOccurred ())
20661997 return err
20671998}
1999+
2000+ // VolumeLifecycle performs Create-Publish-Unpublish-Delete, with optional repeat count to test idempotency.
2001+ func VolumeLifecycle (n csi.NodeClient , c csi.ControllerClient , sc * TestContext , cl * Cleanup , count int ) {
2002+ // CSI spec poses no specific requirements for the cluster/storage setups that a SP MUST support. To perform
2003+ // meaningful checks the following test assumes that topology-aware provisioning on a single node setup is supported
2004+ By ("getting node information" )
2005+ ni , err := n .NodeGetInfo (
2006+ context .Background (),
2007+ & csi.NodeGetInfoRequest {})
2008+ Expect (err ).NotTo (HaveOccurred ())
2009+ Expect (ni ).NotTo (BeNil ())
2010+ Expect (ni .GetNodeId ()).NotTo (BeEmpty ())
2011+
2012+ var accReqs * csi.TopologyRequirement
2013+ if ni .AccessibleTopology != nil {
2014+ // Topology requirements are honored if provided by the driver
2015+ accReqs = & csi.TopologyRequirement {
2016+ Requisite : []* csi.Topology {ni .AccessibleTopology },
2017+ }
2018+ }
2019+
2020+ // Create Volume First
2021+ By ("creating a single node writer volume" )
2022+ name := UniqueString ("sanity-controller-publish" )
2023+
2024+ vol , err := c .CreateVolume (
2025+ context .Background (),
2026+ & csi.CreateVolumeRequest {
2027+ Name : name ,
2028+ VolumeCapabilities : []* csi.VolumeCapability {
2029+ TestVolumeCapabilityWithAccessType (sc , csi .VolumeCapability_AccessMode_SINGLE_NODE_WRITER ),
2030+ },
2031+ Secrets : sc .Secrets .CreateVolumeSecret ,
2032+ Parameters : sc .Config .TestVolumeParameters ,
2033+ AccessibilityRequirements : accReqs ,
2034+ },
2035+ )
2036+ Expect (err ).NotTo (HaveOccurred ())
2037+ Expect (vol ).NotTo (BeNil ())
2038+ Expect (vol .GetVolume ()).NotTo (BeNil ())
2039+ Expect (vol .GetVolume ().GetVolumeId ()).NotTo (BeEmpty ())
2040+ cl .RegisterVolume (name , VolumeInfo {VolumeID : vol .GetVolume ().GetVolumeId ()})
2041+
2042+ // ControllerPublishVolume
2043+ for i := 0 ; i < count ; i ++ {
2044+ By ("calling controllerpublish on that volume" )
2045+ conpubvol , err := c .ControllerPublishVolume (
2046+ context .Background (),
2047+ & csi.ControllerPublishVolumeRequest {
2048+ VolumeId : vol .GetVolume ().GetVolumeId (),
2049+ NodeId : ni .GetNodeId (),
2050+ VolumeCapability : TestVolumeCapabilityWithAccessType (sc , csi .VolumeCapability_AccessMode_SINGLE_NODE_WRITER ),
2051+ Readonly : false ,
2052+ Secrets : sc .Secrets .ControllerPublishVolumeSecret ,
2053+ },
2054+ )
2055+ Expect (err ).NotTo (HaveOccurred ())
2056+ Expect (conpubvol ).NotTo (BeNil ())
2057+ }
2058+ cl .RegisterVolume (name , VolumeInfo {VolumeID : vol .GetVolume ().GetVolumeId (), NodeID : ni .GetNodeId ()})
2059+
2060+ for i := 0 ; i < count ; i ++ {
2061+ By ("cleaning up unpublishing the volume" )
2062+ conunpubvol , err := c .ControllerUnpublishVolume (
2063+ context .Background (),
2064+ & csi.ControllerUnpublishVolumeRequest {
2065+ VolumeId : vol .GetVolume ().GetVolumeId (),
2066+ // NodeID is optional in ControllerUnpublishVolume
2067+ NodeId : ni .GetNodeId (),
2068+ Secrets : sc .Secrets .ControllerUnpublishVolumeSecret ,
2069+ },
2070+ )
2071+ Expect (err ).NotTo (HaveOccurred ())
2072+ Expect (conunpubvol ).NotTo (BeNil ())
2073+ }
2074+
2075+ for i := 0 ; i < count ; i ++ {
2076+ By ("cleaning up deleting the volume" )
2077+ _ , err = c .DeleteVolume (
2078+ context .Background (),
2079+ & csi.DeleteVolumeRequest {
2080+ VolumeId : vol .GetVolume ().GetVolumeId (),
2081+ Secrets : sc .Secrets .DeleteVolumeSecret ,
2082+ },
2083+ )
2084+ Expect (err ).NotTo (HaveOccurred ())
2085+ }
2086+ cl .UnregisterVolume (name )
2087+ }
0 commit comments