Skip to content

Commit 79e8b1d

Browse files
authored
Merge pull request #2780 from mdzraf/e2eValidateParams
Added Verification Of Expected Parameters for e2e tests
2 parents 87f31ef + 33182e3 commit 79e8b1d

File tree

4 files changed

+267
-0
lines changed

4 files changed

+267
-0
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright 2025 The Kubernetes Authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the 'License');
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an 'AS IS' BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package testsuites
16+
17+
import (
18+
"github.com/kubernetes-sigs/aws-ebs-csi-driver/tests/e2e/driver"
19+
. "github.com/onsi/ginkgo/v2"
20+
v1 "k8s.io/api/core/v1"
21+
clientset "k8s.io/client-go/kubernetes"
22+
)
23+
24+
// DynamicallyProvisionedVolumePropertiesTest will create a pod along with a volume.
25+
// It will then wait until the volume is created and verify input parameters were
26+
// properly applied to the volume.
27+
type DynamicallyProvisionedVolumePropertiesTest struct {
28+
CreateVolumeParameters map[string]string
29+
ClaimSize string
30+
}
31+
32+
func (t *DynamicallyProvisionedVolumePropertiesTest) Run(c clientset.Interface, ns *v1.Namespace, ebsDriver driver.PVTestDriver) {
33+
volumeDetails := CreateVolumeDetails(t.CreateVolumeParameters, t.ClaimSize)
34+
testVolume, _ := volumeDetails.SetupDynamicPersistentVolumeClaim(c, ns, ebsDriver)
35+
defer testVolume.Cleanup()
36+
37+
pod := createPodWithVolume(c, ns, "", testVolume, volumeDetails)
38+
defer pod.Cleanup()
39+
pod.WaitForSuccess()
40+
41+
By("verifying volume properties")
42+
volumeID := testVolume.persistentVolume.Spec.CSI.VolumeHandle
43+
44+
expected := BuildExpectedParameters(t.CreateVolumeParameters, t.ClaimSize)
45+
VerifyVolumeProperties(volumeID, expected)
46+
}

