test 7.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. #!/bin/bash
  2. shellfu import jat_dump
  3. shellfu import preupg
  4. shellfu import preupg_fupath
  5. shellfu import xcase
  6. PACKAGE="preupgrade-assistant"
  7. #shellcheck disable=SC2034
  8. PREUPG__RULE=xccdf_preupg_rule_api_deploy_hook_check
  9. HOOKS_ROOT="/root/preupgrade/hooks"
  10. HOOK_DIRNAME="api_deploy_hook"
  11. # mute ShellCheck
  12. Beh=
  13. CallSeq=
  14. assert_deployed() {
  15. #
  16. # Assert our hooks were deployed
  17. #
  18. local call
  19. local arg
  20. local hookdir
  21. for call in "${CallSeq[@]}";
  22. do
  23. debug -v call
  24. case $call in
  25. pre.*) hookdir="$HOOKS_ROOT/$HOOK_DIRNAME/preupgrade" ;;
  26. post.*) hookdir="$HOOKS_ROOT/$HOOK_DIRNAME/postupgrade" ;;
  27. #FIXME: structure unclear at the time of this writing
  28. *) xcase__id_error CallSeq
  29. esac
  30. jat__cmd -h "hook dir exists" \
  31. test -d "$hookdir"
  32. for arg in $(tr . '\n' <<<"${call#*.}");
  33. do
  34. debug -v arg
  35. case $arg in
  36. s*|as*)
  37. jat__cmd -h "hook script content is correct" \
  38. grep "echo hi I am script_$arg.sh" "$hookdir/run_hook"
  39. ;;
  40. f*|af*)
  41. jat__cmd -h "auxiliary file content is correct" \
  42. grep "text of file_$arg" "$hookdir/file_$arg.conf"
  43. ;;
  44. d*)
  45. jat__cmd -h "file_a from auxiliary dir is present" \
  46. test -s "$hookdir/dir_$arg/file_a"
  47. jat__cmd -h "file_b from auxiliary dir is present" \
  48. test -s "$hookdir/dir_$arg/file_b"
  49. ;;
  50. *)
  51. warn "assert_deployed() arg unhandled by assert: $arg"
  52. ;;
  53. esac
  54. done
  55. done
  56. }
  57. rtoken() {
  58. head -c 1000 /dev/urandom \
  59. | md5sum \
  60. | head -c 7
  61. }
  62. mktree() {
  63. #
  64. # Create tree (ini for fupath) for deployment
  65. #
  66. local call
  67. local arg
  68. for call in "${CallSeq[@]}";
  69. do
  70. for arg in ${call//./ };
  71. do
  72. debug -v arg
  73. case $arg in
  74. post|pre|badtype|X) true ;;
  75. as*) echo "echo hi I am script_$arg.sh; find" >"script_$arg.sh" ;;
  76. af*) echo "text of file_$arg" >"file_$arg.conf" ;;
  77. s*) echo "script_$arg.sh = echo hi I am script_$arg.sh; find" ;;
  78. f*) echo "file_$arg.conf = text of file_$arg" ;;
  79. d*) echo "dir_$arg/file_a = text of dir_$arg/file_a"
  80. echo "dir_$arg/file_b = text of dir_$arg/file_b" ;;
  81. *) xcase__id_error CallSeq ;;
  82. esac
  83. done
  84. done
  85. }
  86. mkcalls() {
  87. #
  88. # Create deploy_hook call (ini for fupath)
  89. #
  90. local call
  91. local arg
  92. for call in "${CallSeq[@]}";
  93. do
  94. debug -v call
  95. echo -n "CODE = deploy_hook"
  96. case $lang:$call in
  97. py:pre.*) echo -n "('preupgrade'" ;;
  98. py:post.*) echo -n "('postupgrade'" ;;
  99. py:badtype.*) echo -n "('badtype'" ;;
  100. sh:pre.*) echo -n " preupgrade" ;;
  101. sh:post.*) echo -n " postupgrade" ;;
  102. sh:badtype.*) echo -n " badtype" ;;
  103. *) xcase__id_error lang CallSeq ;;
  104. esac
  105. for arg in $(tr . '\n' <<<"${call#*.}");
  106. do
  107. debug -v arg
  108. case $lang:$arg in
  109. py:as*) echo -n ",'$PWD/script_$arg.sh'" ;;
  110. py:af*) echo -n ",'$PWD/file_$arg.conf'" ;;
  111. py:s*) echo -n ",'script_$arg.sh'" ;;
  112. py:f*) echo -n ",'file_$arg.conf'" ;;
  113. py:d*) echo -n ",'dir_$arg'" ;;
  114. py:X) echo -n ",'nonexistent_file_$(rtoken)'" ;;
  115. sh:as*) echo -n " $PWD/script_$arg.sh" ;;
  116. sh:af*) echo -n " $PWD/file_$arg.conf" ;;
  117. sh:s*) echo -n " script_$arg.sh" ;;
  118. sh:f*) echo -n " file_$arg.conf" ;;
  119. sh:d*) echo -n " dir_$arg" ;;
  120. sh:X) echo -n " nonexistent_file_$(rtoken)" ;;
  121. *) xcase__id_error lang CallSeq ;;
  122. esac
  123. done
  124. case $lang in
  125. py) echo ')';;
  126. sh) echo ;;
  127. esac
  128. done
  129. echo "CODE = exit_fixed$(test "$lang" = py && echo '()')"
  130. }
  131. XCASE__ARRAYS=CallSeq
  132. xcase__enum() {
  133. #
  134. # Enumerate subtest ids
  135. #
  136. # Parameters are 'Beh', behavior hint (to help simplify test phase),
  137. # and 'CallSeq' - plus-separated list of deploy_hook() calls in this
  138. # form:
  139. #
  140. # TYPE[.ARG][.ARG]..
  141. #
  142. # where TYPE is either 'post' or 'pre', and ARG are symbols for the
  143. # arguments deploy_hook() is called with:
  144. #
  145. # * sN means script N (1, 2, ...),
  146. # * fN means file N (1, 2, ...),
  147. # * asN and afN mean the same as sN and fN, but will be called by
  148. # absolute path
  149. # * dN means directory N (1, 2, ...),
  150. # * X means non-existent file
  151. #
  152. # Actual module code as well as all necessary files are created during
  153. # setup phase.
  154. #
  155. {
  156. # normal cases
  157. #
  158. # simplest
  159. echo Beh=OK,CallSeq=post.s1
  160. echo Beh=OK,CallSeq=post.s1.f1
  161. echo Beh=OK,CallSeq=post.s1.f1.d1
  162. echo Beh=OK,CallSeq=pre.s1
  163. echo Beh=OK,CallSeq=pre.s1.f1
  164. echo Beh=OK,CallSeq=pre.s1.f1.d1
  165. echo Beh=OK,CallSeq=pre.as1
  166. echo Beh=OK,CallSeq=pre.s1.af1
  167. # pre and post
  168. echo Beh=OK,CallSeq=pre.s1+post.s2
  169. echo Beh=OK,CallSeq=pre.s1.f1.d1+post.s2.f2.d2
  170. echo Beh=OK,CallSeq=post.s1.f1.d1+pre.s2.f2.d2
  171. # bad cases
  172. #
  173. # deploy twice: same, smaller, bigger
  174. echo Beh=BAD,CallSeq=post.s1+post.s1
  175. echo Beh=BAD,CallSeq=post.s1.f1.d1+post.s1
  176. echo Beh=BAD,CallSeq=post.s1+post.s1.f1.d1
  177. # bad args: no script, script is dir, nonexistent, double arg, bad type
  178. echo Beh=BAD,CallSeq=post.
  179. echo Beh=BAD,CallSeq=post.d1
  180. echo Beh=BAD,CallSeq=post.X
  181. echo Beh=BAD,CallSeq=post.X.X
  182. echo Beh=BAD,CallSeq=post.s1.X.X
  183. # echo Beh=BAD,CallSeq=post.s1.f1.f1 # not sure if we can/need to catch this
  184. echo Beh=BAD,CallSeq=post.s1.d1.X
  185. echo Beh=BAD,CallSeq=badtype.s1
  186. } | xcase__per lang sh py
  187. }
  188. #shellcheck disable=SC2154
  189. xcase__setup() {
  190. #
  191. # Prepare for subtest
  192. #
  193. {
  194. echo "[MODULE]"
  195. echo "GROUP = api"
  196. echo "NAME = deploy_hook"
  197. echo "LANG = $lang"
  198. mkcalls
  199. echo "[FILES]"
  200. mktree
  201. } > module.ini
  202. preupg_fupath RHEL6_7 module.ini
  203. PREUPG__UPATH="RHEL6_7/all-xccdf.xml" \
  204. preupg__run1 --skip-common
  205. }
  206. xcase__test() {
  207. #
  208. # Do the work
  209. #
  210. jat__eval -S 0,1 -h "store hook file list" \
  211. "find '$HOOKS_ROOT' -type f | grep deploy_hook > hooks"
  212. case $Beh in
  213. OK)
  214. assert_deployed
  215. jat__eval -S 1 -h "no errors were logged" \
  216. "preupg__get_messages ERROR | grep ."
  217. ;;
  218. BAD)
  219. jat__eval -S 0 -h "error was logged" \
  220. "preupg__get_messages ERROR | grep ."
  221. preupg__assert result 'error'
  222. ;;
  223. *)
  224. xcase__id_error Beh
  225. ;;
  226. esac
  227. }
  228. xcase__diag() {
  229. #
  230. # Burp up some diag
  231. #
  232. jat_dump__file module.ini hooks
  233. preupg__get_node | jat_dump__pipe NODE
  234. preupg__get_messages | jat_dump__pipe LOG_MESSAGES
  235. }
  236. xcase__cleanup() {
  237. #
  238. # Clean up after subtest
  239. #
  240. preupg__rmresult
  241. }
  242. PREUPG__UPATH=@pass \
  243. preupg__Run1
  244. xcase__run -v
  245. preupg__Cleanup