#!/bin/sh test_description='test trace2 cmd_ancestry event' . ./test-lib.sh # Turn off any inherited trace2 settings for this test. sane_unset GIT_TRACE2 GIT_TRACE2_PERF GIT_TRACE2_EVENT sane_unset GIT_TRACE2_BRIEF sane_unset GIT_TRACE2_CONFIG_PARAMS # Add t/helper directory to PATH so that we can use a relative # path to run nested instances of test-tool.exe (see 004child). # This helps with HEREDOC comparisons later. TTDIR="$GIT_BUILD_DIR/t/helper/" && export TTDIR PATH="$TTDIR:$PATH" && export PATH # The 400ancestry helper spawns a child process so that the child # sees "test-tool" in its process ancestry. We capture only the # child's trace2 output to a file. # # The tests use git commands that spawn child git processes (e.g., # alias resolution) to create a controlled multi-level process tree. # Because cmd_ancestry walks the real process tree, processes will # also report ancestors above "test-tool" that depend on the test # runner environment (e.g., bash, make, tmux). The filter functions # below truncate the ancestry at "test-tool", discarding anything # above it, so only the controlled portion is verified. # # On platforms without a real procinfo implementation (the stub), # no cmd_ancestry event is emitted. We detect this at runtime and # skip the format-specific tests accordingly. # Determine if cmd_ancestry is supported on this platform. test_expect_success 'detect cmd_ancestry support' ' test_when_finished "rm -f trace.detect" && GIT_TRACE2_BRIEF=1 GIT_TRACE2="$(pwd)/trace.detect" \ test-tool trace2 001return 0 && if grep -q "^cmd_ancestry" trace.detect then test_set_prereq TRACE2_ANCESTRY fi ' # Filter functions for each trace2 target format. # # Each extracts cmd_ancestry events, strips format-specific syntax, # and truncates the ancestor list at the outermost "test-tool" # (or "test-tool.exe" on Windows), discarding any higher-level # (uncontrolled) ancestors. # # Output is a space-separated list of ancestor names, one line per # cmd_ancestry event, with the immediate parent listed first: # # test-tool (or: test-tool.exe) # git test-tool (or: git.exe test-tool.exe) # git test-tool test-tool (or: git.exe test-tool.exe test-tool.exe) if test_have_prereq MINGW then TT=test-tool$X else TT=test-tool fi filter_ancestry_normal () { sed -n '/^cmd_ancestry/{ s/^cmd_ancestry // s/ <- / /g s/\(.*'"$TT"'\) .*/\1/ p }' } filter_ancestry_perf () { sed -n '/cmd_ancestry/{ s/.*ancestry:\[// s/\]// s/\(.*'"$TT"'\) .*/\1/ p }' } filter_ancestry_event () { sed -n '/"cmd_ancestry"/{ s/.*"ancestry":\[// s/\].*// s/"//g s/,/ /g s/\(.*'"$TT"'\) .*/\1/ p }' } # On Windows (MINGW) when running with the bin-wrappers, we also see "sh.exe" in # the ancestry. We must therefore account for this expected ancestry element in # the expected output of the tests. if test_have_prereq MINGW && test -z "$no_bin_wrappers"; then SH_TT="sh$X $TT" else SH_TT="$TT" fi # Git alias resolution spawns the target command as a child process. # Using "git -c alias.xyz=version xyz" creates a two-level chain: # # test-tool (400ancestry) # -> git (resolves alias xyz -> version) # -> git (version) # # Both git processes are instrumented and emit cmd_ancestry. After # filtering out ancestors above test-tool, we get: # # test-tool (from git alias resolver) # git test-tool (from git version) test_expect_success TRACE2_ANCESTRY 'normal: git alias chain, 2 levels' ' test_when_finished "rm -f trace.normal actual expect" && test-tool trace2 400ancestry normal "$(pwd)/trace.normal" \ git -c alias.xyz=version xyz && filter_ancestry_normal actual && cat >expect <<-EOF && $SH_TT git$X $SH_TT EOF test_cmp expect actual ' test_expect_success TRACE2_ANCESTRY 'perf: git alias chain, 2 levels' ' test_when_finished "rm -f trace.perf actual expect" && test-tool trace2 400ancestry perf "$(pwd)/trace.perf" \ git -c alias.xyz=version xyz && filter_ancestry_perf actual && cat >expect <<-EOF && $SH_TT git$X $SH_TT EOF test_cmp expect actual ' test_expect_success TRACE2_ANCESTRY 'event: git alias chain, 2 levels' ' test_when_finished "rm -f trace.event actual expect" && test-tool trace2 400ancestry event "$(pwd)/trace.event" \ git -c alias.xyz=version xyz && filter_ancestry_event actual && cat >expect <<-EOF && $SH_TT git$X $SH_TT EOF test_cmp expect actual ' # Use 004child to add a test-tool layer, creating a three-level chain: # # test-tool (400ancestry) # -> test-tool (004child) # -> git (resolves alias xyz -> version) # -> git (version) # # Three instrumented processes emit cmd_ancestry. After filtering: # # test-tool (from test-tool 004child) # test-tool test-tool (from git alias resolver) # git test-tool test-tool (from git version) test_expect_success TRACE2_ANCESTRY 'normal: deeper chain, 3 levels' ' test_when_finished "rm -f trace.normal actual expect" && test-tool trace2 400ancestry normal "$(pwd)/trace.normal" \ test-tool trace2 004child \ git -c alias.xyz=version xyz && filter_ancestry_normal actual && cat >expect <<-EOF && $TT $SH_TT $TT git$X $SH_TT $TT EOF test_cmp expect actual ' test_done