testing.go 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773
  1. /*
  2. Copyright 2014 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 testing
  14. import (
  15. "context"
  16. "fmt"
  17. "net"
  18. "os"
  19. "path/filepath"
  20. "strings"
  21. "sync"
  22. "testing"
  23. "time"
  24. "k8s.io/utils/exec"
  25. testingexec "k8s.io/utils/exec/testing"
  26. "k8s.io/utils/mount"
  27. utilstrings "k8s.io/utils/strings"
  28. authenticationv1 "k8s.io/api/authentication/v1"
  29. v1 "k8s.io/api/core/v1"
  30. "k8s.io/apimachinery/pkg/api/resource"
  31. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  32. "k8s.io/apimachinery/pkg/types"
  33. "k8s.io/apimachinery/pkg/util/uuid"
  34. "k8s.io/apimachinery/pkg/util/wait"
  35. "k8s.io/client-go/informers"
  36. clientset "k8s.io/client-go/kubernetes"
  37. storagelistersv1 "k8s.io/client-go/listers/storage/v1"
  38. storagelisters "k8s.io/client-go/listers/storage/v1beta1"
  39. "k8s.io/client-go/tools/cache"
  40. "k8s.io/client-go/tools/record"
  41. utiltesting "k8s.io/client-go/util/testing"
  42. cloudprovider "k8s.io/cloud-provider"
  43. . "k8s.io/kubernetes/pkg/volume"
  44. "k8s.io/kubernetes/pkg/volume/util"
  45. "k8s.io/kubernetes/pkg/volume/util/hostutil"
  46. "k8s.io/kubernetes/pkg/volume/util/recyclerclient"
  47. "k8s.io/kubernetes/pkg/volume/util/subpath"
  48. volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
  49. "k8s.io/kubernetes/pkg/volume/util/volumepathhandler"
  50. )
  51. const (
  52. // A hook specified in storage class to indicate it's provisioning
  53. // is expected to fail.
  54. ExpectProvisionFailureKey = "expect-provision-failure"
  55. // The node is marked as uncertain. The attach operation will fail and return timeout error
  56. // for the first attach call. The following call will return sucesssfully.
  57. UncertainAttachNode = "uncertain-attach-node"
  58. // The node is marked as timeout. The attach operation will always fail and return timeout error
  59. // but the operation is actually succeeded.
  60. TimeoutAttachNode = "timeout-attach-node"
  61. // The node is marked as multi-attach which means it is allowed to attach the volume to multiple nodes.
  62. MultiAttachNode = "multi-attach-node"
  63. // TimeoutOnSetupVolumeName will cause Setup call to timeout but volume will finish mounting.
  64. TimeoutOnSetupVolumeName = "timeout-setup-volume"
  65. // FailOnSetupVolumeName will cause setup call to fail
  66. FailOnSetupVolumeName = "fail-setup-volume"
  67. //TimeoutAndFailOnSetupVolumeName will first timeout and then fail the setup
  68. TimeoutAndFailOnSetupVolumeName = "timeout-and-fail-setup-volume"
  69. // SuccessAndTimeoutSetupVolumeName will cause first mount operation to succeed but subsequent attempts to timeout
  70. SuccessAndTimeoutSetupVolumeName = "success-and-timeout-setup-volume-name"
  71. // SuccessAndFailOnSetupVolumeName will cause first mount operation to succeed but subsequent attempts to fail
  72. SuccessAndFailOnSetupVolumeName = "success-and-failed-setup-device-name"
  73. // TimeoutOnMountDeviceVolumeName will cause MountDevice call to timeout but Setup will finish.
  74. TimeoutOnMountDeviceVolumeName = "timeout-mount-device-volume"
  75. // TimeoutAndFailOnMountDeviceVolumeName will cause first MountDevice call to timeout but second call will fail
  76. TimeoutAndFailOnMountDeviceVolumeName = "timeout-and-fail-mount-device-name"
  77. // FailMountDeviceVolumeName will cause MountDevice operation on volume to fail
  78. FailMountDeviceVolumeName = "fail-mount-device-volume-name"
  79. // SuccessAndTimeoutDeviceName will cause first mount operation to succeed but subsequent attempts to timeout
  80. SuccessAndTimeoutDeviceName = "success-and-timeout-device-name"
  81. // SuccessAndFailOnMountDeviceName will cause first mount operation to succeed but subsequent attempts to fail
  82. SuccessAndFailOnMountDeviceName = "success-and-failed-mount-device-name"
  83. deviceNotMounted = "deviceNotMounted"
  84. deviceMountUncertain = "deviceMountUncertain"
  85. deviceMounted = "deviceMounted"
  86. volumeNotMounted = "volumeNotMounted"
  87. volumeMountUncertain = "volumeMountUncertain"
  88. volumeMounted = "volumeMounted"
  89. )
  90. // fakeVolumeHost is useful for testing volume plugins.
  91. type fakeVolumeHost struct {
  92. rootDir string
  93. kubeClient clientset.Interface
  94. pluginMgr *VolumePluginMgr
  95. cloud cloudprovider.Interface
  96. mounter mount.Interface
  97. hostUtil hostutil.HostUtils
  98. exec *testingexec.FakeExec
  99. nodeLabels map[string]string
  100. nodeName string
  101. subpather subpath.Interface
  102. csiDriverLister storagelisters.CSIDriverLister
  103. informerFactory informers.SharedInformerFactory
  104. kubeletErr error
  105. mux sync.Mutex
  106. }
  107. var _ VolumeHost = &fakeVolumeHost{}
  108. var _ AttachDetachVolumeHost = &fakeVolumeHost{}
  109. func NewFakeVolumeHost(t *testing.T, rootDir string, kubeClient clientset.Interface, plugins []VolumePlugin) *fakeVolumeHost {
  110. return newFakeVolumeHost(t, rootDir, kubeClient, plugins, nil, nil, "", nil)
  111. }
  112. func NewFakeVolumeHostWithCloudProvider(t *testing.T, rootDir string, kubeClient clientset.Interface, plugins []VolumePlugin, cloud cloudprovider.Interface) *fakeVolumeHost {
  113. return newFakeVolumeHost(t, rootDir, kubeClient, plugins, cloud, nil, "", nil)
  114. }
  115. func NewFakeVolumeHostWithNodeLabels(t *testing.T, rootDir string, kubeClient clientset.Interface, plugins []VolumePlugin, labels map[string]string) *fakeVolumeHost {
  116. volHost := newFakeVolumeHost(t, rootDir, kubeClient, plugins, nil, nil, "", nil)
  117. volHost.nodeLabels = labels
  118. return volHost
  119. }
  120. func NewFakeVolumeHostWithCSINodeName(t *testing.T, rootDir string, kubeClient clientset.Interface, plugins []VolumePlugin, nodeName string, driverLister storagelisters.CSIDriverLister) *fakeVolumeHost {
  121. return newFakeVolumeHost(t, rootDir, kubeClient, plugins, nil, nil, nodeName, driverLister)
  122. }
  123. func NewFakeVolumeHostWithMounterFSType(t *testing.T, rootDir string, kubeClient clientset.Interface, plugins []VolumePlugin, pathToTypeMap map[string]hostutil.FileType) *fakeVolumeHost {
  124. return newFakeVolumeHost(t, rootDir, kubeClient, plugins, nil, pathToTypeMap, "", nil)
  125. }
  126. func newFakeVolumeHost(t *testing.T, rootDir string, kubeClient clientset.Interface, plugins []VolumePlugin, cloud cloudprovider.Interface, pathToTypeMap map[string]hostutil.FileType, nodeName string, driverLister storagelisters.CSIDriverLister) *fakeVolumeHost {
  127. host := &fakeVolumeHost{rootDir: rootDir, kubeClient: kubeClient, cloud: cloud, nodeName: nodeName, csiDriverLister: driverLister}
  128. host.mounter = mount.NewFakeMounter(nil)
  129. host.hostUtil = hostutil.NewFakeHostUtil(pathToTypeMap)
  130. host.exec = &testingexec.FakeExec{DisableScripts: true}
  131. host.pluginMgr = &VolumePluginMgr{}
  132. if err := host.pluginMgr.InitPlugins(plugins, nil /* prober */, host); err != nil {
  133. t.Fatalf("Failed to init plugins while creating fake volume host: %v", err)
  134. }
  135. host.subpather = &subpath.FakeSubpath{}
  136. host.informerFactory = informers.NewSharedInformerFactory(kubeClient, time.Minute)
  137. // Wait until the InitPlugins setup is finished before returning from this setup func
  138. if err := host.WaitForKubeletErrNil(); err != nil {
  139. t.Fatalf("Failed to wait for kubelet err to be nil while creating fake volume host: %v", err)
  140. }
  141. return host
  142. }
  143. func (f *fakeVolumeHost) GetPluginDir(podUID string) string {
  144. return filepath.Join(f.rootDir, "plugins", podUID)
  145. }
  146. func (f *fakeVolumeHost) GetVolumeDevicePluginDir(pluginName string) string {
  147. return filepath.Join(f.rootDir, "plugins", pluginName, "volumeDevices")
  148. }
  149. func (f *fakeVolumeHost) GetPodsDir() string {
  150. return filepath.Join(f.rootDir, "pods")
  151. }
  152. func (f *fakeVolumeHost) GetPodVolumeDir(podUID types.UID, pluginName, volumeName string) string {
  153. return filepath.Join(f.rootDir, "pods", string(podUID), "volumes", pluginName, volumeName)
  154. }
  155. func (f *fakeVolumeHost) GetPodVolumeDeviceDir(podUID types.UID, pluginName string) string {
  156. return filepath.Join(f.rootDir, "pods", string(podUID), "volumeDevices", pluginName)
  157. }
  158. func (f *fakeVolumeHost) GetPodPluginDir(podUID types.UID, pluginName string) string {
  159. return filepath.Join(f.rootDir, "pods", string(podUID), "plugins", pluginName)
  160. }
  161. func (f *fakeVolumeHost) GetKubeClient() clientset.Interface {
  162. return f.kubeClient
  163. }
  164. func (f *fakeVolumeHost) GetCloudProvider() cloudprovider.Interface {
  165. return f.cloud
  166. }
  167. func (f *fakeVolumeHost) GetMounter(pluginName string) mount.Interface {
  168. return f.mounter
  169. }
  170. func (f *fakeVolumeHost) GetHostUtil() hostutil.HostUtils {
  171. return f.hostUtil
  172. }
  173. func (f *fakeVolumeHost) GetSubpather() subpath.Interface {
  174. return f.subpather
  175. }
  176. func (f *fakeVolumeHost) GetPluginMgr() *VolumePluginMgr {
  177. return f.pluginMgr
  178. }
  179. func (f *fakeVolumeHost) NewWrapperMounter(volName string, spec Spec, pod *v1.Pod, opts VolumeOptions) (Mounter, error) {
  180. // The name of wrapper volume is set to "wrapped_{wrapped_volume_name}"
  181. wrapperVolumeName := "wrapped_" + volName
  182. if spec.Volume != nil {
  183. spec.Volume.Name = wrapperVolumeName
  184. }
  185. plug, err := f.pluginMgr.FindPluginBySpec(&spec)
  186. if err != nil {
  187. return nil, err
  188. }
  189. return plug.NewMounter(&spec, pod, opts)
  190. }
  191. func (f *fakeVolumeHost) NewWrapperUnmounter(volName string, spec Spec, podUID types.UID) (Unmounter, error) {
  192. // The name of wrapper volume is set to "wrapped_{wrapped_volume_name}"
  193. wrapperVolumeName := "wrapped_" + volName
  194. if spec.Volume != nil {
  195. spec.Volume.Name = wrapperVolumeName
  196. }
  197. plug, err := f.pluginMgr.FindPluginBySpec(&spec)
  198. if err != nil {
  199. return nil, err
  200. }
  201. return plug.NewUnmounter(spec.Name(), podUID)
  202. }
  203. // Returns the hostname of the host kubelet is running on
  204. func (f *fakeVolumeHost) GetHostName() string {
  205. return "fakeHostName"
  206. }
  207. // Returns host IP or nil in the case of error.
  208. func (f *fakeVolumeHost) GetHostIP() (net.IP, error) {
  209. return nil, fmt.Errorf("GetHostIP() not implemented")
  210. }
  211. func (f *fakeVolumeHost) GetNodeAllocatable() (v1.ResourceList, error) {
  212. return v1.ResourceList{}, nil
  213. }
  214. func (f *fakeVolumeHost) GetSecretFunc() func(namespace, name string) (*v1.Secret, error) {
  215. return func(namespace, name string) (*v1.Secret, error) {
  216. return f.kubeClient.CoreV1().Secrets(namespace).Get(context.TODO(), name, metav1.GetOptions{})
  217. }
  218. }
  219. func (f *fakeVolumeHost) GetExec(pluginName string) exec.Interface {
  220. return f.exec
  221. }
  222. func (f *fakeVolumeHost) GetConfigMapFunc() func(namespace, name string) (*v1.ConfigMap, error) {
  223. return func(namespace, name string) (*v1.ConfigMap, error) {
  224. return f.kubeClient.CoreV1().ConfigMaps(namespace).Get(context.TODO(), name, metav1.GetOptions{})
  225. }
  226. }
  227. func (f *fakeVolumeHost) GetServiceAccountTokenFunc() func(string, string, *authenticationv1.TokenRequest) (*authenticationv1.TokenRequest, error) {
  228. return func(namespace, name string, tr *authenticationv1.TokenRequest) (*authenticationv1.TokenRequest, error) {
  229. return f.kubeClient.CoreV1().ServiceAccounts(namespace).CreateToken(context.TODO(), name, tr, metav1.CreateOptions{})
  230. }
  231. }
  232. func (f *fakeVolumeHost) DeleteServiceAccountTokenFunc() func(types.UID) {
  233. return func(types.UID) {}
  234. }
  235. func (f *fakeVolumeHost) GetNodeLabels() (map[string]string, error) {
  236. if f.nodeLabels == nil {
  237. f.nodeLabels = map[string]string{"test-label": "test-value"}
  238. }
  239. return f.nodeLabels, nil
  240. }
  241. func (f *fakeVolumeHost) GetNodeName() types.NodeName {
  242. return types.NodeName(f.nodeName)
  243. }
  244. func (f *fakeVolumeHost) GetEventRecorder() record.EventRecorder {
  245. return nil
  246. }
  247. func (f *fakeVolumeHost) ScriptCommands(scripts []CommandScript) {
  248. ScriptCommands(f.exec, scripts)
  249. }
  250. // CommandScript is used to pre-configure a command that will be executed and
  251. // optionally set it's output (stdout and stderr combined) and return code.
  252. type CommandScript struct {
  253. // Cmd is the command to execute, e.g. "ls"
  254. Cmd string
  255. // Args is a slice of arguments to pass to the command, e.g. "-a"
  256. Args []string
  257. // Output is the combined stdout and stderr of the command to return
  258. Output string
  259. // ReturnCode is the exit code for the command. Setting this to non-zero will
  260. // cause the command to return an error with this exit code set.
  261. ReturnCode int
  262. }
  263. // ScriptCommands configures fe, the FakeExec, to have a pre-configured list of
  264. // commands to expect. Calling more commands using fe than those scripted will
  265. // result in a panic. By default, the fe does not enforce command argument checking
  266. // or order -- if you have given an Output to the command, the first command scripted
  267. // will return its output on the first command call, even if the command called is
  268. // different than the one scripted. This is mostly useful to make sure that the
  269. // right number of commands were called. If you want to check the exact commands
  270. // and arguments were called, set fe.ExectOrder to true.
  271. func ScriptCommands(fe *testingexec.FakeExec, scripts []CommandScript) {
  272. fe.DisableScripts = false
  273. for _, script := range scripts {
  274. fakeCmd := &testingexec.FakeCmd{}
  275. cmdAction := makeFakeCmd(fakeCmd, script.Cmd, script.Args...)
  276. outputAction := makeFakeOutput(script.Output, script.ReturnCode)
  277. fakeCmd.CombinedOutputScript = append(fakeCmd.CombinedOutputScript, outputAction)
  278. fe.CommandScript = append(fe.CommandScript, cmdAction)
  279. }
  280. }
  281. func makeFakeCmd(fakeCmd *testingexec.FakeCmd, cmd string, args ...string) testingexec.FakeCommandAction {
  282. fc := fakeCmd
  283. c := cmd
  284. a := args
  285. return func(cmd string, args ...string) exec.Cmd {
  286. command := testingexec.InitFakeCmd(fc, c, a...)
  287. return command
  288. }
  289. }
  290. func makeFakeOutput(output string, rc int) testingexec.FakeAction {
  291. o := output
  292. var e error
  293. if rc != 0 {
  294. e = testingexec.FakeExitError{Status: rc}
  295. }
  296. return func() ([]byte, []byte, error) {
  297. return []byte(o), nil, e
  298. }
  299. }
  300. func ProbeVolumePlugins(config VolumeConfig) []VolumePlugin {
  301. if _, ok := config.OtherAttributes["fake-property"]; ok {
  302. return []VolumePlugin{
  303. &FakeVolumePlugin{
  304. PluginName: "fake-plugin",
  305. Host: nil,
  306. // SomeFakeProperty: config.OtherAttributes["fake-property"] -- string, may require parsing by plugin
  307. },
  308. }
  309. }
  310. return []VolumePlugin{&FakeVolumePlugin{PluginName: "fake-plugin"}}
  311. }
  312. // FakeVolumePlugin is useful for testing. It tries to be a fully compliant
  313. // plugin, but all it does is make empty directories.
  314. // Use as:
  315. // volume.RegisterPlugin(&FakePlugin{"fake-name"})
  316. type FakeVolumePlugin struct {
  317. sync.RWMutex
  318. PluginName string
  319. Host VolumeHost
  320. Config VolumeConfig
  321. LastProvisionerOptions VolumeOptions
  322. NewAttacherCallCount int
  323. NewDetacherCallCount int
  324. VolumeLimits map[string]int64
  325. VolumeLimitsError error
  326. LimitKey string
  327. ProvisionDelaySeconds int
  328. SupportsRemount bool
  329. // Add callbacks as needed
  330. WaitForAttachHook func(spec *Spec, devicePath string, pod *v1.Pod, spectimeout time.Duration) (string, error)
  331. UnmountDeviceHook func(globalMountPath string) error
  332. Mounters []*FakeVolume
  333. Unmounters []*FakeVolume
  334. Attachers []*FakeVolume
  335. Detachers []*FakeVolume
  336. BlockVolumeMappers []*FakeVolume
  337. BlockVolumeUnmappers []*FakeVolume
  338. }
  339. var _ VolumePlugin = &FakeVolumePlugin{}
  340. var _ BlockVolumePlugin = &FakeVolumePlugin{}
  341. var _ RecyclableVolumePlugin = &FakeVolumePlugin{}
  342. var _ DeletableVolumePlugin = &FakeVolumePlugin{}
  343. var _ ProvisionableVolumePlugin = &FakeVolumePlugin{}
  344. var _ AttachableVolumePlugin = &FakeVolumePlugin{}
  345. var _ VolumePluginWithAttachLimits = &FakeVolumePlugin{}
  346. var _ DeviceMountableVolumePlugin = &FakeVolumePlugin{}
  347. var _ NodeExpandableVolumePlugin = &FakeVolumePlugin{}
  348. func (plugin *FakeVolumePlugin) getFakeVolume(list *[]*FakeVolume) *FakeVolume {
  349. volumeList := *list
  350. if list != nil && len(volumeList) > 0 {
  351. volume := volumeList[0]
  352. volume.Lock()
  353. defer volume.Unlock()
  354. volume.WaitForAttachHook = plugin.WaitForAttachHook
  355. volume.UnmountDeviceHook = plugin.UnmountDeviceHook
  356. return volume
  357. }
  358. volume := &FakeVolume{
  359. WaitForAttachHook: plugin.WaitForAttachHook,
  360. UnmountDeviceHook: plugin.UnmountDeviceHook,
  361. }
  362. volume.VolumesAttached = make(map[string]types.NodeName)
  363. volume.DeviceMountState = make(map[string]string)
  364. volume.VolumeMountState = make(map[string]string)
  365. *list = append(*list, volume)
  366. return volume
  367. }
  368. func (plugin *FakeVolumePlugin) Init(host VolumeHost) error {
  369. plugin.Lock()
  370. defer plugin.Unlock()
  371. plugin.Host = host
  372. return nil
  373. }
  374. func (plugin *FakeVolumePlugin) GetPluginName() string {
  375. plugin.RLock()
  376. defer plugin.RUnlock()
  377. return plugin.PluginName
  378. }
  379. func (plugin *FakeVolumePlugin) GetVolumeName(spec *Spec) (string, error) {
  380. var volumeName string
  381. if spec.Volume != nil && spec.Volume.GCEPersistentDisk != nil {
  382. volumeName = spec.Volume.GCEPersistentDisk.PDName
  383. } else if spec.PersistentVolume != nil &&
  384. spec.PersistentVolume.Spec.GCEPersistentDisk != nil {
  385. volumeName = spec.PersistentVolume.Spec.GCEPersistentDisk.PDName
  386. }
  387. if volumeName == "" {
  388. volumeName = spec.Name()
  389. }
  390. return volumeName, nil
  391. }
  392. func (plugin *FakeVolumePlugin) CanSupport(spec *Spec) bool {
  393. // TODO: maybe pattern-match on spec.Name() to decide?
  394. return true
  395. }
  396. func (plugin *FakeVolumePlugin) RequiresRemount() bool {
  397. return plugin.SupportsRemount
  398. }
  399. func (plugin *FakeVolumePlugin) SupportsMountOption() bool {
  400. return true
  401. }
  402. func (plugin *FakeVolumePlugin) SupportsBulkVolumeVerification() bool {
  403. return false
  404. }
  405. func (plugin *FakeVolumePlugin) NewMounter(spec *Spec, pod *v1.Pod, opts VolumeOptions) (Mounter, error) {
  406. plugin.Lock()
  407. defer plugin.Unlock()
  408. volume := plugin.getFakeVolume(&plugin.Mounters)
  409. volume.Lock()
  410. defer volume.Unlock()
  411. volume.PodUID = pod.UID
  412. volume.VolName = spec.Name()
  413. volume.Plugin = plugin
  414. volume.MetricsNil = MetricsNil{}
  415. return volume, nil
  416. }
  417. func (plugin *FakeVolumePlugin) GetMounters() (Mounters []*FakeVolume) {
  418. plugin.RLock()
  419. defer plugin.RUnlock()
  420. return plugin.Mounters
  421. }
  422. func (plugin *FakeVolumePlugin) NewUnmounter(volName string, podUID types.UID) (Unmounter, error) {
  423. plugin.Lock()
  424. defer plugin.Unlock()
  425. volume := plugin.getFakeVolume(&plugin.Unmounters)
  426. volume.Lock()
  427. defer volume.Unlock()
  428. volume.PodUID = podUID
  429. volume.VolName = volName
  430. volume.Plugin = plugin
  431. volume.MetricsNil = MetricsNil{}
  432. return volume, nil
  433. }
  434. func (plugin *FakeVolumePlugin) GetUnmounters() (Unmounters []*FakeVolume) {
  435. plugin.RLock()
  436. defer plugin.RUnlock()
  437. return plugin.Unmounters
  438. }
  439. // Block volume support
  440. func (plugin *FakeVolumePlugin) NewBlockVolumeMapper(spec *Spec, pod *v1.Pod, opts VolumeOptions) (BlockVolumeMapper, error) {
  441. plugin.Lock()
  442. defer plugin.Unlock()
  443. volume := plugin.getFakeVolume(&plugin.BlockVolumeMappers)
  444. volume.Lock()
  445. defer volume.Unlock()
  446. if pod != nil {
  447. volume.PodUID = pod.UID
  448. }
  449. volume.VolName = spec.Name()
  450. volume.Plugin = plugin
  451. return volume, nil
  452. }
  453. // Block volume support
  454. func (plugin *FakeVolumePlugin) GetBlockVolumeMapper() (BlockVolumeMappers []*FakeVolume) {
  455. plugin.RLock()
  456. defer plugin.RUnlock()
  457. return plugin.BlockVolumeMappers
  458. }
  459. // Block volume support
  460. func (plugin *FakeVolumePlugin) NewBlockVolumeUnmapper(volName string, podUID types.UID) (BlockVolumeUnmapper, error) {
  461. plugin.Lock()
  462. defer plugin.Unlock()
  463. volume := plugin.getFakeVolume(&plugin.BlockVolumeUnmappers)
  464. volume.Lock()
  465. defer volume.Unlock()
  466. volume.PodUID = podUID
  467. volume.VolName = volName
  468. volume.Plugin = plugin
  469. return volume, nil
  470. }
  471. // Block volume support
  472. func (plugin *FakeVolumePlugin) GetBlockVolumeUnmapper() (BlockVolumeUnmappers []*FakeVolume) {
  473. plugin.RLock()
  474. defer plugin.RUnlock()
  475. return plugin.BlockVolumeUnmappers
  476. }
  477. func (plugin *FakeVolumePlugin) NewAttacher() (Attacher, error) {
  478. plugin.Lock()
  479. defer plugin.Unlock()
  480. plugin.NewAttacherCallCount = plugin.NewAttacherCallCount + 1
  481. return plugin.getFakeVolume(&plugin.Attachers), nil
  482. }
  483. func (plugin *FakeVolumePlugin) NewDeviceMounter() (DeviceMounter, error) {
  484. return plugin.NewAttacher()
  485. }
  486. func (plugin *FakeVolumePlugin) GetAttachers() (Attachers []*FakeVolume) {
  487. plugin.RLock()
  488. defer plugin.RUnlock()
  489. return plugin.Attachers
  490. }
  491. func (plugin *FakeVolumePlugin) GetNewAttacherCallCount() int {
  492. plugin.RLock()
  493. defer plugin.RUnlock()
  494. return plugin.NewAttacherCallCount
  495. }
  496. func (plugin *FakeVolumePlugin) NewDetacher() (Detacher, error) {
  497. plugin.Lock()
  498. defer plugin.Unlock()
  499. plugin.NewDetacherCallCount = plugin.NewDetacherCallCount + 1
  500. detacher := plugin.getFakeVolume(&plugin.Detachers)
  501. attacherList := plugin.Attachers
  502. if attacherList != nil && len(attacherList) > 0 {
  503. detacherList := plugin.Detachers
  504. if detacherList != nil && len(detacherList) > 0 {
  505. detacherList[0].VolumesAttached = attacherList[0].VolumesAttached
  506. }
  507. }
  508. return detacher, nil
  509. }
  510. func (plugin *FakeVolumePlugin) NewDeviceUnmounter() (DeviceUnmounter, error) {
  511. return plugin.NewDetacher()
  512. }
  513. func (plugin *FakeVolumePlugin) GetDetachers() (Detachers []*FakeVolume) {
  514. plugin.RLock()
  515. defer plugin.RUnlock()
  516. return plugin.Detachers
  517. }
  518. func (plugin *FakeVolumePlugin) GetNewDetacherCallCount() int {
  519. plugin.RLock()
  520. defer plugin.RUnlock()
  521. return plugin.NewDetacherCallCount
  522. }
  523. func (plugin *FakeVolumePlugin) CanAttach(spec *Spec) (bool, error) {
  524. return true, nil
  525. }
  526. func (plugin *FakeVolumePlugin) CanDeviceMount(spec *Spec) (bool, error) {
  527. return true, nil
  528. }
  529. func (plugin *FakeVolumePlugin) Recycle(pvName string, spec *Spec, eventRecorder recyclerclient.RecycleEventRecorder) error {
  530. return nil
  531. }
  532. func (plugin *FakeVolumePlugin) NewDeleter(spec *Spec) (Deleter, error) {
  533. return &FakeDeleter{"/attributesTransferredFromSpec", MetricsNil{}}, nil
  534. }
  535. func (plugin *FakeVolumePlugin) NewProvisioner(options VolumeOptions) (Provisioner, error) {
  536. plugin.Lock()
  537. defer plugin.Unlock()
  538. plugin.LastProvisionerOptions = options
  539. return &FakeProvisioner{options, plugin.Host, plugin.ProvisionDelaySeconds}, nil
  540. }
  541. func (plugin *FakeVolumePlugin) GetAccessModes() []v1.PersistentVolumeAccessMode {
  542. return []v1.PersistentVolumeAccessMode{}
  543. }
  544. func (plugin *FakeVolumePlugin) ConstructVolumeSpec(volumeName, mountPath string) (*Spec, error) {
  545. return &Spec{
  546. Volume: &v1.Volume{
  547. Name: volumeName,
  548. },
  549. }, nil
  550. }
  551. // Block volume support
  552. func (plugin *FakeVolumePlugin) ConstructBlockVolumeSpec(podUID types.UID, volumeName, mountPath string) (*Spec, error) {
  553. return &Spec{
  554. Volume: &v1.Volume{
  555. Name: volumeName,
  556. },
  557. }, nil
  558. }
  559. func (plugin *FakeVolumePlugin) GetDeviceMountRefs(deviceMountPath string) ([]string, error) {
  560. return []string{}, nil
  561. }
  562. // Expandable volume support
  563. func (plugin *FakeVolumePlugin) ExpandVolumeDevice(spec *Spec, newSize resource.Quantity, oldSize resource.Quantity) (resource.Quantity, error) {
  564. return resource.Quantity{}, nil
  565. }
  566. func (plugin *FakeVolumePlugin) RequiresFSResize() bool {
  567. return true
  568. }
  569. func (plugin *FakeVolumePlugin) NodeExpand(resizeOptions NodeResizeOptions) (bool, error) {
  570. return true, nil
  571. }
  572. func (plugin *FakeVolumePlugin) GetVolumeLimits() (map[string]int64, error) {
  573. return plugin.VolumeLimits, plugin.VolumeLimitsError
  574. }
  575. func (plugin *FakeVolumePlugin) VolumeLimitKey(spec *Spec) string {
  576. return plugin.LimitKey
  577. }
  578. // FakeBasicVolumePlugin implements a basic volume plugin. It wrappers on
  579. // FakeVolumePlugin but implements VolumePlugin interface only.
  580. // It is useful to test logic involving plugin interfaces.
  581. type FakeBasicVolumePlugin struct {
  582. Plugin FakeVolumePlugin
  583. }
  584. func (f *FakeBasicVolumePlugin) GetPluginName() string {
  585. return f.Plugin.GetPluginName()
  586. }
  587. func (f *FakeBasicVolumePlugin) GetVolumeName(spec *Spec) (string, error) {
  588. return f.Plugin.GetVolumeName(spec)
  589. }
  590. // CanSupport tests whether the plugin supports a given volume specification by
  591. // testing volume spec name begins with plugin name or not.
  592. // This is useful to choose plugin by volume in testing.
  593. func (f *FakeBasicVolumePlugin) CanSupport(spec *Spec) bool {
  594. return strings.HasPrefix(spec.Name(), f.GetPluginName())
  595. }
  596. func (f *FakeBasicVolumePlugin) ConstructVolumeSpec(ame, mountPath string) (*Spec, error) {
  597. return f.Plugin.ConstructVolumeSpec(ame, mountPath)
  598. }
  599. func (f *FakeBasicVolumePlugin) Init(ost VolumeHost) error {
  600. return f.Plugin.Init(ost)
  601. }
  602. func (f *FakeBasicVolumePlugin) NewMounter(spec *Spec, pod *v1.Pod, opts VolumeOptions) (Mounter, error) {
  603. return f.Plugin.NewMounter(spec, pod, opts)
  604. }
  605. func (f *FakeBasicVolumePlugin) NewUnmounter(volName string, podUID types.UID) (Unmounter, error) {
  606. return f.Plugin.NewUnmounter(volName, podUID)
  607. }
  608. func (f *FakeBasicVolumePlugin) RequiresRemount() bool {
  609. return f.Plugin.RequiresRemount()
  610. }
  611. func (f *FakeBasicVolumePlugin) SupportsBulkVolumeVerification() bool {
  612. return f.Plugin.SupportsBulkVolumeVerification()
  613. }
  614. func (f *FakeBasicVolumePlugin) SupportsMountOption() bool {
  615. return f.Plugin.SupportsMountOption()
  616. }
  617. var _ VolumePlugin = &FakeBasicVolumePlugin{}
  618. // FakeDeviceMountableVolumePlugin implements an device mountable plugin based on FakeBasicVolumePlugin.
  619. type FakeDeviceMountableVolumePlugin struct {
  620. FakeBasicVolumePlugin
  621. }
  622. func (f *FakeDeviceMountableVolumePlugin) CanDeviceMount(spec *Spec) (bool, error) {
  623. return true, nil
  624. }
  625. func (f *FakeDeviceMountableVolumePlugin) NewDeviceMounter() (DeviceMounter, error) {
  626. return f.Plugin.NewDeviceMounter()
  627. }
  628. func (f *FakeDeviceMountableVolumePlugin) NewDeviceUnmounter() (DeviceUnmounter, error) {
  629. return f.Plugin.NewDeviceUnmounter()
  630. }
  631. func (f *FakeDeviceMountableVolumePlugin) GetDeviceMountRefs(deviceMountPath string) ([]string, error) {
  632. return f.Plugin.GetDeviceMountRefs(deviceMountPath)
  633. }
  634. var _ VolumePlugin = &FakeDeviceMountableVolumePlugin{}
  635. var _ DeviceMountableVolumePlugin = &FakeDeviceMountableVolumePlugin{}
  636. // FakeAttachableVolumePlugin implements an attachable plugin based on FakeDeviceMountableVolumePlugin.
  637. type FakeAttachableVolumePlugin struct {
  638. FakeDeviceMountableVolumePlugin
  639. }
  640. func (f *FakeAttachableVolumePlugin) NewAttacher() (Attacher, error) {
  641. return f.Plugin.NewAttacher()
  642. }
  643. func (f *FakeAttachableVolumePlugin) NewDetacher() (Detacher, error) {
  644. return f.Plugin.NewDetacher()
  645. }
  646. func (f *FakeAttachableVolumePlugin) CanAttach(spec *Spec) (bool, error) {
  647. return true, nil
  648. }
  649. var _ VolumePlugin = &FakeAttachableVolumePlugin{}
  650. var _ AttachableVolumePlugin = &FakeAttachableVolumePlugin{}
  651. type FakeFileVolumePlugin struct {
  652. }
  653. func (plugin *FakeFileVolumePlugin) Init(host VolumeHost) error {
  654. return nil
  655. }
  656. func (plugin *FakeFileVolumePlugin) GetPluginName() string {
  657. return "fake-file-plugin"
  658. }
  659. func (plugin *FakeFileVolumePlugin) GetVolumeName(spec *Spec) (string, error) {
  660. return "", nil
  661. }
  662. func (plugin *FakeFileVolumePlugin) CanSupport(spec *Spec) bool {
  663. return true
  664. }
  665. func (plugin *FakeFileVolumePlugin) RequiresRemount() bool {
  666. return false
  667. }
  668. func (plugin *FakeFileVolumePlugin) SupportsMountOption() bool {
  669. return false
  670. }
  671. func (plugin *FakeFileVolumePlugin) SupportsBulkVolumeVerification() bool {
  672. return false
  673. }
  674. func (plugin *FakeFileVolumePlugin) NewMounter(spec *Spec, podRef *v1.Pod, opts VolumeOptions) (Mounter, error) {
  675. return nil, nil
  676. }
  677. func (plugin *FakeFileVolumePlugin) NewUnmounter(name string, podUID types.UID) (Unmounter, error) {
  678. return nil, nil
  679. }
  680. func (plugin *FakeFileVolumePlugin) ConstructVolumeSpec(volumeName, mountPath string) (*Spec, error) {
  681. return nil, nil
  682. }
  683. func NewFakeFileVolumePlugin() []VolumePlugin {
  684. return []VolumePlugin{&FakeFileVolumePlugin{}}
  685. }
  686. type FakeVolume struct {
  687. sync.RWMutex
  688. PodUID types.UID
  689. VolName string
  690. Plugin *FakeVolumePlugin
  691. MetricsNil
  692. VolumesAttached map[string]types.NodeName
  693. DeviceMountState map[string]string
  694. VolumeMountState map[string]string
  695. // Add callbacks as needed
  696. WaitForAttachHook func(spec *Spec, devicePath string, pod *v1.Pod, spectimeout time.Duration) (string, error)
  697. UnmountDeviceHook func(globalMountPath string) error
  698. SetUpCallCount int
  699. TearDownCallCount int
  700. AttachCallCount int
  701. DetachCallCount int
  702. WaitForAttachCallCount int
  703. MountDeviceCallCount int
  704. UnmountDeviceCallCount int
  705. GetDeviceMountPathCallCount int
  706. SetUpDeviceCallCount int
  707. TearDownDeviceCallCount int
  708. MapPodDeviceCallCount int
  709. UnmapPodDeviceCallCount int
  710. GlobalMapPathCallCount int
  711. PodDeviceMapPathCallCount int
  712. }
  713. func getUniqueVolumeName(spec *Spec) (string, error) {
  714. var volumeName string
  715. if spec.Volume != nil && spec.Volume.GCEPersistentDisk != nil {
  716. volumeName = spec.Volume.GCEPersistentDisk.PDName
  717. } else if spec.PersistentVolume != nil &&
  718. spec.PersistentVolume.Spec.GCEPersistentDisk != nil {
  719. volumeName = spec.PersistentVolume.Spec.GCEPersistentDisk.PDName
  720. }
  721. if volumeName == "" {
  722. volumeName = spec.Name()
  723. }
  724. return volumeName, nil
  725. }
  726. func (_ *FakeVolume) GetAttributes() Attributes {
  727. return Attributes{
  728. ReadOnly: false,
  729. Managed: true,
  730. SupportsSELinux: true,
  731. }
  732. }
  733. func (fv *FakeVolume) CanMount() error {
  734. return nil
  735. }
  736. func (fv *FakeVolume) SetUp(mounterArgs MounterArgs) error {
  737. fv.Lock()
  738. defer fv.Unlock()
  739. err := fv.setupInternal(mounterArgs)
  740. fv.SetUpCallCount++
  741. return err
  742. }
  743. func (fv *FakeVolume) setupInternal(mounterArgs MounterArgs) error {
  744. if fv.VolName == TimeoutOnSetupVolumeName {
  745. fv.VolumeMountState[fv.VolName] = volumeMountUncertain
  746. return volumetypes.NewUncertainProgressError("time out on setup")
  747. }
  748. if fv.VolName == FailOnSetupVolumeName {
  749. fv.VolumeMountState[fv.VolName] = volumeNotMounted
  750. return fmt.Errorf("mounting volume failed")
  751. }
  752. if fv.VolName == TimeoutAndFailOnSetupVolumeName {
  753. _, ok := fv.VolumeMountState[fv.VolName]
  754. if !ok {
  755. fv.VolumeMountState[fv.VolName] = volumeMountUncertain
  756. return volumetypes.NewUncertainProgressError("time out on setup")
  757. }
  758. fv.VolumeMountState[fv.VolName] = volumeNotMounted
  759. return fmt.Errorf("mounting volume failed")
  760. }
  761. if fv.VolName == SuccessAndFailOnSetupVolumeName {
  762. _, ok := fv.VolumeMountState[fv.VolName]
  763. if ok {
  764. fv.VolumeMountState[fv.VolName] = volumeNotMounted
  765. return fmt.Errorf("mounting volume failed")
  766. }
  767. }
  768. if fv.VolName == SuccessAndTimeoutSetupVolumeName {
  769. _, ok := fv.VolumeMountState[fv.VolName]
  770. if ok {
  771. fv.VolumeMountState[fv.VolName] = volumeMountUncertain
  772. return volumetypes.NewUncertainProgressError("time out on setup")
  773. }
  774. }
  775. fv.VolumeMountState[fv.VolName] = volumeNotMounted
  776. return fv.SetUpAt(fv.getPath(), mounterArgs)
  777. }
  778. func (fv *FakeVolume) GetSetUpCallCount() int {
  779. fv.RLock()
  780. defer fv.RUnlock()
  781. return fv.SetUpCallCount
  782. }
  783. func (fv *FakeVolume) SetUpAt(dir string, mounterArgs MounterArgs) error {
  784. return os.MkdirAll(dir, 0750)
  785. }
  786. func (fv *FakeVolume) GetPath() string {
  787. fv.RLock()
  788. defer fv.RUnlock()
  789. return fv.getPath()
  790. }
  791. func (fv *FakeVolume) getPath() string {
  792. return filepath.Join(fv.Plugin.Host.GetPodVolumeDir(fv.PodUID, utilstrings.EscapeQualifiedName(fv.Plugin.PluginName), fv.VolName))
  793. }
  794. func (fv *FakeVolume) TearDown() error {
  795. fv.Lock()
  796. defer fv.Unlock()
  797. fv.TearDownCallCount++
  798. return fv.TearDownAt(fv.getPath())
  799. }
  800. func (fv *FakeVolume) GetTearDownCallCount() int {
  801. fv.RLock()
  802. defer fv.RUnlock()
  803. return fv.TearDownCallCount
  804. }
  805. func (fv *FakeVolume) TearDownAt(dir string) error {
  806. return os.RemoveAll(dir)
  807. }
  808. // Block volume support
  809. func (fv *FakeVolume) SetUpDevice() error {
  810. fv.Lock()
  811. defer fv.Unlock()
  812. fv.SetUpDeviceCallCount++
  813. return nil
  814. }
  815. // Block volume support
  816. func (fv *FakeVolume) GetSetUpDeviceCallCount() int {
  817. fv.RLock()
  818. defer fv.RUnlock()
  819. return fv.SetUpDeviceCallCount
  820. }
  821. // Block volume support
  822. func (fv *FakeVolume) GetGlobalMapPath(spec *Spec) (string, error) {
  823. fv.RLock()
  824. defer fv.RUnlock()
  825. fv.GlobalMapPathCallCount++
  826. return fv.getGlobalMapPath()
  827. }
  828. // Block volume support
  829. func (fv *FakeVolume) getGlobalMapPath() (string, error) {
  830. return filepath.Join(fv.Plugin.Host.GetVolumeDevicePluginDir(utilstrings.EscapeQualifiedName(fv.Plugin.PluginName)), "pluginDependentPath"), nil
  831. }
  832. // Block volume support
  833. func (fv *FakeVolume) GetGlobalMapPathCallCount() int {
  834. fv.RLock()
  835. defer fv.RUnlock()
  836. return fv.GlobalMapPathCallCount
  837. }
  838. // Block volume support
  839. func (fv *FakeVolume) GetPodDeviceMapPath() (string, string) {
  840. fv.RLock()
  841. defer fv.RUnlock()
  842. fv.PodDeviceMapPathCallCount++
  843. return fv.getPodDeviceMapPath()
  844. }
  845. // Block volume support
  846. func (fv *FakeVolume) getPodDeviceMapPath() (string, string) {
  847. return filepath.Join(fv.Plugin.Host.GetPodVolumeDeviceDir(fv.PodUID, utilstrings.EscapeQualifiedName(fv.Plugin.PluginName))), fv.VolName
  848. }
  849. // Block volume support
  850. func (fv *FakeVolume) GetPodDeviceMapPathCallCount() int {
  851. fv.RLock()
  852. defer fv.RUnlock()
  853. return fv.PodDeviceMapPathCallCount
  854. }
  855. // Block volume support
  856. func (fv *FakeVolume) TearDownDevice(mapPath string, devicePath string) error {
  857. fv.Lock()
  858. defer fv.Unlock()
  859. fv.TearDownDeviceCallCount++
  860. return nil
  861. }
  862. // Block volume support
  863. func (fv *FakeVolume) GetTearDownDeviceCallCount() int {
  864. fv.RLock()
  865. defer fv.RUnlock()
  866. return fv.TearDownDeviceCallCount
  867. }
  868. // Block volume support
  869. func (fv *FakeVolume) UnmapPodDevice() error {
  870. fv.Lock()
  871. defer fv.Unlock()
  872. fv.UnmapPodDeviceCallCount++
  873. return nil
  874. }
  875. // Block volume support
  876. func (fv *FakeVolume) GetUnmapPodDeviceCallCount() int {
  877. fv.RLock()
  878. defer fv.RUnlock()
  879. return fv.UnmapPodDeviceCallCount
  880. }
  881. // Block volume support
  882. func (fv *FakeVolume) MapPodDevice() (string, error) {
  883. fv.Lock()
  884. defer fv.Unlock()
  885. fv.MapPodDeviceCallCount++
  886. return "", nil
  887. }
  888. // Block volume support
  889. func (fv *FakeVolume) GetMapPodDeviceCallCount() int {
  890. fv.RLock()
  891. defer fv.RUnlock()
  892. return fv.MapPodDeviceCallCount
  893. }
  894. func (fv *FakeVolume) Attach(spec *Spec, nodeName types.NodeName) (string, error) {
  895. fv.Lock()
  896. defer fv.Unlock()
  897. fv.AttachCallCount++
  898. volumeName, err := getUniqueVolumeName(spec)
  899. if err != nil {
  900. return "", err
  901. }
  902. volumeNode, exist := fv.VolumesAttached[volumeName]
  903. if exist {
  904. if nodeName == UncertainAttachNode {
  905. return "/dev/vdb-test", nil
  906. }
  907. // even if volume was previously attached to time out, we need to keep returning error
  908. // so as reconciler can not confirm this volume as attached.
  909. if nodeName == TimeoutAttachNode {
  910. return "", fmt.Errorf("Timed out to attach volume %q to node %q", volumeName, nodeName)
  911. }
  912. if volumeNode == nodeName || volumeNode == MultiAttachNode || nodeName == MultiAttachNode {
  913. return "/dev/vdb-test", nil
  914. }
  915. return "", fmt.Errorf("volume %q trying to attach to node %q is already attached to node %q", volumeName, nodeName, volumeNode)
  916. }
  917. fv.VolumesAttached[volumeName] = nodeName
  918. if nodeName == UncertainAttachNode || nodeName == TimeoutAttachNode {
  919. return "", fmt.Errorf("Timed out to attach volume %q to node %q", volumeName, nodeName)
  920. }
  921. return "/dev/vdb-test", nil
  922. }
  923. func (fv *FakeVolume) GetAttachCallCount() int {
  924. fv.RLock()
  925. defer fv.RUnlock()
  926. return fv.AttachCallCount
  927. }
  928. func (fv *FakeVolume) WaitForAttach(spec *Spec, devicePath string, pod *v1.Pod, spectimeout time.Duration) (string, error) {
  929. fv.Lock()
  930. defer fv.Unlock()
  931. fv.WaitForAttachCallCount++
  932. if fv.WaitForAttachHook != nil {
  933. return fv.WaitForAttachHook(spec, devicePath, pod, spectimeout)
  934. }
  935. return "/dev/sdb", nil
  936. }
  937. func (fv *FakeVolume) GetWaitForAttachCallCount() int {
  938. fv.RLock()
  939. defer fv.RUnlock()
  940. return fv.WaitForAttachCallCount
  941. }
  942. func (fv *FakeVolume) GetDeviceMountPath(spec *Spec) (string, error) {
  943. fv.Lock()
  944. defer fv.Unlock()
  945. fv.GetDeviceMountPathCallCount++
  946. return "", nil
  947. }
  948. func (fv *FakeVolume) mountDeviceInternal(spec *Spec, devicePath string, deviceMountPath string) error {
  949. fv.Lock()
  950. defer fv.Unlock()
  951. if spec.Name() == TimeoutOnMountDeviceVolumeName {
  952. fv.DeviceMountState[spec.Name()] = deviceMountUncertain
  953. return volumetypes.NewUncertainProgressError("mount failed")
  954. }
  955. if spec.Name() == FailMountDeviceVolumeName {
  956. fv.DeviceMountState[spec.Name()] = deviceNotMounted
  957. return fmt.Errorf("error mounting disk: %s", devicePath)
  958. }
  959. if spec.Name() == TimeoutAndFailOnMountDeviceVolumeName {
  960. _, ok := fv.DeviceMountState[spec.Name()]
  961. if !ok {
  962. fv.DeviceMountState[spec.Name()] = deviceMountUncertain
  963. return volumetypes.NewUncertainProgressError("timed out mounting error")
  964. }
  965. fv.DeviceMountState[spec.Name()] = deviceNotMounted
  966. return fmt.Errorf("error mounting disk: %s", devicePath)
  967. }
  968. if spec.Name() == SuccessAndTimeoutDeviceName {
  969. _, ok := fv.DeviceMountState[spec.Name()]
  970. if ok {
  971. fv.DeviceMountState[spec.Name()] = deviceMountUncertain
  972. return volumetypes.NewUncertainProgressError("error mounting state")
  973. }
  974. }
  975. if spec.Name() == SuccessAndFailOnMountDeviceName {
  976. _, ok := fv.DeviceMountState[spec.Name()]
  977. if ok {
  978. return fmt.Errorf("error mounting disk: %s", devicePath)
  979. }
  980. }
  981. fv.DeviceMountState[spec.Name()] = deviceMounted
  982. fv.MountDeviceCallCount++
  983. return nil
  984. }
  985. func (fv *FakeVolume) MountDevice(spec *Spec, devicePath string, deviceMountPath string) error {
  986. return fv.mountDeviceInternal(spec, devicePath, deviceMountPath)
  987. }
  988. func (fv *FakeVolume) GetMountDeviceCallCount() int {
  989. fv.RLock()
  990. defer fv.RUnlock()
  991. return fv.MountDeviceCallCount
  992. }
  993. func (fv *FakeVolume) GetUnmountDeviceCallCount() int {
  994. fv.RLock()
  995. defer fv.RUnlock()
  996. return fv.UnmountDeviceCallCount
  997. }
  998. func (fv *FakeVolume) Detach(volumeName string, nodeName types.NodeName) error {
  999. fv.Lock()
  1000. defer fv.Unlock()
  1001. fv.DetachCallCount++
  1002. if _, exist := fv.VolumesAttached[volumeName]; !exist {
  1003. return fmt.Errorf("Trying to detach volume %q that is not attached to the node %q", volumeName, nodeName)
  1004. }
  1005. delete(fv.VolumesAttached, volumeName)
  1006. return nil
  1007. }
  1008. func (fv *FakeVolume) VolumesAreAttached(spec []*Spec, nodeName types.NodeName) (map[*Spec]bool, error) {
  1009. fv.Lock()
  1010. defer fv.Unlock()
  1011. return nil, nil
  1012. }
  1013. func (fv *FakeVolume) GetDetachCallCount() int {
  1014. fv.RLock()
  1015. defer fv.RUnlock()
  1016. return fv.DetachCallCount
  1017. }
  1018. func (fv *FakeVolume) UnmountDevice(globalMountPath string) error {
  1019. fv.Lock()
  1020. defer fv.Unlock()
  1021. fv.UnmountDeviceCallCount++
  1022. if fv.UnmountDeviceHook != nil {
  1023. return fv.UnmountDeviceHook(globalMountPath)
  1024. }
  1025. return nil
  1026. }
  1027. type FakeDeleter struct {
  1028. path string
  1029. MetricsNil
  1030. }
  1031. func (fd *FakeDeleter) Delete() error {
  1032. // nil is success, else error
  1033. return nil
  1034. }
  1035. func (fd *FakeDeleter) GetPath() string {
  1036. return fd.path
  1037. }
  1038. type FakeProvisioner struct {
  1039. Options VolumeOptions
  1040. Host VolumeHost
  1041. ProvisionDelaySeconds int
  1042. }
  1043. func (fc *FakeProvisioner) Provision(selectedNode *v1.Node, allowedTopologies []v1.TopologySelectorTerm) (*v1.PersistentVolume, error) {
  1044. // Add provision failure hook
  1045. if fc.Options.Parameters != nil {
  1046. if _, ok := fc.Options.Parameters[ExpectProvisionFailureKey]; ok {
  1047. return nil, fmt.Errorf("expected error")
  1048. }
  1049. }
  1050. fullpath := fmt.Sprintf("/tmp/hostpath_pv/%s", uuid.NewUUID())
  1051. pv := &v1.PersistentVolume{
  1052. ObjectMeta: metav1.ObjectMeta{
  1053. Name: fc.Options.PVName,
  1054. Annotations: map[string]string{
  1055. util.VolumeDynamicallyCreatedByKey: "fakeplugin-provisioner",
  1056. },
  1057. },
  1058. Spec: v1.PersistentVolumeSpec{
  1059. PersistentVolumeReclaimPolicy: fc.Options.PersistentVolumeReclaimPolicy,
  1060. AccessModes: fc.Options.PVC.Spec.AccessModes,
  1061. Capacity: v1.ResourceList{
  1062. v1.ResourceName(v1.ResourceStorage): fc.Options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)],
  1063. },
  1064. PersistentVolumeSource: v1.PersistentVolumeSource{
  1065. HostPath: &v1.HostPathVolumeSource{
  1066. Path: fullpath,
  1067. },
  1068. },
  1069. },
  1070. }
  1071. if fc.ProvisionDelaySeconds > 0 {
  1072. time.Sleep(time.Duration(fc.ProvisionDelaySeconds) * time.Second)
  1073. }
  1074. return pv, nil
  1075. }
  1076. var _ volumepathhandler.BlockVolumePathHandler = &FakeVolumePathHandler{}
  1077. //NewDeviceHandler Create a new IoHandler implementation
  1078. func NewBlockVolumePathHandler() volumepathhandler.BlockVolumePathHandler {
  1079. return &FakeVolumePathHandler{}
  1080. }
  1081. type FakeVolumePathHandler struct {
  1082. sync.RWMutex
  1083. }
  1084. func (fv *FakeVolumePathHandler) MapDevice(devicePath string, mapDir string, linkName string, bindMount bool) error {
  1085. // nil is success, else error
  1086. return nil
  1087. }
  1088. func (fv *FakeVolumePathHandler) UnmapDevice(mapDir string, linkName string, bindMount bool) error {
  1089. // nil is success, else error
  1090. return nil
  1091. }
  1092. func (fv *FakeVolumePathHandler) RemoveMapPath(mapPath string) error {
  1093. // nil is success, else error
  1094. return nil
  1095. }
  1096. func (fv *FakeVolumePathHandler) IsSymlinkExist(mapPath string) (bool, error) {
  1097. // nil is success, else error
  1098. return true, nil
  1099. }
  1100. func (fv *FakeVolumePathHandler) IsDeviceBindMountExist(mapPath string) (bool, error) {
  1101. // nil is success, else error
  1102. return true, nil
  1103. }
  1104. func (fv *FakeVolumePathHandler) GetDeviceBindMountRefs(devPath string, mapPath string) ([]string, error) {
  1105. // nil is success, else error
  1106. return []string{}, nil
  1107. }
  1108. func (fv *FakeVolumePathHandler) FindGlobalMapPathUUIDFromPod(pluginDir, mapPath string, podUID types.UID) (string, error) {
  1109. // nil is success, else error
  1110. return "", nil
  1111. }
  1112. func (fv *FakeVolumePathHandler) AttachFileDevice(path string) (string, error) {
  1113. // nil is success, else error
  1114. return "", nil
  1115. }
  1116. func (fv *FakeVolumePathHandler) DetachFileDevice(path string) error {
  1117. // nil is success, else error
  1118. return nil
  1119. }
  1120. func (fv *FakeVolumePathHandler) GetLoopDevice(path string) (string, error) {
  1121. // nil is success, else error
  1122. return "/dev/loop1", nil
  1123. }
  1124. // FindEmptyDirectoryUsageOnTmpfs finds the expected usage of an empty directory existing on
  1125. // a tmpfs filesystem on this system.
  1126. func FindEmptyDirectoryUsageOnTmpfs() (*resource.Quantity, error) {
  1127. tmpDir, err := utiltesting.MkTmpdir("metrics_du_test")
  1128. if err != nil {
  1129. return nil, err
  1130. }
  1131. defer os.RemoveAll(tmpDir)
  1132. out, err := exec.New().Command("nice", "-n", "19", "du", "-x", "-s", "-B", "1", tmpDir).CombinedOutput()
  1133. if err != nil {
  1134. return nil, fmt.Errorf("failed command 'du' on %s with error %v", tmpDir, err)
  1135. }
  1136. used, err := resource.ParseQuantity(strings.Fields(string(out))[0])
  1137. if err != nil {
  1138. return nil, fmt.Errorf("failed to parse 'du' output %s due to error %v", out, err)
  1139. }
  1140. used.Format = resource.BinarySI
  1141. return &used, nil
  1142. }
  1143. // VerifyAttachCallCount ensures that at least one of the Attachers for this
  1144. // plugin has the expectedAttachCallCount number of calls. Otherwise it returns
  1145. // an error.
  1146. func VerifyAttachCallCount(
  1147. expectedAttachCallCount int,
  1148. fakeVolumePlugin *FakeVolumePlugin) error {
  1149. for _, attacher := range fakeVolumePlugin.GetAttachers() {
  1150. actualCallCount := attacher.GetAttachCallCount()
  1151. if actualCallCount >= expectedAttachCallCount {
  1152. return nil
  1153. }
  1154. }
  1155. return fmt.Errorf(
  1156. "No attachers have expected AttachCallCount. Expected: <%v>.",
  1157. expectedAttachCallCount)
  1158. }
  1159. // VerifyZeroAttachCalls ensures that all of the Attachers for this plugin have
  1160. // a zero AttachCallCount. Otherwise it returns an error.
  1161. func VerifyZeroAttachCalls(fakeVolumePlugin *FakeVolumePlugin) error {
  1162. for _, attacher := range fakeVolumePlugin.GetAttachers() {
  1163. actualCallCount := attacher.GetAttachCallCount()
  1164. if actualCallCount != 0 {
  1165. return fmt.Errorf(
  1166. "At least one attacher has non-zero AttachCallCount: <%v>.",
  1167. actualCallCount)
  1168. }
  1169. }
  1170. return nil
  1171. }
  1172. // VerifyWaitForAttachCallCount ensures that at least one of the Mounters for
  1173. // this plugin has the expectedWaitForAttachCallCount number of calls. Otherwise
  1174. // it returns an error.
  1175. func VerifyWaitForAttachCallCount(
  1176. expectedWaitForAttachCallCount int,
  1177. fakeVolumePlugin *FakeVolumePlugin) error {
  1178. for _, attacher := range fakeVolumePlugin.GetAttachers() {
  1179. actualCallCount := attacher.GetWaitForAttachCallCount()
  1180. if actualCallCount >= expectedWaitForAttachCallCount {
  1181. return nil
  1182. }
  1183. }
  1184. return fmt.Errorf(
  1185. "No Attachers have expected WaitForAttachCallCount. Expected: <%v>.",
  1186. expectedWaitForAttachCallCount)
  1187. }
  1188. // VerifyZeroWaitForAttachCallCount ensures that all Attachers for this plugin
  1189. // have a zero WaitForAttachCallCount. Otherwise it returns an error.
  1190. func VerifyZeroWaitForAttachCallCount(fakeVolumePlugin *FakeVolumePlugin) error {
  1191. for _, attacher := range fakeVolumePlugin.GetAttachers() {
  1192. actualCallCount := attacher.GetWaitForAttachCallCount()
  1193. if actualCallCount != 0 {
  1194. return fmt.Errorf(
  1195. "At least one attacher has non-zero WaitForAttachCallCount: <%v>.",
  1196. actualCallCount)
  1197. }
  1198. }
  1199. return nil
  1200. }
  1201. // VerifyMountDeviceCallCount ensures that at least one of the Mounters for
  1202. // this plugin has the expectedMountDeviceCallCount number of calls. Otherwise
  1203. // it returns an error.
  1204. func VerifyMountDeviceCallCount(
  1205. expectedMountDeviceCallCount int,
  1206. fakeVolumePlugin *FakeVolumePlugin) error {
  1207. for _, attacher := range fakeVolumePlugin.GetAttachers() {
  1208. actualCallCount := attacher.GetMountDeviceCallCount()
  1209. if actualCallCount >= expectedMountDeviceCallCount {
  1210. return nil
  1211. }
  1212. }
  1213. return fmt.Errorf(
  1214. "No Attachers have expected MountDeviceCallCount. Expected: <%v>.",
  1215. expectedMountDeviceCallCount)
  1216. }
  1217. func VerifyUnmountDeviceCallCount(expectedCallCount int, fakeVolumePlugin *FakeVolumePlugin) error {
  1218. detachers := fakeVolumePlugin.GetDetachers()
  1219. if len(detachers) == 0 && (expectedCallCount == 0) {
  1220. return nil
  1221. }
  1222. actualCallCount := 0
  1223. for _, detacher := range detachers {
  1224. actualCallCount = detacher.GetUnmountDeviceCallCount()
  1225. if expectedCallCount == 0 && actualCallCount == expectedCallCount {
  1226. return nil
  1227. }
  1228. if (expectedCallCount > 0) && (actualCallCount >= expectedCallCount) {
  1229. return nil
  1230. }
  1231. }
  1232. return fmt.Errorf(
  1233. "Expected DeviceUnmount Call %d, got %d",
  1234. expectedCallCount, actualCallCount)
  1235. }
  1236. // VerifyZeroMountDeviceCallCount ensures that all Attachers for this plugin
  1237. // have a zero MountDeviceCallCount. Otherwise it returns an error.
  1238. func VerifyZeroMountDeviceCallCount(fakeVolumePlugin *FakeVolumePlugin) error {
  1239. for _, attacher := range fakeVolumePlugin.GetAttachers() {
  1240. actualCallCount := attacher.GetMountDeviceCallCount()
  1241. if actualCallCount != 0 {
  1242. return fmt.Errorf(
  1243. "At least one attacher has non-zero MountDeviceCallCount: <%v>.",
  1244. actualCallCount)
  1245. }
  1246. }
  1247. return nil
  1248. }
  1249. // VerifySetUpCallCount ensures that at least one of the Mounters for this
  1250. // plugin has the expectedSetUpCallCount number of calls. Otherwise it returns
  1251. // an error.
  1252. func VerifySetUpCallCount(
  1253. expectedSetUpCallCount int,
  1254. fakeVolumePlugin *FakeVolumePlugin) error {
  1255. for _, mounter := range fakeVolumePlugin.GetMounters() {
  1256. actualCallCount := mounter.GetSetUpCallCount()
  1257. if actualCallCount >= expectedSetUpCallCount {
  1258. return nil
  1259. }
  1260. }
  1261. return fmt.Errorf(
  1262. "No Mounters have expected SetUpCallCount. Expected: <%v>.",
  1263. expectedSetUpCallCount)
  1264. }
  1265. // VerifyZeroSetUpCallCount ensures that all Mounters for this plugin have a
  1266. // zero SetUpCallCount. Otherwise it returns an error.
  1267. func VerifyZeroSetUpCallCount(fakeVolumePlugin *FakeVolumePlugin) error {
  1268. for _, mounter := range fakeVolumePlugin.GetMounters() {
  1269. actualCallCount := mounter.GetSetUpCallCount()
  1270. if actualCallCount != 0 {
  1271. return fmt.Errorf(
  1272. "At least one mounter has non-zero SetUpCallCount: <%v>.",
  1273. actualCallCount)
  1274. }
  1275. }
  1276. return nil
  1277. }
  1278. // VerifyTearDownCallCount ensures that at least one of the Unounters for this
  1279. // plugin has the expectedTearDownCallCount number of calls. Otherwise it
  1280. // returns an error.
  1281. func VerifyTearDownCallCount(
  1282. expectedTearDownCallCount int,
  1283. fakeVolumePlugin *FakeVolumePlugin) error {
  1284. unmounters := fakeVolumePlugin.GetUnmounters()
  1285. if len(unmounters) == 0 && (expectedTearDownCallCount == 0) {
  1286. return nil
  1287. }
  1288. for _, unmounter := range unmounters {
  1289. actualCallCount := unmounter.GetTearDownCallCount()
  1290. if expectedTearDownCallCount == 0 && actualCallCount == expectedTearDownCallCount {
  1291. return nil
  1292. }
  1293. if (expectedTearDownCallCount > 0) && (actualCallCount >= expectedTearDownCallCount) {
  1294. return nil
  1295. }
  1296. }
  1297. return fmt.Errorf(
  1298. "No Unmounters have expected SetUpCallCount. Expected: <%v>.",
  1299. expectedTearDownCallCount)
  1300. }
  1301. // VerifyZeroTearDownCallCount ensures that all Mounters for this plugin have a
  1302. // zero TearDownCallCount. Otherwise it returns an error.
  1303. func VerifyZeroTearDownCallCount(fakeVolumePlugin *FakeVolumePlugin) error {
  1304. for _, mounter := range fakeVolumePlugin.GetMounters() {
  1305. actualCallCount := mounter.GetTearDownCallCount()
  1306. if actualCallCount != 0 {
  1307. return fmt.Errorf(
  1308. "At least one mounter has non-zero TearDownCallCount: <%v>.",
  1309. actualCallCount)
  1310. }
  1311. }
  1312. return nil
  1313. }
  1314. // VerifyDetachCallCount ensures that at least one of the Attachers for this
  1315. // plugin has the expectedDetachCallCount number of calls. Otherwise it returns
  1316. // an error.
  1317. func VerifyDetachCallCount(
  1318. expectedDetachCallCount int,
  1319. fakeVolumePlugin *FakeVolumePlugin) error {
  1320. for _, detacher := range fakeVolumePlugin.GetDetachers() {
  1321. actualCallCount := detacher.GetDetachCallCount()
  1322. if actualCallCount == expectedDetachCallCount {
  1323. return nil
  1324. }
  1325. }
  1326. return fmt.Errorf(
  1327. "No Detachers have expected DetachCallCount. Expected: <%v>.",
  1328. expectedDetachCallCount)
  1329. }
  1330. // VerifyZeroDetachCallCount ensures that all Detachers for this plugin have a
  1331. // zero DetachCallCount. Otherwise it returns an error.
  1332. func VerifyZeroDetachCallCount(fakeVolumePlugin *FakeVolumePlugin) error {
  1333. for _, detacher := range fakeVolumePlugin.GetDetachers() {
  1334. actualCallCount := detacher.GetDetachCallCount()
  1335. if actualCallCount != 0 {
  1336. return fmt.Errorf(
  1337. "At least one detacher has non-zero DetachCallCount: <%v>.",
  1338. actualCallCount)
  1339. }
  1340. }
  1341. return nil
  1342. }
  1343. // VerifySetUpDeviceCallCount ensures that at least one of the Mappers for this
  1344. // plugin has the expectedSetUpDeviceCallCount number of calls. Otherwise it
  1345. // returns an error.
  1346. func VerifySetUpDeviceCallCount(
  1347. expectedSetUpDeviceCallCount int,
  1348. fakeVolumePlugin *FakeVolumePlugin) error {
  1349. for _, mapper := range fakeVolumePlugin.GetBlockVolumeMapper() {
  1350. actualCallCount := mapper.GetSetUpDeviceCallCount()
  1351. if actualCallCount >= expectedSetUpDeviceCallCount {
  1352. return nil
  1353. }
  1354. }
  1355. return fmt.Errorf(
  1356. "No Mapper have expected SetUpDeviceCallCount. Expected: <%v>.",
  1357. expectedSetUpDeviceCallCount)
  1358. }
  1359. // VerifyTearDownDeviceCallCount ensures that at least one of the Unmappers for this
  1360. // plugin has the expectedTearDownDeviceCallCount number of calls. Otherwise it
  1361. // returns an error.
  1362. func VerifyTearDownDeviceCallCount(
  1363. expectedTearDownDeviceCallCount int,
  1364. fakeVolumePlugin *FakeVolumePlugin) error {
  1365. for _, unmapper := range fakeVolumePlugin.GetBlockVolumeUnmapper() {
  1366. actualCallCount := unmapper.GetTearDownDeviceCallCount()
  1367. if actualCallCount >= expectedTearDownDeviceCallCount {
  1368. return nil
  1369. }
  1370. }
  1371. return fmt.Errorf(
  1372. "No Unmapper have expected TearDownDeviceCallCount. Expected: <%v>.",
  1373. expectedTearDownDeviceCallCount)
  1374. }
  1375. // VerifyZeroTearDownDeviceCallCount ensures that all Mappers for this plugin have a
  1376. // zero TearDownDeviceCallCount. Otherwise it returns an error.
  1377. func VerifyZeroTearDownDeviceCallCount(fakeVolumePlugin *FakeVolumePlugin) error {
  1378. for _, unmapper := range fakeVolumePlugin.GetBlockVolumeUnmapper() {
  1379. actualCallCount := unmapper.GetTearDownDeviceCallCount()
  1380. if actualCallCount != 0 {
  1381. return fmt.Errorf(
  1382. "At least one unmapper has non-zero TearDownDeviceCallCount: <%v>.",
  1383. actualCallCount)
  1384. }
  1385. }
  1386. return nil
  1387. }
  1388. // VerifyGetGlobalMapPathCallCount ensures that at least one of the Mappers for this
  1389. // plugin has the expectedGlobalMapPathCallCount number of calls. Otherwise it returns
  1390. // an error.
  1391. func VerifyGetGlobalMapPathCallCount(
  1392. expectedGlobalMapPathCallCount int,
  1393. fakeVolumePlugin *FakeVolumePlugin) error {
  1394. for _, mapper := range fakeVolumePlugin.GetBlockVolumeMapper() {
  1395. actualCallCount := mapper.GetGlobalMapPathCallCount()
  1396. if actualCallCount == expectedGlobalMapPathCallCount {
  1397. return nil
  1398. }
  1399. }
  1400. return fmt.Errorf(
  1401. "No Mappers have expected GetGlobalMapPathCallCount. Expected: <%v>.",
  1402. expectedGlobalMapPathCallCount)
  1403. }
  1404. // VerifyGetPodDeviceMapPathCallCount ensures that at least one of the Mappers for this
  1405. // plugin has the expectedPodDeviceMapPathCallCount number of calls. Otherwise it returns
  1406. // an error.
  1407. func VerifyGetPodDeviceMapPathCallCount(
  1408. expectedPodDeviceMapPathCallCount int,
  1409. fakeVolumePlugin *FakeVolumePlugin) error {
  1410. for _, mapper := range fakeVolumePlugin.GetBlockVolumeMapper() {
  1411. actualCallCount := mapper.GetPodDeviceMapPathCallCount()
  1412. if actualCallCount == expectedPodDeviceMapPathCallCount {
  1413. return nil
  1414. }
  1415. }
  1416. return fmt.Errorf(
  1417. "No Mappers have expected GetPodDeviceMapPathCallCount. Expected: <%v>.",
  1418. expectedPodDeviceMapPathCallCount)
  1419. }
  1420. // VerifyGetMapPodDeviceCallCount ensures that at least one of the Mappers for this
  1421. // plugin has the expectedMapPodDeviceCallCount number of calls. Otherwise it
  1422. // returns an error.
  1423. func VerifyGetMapPodDeviceCallCount(
  1424. expectedMapPodDeviceCallCount int,
  1425. fakeVolumePlugin *FakeVolumePlugin) error {
  1426. for _, mapper := range fakeVolumePlugin.GetBlockVolumeMapper() {
  1427. actualCallCount := mapper.GetMapPodDeviceCallCount()
  1428. if actualCallCount >= expectedMapPodDeviceCallCount {
  1429. return nil
  1430. }
  1431. }
  1432. return fmt.Errorf(
  1433. "No Mapper have expected MapPodDeviceCallCount. Expected: <%v>.",
  1434. expectedMapPodDeviceCallCount)
  1435. }
  1436. // GetTestVolumePluginMgr creates, initializes, and returns a test volume plugin
  1437. // manager and fake volume plugin using a fake volume host.
  1438. func GetTestVolumePluginMgr(
  1439. t *testing.T) (*VolumePluginMgr, *FakeVolumePlugin) {
  1440. plugins := ProbeVolumePlugins(VolumeConfig{})
  1441. v := NewFakeVolumeHost(
  1442. t,
  1443. "", /* rootDir */
  1444. nil, /* kubeClient */
  1445. plugins, /* plugins */
  1446. )
  1447. return v.pluginMgr, plugins[0].(*FakeVolumePlugin)
  1448. }
  1449. // CreateTestPVC returns a provisionable PVC for tests
  1450. func CreateTestPVC(capacity string, accessModes []v1.PersistentVolumeAccessMode) *v1.PersistentVolumeClaim {
  1451. claim := v1.PersistentVolumeClaim{
  1452. ObjectMeta: metav1.ObjectMeta{
  1453. Name: "dummy",
  1454. Namespace: "default",
  1455. },
  1456. Spec: v1.PersistentVolumeClaimSpec{
  1457. AccessModes: accessModes,
  1458. Resources: v1.ResourceRequirements{
  1459. Requests: v1.ResourceList{
  1460. v1.ResourceName(v1.ResourceStorage): resource.MustParse(capacity),
  1461. },
  1462. },
  1463. },
  1464. }
  1465. return &claim
  1466. }
  1467. func MetricsEqualIgnoreTimestamp(a *Metrics, b *Metrics) bool {
  1468. available := a.Available == b.Available
  1469. capacity := a.Capacity == b.Capacity
  1470. used := a.Used == b.Used
  1471. inodes := a.Inodes == b.Inodes
  1472. inodesFree := a.InodesFree == b.InodesFree
  1473. inodesUsed := a.InodesUsed == b.InodesUsed
  1474. return available && capacity && used && inodes && inodesFree && inodesUsed
  1475. }
  1476. func ContainsAccessMode(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool {
  1477. for _, m := range modes {
  1478. if m == mode {
  1479. return true
  1480. }
  1481. }
  1482. return false
  1483. }
  1484. func (f *fakeVolumeHost) CSIDriverLister() storagelisters.CSIDriverLister {
  1485. return f.csiDriverLister
  1486. }
  1487. func (f *fakeVolumeHost) CSIDriversSynced() cache.InformerSynced {
  1488. // not needed for testing
  1489. return nil
  1490. }
  1491. func (f *fakeVolumeHost) CSINodeLister() storagelistersv1.CSINodeLister {
  1492. // not needed for testing
  1493. return nil
  1494. }
  1495. func (f *fakeVolumeHost) GetInformerFactory() informers.SharedInformerFactory {
  1496. return f.informerFactory
  1497. }
  1498. func (f *fakeVolumeHost) IsAttachDetachController() bool {
  1499. return true
  1500. }
  1501. func (f *fakeVolumeHost) SetKubeletError(err error) {
  1502. f.mux.Lock()
  1503. defer f.mux.Unlock()
  1504. f.kubeletErr = err
  1505. return
  1506. }
  1507. func (f *fakeVolumeHost) WaitForCacheSync() error {
  1508. return nil
  1509. }
  1510. func (f *fakeVolumeHost) WaitForKubeletErrNil() error {
  1511. return wait.PollImmediate(100*time.Millisecond, 10*time.Second, func() (bool, error) {
  1512. f.mux.Lock()
  1513. defer f.mux.Unlock()
  1514. return f.kubeletErr == nil, nil
  1515. })
  1516. }