apps.sh 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. #!/usr/bin/env bash
  2. # Copyright 2018 The Kubernetes Authors.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. set -o errexit
  16. set -o nounset
  17. set -o pipefail
  18. run_daemonset_tests() {
  19. set -o nounset
  20. set -o errexit
  21. create_and_use_new_namespace
  22. kube::log::status "Testing kubectl(v1:daemonsets)"
  23. ### Create a rolling update DaemonSet
  24. # Pre-condition: no DaemonSet exists
  25. kube::test::get_object_assert daemonsets "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  26. # Command
  27. kubectl apply -f hack/testdata/rollingupdate-daemonset.yaml "${kube_flags[@]:?}"
  28. # Template Generation should be 1
  29. kube::test::get_object_assert 'daemonsets bind' "{{${template_generation_field:?}}}" '1'
  30. kubectl apply -f hack/testdata/rollingupdate-daemonset.yaml "${kube_flags[@]:?}"
  31. # Template Generation should stay 1
  32. kube::test::get_object_assert 'daemonsets bind' "{{${template_generation_field:?}}}" '1'
  33. # Test set commands
  34. kubectl set image daemonsets/bind "${kube_flags[@]:?}" "*=k8s.gcr.io/pause:test-cmd"
  35. kube::test::get_object_assert 'daemonsets bind' "{{${template_generation_field:?}}}" '2'
  36. kubectl set env daemonsets/bind "${kube_flags[@]:?}" foo=bar
  37. kube::test::get_object_assert 'daemonsets bind' "{{${template_generation_field:?}}}" '3'
  38. kubectl set resources daemonsets/bind "${kube_flags[@]:?}" --limits=cpu=200m,memory=512Mi
  39. kube::test::get_object_assert 'daemonsets bind' "{{${template_generation_field:?}}}" '4'
  40. # Rollout restart should change generation
  41. kubectl rollout restart daemonset/bind "${kube_flags[@]}"
  42. kube::test::get_object_assert 'daemonsets bind' "{{${template_generation_field}}}" '5'
  43. # Clean up
  44. kubectl delete -f hack/testdata/rollingupdate-daemonset.yaml "${kube_flags[@]:?}"
  45. set +o nounset
  46. set +o errexit
  47. }
  48. run_daemonset_history_tests() {
  49. set -o nounset
  50. set -o errexit
  51. create_and_use_new_namespace
  52. kube::log::status "Testing kubectl(v1:daemonsets, v1:controllerrevisions)"
  53. ### Test rolling back a DaemonSet
  54. # Pre-condition: no DaemonSet or its pods exists
  55. kube::test::get_object_assert daemonsets "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  56. # Command
  57. # Create a DaemonSet (revision 1)
  58. kubectl apply -f hack/testdata/rollingupdate-daemonset.yaml --record "${kube_flags[@]:?}"
  59. kube::test::wait_object_assert controllerrevisions "{{range.items}}{{${annotations_field:?}}}:{{end}}" ".*rollingupdate-daemonset.yaml --record.*"
  60. # Rollback to revision 1 - should be no-op
  61. kubectl rollout undo daemonset --to-revision=1 "${kube_flags[@]:?}"
  62. kube::test::get_object_assert daemonset "{{range.items}}{{${image_field0:?}}}:{{end}}" "${IMAGE_PAUSE_V2}:"
  63. kube::test::get_object_assert daemonset "{{range.items}}{{${container_len:?}}}{{end}}" "1"
  64. # Update the DaemonSet (revision 2)
  65. kubectl apply -f hack/testdata/rollingupdate-daemonset-rv2.yaml --record "${kube_flags[@]:?}"
  66. kube::test::wait_object_assert daemonset "{{range.items}}{{${image_field0:?}}}:{{end}}" "${IMAGE_DAEMONSET_R2}:"
  67. kube::test::wait_object_assert daemonset "{{range.items}}{{${image_field1:?}}}:{{end}}" "${IMAGE_DAEMONSET_R2_2}:"
  68. kube::test::get_object_assert daemonset "{{range.items}}{{${container_len:?}}}{{end}}" "2"
  69. kube::test::wait_object_assert controllerrevisions "{{range.items}}{{${annotations_field:?}}}:{{end}}" ".*rollingupdate-daemonset-rv2.yaml --record.*"
  70. # Rollback to revision 1 with dry-run - should be no-op
  71. kubectl rollout undo daemonset --dry-run=true "${kube_flags[@]:?}"
  72. kube::test::get_object_assert daemonset "{{range.items}}{{${image_field0:?}}}:{{end}}" "${IMAGE_DAEMONSET_R2}:"
  73. kube::test::get_object_assert daemonset "{{range.items}}{{${image_field1:?}}}:{{end}}" "${IMAGE_DAEMONSET_R2_2}:"
  74. kube::test::get_object_assert daemonset "{{range.items}}{{${container_len:?}}}{{end}}" "2"
  75. # Rollback to revision 1
  76. kubectl rollout undo daemonset --to-revision=1 "${kube_flags[@]:?}"
  77. kube::test::wait_object_assert daemonset "{{range.items}}{{${image_field0:?}}}:{{end}}" "${IMAGE_PAUSE_V2}:"
  78. kube::test::get_object_assert daemonset "{{range.items}}{{${container_len:?}}}{{end}}" "1"
  79. # Rollback to revision 1000000 - should fail
  80. output_message=$(! kubectl rollout undo daemonset --to-revision=1000000 "${kube_flags[@]:?}" 2>&1)
  81. kube::test::if_has_string "${output_message}" "unable to find specified revision"
  82. kube::test::get_object_assert daemonset "{{range.items}}{{${image_field0:?}}}:{{end}}" "${IMAGE_PAUSE_V2}:"
  83. kube::test::get_object_assert daemonset "{{range.items}}{{${container_len:?}}}{{end}}" "1"
  84. # Rollback to last revision
  85. kubectl rollout undo daemonset "${kube_flags[@]:?}"
  86. kube::test::wait_object_assert daemonset "{{range.items}}{{${image_field0:?}}}:{{end}}" "${IMAGE_DAEMONSET_R2}:"
  87. kube::test::wait_object_assert daemonset "{{range.items}}{{${image_field1:?}}}:{{end}}" "${IMAGE_DAEMONSET_R2_2}:"
  88. kube::test::get_object_assert daemonset "{{range.items}}{{${container_len:?}}}{{end}}" "2"
  89. # Clean up
  90. kubectl delete -f hack/testdata/rollingupdate-daemonset.yaml "${kube_flags[@]:?}"
  91. set +o nounset
  92. set +o errexit
  93. }
  94. run_kubectl_apply_deployments_tests() {
  95. set -o nounset
  96. set -o errexit
  97. create_and_use_new_namespace
  98. kube::log::status "Testing kubectl apply deployments"
  99. ## kubectl apply should propagate user defined null values
  100. # Pre-Condition: no Deployments, ReplicaSets, Pods exist
  101. kube::test::get_object_assert deployments "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  102. kube::test::get_object_assert replicasets "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  103. kube::test::get_object_assert pods "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  104. # apply base deployment
  105. kubectl apply -f hack/testdata/null-propagation/deployment-l1.yaml "${kube_flags[@]:?}"
  106. # check right deployment exists
  107. kube::test::get_object_assert 'deployments my-depl' "{{${id_field:?}}}" 'my-depl'
  108. # check right labels exists
  109. kube::test::get_object_assert 'deployments my-depl' "{{.spec.template.metadata.labels.l1}}" 'l1'
  110. kube::test::get_object_assert 'deployments my-depl' "{{.spec.selector.matchLabels.l1}}" 'l1'
  111. kube::test::get_object_assert 'deployments my-depl' "{{.metadata.labels.l1}}" 'l1'
  112. # apply new deployment with new template labels
  113. kubectl apply -f hack/testdata/null-propagation/deployment-l2.yaml "${kube_flags[@]:?}"
  114. # check right labels exists
  115. kube::test::get_object_assert 'deployments my-depl' "{{.spec.template.metadata.labels.l1}}" '<no value>'
  116. kube::test::get_object_assert 'deployments my-depl' "{{.spec.selector.matchLabels.l1}}" '<no value>'
  117. kube::test::get_object_assert 'deployments my-depl' "{{.metadata.labels.l1}}" '<no value>'
  118. kube::test::get_object_assert 'deployments my-depl' "{{.spec.template.metadata.labels.l2}}" 'l2'
  119. kube::test::get_object_assert 'deployments my-depl' "{{.spec.selector.matchLabels.l2}}" 'l2'
  120. kube::test::get_object_assert 'deployments my-depl' "{{.metadata.labels.l2}}" 'l2'
  121. # cleanup
  122. # need to explicitly remove replicasets and pods because we changed the deployment selector and orphaned things
  123. kubectl delete deployments,rs,pods --all --cascade=false --grace-period=0
  124. # Post-Condition: no Deployments, ReplicaSets, Pods exist
  125. kube::test::wait_object_assert deployments "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  126. kube::test::wait_object_assert replicasets "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  127. kube::test::get_object_assert pods "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  128. # kubectl apply deployment --overwrite=true --force=true
  129. # Pre-Condition: no deployment exists
  130. kube::test::get_object_assert deployments "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  131. # apply deployment nginx
  132. kubectl apply -f hack/testdata/deployment-label-change1.yaml "${kube_flags[@]:?}"
  133. # check right deployment exists
  134. kube::test::get_object_assert 'deployment nginx' "{{${id_field:?}}}" 'nginx'
  135. # apply deployment with new labels and a conflicting resourceVersion
  136. output_message=$(! kubectl apply -f hack/testdata/deployment-label-change2.yaml 2>&1 "${kube_flags[@]:?}")
  137. kube::test::if_has_string "${output_message}" 'Error from server (Conflict)'
  138. # apply deployment with --force and --overwrite will succeed
  139. kubectl apply -f hack/testdata/deployment-label-change2.yaml --overwrite=true --force=true --grace-period=10
  140. # check the changed deployment
  141. output_message=$(kubectl apply view-last-applied deploy/nginx -o json 2>&1 "${kube_flags[@]:?}" |grep nginx2)
  142. kube::test::if_has_string "${output_message}" '"name": "nginx2"'
  143. # applying a resource (with --force) that is both conflicting and invalid will
  144. # cause the server to only return a "Conflict" error when we attempt to patch.
  145. # This means that we will delete the existing resource after receiving 5 conflict
  146. # errors in a row from the server, and will attempt to create the modified
  147. # resource that we are passing to "apply". Since the modified resource is also
  148. # invalid, we will receive an invalid error when we attempt to create it, after
  149. # having deleted the old resource. Ensure that when this case is reached, the
  150. # old resource is restored once again, and the validation error is printed.
  151. output_message=$(! kubectl apply -f hack/testdata/deployment-label-change3.yaml --force 2>&1 "${kube_flags[@]:?}")
  152. kube::test::if_has_string "${output_message}" 'Invalid value'
  153. # Ensure that the old object has been restored
  154. kube::test::get_object_assert 'deployment nginx' "{{${template_labels:?}}}" 'nginx2'
  155. # cleanup
  156. kubectl delete deployments --all --grace-period=10
  157. set +o nounset
  158. set +o errexit
  159. }
  160. run_deployment_tests() {
  161. set -o nounset
  162. set -o errexit
  163. create_and_use_new_namespace
  164. kube::log::status "Testing deployments"
  165. # Test kubectl create deployment (using default - old generator)
  166. kubectl create deployment test-nginx-extensions --image=k8s.gcr.io/nginx:test-cmd
  167. # Post-Condition: Deployment "nginx" is created.
  168. kube::test::get_object_assert 'deploy test-nginx-extensions' "{{${container_name_field:?}}}" 'nginx'
  169. # and old generator was used, iow. old defaults are applied
  170. output_message=$(kubectl get deployment.apps/test-nginx-extensions -o jsonpath='{.spec.revisionHistoryLimit}')
  171. kube::test::if_has_not_string "${output_message}" '2'
  172. # Ensure we can interact with deployments through extensions and apps endpoints
  173. output_message=$(kubectl get deployment.extensions -o=jsonpath='{.items[0].apiVersion}' 2>&1 "${kube_flags[@]:?}")
  174. kube::test::if_has_string "${output_message}" 'extensions/v1beta1'
  175. output_message=$(kubectl get deployment.apps -o=jsonpath='{.items[0].apiVersion}' 2>&1 "${kube_flags[@]:?}")
  176. kube::test::if_has_string "${output_message}" 'apps/v1'
  177. # Clean up
  178. kubectl delete deployment test-nginx-extensions "${kube_flags[@]:?}"
  179. # Test kubectl create deployment
  180. kubectl create deployment test-nginx-apps --image=k8s.gcr.io/nginx:test-cmd --generator=deployment-basic/apps.v1beta1
  181. # Post-Condition: Deployment "nginx" is created.
  182. kube::test::get_object_assert 'deploy test-nginx-apps' "{{${container_name_field:?}}}" 'nginx'
  183. # and new generator was used, iow. new defaults are applied
  184. output_message=$(kubectl get deployment/test-nginx-apps -o jsonpath='{.spec.revisionHistoryLimit}')
  185. kube::test::if_has_string "${output_message}" '2'
  186. # Ensure we can interact with deployments through extensions and apps endpoints
  187. output_message=$(kubectl get deployment.extensions -o=jsonpath='{.items[0].apiVersion}' 2>&1 "${kube_flags[@]:?}")
  188. kube::test::if_has_string "${output_message}" 'extensions/v1beta1'
  189. output_message=$(kubectl get deployment.apps -o=jsonpath='{.items[0].apiVersion}' 2>&1 "${kube_flags[@]:?}")
  190. kube::test::if_has_string "${output_message}" 'apps/v1'
  191. # Describe command (resource only) should print detailed information
  192. kube::test::describe_resource_assert rs "Name:" "Pod Template:" "Labels:" "Selector:" "Controlled By" "Replicas:" "Pods Status:" "Volumes:"
  193. # Describe command (resource only) should print detailed information
  194. kube::test::describe_resource_assert pods "Name:" "Image:" "Node:" "Labels:" "Status:" "Controlled By"
  195. # Clean up
  196. kubectl delete deployment test-nginx-apps "${kube_flags[@]:?}"
  197. ### Test kubectl create deployment with image and command
  198. # Pre-Condition: No deployment exists.
  199. kube::test::get_object_assert deployment "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  200. # Command
  201. kubectl create deployment nginx-with-command --image=k8s.gcr.io/nginx:test-cmd -- /bin/sleep infinity
  202. # Post-Condition: Deployment "nginx" is created.
  203. kube::test::get_object_assert 'deploy nginx-with-command' "{{${container_name_field:?}}}" 'nginx'
  204. # Clean up
  205. kubectl delete deployment nginx-with-command "${kube_flags[@]:?}"
  206. ### Test kubectl create deployment should not fail validation
  207. # Pre-Condition: No deployment exists.
  208. kube::test::get_object_assert deployment "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  209. # Command
  210. kubectl create -f hack/testdata/deployment-with-UnixUserID.yaml "${kube_flags[@]:?}"
  211. # Post-Condition: Deployment "deployment-with-unixuserid" is created.
  212. kube::test::get_object_assert deployment "{{range.items}}{{${id_field:?}}}:{{end}}" 'deployment-with-unixuserid:'
  213. # Clean up
  214. kubectl delete deployment deployment-with-unixuserid "${kube_flags[@]:?}"
  215. ### Test cascading deletion
  216. ## Test that rs is deleted when deployment is deleted.
  217. # Pre-condition: no deployment exists
  218. kube::test::get_object_assert deployment "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  219. # Create deployment
  220. kubectl create -f test/fixtures/doc-yaml/user-guide/deployment.yaml "${kube_flags[@]:?}"
  221. # Wait for rs to come up.
  222. kube::test::wait_object_assert rs "{{range.items}}{{${rs_replicas_field:?}}}{{end}}" '3'
  223. # Deleting the deployment should delete the rs.
  224. kubectl delete deployment nginx-deployment "${kube_flags[@]:?}"
  225. kube::test::wait_object_assert rs "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  226. ## Test that rs is not deleted when deployment is deleted with cascade set to false.
  227. # Pre-condition: no deployment and rs exist
  228. kube::test::get_object_assert deployment "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  229. kube::test::get_object_assert rs "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  230. # Create deployment
  231. kubectl create deployment nginx-deployment --image=k8s.gcr.io/nginx:test-cmd
  232. # Wait for rs to come up.
  233. kube::test::wait_object_assert rs "{{range.items}}{{${rs_replicas_field:?}}}{{end}}" '1'
  234. # Delete the deployment with cascade set to false.
  235. kubectl delete deployment nginx-deployment "${kube_flags[@]:?}" --cascade=false
  236. # Wait for the deployment to be deleted and then verify that rs is not
  237. # deleted.
  238. kube::test::wait_object_assert deployment "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  239. kube::test::get_object_assert rs "{{range.items}}{{${rs_replicas_field:?}}}{{end}}" '1'
  240. # Cleanup
  241. # Find the name of the rs to be deleted.
  242. output_message=$(kubectl get rs "${kube_flags[@]:?}" -o template --template="{{range.items}}{{${id_field:?}}}{{end}}")
  243. kubectl delete rs "${output_message}" "${kube_flags[@]:?}"
  244. ### Auto scale deployment
  245. # Pre-condition: no deployment exists
  246. kube::test::get_object_assert deployment "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  247. # Command
  248. kubectl create -f test/fixtures/doc-yaml/user-guide/deployment.yaml "${kube_flags[@]:?}"
  249. kube::test::get_object_assert deployment "{{range.items}}{{${id_field:?}}}:{{end}}" 'nginx-deployment:'
  250. # autoscale 2~3 pods, no CPU utilization specified
  251. kubectl-with-retry autoscale deployment nginx-deployment "${kube_flags[@]:?}" --min=2 --max=3
  252. kube::test::get_object_assert 'hpa nginx-deployment' "{{${hpa_min_field:?}}} {{${hpa_max_field:?}}} {{${hpa_cpu_field:?}}}" '2 3 80'
  253. # Clean up
  254. # Note that we should delete hpa first, otherwise it may fight with the deployment reaper.
  255. kubectl delete hpa nginx-deployment "${kube_flags[@]:?}"
  256. kubectl delete deployment.apps nginx-deployment "${kube_flags[@]:?}"
  257. ### Rollback a deployment
  258. # Pre-condition: no deployment exists
  259. kube::test::get_object_assert deployment "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  260. # Command
  261. # Create a deployment (revision 1)
  262. kubectl create -f hack/testdata/deployment-revision1.yaml "${kube_flags[@]:?}"
  263. kube::test::get_object_assert deployment "{{range.items}}{{${id_field:?}}}:{{end}}" 'nginx:'
  264. kube::test::get_object_assert deployment "{{range.items}}{{${image_field0:?}}}:{{end}}" "${IMAGE_DEPLOYMENT_R1}:"
  265. # Rollback to revision 1 - should be no-op
  266. kubectl rollout undo deployment nginx --to-revision=1 "${kube_flags[@]:?}"
  267. kube::test::get_object_assert deployment "{{range.items}}{{${image_field0:?}}}:{{end}}" "${IMAGE_DEPLOYMENT_R1}:"
  268. # Update the deployment (revision 2)
  269. kubectl apply -f hack/testdata/deployment-revision2.yaml "${kube_flags[@]:?}"
  270. kube::test::get_object_assert deployment.apps "{{range.items}}{{${image_field0:?}}}:{{end}}" "${IMAGE_DEPLOYMENT_R2}:"
  271. # Rollback to revision 1 with dry-run - should be no-op
  272. kubectl rollout undo deployment nginx --dry-run=true "${kube_flags[@]:?}" | grep "test-cmd"
  273. kube::test::get_object_assert deployment.apps "{{range.items}}{{${image_field0:?}}}:{{end}}" "${IMAGE_DEPLOYMENT_R2}:"
  274. # Rollback to revision 1
  275. kubectl rollout undo deployment nginx --to-revision=1 "${kube_flags[@]:?}"
  276. sleep 1
  277. kube::test::get_object_assert deployment "{{range.items}}{{${image_field0:?}}}:{{end}}" "${IMAGE_DEPLOYMENT_R1}:"
  278. # Rollback to revision 1000000 - should be no-op
  279. ! kubectl rollout undo deployment nginx --to-revision=1000000 "${kube_flags[@]:?}"
  280. kube::test::get_object_assert deployment "{{range.items}}{{${image_field0:?}}}:{{end}}" "${IMAGE_DEPLOYMENT_R1}:"
  281. # Rollback to last revision
  282. kubectl rollout undo deployment nginx "${kube_flags[@]:?}"
  283. sleep 1
  284. kube::test::get_object_assert deployment "{{range.items}}{{${image_field0:?}}}:{{end}}" "${IMAGE_DEPLOYMENT_R2}:"
  285. # Pause the deployment
  286. kubectl-with-retry rollout pause deployment nginx "${kube_flags[@]:?}"
  287. # A paused deployment cannot be rolled back
  288. ! kubectl rollout undo deployment nginx "${kube_flags[@]:?}"
  289. # A paused deployment cannot be restarted
  290. ! kubectl rollout restart deployment nginx "${kube_flags[@]:?}"
  291. # Resume the deployment
  292. kubectl-with-retry rollout resume deployment nginx "${kube_flags[@]:?}"
  293. # The resumed deployment can now be rolled back
  294. kubectl rollout undo deployment nginx "${kube_flags[@]:?}"
  295. # Check that the new replica set has all old revisions stored in an annotation
  296. newrs="$(kubectl describe deployment nginx | grep NewReplicaSet | awk '{print $2}')"
  297. kubectl get rs "${newrs}" -o yaml | grep "deployment.kubernetes.io/revision-history: 1,3"
  298. # Check that trying to watch the status of a superseded revision returns an error
  299. ! kubectl rollout status deployment/nginx --revision=3
  300. # Restarting the deployment creates a new replicaset
  301. kubectl rollout restart deployment/nginx
  302. sleep 1
  303. newrs="$(kubectl describe deployment nginx | grep NewReplicaSet | awk '{print $2}')"
  304. rs="$(kubectl get rs "${newrs}" -o yaml)"
  305. kube::test::if_has_string "${rs}" "deployment.kubernetes.io/revision: \"6\""
  306. ${SED} "s/name: nginx$/name: nginx2/" hack/testdata/deployment-revision1.yaml | kubectl create -f - "${kube_flags[@]:?}"
  307. # Deletion of both deployments should not be blocked
  308. kubectl delete deployment nginx2 "${kube_flags[@]:?}"
  309. # Clean up
  310. kubectl delete deployment nginx "${kube_flags[@]:?}"
  311. ### Set image of a deployment
  312. # Pre-condition: no deployment exists
  313. kube::test::get_object_assert deployment "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  314. # Create a deployment
  315. kubectl create -f hack/testdata/deployment-multicontainer.yaml "${kube_flags[@]:?}"
  316. kube::test::get_object_assert deployment "{{range.items}}{{${id_field:?}}}:{{end}}" 'nginx-deployment:'
  317. kube::test::get_object_assert deployment "{{range.items}}{{${image_field0:?}}}:{{end}}" "${IMAGE_DEPLOYMENT_R1}:"
  318. kube::test::get_object_assert deployment "{{range.items}}{{${image_field1:?}}}:{{end}}" "${IMAGE_PERL}:"
  319. # Set the deployment's image
  320. kubectl set image deployment nginx-deployment nginx="${IMAGE_DEPLOYMENT_R2}" "${kube_flags[@]:?}"
  321. kube::test::get_object_assert deployment "{{range.items}}{{${image_field0:?}}}:{{end}}" "${IMAGE_DEPLOYMENT_R2}:"
  322. kube::test::get_object_assert deployment "{{range.items}}{{${image_field1:?}}}:{{end}}" "${IMAGE_PERL}:"
  323. # Set non-existing container should fail
  324. ! kubectl set image deployment nginx-deployment redis=redis "${kube_flags[@]:?}"
  325. # Set image of deployments without specifying name
  326. kubectl set image deployments --all nginx="${IMAGE_DEPLOYMENT_R1}" "${kube_flags[@]:?}"
  327. kube::test::get_object_assert deployment "{{range.items}}{{${image_field0:?}}}:{{end}}" "${IMAGE_DEPLOYMENT_R1}:"
  328. kube::test::get_object_assert deployment "{{range.items}}{{${image_field1:?}}}:{{end}}" "${IMAGE_PERL}:"
  329. # Set image of a deployment specified by file
  330. kubectl set image -f hack/testdata/deployment-multicontainer.yaml nginx="${IMAGE_DEPLOYMENT_R2}" "${kube_flags[@]:?}"
  331. kube::test::get_object_assert deployment "{{range.items}}{{${image_field0:?}}}:{{end}}" "${IMAGE_DEPLOYMENT_R2}:"
  332. kube::test::get_object_assert deployment "{{range.items}}{{${image_field1:?}}}:{{end}}" "${IMAGE_PERL}:"
  333. # Set image of a local file without talking to the server
  334. kubectl set image -f hack/testdata/deployment-multicontainer.yaml nginx="${IMAGE_DEPLOYMENT_R1}" "${kube_flags[@]:?}" --local -o yaml
  335. kube::test::get_object_assert deployment "{{range.items}}{{${image_field0:?}}}:{{end}}" "${IMAGE_DEPLOYMENT_R2}:"
  336. kube::test::get_object_assert deployment "{{range.items}}{{${image_field1:?}}}:{{end}}" "${IMAGE_PERL}:"
  337. # Set image of all containers of the deployment
  338. kubectl set image deployment nginx-deployment "*=${IMAGE_DEPLOYMENT_R1}" "${kube_flags[@]:?}"
  339. kube::test::get_object_assert deployment "{{range.items}}{{${image_field0:?}}}:{{end}}" "${IMAGE_DEPLOYMENT_R1}:"
  340. kube::test::get_object_assert deployment "{{range.items}}{{${image_field1:?}}}:{{end}}" "${IMAGE_DEPLOYMENT_R1}:"
  341. # Set image of all containners of the deployment again when image not change
  342. kubectl set image deployment nginx-deployment "*=${IMAGE_DEPLOYMENT_R1}" "${kube_flags[@]:?}"
  343. kube::test::get_object_assert deployment "{{range.items}}{{${image_field0:?}}}:{{end}}" "${IMAGE_DEPLOYMENT_R1}:"
  344. kube::test::get_object_assert deployment "{{range.items}}{{${image_field1:?}}}:{{end}}" "${IMAGE_DEPLOYMENT_R1}:"
  345. # Clean up
  346. kubectl delete deployment nginx-deployment "${kube_flags[@]:?}"
  347. ### Set env of a deployment
  348. # Pre-condition: no deployment exists
  349. kube::test::get_object_assert deployment "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  350. # Create a deployment
  351. kubectl create -f hack/testdata/deployment-multicontainer.yaml "${kube_flags[@]:?}"
  352. kubectl create -f hack/testdata/configmap.yaml "${kube_flags[@]:?}"
  353. kubectl create -f hack/testdata/secret.yaml "${kube_flags[@]:?}"
  354. kube::test::get_object_assert deployment "{{range.items}}{{${id_field:?}}}:{{end}}" 'nginx-deployment:'
  355. #configmap is special here due to controller will create kube-root-ca.crt for each namespace automatically
  356. kube::test::get_object_assert 'configmaps/test-set-env-config' "{{${id_field:?}}}" 'test-set-env-config'
  357. kube::test::get_object_assert secret "{{range.items}}{{${id_field:?}}}:{{end}}" 'test-set-env-secret:'
  358. # Set env of deployments by configmap from keys
  359. kubectl set env deployment nginx-deployment --keys=key-2 --from=configmap/test-set-env-config "${kube_flags[@]:?}"
  360. # Assert correct value in deployment env
  361. kube::test::get_object_assert 'deploy nginx-deployment' "{{ (index (index .spec.template.spec.containers 0).env 0).name}}" 'KEY_2'
  362. # Assert single value in deployment env
  363. kube::test::get_object_assert 'deploy nginx-deployment' "{{ len (index .spec.template.spec.containers 0).env }}" '1'
  364. # Set env of deployments by configmap
  365. kubectl set env deployment nginx-deployment --from=configmap/test-set-env-config "${kube_flags[@]:?}"
  366. # Assert all values in deployment env
  367. kube::test::get_object_assert 'deploy nginx-deployment' "{{ len (index .spec.template.spec.containers 0).env }}" '2'
  368. # Set env of deployments for all container
  369. kubectl set env deployment nginx-deployment env=prod "${kube_flags[@]:?}"
  370. # Set env of deployments for specific container
  371. kubectl set env deployment nginx-deployment superenv=superprod -c=nginx "${kube_flags[@]:?}"
  372. # Set env of deployments by secret from keys
  373. kubectl set env deployment nginx-deployment --keys=username --from=secret/test-set-env-secret "${kube_flags[@]:?}"
  374. # Set env of deployments by secret
  375. kubectl set env deployment nginx-deployment --from=secret/test-set-env-secret "${kube_flags[@]:?}"
  376. # Remove specific env of deployment
  377. kubectl set env deployment nginx-deployment env-
  378. # Clean up
  379. kubectl delete deployment nginx-deployment "${kube_flags[@]:?}"
  380. kubectl delete configmap test-set-env-config "${kube_flags[@]:?}"
  381. kubectl delete secret test-set-env-secret "${kube_flags[@]:?}"
  382. set +o nounset
  383. set +o errexit
  384. }
  385. run_statefulset_history_tests() {
  386. set -o nounset
  387. set -o errexit
  388. create_and_use_new_namespace
  389. kube::log::status "Testing kubectl(v1:statefulsets, v1:controllerrevisions)"
  390. ### Test rolling back a StatefulSet
  391. # Pre-condition: no statefulset or its pods exists
  392. kube::test::get_object_assert statefulset "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  393. # Command
  394. # Create a StatefulSet (revision 1)
  395. kubectl apply -f hack/testdata/rollingupdate-statefulset.yaml --record "${kube_flags[@]:?}"
  396. kube::test::wait_object_assert controllerrevisions "{{range.items}}{{${annotations_field:?}}}:{{end}}" ".*rollingupdate-statefulset.yaml --record.*"
  397. # Rollback to revision 1 - should be no-op
  398. kubectl rollout undo statefulset --to-revision=1 "${kube_flags[@]:?}"
  399. kube::test::get_object_assert statefulset "{{range.items}}{{${image_field0:?}}}:{{end}}" "${IMAGE_STATEFULSET_R1}:"
  400. kube::test::get_object_assert statefulset "{{range.items}}{{${container_len:?}}}{{end}}" "1"
  401. # Update the statefulset (revision 2)
  402. kubectl apply -f hack/testdata/rollingupdate-statefulset-rv2.yaml --record "${kube_flags[@]:?}"
  403. kube::test::wait_object_assert statefulset "{{range.items}}{{${image_field0:?}}}:{{end}}" "${IMAGE_STATEFULSET_R2}:"
  404. kube::test::wait_object_assert statefulset "{{range.items}}{{${image_field1:?}}}:{{end}}" "${IMAGE_PAUSE_V2}:"
  405. kube::test::get_object_assert statefulset "{{range.items}}{{${container_len:?}}}{{end}}" "2"
  406. kube::test::wait_object_assert controllerrevisions "{{range.items}}{{${annotations_field:?}}}:{{end}}" ".*rollingupdate-statefulset-rv2.yaml --record.*"
  407. # Rollback to revision 1 with dry-run - should be no-op
  408. kubectl rollout undo statefulset --dry-run=true "${kube_flags[@]:?}"
  409. kube::test::get_object_assert statefulset "{{range.items}}{{${image_field0:?}}}:{{end}}" "${IMAGE_STATEFULSET_R2}:"
  410. kube::test::get_object_assert statefulset "{{range.items}}{{${image_field1:?}}}:{{end}}" "${IMAGE_PAUSE_V2}:"
  411. kube::test::get_object_assert statefulset "{{range.items}}{{${container_len:?}}}{{end}}" "2"
  412. # Rollback to revision 1
  413. kubectl rollout undo statefulset --to-revision=1 "${kube_flags[@]:?}"
  414. kube::test::wait_object_assert statefulset "{{range.items}}{{${image_field0:?}}}:{{end}}" "${IMAGE_STATEFULSET_R1}:"
  415. kube::test::get_object_assert statefulset "{{range.items}}{{${container_len:?}}}{{end}}" "1"
  416. # Rollback to revision 1000000 - should fail
  417. output_message=$(! kubectl rollout undo statefulset --to-revision=1000000 "${kube_flags[@]:?}" 2>&1)
  418. kube::test::if_has_string "${output_message}" "unable to find specified revision"
  419. kube::test::get_object_assert statefulset "{{range.items}}{{${image_field0:?}}}:{{end}}" "${IMAGE_STATEFULSET_R1}:"
  420. kube::test::get_object_assert statefulset "{{range.items}}{{${container_len:?}}}{{end}}" "1"
  421. # Rollback to last revision
  422. kubectl rollout undo statefulset "${kube_flags[@]:?}"
  423. kube::test::wait_object_assert statefulset "{{range.items}}{{${image_field0:?}}}:{{end}}" "${IMAGE_STATEFULSET_R2}:"
  424. kube::test::wait_object_assert statefulset "{{range.items}}{{${image_field1:?}}}:{{end}}" "${IMAGE_PAUSE_V2}:"
  425. kube::test::get_object_assert statefulset "{{range.items}}{{${container_len:?}}}{{end}}" "2"
  426. # Clean up - delete newest configuration
  427. kubectl delete -f hack/testdata/rollingupdate-statefulset-rv2.yaml "${kube_flags[@]:?}"
  428. # Post-condition: no pods from statefulset controller
  429. wait-for-pods-with-label "app=nginx-statefulset" ""
  430. set +o nounset
  431. set +o errexit
  432. }
  433. run_stateful_set_tests() {
  434. set -o nounset
  435. set -o errexit
  436. create_and_use_new_namespace
  437. kube::log::status "Testing kubectl(v1:statefulsets)"
  438. ### Create and stop statefulset, make sure it doesn't leak pods
  439. # Pre-condition: no statefulset exists
  440. kube::test::get_object_assert statefulset "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  441. # Command: create statefulset
  442. kubectl create -f hack/testdata/rollingupdate-statefulset.yaml "${kube_flags[@]:?}"
  443. ### Scale statefulset test with current-replicas and replicas
  444. # Pre-condition: 0 replicas
  445. kube::test::get_object_assert 'statefulset nginx' "{{${statefulset_replicas_field:?}}}" '0'
  446. kube::test::wait_object_assert 'statefulset nginx' "{{${statefulset_observed_generation:?}}}" '1'
  447. # Command: Scale up
  448. kubectl scale --current-replicas=0 --replicas=1 statefulset nginx "${kube_flags[@]:?}"
  449. # Post-condition: 1 replica, named nginx-0
  450. kube::test::get_object_assert 'statefulset nginx' "{{${statefulset_replicas_field:?}}}" '1'
  451. kube::test::wait_object_assert 'statefulset nginx' "{{${statefulset_observed_generation:?}}}" '2'
  452. # Typically we'd wait and confirm that N>1 replicas are up, but this framework
  453. # doesn't start the scheduler, so pet-0 will block all others.
  454. # TODO: test robust scaling in an e2e.
  455. wait-for-pods-with-label "app=nginx-statefulset" "nginx-0"
  456. # Rollout restart should change generation
  457. kubectl rollout restart statefulset nginx "${kube_flags[@]}"
  458. kube::test::get_object_assert 'statefulset nginx' "{{$statefulset_observed_generation}}" '3'
  459. ### Clean up
  460. kubectl delete -f hack/testdata/rollingupdate-statefulset.yaml "${kube_flags[@]:?}"
  461. # Post-condition: no pods from statefulset controller
  462. wait-for-pods-with-label "app=nginx-statefulset" ""
  463. set +o nounset
  464. set +o errexit
  465. }
  466. run_rs_tests() {
  467. set -o nounset
  468. set -o errexit
  469. create_and_use_new_namespace
  470. kube::log::status "Testing kubectl(v1:replicasets)"
  471. ### Create and stop a replica set, make sure it doesn't leak pods
  472. # Pre-condition: no replica set exists
  473. kube::test::get_object_assert rs "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  474. # Command
  475. kubectl create -f hack/testdata/frontend-replicaset.yaml "${kube_flags[@]:?}"
  476. kube::log::status "Deleting rs"
  477. kubectl delete rs frontend "${kube_flags[@]:?}"
  478. # Post-condition: no pods from frontend replica set
  479. kube::test::wait_object_assert 'pods -l "tier=frontend"' "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  480. ### Create and then delete a replica set with cascade=false, make sure it doesn't delete pods.
  481. # Pre-condition: no replica set exists
  482. kube::test::get_object_assert rs "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  483. # Command
  484. #TODO(mortent): Remove this workaround when ReplicaSet bug described in issue #69376 is fixed
  485. local replicaset_name="frontend-no-cascade"
  486. sed -r 's/^(\s*)(name\s*:\s*frontend\s*$)/\1name: '"${replicaset_name:?}"'/' hack/testdata/frontend-replicaset.yaml | kubectl create "${kube_flags[@]:?}" -f -
  487. # wait for all 3 pods to be set up
  488. kube::test::wait_object_assert 'pods -l "tier=frontend"' "{{range.items}}{{${pod_container_name_field:?}}}:{{end}}" 'php-redis:php-redis:php-redis:'
  489. kube::log::status "Deleting rs"
  490. kubectl delete rs "${replicaset_name}" "${kube_flags[@]:?}" --cascade=false
  491. # Wait for the rs to be deleted.
  492. kube::test::wait_object_assert rs "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  493. # Post-condition: All 3 pods still remain from frontend replica set
  494. kube::test::get_object_assert 'pods -l "tier=frontend"' "{{range.items}}{{$pod_container_name_field}}:{{end}}" 'php-redis:php-redis:php-redis:'
  495. # Cleanup
  496. kubectl delete pods -l "tier=frontend" "${kube_flags[@]:?}"
  497. kube::test::get_object_assert pods "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  498. ### Create replica set frontend from YAML
  499. # Pre-condition: no replica set exists
  500. kube::test::get_object_assert rs "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  501. # Command
  502. kubectl create -f hack/testdata/frontend-replicaset.yaml "${kube_flags[@]:?}"
  503. # Post-condition: frontend replica set is created
  504. kube::test::get_object_assert rs "{{range.items}}{{${id_field:?}}}:{{end}}" 'frontend:'
  505. # Describe command should print detailed information
  506. kube::test::describe_object_assert rs 'frontend' "Name:" "Pod Template:" "Labels:" "Selector:" "Replicas:" "Pods Status:" "Volumes:"
  507. # Describe command should print events information by default
  508. kube::test::describe_object_events_assert rs 'frontend'
  509. # Describe command should not print events information when show-events=false
  510. kube::test::describe_object_events_assert rs 'frontend' false
  511. # Describe command should print events information when show-events=true
  512. kube::test::describe_object_events_assert rs 'frontend' true
  513. # Describe command (resource only) should print detailed information
  514. kube::test::describe_resource_assert rs "Name:" "Pod Template:" "Labels:" "Selector:" "Replicas:" "Pods Status:" "Volumes:"
  515. # Describe command should print events information by default
  516. kube::test::describe_resource_events_assert rs
  517. # Describe command should not print events information when show-events=false
  518. kube::test::describe_resource_events_assert rs false
  519. # Describe command should print events information when show-events=true
  520. kube::test::describe_resource_events_assert rs true
  521. # Describe command (resource only) should print detailed information
  522. kube::test::describe_resource_assert pods "Name:" "Image:" "Node:" "Labels:" "Status:" "Controlled By"
  523. ### Scale replica set frontend with current-replicas and replicas
  524. # Pre-condition: 3 replicas
  525. kube::test::get_object_assert 'rs frontend' "{{${rs_replicas_field:?}}}" '3'
  526. # Command
  527. kubectl scale --current-replicas=3 --replicas=2 replicasets frontend "${kube_flags[@]:?}"
  528. # Post-condition: 2 replicas
  529. kube::test::get_object_assert 'rs frontend' "{{${rs_replicas_field:?}}}" '2'
  530. # Set up three deploy, two deploy have same label
  531. kubectl create -f hack/testdata/scale-deploy-1.yaml "${kube_flags[@]:?}"
  532. kubectl create -f hack/testdata/scale-deploy-2.yaml "${kube_flags[@]:?}"
  533. kubectl create -f hack/testdata/scale-deploy-3.yaml "${kube_flags[@]:?}"
  534. kube::test::get_object_assert 'deploy scale-1' "{{.spec.replicas}}" '1'
  535. kube::test::get_object_assert 'deploy scale-2' "{{.spec.replicas}}" '1'
  536. kube::test::get_object_assert 'deploy scale-3' "{{.spec.replicas}}" '1'
  537. # Test kubectl scale --selector
  538. kubectl scale deploy --replicas=2 -l run=hello
  539. kube::test::get_object_assert 'deploy scale-1' "{{.spec.replicas}}" '2'
  540. kube::test::get_object_assert 'deploy scale-2' "{{.spec.replicas}}" '2'
  541. kube::test::get_object_assert 'deploy scale-3' "{{.spec.replicas}}" '1'
  542. # Test kubectl scale --all
  543. kubectl scale deploy --replicas=3 --all
  544. kube::test::get_object_assert 'deploy scale-1' "{{.spec.replicas}}" '3'
  545. kube::test::get_object_assert 'deploy scale-2' "{{.spec.replicas}}" '3'
  546. kube::test::get_object_assert 'deploy scale-3' "{{.spec.replicas}}" '3'
  547. # Clean-up
  548. kubectl delete rs frontend "${kube_flags[@]:?}"
  549. kubectl delete deploy scale-1 scale-2 scale-3 "${kube_flags[@]:?}"
  550. ### Expose replica set as service
  551. kubectl create -f hack/testdata/frontend-replicaset.yaml "${kube_flags[@]:?}"
  552. # Pre-condition: 3 replicas
  553. kube::test::get_object_assert 'rs frontend' "{{${rs_replicas_field:?}}}" '3'
  554. # Command
  555. kubectl expose rs frontend --port=80 "${kube_flags[@]:?}"
  556. # Post-condition: service exists and the port is unnamed
  557. kube::test::get_object_assert 'service frontend' "{{${port_name:?}}} {{${port_field:?}}}" '<no value> 80'
  558. # Create a service using service/v1 generator
  559. kubectl expose rs frontend --port=80 --name=frontend-2 --generator=service/v1 "${kube_flags[@]:?}"
  560. # Post-condition: service exists and the port is named default.
  561. kube::test::get_object_assert 'service frontend-2' "{{${port_name:?}}} {{${port_field:?}}}" 'default 80'
  562. # Cleanup services
  563. kubectl delete service frontend{,-2} "${kube_flags[@]:?}"
  564. # Test set commands
  565. # Pre-condition: frontend replica set exists at generation 1
  566. kube::test::get_object_assert 'rs frontend' "{{${generation_field:?}}}" '1'
  567. kubectl set image rs/frontend "${kube_flags[@]:?}" "*=k8s.gcr.io/pause:test-cmd"
  568. kube::test::get_object_assert 'rs frontend' "{{${generation_field:?}}}" '2'
  569. kubectl set env rs/frontend "${kube_flags[@]:?}" foo=bar
  570. kube::test::get_object_assert 'rs frontend' "{{${generation_field:?}}}" '3'
  571. kubectl set resources rs/frontend "${kube_flags[@]:?}" --limits=cpu=200m,memory=512Mi
  572. kube::test::get_object_assert 'rs frontend' "{{${generation_field:?}}}" '4'
  573. ### Delete replica set with id
  574. # Pre-condition: frontend replica set exists
  575. kube::test::get_object_assert rs "{{range.items}}{{${id_field:?}}}:{{end}}" 'frontend:'
  576. # Command
  577. kubectl delete rs frontend "${kube_flags[@]:?}"
  578. # Post-condition: no replica set exists
  579. kube::test::get_object_assert rs "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  580. ### Create two replica sets
  581. # Pre-condition: no replica set exists
  582. kube::test::get_object_assert rs "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  583. # Command
  584. kubectl create -f hack/testdata/frontend-replicaset.yaml "${kube_flags[@]:?}"
  585. kubectl create -f hack/testdata/redis-slave-replicaset.yaml "${kube_flags[@]:?}"
  586. # Post-condition: frontend and redis-slave
  587. kube::test::get_object_assert rs "{{range.items}}{{${id_field:?}}}:{{end}}" 'frontend:redis-slave:'
  588. ### Delete multiple replica sets at once
  589. # Pre-condition: frontend and redis-slave
  590. kube::test::get_object_assert rs "{{range.items}}{{${id_field:?}}}:{{end}}" 'frontend:redis-slave:'
  591. # Command
  592. kubectl delete rs frontend redis-slave "${kube_flags[@]:?}" # delete multiple replica sets at once
  593. # Post-condition: no replica set exists
  594. kube::test::get_object_assert rs "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  595. if kube::test::if_supports_resource "${horizontalpodautoscalers:?}" ; then
  596. ### Auto scale replica set
  597. # Pre-condition: no replica set exists
  598. kube::test::get_object_assert rs "{{range.items}}{{${id_field:?}}}:{{end}}" ''
  599. # Command
  600. kubectl create -f hack/testdata/frontend-replicaset.yaml "${kube_flags[@]:?}"
  601. kube::test::get_object_assert rs "{{range.items}}{{${id_field:?}}}:{{end}}" 'frontend:'
  602. # autoscale 1~2 pods, CPU utilization 70%, replica set specified by file
  603. kubectl autoscale -f hack/testdata/frontend-replicaset.yaml "${kube_flags[@]:?}" --max=2 --cpu-percent=70
  604. kube::test::get_object_assert 'hpa frontend' "{{${hpa_min_field:?}}} {{${hpa_max_field:?}}} {{${hpa_cpu_field:?}}}" '1 2 70'
  605. kubectl delete hpa frontend "${kube_flags[@]:?}"
  606. # autoscale 2~3 pods, no CPU utilization specified, replica set specified by name
  607. kubectl autoscale rs frontend "${kube_flags[@]:?}" --min=2 --max=3
  608. kube::test::get_object_assert 'hpa frontend' "{{${hpa_min_field:?}}} {{${hpa_max_field:?}}} {{${hpa_cpu_field:?}}}" '2 3 80'
  609. kubectl delete hpa frontend "${kube_flags[@]:?}"
  610. # autoscale without specifying --max should fail
  611. ! kubectl autoscale rs frontend "${kube_flags[@]:?}"
  612. # Clean up
  613. kubectl delete rs frontend "${kube_flags[@]:?}"
  614. fi
  615. set +o nounset
  616. set +o errexit
  617. }