Skip to content

Commit 3fe47ff

Browse files
committed
Merge branch 'sg/stress-test'
Flaky tests can now be repeatedly run under load with the "--stress" option. * sg/stress-test: test-lib: add the '--stress' option to run a test repeatedly under load test-lib-functions: introduce the 'test_set_port' helper function test-lib: set $TRASH_DIRECTORY earlier test-lib: consolidate naming of test-results paths test-lib: parse command line options earlier test-lib: parse options in a for loop to keep $@ intact test-lib: extract Bash version check for '-x' tracing test-lib: translate SIGTERM and SIGHUP to an exit
2 parents 2c0a645 + fb7d1e3 commit 3fe47ff

File tree

9 files changed

+308
-133
lines changed

9 files changed

+308
-133
lines changed

t/README

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,22 @@ appropriately before running "make".
186186
this feature by setting the GIT_TEST_CHAIN_LINT environment
187187
variable to "1" or "0", respectively.
188188

189+
--stress::
190+
--stress=<N>::
191+
Run the test script repeatedly in multiple parallel jobs until
192+
one of them fails. Useful for reproducing rare failures in
193+
flaky tests. The number of parallel jobs is, in order of
194+
precedence: <N>, or the value of the GIT_TEST_STRESS_LOAD
195+
environment variable, or twice the number of available
196+
processors (as shown by the 'getconf' utility), or 8.
197+
Implies `--verbose -x --immediate` to get the most information
198+
about the failure. Note that the verbose output of each test
199+
job is saved to 't/test-results/$TEST_NAME.stress-<nr>.out',
200+
and only the output of the failed test job is shown on the
201+
terminal. The names of the trash directories get a
202+
'.stress-<nr>' suffix, and the trash directory of the failed
203+
test job is renamed to end with a '.stress-failed' suffix.
204+
189205
You can also set the GIT_TEST_INSTALLED environment variable to
190206
the bindir of an existing git installation to test that installation.
191207
You still need to have built this git sandbox, from which various
@@ -425,7 +441,8 @@ This test harness library does the following things:
425441
- Creates an empty test directory with an empty .git/objects database
426442
and chdir(2) into it. This directory is 't/trash
427443
directory.$test_name_without_dotsh', with t/ subject to change by
428-
the --root option documented above.
444+
the --root option documented above, and a '.stress-<N>' suffix
445+
appended by the --stress option.
429446

430447
- Defines standard test helper functions for your scripts to
431448
use. These functions are designed to make all scripts behave

t/lib-git-daemon.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ then
2828
test_skip_or_die $GIT_TEST_GIT_DAEMON "file system does not support FIFOs"
2929
fi
3030

31-
LIB_GIT_DAEMON_PORT=${LIB_GIT_DAEMON_PORT-${this_test#t}}
31+
test_set_port LIB_GIT_DAEMON_PORT
3232

3333
GIT_DAEMON_PID=
3434
GIT_DAEMON_DOCUMENT_ROOT_PATH="$PWD"/repo

t/lib-git-p4.sh

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,7 @@ time_in_seconds () {
5353
(cd / && "$PYTHON_PATH" -c 'import time; print(int(time.time()))')
5454
}
5555

56-
# Try to pick a unique port: guess a large number, then hope
57-
# no more than one of each test is running.
58-
#
59-
# This does not handle the case where somebody else is running the
60-
# same tests and has chosen the same ports.
61-
testid=${this_test#t}
62-
git_p4_test_start=9800
63-
P4DPORT=$((10669 + ($testid - $git_p4_test_start)))
56+
test_set_port P4DPORT
6457

6558
P4PORT=localhost:$P4DPORT
6659
P4CLIENT=client

t/lib-git-svn.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ fi
1313
GIT_DIR=$PWD/.git
1414
GIT_SVN_DIR=$GIT_DIR/svn/refs/remotes/git-svn
1515
SVN_TREE=$GIT_SVN_DIR/svn-tree
16+
test_set_port SVNSERVE_PORT
1617

1718
svn >/dev/null 2>&1
1819
if test $? -ne 1
@@ -119,7 +120,6 @@ require_svnserve () {
119120
}
120121

121122
start_svnserve () {
122-
SVNSERVE_PORT=${SVNSERVE_PORT-${this_test#t}}
123123
svnserve --listen-port $SVNSERVE_PORT \
124124
--root "$rawsvnrepo" \
125125
--listen-once \

t/lib-httpd.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ case $(uname) in
8282
esac
8383

8484
LIB_HTTPD_PATH=${LIB_HTTPD_PATH-"$DEFAULT_HTTPD_PATH"}
85-
LIB_HTTPD_PORT=${LIB_HTTPD_PORT-${this_test#t}}
85+
test_set_port LIB_HTTPD_PORT
8686

8787
TEST_PATH="$TEST_DIRECTORY"/lib-httpd
8888
HTTPD_ROOT_PATH="$PWD"/httpd

t/t0410-partial-clone.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,6 @@ test_expect_success 'gc stops traversal when a missing but promised object is re
492492
! grep "$TREE_HASH" out
493493
'
494494

495-
LIB_HTTPD_PORT=12345 # default port, 410, cannot be used as non-root
496495
. "$TEST_DIRECTORY"/lib-httpd.sh
497496
start_httpd
498497

t/t5512-ls-remote.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ test_lazy_prereq GIT_DAEMON '
260260
# This test spawns a daemon, so run it only if the user would be OK with
261261
# testing with git-daemon.
262262
test_expect_success PIPE,JGIT,GIT_DAEMON 'indicate no refs in standards-compliant empty remote' '
263-
JGIT_DAEMON_PORT=${JGIT_DAEMON_PORT-${this_test#t}} &&
263+
test_set_port JGIT_DAEMON_PORT &&
264264
JGIT_DAEMON_PID= &&
265265
git init --bare empty.git &&
266266
>empty.git/git-daemon-export-ok &&

t/test-lib-functions.sh

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,3 +1263,42 @@ test_oid () {
12631263
fi &&
12641264
eval "printf '%s' \"\${$var}\""
12651265
}
1266+
1267+
# Choose a port number based on the test script's number and store it in
1268+
# the given variable name, unless that variable already contains a number.
1269+
test_set_port () {
1270+
local var=$1 port
1271+
1272+
if test $# -ne 1 || test -z "$var"
1273+
then
1274+
BUG "test_set_port requires a variable name"
1275+
fi
1276+
1277+
eval port=\$$var
1278+
case "$port" in
1279+
"")
1280+
# No port is set in the given env var, use the test
1281+
# number as port number instead.
1282+
# Remove not only the leading 't', but all leading zeros
1283+
# as well, so the arithmetic below won't (mis)interpret
1284+
# a test number like '0123' as an octal value.
1285+
port=${this_test#${this_test%%[1-9]*}}
1286+
if test "${port:-0}" -lt 1024
1287+
then
1288+
# root-only port, use a larger one instead.
1289+
port=$(($port + 10000))
1290+
fi
1291+
;;
1292+
*[^0-9]*|0*)
1293+
error >&7 "invalid port number: $port"
1294+
;;
1295+
*)
1296+
# The user has specified the port.
1297+
;;
1298+
esac
1299+
1300+
# Make sure that parallel '--stress' test jobs get different
1301+
# ports.
1302+
port=$(($port + ${GIT_TEST_STRESS_JOB_NR:-0}))
1303+
eval $var=$port
1304+
}

0 commit comments

Comments
 (0)