tests/e2e/testsuites/e2e_utils.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@ package testsuites
1717
import (
1818
"context"
1919
"fmt"
20+
"strconv"
2021
"time"
2122

23+
"github.com/aws/aws-sdk-go-v2/aws"
24+
"github.com/aws/aws-sdk-go-v2/config"
25+
"github.com/aws/aws-sdk-go-v2/service/ec2"
2226
"github.com/kubernetes-sigs/aws-ebs-csi-driver/pkg/util"
2327
v1 "k8s.io/api/core/v1"
2428
"k8s.io/apimachinery/pkg/api/resource"
@@ -44,6 +48,7 @@ const (
4448
VolumeType = "type"
4549
TagSpec = "tagSpecification"
4650
TagDel = "tagDeletion"
51+
Encrypted = "encrypted"
4752
)
4853

4954
var DefaultGeneratedVolumeMount = VolumeMountDetails{
@@ -181,3 +186,92 @@ func PrefixAnnotations(prefix string, parameters map[string]string) map[string]s
181186
}
182187
return result
183188
}
189+
190+
type ExpectedParameters struct {
191+
Size *int32
192+
IOPS *int32
193+
Throughput *int32
194+
VolumeType *string
195+
Encrypted *bool
196+
}
197+
198+
func BuildExpectedParameters(params map[string]string, claimSize string) ExpectedParameters {
199+
expected := ExpectedParameters{}
200+
201+
if claimSize != "" {
202+
quantity, err := resource.ParseQuantity(claimSize)
203+
framework.ExpectNoError(err, "failed to parse claim size")
204+
sizeGiB := util.BytesToGiB(quantity.Value())
205+
expected.Size = &sizeGiB
206+
}
207+
208+
if iopsStr, ok := params[Iops]; ok {
209+
iops, err := strconv.ParseInt(iopsStr, 10, 32)
210+
framework.ExpectNoError(err, "failed to parse IOPS")
211+
iops32 := int32(iops)
212+
expected.IOPS = &iops32
213+
}
214+
215+
if throughputStr, ok := params[Throughput]; ok {
216+
throughput, err := strconv.ParseInt(throughputStr, 10, 32)
217+
framework.ExpectNoError(err, "failed to parse throughput")
218+
throughput32 := int32(throughput)
219+
expected.Throughput = &throughput32
220+
}
221+
222+
if volType, ok := params[VolumeType]; ok {
223+
expected.VolumeType = &volType
224+
}
225+
226+
if _, ok := params[Encrypted]; ok {
227+
expected.Encrypted = aws.Bool(true)
228+
}
229+
230+
return expected
231+
}
232+
233+
func VerifyVolumeProperties(volumeID string, verification ExpectedParameters) {
234+
cfg, err := config.LoadDefaultConfig(context.Background())
235+
framework.ExpectNoError(err, "failed to load AWS config")
236+
237+
ec2Client := ec2.NewFromConfig(cfg)
238+
resp, err := ec2Client.DescribeVolumes(context.Background(), &ec2.DescribeVolumesInput{
239+
VolumeIds: []string{volumeID},
240+
})
241+
framework.ExpectNoError(err, fmt.Sprintf("failed to describe volume %s", volumeID))
242+
if len(resp.Volumes) == 0 {
243+
framework.Failf("volume %s not found", volumeID)
244+
}
245+
volume := &resp.Volumes[0]
246+
247+
if verification.Size != nil && volume.Size != nil {
248+
if *volume.Size != *verification.Size {
249+
framework.Failf("volume size mismatch: expected %d GiB, got %d GiB", *verification.Size, *volume.Size)
250+
}
251+
}
252+
253+
if verification.IOPS != nil && volume.Iops != nil {
254+
if *volume.Iops != *verification.IOPS {
255+
framework.Failf("volume IOPS mismatch: expected %d, got %d", *verification.IOPS, *volume.Iops)
256+
}
257+
}
258+
259+
if verification.Throughput != nil && volume.Throughput != nil {
260+
if *volume.Throughput != *verification.Throughput {
261+
framework.Failf("volume throughput mismatch: expected %d, got %d", *verification.Throughput, *volume.Throughput)
262+
}
263+
}
264+
265+
if verification.VolumeType != nil {
266+
if string(volume.VolumeType) != *verification.VolumeType {
267+
framework.Failf("volume type mismatch: expected %s, got %s", *verification.VolumeType, volume.VolumeType)
268+
}
269+
}
270+
271+
if verification.Encrypted != nil && volume.Encrypted != nil {
272+
if *volume.Encrypted != *verification.Encrypted {
273+
framework.Failf("volume encryption mismatch: expected %t, got %t", *verification.Encrypted, *volume.Encrypted)
274+
}
275+
}
276+
framework.Logf("Volume %s verified successfully", volumeID)
277+
}

tests/e2e/testsuites/modify_volume_tester.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,17 @@ func (modifyVolumeTest *ModifyVolumeTest) Run(c clientset.Interface, ns *v1.Name
112112
err = WaitForPvToResize(c, ns, testVolume.persistentVolume.Name, updatedPvcSize, DefaultResizeTimout, DefaultK8sAPIPollingInterval)
113113
framework.ExpectNoError(err, fmt.Sprintf("fail to resize pv(%s): %v", modifyingPvc.Name, err))
114114
}
115+
116+
By("verifying volume properties")
117+
volumeID := testVolume.persistentVolume.Spec.CSI.VolumeHandle
118+
119+
expected := BuildExpectedParameters(modifyVolumeTest.ModifyVolumeParameters, "")
120+
if modifyVolumeTest.ShouldResizeVolume {
121+
sizeGiB := util.BytesToGiB(updatedPvcSize.Value())
122+
expected.Size = &sizeGiB
123+
}
124+
125+
VerifyVolumeProperties(volumeID, expected)
115126
}
116127

