Skip to content

Commit d06296e

Browse files
committed
sanity/controller.go: Add idempotency loop for controller operations
Add idempotency-testing loops for controller operations. Move Create-Publish-Unpublish-Delete cycle into a function, which is called with argument specifying repetition count.
1 parent 8e1a754 commit d06296e

File tree

1 file changed

+100
-86
lines changed

1 file changed

+100
-86
lines changed

pkg/sanity/controller.go

+100-86
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo
123123
AfterEach(func() {
124124
cl.DeleteVolumes()
125125
})
126+
idempotentcount := sc.Config.IdempotentCount
126127

127128
Describe("ControllerGetCapabilities", func() {
128129
It("should return appropriate capabilities", func() {
@@ -1065,92 +1066,6 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo
10651066
Expect(serverError.Code()).To(Equal(codes.InvalidArgument))
10661067
})
10671068

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
1070-
It("should return appropriate values (no optional values added)", func() {
1071-
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)
1152-
})
1153-
11541069
It("should fail when publishing more volumes than the node max attach limit", func() {
11551070
if !sc.Config.TestNodeVolumeAttachLimit {
11561071
Skip("testnodevolumeattachlimit not enabled")
@@ -1360,6 +1275,16 @@ var _ = DescribeSanity("Controller Service [Controller Server]", func(sc *TestCo
13601275
})
13611276
})
13621277

1278+
Describe("ControllerVolumeLifecycle", func() {
1279+
It("should work", func() {
1280+
VolumeLifecycle(n, c, sc, cl, 1)
1281+
})
1282+
1283+
It("should be idempotent", func() {
1284+
VolumeLifecycle(n, c, sc, cl, idempotentcount)
1285+
})
1286+
})
1287+
13631288
Describe("ControllerUnpublishVolume", func() {
13641289
BeforeEach(func() {
13651290
if !isControllerCapabilitySupported(c, csi.ControllerServiceCapability_RPC_PUBLISH_UNPUBLISH_VOLUME) {
@@ -2065,3 +1990,92 @@ func ControllerUnpublishAndDeleteVolume(sc *TestContext, c csi.ControllerClient,
20651990
Expect(err).NotTo(HaveOccurred())
20661991
return err
20671992
}
1993+
1994+
// VolumeLifecycle performs Create-Publish-Unpublish-Delete, with optional repeat count to test idempotency.
1995+
func VolumeLifecycle(n csi.NodeClient, c csi.ControllerClient, sc *TestContext, cl *Cleanup, count int) {
1996+
// CSI spec poses no specific requirements for the cluster/storage setups that a SP MUST support. To perform
1997+
// meaningful checks the following test assumes that topology-aware provisioning on a single node setup is supported
1998+
By("getting node information")
1999+
ni, err := n.NodeGetInfo(
2000+
context.Background(),
2001+
&csi.NodeGetInfoRequest{})
2002+
Expect(err).NotTo(HaveOccurred())
2003+
Expect(ni).NotTo(BeNil())
2004+
Expect(ni.GetNodeId()).NotTo(BeEmpty())
2005+
2006+
var accReqs *csi.TopologyRequirement
2007+
if ni.AccessibleTopology != nil {
2008+
// Topology requirements are honored if provided by the driver
2009+
accReqs = &csi.TopologyRequirement{
2010+
Requisite: []*csi.Topology{ni.AccessibleTopology},
2011+
}
2012+
}
2013+
2014+
// Create Volume First
2015+
By("creating a single node writer volume")
2016+
name := UniqueString("sanity-controller-publish")
2017+
2018+
vol, err := c.CreateVolume(
2019+
context.Background(),
2020+
&csi.CreateVolumeRequest{
2021+
Name: name,
2022+
VolumeCapabilities: []*csi.VolumeCapability{
2023+
TestVolumeCapabilityWithAccessType(sc, csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER),
2024+
},
2025+
Secrets: sc.Secrets.CreateVolumeSecret,
2026+
Parameters: sc.Config.TestVolumeParameters,
2027+
AccessibilityRequirements: accReqs,
2028+
},
2029+
)
2030+
Expect(err).NotTo(HaveOccurred())
2031+
Expect(vol).NotTo(BeNil())
2032+
Expect(vol.GetVolume()).NotTo(BeNil())
2033+
Expect(vol.GetVolume().GetVolumeId()).NotTo(BeEmpty())
2034+
cl.RegisterVolume(name, VolumeInfo{VolumeID: vol.GetVolume().GetVolumeId()})
2035+
2036+
// ControllerPublishVolume
2037+
for i := 0; i < count; i++ {
2038+
By("calling controllerpublish on that volume")
2039+
conpubvol, err := c.ControllerPublishVolume(
2040+
context.Background(),
2041+
&csi.ControllerPublishVolumeRequest{
2042+
VolumeId: vol.GetVolume().GetVolumeId(),
2043+
NodeId: ni.GetNodeId(),
2044+
VolumeCapability: TestVolumeCapabilityWithAccessType(sc, csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER),
2045+
Readonly: false,
2046+
Secrets: sc.Secrets.ControllerPublishVolumeSecret,
2047+
},
2048+
)
2049+
Expect(err).NotTo(HaveOccurred())
2050+
Expect(conpubvol).NotTo(BeNil())
2051+
}
2052+
cl.RegisterVolume(name, VolumeInfo{VolumeID: vol.GetVolume().GetVolumeId(), NodeID: ni.GetNodeId()})
2053+
2054+
for i := 0; i < count; i++ {
2055+
By("cleaning up unpublishing the volume")
2056+
conunpubvol, err := c.ControllerUnpublishVolume(
2057+
context.Background(),
2058+
&csi.ControllerUnpublishVolumeRequest{
2059+
VolumeId: vol.GetVolume().GetVolumeId(),
2060+
// NodeID is optional in ControllerUnpublishVolume
2061+
NodeId: ni.GetNodeId(),
2062+
Secrets: sc.Secrets.ControllerUnpublishVolumeSecret,
2063+
},
2064+
)
2065+
Expect(err).NotTo(HaveOccurred())
2066+
Expect(conunpubvol).NotTo(BeNil())
2067+
}
2068+
2069+
for i := 0; i < count; i++ {
2070+
By("cleaning up deleting the volume")
2071+
_, err = c.DeleteVolume(
2072+
context.Background(),
2073+
&csi.DeleteVolumeRequest{
2074+
VolumeId: vol.GetVolume().GetVolumeId(),
2075+
Secrets: sc.Secrets.DeleteVolumeSecret,
2076+
},
2077+
)
2078+
Expect(err).NotTo(HaveOccurred())
2079+
}
2080+
cl.UnregisterVolume(name)
2081+
}

0 commit comments

Comments
 (0)