Add a configurable per-test timeout. By default, tests will run fully.
If $TIMEOUT is set, tests may restrict themselves to that timeout. So,
e.g., `TIMEOUT=30 ./check -g quick -g timed` can be used to do a quick
sanity test without doing the full run.
Signed-off-by: Omar Sandoval <osandov@fb.com>
pass reliably.
- The `quick` group is a subset of `auto` comprising tests that complete
"quickly" (i.e., in ~30 seconds or less on reasonable hardware).
+- The `timed` group comprises tests that honor the configured test timeout (see
+ below)
`./check` can execute individual tests or test groups, as well as exclude tests
or test groups. See `./check -h`.
```sh
TEST_DEVS=(/dev/nvme0n1 /dev/sdb)
```
+
+### Test Timeout
+
+Many tests can take a long time to run. By setting the `TIMEOUT` variable, you
+can limit the runtime of each test to a specific length (in seconds).
+
+```sh
+TIMEOUT=30
+```
+
+Note that only tests in the `timed` group honor the timeout.
# The possible fields are specified above. The optional $FIO_PERF_PREFIX
# variable is prepended to the field name when reporting.
_fio_perf() {
- _fio_perf_run "$@"
+ _run_fio "$@"
_fio_perf_report
}
-_fio_perf_run() {
- fio --output="$TMPDIR/fio_perf" --output-format=terse --terse-version=4 \
- --group_reporting=1 "$@"
+# Wrapper around fio that handles:
+# - Recording perf results
+# - $TIMEOUT
+# You should usually use this instead of calling fio directly.
+_run_fio() {
+ local args=(--output="$TMPDIR/fio_perf" --output-format=terse --terse-version=4 --group_reporting=1)
+ if [[ -v TIMEOUT ]]; then
+ args+=(--runtime="$TIMEOUT")
+ fi
+ fio "${args[@]}" "$@"
}
_fio_perf_report() {
exit 1
}
+# If a test runs multiple "subtests", then each subtest should typically run
+# for TIMEOUT / number of subtests.
+_divide_timeout() {
+ local num_tests="$1"
+ if [[ -v TIMEOUT ]]; then
+ ((TIMEOUT = (TIMEOUT + num_tests - 1) / num_tests))
+ fi
+}
+
_have_root() {
if [[ $EUID -ne 0 ]]; then
SKIP_REASON="not running as root"
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# TODO: if this test shouldn't be run by default, remove the "auto" group. If
-# this test runs quickly, add it to the "quick" group. Add any other groups
-# describing what functionality this tests (e.g., "discard" or "hotplug"). Feel
-# free to create new groups if it makes sense.
+# this test runs quickly, add it to the "quick" group. If this test honors the
+# configured \$TIMEOUT, add it to the "timed" group.
+# Add any other groups describing what functionality this tests (e.g.,
+# "discard" or "hotplug"). Feel free to create new groups if it makes sense.
TEST_GROUPS=($category auto)
# TODO: fill in a very brief description of what this test does. The
# description should complete the sentence "This test will...". For example,
. common/scsi_debug
-TEST_GROUPS=(block auto hotplug)
+TEST_GROUPS=(block auto timed hotplug)
DESCRIPTION="stress device hotplugging"
prepare() {
host="${target%%:*}"
scan="${target#*:}"
scan="${scan//:/ }"
- for ((i = 0; i < 100; i++)); do
+ while [[ ! -e "$TMPDIR/stop" ]]; do
echo "${scan}" > "/sys/class/scsi_host/host${host}/scan"
echo 1 > "/sys/class/scsi_device/${target}/device/delete"
done
) &
done
+ sleep "$TIMEOUT"
+ touch "$TMPDIR/stop"
wait
+ rm -f "$TMPDIR/stop"
modprobe -r scsi_debug
}
test() {
echo "Running ${TEST_NAME}"
+ : ${TIMEOUT:=30}
+ _divide_timeout 2
+
echo "Stressing sd"
stress_scsi_debug add_host=4 num_tgts=1 ptype=0
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-TEST_GROUPS=(block auto discard)
+TEST_GROUPS=(block auto timed discard)
DESCRIPTION="run various discard sizes"
prepare() {
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-TEST_GROUPS=(block auto flush)
+TEST_GROUPS=(block auto timed flush)
DESCRIPTION="run lots of flushes"
prepare() {
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-TEST_GROUPS=(block auto sched)
+TEST_GROUPS=(block auto timed sched)
DESCRIPTION="switch schedulers while doing IO"
prepare() {
fi
# start fio job
- _fio_perf_run --bs=4k --rw=randread --norandommap \
+ _run_fio --bs=4k --rw=randread --norandommap \
--name=reads --filename="$TEST_DEV" --size="$size" \
--numjobs=8 --direct=1 &
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-TEST_GROUPS=(block auto)
+TEST_GROUPS=(block auto timed)
DESCRIPTION="run null-blk in blocking mode"
prepare() {
test() {
echo "Running ${TEST_NAME}"
+ _divide_timeout 2
+ FIO_PERF_FIELDS=("read iops")
+
modprobe -r null_blk
if ! modprobe null_blk queue_mode=2 submit_queues=2 blocking=1; then
return 1
fi
# run sync test
- fio --bs=4k --ioengine=sync --rw=randread --norandommap --name=reads \
- --filename=/dev/nullb0 --size=5g --direct=1 >> "$FULL"
+ _run_fio --bs=4k --ioengine=sync --rw=randread --norandommap --name=sync \
+ --filename=/dev/nullb0 --size=5g --direct=1
# run async test
- fio --bs=4k --ioengine=sync --rw=randread --norandommap --name=reads \
- --ioengine=libaio --iodepth=8 --numjobs=4 \
- --filename=/dev/nullb0 --size=5g --direct=1 >> "$FULL"
+ _run_fio --bs=4k --ioengine=libaio --iodepth=8 --numjobs=4 \
+ --rw=randread --norandommap --name=async \
+ --filename=/dev/nullb0 --size=5g --direct=1
modprobe -r null_blk
. common/iopoll
-TEST_GROUPS=(block auto poll)
+TEST_GROUPS=(block auto timed poll)
DESCRIPTION="test classic and hybrid IO polling"
prepare() {
test_device() {
echo "Running ${TEST_NAME}"
+ _divide_timeout 4
FIO_PERF_FIELDS=("read iops" "read lat mean" "system cpu")
# no polling, run job