Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / qa / run_xfstests.sh
1 #!/bin/bash
2
3 # Copyright (C) 2012 Dreamhost, LLC
4 #
5 # This is free software; see the source for copying conditions.
6 # There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR
7 # A PARTICULAR PURPOSE.
8 #
9 # This is free software; you can redistribute it and/or modify it
10 # under the terms of the GNU General Public License as
11 # published by the Free Software Foundation version 2.
12
13 # Usage:
14 # run_xfstests -t /dev/<testdev> -s /dev/<scratchdev> [-f <fstype>] -- <tests>
15 #   - test device and scratch device will both get trashed
16 #   - fstypes can be xfs, ext4, or btrfs (xfs default)
17 #   - tests can be listed individually: generic/001 xfs/008 xfs/009
18 #     tests can also be specified by group: -g quick
19 #
20 # Exit status:
21 #     0:  success
22 #     1:  usage error
23 #     2:  other runtime error
24 #    99:  argument count error (programming error)
25 #   100:  getopt error (internal error)
26
27 # Alex Elder <elder@dreamhost.com>
28 # April 13, 2012
29
30 set -e
31
32 PROGNAME=$(basename $0)
33
34 # Default command line option values
35 COUNT="1"
36 EXPUNGE_FILE=""
37 DO_RANDOMIZE="" # false
38 FSTYP="xfs"
39 SCRATCH_DEV=""  # MUST BE SPECIFIED
40 TEST_DEV=""     # MUST BE SPECIFIED
41 TESTS="-g auto" # The "auto" group is supposed to be "known good"
42
43 # print an error message and quit with non-zero status
44 function err() {
45         if [ $# -gt 0 ]; then
46                 echo "" >&2
47                 echo "${PROGNAME}: ${FUNCNAME[1]}: $@" >&2
48         fi
49         exit 2
50 }
51
52 # routine used to validate argument counts to all shell functions
53 function arg_count() {
54         local func
55         local want
56         local got
57
58         if [ $# -eq 2 ]; then
59                 func="${FUNCNAME[1]}"   # calling function
60                 want=$1
61                 got=$2
62         else
63                 func="${FUNCNAME[0]}"   # i.e., arg_count
64                 want=2
65                 got=$#
66         fi
67         [ "${want}" -eq "${got}" ] && return 0
68         echo "${PROGNAME}: ${func}: arg count bad (want ${want} got ${got})" >&2
69         exit 99
70 }
71
72 # validation function for repeat count argument
73 function count_valid() {
74         arg_count 1 $#
75
76         test "$1" -gt 0 # 0 is pointless; negative is wrong
77 }
78
79 # validation function for filesystem type argument
80 function fs_type_valid() {
81         arg_count 1 $#
82
83         case "$1" in
84                 xfs|ext4|btrfs) return 0 ;;
85                 *)              return 1 ;;
86         esac
87 }
88
89 # validation function for device arguments
90 function device_valid() {
91         arg_count 1 $#
92
93         # Very simple testing--really should try to be more careful...
94         test -b "$1"
95 }
96
97 # validation function for expunge file argument
98 function expunge_file_valid() {
99         arg_count 1 $#
100
101         test -s "$1"
102 }
103
104 # print a usage message and quit
105 #
106 # if a message is supplied, print that first, and then exit
107 # with non-zero status
108 function usage() {
109         if [ $# -gt 0 ]; then
110                 echo "" >&2
111                 echo "$@" >&2
112         fi
113
114         echo "" >&2
115         echo "Usage: ${PROGNAME} <options> -- <tests>" >&2
116         echo "" >&2
117         echo "    options:" >&2
118         echo "        -h or --help" >&2
119         echo "            show this message" >&2
120         echo "        -c or --count" >&2
121         echo "            iteration count (1 or more)" >&2
122         echo "        -f or --fs-type" >&2
123         echo "            one of: xfs, ext4, btrfs" >&2
124         echo "            (default fs-type: xfs)" >&2
125         echo "        -r or --randomize" >&2
126         echo "            randomize test order" >&2
127         echo "        -s or --scratch-dev     (REQUIRED)" >&2
128         echo "            name of device used for scratch filesystem" >&2
129         echo "        -t or --test-dev        (REQUIRED)" >&2
130         echo "            name of device used for test filesystem" >&2
131         echo "        -x or --expunge-file" >&2
132         echo "            name of file with list of tests to skip" >&2
133         echo "    tests:" >&2
134         echo "        list of test numbers, e.g.:" >&2
135         echo "            generic/001 xfs/008 shared/032 btrfs/009" >&2
136         echo "        or possibly an xfstests test group, e.g.:" >&2
137         echo "            -g quick" >&2
138         echo "        (default tests: -g auto)" >&2
139         echo "" >&2
140
141         [ $# -gt 0 ] && exit 1
142
143         exit 0          # This is used for a --help
144 }
145
146 # parse command line arguments
147 function parseargs() {
148         # Short option flags
149         SHORT_OPTS=""
150         SHORT_OPTS="${SHORT_OPTS},h"
151         SHORT_OPTS="${SHORT_OPTS},c:"
152         SHORT_OPTS="${SHORT_OPTS},f:"
153         SHORT_OPTS="${SHORT_OPTS},r"
154         SHORT_OPTS="${SHORT_OPTS},s:"
155         SHORT_OPTS="${SHORT_OPTS},t:"
156         SHORT_OPTS="${SHORT_OPTS},x:"
157
158         # Long option flags
159         LONG_OPTS=""
160         LONG_OPTS="${LONG_OPTS},help"
161         LONG_OPTS="${LONG_OPTS},count:"
162         LONG_OPTS="${LONG_OPTS},fs-type:"
163         LONG_OPTS="${LONG_OPTS},randomize"
164         LONG_OPTS="${LONG_OPTS},scratch-dev:"
165         LONG_OPTS="${LONG_OPTS},test-dev:"
166         LONG_OPTS="${LONG_OPTS},expunge-file:"
167
168         TEMP=$(getopt --name "${PROGNAME}" \
169                 --options "${SHORT_OPTS}" \
170                 --longoptions "${LONG_OPTS}" \
171                 -- "$@")
172         eval set -- "$TEMP"
173
174         while [ "$1" != "--" ]; do
175                 case "$1" in
176                         -h|--help)
177                                 usage
178                                 ;;
179                         -c|--count)
180                                 count_valid "$2" ||
181                                         usage "invalid count '$2'"
182                                 COUNT="$2"
183                                 shift
184                                 ;;
185                         -f|--fs-type)
186                                 fs_type_valid "$2" ||
187                                         usage "invalid fs_type '$2'"
188                                 FSTYP="$2"
189                                 shift
190                                 ;;
191                         -r|--randomize)
192                                 DO_RANDOMIZE="t"
193                                 ;;
194                         -s|--scratch-dev)
195                                 device_valid "$2" ||
196                                         usage "invalid scratch-dev '$2'"
197                                 SCRATCH_DEV="$2"
198                                 shift
199                                 ;;
200                         -t|--test-dev)
201                                 device_valid "$2" ||
202                                         usage "invalid test-dev '$2'"
203                                 TEST_DEV="$2"
204                                 shift
205                                 ;;
206                         -x|--expunge-file)
207                                 expunge_file_valid "$2" ||
208                                         usage "invalid expunge-file '$2'"
209                                 EXPUNGE_FILE="$2"
210                                 shift
211                                 ;;
212                         *)
213                                 exit 100        # Internal error
214                                 ;;
215                 esac
216                 shift
217         done
218         shift
219
220         [ -n "${TEST_DEV}" ] || usage "test-dev must be supplied"
221         [ -n "${SCRATCH_DEV}" ] || usage "scratch-dev must be supplied"
222
223         [ $# -eq 0 ] || TESTS="$@"
224 }
225
226 ################################################################
227
228 # run mkfs on the given device using the specified filesystem type
229 function do_mkfs() {
230         arg_count 1 $#
231
232         local dev="${1}"
233         local options
234
235         case "${FSTYP}" in
236                 xfs)    options="-f" ;;
237                 ext4)   options="-F" ;;
238                 btrfs)  options="-f" ;;
239         esac
240
241         "mkfs.${FSTYP}" ${options} "${dev}" ||
242                 err "unable to make ${FSTYP} file system on device \"${dev}\""
243 }
244
245 # top-level setup routine
246 function setup() {
247         arg_count 0 $#
248
249         wget -P "${TESTDIR}" http://download.ceph.com/qa/xfstests.tar.gz
250         tar zxf "${TESTDIR}/xfstests.tar.gz" -C "$(dirname "${XFSTESTS_DIR}")"
251         mkdir "${TEST_DIR}"
252         mkdir "${SCRATCH_MNT}"
253         do_mkfs "${TEST_DEV}"
254 }
255
256 # top-level (final) cleanup routine
257 function cleanup() {
258         arg_count 0 $#
259
260         # ensure teuthology can clean up the logs
261         chmod -R a+rw "${TESTDIR}/archive"
262
263         findmnt "${TEST_DEV}" && umount "${TEST_DEV}"
264         [ -d "${SCRATCH_MNT}" ] && rmdir "${SCRATCH_MNT}"
265         [ -d "${TEST_DIR}" ] && rmdir "${TEST_DIR}"
266         rm -rf "${XFSTESTS_DIR}"
267         rm -f "${TESTDIR}/xfstests.tar.gz"
268 }
269
270 # ################################################################
271
272 start_date="$(date)"
273 parseargs "$@"
274 [ -n "${TESTDIR}" ] || usage "TESTDIR env variable must be set"
275 [ -d "${TESTDIR}/archive" ] || usage "\$TESTDIR/archive directory must exist"
276 TESTDIR="$(readlink -e "${TESTDIR}")"
277 [ -n "${EXPUNGE_FILE}" ] && EXPUNGE_FILE="$(readlink -e "${EXPUNGE_FILE}")"
278
279 XFSTESTS_DIR="/var/lib/xfstests"  # hardcoded into dbench binary
280 TEST_DIR="/mnt/test_dir"
281 SCRATCH_MNT="/mnt/scratch_mnt"
282 MKFS_OPTIONS=""
283 EXT_MOUNT_OPTIONS="-o block_validity"
284
285 trap cleanup EXIT ERR HUP INT QUIT
286 setup
287
288 export TEST_DEV
289 export TEST_DIR
290 export SCRATCH_DEV
291 export SCRATCH_MNT
292 export FSTYP
293 export MKFS_OPTIONS
294 export EXT_MOUNT_OPTIONS
295
296 pushd "${XFSTESTS_DIR}"
297 for (( i = 1 ; i <= "${COUNT}" ; i++ )); do
298         [ "${COUNT}" -gt 1 ] && echo "=== Iteration "$i" starting at:  $(date)"
299
300         RESULT_BASE="${TESTDIR}/archive/results-${i}"
301         mkdir "${RESULT_BASE}"
302         export RESULT_BASE
303
304         EXPUNGE=""
305         [ -n "${EXPUNGE_FILE}" ] && EXPUNGE="-E ${EXPUNGE_FILE}"
306
307         RANDOMIZE=""
308         [ -n "${DO_RANDOMIZE}" ] && RANDOMIZE="-r"
309
310         # -T output timestamps
311         PATH="${PWD}/bin:${PATH}" ./check -T ${RANDOMIZE} ${EXPUNGE} ${TESTS}
312         findmnt "${TEST_DEV}" && umount "${TEST_DEV}"
313
314         [ "${COUNT}" -gt 1 ] && echo "=== Iteration "$i" complete at:  $(date)"
315 done
316 popd
317
318 # cleanup is called via the trap call, above
319
320 echo "This xfstests run started at:  ${start_date}"
321 echo "xfstests run completed at:     $(date)"
322 [ "${COUNT}" -gt 1 ] && echo "xfstests run consisted of ${COUNT} iterations"
323 echo OK