@@ -17,8 +17,10 @@ package tests
1717import (
1818 "context"
1919 "fmt"
20+ "os"
2021 "path/filepath"
2122 "regexp"
23+ "strconv"
2224 "strings"
2325 "time"
2426
@@ -44,26 +46,36 @@ import (
4446const (
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
6981var _ = 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 ("181" ),
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 ("70" ),
1644+ ),
1645+ )
15521646})
15531647
15541648func 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+ }
0 commit comments