Skip to content

Commit 08af530

Browse files
committed
Require VACs to use SI units
1 parent 6491802 commit 08af530

File tree

6 files changed

+255
-30
lines changed

6 files changed

+255
-30
lines changed
+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
apiVersion: storage.k8s.io/v1
2+
kind: StorageClass
3+
metadata:
4+
name: test-sc
5+
provisioner: pd.csi.storage.gke.io
6+
parameters:
7+
type: "hyperdisk-balanced"
8+
provisioned-iops-on-create: "3000"
9+
provisioned-throughput-on-create: "150Mi"
10+
volumeBindingMode: WaitForFirstConsumer
11+
---
12+
apiVersion: storage.k8s.io/v1beta1
13+
kind: VolumeAttributesClass
14+
metadata:
15+
name: silver
16+
driverName: pd.csi.storage.gke.io
17+
parameters:
18+
iops: "3000"
19+
throughput: "150Mi"
20+
---
21+
apiVersion: storage.k8s.io/v1beta1
22+
kind: VolumeAttributesClass
23+
metadata:
24+
name: gold
25+
driverName: pd.csi.storage.gke.io
26+
parameters:
27+
iops: "3013"
28+
throughput: "151Mi"
29+
---
30+
apiVersion: v1
31+
kind: PersistentVolumeClaim
32+
metadata:
33+
name: test-pvc
34+
spec:
35+
storageClassName: test-sc
36+
volumeAttributesClassName: silver
37+
accessModes:
38+
- ReadWriteOnce
39+
resources:
40+
requests:
41+
storage: 64Gi
42+
---
43+
apiVersion: v1
44+
kind: Pod
45+
metadata:
46+
name: nginx
47+
spec:
48+
volumes:
49+
- name: vol
50+
persistentVolumeClaim:
51+
claimName: test-pvc
52+
containers:
53+
- name: nginx
54+
image: nginx:1.14.2
55+
ports:
56+
- containerPort: 80
57+
volumeMounts:
58+
- mountPath: "/vol"
59+
name: vol

pkg/common/parameters.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ func ExtractModifyVolumeParameters(parameters map[string]string) (ModifyVolumePa
343343
}
344344
modifyVolumeParams.IOPS = &iops
345345
case "throughput":
346-
throughput, err := ConvertStringToInt64(value)
346+
throughput, err := ConvertMiStringToInt64(value)
347347
if err != nil {
348348
return ModifyVolumeParameters{}, fmt.Errorf("parameters contain invalid throughput parameter: %w", err)
349349
}

