From eb2ebddf61c5d791164990e4e561e73a17b3ba4a Mon Sep 17 00:00:00 2001 From: zhucan Date: Tue, 29 Mar 2022 11:49:46 +0800 Subject: [PATCH] fix: add unit test Signed-off-by: zhucan --- pkg/api/persistentvolume/util_test.go | 110 ++++++++++++++++++++ pkg/api/v1/persistentvolume/util_test.go | 9 ++ pkg/apis/core/validation/validation_test.go | 16 +++ pkg/volume/csi/expander_test.go | 57 ++++++++-- 4 files changed, 184 insertions(+), 8 deletions(-) create mode 100644 pkg/api/persistentvolume/util_test.go diff --git a/pkg/api/persistentvolume/util_test.go b/pkg/api/persistentvolume/util_test.go new file mode 100644 index 00000000000..3874adb18c7 --- /dev/null +++ b/pkg/api/persistentvolume/util_test.go @@ -0,0 +1,110 @@ +/* +Copyright 2018 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 persistentvolume + +import ( + "reflect" + "testing" + + "github.com/google/go-cmp/cmp" + + utilfeature "k8s.io/apiserver/pkg/util/feature" + featuregatetesting "k8s.io/component-base/featuregate/testing" + api "k8s.io/kubernetes/pkg/apis/core" + "k8s.io/kubernetes/pkg/features" +) + +func TestDropDisabledFields(t *testing.T) { + secretRef := &api.SecretReference{ + Name: "expansion-secret", + Namespace: "default", + } + + tests := map[string]struct { + oldSpec *api.PersistentVolumeSpec + newSpec *api.PersistentVolumeSpec + expectOldSpec *api.PersistentVolumeSpec + expectNewSpec *api.PersistentVolumeSpec + csiExpansionEnabled bool + }{ + "disabled csi expansion clears secrets": { + csiExpansionEnabled: false, + newSpec: specWithCSISecrets(secretRef), + expectNewSpec: specWithCSISecrets(nil), + oldSpec: nil, + expectOldSpec: nil, + }, + "enabled csi expansion preserve secrets": { + csiExpansionEnabled: true, + newSpec: specWithCSISecrets(secretRef), + expectNewSpec: specWithCSISecrets(secretRef), + oldSpec: nil, + expectOldSpec: nil, + }, + "enabled csi expansion preserve secrets when both old and new have it": { + csiExpansionEnabled: true, + newSpec: specWithCSISecrets(secretRef), + expectNewSpec: specWithCSISecrets(secretRef), + oldSpec: specWithCSISecrets(secretRef), + expectOldSpec: specWithCSISecrets(secretRef), + }, + "disabled csi expansion old pv had secrets": { + csiExpansionEnabled: false, + newSpec: specWithCSISecrets(secretRef), + expectNewSpec: specWithCSISecrets(secretRef), + oldSpec: specWithCSISecrets(secretRef), + expectOldSpec: specWithCSISecrets(secretRef), + }, + "enabled csi expansion preserves secrets when old pv did not had secrets": { + csiExpansionEnabled: true, + newSpec: specWithCSISecrets(secretRef), + expectNewSpec: specWithCSISecrets(secretRef), + oldSpec: specWithCSISecrets(nil), + expectOldSpec: specWithCSISecrets(nil), + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSINodeExpandSecret, tc.csiExpansionEnabled)() + + DropDisabledFields(tc.newSpec, tc.oldSpec) + if !reflect.DeepEqual(tc.newSpec, tc.expectNewSpec) { + t.Error(cmp.Diff(tc.newSpec, tc.expectNewSpec)) + } + if !reflect.DeepEqual(tc.oldSpec, tc.expectOldSpec) { + t.Error(cmp.Diff(tc.oldSpec, tc.expectOldSpec)) + } + }) + } +} + +func specWithCSISecrets(secret *api.SecretReference) *api.PersistentVolumeSpec { + pvSpec := &api.PersistentVolumeSpec{ + PersistentVolumeSource: api.PersistentVolumeSource{ + CSI: &api.CSIPersistentVolumeSource{ + Driver: "com.google.gcepd", + VolumeHandle: "foobar", + }, + }, + } + + if secret != nil { + pvSpec.CSI.NodeExpandSecretRef = secret + } + return pvSpec +} diff --git a/pkg/api/v1/persistentvolume/util_test.go b/pkg/api/v1/persistentvolume/util_test.go index 8ae481bb5be..b5fbf7f357d 100644 --- a/pkg/api/v1/persistentvolume/util_test.go +++ b/pkg/api/v1/persistentvolume/util_test.go @@ -149,6 +149,13 @@ func TestPVSecrets(t *testing.T) { ControllerExpandSecretRef: &corev1.SecretReference{ Name: "Spec.PersistentVolumeSource.CSI.ControllerExpandSecretRef", Namespace: "csi"}}}}}, + {Spec: corev1.PersistentVolumeSpec{ + ClaimRef: &corev1.ObjectReference{Namespace: "claimrefns", Name: "claimrefname"}, + PersistentVolumeSource: corev1.PersistentVolumeSource{ + CSI: &corev1.CSIPersistentVolumeSource{ + NodeExpandSecretRef: &corev1.SecretReference{ + Name: "Spec.PersistentVolumeSource.CSI.NodeExpandSecretRef", + Namespace: "csi"}}}}}, } extractedNames := sets.NewString() extractedNamesWithNamespace := sets.NewString() @@ -181,6 +188,7 @@ func TestPVSecrets(t *testing.T) { "Spec.PersistentVolumeSource.CSI.NodePublishSecretRef", "Spec.PersistentVolumeSource.CSI.NodeStageSecretRef", "Spec.PersistentVolumeSource.CSI.ControllerExpandSecretRef", + "Spec.PersistentVolumeSource.CSI.NodeExpandSecretRef", ) secretPaths := collectSecretPaths(t, nil, "", reflect.TypeOf(&api.PersistentVolume{})) secretPaths = secretPaths.Difference(excludedSecretPaths) @@ -229,6 +237,7 @@ func TestPVSecrets(t *testing.T) { "csi/Spec.PersistentVolumeSource.CSI.NodePublishSecretRef", "csi/Spec.PersistentVolumeSource.CSI.NodeStageSecretRef", "csi/Spec.PersistentVolumeSource.CSI.ControllerExpandSecretRef", + "csi/Spec.PersistentVolumeSource.CSI.NodeExpandSecretRef", ) if missingNames := expectedNamespacedNames.Difference(extractedNamesWithNamespace); len(missingNames) > 0 { t.Logf("Missing expected namespaced names:\n%s", strings.Join(missingNames.List(), "\n")) diff --git a/pkg/apis/core/validation/validation_test.go b/pkg/apis/core/validation/validation_test.go index 72c77a31805..a4383152440 100644 --- a/pkg/apis/core/validation/validation_test.go +++ b/pkg/apis/core/validation/validation_test.go @@ -2898,6 +2898,22 @@ func TestValidateCSIPersistentVolumeSource(t *testing.T) { errtype: field.ErrorTypeRequired, errfield: "nodePublishSecretRef.namespace", }, + { + name: "nodeExpandSecretRef: invalid name missing", + csi: &core.CSIPersistentVolumeSource{Driver: "com.google.gcepd", VolumeHandle: "foobar", NodeExpandSecretRef: &core.SecretReference{Namespace: "default"}}, + errtype: field.ErrorTypeRequired, + errfield: "nodeExpandSecretRef.name", + }, + { + name: "nodeExpandSecretRef: invalid namespace missing", + csi: &core.CSIPersistentVolumeSource{Driver: "com.google.gcepd", VolumeHandle: "foobar", NodeExpandSecretRef: &core.SecretReference{Name: "foobar"}}, + errtype: field.ErrorTypeRequired, + errfield: "nodeExpandSecretRef.namespace", + }, + { + name: "valid nodeExpandSecretRef", + csi: &core.CSIPersistentVolumeSource{Driver: "com.google.gcepd", VolumeHandle: "foobar", NodeExpandSecretRef: &core.SecretReference{Name: "foobar", Namespace: "default"}}, + }, } for i, tc := range testCases { diff --git a/pkg/volume/csi/expander_test.go b/pkg/volume/csi/expander_test.go index 32af09b928b..44660305bb7 100644 --- a/pkg/volume/csi/expander_test.go +++ b/pkg/volume/csi/expander_test.go @@ -17,26 +17,34 @@ limitations under the License. package csi import ( + "context" "os" "testing" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + api "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + utilfeature "k8s.io/apiserver/pkg/util/feature" + featuregatetesting "k8s.io/component-base/featuregate/testing" + "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/volume" volumetypes "k8s.io/kubernetes/pkg/volume/util/types" ) func TestNodeExpand(t *testing.T) { tests := []struct { - name string - nodeExpansion bool - nodeStageSet bool - success bool - fsVolume bool - grpcError error - hasVolumeInUseError bool - deviceStagePath string + name string + nodeExpansion bool + nodeStageSet bool + success bool + fsVolume bool + grpcError error + hasVolumeInUseError bool + deviceStagePath string + enableCSINodeExpandSecret bool + secret *api.Secret }{ { name: "when node expansion is not set", @@ -87,13 +95,39 @@ func TestNodeExpand(t *testing.T) { grpcError: status.Error(codes.InvalidArgument, "invalid-argument"), hasVolumeInUseError: false, }, + { + name: "when nodeExpansion=on, nodeStage=on, volumePhase=staged", + nodeExpansion: true, + nodeStageSet: true, + success: true, + fsVolume: true, + deviceStagePath: "/foo/bar", + enableCSINodeExpandSecret: true, + secret: &api.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "expand-secret", + Namespace: "default", + }, + Data: map[string][]byte{ + "apiUsername": []byte("csiusername"), + "apiPassword": []byte("csipassword"), + }, + }, + }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { + defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSINodeExpandSecret, tc.enableCSINodeExpandSecret)() plug, tmpDir := newTestPlugin(t, nil) defer os.RemoveAll(tmpDir) spec := volume.NewSpecFromPersistentVolume(makeTestPV("test-pv", 10, "expandable", "test-vol"), false) + if tc.enableCSINodeExpandSecret { + spec.PersistentVolume.Spec.CSI.NodeExpandSecretRef = &api.SecretReference{ + Name: tc.secret.Name, + Namespace: tc.secret.Namespace, + } + } newSize, _ := resource.ParseQuantity("20Gi") @@ -110,6 +144,13 @@ func TestNodeExpand(t *testing.T) { fakeCSIClient, _ := csClient.(*fakeCsiDriverClient) fakeNodeClient := fakeCSIClient.nodeClient + if tc.enableCSINodeExpandSecret { + _, err := plug.host.GetKubeClient().CoreV1().Secrets(tc.secret.Namespace).Create(context.TODO(), tc.secret, metav1.CreateOptions{}) + if err != nil { + t.Fatal(err) + } + } + if tc.grpcError != nil { fakeNodeClient.SetNextError(tc.grpcError) }