From: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
To: git@vger.kernel.org
Cc: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
Subject: [RFC/PATCH] WIP: Report intra-test progress with TAP subtests
Date: Tue, 10 Aug 2010 20:57:09 +0000 [thread overview]
Message-ID: <1281473829-2102-1-git-send-email-avarab@gmail.com> (raw)
It can be a PITA to debug Git's tests. They're a maze of chained &&'s,
and if one bit fails it can be hard to find out what that bit is.
As I mentioned in the comments for the "user friendly alterantives to
-d -f.." series we could do this with TAP subtests:
$ perl -MTest::More=no_plan -E '
subtest "A git test" => sub {
pass("doing test -f file");
pass("git commit ...");
pass("test_tick...");
done_testing();
} for 1 .. 2
'
ok 1 - doing test -f file
ok 2 - git commit ...
ok 3 - test_tick...
1..3
ok 1 - A git test
ok 1 - doing test -f file
ok 2 - git commit ...
ok 3 - test_tick...
1..3
ok 2 - A git test
1..2
Here's an attempt at that, I've convented test_commit, test_merge and
test_cmp to report intra-test progress. The only problem is that it
doesn't quite work.
It works lik this:
$ ./t0100-previous.sh --verbose 2>&1 | ack '(?:^\s*ok|^\s*not ok|\d\.\.\d)'
ok 1 - test_commit file:<A.t> message:<A> contents<A>
1..1
ok 1 - branch -d @{-1}
ok 2 - branch -d @{-12} when there is not enough switches yet
ok 3 - test_commit file:<B.t> message:<B> contents<B>
ok 3 - test_commit file:<C.t> message:<C> contents<C>
1..2
ok 3 - merge @{-1}
ok 4 - merge @{-1} when there is not enough switches yet
1..4
But the problem is that the subtest code is evaluated in the context of the test itself:
eval >&3 2>&4 "$1"
So when you run it you'll just get:
$ ./t0100-previous.sh
1..1
ok 1 - branch -d @{-1}
ok 2 - branch -d @{-12} when there is not enough switches yet
1..2
ok 3 - merge @{-1}
ok 4 - merge @{-1} when there is not enough switches yet
# passed all 4 test(s)
1..4
Is there some filedescriptor saving/redirection magic I can do within
the subtest code to print things to the *real* stdout and stderr, not
the new file descriptors Git has aliased stdout/stderr to in the eval?
Another way to to it would be to buffer up the subtest output in a
shell variable and spew it out all at once when the whole test
finishes, but then it would be out of context with the --verbose
output, and it'd be ugly.
---
t/test-lib.sh | 66 +++++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 57 insertions(+), 9 deletions(-)
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 4e73fff..2380cb9 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -208,6 +208,11 @@ test_success=0
test_external_has_tap=0
+# subtest state
+in_subtest=
+subtest_count=0
+tap_prefix=
+
die () {
code=$?
if test -n "$GIT_EXIT_OK"
@@ -290,20 +295,38 @@ test_tick () {
test_commit () {
file=${2:-"$1.t"}
- echo "${3-$1}" > "$file" &&
- git add "$file" &&
- test_tick &&
- git commit -m "$1" &&
- git tag "$1"
+ subtest_count=$(($subtest_count + 1))
+
+ if echo "${3-$1}" > "$file" &&
+ git add "$file" &&
+ test_tick &&
+ git commit -m "$1" &&
+ git tag "$1"
+ then
+ test_ok_ "test_commit file:<$file> message:<$1> contents<${3-$1}>"
+ true
+ else
+ test_failure_ "test_commit file:<$file> message:<$1> contents<${3-$1}>"
+ true
+ fi
}
# Call test_merge with the arguments "<message> <commit>", where <commit>
# can be a tag pointing to the commit-to-merge.
test_merge () {
- test_tick &&
- git merge -m "$1" "$2" &&
- git tag "$1"
+
+ subtest_count=$(($subtest_count + 1))
+ if test_tick &&
+ git merge -m "$1" "$2" &&
+ git tag "$1"
+ then
+ test_ok_ "test_merge: file<$2> message<$1> tag:<$1>"
+ true
+ else
+ test_failure_ "test_merge: file<$2> message<$1> tag:<$1>"
+ false
+ fi
}
# This function helps systems where core.filemode=false is set.
@@ -353,7 +376,7 @@ test_have_prereq () {
test_ok_ () {
test_success=$(($test_success + 1))
- say_color "" "ok $test_count - $@"
+ say_color "" "${tap_prefix}ok $test_count - $@"
}
test_failure_ () {
@@ -380,9 +403,25 @@ test_debug () {
test_run_ () {
test_cleanup=:
+
+ # Run the test in a subtest scope
+ in_subtest=1
+ subtest_count=0
+ tap_prefix=' '
eval >&3 2>&4 "$1"
+ in_subtest=
+
eval_ret=$?
eval >&3 2>&4 "$test_cleanup"
+
+ # Report the subtest plan
+ if test $subtest_count -gt 0
+ then
+ say "${tap_prefix}1..$subtest_count"
+ subtest_count=0
+ fi
+ tap_prefix=
+
if test "$verbose" = "t" && test -n "$HARNESS_ACTIVE"; then
echo ""
fi
@@ -602,6 +641,15 @@ test_might_fail () {
test_cmp() {
$GIT_TEST_CMP "$@"
+ subtest_count=$(($subtest_count + 1))
+ if test "$?" = 0
+ then
+ test_ok_ "test_cmp '$@'"
+ true
+ else
+ test_failure_ "test_cmp '$@'"
+ false
+ fi
}
# This function can be used to schedule some commands to be run
--
1.7.2.1.295.gd03d
next reply other threads:[~2010-08-10 20:57 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-08-10 20:57 Ævar Arnfjörð Bjarmason [this message]
2010-08-11 0:44 ` [RFC/PATCH] WIP: Report intra-test progress with TAP subtests Jonathan Nieder
2010-08-11 0:55 ` Ævar Arnfjörð Bjarmason
2010-08-11 1:04 ` Jonathan Nieder
2010-08-11 6:44 ` Johannes Sixt
2010-08-11 5:28 ` Jonathan Nieder
2010-08-11 16:41 ` Ævar Arnfjörð Bjarmason
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1281473829-2102-1-git-send-email-avarab@gmail.com \
--to=avarab@gmail.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).