Skip to content

Commit 21ec2d2

Browse files
committed
t0213: add trace2 cmd_ancestry tests
Add a new test script t0213-trace2-ancestry.sh that verifies cmd_ancestry events across all three trace2 output formats (normal, perf, and event). The tests use the "400ancestry" test helper to spawn child processes with controlled trace2 environments. Git alias resolution (which spawns a child git process) creates a predictable multi-level process tree. Filter functions extract cmd_ancestry events from each format, truncating the ancestor list at the outermost "test-tool" so that only the controlled portion of the tree is verified, regardless of the test runner environment. A runtime prerequisite (TRACE2_ANCESTRY) is used to detect whether the platform has a real procinfo implementation; platforms with only the stub are skipped. We must special case the expected ancestry on Windows as we have different ancestry from the `run_command` invocations in test-tool (sh.exe is present after test-tool.exe), plus the presence of the .exe file extension in the process names. Also update the comment in t0210-trace2-normal.sh to reflect that ancestry testing now has its own dedicated test script. Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
1 parent b9a9429 commit 21ec2d2

3 files changed

Lines changed: 212 additions & 2 deletions

File tree

t/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ integration_tests = [
131131
't0210-trace2-normal.sh',
132132
't0211-trace2-perf.sh',
133133
't0212-trace2-event.sh',
134+
't0213-trace2-ancestry.sh',
134135
't0300-credentials.sh',
135136
't0301-credential-cache.sh',
136137
't0302-credential-store.sh',

t/t0210-trace2-normal.sh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,9 @@ scrub_normal () {
7474
# This line is only emitted when RUNTIME_PREFIX is defined,
7575
# so just omit it for testing purposes.
7676
#
77-
# 4. 'cmd_ancestry' is not implemented everywhere, so for portability's
78-
# sake, skip it when parsing normal.
77+
# 4. 'cmd_ancestry' output depends on how the test is run and
78+
# is not relevant to the features we are testing here.
79+
# Ancestry tests are covered in t0213-trace2-ancestry.sh instead.
7980
sed \
8081
-e 's/elapsed:[0-9]*\.[0-9][0-9]*\([eE][-+]\{0,1\}[0-9][0-9]*\)\{0,1\}/elapsed:_TIME_/g' \
8182
-e "s/^start '[^']*' \(.*\)/start _EXE_ \1/" \

t/t0213-trace2-ancestry.sh

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
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.exe
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+
# Note: On Windows (under MINGW) we also see "sh.exe" in the ancestry, which is
96+
# expected. We must therefore special case MINGW in the expected ancestry output
97+
# for the tests below.
98+
99+
# Git alias resolution spawns the target command as a child process.
100+
# Using "git -c alias.xyz=version xyz" creates a two-level chain:
101+
#
102+
# test-tool (400ancestry)
103+
# -> git (resolves alias xyz -> version)
104+
# -> git (version)
105+
#
106+
# Both git processes are instrumented and emit cmd_ancestry. After
107+
# filtering out ancestors above test-tool, we get:
108+
#
109+
# test-tool (from git alias resolver)
110+
# git test-tool (from git version)
111+
112+
test_expect_success TRACE2_ANCESTRY 'normal: git alias chain, 2 levels' '
113+
test_when_finished "rm -f trace.normal actual expect" &&
114+
test-tool trace2 400ancestry normal "$(pwd)/trace.normal" \
115+
git -c alias.xyz=version xyz &&
116+
filter_ancestry_normal <trace.normal >actual &&
117+
if test_have_prereq MINGW
118+
then
119+
cat >expect <<-\EOF
120+
sh.exe test-tool.exe
121+
git.exe sh.exe test-tool.exe
122+
EOF
123+
else
124+
cat >expect <<-\EOF
125+
test-tool
126+
git test-tool
127+
EOF
128+
fi &&
129+
test_cmp expect actual
130+
'
131+
132+
test_expect_success TRACE2_ANCESTRY 'perf: git alias chain, 2 levels' '
133+
test_when_finished "rm -f trace.perf actual expect" &&
134+
test-tool trace2 400ancestry perf "$(pwd)/trace.perf" \
135+
git -c alias.xyz=version xyz &&
136+
filter_ancestry_perf <trace.perf >actual &&
137+
if test_have_prereq MINGW
138+
then
139+
cat >expect <<-\EOF
140+
sh.exe test-tool.exe
141+
git.exe sh.exe test-tool.exe
142+
EOF
143+
else
144+
cat >expect <<-\EOF
145+
test-tool
146+
git test-tool
147+
EOF
148+
fi &&
149+
test_cmp expect actual
150+
'
151+
152+
test_expect_success TRACE2_ANCESTRY 'event: git alias chain, 2 levels' '
153+
test_when_finished "rm -f trace.event actual expect" &&
154+
test-tool trace2 400ancestry event "$(pwd)/trace.event" \
155+
git -c alias.xyz=version xyz &&
156+
filter_ancestry_event <trace.event >actual &&
157+
if test_have_prereq MINGW
158+
then
159+
cat >expect <<-\EOF
160+
sh.exe test-tool.exe
161+
git.exe sh.exe test-tool.exe
162+
EOF
163+
else
164+
cat >expect <<-\EOF
165+
test-tool
166+
git test-tool
167+
EOF
168+
fi &&
169+
test_cmp expect actual
170+
'
171+
172+
# Use 004child to add a test-tool layer, creating a three-level chain:
173+
#
174+
# test-tool (400ancestry)
175+
# -> test-tool (004child)
176+
# -> git (resolves alias xyz -> version)
177+
# -> git (version)
178+
#
179+
# Three instrumented processes emit cmd_ancestry. After filtering:
180+
#
181+
# test-tool (from test-tool 004child)
182+
# test-tool test-tool (from git alias resolver)
183+
# git test-tool test-tool (from git version)
184+
185+
test_expect_success TRACE2_ANCESTRY 'normal: deeper chain, 3 levels' '
186+
test_when_finished "rm -f trace.normal actual expect" &&
187+
test-tool trace2 400ancestry normal "$(pwd)/trace.normal" \
188+
test-tool trace2 004child \
189+
git -c alias.xyz=version xyz &&
190+
filter_ancestry_normal <trace.normal >actual &&
191+
if test_have_prereq MINGW
192+
then
193+
cat >expect <<-\EOF
194+
test-tool.exe
195+
sh.exe test-tool.exe test-tool.exe
196+
git.exe sh.exe test-tool.exe test-tool.exe
197+
EOF
198+
else
199+
cat >expect <<-\EOF
200+
test-tool
201+
test-tool test-tool
202+
git test-tool test-tool
203+
EOF
204+
fi &&
205+
test_cmp expect actual
206+
'
207+
208+
test_done

0 commit comments

Comments
 (0)