* [RFC/PATCH] WIP: Report intra-test progress with TAP subtests
@ 2010-08-10 20:57 Ævar Arnfjörð Bjarmason
2010-08-11 0:44 ` Jonathan Nieder
2010-08-11 5:28 ` Jonathan Nieder
0 siblings, 2 replies; 7+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2010-08-10 20:57 UTC (permalink / raw)
To: git; +Cc: Ævar Arnfjörð Bjarmason
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
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [RFC/PATCH] WIP: Report intra-test progress with TAP subtests
2010-08-10 20:57 [RFC/PATCH] WIP: Report intra-test progress with TAP subtests Ævar Arnfjörð Bjarmason
@ 2010-08-11 0:44 ` Jonathan Nieder
2010-08-11 0:55 ` Ævar Arnfjörð Bjarmason
2010-08-11 5:28 ` Jonathan Nieder
1 sibling, 1 reply; 7+ messages in thread
From: Jonathan Nieder @ 2010-08-11 0:44 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason; +Cc: git
Hi Ævar,
Ævar Arnfjörð Bjarmason wrote:
> 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.
What if a test uses none of those commands?
The ultimate conclusion of such an approach would be to use
replacements for common commands like “git” and “cd”, making tests a
lot harder to read and write for the uninitiated.
If we get peeks where the infrastructure has a chance to provide
them, maybe it would be nice to allow explicitly inserting such
checkpoints, too? Like:
mv init init2 &&
checkpoint &&
git config -f .gitmodules submodule.example.url "$(pwd)/init2" &&
checkpoint &&
git config --remove-section submodule.example &&
checkpoint &&
[...]
while debugging.
However, I would rather see those inserted automatically.
Two ideas without code to back them up:
1. Script parsing.
Yes, parsing shell command language is hard, but tests use only
a subset of it. In particular the &&-chaining means it might
be relatively easy to find where each command starts and ends.
The hard bits: “if”, “while”, and “for” flow control constructs.
The payoff of even partial progress in this would be very high,
since it should make static analysis of &&-chaining possible.
2. Letting the shell trace for us.
When tests fail, I generally use
sh -x ./failing-test.sh -v -i
and scroll back through the log to the important part.
Maybe the test harness could automate that a little, by using
set -x at the beginning and set +x at the end of each test.
Hope that helps,
Jonathan
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC/PATCH] WIP: Report intra-test progress with TAP subtests
2010-08-11 0:44 ` Jonathan Nieder
@ 2010-08-11 0:55 ` Ævar Arnfjörð Bjarmason
2010-08-11 1:04 ` Jonathan Nieder
0 siblings, 1 reply; 7+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2010-08-11 0:55 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: git
On Wed, Aug 11, 2010 at 00:44, Jonathan Nieder <jrnieder@gmail.com> wrote:
> Hi Ævar,
>
> Ævar Arnfjörð Bjarmason wrote:
>
>> 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.
>
> What if a test uses none of those commands?
Then it won't get any progress output.
> The ultimate conclusion of such an approach would be to use
> replacements for common commands like “git” and “cd”, making tests a
> lot harder to read and write for the uninitiated.
Yes, but there's a middle ground here. We use a lot of utility
functions in the tests, adding tracing to these makes it easier to see
what's going on, especially in large tests.
> If we get peeks where the infrastructure has a chance to provide
> them, maybe it would be nice to allow explicitly inserting such
> checkpoints, too? Like:
>
> mv init init2 &&
> checkpoint &&
> git config -f .gitmodules submodule.example.url "$(pwd)/init2" &&
> checkpoint &&
> git config --remove-section submodule.example &&
> checkpoint &&
> [...]
>
> while debugging.
Yeah. I was going to add something like that if I got this working.
> However, I would rather see those inserted automatically.
> Two ideas without code to back them up:
>
> 1. Script parsing.
>
> Yes, parsing shell command language is hard, but tests use only
> a subset of it. In particular the &&-chaining means it might
> be relatively easy to find where each command starts and ends.
>
> The hard bits: “if”, “while”, and “for” flow control constructs.
>
> The payoff of even partial progress in this would be very high,
> since it should make static analysis of &&-chaining possible.
Sounds like a good long term project, and shouldn't be so hard for the
simple case.
> 2. Letting the shell trace for us.
>
> When tests fail, I generally use
>
> sh -x ./failing-test.sh -v -i
>
> and scroll back through the log to the important part.
>
> Maybe the test harness could automate that a little, by using
> set -x at the beginning and set +x at the end of each test.
The main use case for this for me is the smoke tester output, where
you won't get access to the original machine (without asking). Having
a few intra-test checkpoints helps you to see where things might have
gone wrong.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC/PATCH] WIP: Report intra-test progress with TAP subtests
2010-08-11 0:55 ` Ævar Arnfjörð Bjarmason
@ 2010-08-11 1:04 ` Jonathan Nieder
2010-08-11 6:44 ` Johannes Sixt
0 siblings, 1 reply; 7+ messages in thread
From: Jonathan Nieder @ 2010-08-11 1:04 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason; +Cc: git
Ævar Arnfjörð Bjarmason wrote:
> On Wed, Aug 11, 2010 at 00:44, Jonathan Nieder <jrnieder@gmail.com> wrote:
>> Maybe the test harness could automate that a little, by using
>> set -x at the beginning and set +x at the end of each test.
>
> The main use case for this for me is the smoke tester output, where
> you won't get access to the original machine (without asking). Having
> a few intra-test checkpoints helps you to see where things might have
> gone wrong.
I meant something like this:
-- 8< --
diff --git a/t/test-lib.sh b/t/test-lib.sh
index e5523dd..a4bc358 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -368,9 +368,11 @@ test_debug () {
test_run_ () {
test_cleanup=:
+ set -x
eval >&3 2>&4 "$1"
eval_ret=$?
eval >&3 2>&4 "$test_cleanup"
+ set +x
if test "$verbose" = "t" && test -n "$HARNESS_ACTIVE"; then
echo ""
fi
-- >8 --
but made optional and with output munged into parsable format by
changing PS4 (or "set -T" with a DEBUG trap, if that’s portable
enough).
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [RFC/PATCH] WIP: Report intra-test progress with TAP subtests
2010-08-10 20:57 [RFC/PATCH] WIP: Report intra-test progress with TAP subtests Ævar Arnfjörð Bjarmason
2010-08-11 0:44 ` Jonathan Nieder
@ 2010-08-11 5:28 ` Jonathan Nieder
2010-08-11 16:41 ` Ævar Arnfjörð Bjarmason
1 sibling, 1 reply; 7+ messages in thread
From: Jonathan Nieder @ 2010-08-11 5:28 UTC (permalink / raw)
To: Ævar Arnfjörð Bjarmason; +Cc: git
Ævar Arnfjörð Bjarmason wrote:
> 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.
I forgot to say: thanks for the demonstration. This is neat stuff.
> 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
Descriptor 5 is a pass-through for stdout: see v0.99.5~24^2~4
(Trapping exit in tests, 2005-08-10).
Do you need a pass-through for stderr, too, or was that theoretical?
> @@ -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
This would make the test continue after the subtest, right? Is that
intended?
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC/PATCH] WIP: Report intra-test progress with TAP subtests
2010-08-11 1:04 ` Jonathan Nieder
@ 2010-08-11 6:44 ` Johannes Sixt
0 siblings, 0 replies; 7+ messages in thread
From: Johannes Sixt @ 2010-08-11 6:44 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Ævar Arnfjörð Bjarmason, git
Am 8/11/2010 3:04, schrieb Jonathan Nieder:
> I meant something like this:
> -- 8< --
> diff --git a/t/test-lib.sh b/t/test-lib.sh
> index e5523dd..a4bc358 100644
> --- a/t/test-lib.sh
> +++ b/t/test-lib.sh
> @@ -368,9 +368,11 @@ test_debug () {
>
> test_run_ () {
> test_cleanup=:
> + set -x
> eval >&3 2>&4 "$1"
> eval_ret=$?
> eval >&3 2>&4 "$test_cleanup"
> + set +x
> if test "$verbose" = "t" && test -n "$HARNESS_ACTIVE"; then
> echo ""
> fi
> -- >8 --
Heh. I use something like this in my private build. It breaks a number of
tests due to additional output from test_must_fail invocations. I work
around it by adding 'set +x' inside the test case code. See
http://repo.or.cz/w/git/mingw/j6t.git/commitdiff/3943fd12f69da58937ac67a20be440f0ed532f18
-- Hannes
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC/PATCH] WIP: Report intra-test progress with TAP subtests
2010-08-11 5:28 ` Jonathan Nieder
@ 2010-08-11 16:41 ` Ævar Arnfjörð Bjarmason
0 siblings, 0 replies; 7+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2010-08-11 16:41 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: git
On Wed, Aug 11, 2010 at 05:28, Jonathan Nieder <jrnieder@gmail.com> wrote:
> Ævar Arnfjörð Bjarmason wrote:
>
>> 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.
>
> I forgot to say: thanks for the demonstration. This is neat stuff.
>
>> 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
>
> Descriptor 5 is a pass-through for stdout: see v0.99.5~24^2~4
> (Trapping exit in tests, 2005-08-10).
>
> Do you need a pass-through for stderr, too, or was that theoretical?
Nope, thanks. Using >&5 works.
>> @@ -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
>
> This would make the test continue after the subtest, right? Is that
> intended?
No, should be return 0/1. Changed that in my working branch.
I'm going to drop this for a while until my pending patches to test
stuff get into pu. But initial experiments with using >&5 everywhere
for test progress are promising:
http://github.com/avar/git/tree/test-intra-progress-using-tap-subtests-v2
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2010-08-11 16:42 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-08-10 20:57 [RFC/PATCH] WIP: Report intra-test progress with TAP subtests Ævar Arnfjörð Bjarmason
2010-08-11 0:44 ` 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
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).