storage e2e: simplify CSIStorageCapacity test

We can support topology detection for all drivers with a single
topology key by allowing different nodes to have the same topology
value. This makes the test a bit more generic and its configuration
simpler.
This commit is contained in:
Patrick Ohly 2021-03-24 22:31:43 +01:00
parent b9b5d13b6d
commit d7a086ddd8
2 changed files with 15 additions and 18 deletions

View File

@ -171,13 +171,6 @@ const (
// for dynamic provisioning exists, the driver is expected to provide // for dynamic provisioning exists, the driver is expected to provide
// capacity information for it. // capacity information for it.
CapCapacity Capability = "capacity" CapCapacity Capability = "capacity"
// The driver manages storage locally through CSI. TopologyKeys must be
// set and contain exactly one entry for distinguishing nodes.
// When the driver supports CapCapacity and the storage class
// for dynamic provisioning exists, the driver is expected to
// provider capacity information for it for each node.
CapCSILocalStorage Capability = "CSILocalStorage"
) )
// DriverInfo represents static information about a TestDriver. // DriverInfo represents static information about a TestDriver.

View File

@ -125,12 +125,17 @@ func (p *capacityTestSuite) DefineTests(driver storageframework.TestDriver, patt
// is that it provides some arbitrary capacity for the // is that it provides some arbitrary capacity for the
// storage class. // storage class.
matcher := matchSC matcher := matchSC
if dInfo.Capabilities[storageframework.CapCSILocalStorage] { if len(dInfo.TopologyKeys) == 1 {
// Local storage. We expect one CSIStorageCapacity object per // We can construct topology segments by
// node for the storage class. // collecting all values for this one key and
if len(dInfo.TopologyKeys) != 1 { // then expect one CSIStorageCapacity object
framework.Failf("need exactly one topology key for local storage, DriverInfo.TopologyKeys has: %v", dInfo.TopologyKeys) // per value for the storage class.
} //
// Local storage on a node will be covered by
// this checking. A more complex approach for
// drivers with multiple keys might be
// possible, too, but is not currently
// implemented.
matcher = HaveCapacitiesForClassAndNodes(f.ClientSet, sc.Provisioner, sc.Name, dInfo.TopologyKeys[0]) matcher = HaveCapacitiesForClassAndNodes(f.ClientSet, sc.Provisioner, sc.Name, dInfo.TopologyKeys[0])
} }
@ -259,7 +264,6 @@ type haveLocalStorageCapacities struct {
topologyKey string topologyKey string
matchSuccess bool matchSuccess bool
topologyValues []string
expectedCapacities []storagev1beta1.CSIStorageCapacity expectedCapacities []storagev1beta1.CSIStorageCapacity
unexpectedCapacities []storagev1beta1.CSIStorageCapacity unexpectedCapacities []storagev1beta1.CSIStorageCapacity
missingTopologyValues []string missingTopologyValues []string
@ -268,7 +272,6 @@ type haveLocalStorageCapacities struct {
var _ CapacityMatcher = &haveLocalStorageCapacities{} var _ CapacityMatcher = &haveLocalStorageCapacities{}
func (h *haveLocalStorageCapacities) Match(actual interface{}) (success bool, err error) { func (h *haveLocalStorageCapacities) Match(actual interface{}) (success bool, err error) {
h.topologyValues = nil
h.expectedCapacities = nil h.expectedCapacities = nil
h.unexpectedCapacities = nil h.unexpectedCapacities = nil
h.missingTopologyValues = nil h.missingTopologyValues = nil
@ -285,6 +288,7 @@ func (h *haveLocalStorageCapacities) Match(actual interface{}) (success bool, er
if err != nil { if err != nil {
return false, err return false, err
} }
topologyValues := map[string]bool{}
for _, csiNode := range csiNodes.Items { for _, csiNode := range csiNodes.Items {
for _, driver := range csiNode.Spec.Drivers { for _, driver := range csiNode.Spec.Drivers {
if driver.Name != h.driverName { if driver.Name != h.driverName {
@ -301,17 +305,17 @@ func (h *haveLocalStorageCapacities) Match(actual interface{}) (success bool, er
node.Name, node.Name,
h.topologyKey) h.topologyKey)
} }
h.topologyValues = append(h.topologyValues, value) topologyValues[value] = true
break break
} }
} }
if len(h.topologyValues) == 0 { if len(topologyValues) == 0 {
return false, fmt.Errorf("driver %q not running on any node", h.driverName) return false, fmt.Errorf("driver %q not running on any node", h.driverName)
} }
// Now check that for each topology value there is exactly one CSIStorageCapacity object. // Now check that for each topology value there is exactly one CSIStorageCapacity object.
remainingTopologyValues := map[string]bool{} remainingTopologyValues := map[string]bool{}
for _, value := range h.topologyValues { for value := range topologyValues {
remainingTopologyValues[value] = true remainingTopologyValues[value] = true
} }
capacities := h.match.MatchedCapacities() capacities := h.match.MatchedCapacities()