Merge pull request #121391 from pohly/e2e-storage-test-labels

e2e storage: test labels
This commit is contained in:
Kubernetes Prow Robot 2023-10-24 10:12:40 +02:00 committed by GitHub
commit 9ae55e9886
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 200 additions and 77 deletions

View File

@ -21,6 +21,7 @@ import (
"path"
"reflect"
"regexp"
"slices"
"strings"
"github.com/onsi/ginkgo/v2"
@ -457,3 +458,22 @@ type label struct {
func newLabel(parts ...string) label {
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)
}

View 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)
}
})
}
}

View File

@ -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},
}

View File

@ -17,12 +17,11 @@ limitations under the License.
package storage
import (
"k8s.io/kubernetes/test/e2e/framework"
"k8s.io/kubernetes/test/e2e/storage/drivers"
storageframework "k8s.io/kubernetes/test/e2e/storage/framework"
"k8s.io/kubernetes/test/e2e/storage/testsuites"
"k8s.io/kubernetes/test/e2e/storage/utils"
"github.com/onsi/ginkgo/v2"
)
// List of testDrivers to be executed in below loop
@ -37,8 +36,10 @@ var _ = utils.SIGDescribe("CSI Volumes", func() {
for _, initDriver := range csiTestDrivers {
curDriver := initDriver()
ginkgo.Context(storageframework.GetDriverNameWithFeatureTags(curDriver), func() {
args := storageframework.GetDriverNameWithFeatureTags(curDriver)
args = append(args, func() {
storageframework.DefineTestSuites(curDriver, testsuites.CSISuites)
})
framework.Context(args...)
}
})

View File

@ -61,6 +61,7 @@ import (
"k8s.io/apimachinery/pkg/util/wait"
clientset "k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"
"k8s.io/kubernetes/test/e2e/feature"
"k8s.io/kubernetes/test/e2e/framework"
e2enode "k8s.io/kubernetes/test/e2e/framework/node"
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
@ -96,7 +97,6 @@ func initHostPathCSIDriver(name string, capabilities map[storageframework.Capabi
return &hostpathCSIDriver{
driverInfo: storageframework.DriverInfo{
Name: name,
FeatureTag: "",
MaxFileSize: storageframework.FileSizeMedium,
SupportedFsType: sets.NewString(
"", // Default fsType
@ -488,7 +488,6 @@ func InitMockCSIDriver(driverOpts CSIMockDriverOpts) MockCSITestDriver {
return &mockCSIDriver{
driverInfo: storageframework.DriverInfo{
Name: "csi-mock",
FeatureTag: "",
MaxFileSize: storageframework.FileSizeMedium,
SupportedFsType: sets.NewString(
"", // Default fsType
@ -796,7 +795,7 @@ func InitGcePDCSIDriver() storageframework.TestDriver {
return &gcePDCSIDriver{
driverInfo: storageframework.DriverInfo{
Name: GCEPDCSIDriverName,
FeatureTag: "[Serial]",
TestTags: []interface{}{framework.WithSerial()},
MaxFileSize: storageframework.FileSizeMedium,
SupportedSizeRange: e2evolume.SizeRange{
Min: "5Gi",
@ -855,8 +854,10 @@ func (g *gcePDCSIDriver) SkipUnsupportedTest(pattern storageframework.TestPatter
if pattern.FsType == "xfs" {
e2eskipper.SkipUnlessNodeOSDistroIs("ubuntu", "custom")
}
if pattern.FeatureTag == "[Feature:Windows]" {
e2eskipper.Skipf("Skipping tests for windows since CSI does not support it yet")
for _, tag := range pattern.TestTags {
if framework.TagsEqual(tag, feature.Windows) {
e2eskipper.Skipf("Skipping tests for windows since CSI does not support it yet")
}
}
}

View File

@ -51,6 +51,7 @@ import (
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/authentication/serviceaccount"
clientset "k8s.io/client-go/kubernetes"
"k8s.io/kubernetes/test/e2e/feature"
"k8s.io/kubernetes/test/e2e/framework"
e2eauth "k8s.io/kubernetes/test/e2e/framework/auth"
e2enode "k8s.io/kubernetes/test/e2e/framework/node"
@ -240,7 +241,7 @@ func InitISCSIDriver() storageframework.TestDriver {
driverInfo: storageframework.DriverInfo{
Name: "iscsi",
InTreePluginName: "kubernetes.io/iscsi",
FeatureTag: "[Feature:Volumes]",
TestTags: []interface{}{feature.Volumes},
MaxFileSize: storageframework.FileSizeMedium,
SupportedFsType: sets.NewString(
"", // Default fsType
@ -423,7 +424,7 @@ func InitRbdDriver() storageframework.TestDriver {
driverInfo: storageframework.DriverInfo{
Name: "rbd",
InTreePluginName: "kubernetes.io/rbd",
FeatureTag: "[Feature:Volumes][Serial]",
TestTags: []interface{}{feature.Volumes, framework.WithSerial()},
MaxFileSize: storageframework.FileSizeMedium,
SupportedSizeRange: e2evolume.SizeRange{
Min: "1Gi",
@ -553,7 +554,7 @@ func InitCephFSDriver() storageframework.TestDriver {
driverInfo: storageframework.DriverInfo{
Name: "ceph",
InTreePluginName: "kubernetes.io/cephfs",
FeatureTag: "[Feature:Volumes][Serial]",
TestTags: []interface{}{feature.Volumes, framework.WithSerial()},
MaxFileSize: storageframework.FileSizeMedium,
SupportedSizeRange: e2evolume.SizeRange{
Min: "1Gi",
@ -1083,8 +1084,10 @@ func (g *gcePdDriver) GetDriverInfo() *storageframework.DriverInfo {
func (g *gcePdDriver) SkipUnsupportedTest(pattern storageframework.TestPattern) {
e2eskipper.SkipUnlessProviderIs("gce", "gke")
if pattern.FeatureTag == "[Feature:Windows]" {
e2eskipper.SkipUnlessNodeOSDistroIs("windows")
for _, tag := range pattern.TestTags {
if tag == feature.Windows {
e2eskipper.SkipUnlessNodeOSDistroIs("windows")
}
}
}
@ -1615,16 +1618,16 @@ func InitLocalDriverWithVolumeType(volumeType utils.LocalVolumeType) func() stor
}
return func() storageframework.TestDriver {
// 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
if volumeType == utils.LocalVolumeGCELocalSSD {
featureTag += " [Serial]"
testTags = append(testTags, framework.WithSerial())
}
return &localDriver{
driverInfo: storageframework.DriverInfo{
Name: "local",
InTreePluginName: "kubernetes.io/local-volume",
FeatureTag: featureTag,
TestTags: testTags,
MaxFileSize: maxFileSize,
SupportedFsType: supportedFsTypes,
Capabilities: capabilities,

View File

@ -41,7 +41,6 @@ import (
"k8s.io/kubernetes/test/e2e/storage/testsuites"
"k8s.io/kubernetes/test/e2e/storage/utils"
"github.com/onsi/ginkgo/v2"
"github.com/onsi/gomega"
)
@ -170,10 +169,12 @@ func AddDriverDefinition(filename string) error {
return fmt.Errorf("%q: DriverInfo.Name not set", filename)
}
description := "External Storage " + storageframework.GetDriverNameWithFeatureTags(driver)
ginkgo.Describe(description, func() {
args := []interface{}{"External Storage"}
args = append(args, storageframework.GetDriverNameWithFeatureTags(driver)...)
args = append(args, func() {
storageframework.DefineTestSuites(driver, testsuites.CSISuites)
})
framework.Describe(args)
return nil
}

View File

@ -27,14 +27,14 @@ import (
"k8s.io/kubernetes/test/e2e/framework"
)
// GetDriverNameWithFeatureTags returns driver name with feature tags
// For example)
// GetDriverNameWithFeatureTags returns parameters that can be passed to framework.Context.
// For example:
// - [Driver: nfs]
// - [Driver: rbd][Feature:Volumes]
func GetDriverNameWithFeatureTags(driver TestDriver) string {
// - [Driver: rbd], feature.Volumes
func GetDriverNameWithFeatureTags(driver TestDriver) []interface{} {
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

View File

@ -219,7 +219,7 @@ type DriverInfo struct {
// plugin if it exists and is empty if this DriverInfo represents a CSI
// Driver
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
MaxFileSize int64

View File

@ -19,6 +19,8 @@ package framework
import (
v1 "k8s.io/api/core/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"
)
@ -77,7 +79,7 @@ func (t TestSnapshotDeletionPolicy) String() string {
// TestPattern represents a combination of parameters to be tested in a TestSuite
type TestPattern struct {
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
FsType string // Fstype of the volume
VolMode v1.PersistentVolumeMode // PersistentVolumeMode of the volume
@ -191,38 +193,38 @@ var (
// XfsInlineVolume is TestPattern for "Inline-volume (xfs)"
XfsInlineVolume = TestPattern{
Name: "Inline-volume (xfs)",
VolType: InlineVolume,
FsType: "xfs",
FeatureTag: "[Slow]",
Name: "Inline-volume (xfs)",
VolType: InlineVolume,
FsType: "xfs",
TestTags: []interface{}{framework.WithSlow()},
}
// XfsCSIEphemeralVolume is TestPattern for "CSI Ephemeral-volume (xfs)"
XfsCSIEphemeralVolume = TestPattern{
Name: "CSI Ephemeral-volume (xfs)",
VolType: CSIInlineVolume,
FsType: "xfs",
FeatureTag: "[Slow]",
Name: "CSI Ephemeral-volume (xfs)",
VolType: CSIInlineVolume,
FsType: "xfs",
TestTags: []interface{}{framework.WithSlow()},
}
// XfsGenericEphemeralVolume is TestPattern for "Generic Ephemeral-volume (xfs)"
XfsGenericEphemeralVolume = TestPattern{
Name: "Generic Ephemeral-volume (xfs)",
VolType: GenericEphemeralVolume,
FsType: "xfs",
FeatureTag: "[Slow]",
Name: "Generic Ephemeral-volume (xfs)",
VolType: GenericEphemeralVolume,
FsType: "xfs",
TestTags: []interface{}{framework.WithSlow()},
}
// XfsPreprovisionedPV is TestPattern for "Pre-provisioned PV (xfs)"
XfsPreprovisionedPV = TestPattern{
Name: "Pre-provisioned PV (xfs)",
VolType: PreprovisionedPV,
FsType: "xfs",
FeatureTag: "[Slow]",
Name: "Pre-provisioned PV (xfs)",
VolType: PreprovisionedPV,
FsType: "xfs",
TestTags: []interface{}{framework.WithSlow()},
}
// XfsDynamicPV is TestPattern for "Dynamic PV (xfs)"
XfsDynamicPV = TestPattern{
Name: "Dynamic PV (xfs)",
VolType: DynamicPV,
FsType: "xfs",
FeatureTag: "[Slow]",
TestTags: []interface{}{framework.WithSlow()},
SnapshotType: DynamicCreatedSnapshot,
SnapshotDeletionPolicy: DeleteSnapshot,
}
@ -231,38 +233,38 @@ var (
// NtfsInlineVolume is TestPattern for "Inline-volume (ntfs)"
NtfsInlineVolume = TestPattern{
Name: "Inline-volume (ntfs)",
VolType: InlineVolume,
FsType: "ntfs",
FeatureTag: "[Feature:Windows]",
Name: "Inline-volume (ntfs)",
VolType: InlineVolume,
FsType: "ntfs",
TestTags: []interface{}{feature.Windows},
}
// NtfsCSIEphemeralVolume is TestPattern for "CSI Ephemeral-volume (ntfs)"
NtfsCSIEphemeralVolume = TestPattern{
Name: "CSI Ephemeral-volume (ntfs) [alpha]",
VolType: CSIInlineVolume,
FsType: "ntfs",
FeatureTag: "[Feature:Windows]",
Name: "CSI Ephemeral-volume (ntfs) [alpha]",
VolType: CSIInlineVolume,
FsType: "ntfs",
TestTags: []interface{}{feature.Windows},
}
// NtfsGenericEphemeralVolume is TestPattern for "Generic Ephemeral-volume (ntfs)"
NtfsGenericEphemeralVolume = TestPattern{
Name: "Generic Ephemeral-volume (ntfs)",
VolType: GenericEphemeralVolume,
FsType: "ntfs",
FeatureTag: "[Feature:Windows]",
Name: "Generic Ephemeral-volume (ntfs)",
VolType: GenericEphemeralVolume,
FsType: "ntfs",
TestTags: []interface{}{feature.Windows},
}
// NtfsPreprovisionedPV is TestPattern for "Pre-provisioned PV (ntfs)"
NtfsPreprovisionedPV = TestPattern{
Name: "Pre-provisioned PV (ntfs)",
VolType: PreprovisionedPV,
FsType: "ntfs",
FeatureTag: "[Feature:Windows]",
Name: "Pre-provisioned PV (ntfs)",
VolType: PreprovisionedPV,
FsType: "ntfs",
TestTags: []interface{}{feature.Windows},
}
// NtfsDynamicPV is TestPattern for "Dynamic PV (ntfs)"
NtfsDynamicPV = TestPattern{
Name: "Dynamic PV (ntfs)",
VolType: DynamicPV,
FsType: "ntfs",
FeatureTag: "[Feature:Windows]",
TestTags: []interface{}{feature.Windows},
SnapshotDeletionPolicy: DeleteSnapshot,
SnapshotType: DynamicCreatedSnapshot,
}
@ -369,7 +371,7 @@ var (
VolType: DynamicPV,
AllowExpansion: true,
FsType: "ntfs",
FeatureTag: "[Feature:Windows]",
TestTags: []interface{}{feature.Windows},
}
// BlockVolModeDynamicPVAllowExpansion is TestPattern for "Dynamic PV (block volmode)(allowExpansion)"

View File

@ -46,8 +46,12 @@ type TestSuite interface {
// This function actually register tests inside testsuite
func RegisterTests(suite TestSuite, driver TestDriver, pattern TestPattern) {
tsInfo := suite.GetTestSuiteInfo()
testName := fmt.Sprintf("[Testpattern: %s]%s %s%s", pattern.Name, pattern.FeatureTag, tsInfo.Name, tsInfo.FeatureTag)
ginkgo.Context(testName, func() {
var args []interface{}
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() {
// skip all the invalid combination of driver and pattern
SkipInvalidDriverPatternCombination(driver, pattern)
@ -60,6 +64,7 @@ func RegisterTests(suite TestSuite, driver TestDriver, pattern TestPattern) {
// might still needed for specific independent test cases.
suite.DefineTests(driver, pattern)
})
framework.Context(args...)
}
// 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
type TestSuiteInfo struct {
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
SupportedSizeRange e2evolume.SizeRange // Size range supported by the test suite
}

View File

@ -19,7 +19,6 @@ package storage
import (
"os"
"github.com/onsi/ginkgo/v2"
"k8s.io/kubernetes/test/e2e/framework"
"k8s.io/kubernetes/test/e2e/storage/drivers"
storageframework "k8s.io/kubernetes/test/e2e/storage/framework"
@ -80,8 +79,8 @@ var _ = utils.SIGDescribe("In-tree Volumes", func() {
for _, initDriver := range testDrivers {
curDriver := initDriver()
ginkgo.Context(storageframework.GetDriverNameWithFeatureTags(curDriver), func() {
framework.Context(append(storageframework.GetDriverNameWithFeatureTags(curDriver), func() {
storageframework.DefineTestSuites(curDriver, testsuites.BaseSuites)
})
})...)
}
})

View File

@ -42,7 +42,7 @@ func InitCustomDisruptiveTestSuite(patterns []storageframework.TestPattern) stor
return &disruptiveTestSuite{
tsInfo: storageframework.TestSuiteInfo{
Name: "disruptive",
FeatureTag: "[Disruptive][LinuxOnly]",
TestTags: []interface{}{framework.WithDisruptive(), framework.WithLabel("LinuxOnly")},
TestPatterns: patterns,
},
}
@ -207,26 +207,26 @@ func (s *disruptiveTestSuite) DefineTests(driver storageframework.TestDriver, pa
}
multiplePodTests := []multiplePodTest{
{
testItStmt: "Should test that pv used in a pod that is deleted while the kubelet is down is usable by a new pod when kubelet returns [Feature:SELinux].",
testItStmt: "Should test that pv used in a pod that is deleted while the kubelet is down is usable by a new pod when kubelet returns [Feature:SELinux]",
runTestFile: func(ctx context.Context, c clientset.Interface, f *framework.Framework, pod1, pod2 *v1.Pod) {
storageutils.TestVolumeUnmountsFromDeletedPodWithForceOption(ctx, c, f, pod1, false, false, pod2, e2epod.VolumeMountPath1)
},
},
{
testItStmt: "Should test that pv used in a pod that is force deleted while the kubelet is down is usable by a new pod when kubelet returns [Feature:SELinux].",
testItStmt: "Should test that pv used in a pod that is force deleted while the kubelet is down is usable by a new pod when kubelet returns [Feature:SELinux]",
runTestFile: func(ctx context.Context, c clientset.Interface, f *framework.Framework, pod1, pod2 *v1.Pod) {
storageutils.TestVolumeUnmountsFromDeletedPodWithForceOption(ctx, c, f, pod1, true, false, pod2, e2epod.VolumeMountPath1)
},
},
{
testItStmt: "Should test that pv used in a pod that is deleted while the kubelet is down is usable by a new pod with a different SELinux context when kubelet returns [Feature:SELinux].",
testItStmt: "Should test that pv used in a pod that is deleted while the kubelet is down is usable by a new pod with a different SELinux context when kubelet returns [Feature:SELinux]",
changeSELinuxContexts: true,
runTestFile: func(ctx context.Context, c clientset.Interface, f *framework.Framework, pod1, pod2 *v1.Pod) {
storageutils.TestVolumeUnmountsFromDeletedPodWithForceOption(ctx, c, f, pod1, false, false, pod2, e2epod.VolumeMountPath1)
},
},
{
testItStmt: "Should test that pv used in a pod that is force deleted while the kubelet is down is usable by a new pod with a different SELinux context when kubelet returns [Feature:SELinux].",
testItStmt: "Should test that pv used in a pod that is force deleted while the kubelet is down is usable by a new pod with a different SELinux context when kubelet returns [Feature:SELinux]",
changeSELinuxContexts: true,
runTestFile: func(ctx context.Context, c clientset.Interface, f *framework.Framework, pod1, pod2 *v1.Pod) {
storageutils.TestVolumeUnmountsFromDeletedPodWithForceOption(ctx, c, f, pod1, true, false, pod2, e2epod.VolumeMountPath1)

View File

@ -19,6 +19,7 @@ package testsuites
import (
"context"
"fmt"
"reflect"
"time"
"github.com/onsi/ginkgo/v2"
@ -26,6 +27,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/errors"
clientset "k8s.io/client-go/kubernetes"
"k8s.io/kubernetes/test/e2e/feature"
"k8s.io/kubernetes/test/e2e/framework"
e2enode "k8s.io/kubernetes/test/e2e/framework/node"
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
@ -316,7 +318,7 @@ func (t *multiVolumeTestSuite) DefineTests(driver storageframework.TestDriver, p
// [ node1 ]
// | | <- same volume mode
// [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)
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)
}
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)
}

View File

@ -60,7 +60,7 @@ func InitCustomReadWriteOncePodTestSuite(patterns []storageframework.TestPattern
tsInfo: storageframework.TestSuiteInfo{
Name: "read-write-once-pod",
TestPatterns: patterns,
FeatureTag: "[MinimumKubeletVersion:1.27]",
TestTags: []interface{}{framework.WithLabel("MinimumKubeletVersion:1.27")},
},
}
}

View File

@ -33,6 +33,7 @@ import (
"k8s.io/client-go/dynamic"
clientset "k8s.io/client-go/kubernetes"
"k8s.io/component-helpers/storage/ephemeral"
"k8s.io/kubernetes/test/e2e/feature"
"k8s.io/kubernetes/test/e2e/framework"
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
e2eoutput "k8s.io/kubernetes/test/e2e/framework/pod/output"
@ -66,7 +67,7 @@ func InitCustomSnapshottableTestSuite(patterns []storageframework.TestPattern) s
SupportedSizeRange: e2evolume.SizeRange{
Min: "1Mi",
},
FeatureTag: "[Feature:VolumeSnapshotDataSource]",
TestTags: []interface{}{feature.VolumeSnapshotDataSource},
},
}
}

View File

@ -28,6 +28,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
errors "k8s.io/apimachinery/pkg/util/errors"
clientset "k8s.io/client-go/kubernetes"
"k8s.io/kubernetes/test/e2e/feature"
"k8s.io/kubernetes/test/e2e/framework"
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
e2epv "k8s.io/kubernetes/test/e2e/framework/pv"
@ -67,7 +68,7 @@ func InitCustomSnapshottableStressTestSuite(patterns []storageframework.TestPatt
SupportedSizeRange: e2evolume.SizeRange{
Min: "1Mi",
},
FeatureTag: "[Feature:VolumeSnapshotDataSource]",
TestTags: []interface{}{feature.VolumeSnapshotDataSource},
},
}
}