Automate Git Bisect with Event Simulation¶
This page demonstrates how to find when bugs were introduced that can only be reproduced with interactive user actions.
Git Bisect Run¶
Git includes the ability to automate bisecting using a script, the typical workflow is as follows:
(replace: a09c728
, b6a0692
and git_bisect.sh
with the values
that apply to the issue you're investigating).
Once git bisect run
is finished it will report the exact revision
that introduced an error.
For more details on this see Fully automated bisecting with "git bisect run".
Simulating Events in Blender¶
Using a script often limits the kinds actions that can be automatically tested to things that can be performed in background mode (without a graphical window).
As Blender is a graphical application, there are times it can be useful to automate interface interactions such as activating menu items, pressing keys, interactive tools that require mouse motion... etc
Since Blender 2.81 it's possible to simulate events, and more recently a utility has been added to simplify the process of creating reproducible actions that can be automated without any user input.
Working Example¶
This is a practical example of how git bisect run
was used with
event simulation to find the cause of an error.
This can be used as a template, the actions argument will need to be changed for your specific use case.
The contents of git_bisect.sh
:
#!/bin/bash
BUILD_DIR="../build_linux_debug"
BLENDER_BIN="$BUILD_DIR/bin/blender"
# An exit code of 125 asks "git bisect" to "skip" the current commit.
# (useful if the build is broken for a short period of time).
cmake --build "$BUILD_DIR" --target install || exit 125
# Prevent non-critical ASAN issues from causing a non-zero exit code.
export ASAN_OPTIONS="detect_leaks=0:check_initialization_order=0"
"$BLENDER_BIN" \
--factory-startup \
--no-window-focus \
--enable-event-simulate \
--python tests/python/bl_run_operators_event_simulate.py \
-- \
--actions \
'event(type="Z", value="TAP", shift=True)' \
'operator("object.modifier_add", type="TRIANGULATE")' \
'event(type="TAB", value="TAP")' \
'event(type="Z", value="TAP", shift=True)' \
'event(type="MOUSEMOVE", value="NOTHING")'
# Always use exit code 1 when non-zero,
# since exit codes over 127 from ASAN cause bisect to abort with an error.
STATUS=$?
echo "exit code: $STATUS"
if [ $STATUS -ne 0 ]; then
exit 1
fi
These commands track down the commit that caused the error:
git bisect start
git bisect good 3ec57ce6c7fcd3aa59c9b60139321c11f73fb7f7
git bisect bad 1a912462f4e51d069bda5084f3d702006e0a5b7e
git bisect run bash git_bisect.sh
Hints¶
-
For a full list of options and other examples run:
-
The example on this page relies on crashing for bisect to fail. If the issue you're investigating doesn't result in a crash, you will need another way to exit with a non-zero exit-code.
This can be done using thescript.python_file_run
operator which will execute any Python script. This script needs to check for the error case and runsys.exit(1)
for the failure state.
The last action given should look like this:
- You may need to add
event(type="MOUSEMOVE", value="NOTHING")
as the last action, so the final state of the file is refreshed before exiting.
- You may need to copy
tests/python/bl_run_operators_event_simulate.py
to a temporary location as bisecting to past revisions may remove functionality or the script it's self.
- Menu search can be a quick way to to run an action:
menu("Add Curve Bezier")
Is the equivalent of pressingF3
, typing in "Add Curve Bezier", then pressingEnter
.
- The
--keep-open
argument can be used to inspect the state of the file once event-simulation has finished, this is helpful when constructing actions and the state of the file is not what you expect.
If you only want to keep blender open for a short period of time to see the result, adding dummy events is an alternative, e.g.event(type="MOUSEMOVE", value="NOTHING", repeat=10_000)
- The
git_bisect.sh
script can be executed directly from the command-line, comment out the line that builds to quickly test the script.
-
To automatically run the script on file-save
inotifywait
(frominotify-tools
) can be used.This allows for fast iterations when setting up command line arguments.