Raw
1 #!/bin/sh
2
3 test_description='test trace2 cmd_ancestry event'
4
5 . ./test-lib.sh
6
7 # Turn off any inherited trace2 settings for this test.
8 sane_unset GIT_TRACE2 GIT_TRACE2_PERF GIT_TRACE2_EVENT
9 sane_unset GIT_TRACE2_BRIEF
10 sane_unset GIT_TRACE2_CONFIG_PARAMS
11
12 # Add t/helper directory to PATH so that we can use a relative
13 # path to run nested instances of test-tool.exe (see 004child).
14 # This helps with HEREDOC comparisons later.
15 TTDIR="$GIT_BUILD_DIR/t/helper/" && export TTDIR
16 PATH="$TTDIR:$PATH" && export PATH
17
18 # The 400ancestry helper spawns a child process so that the child
19 # sees "test-tool" in its process ancestry. We capture only the
20 # child's trace2 output to a file.
21 #
22 # The tests use git commands that spawn child git processes (e.g.,
23 # alias resolution) to create a controlled multi-level process tree.
24 # Because cmd_ancestry walks the real process tree, processes will
25 # also report ancestors above "test-tool" that depend on the test
26 # runner environment (e.g., bash, make, tmux). The filter functions
27 # below truncate the ancestry at "test-tool", discarding anything
28 # above it, so only the controlled portion is verified.
29 #
30 # On platforms without a real procinfo implementation (the stub),
31 # no cmd_ancestry event is emitted. We detect this at runtime and
32 # skip the format-specific tests accordingly.
33
34 # Determine if cmd_ancestry is supported on this platform.
35 test_expect_success 'detect cmd_ancestry support' '
36 test_when_finished "rm -f trace.detect" &&
37 GIT_TRACE2_BRIEF=1 GIT_TRACE2="$(pwd)/trace.detect" \
38 test-tool trace2 001return 0 &&
39 if grep -q "^cmd_ancestry" trace.detect
40 then
41 test_set_prereq TRACE2_ANCESTRY
42 fi
43 '
44
45 # Filter functions for each trace2 target format.
46 #
47 # Each extracts cmd_ancestry events, strips format-specific syntax,
48 # and truncates the ancestor list at the outermost "test-tool"
49 # (or "test-tool.exe" on Windows), discarding any higher-level
50 # (uncontrolled) ancestors.
51 #
52 # Output is a space-separated list of ancestor names, one line per
53 # cmd_ancestry event, with the immediate parent listed first:
54 #
55 # test-tool (or: test-tool.exe)
56 # git test-tool (or: git.exe test-tool.exe)
57 # git test-tool test-tool (or: git.exe test-tool.exe test-tool.exe)
58
59 if test_have_prereq MINGW
60 then
61 TT=test-tool$X
62 else
63 TT=test-tool
64 fi
65
66 filter_ancestry_normal () {
67 sed -n '/^cmd_ancestry/{
68 s/^cmd_ancestry //
69 s/ <- / /g
70 s/\(.*'"$TT"'\) .*/\1/
71 p
72 }'
73 }
74
75 filter_ancestry_perf () {
76 sed -n '/cmd_ancestry/{
77 s/.*ancestry:\[//
78 s/\]//
79 s/\(.*'"$TT"'\) .*/\1/
80 p
81 }'
82 }
83
84 filter_ancestry_event () {
85 sed -n '/"cmd_ancestry"/{
86 s/.*"ancestry":\[//
87 s/\].*//
88 s/"//g
89 s/,/ /g
90 s/\(.*'"$TT"'\) .*/\1/
91 p
92 }'
93 }
94
95 # On Windows (MINGW) when running with the bin-wrappers, we also see "sh.exe" in
96 # the ancestry. We must therefore account for this expected ancestry element in
97 # the expected output of the tests.
98 if test_have_prereq MINGW && test -z "$no_bin_wrappers"; then
99 SH_TT="sh$X $TT"
100 else
101 SH_TT="$TT"
102 fi
103
104 # Git alias resolution spawns the target command as a child process.
105 # Using "git -c alias.xyz=version xyz" creates a two-level chain:
106 #
107 # test-tool (400ancestry)
108 # -> git (resolves alias xyz -> version)
109 # -> git (version)
110 #
111 # Both git processes are instrumented and emit cmd_ancestry. After
112 # filtering out ancestors above test-tool, we get:
113 #
114 # test-tool (from git alias resolver)
115 # git test-tool (from git version)
116
117 test_expect_success TRACE2_ANCESTRY 'normal: git alias chain, 2 levels' '
118 test_when_finished "rm -f trace.normal actual expect" &&
119 test-tool trace2 400ancestry normal "$(pwd)/trace.normal" \
120 git -c alias.xyz=version xyz &&
121 filter_ancestry_normal <trace.normal >actual &&
122 cat >expect <<-EOF &&
123 $SH_TT
124 git$X $SH_TT
125 EOF
126 test_cmp expect actual
127 '
128
129 test_expect_success TRACE2_ANCESTRY 'perf: git alias chain, 2 levels' '
130 test_when_finished "rm -f trace.perf actual expect" &&
131 test-tool trace2 400ancestry perf "$(pwd)/trace.perf" \
132 git -c alias.xyz=version xyz &&
133 filter_ancestry_perf <trace.perf >actual &&
134 cat >expect <<-EOF &&
135 $SH_TT
136 git$X $SH_TT
137 EOF
138 test_cmp expect actual
139 '
140
141 test_expect_success TRACE2_ANCESTRY 'event: git alias chain, 2 levels' '
142 test_when_finished "rm -f trace.event actual expect" &&
143 test-tool trace2 400ancestry event "$(pwd)/trace.event" \
144 git -c alias.xyz=version xyz &&
145 filter_ancestry_event <trace.event >actual &&
146 cat >expect <<-EOF &&
147 $SH_TT
148 git$X $SH_TT
149 EOF
150 test_cmp expect actual
151 '
152
153 # Use 004child to add a test-tool layer, creating a three-level chain:
154 #
155 # test-tool (400ancestry)
156 # -> test-tool (004child)
157 # -> git (resolves alias xyz -> version)
158 # -> git (version)
159 #
160 # Three instrumented processes emit cmd_ancestry. After filtering:
161 #
162 # test-tool (from test-tool 004child)
163 # test-tool test-tool (from git alias resolver)
164 # git test-tool test-tool (from git version)
165
166 test_expect_success TRACE2_ANCESTRY 'normal: deeper chain, 3 levels' '
167 test_when_finished "rm -f trace.normal actual expect" &&
168 test-tool trace2 400ancestry normal "$(pwd)/trace.normal" \
169 test-tool trace2 004child \
170 git -c alias.xyz=version xyz &&
171 filter_ancestry_normal <trace.normal >actual &&
172 cat >expect <<-EOF &&
173 $TT
174 $SH_TT $TT
175 git$X $SH_TT $TT
176 EOF
177 test_cmp expect actual
178 '
179
180 test_done