117128
func attemptInvalidModification(c clientset.Interface, ns *v1.Namespace, testVolume *TestPersistentVolumeClaim) {

tests/e2e/volume_properties.go

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// Copyright 2025 The Kubernetes Authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the 'License');
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an 'AS IS' BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package e2e
16+
17+
import (
18+
awscloud "github.com/kubernetes-sigs/aws-ebs-csi-driver/pkg/cloud"
19+
ebscsidriver "github.com/kubernetes-sigs/aws-ebs-csi-driver/pkg/driver"
20+
"github.com/kubernetes-sigs/aws-ebs-csi-driver/tests/e2e/driver"
21+
"github.com/kubernetes-sigs/aws-ebs-csi-driver/tests/e2e/testsuites"
22+
. "github.com/onsi/ginkgo/v2"
23+
v1 "k8s.io/api/core/v1"
24+
clientset "k8s.io/client-go/kubernetes"
25+
"k8s.io/kubernetes/test/e2e/framework"
26+
admissionapi "k8s.io/pod-security-admission/api"
27+
)
28+
29+
var _ = Describe("[ebs-csi-e2e] [single-az] Volume Properties Verification", func() {
30+
f := framework.NewDefaultFramework("ebs")
31+
f.NamespacePodSecurityEnforceLevel = admissionapi.LevelPrivileged
32+
33+
var (
34+
cs clientset.Interface
35+
ns *v1.Namespace
36+
ebsDriver driver.PVTestDriver
37+
)
38+
39+
BeforeEach(func() {
40+
cs = f.ClientSet
41+
ns = f.Namespace
42+
ebsDriver = driver.InitEbsCSIDriver()
43+
})
44+
45+
It("should create a gp3 volume with custom IOPS", func() {
46+
test := testsuites.DynamicallyProvisionedVolumePropertiesTest{
47+
CreateVolumeParameters: map[string]string{
48+
ebscsidriver.VolumeTypeKey: awscloud.VolumeTypeGP3,
49+
ebscsidriver.IopsKey: "4000",
50+
},
51+
ClaimSize: "10Gi",
52+
}
53+
test.Run(cs, ns, ebsDriver)
54+
})
55+
56+
It("should create a gp3 volume with custom IOPS and throughput", func() {
57+
test := testsuites.DynamicallyProvisionedVolumePropertiesTest{
58+
CreateVolumeParameters: map[string]string{
59+
ebscsidriver.VolumeTypeKey: awscloud.VolumeTypeGP3,
60+
ebscsidriver.IopsKey: "5000",
61+
ebscsidriver.ThroughputKey: "250",
62+
},
63+
ClaimSize: "10Gi",
64+
}
65+
test.Run(cs, ns, ebsDriver)
66+
})
67+
68+
It("should create an io2 volume with custom IOPS", func() {
69+
test := testsuites.DynamicallyProvisionedVolumePropertiesTest{
70+
CreateVolumeParameters: map[string]string{
71+
ebscsidriver.VolumeTypeKey: awscloud.VolumeTypeIO2,
72+
ebscsidriver.IopsKey: "10000",
73+
},
74+
ClaimSize: "10Gi",
75+
}
76+
test.Run(cs, ns, ebsDriver)
77+
})
78+
79+
It("should create a io2 volume with custom IOPS and encryption", func() {
80+
test := testsuites.DynamicallyProvisionedVolumePropertiesTest{
81+
CreateVolumeParameters: map[string]string{
82+
ebscsidriver.VolumeTypeKey: awscloud.VolumeTypeIO2,
83+
ebscsidriver.IopsKey: "5000",
84+
ebscsidriver.EncryptedKey: "true",
85+
},
86+
ClaimSize: "10Gi",
87+
}
88+
test.Run(cs, ns, ebsDriver)
89+
})
90+
91+
It("should create an io2 volume with encryption", func() {
92+
test := testsuites.DynamicallyProvisionedVolumePropertiesTest{
93+
CreateVolumeParameters: map[string]string{
94+
ebscsidriver.VolumeTypeKey: awscloud.VolumeTypeIO2,
95+
ebscsidriver.IopsKey: "1000",
96+
ebscsidriver.EncryptedKey: "true",
97+
},
98+
ClaimSize: "10Gi",
99+
}
100+
test.Run(cs, ns, ebsDriver)
101+
})
102+
103+
It("should create an gp3 volume with custom size, IOPS, throughput, and encryption", func() {
104+
test := testsuites.DynamicallyProvisionedVolumePropertiesTest{
105+
CreateVolumeParameters: map[string]string{
106+
ebscsidriver.VolumeTypeKey: awscloud.VolumeTypeGP3,
107+
ebscsidriver.IopsKey: "4000",
108+
ebscsidriver.ThroughputKey: "250",
109+
ebscsidriver.EncryptedKey: "true",
110+
},
111+
ClaimSize: "10Gi",
112+
}
113+
test.Run(cs, ns, ebsDriver)
114+
})
115+
116+
})

0 commit comments

Comments
 (0)