Skip to content

Commit 667d926

Browse files
committed
Refactor parallel download testsuite for dynamic test generation
1 parent 154b98e commit 667d926

15 files changed

+857
-269
lines changed

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515

1616
BINDIR ?= $(shell pwd)/bin
1717

18+
ifeq ($(ENABLE_ZB), true)
19+
export GCSFUSE_CLIENT_PROTOCOL = grpc
20+
endif
21+
1822
# The various gcloud and kubectl checks can be slow. Setting SKIP_VAR=true when
1923
# making only targets like driver, sidecar-mounter and webook will speed up your
2024
# life.

pkg/sidecar_mounter/sidecar_mounter_config.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ type sidecarRetryConfig struct {
8080

8181
var prometheusPort = 62990
8282

83+
// disallowedFlags is a map of flags that are not allowed to be passed to gcsfuse directly.
84+
// Note: If you add more disallowed flags here, you should update the disallowedFlagsMapping
85+
// in test/e2e/utils/utils.go to ensure they are correctly translated to the config file format.
8386
var disallowedFlags = map[string]bool{
8487
"temp-dir": true,
8588
"config-file": true,

test/e2e/e2e_test.go

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ limitations under the License.
1818
package main
1919

2020
import (
21-
"context"
2221
"flag"
2322
"fmt"
2423
"os"
@@ -33,6 +32,7 @@ import (
3332
"github.com/googlecloudplatform/gcs-fuse-csi-driver/pkg/cloud_provider/metadata"
3433
"github.com/onsi/ginkgo/v2"
3534
"github.com/onsi/gomega"
35+
3636
"k8s.io/client-go/tools/clientcmd"
3737
"k8s.io/klog/v2"
3838
"k8s.io/kubernetes/test/e2e/framework"
@@ -54,6 +54,7 @@ var (
5454

5555
var _ = func() bool {
5656
testing.Init()
57+
5758
if os.Getenv(clientcmd.RecommendedConfigPathEnvVar) == "" {
5859
kubeconfig := filepath.Join(os.Getenv("HOME"), ".kube", "config")
5960
os.Setenv(clientcmd.RecommendedConfigPathEnvVar, kubeconfig)
@@ -84,6 +85,8 @@ var _ = func() bool {
8485
if err != nil {
8586
klog.Fatalf("Failed to create fake meta data service: %v", err)
8687
}
88+
89+
testsuites.GCSFuseVersionStr = specs.GetGCSFuseVersion()
8790
return true
8891
}()
8992

@@ -102,13 +105,6 @@ func TestE2E(t *testing.T) {
102105
ginkgo.RunSpecs(t, "Cloud Storage FUSE CSI Driver", suiteConfig, reporterConfig)
103106
}
104107

105-
var _ = ginkgo.SynchronizedBeforeSuite(func(ctx context.Context) []byte {
106-
gcsfuseVersion := specs.GetGCSFuseVersion(ctx)
107-
return []byte(gcsfuseVersion)
108-
}, func(ctx context.Context, data []byte) {
109-
os.Setenv(specs.GcsfuseVersionVarName, string(data))
110-
})
111-
112108
var _ = ginkgo.Describe("E2E Test Suite", func() {
113109
GCSFuseCSITestSuites := func() []func() storageframework.TestSuite {
114110
suites := []func() storageframework.TestSuite{
@@ -156,6 +152,15 @@ var _ = ginkgo.Describe("E2E Test Suite", func() {
156152
testDriverHNS := specs.InitGCSFuseCSITestDriver(c, m, *bucketLocation, *skipGcpSaTest, true, *clientProtocol, *zbFlag)
157153

158154
ginkgo.Context(fmt.Sprintf("[Driver: %s HNS]", testDriverHNS.GetDriverInfo().Name), func() {
155+
// Skip HNS tests suites for ZB since enable ZB will automatically enable HNS
156+
// And the test cases in GCSFuseCSITestSuites already includes HNS tests
157+
if *zbFlag {
158+
ginkgo.It("should be skipped since ZB already enables HNS", func() {
159+
ginkgo.Skip("Skipping HNS tests suites for ZB since enable ZB will automatically enable HNS")
160+
})
161+
return
162+
}
163+
159164
storageframework.DefineTestSuites(testDriverHNS, GCSFuseCSITestSuitesHNS)
160165
})
161166
})

test/e2e/specs/specs.go

Lines changed: 6 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,8 @@ import (
3939
"k8s.io/apimachinery/pkg/util/rand"
4040
"k8s.io/apimachinery/pkg/util/version"
4141
"k8s.io/apimachinery/pkg/util/wait"
42-
"k8s.io/klog/v2"
4342

4443
clientset "k8s.io/client-go/kubernetes"
45-
"k8s.io/client-go/tools/clientcmd"
4644
"k8s.io/kubernetes/pkg/kubelet/events"
4745
"k8s.io/kubernetes/test/e2e/framework"
4846
e2eevents "k8s.io/kubernetes/test/e2e/framework/events"
@@ -121,8 +119,6 @@ const (
121119
driverDaemonsetLabel = "k8s-app=gcs-fuse-csi-driver"
122120

123121
IsOSSEnvVar = "IS_OSS"
124-
125-
GcsfuseVersionVarName = "gcsfuse-version"
126122
)
127123

128124
var InvalidVolume = fmt.Sprintf("non-existent-test-bucket-%s", rand.String(8))
@@ -1083,107 +1079,14 @@ func (t *TestJob) Cleanup(ctx context.Context) {
10831079
framework.ExpectNoError(err)
10841080
}
10851081

1086-
func GetGCSFuseVersion(ctx context.Context) string {
1087-
config, err := clientcmd.BuildConfigFromFlags("", framework.TestContext.KubeConfig)
1088-
framework.ExpectNoError(err)
1089-
1090-
cs, err := clientset.NewForConfig(config)
1091-
framework.ExpectNoError(err)
1092-
1093-
versionData := os.Getenv(GcsfuseVersionVarName)
1094-
if versionData != "" {
1095-
return versionData
1096-
}
1097-
klog.Infof("GCSFuseVersion env var has not been set will retrieve it manually")
1098-
1099-
gcsfuseVersion, err := deployGCSFuseVersionFetcherPod(ctx, cs)
1100-
if err != nil {
1101-
klog.Errorf("Failed to deploy GCS Fuse version fetcher pod: %v", err)
1102-
framework.ExpectNoError(err)
1103-
}
1104-
1105-
return gcsfuseVersion
1106-
}
1107-
1108-
func deployGCSFuseVersionFetcherPod(ctx context.Context, clientset clientset.Interface) (string, error) {
1109-
configMaps, err := clientset.CoreV1().ConfigMaps("").List(ctx, metav1.ListOptions{
1110-
FieldSelector: "metadata.name=gcsfusecsi-image-config",
1111-
})
1112-
framework.ExpectNoError(err)
1113-
if len(configMaps.Items) != 1 {
1114-
framework.Failf("expected one config map `gcsfusecsi-image-config` but found %d", len(configMaps.Items))
1115-
}
1116-
1117-
sidecarImageConfig := configMaps.Items[0]
1118-
1119-
image := sidecarImageConfig.Data["sidecar-image"]
1120-
if image == "" {
1121-
framework.Failf("expected data for key `sidecar-image` in the config map `gcsfusecsi-image-config`")
1122-
}
1123-
1124-
pod := &corev1.Pod{
1125-
ObjectMeta: metav1.ObjectMeta{
1126-
GenerateName: "gcsfuse-version-fetcher-",
1127-
Namespace: utils.DefaultNamespace,
1128-
},
1129-
Spec: corev1.PodSpec{
1130-
TerminationGracePeriodSeconds: ptr.To(int64(0)),
1131-
Containers: []corev1.Container{
1132-
{
1133-
Name: webhook.GcsFuseSidecarName,
1134-
Image: image,
1135-
Command: []string{"/gcsfuse", "--version"},
1136-
},
1137-
{
1138-
Name: "sleeper",
1139-
Image: "busybox",
1140-
Command: []string{"sleep", "infinity"},
1141-
},
1142-
},
1143-
RestartPolicy: corev1.RestartPolicyNever,
1144-
Tolerations: []corev1.Toleration{
1145-
{Operator: corev1.TolerationOpExists},
1146-
},
1147-
},
1148-
}
1149-
1150-
createdPod, err := clientset.CoreV1().Pods(utils.DefaultNamespace).Create(ctx, pod, metav1.CreateOptions{})
1151-
if createdPod != nil {
1152-
defer clientset.CoreV1().Pods(utils.DefaultNamespace).Delete(context.Background(), createdPod.Name, metav1.DeleteOptions{})
1153-
}
1154-
framework.ExpectNoError(err,
1155-
"Pods.Create should succeed, but failed with error message: %v", err)
1156-
1157-
e2epod.WaitForPodRunningInNamespace(ctx, clientset, createdPod)
1158-
klog.Infof("Pod %s is running, waiting 60s before fetching GCSFuse version from logs", createdPod.Name)
1159-
time.Sleep(60 * time.Second)
1160-
1161-
var logs []byte
1162-
req := clientset.CoreV1().Pods(utils.DefaultNamespace).GetLogs(createdPod.Name, &corev1.PodLogOptions{Container: webhook.GcsFuseSidecarName})
1163-
err = wait.PollUntilContextTimeout(ctx, 30*time.Second, time.Minute*10, true, func(context.Context) (bool, error) {
1164-
logs, err = req.DoRaw(ctx)
1165-
if err != nil {
1166-
framework.Logf("failed to read pod logs, retrying: %v", err)
1167-
return false, nil
1168-
}
1169-
return true, nil
1170-
})
1171-
if err != nil {
1172-
return "", fmt.Errorf("failed to read pod logs: %w", err)
1173-
}
1174-
1175-
output := string(logs)
1176-
1177-
// Parse: "gcsfuse version 3.7.1-gke.0 ..."
1178-
l := strings.Split(strings.TrimSpace(output), " ")
1179-
if len(l) <= 2 {
1180-
return "", fmt.Errorf("unexpected version output format: %s", output)
1181-
}
1182-
return l[2], nil
1082+
// GetGCSFuseVersion returns the GCSFuse version to be tested.
1083+
// The env var is set by the handler.go before running the tests.
1084+
func GetGCSFuseVersion() string {
1085+
return os.Getenv(utils.GcsfuseVersionVarName)
11831086
}
11841087

1185-
func GCSFuseVersionAndBranch(ctx context.Context) (*version.Version, string) {
1186-
vStr := GetGCSFuseVersion(ctx)
1088+
func GCSFuseVersionAndBranch() (*version.Version, string) {
1089+
vStr := GetGCSFuseVersion()
11871090
v, branch := utils.GCSFuseBranch(vStr)
11881091
if v == nil {
11891092
// This happens for master branch builds. We still need to parse the version.

test/e2e/specs/testdriver.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ func (n *GCSFuseCSITestDriver) CreateVolume(ctx context.Context, config *storage
248248
mountOptions += ",client-protocol=grpc"
249249
}
250250
if n.gcsfuseVersion == nil || n.gcsfuseBranch == "" {
251-
n.gcsfuseVersion, n.gcsfuseBranch = GCSFuseVersionAndBranch(ctx)
251+
n.gcsfuseVersion, n.gcsfuseBranch = GCSFuseVersionAndBranch()
252252
}
253253
kernelParamsSupported := n.gcsfuseBranch == utils.MasterBranchName || n.gcsfuseVersion.AtLeast(version.MustParseSemantic(utils.MinGCSFuseKernelParamsVersion))
254254

test/e2e/testsuites/failed_mount.go

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,7 @@ func (t *gcsFuseCSIFailedMountTestSuite) DefineTests(driver storageframework.Tes
147147
defer tPod.Cleanup(ctx)
148148

149149
ginkgo.By("Checking that the pod has failed mount error")
150-
if gcsfuseVersionStr == "" {
151-
gcsfuseVersionStr = specs.GetGCSFuseVersion(ctx)
152-
}
153-
v, err := version.ParseSemantic(gcsfuseVersionStr)
150+
v, err := version.ParseSemantic(GCSFuseVersionStr)
154151

155152
if enableSidecarBucketAccessCheck && configPrefix == specs.SkipCSIBucketAccessCheckAndFakeVolumePrefix {
156153
tPod.WaitForFailedContainerError(ctx, "Error: failed to reserve container name")
@@ -201,10 +198,10 @@ func (t *gcsFuseCSIFailedMountTestSuite) DefineTests(driver storageframework.Tes
201198

202199
ginkgo.By("Checking that the pod has failed mount error")
203200

204-
if gcsfuseVersionStr == "" {
205-
gcsfuseVersionStr = specs.GetGCSFuseVersion(ctx)
201+
if GCSFuseVersionStr == "" {
202+
GCSFuseVersionStr = specs.GetGCSFuseVersion()
206203
}
207-
v, err := version.ParseSemantic(gcsfuseVersionStr)
204+
v, err := version.ParseSemantic(GCSFuseVersionStr)
208205
if configPrefix == specs.SkipCSIBucketAccessCheckAndInvalidVolumePrefix && (err != nil || v.AtLeast(version.MustParseSemantic("v2.9.0-gke.0"))) {
209206
if enableSidecarBucketAccessCheck {
210207
tPod.WaitForFailedContainerError(ctx, "Error: failed to reserve container name")
@@ -480,10 +477,10 @@ func (t *gcsFuseCSIFailedMountTestSuite) DefineTests(driver storageframework.Tes
480477
})
481478

482479
ginkgo.It("should fail when invalid bool mount options are passed", func() {
483-
if gcsfuseVersionStr == "" {
484-
gcsfuseVersionStr = specs.GetGCSFuseVersion(ctx)
480+
if GCSFuseVersionStr == "" {
481+
GCSFuseVersionStr = specs.GetGCSFuseVersion()
485482
}
486-
v, err := version.ParseSemantic(gcsfuseVersionStr)
483+
v, err := version.ParseSemantic(GCSFuseVersionStr)
487484
if err == nil && v != nil && v.AtLeast(version.MustParseSemantic("v3.8.0-gke.0")) {
488485
testcaseInvalidMountOptions(specs.InvalidBoolMountOptionsVolumePrefix, "invalid syntax")
489486
}

0 commit comments

Comments
 (0)