summaryrefslogtreecommitdiffstats
path: root/bin/lvc/run_test_suite
blob: 9939abcad9b49851515a509f5b248cfdeba69019 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#!/bin/sh

set -e
set -u

NAME=$(basename ${0})

usage() {
    echo "Usage: $NAME [OPTION]... [FEATURE]...
Sets up an appropriate environment and tests FEATUREs (all by default). Note
that this script must be run from the Tails source directory root.

Options for '@product' features:
  --capture FILE     Captures the test session into FILE using VP8 encoding.
                     Requires ffmpeg and libvpx1.
  --debug            Display various debugging information while running the
                     test suite.
  --pause-on-fail    On failure, pause test suite until pressing Enter. This is
                     useful for investigating the state of the VM guest to see
                     exactly why a test failed.
  --keep-snapshots   Don't ever delete the background snapshots. This can a big
                     time saver when debugging new features.
  --retry-find       Print a warning whenever Sikuli fails to find an image
                     and allow *one* retry after pressing ENTER. This is useful
                     for updating outdated images.
  --temp-dir         Directory where various temporary files are written
                     during a test, e.g. VM snapshots and memory dumps,
                     failure screenshots, pcap files and disk images
                     (default is /tmp/DebianToaster).
  --view             Shows the test session in a windows. Requires x11vnc
                     and xtightvncviewer.
  --vnc-server-only  Starts a VNC server for the test session. Requires x11vnc.
  --iso IMAGE        Test '@product' features using IMAGE. If none is given,
                     the ISO with most recent creation date (according to the
                     ISO's label) in the current directory will be used.
  --old-iso IMAGE    For some '@product' features (e.g. usb_install) we need
                     an older version of Tails, which this options sets to
                     IMAGE. If none is given, the ISO with the least recent
                     creation date will be used.

Note that '@source' features has no relevant options.
"
}

error() {
    echo "${NAME}: error: ${*}" >&2
    usage
    exit 1
}

check_dependency() {
    if ! which "${1}" >/dev/null && \
       ! dpkg -s "${1}" 2>/dev/null | grep -q "^Status:.*installed"; then
        error "'${1}' is missing, please install it and run again. Aborting..."
    fi
}

display_in_use() {
    [ -e "/tmp/.X${1#:}-lock" ] || [ -e "/tmp/.X11-unix/X${1#:}" ]
}

next_free_display() {
    display_nr=0
    while display_in_use ":${display_nr}"; do
	display_nr=$((display_nr+1))
    done
    echo ":${display_nr}"
}

start_xvfb() {
    Xvfb $TARGET_DISPLAY -screen 0 1024x768x24+32 >/dev/null 2>&1 &
    XVFB_PID=$!
    trap "kill -0 ${XVFB_PID} 2>/dev/null && kill -9 ${XVFB_PID}; \
          rm -f /tmp/.X${TARGET_DISPLAY#:}-lock" EXIT
    # Wait for Xvfb to run on TARGET_DISPLAY
    until display_in_use $TARGET_DISPLAY; do
	sleep 1
    done
    echo "Virtual X framebuffer started on display ${TARGET_DISPLAY}"
    # Hide the mouse cursor so it won't mess up Sikuli's screen scanning
    unclutter -display $TARGET_DISPLAY -root -idle 0 >/dev/null 2>&1 &
}

start_vnc_server() {
    check_dependency x11vnc
    VNC_SERVER_PORT="$(x11vnc -listen localhost -display ${TARGET_DISPLAY} \
                              -bg -nopw 2>&1 | \
                                  grep -m 1 "^PORT=[0-9]\+" | sed 's/^PORT=//')"
    echo "VNC server running on: localhost:${VNC_SERVER_PORT}"
}

start_vnc_viewer() {
    check_dependency xtightvncviewer
    xtightvncviewer -viewonly localhost:${VNC_SERVER_PORT} 1>/dev/null 2>&1 &
}

capture_session() {
    echo "Capturing guest display into ${CAPTURE_FILE}"
    ffmpeg -f x11grab -s 1024x768 -r 15 -i ${TARGET_DISPLAY}.0 -an \
        -vcodec libvpx -y "${CAPTURE_FILE}" >/dev/null 2>&1 &
}

# main script

CAPTURE_FILE=
VNC_VIEWER=
VNC_SERVER=
DEBUG=
PAUSE_ON_FAIL=
KEEP_SNAPSHOTS=
SIKULI_RETRY_FINDFAILED=
TEMP_DIR=
ISO=
OLD_ISO=

LONGOPTS="view,vnc-server-only,capture:,help,temp-dir:,keep-snapshots,retry-find,iso:,old-iso:,debug,pause-on-fail"
OPTS=$(getopt -o "" --longoptions $LONGOPTS -n "${NAME}" -- "$@")
eval set -- "$OPTS"
while [ $# -gt 0 ]; do
    case $1 in
        --view)
            VNC_VIEWER=yes
            VNC_SERVER=yes
            ;;
        --vnc-server-only)
            VNC_VIEWER=
            VNC_SERVER=yes
            ;;
        --capture)
            shift
            CAPTURE_FILE="$1"
            ;;
        --debug)
            export DEBUG="yes"
            ;;
        --pause-on-fail)
            export PAUSE_ON_FAIL="yes"
            ;;
        --keep-snapshots)
            export KEEP_SNAPSHOTS="yes"
            ;;
        --retry-find)
            export SIKULI_RETRY_FINDFAILED="yes"
            ;;
        --temp-dir)
            shift
            export TEMP_DIR="$(readlink -f $1)"
            ;;
        --iso)
            shift
            export ISO="$(readlink -f $1)"
            ;;
        --old-iso)
            shift
            export OLD_ISO="$(readlink -f $1)"
            ;;
        --help)
	    usage
            exit 0
            ;;
        --)
            shift
            break
            ;;
    esac
    shift
done

for dep in ffmpeg git libvirt-bin libvirt-dev libavcodec-extra-53 libvpx1 \
           virt-viewer libsikuli-script-java ovmf tcpdump xvfb; do
    check_dependency "${dep}"
done

TARGET_DISPLAY=$(next_free_display)

start_xvfb

if [ -n "${CAPTURE_FILE}" ]; then
    capture_session
fi
if [ -n "${VNC_SERVER}" ]; then
    start_vnc_server
fi
if [ -n "${VNC_VIEWER}" ]; then
    start_vnc_viewer
fi

export JAVA_HOME="/usr/lib/jvm/java-7-openjdk-amd64"
export SIKULI_HOME="/usr/share/java"
export SIKULI_IMAGE_PATH="/srv/jenkins/features/images/"
export RUBYLIB="/srv/jenkins"
export FEATURE_PATH="/srv/jenkins/features"
export VM_XML_PATH="/srv/jenkins/features/domains"
export DISPLAY=${TARGET_DISPLAY}
CUCUMBEROPTS="--verbose --backtrace --expand"
check_dependency cucumber
if [ -z "${*}" ]; then
    cucumber $CUCUMBEROPTS --format ExtraHooks::Pretty $FEATURE_PATH
else
    FEATURES=""
    for f in ${*} ; do
	FEATURES="$FEATURES $FEATURE_PATH/$f"
    done
    cucumber $CUCUMBEROPTS --format ExtraHooks::Pretty $FEATURE_PATH/step_definitions $FEATURE_PATH/support $FEATURES
fi