-
Notifications
You must be signed in to change notification settings - Fork 440
WIP: Add a --trace feature #137
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Part of #136. The final implementation will set the BATS_TRACE variable via a command-line flag, but setting `BATS_TRACE=1 bin/bats ...` will work. This did require explicitly filtering out the line from `bats_perform_test` that executes the test case; somehow the `"$BATS_SOURCE" != "$1"` condition doesn't filter it. If I (or anyone else) can think of a cleaner way to filter out this line than quoting it directly, I'm all for it. Two minor caveats: - If a command fails, it will be printed twice. Then, of course, it'll appear in the failure output, for a total of three times. - When using the pretty formatter, the first line of the trace from a test case will overlap with the line printing the name of the test case before execution begins.
This prevents `bats_capture_stack_trace` from executing on lines that realistically will never fail. (Or, more precisely, if they do, then Bats itself is seriously broken.) This consistently shaves off O(0.1s) from the test suite under both Bash 3.2.57(1)-release and 4.4.23(1)-release on my Macbook Pro (2.5GHz Core i7, 16GB RAM).
This replaces setting `BATS_TRACE` as an environment variable. And in the next commit...tests!
This final version will filter out any stack trace values and trace output where: - the `DEBUG` trap fires for the function definition itself, resulting in redundant --trace output lines (comparing `BASH_COMMAND` against `${FUNCNAME[1]}`) - the `DEBUG` trap fires before the `ERR` trap on error; apparently when both functions fire, `$?` refers to the value returned by the last command before either trap is fired (checking `$status` before emitting the trace output) The use of `case` patterns instead of multiple tests in an `if` condition is a bit more compact, and very slightly faster on average. Hence, I took the opportunity to apply a `case` statement in `bats_capture_stack_trace` as well.
OK, tests are added; this PR is ready for review. From the last commit message: This final version will filter out any stack trace values and trace output where:
The use of |
The previous implementation had two bugs: - Recursive function calls wouldn't appear in the trace output as they should've. - The `$?` check by itself meant that the first line of an `else` clause wouldn't get printed. For more discussion of this phenemonon: #110 (comment) The new test case reproduced both of these bugs, and the new implementation fixes them. However, there is a slight but measurable performance degradation with this update. I'm going to see if I can't tweak it some more before merging this PR.
I pushed a new commit to cover recursive function calls and However, test case 57, "trace a failing test case", now fails consistently on Bash 4.0.44(1)-release, 4.1.17(2)-release, and 4.2.53(2)-release. I'll have to investigate and fix a little later. Regarding the slight performance regression mentioned in the last commit message, I'm thinking of leaving it for now, as performance overall doesn't seem to suffer from the new feature. However, I do have ideas for making a more radical performance improvement—I think I see a way to get away with only capturing the stack trace on error—but I'll try it in another PR. |
FYI, I just filed #138 with some stack trace optimizations. It doesn't eliminate the need to capture the stack trace on every call, but eliminates some unnecessary calls and makes the code a little cleaner. I'll likely try to merge that PR first and update this one, and then attempt to fix the breakages. Still, @gtkramer, the semantics won't change, and I'd be interested in hearing some feedback once you try out this branch in the meanwhile. |
Note that this commit also extracts the `bats_emit_trace` function and makes use of variables introduced by #138.
Turns out with the `BASH_COMMAND` and `BATS_LINENO` comparisons, the value of `$?` is completely irrelevant. This feature still introduces a very slight decrease in performance for the existing test suite (before the three new test cases). This is somewhat unavoidable since we're introducing an extra conditional into `bats_debug_trap`, the most frequently executed function in the system. Bash 3.2.57(1)-release before: real 0m6.217s user 0m3.067s sys 0m1.927s real 0m6.051s user 0m3.070s sys 0m1.946s real 0m6.135s user 0m3.091s sys 0m1.997s Bash 3.2.57(1)-release after: real 0m6.131s user 0m3.124s sys 0m1.982s real 0m6.096s user 0m3.113s sys 0m1.975s Bash 4.4.23(1)-release before: real 0m6.490s user 0m3.106s sys 0m2.091s real 0m6.480s user 0m3.097s sys 0m2.087s real 0m6.513s user 0m3.099s sys 0m2.106s Bash 4.4.23(1)-release after: real 0m6.529s user 0m3.146s sys 0m2.096s real 0m6.522s user 0m3.136s sys 0m2.087s
The strangest thing is happening with these failures under Bash 4.0.44, 4.1.17, and 4.2.53. When I run the tests under those versions locally, adding
That last line number, This appears to be attributable to the fact that starting with Bash 4.3, the This is tricky to work around. I'll let it sit and think about it some more, or whether it's worth adjusting/skipping the test under Bash 4.0, 4.1, and 4.2. Ideas welcome. |
Some notes to myself about how to handle this:
|
|
Just wondering, if this PR stuck? I had 'fun' following the history of requests for a trace/verbosity/debug feature for |
Bump |
I am closing this in favor of #467 |
Closes #136. The final implementation will set the BATS_TRACE variable via a command-line flag, but setting
BATS_TRACE=1 bin/bats ...
will work.This did require explicitly filtering out the line from
bats_perform_test
that executes the test case; somehow the"$BATS_SOURCE" != "$1"
condition doesn't filter it. If I (or anyone else) can think of a cleaner way to filter out this line than quoting it directly, I'm all for it.Two minor caveats:
Also, I still need to add tests, of course.
cc: @gtkramer