attacher_test.go 19 KB

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