attacher_test.go 19 KB

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