forked from osandov/blktests
-
Notifications
You must be signed in to change notification settings - Fork 0
/
new
executable file
·283 lines (253 loc) · 10.9 KB
/
new
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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
#!/bin/bash
# SPDX-License-Identifier: GPL-3.0+
# Copyright (C) 2017 Omar Sandoval
set -e
shopt -s extglob
_error() {
echo "$0: $*" >&2
exit 1
}
prompt_yes_no() {
if [[ $2 =~ ^[Yy] ]]; then
local default=0
local prompt="$1 [Y/n] "
else
local default=1
local prompt="$1 [y/N] "
fi
local yn
read -r -n 1 -p "${prompt}" yn
if [[ -n "${yn}" ]]; then
echo
fi
if [[ "${yn}" =~ ^[Yy] ]]; then
return 0
elif [[ "${yn}" =~ ^[Nn] ]]; then
return 1
else
return $default
fi
}
echo "Available test groups:"
find tests -mindepth 1 -maxdepth 1 -type d -not -name meta -printf ' %P\n' | sort
read -r -p "Category for new test (pick one of the above or create a new one): " group
if [[ -z $group ]]; then
exit 1
fi
if [[ $group =~ [[:space:]/] ]]; then
_error 'group name must not contain whitespace or "/"'
fi
if [[ ! -e tests/${group} ]]; then
if ! prompt_yes_no "Category does not exist; create it?"; then
exit 1
fi
mkdir -p "tests/${group}"
cat << EOF > "tests/${group}/rc"
#!/bin/bash
# SPDX-License-Identifier: GPL-3.0+
# Copyright (C) $(date +%Y) TODO YOUR NAME HERE
#
# TODO: provide a brief description of the group here.
. common/rc
# TODO: source any more common helpers needed for this group.
# . common/foo
# TODO: if this test group has any extra requirements, it should define a
# group_requires() function. If tests in this group cannot be run,
# group_requires() should add strings to the \$SKIP_REASONS array which
# describe why the group cannot be run.
#
# Usually, group_requires() just needs to check that any necessary programs and
# kernel features are available using the _have_foo helpers. If
# group_requires() adds strings to \$SKIP_REASONS, all tests in this group will
# be skipped.
group_requires() {
_have_root
}
# TODO: if this test group has extra requirements for what devices it can be
# run on, it should define a group_device_requires() function. If tests in this
# group cannot be run on the test device, it should add strings to
# \$SKIP_REASONS. \$TEST_DEV is the full path of the block device (e.g.,
# /dev/nvme0n1 or /dev/sda1), and \$TEST_DEV_SYSFS is the sysfs path of the
# disk (not the partition, e.g., /sys/block/nvme0n1 or /sys/block/sda). If
# the target device is a partition device, \$TEST_DEV_PART_SYSFS is the sysfs
# path of the partition device (e.g., /sys/block/nvme0n1/nvme0n1p1 or
# /sys/block/sda/sda1). Otherwise, \$TEST_DEV_PART_SYSFS is an empty string.
#
# Usually, group_device_requires() just needs to check that the test device is
# the right type of hardware or supports any necessary features using the
# _require_test_dev_foo helpers. If group_device_requires() adds strings to
# \$SKIP_REASONS, all tests in this group will be skipped on that device.
# group_device_requires() {
# _require_test_dev_is_foo && _require_test_dev_supports_bar
# }
# TODO: define any helpers that are specific to this group.
EOF
echo "Created tests/${group}/rc"
fi
seq=0
for test in tests/"$group"/+([0-9]); do
if [[ -e $test ]]; then
seq=${test##tests/"${group}"/+(0)}
fi
done
test_name="${group}/$(printf "%03d" $((seq + 1)))"
cat << EOF > "tests/${test_name}"
#!/bin/bash
# SPDX-License-Identifier: GPL-3.0+
# Copyright (C) $(date +%Y) TODO YOUR NAME HERE
#
# TODO: provide a description of the test here, i.e., what it tests and how. If
# this is a regression test for a patch, reference the patch title:
#
# Regression test for patch "blk-stat: fix blk_stat_sum() if all samples are
# batched".
#
# For a commit, use the first 12 characters of the commit hash and the one-line
# commit summary:
#
# Regression test for commit efd4b81abbe1 ("blk-stat: fix blk_stat_sum() if all
# samples are batched").
. tests/${group}/rc
# TODO: source any more common helpers needed for this test.
# TODO: fill in a very brief description of what this test does. The
# description should complete the sentence "This test will...". For example,
# "run a mixed read/write workload" would be a good description.
DESCRIPTION=""
# TODO: if this test completes quickly (i.e., in ~30 seconds or less on
# reasonable hardware), uncomment the line below.
# QUICK=1
# TODO: if this test honors the configured \$TIMEOUT, uncomment the line below.
# This is for tests that can potentially run for a long time but where it's
# possible to limit the runtime (e.g., with the \`timeout\` command or with
# fio --runtime, which is what the _run_fio helper does). A test shouldn't be
# both QUICK and TIMED.
# TIMED=1
# TODO: dmesg is checked for oopses, warnings, etc. after each test run by
# default. You can suppress this by defining:
# CHECK_DMESG=0
# Alternatively, you can filter out any unimportant messages in dmesg like so:
# DMESG_FILTER="grep -v sysfs"
# TODO: if this test can be run for both regular block devices and zoned block
# devices, uncomment the line below.
# CAN_BE_ZONED=1
# TODO: if this test has any extra requirements, it should define a requires()
# function. If the test cannot be run, requires() should add strings to
# \$SKIP_REASONS. Usually, requires() just needs to check that any necessary
# programs and kernel features are available using the _have_foo helpers.
# If requires() adds strings to \$SKIP_REASONS, the test is skipped.
# requires() {
# _have_foo
# }
# TODO: if this test has extra requirements for what devices it can be run on,
# it should define a device_requires() function. If this test cannot be run on
# the test device, it should add strings to \$SKIP_REASONS. \$TEST_DEV is the
# full path of the block device (e.g., /dev/nvme0n1 or /dev/sda1), and
# \$TEST_DEV_SYSFS is the sysfs path of the disk (not the partition, e.g.,
# /sys/block/nvme0n1 or /sys/block/sda). If the target device is a partition
# device, \$TEST_DEV_PART_SYSFS is the sysfs path of the partition device
# (e.g., /sys/block/nvme0n1/nvme0n1p1 or /sys/block/sda/sda1). Otherwise,
# \$TEST_DEV_PART_SYSFS is an empty string.
#
# Usually, device_requires() just needs to check that the test device is the
# right type of hardware or supports any necessary features using the
# _require_test_dev_foo helpers. If device_requires() adds strings to
# \$SKIP_REASONS, the test will be skipped on that device.
# device_requires() {
# _require_test_dev_is_foo && _require_test_dev_supports_bar
# }
# TODO: if the test case can run the same test for different conditions, define
# the helper function "set_conditions". When no argument is specified, return
# the number of condition variations. Blktests repeats the test case as many
# times as the returned number. When its argument is specified, refer to it as
# the condition variation index and set up the conditions for it. Also set the
# global variable COND_DESC which is printed at the test case run and used for
# the result directory name. Blktests calls set_conditions() before each run of
# the test case incrementing the argument index from 0.
# set_conditions() {
# local index=\$1
#
# if [[ -z \$index ]]; then
# echo 2 # return number of condition variations
# return
# fi
#
# # Set test conditions based on the $index
# ...
# COND_DESC="Describe the conditions shortly"
# }
# TODO: define the test. The output of this function (stdout and stderr) will
# be compared to tests/\${TEST_NAME}.out. If it does not match, the test is
# considered a failure. If the test runs a command which has unnecessary
# output, either redirect that output to \$FULL or /dev/null, or filter out the
# unimportant parts (e.g., with grep or the _filter_foo helpers).
#
# Additionally, if the test function returns non-zero, it is considered a
# failure. You should prefer letting the test fail because of broken output
# over, say, checking the exit status of every command you run.
#
# If the test cannot be run, this function may add strings to \$SKIP_REASONS
# and return. In that case, the return value and output are ignored, and the
# test is considered skipped. This should only be done when the requirements
# can only be detected with a non-trivial amount of setup; use
# group_requires(), requires(), and/or device_requires() instead when possible.
#
# Various variables are defined for the test:
# - \$TEST_NAME -- the full name of the test.
# - \$TMPDIR -- a temporary directory deleted after the test is run.
# - \$SRCDIR -- absolute path of the src/ subdirectory
# - \$FULL -- a file where the test may log verbose output (e.g., the output
# of fio or mkfs).
# - \$TEST_RUN -- an associative array of additional test data to display
# after the test is run and store for comparison on future
# test runs. Use like TEST_RUN[iops]="\$(measure_iops)".
# - \$TIMEOUT -- an optional timeout configured by the user. If possible, limit
# the runtime of the entire test to this value if it is set.
#
# Many tests do not need a test device (usually because they set up their own
# virtual devices, like null-blk or loop). These tests should define the test()
# function.
#
# Tests that require a test device should rename test() to test_device(). These
# tests will be run with a few more variables defined:
# - \$TEST_DEV -- the block device to run the test on (e.g., /dev/sda1).
# - \$TEST_DEV_SYSFS -- the sysfs directory of the device (e.g.,
# /sys/block/sda). In general, you should use the
# _test_dev_queue_{get,set} helpers. If the device is a
# partition, this is the directory of its holder
# device.
# - \$TEST_DEV_PART_SYSFS -- the sysfs directory of the device if the device
# is a partition device (e.g.,
# /sys/block/sda/sda1). If the device is not a
# partition, this is an empty string.
test() {
echo "Running \${TEST_NAME}"
# TODO: fill in the test case.
echo "Test complete"
}
# Finally, some coding style guidelines:
# - Indent with tabs.
# - Don't add a space before the parentheses or a newline before the curly brace
# in function definitions.
# - Variables set and used by the testing framework are in caps with underscores.
# E.g., TEST_NAME and GROUPS. Variables local to the test are lowercase
# with underscores.
# - Functions defined by the testing framework or group scripts, including
# helpers, have a leading underscore. E.g., _have_scsi_debug. Functions local
# to the test should not have a leading underscore.
# - Both [[ ]] form and [ ] form are fine for tests. [[ ]] is preferred.
# - Always quote variable expansions unless the variable is a number or inside of
# a [[ ]] test.
# - Use the \$() form of command substitution instead of backticks.
# - Use bash for loops instead of seq. E.g., for ((i = 0; i < 10; i++)), not
# for i in \$(seq 0 9).
#
# Please run \`make check\` after your test is done to check for shell
# scripting errors and other mistakes.
EOF
chmod +x "tests/${test_name}"
echo "Created tests/${test_name}"
cat << EOF > "tests/${test_name}.out"
Running ${test_name}
Test complete
EOF
echo "Created tests/${test_name}.out"