binder_test.go 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. /*
  2. Copyright 2016 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package persistentvolume
  14. import (
  15. "testing"
  16. "k8s.io/kubernetes/pkg/api"
  17. "k8s.io/kubernetes/pkg/apis/extensions"
  18. )
  19. // Test single call to syncClaim and syncVolume methods.
  20. // 1. Fill in the controller with initial data
  21. // 2. Call the tested function (syncClaim/syncVolume) via
  22. // controllerTest.testCall *once*.
  23. // 3. Compare resulting volumes and claims with expected volumes and claims.
  24. func TestSync(t *testing.T) {
  25. labels := map[string]string{
  26. "foo": "true",
  27. "bar": "false",
  28. }
  29. tests := []controllerTest{
  30. // [Unit test set 1] User did not care which PV they get.
  31. // Test the matching with no claim.Spec.VolumeName and with various
  32. // volumes.
  33. {
  34. // syncClaim binds to a matching unbound volume.
  35. "1-1 - successful bind",
  36. newVolumeArray("volume1-1", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
  37. newVolumeArray("volume1-1", "1Gi", "uid1-1", "claim1-1", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
  38. newClaimArray("claim1-1", "uid1-1", "1Gi", "", api.ClaimPending),
  39. newClaimArray("claim1-1", "uid1-1", "1Gi", "volume1-1", api.ClaimBound, annBoundByController, annBindCompleted),
  40. noevents, noerrors, testSyncClaim,
  41. },
  42. {
  43. // syncClaim does not do anything when there is no matching volume.
  44. "1-2 - noop",
  45. newVolumeArray("volume1-2", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
  46. newVolumeArray("volume1-2", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
  47. newClaimArray("claim1-2", "uid1-2", "10Gi", "", api.ClaimPending),
  48. newClaimArray("claim1-2", "uid1-2", "10Gi", "", api.ClaimPending),
  49. noevents, noerrors, testSyncClaim,
  50. },
  51. {
  52. // syncClaim resets claim.Status to Pending when there is no
  53. // matching volume.
  54. "1-3 - reset to Pending",
  55. newVolumeArray("volume1-3", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
  56. newVolumeArray("volume1-3", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
  57. newClaimArray("claim1-3", "uid1-3", "10Gi", "", api.ClaimBound),
  58. newClaimArray("claim1-3", "uid1-3", "10Gi", "", api.ClaimPending),
  59. noevents, noerrors, testSyncClaim,
  60. },
  61. {
  62. // syncClaim binds claims to the smallest matching volume
  63. "1-4 - smallest volume",
  64. []*api.PersistentVolume{
  65. newVolume("volume1-4_1", "10Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
  66. newVolume("volume1-4_2", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
  67. },
  68. []*api.PersistentVolume{
  69. newVolume("volume1-4_1", "10Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
  70. newVolume("volume1-4_2", "1Gi", "uid1-4", "claim1-4", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
  71. },
  72. newClaimArray("claim1-4", "uid1-4", "1Gi", "", api.ClaimPending),
  73. newClaimArray("claim1-4", "uid1-4", "1Gi", "volume1-4_2", api.ClaimBound, annBoundByController, annBindCompleted),
  74. noevents, noerrors, testSyncClaim,
  75. },
  76. {
  77. // syncClaim binds a claim only to volume that points to it (by
  78. // name), even though a smaller one is available.
  79. "1-5 - prebound volume by name - success",
  80. []*api.PersistentVolume{
  81. newVolume("volume1-5_1", "10Gi", "", "claim1-5", api.VolumePending, api.PersistentVolumeReclaimRetain),
  82. newVolume("volume1-5_2", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
  83. },
  84. []*api.PersistentVolume{
  85. newVolume("volume1-5_1", "10Gi", "uid1-5", "claim1-5", api.VolumeBound, api.PersistentVolumeReclaimRetain),
  86. newVolume("volume1-5_2", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
  87. },
  88. newClaimArray("claim1-5", "uid1-5", "1Gi", "", api.ClaimPending),
  89. withExpectedCapacity("10Gi", newClaimArray("claim1-5", "uid1-5", "1Gi", "volume1-5_1", api.ClaimBound, annBoundByController, annBindCompleted)),
  90. noevents, noerrors, testSyncClaim,
  91. },
  92. {
  93. // syncClaim binds a claim only to volume that points to it (by
  94. // UID), even though a smaller one is available.
  95. "1-6 - prebound volume by UID - success",
  96. []*api.PersistentVolume{
  97. newVolume("volume1-6_1", "10Gi", "uid1-6", "claim1-6", api.VolumePending, api.PersistentVolumeReclaimRetain),
  98. newVolume("volume1-6_2", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
  99. },
  100. []*api.PersistentVolume{
  101. newVolume("volume1-6_1", "10Gi", "uid1-6", "claim1-6", api.VolumeBound, api.PersistentVolumeReclaimRetain),
  102. newVolume("volume1-6_2", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
  103. },
  104. newClaimArray("claim1-6", "uid1-6", "1Gi", "", api.ClaimPending),
  105. withExpectedCapacity("10Gi", newClaimArray("claim1-6", "uid1-6", "1Gi", "volume1-6_1", api.ClaimBound, annBoundByController, annBindCompleted)),
  106. noevents, noerrors, testSyncClaim,
  107. },
  108. {
  109. // syncClaim does not bind claim to a volume prebound to a claim with
  110. // same name and different UID
  111. "1-7 - prebound volume to different claim",
  112. newVolumeArray("volume1-7", "10Gi", "uid1-777", "claim1-7", api.VolumePending, api.PersistentVolumeReclaimRetain),
  113. newVolumeArray("volume1-7", "10Gi", "uid1-777", "claim1-7", api.VolumePending, api.PersistentVolumeReclaimRetain),
  114. newClaimArray("claim1-7", "uid1-7", "1Gi", "", api.ClaimPending),
  115. newClaimArray("claim1-7", "uid1-7", "1Gi", "", api.ClaimPending),
  116. noevents, noerrors, testSyncClaim,
  117. },
  118. {
  119. // syncClaim completes binding - simulates controller crash after
  120. // PV.ClaimRef is saved
  121. "1-8 - complete bind after crash - PV bound",
  122. newVolumeArray("volume1-8", "1Gi", "uid1-8", "claim1-8", api.VolumePending, api.PersistentVolumeReclaimRetain, annBoundByController),
  123. newVolumeArray("volume1-8", "1Gi", "uid1-8", "claim1-8", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
  124. newClaimArray("claim1-8", "uid1-8", "1Gi", "", api.ClaimPending),
  125. newClaimArray("claim1-8", "uid1-8", "1Gi", "volume1-8", api.ClaimBound, annBoundByController, annBindCompleted),
  126. noevents, noerrors, testSyncClaim,
  127. },
  128. {
  129. // syncClaim completes binding - simulates controller crash after
  130. // PV.Status is saved
  131. "1-9 - complete bind after crash - PV status saved",
  132. newVolumeArray("volume1-9", "1Gi", "uid1-9", "claim1-9", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
  133. newVolumeArray("volume1-9", "1Gi", "uid1-9", "claim1-9", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
  134. newClaimArray("claim1-9", "uid1-9", "1Gi", "", api.ClaimPending),
  135. newClaimArray("claim1-9", "uid1-9", "1Gi", "volume1-9", api.ClaimBound, annBoundByController, annBindCompleted),
  136. noevents, noerrors, testSyncClaim,
  137. },
  138. {
  139. // syncClaim completes binding - simulates controller crash after
  140. // PVC.VolumeName is saved
  141. "1-10 - complete bind after crash - PVC bound",
  142. newVolumeArray("volume1-10", "1Gi", "uid1-10", "claim1-10", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
  143. newVolumeArray("volume1-10", "1Gi", "uid1-10", "claim1-10", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
  144. newClaimArray("claim1-10", "uid1-10", "1Gi", "volume1-10", api.ClaimPending, annBoundByController, annBindCompleted),
  145. newClaimArray("claim1-10", "uid1-10", "1Gi", "volume1-10", api.ClaimBound, annBoundByController, annBindCompleted),
  146. noevents, noerrors, testSyncClaim,
  147. },
  148. {
  149. // syncClaim binds a claim only when the label selector matches the volume
  150. "1-11 - bind when selector matches",
  151. withLabels(labels, newVolumeArray("volume1-1", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain)),
  152. withLabels(labels, newVolumeArray("volume1-1", "1Gi", "uid1-1", "claim1-1", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController)),
  153. withLabelSelector(labels, newClaimArray("claim1-1", "uid1-1", "1Gi", "", api.ClaimPending)),
  154. withLabelSelector(labels, newClaimArray("claim1-1", "uid1-1", "1Gi", "volume1-1", api.ClaimBound, annBoundByController, annBindCompleted)),
  155. noevents, noerrors, testSyncClaim,
  156. },
  157. {
  158. // syncClaim does not bind a claim when the label selector doesn't match
  159. "1-12 - do not bind when selector does not match",
  160. newVolumeArray("volume1-1", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
  161. newVolumeArray("volume1-1", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
  162. withLabelSelector(labels, newClaimArray("claim1-1", "uid1-1", "1Gi", "", api.ClaimPending)),
  163. withLabelSelector(labels, newClaimArray("claim1-1", "uid1-1", "1Gi", "", api.ClaimPending)),
  164. noevents, noerrors, testSyncClaim,
  165. },
  166. // [Unit test set 2] User asked for a specific PV.
  167. // Test the binding when pv.ClaimRef is already set by controller or
  168. // by user.
  169. {
  170. // syncClaim with claim pre-bound to a PV that does not exist
  171. "2-1 - claim prebound to non-existing volume - noop",
  172. novolumes,
  173. novolumes,
  174. newClaimArray("claim2-1", "uid2-1", "10Gi", "volume2-1", api.ClaimPending),
  175. newClaimArray("claim2-1", "uid2-1", "10Gi", "volume2-1", api.ClaimPending),
  176. noevents, noerrors, testSyncClaim,
  177. },
  178. {
  179. // syncClaim with claim pre-bound to a PV that does not exist.
  180. // Check that the claim status is reset to Pending
  181. "2-2 - claim prebound to non-existing volume - reset status",
  182. novolumes,
  183. novolumes,
  184. newClaimArray("claim2-2", "uid2-2", "10Gi", "volume2-2", api.ClaimBound),
  185. newClaimArray("claim2-2", "uid2-2", "10Gi", "volume2-2", api.ClaimPending),
  186. noevents, noerrors, testSyncClaim,
  187. },
  188. {
  189. // syncClaim with claim pre-bound to a PV that exists and is
  190. // unbound. Check it gets bound and no annBoundByController is set.
  191. "2-3 - claim prebound to unbound volume",
  192. newVolumeArray("volume2-3", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
  193. newVolumeArray("volume2-3", "1Gi", "uid2-3", "claim2-3", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
  194. newClaimArray("claim2-3", "uid2-3", "1Gi", "volume2-3", api.ClaimPending),
  195. newClaimArray("claim2-3", "uid2-3", "1Gi", "volume2-3", api.ClaimBound, annBindCompleted),
  196. noevents, noerrors, testSyncClaim,
  197. },
  198. {
  199. // claim with claim pre-bound to a PV that is pre-bound to the claim
  200. // by name. Check it gets bound and no annBoundByController is set.
  201. "2-4 - claim prebound to prebound volume by name",
  202. newVolumeArray("volume2-4", "1Gi", "", "claim2-4", api.VolumePending, api.PersistentVolumeReclaimRetain),
  203. newVolumeArray("volume2-4", "1Gi", "uid2-4", "claim2-4", api.VolumeBound, api.PersistentVolumeReclaimRetain),
  204. newClaimArray("claim2-4", "uid2-4", "1Gi", "volume2-4", api.ClaimPending),
  205. newClaimArray("claim2-4", "uid2-4", "1Gi", "volume2-4", api.ClaimBound, annBindCompleted),
  206. noevents, noerrors, testSyncClaim,
  207. },
  208. {
  209. // syncClaim with claim pre-bound to a PV that is pre-bound to the
  210. // claim by UID. Check it gets bound and no annBoundByController is
  211. // set.
  212. "2-5 - claim prebound to prebound volume by UID",
  213. newVolumeArray("volume2-5", "1Gi", "uid2-5", "claim2-5", api.VolumePending, api.PersistentVolumeReclaimRetain),
  214. newVolumeArray("volume2-5", "1Gi", "uid2-5", "claim2-5", api.VolumeBound, api.PersistentVolumeReclaimRetain),
  215. newClaimArray("claim2-5", "uid2-5", "1Gi", "volume2-5", api.ClaimPending),
  216. newClaimArray("claim2-5", "uid2-5", "1Gi", "volume2-5", api.ClaimBound, annBindCompleted),
  217. noevents, noerrors, testSyncClaim,
  218. },
  219. {
  220. // syncClaim with claim pre-bound to a PV that is bound to different
  221. // claim. Check it's reset to Pending.
  222. "2-6 - claim prebound to already bound volume",
  223. newVolumeArray("volume2-6", "1Gi", "uid2-6_1", "claim2-6_1", api.VolumeBound, api.PersistentVolumeReclaimRetain),
  224. newVolumeArray("volume2-6", "1Gi", "uid2-6_1", "claim2-6_1", api.VolumeBound, api.PersistentVolumeReclaimRetain),
  225. newClaimArray("claim2-6", "uid2-6", "1Gi", "volume2-6", api.ClaimBound),
  226. newClaimArray("claim2-6", "uid2-6", "1Gi", "volume2-6", api.ClaimPending),
  227. noevents, noerrors, testSyncClaim,
  228. },
  229. {
  230. // syncClaim with claim bound by controller to a PV that is bound to
  231. // different claim. Check it throws an error.
  232. "2-7 - claim bound by controller to already bound volume",
  233. newVolumeArray("volume2-7", "1Gi", "uid2-7_1", "claim2-7_1", api.VolumeBound, api.PersistentVolumeReclaimRetain),
  234. newVolumeArray("volume2-7", "1Gi", "uid2-7_1", "claim2-7_1", api.VolumeBound, api.PersistentVolumeReclaimRetain),
  235. newClaimArray("claim2-7", "uid2-7", "1Gi", "volume2-7", api.ClaimBound, annBoundByController),
  236. newClaimArray("claim2-7", "uid2-7", "1Gi", "volume2-7", api.ClaimBound, annBoundByController),
  237. noevents, noerrors, testSyncClaimError,
  238. },
  239. {
  240. // syncClaim with claim pre-bound to a PV that exists and is
  241. // unbound, but does not match the selector. Check it gets bound
  242. // and no annBoundByController is set.
  243. "2-8 - claim prebound to unbound volume that does not match the selector",
  244. newVolumeArray("volume2-3", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
  245. newVolumeArray("volume2-3", "1Gi", "uid2-3", "claim2-3", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
  246. withLabelSelector(labels, newClaimArray("claim2-3", "uid2-3", "1Gi", "volume2-3", api.ClaimPending)),
  247. withLabelSelector(labels, newClaimArray("claim2-3", "uid2-3", "1Gi", "volume2-3", api.ClaimBound, annBindCompleted)),
  248. noevents, noerrors, testSyncClaim,
  249. },
  250. // [Unit test set 3] Syncing bound claim
  251. {
  252. // syncClaim with claim bound and its claim.Spec.VolumeName is
  253. // removed. Check it's marked as Lost.
  254. "3-1 - bound claim with missing VolumeName",
  255. novolumes,
  256. novolumes,
  257. newClaimArray("claim3-1", "uid3-1", "10Gi", "", api.ClaimBound, annBoundByController, annBindCompleted),
  258. newClaimArray("claim3-1", "uid3-1", "10Gi", "", api.ClaimLost, annBoundByController, annBindCompleted),
  259. []string{"Warning ClaimLost"}, noerrors, testSyncClaim,
  260. },
  261. {
  262. // syncClaim with claim bound to non-existing volume. Check it's
  263. // marked as Lost.
  264. "3-2 - bound claim with missing volume",
  265. novolumes,
  266. novolumes,
  267. newClaimArray("claim3-2", "uid3-2", "10Gi", "volume3-2", api.ClaimBound, annBoundByController, annBindCompleted),
  268. newClaimArray("claim3-2", "uid3-2", "10Gi", "volume3-2", api.ClaimLost, annBoundByController, annBindCompleted),
  269. []string{"Warning ClaimLost"}, noerrors, testSyncClaim,
  270. },
  271. {
  272. // syncClaim with claim bound to unbound volume. Check it's bound.
  273. // Also check that Pending phase is set to Bound
  274. "3-3 - bound claim with unbound volume",
  275. newVolumeArray("volume3-3", "10Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
  276. newVolumeArray("volume3-3", "10Gi", "uid3-3", "claim3-3", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
  277. newClaimArray("claim3-3", "uid3-3", "10Gi", "volume3-3", api.ClaimPending, annBoundByController, annBindCompleted),
  278. newClaimArray("claim3-3", "uid3-3", "10Gi", "volume3-3", api.ClaimBound, annBoundByController, annBindCompleted),
  279. noevents, noerrors, testSyncClaim,
  280. },
  281. {
  282. // syncClaim with claim bound to volume with missing (or different)
  283. // volume.Spec.ClaimRef.UID. Check that the claim is marked as lost.
  284. "3-4 - bound claim with prebound volume",
  285. newVolumeArray("volume3-4", "10Gi", "claim3-4-x", "claim3-4", api.VolumePending, api.PersistentVolumeReclaimRetain),
  286. newVolumeArray("volume3-4", "10Gi", "claim3-4-x", "claim3-4", api.VolumePending, api.PersistentVolumeReclaimRetain),
  287. newClaimArray("claim3-4", "uid3-4", "10Gi", "volume3-4", api.ClaimPending, annBoundByController, annBindCompleted),
  288. newClaimArray("claim3-4", "uid3-4", "10Gi", "volume3-4", api.ClaimLost, annBoundByController, annBindCompleted),
  289. []string{"Warning ClaimMisbound"}, noerrors, testSyncClaim,
  290. },
  291. {
  292. // syncClaim with claim bound to bound volume. Check that the
  293. // controller does not do anything. Also check that Pending phase is
  294. // set to Bound
  295. "3-5 - bound claim with bound volume",
  296. newVolumeArray("volume3-5", "10Gi", "uid3-5", "claim3-5", api.VolumePending, api.PersistentVolumeReclaimRetain),
  297. newVolumeArray("volume3-5", "10Gi", "uid3-5", "claim3-5", api.VolumeBound, api.PersistentVolumeReclaimRetain),
  298. newClaimArray("claim3-5", "uid3-5", "10Gi", "volume3-5", api.ClaimPending, annBindCompleted),
  299. newClaimArray("claim3-5", "uid3-5", "10Gi", "volume3-5", api.ClaimBound, annBindCompleted),
  300. noevents, noerrors, testSyncClaim,
  301. },
  302. {
  303. // syncClaim with claim bound to a volume that is bound to different
  304. // claim. Check that the claim is marked as lost.
  305. // TODO: test that an event is emitted
  306. "3-6 - bound claim with bound volume",
  307. newVolumeArray("volume3-6", "10Gi", "uid3-6-x", "claim3-6-x", api.VolumePending, api.PersistentVolumeReclaimRetain),
  308. newVolumeArray("volume3-6", "10Gi", "uid3-6-x", "claim3-6-x", api.VolumePending, api.PersistentVolumeReclaimRetain),
  309. newClaimArray("claim3-6", "uid3-6", "10Gi", "volume3-6", api.ClaimPending, annBindCompleted),
  310. newClaimArray("claim3-6", "uid3-6", "10Gi", "volume3-6", api.ClaimLost, annBindCompleted),
  311. []string{"Warning ClaimMisbound"}, noerrors, testSyncClaim,
  312. },
  313. {
  314. // syncClaim with claim bound to unbound volume. Check it's bound
  315. // even if the claim's selector doesn't match the volume. Also
  316. // check that Pending phase is set to Bound
  317. "3-7 - bound claim with unbound volume where selector doesn't match",
  318. newVolumeArray("volume3-3", "10Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
  319. newVolumeArray("volume3-3", "10Gi", "uid3-3", "claim3-3", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
  320. withLabelSelector(labels, newClaimArray("claim3-3", "uid3-3", "10Gi", "volume3-3", api.ClaimPending, annBoundByController, annBindCompleted)),
  321. withLabelSelector(labels, newClaimArray("claim3-3", "uid3-3", "10Gi", "volume3-3", api.ClaimBound, annBoundByController, annBindCompleted)),
  322. noevents, noerrors, testSyncClaim,
  323. },
  324. // [Unit test set 4] All syncVolume tests.
  325. {
  326. // syncVolume with pending volume. Check it's marked as Available.
  327. "4-1 - pending volume",
  328. newVolumeArray("volume4-1", "10Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
  329. newVolumeArray("volume4-1", "10Gi", "", "", api.VolumeAvailable, api.PersistentVolumeReclaimRetain),
  330. noclaims,
  331. noclaims,
  332. noevents, noerrors, testSyncVolume,
  333. },
  334. {
  335. // syncVolume with prebound pending volume. Check it's marked as
  336. // Available.
  337. "4-2 - pending prebound volume",
  338. newVolumeArray("volume4-2", "10Gi", "", "claim4-2", api.VolumePending, api.PersistentVolumeReclaimRetain),
  339. newVolumeArray("volume4-2", "10Gi", "", "claim4-2", api.VolumeAvailable, api.PersistentVolumeReclaimRetain),
  340. noclaims,
  341. noclaims,
  342. noevents, noerrors, testSyncVolume,
  343. },
  344. {
  345. // syncVolume with volume bound to missing claim.
  346. // Check the volume gets Released
  347. "4-3 - bound volume with missing claim",
  348. newVolumeArray("volume4-3", "10Gi", "uid4-3", "claim4-3", api.VolumeBound, api.PersistentVolumeReclaimRetain),
  349. newVolumeArray("volume4-3", "10Gi", "uid4-3", "claim4-3", api.VolumeReleased, api.PersistentVolumeReclaimRetain),
  350. noclaims,
  351. noclaims,
  352. noevents, noerrors, testSyncVolume,
  353. },
  354. {
  355. // syncVolume with volume bound to claim with different UID.
  356. // Check the volume gets Released.
  357. "4-4 - volume bound to claim with different UID",
  358. newVolumeArray("volume4-4", "10Gi", "uid4-4", "claim4-4", api.VolumeBound, api.PersistentVolumeReclaimRetain),
  359. newVolumeArray("volume4-4", "10Gi", "uid4-4", "claim4-4", api.VolumeReleased, api.PersistentVolumeReclaimRetain),
  360. newClaimArray("claim4-4", "uid4-4-x", "10Gi", "volume4-4", api.ClaimBound, annBindCompleted),
  361. newClaimArray("claim4-4", "uid4-4-x", "10Gi", "volume4-4", api.ClaimBound, annBindCompleted),
  362. noevents, noerrors, testSyncVolume,
  363. },
  364. {
  365. // syncVolume with volume bound by controller to unbound claim.
  366. // Check syncVolume does not do anything.
  367. "4-5 - volume bound by controller to unbound claim",
  368. newVolumeArray("volume4-5", "10Gi", "uid4-5", "claim4-5", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
  369. newVolumeArray("volume4-5", "10Gi", "uid4-5", "claim4-5", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
  370. newClaimArray("claim4-5", "uid4-5", "10Gi", "", api.ClaimPending),
  371. newClaimArray("claim4-5", "uid4-5", "10Gi", "", api.ClaimPending),
  372. noevents, noerrors, testSyncVolume,
  373. },
  374. {
  375. // syncVolume with volume bound by user to unbound claim.
  376. // Check syncVolume does not do anything.
  377. "4-5 - volume bound by user to bound claim",
  378. newVolumeArray("volume4-5", "10Gi", "uid4-5", "claim4-5", api.VolumeBound, api.PersistentVolumeReclaimRetain),
  379. newVolumeArray("volume4-5", "10Gi", "uid4-5", "claim4-5", api.VolumeBound, api.PersistentVolumeReclaimRetain),
  380. newClaimArray("claim4-5", "uid4-5", "10Gi", "", api.ClaimPending),
  381. newClaimArray("claim4-5", "uid4-5", "10Gi", "", api.ClaimPending),
  382. noevents, noerrors, testSyncVolume,
  383. },
  384. {
  385. // syncVolume with volume bound to bound claim.
  386. // Check that the volume is marked as Bound.
  387. "4-6 - volume bound by to bound claim",
  388. newVolumeArray("volume4-6", "10Gi", "uid4-6", "claim4-6", api.VolumeAvailable, api.PersistentVolumeReclaimRetain),
  389. newVolumeArray("volume4-6", "10Gi", "uid4-6", "claim4-6", api.VolumeBound, api.PersistentVolumeReclaimRetain),
  390. newClaimArray("claim4-6", "uid4-6", "10Gi", "volume4-6", api.ClaimBound),
  391. newClaimArray("claim4-6", "uid4-6", "10Gi", "volume4-6", api.ClaimBound),
  392. noevents, noerrors, testSyncVolume,
  393. },
  394. {
  395. // syncVolume with volume bound by controller to claim bound to
  396. // another volume. Check that the volume is rolled back.
  397. "4-7 - volume bound by controller to claim bound somewhere else",
  398. newVolumeArray("volume4-7", "10Gi", "uid4-7", "claim4-7", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
  399. newVolumeArray("volume4-7", "10Gi", "", "", api.VolumeAvailable, api.PersistentVolumeReclaimRetain),
  400. newClaimArray("claim4-7", "uid4-7", "10Gi", "volume4-7-x", api.ClaimBound),
  401. newClaimArray("claim4-7", "uid4-7", "10Gi", "volume4-7-x", api.ClaimBound),
  402. noevents, noerrors, testSyncVolume,
  403. },
  404. {
  405. // syncVolume with volume bound by user to claim bound to
  406. // another volume. Check that the volume is marked as Available
  407. // and its UID is reset.
  408. "4-8 - volume bound by user to claim bound somewhere else",
  409. newVolumeArray("volume4-8", "10Gi", "uid4-8", "claim4-8", api.VolumeBound, api.PersistentVolumeReclaimRetain),
  410. newVolumeArray("volume4-8", "10Gi", "", "claim4-8", api.VolumeAvailable, api.PersistentVolumeReclaimRetain),
  411. newClaimArray("claim4-8", "uid4-8", "10Gi", "volume4-8-x", api.ClaimBound),
  412. newClaimArray("claim4-8", "uid4-8", "10Gi", "volume4-8-x", api.ClaimBound),
  413. noevents, noerrors, testSyncVolume,
  414. },
  415. // PVC with class
  416. {
  417. // syncVolume binds a claim to requested class even if there is a
  418. // smaller PV available
  419. "13-1 - binding to class",
  420. []*api.PersistentVolume{
  421. newVolume("volume13-1-1", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
  422. newVolume("volume13-1-2", "10Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain, annClass),
  423. },
  424. []*api.PersistentVolume{
  425. newVolume("volume13-1-1", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
  426. newVolume("volume13-1-2", "10Gi", "uid13-1", "claim13-1", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController, annClass),
  427. },
  428. newClaimArray("claim13-1", "uid13-1", "1Gi", "", api.ClaimPending, annClass),
  429. withExpectedCapacity("10Gi", newClaimArray("claim13-1", "uid13-1", "1Gi", "volume13-1-2", api.ClaimBound, annBoundByController, annClass, annBindCompleted)),
  430. noevents, noerrors, testSyncClaim,
  431. },
  432. {
  433. // syncVolume binds a claim without a class even if there is a
  434. // smaller PV with a class available
  435. "13-2 - binding without a class",
  436. []*api.PersistentVolume{
  437. newVolume("volume13-2-1", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain, annClass),
  438. newVolume("volume13-2-2", "10Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
  439. },
  440. []*api.PersistentVolume{
  441. newVolume("volume13-2-1", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain, annClass),
  442. newVolume("volume13-2-2", "10Gi", "uid13-2", "claim13-2", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
  443. },
  444. newClaimArray("claim13-2", "uid13-2", "1Gi", "", api.ClaimPending),
  445. withExpectedCapacity("10Gi", newClaimArray("claim13-2", "uid13-2", "1Gi", "volume13-2-2", api.ClaimBound, annBoundByController, annBindCompleted)),
  446. noevents, noerrors, testSyncClaim,
  447. },
  448. {
  449. // syncVolume binds a claim with given class even if there is a
  450. // smaller PV with different class available
  451. "13-3 - binding to specific a class",
  452. volumeWithClass("silver", []*api.PersistentVolume{
  453. newVolume("volume13-3-1", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
  454. newVolume("volume13-3-2", "10Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain, annClass),
  455. }),
  456. volumeWithClass("silver", []*api.PersistentVolume{
  457. newVolume("volume13-3-1", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
  458. newVolume("volume13-3-2", "10Gi", "uid13-3", "claim13-3", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController, annClass),
  459. }),
  460. newClaimArray("claim13-3", "uid13-3", "1Gi", "", api.ClaimPending, annClass),
  461. withExpectedCapacity("10Gi", newClaimArray("claim13-3", "uid13-3", "1Gi", "volume13-3-2", api.ClaimBound, annBoundByController, annBindCompleted, annClass)),
  462. noevents, noerrors, testSyncClaim,
  463. },
  464. {
  465. // syncVolume binds claim requesting class "" to claim to PV with
  466. // class=""
  467. "13-4 - empty class",
  468. volumeWithClass("", newVolumeArray("volume13-4", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain)),
  469. volumeWithClass("", newVolumeArray("volume13-4", "1Gi", "uid13-4", "claim13-4", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController)),
  470. claimWithClass("", newClaimArray("claim13-4", "uid13-4", "1Gi", "", api.ClaimPending)),
  471. claimWithClass("", newClaimArray("claim13-4", "uid13-4", "1Gi", "volume13-4", api.ClaimBound, annBoundByController, annBindCompleted)),
  472. noevents, noerrors, testSyncClaim,
  473. },
  474. {
  475. // syncVolume binds claim requesting class nil to claim to PV with
  476. // class = ""
  477. "13-5 - nil class",
  478. volumeWithClass("", newVolumeArray("volume13-5", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain)),
  479. volumeWithClass("", newVolumeArray("volume13-5", "1Gi", "uid13-5", "claim13-5", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController)),
  480. newClaimArray("claim13-5", "uid13-5", "1Gi", "", api.ClaimPending),
  481. newClaimArray("claim13-5", "uid13-5", "1Gi", "volume13-5", api.ClaimBound, annBoundByController, annBindCompleted),
  482. noevents, noerrors, testSyncClaim,
  483. },
  484. {
  485. // syncVolume binds claim requesting class "" to claim to PV with
  486. // class=nil
  487. "13-6 - nil class in PV, '' class in claim",
  488. newVolumeArray("volume13-6", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
  489. newVolumeArray("volume13-6", "1Gi", "uid13-6", "claim13-6", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
  490. claimWithClass("", newClaimArray("claim13-6", "uid13-6", "1Gi", "", api.ClaimPending)),
  491. claimWithClass("", newClaimArray("claim13-6", "uid13-6", "1Gi", "volume13-6", api.ClaimBound, annBoundByController, annBindCompleted)),
  492. noevents, noerrors, testSyncClaim,
  493. },
  494. }
  495. runSyncTests(t, tests, []*extensions.StorageClass{})
  496. }
  497. // Test multiple calls to syncClaim/syncVolume and periodic sync of all
  498. // volume/claims. The test follows this pattern:
  499. // 0. Load the controller with initial data.
  500. // 1. Call controllerTest.testCall() once as in TestSync()
  501. // 2. For all volumes/claims changed by previous syncVolume/syncClaim calls,
  502. // call appropriate syncVolume/syncClaim (simulating "volume/claim changed"
  503. // events). Go to 2. if these calls change anything.
  504. // 3. When all changes are processed and no new changes were made, call
  505. // syncVolume/syncClaim on all volumes/claims (simulating "periodic sync").
  506. // 4. If some changes were done by step 3., go to 2. (simulation of
  507. // "volume/claim updated" events, eventually performing step 3. again)
  508. // 5. When 3. does not do any changes, finish the tests and compare final set
  509. // of volumes/claims with expected claims/volumes and report differences.
  510. // Some limit of calls in enforced to prevent endless loops.
  511. func TestMultiSync(t *testing.T) {
  512. tests := []controllerTest{
  513. // Test simple binding
  514. {
  515. // syncClaim binds to a matching unbound volume.
  516. "10-1 - successful bind",
  517. newVolumeArray("volume10-1", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
  518. newVolumeArray("volume10-1", "1Gi", "uid10-1", "claim10-1", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
  519. newClaimArray("claim10-1", "uid10-1", "1Gi", "", api.ClaimPending),
  520. newClaimArray("claim10-1", "uid10-1", "1Gi", "volume10-1", api.ClaimBound, annBoundByController, annBindCompleted),
  521. noevents, noerrors, testSyncClaim,
  522. },
  523. {
  524. // Two controllers bound two PVs to single claim. Test one of them
  525. // wins and the second rolls back.
  526. "10-2 - bind PV race",
  527. []*api.PersistentVolume{
  528. newVolume("volume10-2-1", "1Gi", "uid10-2", "claim10-2", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
  529. newVolume("volume10-2-2", "1Gi", "uid10-2", "claim10-2", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
  530. },
  531. []*api.PersistentVolume{
  532. newVolume("volume10-2-1", "1Gi", "uid10-2", "claim10-2", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
  533. newVolume("volume10-2-2", "1Gi", "", "", api.VolumeAvailable, api.PersistentVolumeReclaimRetain),
  534. },
  535. newClaimArray("claim10-2", "uid10-2", "1Gi", "volume10-2-1", api.ClaimBound, annBoundByController, annBindCompleted),
  536. newClaimArray("claim10-2", "uid10-2", "1Gi", "volume10-2-1", api.ClaimBound, annBoundByController, annBindCompleted),
  537. noevents, noerrors, testSyncClaim,
  538. },
  539. }
  540. runMultisyncTests(t, tests, []*extensions.StorageClass{}, "")
  541. }