e2e storage: use framework to tag tests
This makes it possible to select tests through `ginkgo --label-filter` also for the custom labels.
This commit is contained in:
@@ -21,6 +21,7 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/onsi/ginkgo/v2"
|
"github.com/onsi/ginkgo/v2"
|
||||||
@@ -457,3 +458,22 @@ type label struct {
|
|||||||
func newLabel(parts ...string) label {
|
func newLabel(parts ...string) label {
|
||||||
return label{parts: parts}
|
return label{parts: parts}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TagsEqual can be used to check whether two tags are the same.
|
||||||
|
// It's safe to compare e.g. the result of WithSlow() against the result
|
||||||
|
// of WithSerial(), the result will be false. False is also returned
|
||||||
|
// when a parameter is some completely different value.
|
||||||
|
func TagsEqual(a, b interface{}) bool {
|
||||||
|
al, ok := a.(label)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
bl, ok := b.(label)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if al.extra != bl.extra {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return slices.Equal(al.parts, bl.parts)
|
||||||
|
}
|
||||||
|
|||||||
52
test/e2e/framework/ginkgowrapper_test.go
Normal file
52
test/e2e/framework/ginkgowrapper_test.go
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2023 The 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 framework
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/test/e2e/framework/internal/unittests/features"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTagsEqual(t *testing.T) {
|
||||||
|
testcases := []struct {
|
||||||
|
a, b interface{}
|
||||||
|
expectEqual bool
|
||||||
|
}{
|
||||||
|
{1, 2, false},
|
||||||
|
{2, 2, false},
|
||||||
|
{WithSlow(), 2, false},
|
||||||
|
{WithSlow(), WithSerial(), false},
|
||||||
|
{WithSerial(), WithSlow(), false},
|
||||||
|
{WithSlow(), WithSlow(), true},
|
||||||
|
{WithSerial(), WithSerial(), true},
|
||||||
|
{WithLabel("hello"), WithLabel("world"), false},
|
||||||
|
{WithLabel("hello"), WithLabel("hello"), true},
|
||||||
|
{WithFeatureGate(features.Test), WithLabel("Test"), false},
|
||||||
|
{WithFeatureGate(features.Test), WithFeatureGate(features.Test), true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testcases {
|
||||||
|
t.Run(fmt.Sprintf("%v=%v", tc.a, tc.b), func(t *testing.T) {
|
||||||
|
actualEqual := TagsEqual(tc.a, tc.b)
|
||||||
|
if actualEqual != tc.expectEqual {
|
||||||
|
t.Errorf("expected %v, got %v", tc.expectEqual, actualEqual)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2023 The 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 features
|
||||||
|
|
||||||
|
import (
|
||||||
|
"k8s.io/apimachinery/pkg/util/runtime"
|
||||||
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
|
"k8s.io/component-base/featuregate"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
Test featuregate.Feature = "Test"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
runtime.Must(utilfeature.DefaultMutableFeatureGate.Add(defaultKubernetesFeatureGates))
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{
|
||||||
|
Test: {Default: false, PreRelease: featuregate.Alpha},
|
||||||
|
}
|
||||||
@@ -17,12 +17,11 @@ limitations under the License.
|
|||||||
package storage
|
package storage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
"k8s.io/kubernetes/test/e2e/storage/drivers"
|
"k8s.io/kubernetes/test/e2e/storage/drivers"
|
||||||
storageframework "k8s.io/kubernetes/test/e2e/storage/framework"
|
storageframework "k8s.io/kubernetes/test/e2e/storage/framework"
|
||||||
"k8s.io/kubernetes/test/e2e/storage/testsuites"
|
"k8s.io/kubernetes/test/e2e/storage/testsuites"
|
||||||
"k8s.io/kubernetes/test/e2e/storage/utils"
|
"k8s.io/kubernetes/test/e2e/storage/utils"
|
||||||
|
|
||||||
"github.com/onsi/ginkgo/v2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// List of testDrivers to be executed in below loop
|
// List of testDrivers to be executed in below loop
|
||||||
@@ -37,8 +36,10 @@ var _ = utils.SIGDescribe("CSI Volumes", func() {
|
|||||||
for _, initDriver := range csiTestDrivers {
|
for _, initDriver := range csiTestDrivers {
|
||||||
curDriver := initDriver()
|
curDriver := initDriver()
|
||||||
|
|
||||||
ginkgo.Context(storageframework.GetDriverNameWithFeatureTags(curDriver), func() {
|
args := storageframework.GetDriverNameWithFeatureTags(curDriver)
|
||||||
|
args = append(args, func() {
|
||||||
storageframework.DefineTestSuites(curDriver, testsuites.CSISuites)
|
storageframework.DefineTestSuites(curDriver, testsuites.CSISuites)
|
||||||
})
|
})
|
||||||
|
framework.Context(args...)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
|
"k8s.io/kubernetes/test/e2e/feature"
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
e2enode "k8s.io/kubernetes/test/e2e/framework/node"
|
e2enode "k8s.io/kubernetes/test/e2e/framework/node"
|
||||||
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
|
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
|
||||||
@@ -96,7 +97,6 @@ func initHostPathCSIDriver(name string, capabilities map[storageframework.Capabi
|
|||||||
return &hostpathCSIDriver{
|
return &hostpathCSIDriver{
|
||||||
driverInfo: storageframework.DriverInfo{
|
driverInfo: storageframework.DriverInfo{
|
||||||
Name: name,
|
Name: name,
|
||||||
FeatureTag: "",
|
|
||||||
MaxFileSize: storageframework.FileSizeMedium,
|
MaxFileSize: storageframework.FileSizeMedium,
|
||||||
SupportedFsType: sets.NewString(
|
SupportedFsType: sets.NewString(
|
||||||
"", // Default fsType
|
"", // Default fsType
|
||||||
@@ -488,7 +488,6 @@ func InitMockCSIDriver(driverOpts CSIMockDriverOpts) MockCSITestDriver {
|
|||||||
return &mockCSIDriver{
|
return &mockCSIDriver{
|
||||||
driverInfo: storageframework.DriverInfo{
|
driverInfo: storageframework.DriverInfo{
|
||||||
Name: "csi-mock",
|
Name: "csi-mock",
|
||||||
FeatureTag: "",
|
|
||||||
MaxFileSize: storageframework.FileSizeMedium,
|
MaxFileSize: storageframework.FileSizeMedium,
|
||||||
SupportedFsType: sets.NewString(
|
SupportedFsType: sets.NewString(
|
||||||
"", // Default fsType
|
"", // Default fsType
|
||||||
@@ -796,7 +795,7 @@ func InitGcePDCSIDriver() storageframework.TestDriver {
|
|||||||
return &gcePDCSIDriver{
|
return &gcePDCSIDriver{
|
||||||
driverInfo: storageframework.DriverInfo{
|
driverInfo: storageframework.DriverInfo{
|
||||||
Name: GCEPDCSIDriverName,
|
Name: GCEPDCSIDriverName,
|
||||||
FeatureTag: "[Serial]",
|
TestTags: []interface{}{framework.WithSerial()},
|
||||||
MaxFileSize: storageframework.FileSizeMedium,
|
MaxFileSize: storageframework.FileSizeMedium,
|
||||||
SupportedSizeRange: e2evolume.SizeRange{
|
SupportedSizeRange: e2evolume.SizeRange{
|
||||||
Min: "5Gi",
|
Min: "5Gi",
|
||||||
@@ -855,9 +854,11 @@ func (g *gcePDCSIDriver) SkipUnsupportedTest(pattern storageframework.TestPatter
|
|||||||
if pattern.FsType == "xfs" {
|
if pattern.FsType == "xfs" {
|
||||||
e2eskipper.SkipUnlessNodeOSDistroIs("ubuntu", "custom")
|
e2eskipper.SkipUnlessNodeOSDistroIs("ubuntu", "custom")
|
||||||
}
|
}
|
||||||
if pattern.FeatureTag == "[Feature:Windows]" {
|
for _, tag := range pattern.TestTags {
|
||||||
|
if framework.TagsEqual(tag, feature.Windows) {
|
||||||
e2eskipper.Skipf("Skipping tests for windows since CSI does not support it yet")
|
e2eskipper.Skipf("Skipping tests for windows since CSI does not support it yet")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *gcePDCSIDriver) GetDynamicProvisionStorageClass(ctx context.Context, config *storageframework.PerTestConfig, fsType string) *storagev1.StorageClass {
|
func (g *gcePDCSIDriver) GetDynamicProvisionStorageClass(ctx context.Context, config *storageframework.PerTestConfig, fsType string) *storagev1.StorageClass {
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apiserver/pkg/authentication/serviceaccount"
|
"k8s.io/apiserver/pkg/authentication/serviceaccount"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
|
"k8s.io/kubernetes/test/e2e/feature"
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
e2eauth "k8s.io/kubernetes/test/e2e/framework/auth"
|
e2eauth "k8s.io/kubernetes/test/e2e/framework/auth"
|
||||||
e2enode "k8s.io/kubernetes/test/e2e/framework/node"
|
e2enode "k8s.io/kubernetes/test/e2e/framework/node"
|
||||||
@@ -240,7 +241,7 @@ func InitISCSIDriver() storageframework.TestDriver {
|
|||||||
driverInfo: storageframework.DriverInfo{
|
driverInfo: storageframework.DriverInfo{
|
||||||
Name: "iscsi",
|
Name: "iscsi",
|
||||||
InTreePluginName: "kubernetes.io/iscsi",
|
InTreePluginName: "kubernetes.io/iscsi",
|
||||||
FeatureTag: "[Feature:Volumes]",
|
TestTags: []interface{}{feature.Volumes},
|
||||||
MaxFileSize: storageframework.FileSizeMedium,
|
MaxFileSize: storageframework.FileSizeMedium,
|
||||||
SupportedFsType: sets.NewString(
|
SupportedFsType: sets.NewString(
|
||||||
"", // Default fsType
|
"", // Default fsType
|
||||||
@@ -423,7 +424,7 @@ func InitRbdDriver() storageframework.TestDriver {
|
|||||||
driverInfo: storageframework.DriverInfo{
|
driverInfo: storageframework.DriverInfo{
|
||||||
Name: "rbd",
|
Name: "rbd",
|
||||||
InTreePluginName: "kubernetes.io/rbd",
|
InTreePluginName: "kubernetes.io/rbd",
|
||||||
FeatureTag: "[Feature:Volumes][Serial]",
|
TestTags: []interface{}{feature.Volumes, framework.WithSerial()},
|
||||||
MaxFileSize: storageframework.FileSizeMedium,
|
MaxFileSize: storageframework.FileSizeMedium,
|
||||||
SupportedSizeRange: e2evolume.SizeRange{
|
SupportedSizeRange: e2evolume.SizeRange{
|
||||||
Min: "1Gi",
|
Min: "1Gi",
|
||||||
@@ -553,7 +554,7 @@ func InitCephFSDriver() storageframework.TestDriver {
|
|||||||
driverInfo: storageframework.DriverInfo{
|
driverInfo: storageframework.DriverInfo{
|
||||||
Name: "ceph",
|
Name: "ceph",
|
||||||
InTreePluginName: "kubernetes.io/cephfs",
|
InTreePluginName: "kubernetes.io/cephfs",
|
||||||
FeatureTag: "[Feature:Volumes][Serial]",
|
TestTags: []interface{}{feature.Volumes, framework.WithSerial()},
|
||||||
MaxFileSize: storageframework.FileSizeMedium,
|
MaxFileSize: storageframework.FileSizeMedium,
|
||||||
SupportedSizeRange: e2evolume.SizeRange{
|
SupportedSizeRange: e2evolume.SizeRange{
|
||||||
Min: "1Gi",
|
Min: "1Gi",
|
||||||
@@ -1083,9 +1084,11 @@ func (g *gcePdDriver) GetDriverInfo() *storageframework.DriverInfo {
|
|||||||
|
|
||||||
func (g *gcePdDriver) SkipUnsupportedTest(pattern storageframework.TestPattern) {
|
func (g *gcePdDriver) SkipUnsupportedTest(pattern storageframework.TestPattern) {
|
||||||
e2eskipper.SkipUnlessProviderIs("gce", "gke")
|
e2eskipper.SkipUnlessProviderIs("gce", "gke")
|
||||||
if pattern.FeatureTag == "[Feature:Windows]" {
|
for _, tag := range pattern.TestTags {
|
||||||
|
if tag == feature.Windows {
|
||||||
e2eskipper.SkipUnlessNodeOSDistroIs("windows")
|
e2eskipper.SkipUnlessNodeOSDistroIs("windows")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *gcePdDriver) GetVolumeSource(readOnly bool, fsType string, e2evolume storageframework.TestVolume) *v1.VolumeSource {
|
func (g *gcePdDriver) GetVolumeSource(readOnly bool, fsType string, e2evolume storageframework.TestVolume) *v1.VolumeSource {
|
||||||
@@ -1615,16 +1618,16 @@ func InitLocalDriverWithVolumeType(volumeType utils.LocalVolumeType) func() stor
|
|||||||
}
|
}
|
||||||
return func() storageframework.TestDriver {
|
return func() storageframework.TestDriver {
|
||||||
// custom tag to distinguish from tests of other volume types
|
// custom tag to distinguish from tests of other volume types
|
||||||
featureTag := fmt.Sprintf("[LocalVolumeType: %s]", volumeType)
|
testTags := []interface{}{fmt.Sprintf("[LocalVolumeType: %s]", volumeType)}
|
||||||
// For GCE Local SSD volumes, we must run serially
|
// For GCE Local SSD volumes, we must run serially
|
||||||
if volumeType == utils.LocalVolumeGCELocalSSD {
|
if volumeType == utils.LocalVolumeGCELocalSSD {
|
||||||
featureTag += " [Serial]"
|
testTags = append(testTags, framework.WithSerial())
|
||||||
}
|
}
|
||||||
return &localDriver{
|
return &localDriver{
|
||||||
driverInfo: storageframework.DriverInfo{
|
driverInfo: storageframework.DriverInfo{
|
||||||
Name: "local",
|
Name: "local",
|
||||||
InTreePluginName: "kubernetes.io/local-volume",
|
InTreePluginName: "kubernetes.io/local-volume",
|
||||||
FeatureTag: featureTag,
|
TestTags: testTags,
|
||||||
MaxFileSize: maxFileSize,
|
MaxFileSize: maxFileSize,
|
||||||
SupportedFsType: supportedFsTypes,
|
SupportedFsType: supportedFsTypes,
|
||||||
Capabilities: capabilities,
|
Capabilities: capabilities,
|
||||||
|
|||||||
7
test/e2e/storage/external/external.go
vendored
7
test/e2e/storage/external/external.go
vendored
@@ -41,7 +41,6 @@ import (
|
|||||||
"k8s.io/kubernetes/test/e2e/storage/testsuites"
|
"k8s.io/kubernetes/test/e2e/storage/testsuites"
|
||||||
"k8s.io/kubernetes/test/e2e/storage/utils"
|
"k8s.io/kubernetes/test/e2e/storage/utils"
|
||||||
|
|
||||||
"github.com/onsi/ginkgo/v2"
|
|
||||||
"github.com/onsi/gomega"
|
"github.com/onsi/gomega"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -170,10 +169,12 @@ func AddDriverDefinition(filename string) error {
|
|||||||
return fmt.Errorf("%q: DriverInfo.Name not set", filename)
|
return fmt.Errorf("%q: DriverInfo.Name not set", filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
description := "External Storage " + storageframework.GetDriverNameWithFeatureTags(driver)
|
args := []interface{}{"External Storage"}
|
||||||
ginkgo.Describe(description, func() {
|
args = append(args, storageframework.GetDriverNameWithFeatureTags(driver)...)
|
||||||
|
args = append(args, func() {
|
||||||
storageframework.DefineTestSuites(driver, testsuites.CSISuites)
|
storageframework.DefineTestSuites(driver, testsuites.CSISuites)
|
||||||
})
|
})
|
||||||
|
framework.Describe(args)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,14 +27,14 @@ import (
|
|||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetDriverNameWithFeatureTags returns driver name with feature tags
|
// GetDriverNameWithFeatureTags returns parameters that can be passed to framework.Context.
|
||||||
// For example)
|
// For example:
|
||||||
// - [Driver: nfs]
|
// - [Driver: nfs]
|
||||||
// - [Driver: rbd][Feature:Volumes]
|
// - [Driver: rbd], feature.Volumes
|
||||||
func GetDriverNameWithFeatureTags(driver TestDriver) string {
|
func GetDriverNameWithFeatureTags(driver TestDriver) []interface{} {
|
||||||
dInfo := driver.GetDriverInfo()
|
dInfo := driver.GetDriverInfo()
|
||||||
|
|
||||||
return fmt.Sprintf("[Driver: %s]%s", dInfo.Name, dInfo.FeatureTag)
|
return append([]interface{}{fmt.Sprintf("[Driver: %s]", dInfo.Name)}, dInfo.TestTags...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateVolume creates volume for test unless dynamicPV or CSI ephemeral inline volume test
|
// CreateVolume creates volume for test unless dynamicPV or CSI ephemeral inline volume test
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ type DriverInfo struct {
|
|||||||
// plugin if it exists and is empty if this DriverInfo represents a CSI
|
// plugin if it exists and is empty if this DriverInfo represents a CSI
|
||||||
// Driver
|
// Driver
|
||||||
InTreePluginName string
|
InTreePluginName string
|
||||||
FeatureTag string // FeatureTag for the driver
|
TestTags []interface{} // tags for the driver (e.g. framework.WithSlow())
|
||||||
|
|
||||||
// Maximum single file size supported by this driver
|
// Maximum single file size supported by this driver
|
||||||
MaxFileSize int64
|
MaxFileSize int64
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ package framework
|
|||||||
import (
|
import (
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
storagev1 "k8s.io/api/storage/v1"
|
storagev1 "k8s.io/api/storage/v1"
|
||||||
|
"k8s.io/kubernetes/test/e2e/feature"
|
||||||
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
e2evolume "k8s.io/kubernetes/test/e2e/framework/volume"
|
e2evolume "k8s.io/kubernetes/test/e2e/framework/volume"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -77,7 +79,7 @@ func (t TestSnapshotDeletionPolicy) String() string {
|
|||||||
// TestPattern represents a combination of parameters to be tested in a TestSuite
|
// TestPattern represents a combination of parameters to be tested in a TestSuite
|
||||||
type TestPattern struct {
|
type TestPattern struct {
|
||||||
Name string // Name of TestPattern
|
Name string // Name of TestPattern
|
||||||
FeatureTag string // featureTag for the TestSuite
|
TestTags []interface{} // additional parameters for framework.It, like framework.WithDisruptive()
|
||||||
VolType TestVolType // Volume type of the volume
|
VolType TestVolType // Volume type of the volume
|
||||||
FsType string // Fstype of the volume
|
FsType string // Fstype of the volume
|
||||||
VolMode v1.PersistentVolumeMode // PersistentVolumeMode of the volume
|
VolMode v1.PersistentVolumeMode // PersistentVolumeMode of the volume
|
||||||
@@ -194,35 +196,35 @@ var (
|
|||||||
Name: "Inline-volume (xfs)",
|
Name: "Inline-volume (xfs)",
|
||||||
VolType: InlineVolume,
|
VolType: InlineVolume,
|
||||||
FsType: "xfs",
|
FsType: "xfs",
|
||||||
FeatureTag: "[Slow]",
|
TestTags: []interface{}{framework.WithSlow()},
|
||||||
}
|
}
|
||||||
// XfsCSIEphemeralVolume is TestPattern for "CSI Ephemeral-volume (xfs)"
|
// XfsCSIEphemeralVolume is TestPattern for "CSI Ephemeral-volume (xfs)"
|
||||||
XfsCSIEphemeralVolume = TestPattern{
|
XfsCSIEphemeralVolume = TestPattern{
|
||||||
Name: "CSI Ephemeral-volume (xfs)",
|
Name: "CSI Ephemeral-volume (xfs)",
|
||||||
VolType: CSIInlineVolume,
|
VolType: CSIInlineVolume,
|
||||||
FsType: "xfs",
|
FsType: "xfs",
|
||||||
FeatureTag: "[Slow]",
|
TestTags: []interface{}{framework.WithSlow()},
|
||||||
}
|
}
|
||||||
// XfsGenericEphemeralVolume is TestPattern for "Generic Ephemeral-volume (xfs)"
|
// XfsGenericEphemeralVolume is TestPattern for "Generic Ephemeral-volume (xfs)"
|
||||||
XfsGenericEphemeralVolume = TestPattern{
|
XfsGenericEphemeralVolume = TestPattern{
|
||||||
Name: "Generic Ephemeral-volume (xfs)",
|
Name: "Generic Ephemeral-volume (xfs)",
|
||||||
VolType: GenericEphemeralVolume,
|
VolType: GenericEphemeralVolume,
|
||||||
FsType: "xfs",
|
FsType: "xfs",
|
||||||
FeatureTag: "[Slow]",
|
TestTags: []interface{}{framework.WithSlow()},
|
||||||
}
|
}
|
||||||
// XfsPreprovisionedPV is TestPattern for "Pre-provisioned PV (xfs)"
|
// XfsPreprovisionedPV is TestPattern for "Pre-provisioned PV (xfs)"
|
||||||
XfsPreprovisionedPV = TestPattern{
|
XfsPreprovisionedPV = TestPattern{
|
||||||
Name: "Pre-provisioned PV (xfs)",
|
Name: "Pre-provisioned PV (xfs)",
|
||||||
VolType: PreprovisionedPV,
|
VolType: PreprovisionedPV,
|
||||||
FsType: "xfs",
|
FsType: "xfs",
|
||||||
FeatureTag: "[Slow]",
|
TestTags: []interface{}{framework.WithSlow()},
|
||||||
}
|
}
|
||||||
// XfsDynamicPV is TestPattern for "Dynamic PV (xfs)"
|
// XfsDynamicPV is TestPattern for "Dynamic PV (xfs)"
|
||||||
XfsDynamicPV = TestPattern{
|
XfsDynamicPV = TestPattern{
|
||||||
Name: "Dynamic PV (xfs)",
|
Name: "Dynamic PV (xfs)",
|
||||||
VolType: DynamicPV,
|
VolType: DynamicPV,
|
||||||
FsType: "xfs",
|
FsType: "xfs",
|
||||||
FeatureTag: "[Slow]",
|
TestTags: []interface{}{framework.WithSlow()},
|
||||||
SnapshotType: DynamicCreatedSnapshot,
|
SnapshotType: DynamicCreatedSnapshot,
|
||||||
SnapshotDeletionPolicy: DeleteSnapshot,
|
SnapshotDeletionPolicy: DeleteSnapshot,
|
||||||
}
|
}
|
||||||
@@ -234,35 +236,35 @@ var (
|
|||||||
Name: "Inline-volume (ntfs)",
|
Name: "Inline-volume (ntfs)",
|
||||||
VolType: InlineVolume,
|
VolType: InlineVolume,
|
||||||
FsType: "ntfs",
|
FsType: "ntfs",
|
||||||
FeatureTag: "[Feature:Windows]",
|
TestTags: []interface{}{feature.Windows},
|
||||||
}
|
}
|
||||||
// NtfsCSIEphemeralVolume is TestPattern for "CSI Ephemeral-volume (ntfs)"
|
// NtfsCSIEphemeralVolume is TestPattern for "CSI Ephemeral-volume (ntfs)"
|
||||||
NtfsCSIEphemeralVolume = TestPattern{
|
NtfsCSIEphemeralVolume = TestPattern{
|
||||||
Name: "CSI Ephemeral-volume (ntfs) [alpha]",
|
Name: "CSI Ephemeral-volume (ntfs) [alpha]",
|
||||||
VolType: CSIInlineVolume,
|
VolType: CSIInlineVolume,
|
||||||
FsType: "ntfs",
|
FsType: "ntfs",
|
||||||
FeatureTag: "[Feature:Windows]",
|
TestTags: []interface{}{feature.Windows},
|
||||||
}
|
}
|
||||||
// NtfsGenericEphemeralVolume is TestPattern for "Generic Ephemeral-volume (ntfs)"
|
// NtfsGenericEphemeralVolume is TestPattern for "Generic Ephemeral-volume (ntfs)"
|
||||||
NtfsGenericEphemeralVolume = TestPattern{
|
NtfsGenericEphemeralVolume = TestPattern{
|
||||||
Name: "Generic Ephemeral-volume (ntfs)",
|
Name: "Generic Ephemeral-volume (ntfs)",
|
||||||
VolType: GenericEphemeralVolume,
|
VolType: GenericEphemeralVolume,
|
||||||
FsType: "ntfs",
|
FsType: "ntfs",
|
||||||
FeatureTag: "[Feature:Windows]",
|
TestTags: []interface{}{feature.Windows},
|
||||||
}
|
}
|
||||||
// NtfsPreprovisionedPV is TestPattern for "Pre-provisioned PV (ntfs)"
|
// NtfsPreprovisionedPV is TestPattern for "Pre-provisioned PV (ntfs)"
|
||||||
NtfsPreprovisionedPV = TestPattern{
|
NtfsPreprovisionedPV = TestPattern{
|
||||||
Name: "Pre-provisioned PV (ntfs)",
|
Name: "Pre-provisioned PV (ntfs)",
|
||||||
VolType: PreprovisionedPV,
|
VolType: PreprovisionedPV,
|
||||||
FsType: "ntfs",
|
FsType: "ntfs",
|
||||||
FeatureTag: "[Feature:Windows]",
|
TestTags: []interface{}{feature.Windows},
|
||||||
}
|
}
|
||||||
// NtfsDynamicPV is TestPattern for "Dynamic PV (ntfs)"
|
// NtfsDynamicPV is TestPattern for "Dynamic PV (ntfs)"
|
||||||
NtfsDynamicPV = TestPattern{
|
NtfsDynamicPV = TestPattern{
|
||||||
Name: "Dynamic PV (ntfs)",
|
Name: "Dynamic PV (ntfs)",
|
||||||
VolType: DynamicPV,
|
VolType: DynamicPV,
|
||||||
FsType: "ntfs",
|
FsType: "ntfs",
|
||||||
FeatureTag: "[Feature:Windows]",
|
TestTags: []interface{}{feature.Windows},
|
||||||
SnapshotDeletionPolicy: DeleteSnapshot,
|
SnapshotDeletionPolicy: DeleteSnapshot,
|
||||||
SnapshotType: DynamicCreatedSnapshot,
|
SnapshotType: DynamicCreatedSnapshot,
|
||||||
}
|
}
|
||||||
@@ -369,7 +371,7 @@ var (
|
|||||||
VolType: DynamicPV,
|
VolType: DynamicPV,
|
||||||
AllowExpansion: true,
|
AllowExpansion: true,
|
||||||
FsType: "ntfs",
|
FsType: "ntfs",
|
||||||
FeatureTag: "[Feature:Windows]",
|
TestTags: []interface{}{feature.Windows},
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlockVolModeDynamicPVAllowExpansion is TestPattern for "Dynamic PV (block volmode)(allowExpansion)"
|
// BlockVolModeDynamicPVAllowExpansion is TestPattern for "Dynamic PV (block volmode)(allowExpansion)"
|
||||||
|
|||||||
@@ -46,8 +46,12 @@ type TestSuite interface {
|
|||||||
// This function actually register tests inside testsuite
|
// This function actually register tests inside testsuite
|
||||||
func RegisterTests(suite TestSuite, driver TestDriver, pattern TestPattern) {
|
func RegisterTests(suite TestSuite, driver TestDriver, pattern TestPattern) {
|
||||||
tsInfo := suite.GetTestSuiteInfo()
|
tsInfo := suite.GetTestSuiteInfo()
|
||||||
testName := fmt.Sprintf("[Testpattern: %s]%s %s%s", pattern.Name, pattern.FeatureTag, tsInfo.Name, tsInfo.FeatureTag)
|
var args []interface{}
|
||||||
ginkgo.Context(testName, func() {
|
args = append(args, fmt.Sprintf("[Testpattern: %s]", pattern.Name))
|
||||||
|
args = append(args, pattern.TestTags...)
|
||||||
|
args = append(args, tsInfo.Name)
|
||||||
|
args = append(args, tsInfo.TestTags...)
|
||||||
|
args = append(args, func() {
|
||||||
ginkgo.BeforeEach(func() {
|
ginkgo.BeforeEach(func() {
|
||||||
// skip all the invalid combination of driver and pattern
|
// skip all the invalid combination of driver and pattern
|
||||||
SkipInvalidDriverPatternCombination(driver, pattern)
|
SkipInvalidDriverPatternCombination(driver, pattern)
|
||||||
@@ -60,6 +64,7 @@ func RegisterTests(suite TestSuite, driver TestDriver, pattern TestPattern) {
|
|||||||
// might still needed for specific independent test cases.
|
// might still needed for specific independent test cases.
|
||||||
suite.DefineTests(driver, pattern)
|
suite.DefineTests(driver, pattern)
|
||||||
})
|
})
|
||||||
|
framework.Context(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefineTestSuites defines tests for all testpatterns and all testSuites for a driver
|
// DefineTestSuites defines tests for all testpatterns and all testSuites for a driver
|
||||||
@@ -75,7 +80,7 @@ func DefineTestSuites(driver TestDriver, tsInits []func() TestSuite) {
|
|||||||
// TestSuiteInfo represents a set of parameters for TestSuite
|
// TestSuiteInfo represents a set of parameters for TestSuite
|
||||||
type TestSuiteInfo struct {
|
type TestSuiteInfo struct {
|
||||||
Name string // name of the TestSuite
|
Name string // name of the TestSuite
|
||||||
FeatureTag string // featureTag for the TestSuite
|
TestTags []interface{} // additional parameters for framework.It, like framework.WithDisruptive()
|
||||||
TestPatterns []TestPattern // Slice of TestPattern for the TestSuite
|
TestPatterns []TestPattern // Slice of TestPattern for the TestSuite
|
||||||
SupportedSizeRange e2evolume.SizeRange // Size range supported by the test suite
|
SupportedSizeRange e2evolume.SizeRange // Size range supported by the test suite
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package storage
|
|||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/onsi/ginkgo/v2"
|
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
"k8s.io/kubernetes/test/e2e/storage/drivers"
|
"k8s.io/kubernetes/test/e2e/storage/drivers"
|
||||||
storageframework "k8s.io/kubernetes/test/e2e/storage/framework"
|
storageframework "k8s.io/kubernetes/test/e2e/storage/framework"
|
||||||
@@ -80,8 +79,8 @@ var _ = utils.SIGDescribe("In-tree Volumes", func() {
|
|||||||
for _, initDriver := range testDrivers {
|
for _, initDriver := range testDrivers {
|
||||||
curDriver := initDriver()
|
curDriver := initDriver()
|
||||||
|
|
||||||
ginkgo.Context(storageframework.GetDriverNameWithFeatureTags(curDriver), func() {
|
framework.Context(append(storageframework.GetDriverNameWithFeatureTags(curDriver), func() {
|
||||||
storageframework.DefineTestSuites(curDriver, testsuites.BaseSuites)
|
storageframework.DefineTestSuites(curDriver, testsuites.BaseSuites)
|
||||||
})
|
})...)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ func InitCustomDisruptiveTestSuite(patterns []storageframework.TestPattern) stor
|
|||||||
return &disruptiveTestSuite{
|
return &disruptiveTestSuite{
|
||||||
tsInfo: storageframework.TestSuiteInfo{
|
tsInfo: storageframework.TestSuiteInfo{
|
||||||
Name: "disruptive",
|
Name: "disruptive",
|
||||||
FeatureTag: "[Disruptive][LinuxOnly]",
|
TestTags: []interface{}{framework.WithDisruptive(), framework.WithLabel("LinuxOnly")},
|
||||||
TestPatterns: patterns,
|
TestPatterns: patterns,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package testsuites
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"reflect"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/onsi/ginkgo/v2"
|
"github.com/onsi/ginkgo/v2"
|
||||||
@@ -26,6 +27,7 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/errors"
|
"k8s.io/apimachinery/pkg/util/errors"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
|
"k8s.io/kubernetes/test/e2e/feature"
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
e2enode "k8s.io/kubernetes/test/e2e/framework/node"
|
e2enode "k8s.io/kubernetes/test/e2e/framework/node"
|
||||||
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
|
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
|
||||||
@@ -316,7 +318,7 @@ func (t *multiVolumeTestSuite) DefineTests(driver storageframework.TestDriver, p
|
|||||||
// [ node1 ]
|
// [ node1 ]
|
||||||
// | | <- same volume mode
|
// | | <- same volume mode
|
||||||
// [volume1] -> [restored volume1 snapshot]
|
// [volume1] -> [restored volume1 snapshot]
|
||||||
ginkgo.It("should concurrently access the volume and restored snapshot from pods on the same node [LinuxOnly][Feature:VolumeSnapshotDataSource][Feature:VolumeSourceXFS]", func(ctx context.Context) {
|
f.It("should concurrently access the volume and restored snapshot from pods on the same node [LinuxOnly]", feature.VolumeSnapshotDataSource, feature.VolumeSourceXFS, func(ctx context.Context) {
|
||||||
init(ctx)
|
init(ctx)
|
||||||
ginkgo.DeferCleanup(cleanup)
|
ginkgo.DeferCleanup(cleanup)
|
||||||
|
|
||||||
@@ -420,7 +422,7 @@ func (t *multiVolumeTestSuite) DefineTests(driver storageframework.TestDriver, p
|
|||||||
e2eskipper.Skipf("Driver %q does not support multiple concurrent pods - skipping", dInfo.Name)
|
e2eskipper.Skipf("Driver %q does not support multiple concurrent pods - skipping", dInfo.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if l.driver.GetDriverInfo().Name == "vsphere" && pattern == storageframework.BlockVolModeDynamicPV {
|
if l.driver.GetDriverInfo().Name == "vsphere" && reflect.DeepEqual(pattern, storageframework.BlockVolModeDynamicPV) {
|
||||||
e2eskipper.Skipf("Driver %q does not support read only raw block volumes - skipping", dInfo.Name)
|
e2eskipper.Skipf("Driver %q does not support read only raw block volumes - skipping", dInfo.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ func InitCustomReadWriteOncePodTestSuite(patterns []storageframework.TestPattern
|
|||||||
tsInfo: storageframework.TestSuiteInfo{
|
tsInfo: storageframework.TestSuiteInfo{
|
||||||
Name: "read-write-once-pod",
|
Name: "read-write-once-pod",
|
||||||
TestPatterns: patterns,
|
TestPatterns: patterns,
|
||||||
FeatureTag: "[MinimumKubeletVersion:1.27]",
|
TestTags: []interface{}{framework.WithLabel("MinimumKubeletVersion:1.27")},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import (
|
|||||||
"k8s.io/client-go/dynamic"
|
"k8s.io/client-go/dynamic"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
"k8s.io/component-helpers/storage/ephemeral"
|
"k8s.io/component-helpers/storage/ephemeral"
|
||||||
|
"k8s.io/kubernetes/test/e2e/feature"
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
|
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
|
||||||
e2eoutput "k8s.io/kubernetes/test/e2e/framework/pod/output"
|
e2eoutput "k8s.io/kubernetes/test/e2e/framework/pod/output"
|
||||||
@@ -66,7 +67,7 @@ func InitCustomSnapshottableTestSuite(patterns []storageframework.TestPattern) s
|
|||||||
SupportedSizeRange: e2evolume.SizeRange{
|
SupportedSizeRange: e2evolume.SizeRange{
|
||||||
Min: "1Mi",
|
Min: "1Mi",
|
||||||
},
|
},
|
||||||
FeatureTag: "[Feature:VolumeSnapshotDataSource]",
|
TestTags: []interface{}{feature.VolumeSnapshotDataSource},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
errors "k8s.io/apimachinery/pkg/util/errors"
|
errors "k8s.io/apimachinery/pkg/util/errors"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
|
"k8s.io/kubernetes/test/e2e/feature"
|
||||||
"k8s.io/kubernetes/test/e2e/framework"
|
"k8s.io/kubernetes/test/e2e/framework"
|
||||||
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
|
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
|
||||||
e2epv "k8s.io/kubernetes/test/e2e/framework/pv"
|
e2epv "k8s.io/kubernetes/test/e2e/framework/pv"
|
||||||
@@ -67,7 +68,7 @@ func InitCustomSnapshottableStressTestSuite(patterns []storageframework.TestPatt
|
|||||||
SupportedSizeRange: e2evolume.SizeRange{
|
SupportedSizeRange: e2evolume.SizeRange{
|
||||||
Min: "1Mi",
|
Min: "1Mi",
|
||||||
},
|
},
|
||||||
FeatureTag: "[Feature:VolumeSnapshotDataSource]",
|
TestTags: []interface{}{feature.VolumeSnapshotDataSource},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user