test.sh 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. #!/usr/bin/env bash
  2. # Copyright 2015 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. # A set of helpers for tests
  16. readonly reset=$(tput sgr0)
  17. readonly bold=$(tput bold)
  18. readonly black=$(tput setaf 0)
  19. readonly red=$(tput setaf 1)
  20. readonly green=$(tput setaf 2)
  21. kube::test::clear_all() {
  22. if kube::test::if_supports_resource "rc" ; then
  23. kubectl delete "${kube_flags[@]}" rc --all --grace-period=0 --force
  24. fi
  25. if kube::test::if_supports_resource "pods" ; then
  26. kubectl delete "${kube_flags[@]}" pods --all --grace-period=0 --force
  27. fi
  28. }
  29. # Prints the calling file and line number $1 levels deep
  30. # Defaults to 2 levels so you can call this to find your own caller
  31. kube::test::get_caller() {
  32. local levels=${1:-2}
  33. local caller_file="${BASH_SOURCE[${levels}]}"
  34. local caller_line="${BASH_LINENO[${levels}-1]}"
  35. echo "$(basename "${caller_file}"):${caller_line}"
  36. }
  37. # Force exact match of a returned result for a object query. Wrap this with || to support multiple
  38. # valid return types.
  39. # This runs `kubectl get` once and asserts that the result is as expected.
  40. ## $1: Object on which get should be run
  41. # $2: The go-template to run on the result
  42. # $3: The expected output
  43. # $4: Additional args to be passed to kubectl
  44. kube::test::get_object_assert() {
  45. kube::test::object_assert 1 "$@"
  46. }
  47. # Asserts that the output of a given get query is as expected.
  48. # Runs the query multiple times before failing it.
  49. # $1: Object on which get should be run
  50. # $2: The go-template to run on the result
  51. # $3: The expected output
  52. # $4: Additional args to be passed to kubectl
  53. kube::test::wait_object_assert() {
  54. kube::test::object_assert 10 "$@"
  55. }
  56. # Asserts that the output of a given get query is as expected.
  57. # Can run the query multiple times before failing it.
  58. # $1: Number of times the query should be run before failing it.
  59. # $2: Object on which get should be run
  60. # $3: The go-template to run on the result
  61. # $4: The expected output
  62. # $5: Additional args to be passed to kubectl
  63. kube::test::object_assert() {
  64. local tries=$1
  65. local object=$2
  66. local request=$3
  67. local expected=$4
  68. local args=${5:-}
  69. for j in $(seq 1 ${tries}); do
  70. res=$(eval kubectl get "${kube_flags[@]}" ${args} ${object} -o go-template=\"${request}\")
  71. if [[ "${res}" =~ ^$expected$ ]]; then
  72. echo -n "${green}"
  73. echo "$(kube::test::get_caller 3): Successful get ${object} ${request}: ${res}"
  74. echo -n "${reset}"
  75. return 0
  76. fi
  77. echo "Waiting for Get ${object} ${request} ${args}: expected: ${expected}, got: ${res}"
  78. sleep $((${j}-1))
  79. done
  80. echo "${bold}${red}"
  81. echo "$(kube::test::get_caller 3): FAIL!"
  82. echo "Get ${object} ${request}"
  83. echo " Expected: ${expected}"
  84. echo " Got: ${res}"
  85. echo "${reset}${red}"
  86. caller
  87. echo "${reset}"
  88. return 1
  89. }
  90. kube::test::get_object_jsonpath_assert() {
  91. local object=$1
  92. local request=$2
  93. local expected=$3
  94. res=$(eval kubectl get "${kube_flags[@]}" ${object} -o jsonpath=\"${request}\")
  95. if [[ "${res}" =~ ^$expected$ ]]; then
  96. echo -n "${green}"
  97. echo "$(kube::test::get_caller): Successful get ${object} ${request}: ${res}"
  98. echo -n "${reset}"
  99. return 0
  100. else
  101. echo "${bold}${red}"
  102. echo "$(kube::test::get_caller): FAIL!"
  103. echo "Get ${object} ${request}"
  104. echo " Expected: ${expected}"
  105. echo " Got: ${res}"
  106. echo "${reset}${red}"
  107. caller
  108. echo "${reset}"
  109. return 1
  110. fi
  111. }
  112. kube::test::describe_object_assert() {
  113. local resource=$1
  114. local object=$2
  115. local matches=${@:3}
  116. result=$(eval kubectl describe "${kube_flags[@]}" ${resource} ${object})
  117. for match in ${matches}; do
  118. if [[ ! $(echo "${result}" | grep ${match}) ]]; then
  119. echo "${bold}${red}"
  120. echo "$(kube::test::get_caller): FAIL!"
  121. echo "Describe ${resource} ${object}"
  122. echo " Expected Match: ${match}"
  123. echo " Not found in:"
  124. echo "${result}"
  125. echo "${reset}${red}"
  126. caller
  127. echo "${reset}"
  128. return 1
  129. fi
  130. done
  131. echo -n "${green}"
  132. echo "$(kube::test::get_caller): Successful describe ${resource} ${object}:"
  133. echo "${result}"
  134. echo -n "${reset}"
  135. return 0
  136. }
  137. kube::test::describe_object_events_assert() {
  138. local resource=$1
  139. local object=$2
  140. local showevents=${3:-"true"}
  141. if [[ -z "${3:-}" ]]; then
  142. result=$(eval kubectl describe "${kube_flags[@]}" ${resource} ${object})
  143. else
  144. result=$(eval kubectl describe "${kube_flags[@]}" "--show-events=${showevents}" ${resource} ${object})
  145. fi
  146. if [[ -n $(echo "${result}" | grep "No events.\|Events:") ]]; then
  147. local has_events="true"
  148. else
  149. local has_events="false"
  150. fi
  151. if [[ "${showevents}" == "${has_events}" ]]; then
  152. echo -n "${green}"
  153. echo "$(kube::test::get_caller): Successful describe"
  154. echo "${result}"
  155. echo "${reset}"
  156. return 0
  157. else
  158. echo "${bold}${red}"
  159. echo "$(kube::test::get_caller): FAIL"
  160. if [[ "${showevents}" == "false" ]]; then
  161. echo " Events information should not be described in:"
  162. else
  163. echo " Events information not found in:"
  164. fi
  165. echo "${result}"
  166. echo "${reset}${red}"
  167. caller
  168. echo "${reset}"
  169. return 1
  170. fi
  171. }
  172. kube::test::describe_resource_assert() {
  173. local resource=$1
  174. local matches=${@:2}
  175. result=$(eval kubectl describe "${kube_flags[@]}" ${resource})
  176. for match in ${matches}; do
  177. if [[ ! $(echo "${result}" | grep ${match}) ]]; then
  178. echo "${bold}${red}"
  179. echo "FAIL!"
  180. echo "Describe ${resource}"
  181. echo " Expected Match: ${match}"
  182. echo " Not found in:"
  183. echo "${result}"
  184. echo "${reset}${red}"
  185. caller
  186. echo "${reset}"
  187. return 1
  188. fi
  189. done
  190. echo -n "${green}"
  191. echo "Successful describe ${resource}:"
  192. echo "${result}"
  193. echo -n "${reset}"
  194. return 0
  195. }
  196. kube::test::describe_resource_events_assert() {
  197. local resource=$1
  198. local showevents=${2:-"true"}
  199. result=$(eval kubectl describe "${kube_flags[@]}" "--show-events=${showevents}" ${resource})
  200. if [[ $(echo "${result}" | grep "No events.\|Events:") ]]; then
  201. local has_events="true"
  202. else
  203. local has_events="false"
  204. fi
  205. if [[ "${showevents}" == "${has_events}" ]]; then
  206. echo -n "${green}"
  207. echo "Successful describe"
  208. echo "${result}"
  209. echo -n "${reset}"
  210. return 0
  211. else
  212. echo "${bold}${red}"
  213. echo "FAIL"
  214. if [[ "${showevents}" == "false" ]]; then
  215. echo " Events information should not be described in:"
  216. else
  217. echo " Events information not found in:"
  218. fi
  219. echo "${result}"
  220. caller
  221. echo "${reset}"
  222. return 1
  223. fi
  224. }
  225. # Compare sort-by resource name output with expected order specify in the last parameter
  226. kube::test::if_sort_by_has_correct_order() {
  227. local array=($(echo "$1" |awk '{if(NR!=1) print $1}'))
  228. local var
  229. for i in "${array[@]}"; do
  230. var+="${i}:"
  231. done
  232. kube::test::if_has_string "${var}" "${@:$#}"
  233. }
  234. kube::test::if_has_string() {
  235. local message=$1
  236. local match=$2
  237. if grep -q "${match}" <<< "${message}"; then
  238. echo "Successful"
  239. echo "message:${message}"
  240. echo "has:${match}"
  241. return 0
  242. else
  243. echo "FAIL!"
  244. echo "message:${message}"
  245. echo "has not:${match}"
  246. caller
  247. return 1
  248. fi
  249. }
  250. kube::test::if_has_not_string() {
  251. local message=$1
  252. local match=$2
  253. if grep -q "${match}" <<< "${message}"; then
  254. echo "FAIL!"
  255. echo "message:${message}"
  256. echo "has:${match}"
  257. caller
  258. return 1
  259. else
  260. echo "Successful"
  261. echo "message:${message}"
  262. echo "has not:${match}"
  263. return 0
  264. fi
  265. }
  266. kube::test::if_empty_string() {
  267. local match=$1
  268. if [ -n "${match}" ]; then
  269. echo "${match} is not empty"
  270. caller
  271. return 1
  272. else
  273. echo "Successful"
  274. return 0
  275. fi
  276. }
  277. # Returns true if the required resource is part of supported resources.
  278. # Expects env vars:
  279. # SUPPORTED_RESOURCES: Array of all resources supported by the apiserver. "*"
  280. # means it supports all resources. For ex: ("*") or ("rc" "*") both mean that
  281. # all resources are supported.
  282. # $1: Name of the resource to be tested.
  283. kube::test::if_supports_resource() {
  284. SUPPORTED_RESOURCES=${SUPPORTED_RESOURCES:-""}
  285. REQUIRED_RESOURCE=${1:-""}
  286. for r in "${SUPPORTED_RESOURCES[@]}"; do
  287. if [[ "${r}" == "*" || "${r}" == "${REQUIRED_RESOURCE}" ]]; then
  288. return 0
  289. fi
  290. done
  291. return 1
  292. }
  293. kube::test::version::object_to_file() {
  294. name=$1
  295. flags=${2:-""}
  296. file=$3
  297. kubectl version ${flags} | grep "${name} Version:" | sed -e s/"${name} Version: version.Info{"/'/' -e s/'}'/'/' -e s/', '/','/g -e s/':'/'=/g' -e s/'"'/""/g | tr , '\n' > "${file}"
  298. }
  299. kube::test::version::json_object_to_file() {
  300. flags=$1
  301. file=$2
  302. kubectl version ${flags} --output json | sed -e s/' '/''/g -e s/'\"'/''/g -e s/'}'/''/g -e s/'{'/''/g -e s/'clientVersion:'/'clientVersion:,'/ -e s/'serverVersion:'/'serverVersion:,'/ | tr , '\n' > "${file}"
  303. }
  304. kube::test::version::json_client_server_object_to_file() {
  305. flags=$1
  306. name=$2
  307. file=$3
  308. kubectl version ${flags} --output json | jq -r ".${name}" | sed -e s/'\"'/''/g -e s/'}'/''/g -e s/'{'/''/g -e /^$/d -e s/','/''/g -e s/':'/'='/g > "${file}"
  309. }
  310. kube::test::version::yaml_object_to_file() {
  311. flags=$1
  312. file=$2
  313. kubectl version ${flags} --output yaml | sed -e s/' '/''/g -e s/'\"'/''/g -e /^$/d > "${file}"
  314. }
  315. kube::test::version::diff_assert() {
  316. local original=$1
  317. local comparator=${2:-"eq"}
  318. local latest=$3
  319. local diff_msg=${4:-""}
  320. local res=""
  321. if [ ! -f "${original}" ]; then
  322. echo "${bold}${red}"
  323. echo "FAIL! ${diff_msg}"
  324. echo "the file '${original}' does not exit"
  325. echo "${reset}${red}"
  326. caller
  327. echo "${reset}"
  328. return 1
  329. fi
  330. if [ ! -f "${latest}" ]; then
  331. echo "${bold}${red}"
  332. echo "FAIL! ${diff_msg}"
  333. echo "the file '${latest}' does not exit"
  334. echo "${reset}${red}"
  335. caller
  336. echo "${reset}"
  337. return 1
  338. fi
  339. sort ${original} > "${original}.sorted"
  340. sort ${latest} > "${latest}.sorted"
  341. if [ "${comparator}" == "eq" ]; then
  342. if [ "$(diff -iwB ${original}.sorted ${latest}.sorted)" == "" ] ; then
  343. echo -n "${green}"
  344. echo "Successful: ${diff_msg}"
  345. echo -n "${reset}"
  346. return 0
  347. else
  348. echo "${bold}${red}"
  349. echo "FAIL! ${diff_msg}"
  350. echo " Expected: "
  351. echo "$(cat ${original})"
  352. echo " Got: "
  353. echo "$(cat ${latest})"
  354. echo "${reset}${red}"
  355. caller
  356. echo "${reset}"
  357. return 1
  358. fi
  359. else
  360. if [ ! -z "$(diff -iwB ${original}.sorted ${latest}.sorted)" ] ; then
  361. echo -n "${green}"
  362. echo "Successful: ${diff_msg}"
  363. echo -n "${reset}"
  364. return 0
  365. else
  366. echo "${bold}${red}"
  367. echo "FAIL! ${diff_msg}"
  368. echo " Expected: "
  369. echo "$(cat ${original})"
  370. echo " Got: "
  371. echo "$(cat ${latest})"
  372. echo "${reset}${red}"
  373. caller
  374. echo "${reset}"
  375. return 1
  376. fi
  377. fi
  378. }