pkg/common/parameters_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ func TestSnapshotParameters(t *testing.T) {
485485
func TestExtractModifyVolumeParameters(t *testing.T) {
486486
parameters := map[string]string{
487487
"iops": "1000",
488-
"throughput": "500",
488+
"throughput": "500Mi",
489489
}
490490

491491
iops := int64(1000)

pkg/gce-pd-csi-driver/controller_test.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -1789,7 +1789,7 @@ func TestCreateVolumeWithVolumeAttributeClassParameters(t *testing.T) {
17891789
},
17901790
},
17911791
},
1792-
MutableParameters: map[string]string{"iops": "20000", "throughput": "600"},
1792+
MutableParameters: map[string]string{"iops": "20000", "throughput": "600Mi"},
17931793
},
17941794
expIops: 20000,
17951795
expThroughput: 600,
@@ -1822,7 +1822,7 @@ func TestCreateVolumeWithVolumeAttributeClassParameters(t *testing.T) {
18221822
},
18231823
},
18241824
},
1825-
MutableParameters: map[string]string{"iops": "20000", "throughput": "600"},
1825+
MutableParameters: map[string]string{"iops": "20000", "throughput": "600Mi"},
18261826
},
18271827
expIops: 0,
18281828
expThroughput: 0,
@@ -1890,7 +1890,7 @@ func TestVolumeModifyOperation(t *testing.T) {
18901890
name: "Update volume with valid parameters",
18911891
req: &csi.ControllerModifyVolumeRequest{
18921892
VolumeId: testVolumeID,
1893-
MutableParameters: map[string]string{"iops": "20000", "throughput": "600"},
1893+
MutableParameters: map[string]string{"iops": "20000", "throughput": "600Mi"},
18941894
},
18951895
diskType: "hyperdisk-balanced",
18961896
params: &common.DiskParameters{
@@ -1906,7 +1906,7 @@ func TestVolumeModifyOperation(t *testing.T) {
19061906
name: "Update volume with invalid parameters",
19071907
req: &csi.ControllerModifyVolumeRequest{
19081908
VolumeId: testVolumeID,
1909-
MutableParameters: map[string]string{"iops": "0", "throughput": "0"},
1909+
MutableParameters: map[string]string{"iops": "0", "throughput": "0Mi"},
19101910
},
19111911
diskType: "hyperdisk-balanced",
19121912
params: &common.DiskParameters{
@@ -1922,7 +1922,7 @@ func TestVolumeModifyOperation(t *testing.T) {
19221922
name: "Update volume with valid parameters but invalid disk type",
19231923
req: &csi.ControllerModifyVolumeRequest{
19241924
VolumeId: testVolumeID,
1925-
MutableParameters: map[string]string{"iops": "20000", "throughput": "600"},
1925+
MutableParameters: map[string]string{"iops": "20000", "throughput": "600Mi"},
19261926
},
19271927
diskType: "pd-ssd",
19281928
params: &common.DiskParameters{
@@ -2053,7 +2053,7 @@ func TestVolumeModifyErrorHandling(t *testing.T) {
20532053
},
20542054
},
20552055
modifyReq: &csi.ControllerModifyVolumeRequest{
2056-
MutableParameters: map[string]string{"iops": "3001", "throughput": "151"},
2056+
MutableParameters: map[string]string{"iops": "3001", "throughput": "151Mi"},
20572057
},
20582058
modifyVolumeErrors: map[*meta.Key]error{
20592059
meta.ZonalKey(name, "us-central1-a"): &googleapi.Error{
@@ -2089,7 +2089,7 @@ func TestVolumeModifyErrorHandling(t *testing.T) {
20892089
},
20902090
},
20912091
modifyReq: &csi.ControllerModifyVolumeRequest{
2092-
MutableParameters: map[string]string{"iops": "10000", "throughput": "2400"},
2092+
MutableParameters: map[string]string{"iops": "10000", "throughput": "2400Mi"},
20932093
},
20942094
modifyVolumeErrors: map[*meta.Key]error{
20952095
meta.ZonalKey(name, "us-central1-a"): &googleapi.Error{Code: int(codes.InvalidArgument), Message: "InvalidArgument"},

test/e2e/tests/single_zone_e2e_test.go

+186-20
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ package tests
1717
import (
1818
"context"
1919
"fmt"
20+
"os"
2021
"path/filepath"
2122
"regexp"
23+
"strconv"
2224
"strings"
2325
"time"
2426

@@ -44,26 +46,36 @@ import (
4446
const (
4547
testNamePrefix = "gcepd-csi-e2e-"
4648

47-
defaultSizeGb int64 = 5
48-
defaultExtremeSizeGb int64 = 500
49-
defaultHdTSizeGb int64 = 2048
50-
defaultHdmlSizeGb int64 = 200
51-
defaultRepdSizeGb int64 = 200
52-
defaultMwSizeGb int64 = 200
53-
defaultVolumeLimit int64 = 127
54-
invalidSizeGb int64 = 66000
55-
readyState = "READY"
56-
standardDiskType = "pd-standard"
57-
ssdDiskType = "pd-ssd"
58-
extremeDiskType = "pd-extreme"
59-
hdtDiskType = "hyperdisk-throughput"
60-
hdmlDiskType = "hyperdisk-ml"
61-
provisionedIOPSOnCreate = "12345"
62-
provisionedIOPSOnCreateInt = int64(12345)
63-
provisionedIOPSOnCreateDefaultInt = int64(100000)
64-
provisionedThroughputOnCreate = "66Mi"
65-
provisionedThroughputOnCreateInt = int64(66)
66-
defaultEpsilon = 500000000 // 500M
49+
defaultSizeGb int64 = 5
50+
defaultExtremeSizeGb int64 = 500
51+
defaultHdBSizeGb int64 = 100
52+
defaultHdXSizeGb int64 = 100
53+
defaultHdTSizeGb int64 = 2048
54+
defaultHdmlSizeGb int64 = 200
55+
defaultRepdSizeGb int64 = 200
56+
defaultMwSizeGb int64 = 200
57+
defaultVolumeLimit int64 = 127
58+
invalidSizeGb int64 = 66000
59+
readyState = "READY"
60+
standardDiskType = "pd-standard"
61+
ssdDiskType = "pd-ssd"
62+
extremeDiskType = "pd-extreme"
63+
hdbDiskType = "hyperdisk-balanced"
64+
hdxDiskType = "hyperdisk-extreme"
65+
hdtDiskType = "hyperdisk-throughput"
66+
hdmlDiskType = "hyperdisk-ml"
67+
provisionedIOPSOnCreate = "12345"
68+
provisionedIOPSOnCreateInt = int64(12345)
69+
provisionedIOPSOnCreateDefaultInt = int64(100000)
70+
provisionedIOPSOnCreateHdb = "3000"
71+
provisionedIOPSOnCreateHdbInt = int64(3000)
72+
provisionedIOPSOnCreateHdx = "200"
73+
provisionedIOPSOnCreateHdxInt = int64(200)
74+
provisionedThroughputOnCreate = "66Mi"
75+
provisionedThroughputOnCreateInt = int64(66)
76+
provisionedThroughputOnCreateHdb = "150Mi"
77+
provisionedThroughputOnCreateHdbInt = int64(150)
78+
defaultEpsilon = 500000000 // 500M
6779
)
6880

6981
var _ = Describe("GCE PD CSI Driver", func() {
@@ -1549,6 +1561,88 @@ var _ = Describe("GCE PD CSI Driver", func() {
15491561
Entry("with missing multi-zone label", multiZoneTestConfig{diskType: standardDiskType, readOnly: true, hasMultiZoneLabel: false, wantErrSubstring: "points to disk that is missing label \"goog-gke-multi-zone\""}),
15501562
Entry("with unsupported disk-type pd-extreme", multiZoneTestConfig{diskType: extremeDiskType, readOnly: true, hasMultiZoneLabel: true, wantErrSubstring: "points to disk with unsupported disk type"}),
15511563
)
1564+
1565+
// Mark tests as pending while VolumeAttributesClasses are in beta
1566+
DescribeTable("Should update metadata when providing valid metadata",
1567+
func(
1568+
diskType string,
1569+
diskSize int64,
1570+
initialIops *string,
1571+
initialThroughput *string,
1572+
updatedIops *string,
1573+
updatedThroughput *string,
1574+
) {
1575+
if !runCMVTests() {
1576+
Skip("Not running ControllerModifyVolume tests, as RUN_CONTROLLER_MODIFY_VOLUME_TESTS is falsy")
1577+
}
1578+
Expect(testContexts).ToNot(BeEmpty())
1579+
testContext := getRandomTestContext()
1580+
1581+
client := testContext.Client
1582+
instance := testContext.Instance
1583+
p, z, _ := instance.GetIdentity()
1584+
1585+
volName, volId := createAndValidateUniqueZonalDisk(client, p, z, diskType)
1586+
defer func() {
1587+
err := client.DeleteVolume(volId)
1588+
Expect(err).To(BeNil(), "DeleteVolume failed")
1589+
}()
1590+
1591+
// Validate disk created
1592+
_, err := computeService.Disks.Get(p, z, volName).Do()
1593+
Expect(err).To(BeNil(), "Could not get disk from cloud directly")
1594+
1595+
mutableParams := map[string]string{}
1596+
if updatedIops != nil {
1597+
mutableParams["iops"] = *updatedIops
1598+
}
1599+
if updatedThroughput != nil {
1600+
mutableParams["throughput"] = *updatedThroughput
1601+
}
1602+
err = client.ControllerModifyVolume(volId, mutableParams)
1603+
Expect(err).To(BeNil(), "Expected ControllerModifyVolume to succeed")
1604+
1605+
err = waitForMetadataUpdate(6, p, z, volName, initialIops, initialThroughput)
1606+
Expect(err).To(BeNil(), "Expected ControllerModifyVolume to update metadata")
1607+
1608+
// Assert ControllerModifyVolume successfully updated metadata
1609+
disk, err := computeService.Disks.Get(p, z, volName).Do()
1610+
Expect(err).To(BeNil(), "Could not get disk from cloud directly")
1611+
if updatedIops != nil {
1612+
Expect(strconv.FormatInt(disk.ProvisionedIops, 10)).To(Equal(*updatedIops))
1613+
}
1614+
if updatedThroughput != nil {
1615+
Expect(strconv.FormatInt(disk.ProvisionedThroughput, 10)).To(Equal(*updatedThroughput))
1616+
}
1617+
},
1618+
Entry(
1619+
"for hyperdisk-balanced",
1620+
hdbDiskType,
1621+
defaultHdBSizeGb,
1622+
stringPtr(provisionedIOPSOnCreateHdb),
1623+
stringPtr(provisionedThroughputOnCreateHdb),
1624+
stringPtr("3013"),
1625+
stringPtr("181Mi"),
1626+
),
1627+
Entry(
1628+
"for hyperdisk-extreme",
1629+
hdxDiskType,
1630+
defaultHdXSizeGb,
1631+
stringPtr(provisionedIOPSOnCreateHdx),
1632+
nil,
1633+
stringPtr("250"),
1634+
nil,
1635+
),
1636+
Entry(
1637+
"for hyperdisk-throughput",
1638+
hdtDiskType,
1639+
defaultHdTSizeGb,
1640+
nil,
1641+
stringPtr(provisionedThroughputOnCreate),
1642+
nil,
1643+
stringPtr("70Mi"),
1644+
),
1645+
)
15521646
})
15531647

15541648
func equalWithinEpsilon(a, b, epsiolon int64) bool {
@@ -1571,6 +1665,10 @@ func createAndValidateZonalDisk(client *remote.CsiClient, project, zone string,
15711665
switch diskType {
15721666
case extremeDiskType:
15731667
diskSize = defaultExtremeSizeGb
1668+
case hdbDiskType:
1669+
diskSize = defaultHdBSizeGb
1670+
case hdxDiskType:
1671+
diskSize = defaultHdXSizeGb
15741672
case hdtDiskType:
15751673
diskSize = defaultHdTSizeGb
15761674
case hdmlDiskType:
@@ -1737,6 +1835,28 @@ var typeToDisk = map[string]*disk{
17371835
Expect(disk.ProvisionedIops).To(Equal(provisionedIOPSOnCreateInt))
17381836
},
17391837
},
1838+
hdbDiskType: {
1839+
params: map[string]string{
1840+
common.ParameterKeyType: hdbDiskType,
1841+
common.ParameterKeyProvisionedIOPSOnCreate: provisionedIOPSOnCreateHdb,
1842+
common.ParameterKeyProvisionedThroughputOnCreate: provisionedThroughputOnCreateHdb,
1843+
},
1844+
validate: func(disk *compute.Disk) {
1845+
Expect(disk.Type).To(ContainSubstring(hdbDiskType))
1846+
Expect(disk.ProvisionedIops).To(Equal(provisionedIOPSOnCreateHdbInt))
1847+
Expect(disk.ProvisionedThroughput).To(Equal(provisionedThroughputOnCreateHdbInt))
1848+
},
1849+
},
1850+
hdxDiskType: {
1851+
params: map[string]string{
1852+
common.ParameterKeyType: hdxDiskType,
1853+
common.ParameterKeyProvisionedIOPSOnCreate: provisionedIOPSOnCreateHdx,
1854+
},
1855+
validate: func(disk *compute.Disk) {
1856+
Expect(disk.Type).To(ContainSubstring(hdxDiskType))
1857+
Expect(disk.ProvisionedIops).To(Equal(provisionedIOPSOnCreateHdxInt))
1858+
},
1859+
},
17401860
hdtDiskType: {
17411861
params: map[string]string{
17421862
common.ParameterKeyType: hdtDiskType,
@@ -1775,3 +1895,49 @@ func merge(a, b map[string]string) map[string]string {
17751895
}
17761896
return res
17771897
}
1898+
1899+
func runCMVTests() bool {
1900+
runCMVStr, ok := os.LookupEnv("RUN_CONTROLLER_MODIFY_VOLUME_TESTS")
1901+
if !ok {
1902+
return false
1903+
}
1904+
1905+
runCMVTests, err := strconv.ParseBool(runCMVStr)
1906+
if err != nil {
1907+
return false
1908+
}
1909+
1910+
return runCMVTests
1911+
}
1912+
1913+
func stringPtr(str string) *string {
1914+
return &str
1915+
}
1916+
1917+
// waitForMetadataUpdate tries to poll every minute until numMinutes and tests if IOPS/throughput are updated
1918+
func waitForMetadataUpdate(numMinutes int, project, zone, volName string, initialIops *string, initialThroughput *string) error {
1919+
backoff := wait.Backoff{
1920+
Duration: 1 * time.Minute,
1921+
Factor: 1.0,
1922+
Steps: numMinutes,
1923+
Cap: time.Duration(numMinutes) * time.Minute,
1924+
}
1925+
err := wait.ExponentialBackoffWithContext(context.Background(), backoff, func() (bool, error) {
1926+
disk, err := computeService.Disks.Get(project, zone, volName).Do()
1927+
if err != nil {
1928+
return false, nil
1929+
}
1930+
if initialIops != nil && strconv.FormatInt(disk.ProvisionedIops, 10) != *initialIops {
1931+
return true, nil
1932+
}
1933+
if initialThroughput != nil {
1934+
throughput := *initialThroughput
1935+
// Strip "Mi" from throughput
1936+
if len(throughput) > 2 && strconv.FormatInt(disk.ProvisionedThroughput, 10) != throughput[:len(throughput)-2] {
1937+
return true, nil
1938+
}
1939+
}
1940+
return false, nil
1941+
})
1942+
return err
1943+
}

test/k8s-integration/config/hdb-volumeattributesclass.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ metadata:
55
driverName: pd.csi.storage.gke.io
66
parameters:
77
iops: "3600"
8-
throughput: "290"
8+
throughput: "290Mi"

0 commit comments

Comments
 (0)