Skip to content

Commit 151ee8c

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 151ee8c

File tree

1 file changed

+102
-82
lines changed

1 file changed

+102
-82
lines changed

pkg/sanity/controller.go

+102-82
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)