@@ -17,8 +17,10 @@ package tests
17
17
import (
18
18
"context"
19
19
"fmt"
20
+ "os"
20
21
"path/filepath"
21
22
"regexp"
23
+ "strconv"
22
24
"strings"
23
25
"time"
24
26
@@ -44,26 +46,36 @@ import (
44
46
const (
45
47
testNamePrefix = "gcepd-csi-e2e-"
46
48
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
67
79
)
68
80
69
81
var _ = Describe ("GCE PD CSI Driver" , func () {
@@ -1549,6 +1561,88 @@ var _ = Describe("GCE PD CSI Driver", func() {
1549
1561
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\" " }),
1550
1562
Entry ("with unsupported disk-type pd-extreme" , multiZoneTestConfig {diskType : extremeDiskType , readOnly : true , hasMultiZoneLabel : true , wantErrSubstring : "points to disk with unsupported disk type" }),
1551
1563
)
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
+ )
1552
1646
})
1553
1647
1554
1648
func equalWithinEpsilon (a , b , epsiolon int64 ) bool {
@@ -1571,6 +1665,10 @@ func createAndValidateZonalDisk(client *remote.CsiClient, project, zone string,
1571
1665
switch diskType {
1572
1666
case extremeDiskType :
1573
1667
diskSize = defaultExtremeSizeGb
1668
+ case hdbDiskType :
1669
+ diskSize = defaultHdBSizeGb
1670
+ case hdxDiskType :
1671
+ diskSize = defaultHdXSizeGb
1574
1672
case hdtDiskType :
1575
1673
diskSize = defaultHdTSizeGb
1576
1674
case hdmlDiskType :
@@ -1737,6 +1835,28 @@ var typeToDisk = map[string]*disk{
1737
1835
Expect (disk .ProvisionedIops ).To (Equal (provisionedIOPSOnCreateInt ))
1738
1836
},
1739
1837
},
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
+ },
1740
1860
hdtDiskType : {
1741
1861
params : map [string ]string {
1742
1862
common .ParameterKeyType : hdtDiskType ,
@@ -1775,3 +1895,49 @@ func merge(a, b map[string]string) map[string]string {
1775
1895
}
1776
1896
return res
1777
1897
}
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
+ }
0 commit comments