run_test_suite 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. #!/bin/bash
  2. set -e
  3. set -u
  4. set -o pipefail
  5. NAME=$(basename ${0})
  6. GENERAL_DEPENDENCIES="
  7. cucumber
  8. devscripts
  9. dnsmasq-base
  10. gawk
  11. git
  12. i18nspector
  13. libav-tools
  14. libcap2-bin
  15. libsikuli-script-java
  16. libvirt-clients
  17. libvirt-daemon-system
  18. libvirt-dev
  19. libvirt0
  20. obfs4proxy
  21. openssh-server
  22. ovmf
  23. pry
  24. python-jabberbot
  25. python-potr
  26. qemu-kvm
  27. qemu-system-x86
  28. ruby-guestfs
  29. ruby-json
  30. ruby-libvirt
  31. ruby-net-irc
  32. ruby-packetfu
  33. ruby-rb-inotify
  34. ruby-rjb
  35. ruby-rspec
  36. ruby-test-unit
  37. seabios
  38. tcpdump
  39. tor
  40. unclutter
  41. virt-viewer
  42. xvfb
  43. "
  44. usage() {
  45. echo "Usage: $NAME [OPTION]... [--] [CUCUMBER_ARGS]...
  46. Sets up an appropriate environment and invokes cucumber. Note that this script
  47. must be run from the Tails source directory root.
  48. Options for '@product' features:
  49. --artifacts-base-uri URI
  50. Pretend that the artifact is located at URI when printing
  51. its location during a scenario failure. This is useful if
  52. you intend to serve the artifacts via the web, for
  53. instance.
  54. --capture Captures failed scenarios into videos stored in the
  55. temporary directory (see --tmpdir below) using x264
  56. encoding. Requires x264.
  57. --capture-all Keep videos for all scenarios, including those that
  58. succeed (implies --capture).
  59. --interactive-debugging
  60. On failure, pause test suite until pressing Enter. Also
  61. offer the option to open an interactive Ruby shell (pry)
  62. in the Cucumber world's context.
  63. --keep-snapshots Don't ever delete any snapshots (including ones marked as
  64. temporary). This can be a big time saver when debugging new
  65. features.
  66. --retry-find Print a warning whenever Sikuli fails to find an image
  67. and allow *one* retry after pressing ENTER. This is useful
  68. for updating outdated images.
  69. --tmpdir Directory where various temporary files are written
  70. during a test, e.g. VM snapshots and memory dumps,
  71. failure screenshots, pcap files and disk images
  72. (default is TMPDIR in the environment, and if unset,
  73. /tmp/TailsToaster).
  74. --view Shows the test session in a windows. Requires x11vnc
  75. and xtightvncviewer.
  76. --vnc-server-only Starts a VNC server for the test session. Requires x11vnc.
  77. --iso IMAGE Test '@product' features using IMAGE.
  78. --old-iso IMAGE For some '@product' features (e.g. usb_install) we need
  79. an older version of Tails, which this options sets to
  80. IMAGE. If none is given, it defaults to the same IMAGE
  81. given by --iso, which will be good enough for most testing
  82. purposes.
  83. Note that '@source' features has no relevant options.
  84. CUCUMBER_ARGS can be used to specify which features to be run, but also any
  85. cucumber option, although then you must pass \`--\` first to let this wrapper
  86. script know that we're done with *its* options. For debugging purposes, a
  87. 'debug' formatter has been added so pretty debugging can be enabled with
  88. \`--format debug\`. You could even combine the default (pretty) formatter with
  89. pretty debugging printed to a file with \`--format pretty --format debug
  90. --out debug.log\`.
  91. "
  92. }
  93. error() {
  94. echo "${NAME}: error: ${*}" >&2
  95. usage
  96. exit 1
  97. }
  98. package_installed() {
  99. local ret
  100. set +o pipefail
  101. if dpkg -s "${1}" 2>/dev/null | grep -q "^Status:.*installed"; then
  102. ret=0
  103. else
  104. ret=1
  105. fi
  106. set -o pipefail
  107. return ${ret}
  108. }
  109. check_dependencies() {
  110. while [ -n "${1:-}" ]; do
  111. if ! which "${1}" >/dev/null && ! package_installed "${1}" ; then
  112. error "'${1}' is missing, please install it and run again."
  113. fi
  114. shift
  115. done
  116. }
  117. display_in_use() {
  118. [ -e "/tmp/.X${1#:}-lock" ] || [ -e "/tmp/.X11-unix/X${1#:}" ]
  119. }
  120. next_free_display() {
  121. display_nr=0
  122. while display_in_use ":${display_nr}"; do
  123. display_nr=$((display_nr+1))
  124. done
  125. echo ":${display_nr}"
  126. }
  127. test_suite_cleanup() {
  128. (kill -0 ${XVFB_PID} 2>/dev/null && kill ${XVFB_PID}) || /bin/true
  129. }
  130. start_xvfb() {
  131. Xvfb $TARGET_DISPLAY -screen 0 1024x768x24+32 >/dev/null 2>&1 &
  132. XVFB_PID=$!
  133. # Wait for Xvfb to run on TARGET_DISPLAY
  134. until display_in_use $TARGET_DISPLAY; do
  135. sleep 1
  136. done
  137. echo "Virtual X framebuffer started on display ${TARGET_DISPLAY}"
  138. # Hide the mouse cursor so it won't mess up Sikuli's screen scanning
  139. unclutter -display $TARGET_DISPLAY -root -idle 0 >/dev/null 2>&1 &
  140. }
  141. start_vnc_server() {
  142. check_dependencies x11vnc
  143. VNC_SERVER_PORT="$(x11vnc -listen localhost -display ${TARGET_DISPLAY} \
  144. -bg -nopw -forever 2>&1 | \
  145. grep -m 1 "^PORT=[0-9]\+" | sed 's/^PORT=//')"
  146. echo "VNC server running on: localhost:${VNC_SERVER_PORT}"
  147. }
  148. start_vnc_viewer() {
  149. check_dependencies xtightvncviewer
  150. xtightvncviewer -viewonly localhost:${VNC_SERVER_PORT} 1>/dev/null 2>&1 &
  151. }
  152. capture_session() {
  153. check_dependencies libvpx1
  154. echo "Capturing guest display into ${CAPTURE_FILE}"
  155. avconv -f x11grab -s 1024x768 -r 15 -i ${TARGET_DISPLAY}.0 -an \
  156. -vcodec libvpx -y "${CAPTURE_FILE}" >/dev/null 2>&1 &
  157. }
  158. # main script
  159. # Unset all environment variables used by this script to pass options
  160. # to cucumber, except TMPDIR since we explicitly want to support
  161. # setting it that way.
  162. ARTIFACTS_BASE_URI=
  163. CAPTURE=
  164. CAPTURE_ALL=
  165. LOG_FILE=
  166. VNC_VIEWER=
  167. VNC_SERVER=
  168. INTERACTIVE_DEBUGGING=
  169. KEEP_SNAPSHOTS=
  170. SIKULI_RETRY_FINDFAILED=
  171. TAILS_ISO=
  172. OLD_TAILS_ISO=
  173. LONGOPTS="artifacts-base-uri:,view,vnc-server-only,capture,capture-all,help,tmpdir:,keep-snapshots,retry-find,iso:,old-iso:,interactive-debugging"
  174. OPTS=$(getopt -o "" --longoptions $LONGOPTS -n "${NAME}" -- "$@")
  175. eval set -- "$OPTS"
  176. while [ $# -gt 0 ]; do
  177. case $1 in
  178. --artifacts-base-uri)
  179. shift
  180. export ARTIFACTS_BASE_URI="${1}"
  181. ;;
  182. --view)
  183. VNC_VIEWER=yes
  184. VNC_SERVER=yes
  185. ;;
  186. --vnc-server-only)
  187. VNC_VIEWER=
  188. VNC_SERVER=yes
  189. ;;
  190. --capture)
  191. check_dependencies x264
  192. export CAPTURE="yes"
  193. ;;
  194. --capture-all)
  195. check_dependencies x264
  196. export CAPTURE="yes"
  197. export CAPTURE_ALL="yes"
  198. ;;
  199. --interactive-debugging)
  200. export INTERACTIVE_DEBUGGING="yes"
  201. ;;
  202. --keep-snapshots)
  203. export KEEP_SNAPSHOTS="yes"
  204. ;;
  205. --retry-find)
  206. export SIKULI_RETRY_FINDFAILED="yes"
  207. ;;
  208. --tmpdir)
  209. shift
  210. export TMPDIR="$(readlink -f $1)"
  211. ;;
  212. --iso)
  213. shift
  214. export TAILS_ISO="$(readlink -f $1)"
  215. ;;
  216. --old-iso)
  217. shift
  218. export OLD_TAILS_ISO="$(readlink -f $1)"
  219. ;;
  220. --help)
  221. usage
  222. exit 0
  223. ;;
  224. --)
  225. shift
  226. break
  227. ;;
  228. esac
  229. shift
  230. done
  231. trap "test_suite_cleanup" EXIT HUP INT QUIT TERM
  232. check_dependencies ${GENERAL_DEPENDENCIES}
  233. TARGET_DISPLAY=$(next_free_display)
  234. start_xvfb
  235. if [ -n "${VNC_SERVER:-}" ]; then
  236. start_vnc_server
  237. fi
  238. if [ -n "${VNC_VIEWER:-}" ]; then
  239. start_vnc_viewer
  240. fi
  241. export SIKULI_HOME="/usr/share/java"
  242. export DISPLAY=${TARGET_DISPLAY}
  243. cucumber ${@}