attacher_test.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. /*
  2. Copyright 2016 The Kubernetes Authors.
  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. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package gcepd
  14. import (
  15. "errors"
  16. "fmt"
  17. "testing"
  18. "k8s.io/api/core/v1"
  19. "k8s.io/apimachinery/pkg/api/resource"
  20. "k8s.io/apimachinery/pkg/util/sets"
  21. cloudprovider "k8s.io/cloud-provider"
  22. cloudvolume "k8s.io/cloud-provider/volume"
  23. "k8s.io/kubernetes/pkg/volume"
  24. volumetest "k8s.io/kubernetes/pkg/volume/testing"
  25. "k8s.io/apimachinery/pkg/types"
  26. "k8s.io/klog"
  27. "strings"
  28. )
  29. func TestGetDeviceName_Volume(t *testing.T) {
  30. plugin := newPlugin()
  31. name := "my-pd-volume"
  32. spec := createVolSpec(name, false)
  33. deviceName, err := plugin.GetVolumeName(spec)
  34. if err != nil {
  35. t.Errorf("GetDeviceName error: %v", err)
  36. }
  37. if deviceName != name {
  38. t.Errorf("GetDeviceName error: expected %s, got %s", name, deviceName)
  39. }
  40. }
  41. func TestGetDeviceName_PersistentVolume(t *testing.T) {
  42. plugin := newPlugin()
  43. name := "my-pd-pv"
  44. spec := createPVSpec(name, true, nil)
  45. deviceName, err := plugin.GetVolumeName(spec)
  46. if err != nil {
  47. t.Errorf("GetDeviceName error: %v", err)
  48. }
  49. if deviceName != name {
  50. t.Errorf("GetDeviceName error: expected %s, got %s", name, deviceName)
  51. }
  52. }
  53. // One testcase for TestAttachDetach table test below
  54. type testcase struct {
  55. name string
  56. // For fake GCE:
  57. attach attachCall
  58. detach detachCall
  59. diskIsAttached diskIsAttachedCall
  60. t *testing.T
  61. // Actual test to run
  62. test func(test *testcase) error
  63. // Expected return of the test
  64. expectedReturn error
  65. }
  66. func TestAttachDetachRegional(t *testing.T) {
  67. diskName := "disk"
  68. nodeName := types.NodeName("instance")
  69. readOnly := false
  70. regional := true
  71. spec := createPVSpec(diskName, readOnly, []string{"zone1", "zone2"})
  72. // Successful Attach call
  73. testcase := testcase{
  74. name: "Attach_Regional_Positive",
  75. diskIsAttached: diskIsAttachedCall{disksAttachedMap{nodeName: {diskName}}, nil},
  76. attach: attachCall{diskName, nodeName, readOnly, regional, nil},
  77. test: func(testcase *testcase) error {
  78. attacher := newAttacher(testcase)
  79. devicePath, err := attacher.Attach(spec, nodeName)
  80. if devicePath != "/dev/disk/by-id/google-disk" {
  81. return fmt.Errorf("devicePath incorrect. Expected<\"/dev/disk/by-id/google-disk\"> Actual: <%q>", devicePath)
  82. }
  83. return err
  84. },
  85. }
  86. err := testcase.test(&testcase)
  87. if err != testcase.expectedReturn {
  88. t.Errorf("%s failed: expected err=%v, got %v", testcase.name, testcase.expectedReturn, err)
  89. }
  90. }
  91. func TestAttachDetach(t *testing.T) {
  92. diskName := "disk"
  93. nodeName := types.NodeName("instance")
  94. readOnly := false
  95. regional := false
  96. spec := createVolSpec(diskName, readOnly)
  97. attachError := errors.New("Fake attach error")
  98. detachError := errors.New("Fake detach error")
  99. diskCheckError := errors.New("Fake DiskIsAttached error")
  100. tests := []testcase{
  101. // Successful Attach call
  102. {
  103. name: "Attach_Positive",
  104. diskIsAttached: diskIsAttachedCall{disksAttachedMap{nodeName: {}}, nil},
  105. attach: attachCall{diskName, nodeName, readOnly, regional, nil},
  106. test: func(testcase *testcase) error {
  107. attacher := newAttacher(testcase)
  108. devicePath, err := attacher.Attach(spec, nodeName)
  109. if devicePath != "/dev/disk/by-id/google-disk" {
  110. return fmt.Errorf("devicePath incorrect. Expected<\"/dev/disk/by-id/google-disk\"> Actual: <%q>", devicePath)
  111. }
  112. return err
  113. },
  114. },
  115. // Disk is already attached
  116. {
  117. name: "Attach_Positive_AlreadyAttached",
  118. diskIsAttached: diskIsAttachedCall{disksAttachedMap{nodeName: {diskName}}, nil},
  119. test: func(testcase *testcase) error {
  120. attacher := newAttacher(testcase)
  121. devicePath, err := attacher.Attach(spec, nodeName)
  122. if devicePath != "/dev/disk/by-id/google-disk" {
  123. return fmt.Errorf("devicePath incorrect. Expected<\"/dev/disk/by-id/google-disk\"> Actual: <%q>", devicePath)
  124. }
  125. return err
  126. },
  127. },
  128. // DiskIsAttached fails and Attach succeeds
  129. {
  130. name: "Attach_Positive_CheckFails",
  131. diskIsAttached: diskIsAttachedCall{disksAttachedMap{nodeName: {}}, diskCheckError},
  132. attach: attachCall{diskName, nodeName, readOnly, regional, nil},
  133. test: func(testcase *testcase) error {
  134. attacher := newAttacher(testcase)
  135. devicePath, err := attacher.Attach(spec, nodeName)
  136. if devicePath != "/dev/disk/by-id/google-disk" {
  137. return fmt.Errorf("devicePath incorrect. Expected<\"/dev/disk/by-id/google-disk\"> Actual: <%q>", devicePath)
  138. }
  139. return err
  140. },
  141. },
  142. // Attach call fails
  143. {
  144. name: "Attach_Negative",
  145. diskIsAttached: diskIsAttachedCall{disksAttachedMap{nodeName: {}}, diskCheckError},
  146. attach: attachCall{diskName, nodeName, readOnly, regional, attachError},
  147. test: func(testcase *testcase) error {
  148. attacher := newAttacher(testcase)
  149. devicePath, err := attacher.Attach(spec, nodeName)
  150. if devicePath != "" {
  151. return fmt.Errorf("devicePath incorrect. Expected<\"\"> Actual: <%q>", devicePath)
  152. }
  153. return err
  154. },
  155. expectedReturn: attachError,
  156. },
  157. // Detach succeeds
  158. {
  159. name: "Detach_Positive",
  160. diskIsAttached: diskIsAttachedCall{disksAttachedMap{nodeName: {diskName}}, nil},
  161. detach: detachCall{diskName, nodeName, nil},
  162. test: func(testcase *testcase) error {
  163. detacher := newDetacher(testcase)
  164. return detacher.Detach(diskName, nodeName)
  165. },
  166. },
  167. // Disk is already detached
  168. {
  169. name: "Detach_Positive_AlreadyDetached",
  170. diskIsAttached: diskIsAttachedCall{disksAttachedMap{nodeName: {}}, nil},
  171. test: func(testcase *testcase) error {
  172. detacher := newDetacher(testcase)
  173. return detacher.Detach(diskName, nodeName)
  174. },
  175. },
  176. // Detach succeeds when DiskIsAttached fails
  177. {
  178. name: "Detach_Positive_CheckFails",
  179. diskIsAttached: diskIsAttachedCall{disksAttachedMap{nodeName: {}}, diskCheckError},
  180. detach: detachCall{diskName, nodeName, nil},
  181. test: func(testcase *testcase) error {
  182. detacher := newDetacher(testcase)
  183. return detacher.Detach(diskName, nodeName)
  184. },
  185. },
  186. // Detach fails
  187. {
  188. name: "Detach_Negative",
  189. diskIsAttached: diskIsAttachedCall{disksAttachedMap{nodeName: {}}, diskCheckError},
  190. detach: detachCall{diskName, nodeName, detachError},
  191. test: func(testcase *testcase) error {
  192. detacher := newDetacher(testcase)
  193. return detacher.Detach(diskName, nodeName)
  194. },
  195. expectedReturn: detachError,
  196. },
  197. }
  198. for _, testcase := range tests {
  199. testcase.t = t
  200. err := testcase.test(&testcase)
  201. if err != testcase.expectedReturn {
  202. t.Errorf("%s failed: expected err=%v, got %v", testcase.name, testcase.expectedReturn, err)
  203. }
  204. }
  205. }
  206. func TestVerifyVolumesAttached(t *testing.T) {
  207. readOnly := false
  208. nodeName1 := types.NodeName("instance1")
  209. nodeName2 := types.NodeName("instance2")
  210. diskAName := "diskA"
  211. diskBName := "diskB"
  212. diskCName := "diskC"
  213. diskASpec := createVolSpec(diskAName, readOnly)
  214. diskBSpec := createVolSpec(diskBName, readOnly)
  215. diskCSpec := createVolSpec(diskCName, readOnly)
  216. verifyDiskAttachedInResult := func(results map[*volume.Spec]bool, spec *volume.Spec, expected bool) error {
  217. found, ok := results[spec]
  218. if !ok {
  219. return fmt.Errorf("expected to find volume %s in verifcation result, but didn't", spec.Name())
  220. }
  221. if found != expected {
  222. return fmt.Errorf("expected to find volume %s to be have attached value %v but got %v", spec.Name(), expected, found)
  223. }
  224. return nil
  225. }
  226. tests := []testcase{
  227. // Successful VolumesAreAttached
  228. {
  229. name: "VolumesAreAttached_Positive",
  230. diskIsAttached: diskIsAttachedCall{disksAttachedMap{nodeName1: {diskAName, diskBName}}, nil},
  231. test: func(testcase *testcase) error {
  232. attacher := newAttacher(testcase)
  233. results, err := attacher.VolumesAreAttached([]*volume.Spec{diskASpec, diskBSpec}, nodeName1)
  234. if err != nil {
  235. return err
  236. }
  237. err = verifyDiskAttachedInResult(results, diskASpec, true)
  238. if err != nil {
  239. return err
  240. }
  241. return verifyDiskAttachedInResult(results, diskBSpec, true)
  242. },
  243. },
  244. // Successful VolumesAreAttached for detached disk
  245. {
  246. name: "VolumesAreAttached_Negative",
  247. diskIsAttached: diskIsAttachedCall{disksAttachedMap{nodeName1: {diskAName}}, nil},
  248. test: func(testcase *testcase) error {
  249. attacher := newAttacher(testcase)
  250. results, err := attacher.VolumesAreAttached([]*volume.Spec{diskASpec, diskBSpec}, nodeName1)
  251. if err != nil {
  252. return err
  253. }
  254. err = verifyDiskAttachedInResult(results, diskASpec, true)
  255. if err != nil {
  256. return err
  257. }
  258. return verifyDiskAttachedInResult(results, diskBSpec, false)
  259. },
  260. },
  261. // VolumesAreAttached with InstanceNotFound
  262. {
  263. name: "VolumesAreAttached_InstanceNotFound",
  264. diskIsAttached: diskIsAttachedCall{disksAttachedMap{}, nil},
  265. expectedReturn: cloudprovider.InstanceNotFound,
  266. test: func(testcase *testcase) error {
  267. attacher := newAttacher(testcase)
  268. _, err := attacher.VolumesAreAttached([]*volume.Spec{diskASpec}, nodeName1)
  269. if err != cloudprovider.InstanceNotFound {
  270. return fmt.Errorf("expected InstanceNotFound error, but got %v", err)
  271. }
  272. return err
  273. },
  274. },
  275. // Successful BulkDisksAreAttached
  276. {
  277. name: "BulkDisksAreAttached_Positive",
  278. diskIsAttached: diskIsAttachedCall{disksAttachedMap{nodeName1: {diskAName}, nodeName2: {diskBName, diskCName}}, nil},
  279. test: func(testcase *testcase) error {
  280. attacher := newAttacher(testcase)
  281. results, err := attacher.BulkVerifyVolumes(map[types.NodeName][]*volume.Spec{nodeName1: {diskASpec}, nodeName2: {diskBSpec, diskCSpec}})
  282. if err != nil {
  283. return err
  284. }
  285. disksAttachedNode1, nodeFound := results[nodeName1]
  286. if !nodeFound {
  287. return fmt.Errorf("expected to find node %s but didn't", nodeName1)
  288. }
  289. if err := verifyDiskAttachedInResult(disksAttachedNode1, diskASpec, true); err != nil {
  290. return err
  291. }
  292. disksAttachedNode2, nodeFound := results[nodeName2]
  293. if !nodeFound {
  294. return fmt.Errorf("expected to find node %s but didn't", nodeName2)
  295. }
  296. if err := verifyDiskAttachedInResult(disksAttachedNode2, diskBSpec, true); err != nil {
  297. return err
  298. }
  299. return verifyDiskAttachedInResult(disksAttachedNode2, diskCSpec, true)
  300. },
  301. },
  302. // Successful BulkDisksAreAttached for detached disk
  303. {
  304. name: "BulkDisksAreAttached_Negative",
  305. diskIsAttached: diskIsAttachedCall{disksAttachedMap{nodeName1: {}, nodeName2: {diskBName}}, nil},
  306. test: func(testcase *testcase) error {
  307. attacher := newAttacher(testcase)
  308. results, err := attacher.BulkVerifyVolumes(map[types.NodeName][]*volume.Spec{nodeName1: {diskASpec}, nodeName2: {diskBSpec, diskCSpec}})
  309. if err != nil {
  310. return err
  311. }
  312. disksAttachedNode1, nodeFound := results[nodeName1]
  313. if !nodeFound {
  314. return fmt.Errorf("expected to find node %s but didn't", nodeName1)
  315. }
  316. if err := verifyDiskAttachedInResult(disksAttachedNode1, diskASpec, false); err != nil {
  317. return err
  318. }
  319. disksAttachedNode2, nodeFound := results[nodeName2]
  320. if !nodeFound {
  321. return fmt.Errorf("expected to find node %s but didn't", nodeName2)
  322. }
  323. if err := verifyDiskAttachedInResult(disksAttachedNode2, diskBSpec, true); err != nil {
  324. return err
  325. }
  326. return verifyDiskAttachedInResult(disksAttachedNode2, diskCSpec, false)
  327. },
  328. },
  329. // Successful BulkDisksAreAttached with InstanceNotFound
  330. {
  331. name: "BulkDisksAreAttached_InstanceNotFound",
  332. diskIsAttached: diskIsAttachedCall{disksAttachedMap{nodeName1: {diskAName}}, nil},
  333. test: func(testcase *testcase) error {
  334. attacher := newAttacher(testcase)
  335. results, err := attacher.BulkVerifyVolumes(map[types.NodeName][]*volume.Spec{nodeName1: {diskASpec}, nodeName2: {diskBSpec, diskCSpec}})
  336. if err != nil {
  337. return err
  338. }
  339. disksAttachedNode1, nodeFound := results[nodeName1]
  340. if !nodeFound {
  341. return fmt.Errorf("expected to find node %s but didn't", nodeName1)
  342. }
  343. if err := verifyDiskAttachedInResult(disksAttachedNode1, diskASpec, true); err != nil {
  344. return err
  345. }
  346. disksAttachedNode2, nodeFound := results[nodeName2]
  347. if !nodeFound {
  348. return fmt.Errorf("expected to find node %s but didn't", nodeName2)
  349. }
  350. if err := verifyDiskAttachedInResult(disksAttachedNode2, diskBSpec, false); err != nil {
  351. return err
  352. }
  353. return verifyDiskAttachedInResult(disksAttachedNode2, diskCSpec, false)
  354. },
  355. },
  356. }
  357. for _, testcase := range tests {
  358. testcase.t = t
  359. err := testcase.test(&testcase)
  360. if err != testcase.expectedReturn {
  361. t.Errorf("%s failed: expected err=%v, got %v", testcase.name, testcase.expectedReturn, err)
  362. }
  363. }
  364. }
  365. // newPlugin creates a new gcePersistentDiskPlugin with fake cloud, NewAttacher
  366. // and NewDetacher won't work.
  367. func newPlugin() *gcePersistentDiskPlugin {
  368. host := volumetest.NewFakeVolumeHost(
  369. "/tmp", /* rootDir */
  370. nil, /* kubeClient */
  371. nil, /* plugins */
  372. )
  373. plugins := ProbeVolumePlugins()
  374. plugin := plugins[0]
  375. plugin.Init(host)
  376. return plugin.(*gcePersistentDiskPlugin)
  377. }
  378. func newAttacher(testcase *testcase) *gcePersistentDiskAttacher {
  379. return &gcePersistentDiskAttacher{
  380. host: nil,
  381. gceDisks: testcase,
  382. }
  383. }
  384. func newDetacher(testcase *testcase) *gcePersistentDiskDetacher {
  385. return &gcePersistentDiskDetacher{
  386. gceDisks: testcase,
  387. }
  388. }
  389. func createVolSpec(name string, readOnly bool) *volume.Spec {
  390. return &volume.Spec{
  391. Volume: &v1.Volume{
  392. VolumeSource: v1.VolumeSource{
  393. GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{
  394. PDName: name,
  395. ReadOnly: readOnly,
  396. },
  397. },
  398. },
  399. }
  400. }
  401. func createPVSpec(name string, readOnly bool, zones []string) *volume.Spec {
  402. spec := &volume.Spec{
  403. PersistentVolume: &v1.PersistentVolume{
  404. Spec: v1.PersistentVolumeSpec{
  405. PersistentVolumeSource: v1.PersistentVolumeSource{
  406. GCEPersistentDisk: &v1.GCEPersistentDiskVolumeSource{
  407. PDName: name,
  408. ReadOnly: readOnly,
  409. },
  410. },
  411. },
  412. },
  413. }
  414. if zones != nil {
  415. zonesLabel := strings.Join(zones, cloudvolume.LabelMultiZoneDelimiter)
  416. spec.PersistentVolume.ObjectMeta.Labels = map[string]string{
  417. v1.LabelZoneFailureDomain: zonesLabel,
  418. }
  419. }
  420. return spec
  421. }
  422. // Fake GCE implementation
  423. type attachCall struct {
  424. diskName string
  425. nodeName types.NodeName
  426. readOnly bool
  427. regional bool
  428. retErr error
  429. }
  430. type detachCall struct {
  431. devicePath string
  432. nodeName types.NodeName
  433. retErr error
  434. }
  435. type diskIsAttachedCall struct {
  436. attachedDisks disksAttachedMap
  437. retErr error
  438. }
  439. // disksAttachedMap specifies what disks in the test scenario are actually attached to each node
  440. type disksAttachedMap map[types.NodeName][]string
  441. func (testcase *testcase) AttachDisk(diskName string, nodeName types.NodeName, readOnly bool, regional bool) error {
  442. expected := &testcase.attach
  443. if expected.diskName == "" && expected.nodeName == "" {
  444. // testcase.attach looks uninitialized, test did not expect to call AttachDisk
  445. return errors.New("unexpected AttachDisk call")
  446. }
  447. if expected.diskName != diskName {
  448. return fmt.Errorf("Unexpected AttachDisk call: expected diskName %s, got %s", expected.diskName, diskName)
  449. }
  450. if expected.nodeName != nodeName {
  451. return fmt.Errorf("Unexpected AttachDisk call: expected nodeName %s, got %s", expected.nodeName, nodeName)
  452. }
  453. if expected.readOnly != readOnly {
  454. return fmt.Errorf("Unexpected AttachDisk call: expected readOnly %v, got %v", expected.readOnly, readOnly)
  455. }
  456. if expected.regional != regional {
  457. return fmt.Errorf("Unexpected AttachDisk call: expected regional %v, got %v", expected.regional, regional)
  458. }
  459. klog.V(4).Infof("AttachDisk call: %s, %s, %v, returning %v", diskName, nodeName, readOnly, expected.retErr)
  460. return expected.retErr
  461. }
  462. func (testcase *testcase) DetachDisk(devicePath string, nodeName types.NodeName) error {
  463. expected := &testcase.detach
  464. if expected.devicePath == "" && expected.nodeName == "" {
  465. // testcase.detach looks uninitialized, test did not expect to call DetachDisk
  466. return errors.New("unexpected DetachDisk call")
  467. }
  468. if expected.devicePath != devicePath {
  469. return fmt.Errorf("Unexpected DetachDisk call: expected devicePath %s, got %s", expected.devicePath, devicePath)
  470. }
  471. if expected.nodeName != nodeName {
  472. return fmt.Errorf("Unexpected DetachDisk call: expected nodeName %s, got %s", expected.nodeName, nodeName)
  473. }
  474. klog.V(4).Infof("DetachDisk call: %s, %s, returning %v", devicePath, nodeName, expected.retErr)
  475. return expected.retErr
  476. }
  477. func (testcase *testcase) DiskIsAttached(diskName string, nodeName types.NodeName) (bool, error) {
  478. expected := &testcase.diskIsAttached
  479. if expected.attachedDisks == nil {
  480. // testcase.attachedDisks looks uninitialized, test did not expect to call DiskIsAttached
  481. return false, errors.New("unexpected DiskIsAttached call")
  482. }
  483. if expected.retErr != nil {
  484. return false, expected.retErr
  485. }
  486. disksForNode, nodeExists := expected.attachedDisks[nodeName]
  487. if !nodeExists {
  488. return false, cloudprovider.InstanceNotFound
  489. }
  490. found := false
  491. for _, diskAttachedName := range disksForNode {
  492. if diskAttachedName == diskName {
  493. found = true
  494. }
  495. }
  496. klog.V(4).Infof("DiskIsAttached call: %s, %s, returning %v", diskName, nodeName, found)
  497. return found, nil
  498. }
  499. func (testcase *testcase) DisksAreAttached(diskNames []string, nodeName types.NodeName) (map[string]bool, error) {
  500. verifiedDisks := make(map[string]bool)
  501. for _, name := range diskNames {
  502. found, err := testcase.DiskIsAttached(name, nodeName)
  503. if err != nil {
  504. return nil, err
  505. }
  506. verifiedDisks[name] = found
  507. }
  508. return verifiedDisks, nil
  509. }
  510. func (testcase *testcase) BulkDisksAreAttached(diskByNodes map[types.NodeName][]string) (map[types.NodeName]map[string]bool, error) {
  511. verifiedDisksByNodes := make(map[types.NodeName]map[string]bool)
  512. for nodeName, disksForNode := range diskByNodes {
  513. verifiedDisks, err := testcase.DisksAreAttached(disksForNode, nodeName)
  514. if err != nil {
  515. if err != cloudprovider.InstanceNotFound {
  516. return nil, err
  517. }
  518. verifiedDisks = make(map[string]bool)
  519. for _, diskName := range disksForNode {
  520. verifiedDisks[diskName] = false
  521. }
  522. }
  523. verifiedDisksByNodes[nodeName] = verifiedDisks
  524. }
  525. return verifiedDisksByNodes, nil
  526. }
  527. func (testcase *testcase) CreateDisk(name string, diskType string, zone string, sizeGb int64, tags map[string]string) error {
  528. return errors.New("Not implemented")
  529. }
  530. func (testcase *testcase) CreateRegionalDisk(name string, diskType string, replicaZones sets.String, sizeGb int64, tags map[string]string) error {
  531. return errors.New("Not implemented")
  532. }
  533. func (testcase *testcase) DeleteDisk(diskToDelete string) error {
  534. return errors.New("Not implemented")
  535. }
  536. func (testcase *testcase) GetAutoLabelsForPD(name string, zone string) (map[string]string, error) {
  537. return map[string]string{}, errors.New("Not implemented")
  538. }
  539. func (testcase *testcase) ResizeDisk(
  540. diskName string,
  541. oldSize resource.Quantity,
  542. newSize resource.Quantity) (resource.Quantity, error) {
  543. return oldSize, errors.New("Not implemented")
  544. }