Git fork
at reftables-rust 528 lines 19 kB view raw
1#!/bin/sh 2 3test_description='test trace2 facility (perf target)' 4 5. ./test-lib.sh 6 7if ! test_have_prereq PERL_TEST_HELPERS 8then 9 skip_all='skipping trace2 tests; Perl not available' 10 test_done 11fi 12 13# Turn off any inherited trace2 settings for this test. 14sane_unset GIT_TRACE2 GIT_TRACE2_PERF GIT_TRACE2_EVENT 15sane_unset GIT_TRACE2_PERF_BRIEF 16sane_unset GIT_TRACE2_CONFIG_PARAMS 17 18# Add t/helper directory to PATH so that we can use a relative 19# path to run nested instances of test-tool.exe (see 004child). 20# This helps with HEREDOC comparisons later. 21TTDIR="$GIT_BUILD_DIR/t/helper/" && export TTDIR 22PATH="$TTDIR:$PATH" && export PATH 23 24# Warning: use of 'test_cmp' may run test-tool.exe and/or git.exe 25# Warning: to do the actual diff/comparison, so the HEREDOCs here 26# Warning: only cover our actual calls to test-tool and/or git. 27# Warning: So you may see extra lines in artifact files when 28# Warning: interactively debugging. 29 30V=$(git version | sed -e 's/^git version //') && export V 31 32# There are multiple trace2 targets: normal, perf, and event. 33# Trace2 events will/can be written to each active target (subject 34# to whatever filtering that target decides to do). 35# Test each target independently. 36# 37# Defer setting GIT_TRACE2_PERF until the actual command we want to 38# test because hidden git and test-tool commands in the test 39# harness can contaminate our output. 40 41# Enable "brief" feature which turns off the prefix: 42# "<clock> <file>:<line> | <nr_parents> | " 43GIT_TRACE2_PERF_BRIEF=1 && export GIT_TRACE2_PERF_BRIEF 44 45# Repeat some of the t0210 tests using the perf target stream instead of 46# the normal stream. 47# 48# Tokens here of the form _FIELD_ have been replaced in the observed output. 49 50# Verb 001return 51# 52# Implicit return from cmd_<verb> function propagates <code>. 53 54test_expect_success 'perf stream, return code 0' ' 55 test_when_finished "rm trace.perf actual expect" && 56 GIT_TRACE2_PERF="$(pwd)/trace.perf" test-tool trace2 001return 0 && 57 perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual && 58 cat >expect <<-EOF && 59 d0|main|version|||||$V 60 d0|main|start||_T_ABS_|||_EXE_ trace2 001return 0 61 d0|main|cmd_name|||||trace2 (trace2) 62 d0|main|exit||_T_ABS_|||code:0 63 d0|main|atexit||_T_ABS_|||code:0 64 EOF 65 test_cmp expect actual 66' 67 68test_expect_success 'perf stream, return code 1' ' 69 test_when_finished "rm trace.perf actual expect" && 70 test_must_fail env GIT_TRACE2_PERF="$(pwd)/trace.perf" test-tool trace2 001return 1 && 71 perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual && 72 cat >expect <<-EOF && 73 d0|main|version|||||$V 74 d0|main|start||_T_ABS_|||_EXE_ trace2 001return 1 75 d0|main|cmd_name|||||trace2 (trace2) 76 d0|main|exit||_T_ABS_|||code:1 77 d0|main|atexit||_T_ABS_|||code:1 78 EOF 79 test_cmp expect actual 80' 81 82# Verb 003error 83# 84# To the above, add multiple 'error <msg>' events 85 86test_expect_success 'perf stream, error event' ' 87 test_when_finished "rm trace.perf actual expect" && 88 GIT_TRACE2_PERF="$(pwd)/trace.perf" test-tool trace2 003error "hello world" "this is a test" && 89 perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual && 90 cat >expect <<-EOF && 91 d0|main|version|||||$V 92 d0|main|start||_T_ABS_|||_EXE_ trace2 003error '\''hello world'\'' '\''this is a test'\'' 93 d0|main|cmd_name|||||trace2 (trace2) 94 d0|main|error|||||hello world 95 d0|main|error|||||this is a test 96 d0|main|exit||_T_ABS_|||code:0 97 d0|main|atexit||_T_ABS_|||code:0 98 EOF 99 test_cmp expect actual 100' 101 102# Verb 004child 103# 104# Test nested spawning of child processes. 105# 106# Conceptually, this looks like: 107# P1: TT trace2 004child 108# P2: |--- TT trace2 004child 109# P3: |--- TT trace2 001return 0 110# 111# Which should generate events: 112# P1: version 113# P1: start 114# P1: cmd_name 115# P1: child_start 116# P2: version 117# P2: start 118# P2: cmd_name 119# P2: child_start 120# P3: version 121# P3: start 122# P3: cmd_name 123# P3: exit 124# P3: atexit 125# P2: child_exit 126# P2: exit 127# P2: atexit 128# P1: child_exit 129# P1: exit 130# P1: atexit 131 132test_expect_success 'perf stream, child processes' ' 133 test_when_finished "rm trace.perf actual expect" && 134 GIT_TRACE2_PERF="$(pwd)/trace.perf" test-tool trace2 004child test-tool trace2 004child test-tool trace2 001return 0 && 135 perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual && 136 cat >expect <<-EOF && 137 d0|main|version|||||$V 138 d0|main|start||_T_ABS_|||_EXE_ trace2 004child test-tool trace2 004child test-tool trace2 001return 0 139 d0|main|cmd_name|||||trace2 (trace2) 140 d0|main|child_start||_T_ABS_|||[ch0] class:? argv:[test-tool trace2 004child test-tool trace2 001return 0] 141 d1|main|version|||||$V 142 d1|main|start||_T_ABS_|||_EXE_ trace2 004child test-tool trace2 001return 0 143 d1|main|cmd_name|||||trace2 (trace2/trace2) 144 d1|main|child_start||_T_ABS_|||[ch0] class:? argv:[test-tool trace2 001return 0] 145 d2|main|version|||||$V 146 d2|main|start||_T_ABS_|||_EXE_ trace2 001return 0 147 d2|main|cmd_name|||||trace2 (trace2/trace2/trace2) 148 d2|main|exit||_T_ABS_|||code:0 149 d2|main|atexit||_T_ABS_|||code:0 150 d1|main|child_exit||_T_ABS_|_T_REL_||[ch0] pid:_PID_ code:0 151 d1|main|exit||_T_ABS_|||code:0 152 d1|main|atexit||_T_ABS_|||code:0 153 d0|main|child_exit||_T_ABS_|_T_REL_||[ch0] pid:_PID_ code:0 154 d0|main|exit||_T_ABS_|||code:0 155 d0|main|atexit||_T_ABS_|||code:0 156 EOF 157 test_cmp expect actual 158' 159 160sane_unset GIT_TRACE2_PERF_BRIEF 161 162# Now test without environment variables and get all Trace2 settings 163# from the global config. 164 165test_expect_success 'using global config, perf stream, return code 0' ' 166 test_when_finished "rm trace.perf actual expect" && 167 test_config_global trace2.perfBrief 1 && 168 test_config_global trace2.perfTarget "$(pwd)/trace.perf" && 169 test-tool trace2 001return 0 && 170 perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual && 171 cat >expect <<-EOF && 172 d0|main|version|||||$V 173 d0|main|start||_T_ABS_|||_EXE_ trace2 001return 0 174 d0|main|cmd_name|||||trace2 (trace2) 175 d0|main|exit||_T_ABS_|||code:0 176 d0|main|atexit||_T_ABS_|||code:0 177 EOF 178 test_cmp expect actual 179' 180 181# Exercise the stopwatch timers in a loop and confirm that we have 182# as many start/stop intervals as expected. We cannot really test the 183# actual (total, min, max) timer values, so we have to assume that they 184# are good, but we can verify the interval count. 185# 186# The timer "test/test1" should only emit a global summary "timer" event. 187# The timer "test/test2" should emit per-thread "th_timer" events and a 188# global summary "timer" event. 189 190have_timer_event () { 191 thread=$1 event=$2 category=$3 name=$4 intervals=$5 file=$6 && 192 193 pattern="d0|${thread}|${event}||||${category}|name:${name} intervals:${intervals}" && 194 195 grep "${pattern}" ${file} 196} 197 198test_expect_success 'stopwatch timer test/test1' ' 199 test_when_finished "rm trace.perf actual" && 200 test_config_global trace2.perfBrief 1 && 201 test_config_global trace2.perfTarget "$(pwd)/trace.perf" && 202 203 # Use the timer "test1" 5 times from "main". 204 test-tool trace2 100timer 5 10 && 205 206 perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual && 207 208 have_timer_event "main" "timer" "test" "test1" 5 actual 209' 210 211test_expect_success PTHREADS 'stopwatch timer test/test2' ' 212 test_when_finished "rm trace.perf actual" && 213 test_config_global trace2.perfBrief 1 && 214 test_config_global trace2.perfTarget "$(pwd)/trace.perf" && 215 216 # Use the timer "test2" 5 times each in 3 threads. 217 test-tool trace2 101timer 5 10 3 && 218 219 perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual && 220 221 # So we should have 3 per-thread events of 5 each. 222 have_timer_event "th01:ut_101" "th_timer" "test" "test2" 5 actual && 223 have_timer_event "th02:ut_101" "th_timer" "test" "test2" 5 actual && 224 have_timer_event "th03:ut_101" "th_timer" "test" "test2" 5 actual && 225 226 # And we should have 15 total uses. 227 have_timer_event "main" "timer" "test" "test2" 15 actual 228' 229 230# Exercise the global counters and confirm that we get the expected values. 231# 232# The counter "test/test1" should only emit a global summary "counter" event. 233# The counter "test/test2" could emit per-thread "th_counter" events and a 234# global summary "counter" event. 235 236have_counter_event () { 237 thread=$1 event=$2 category=$3 name=$4 value=$5 file=$6 && 238 239 pattern="d0|${thread}|${event}||||${category}|name:${name} value:${value}" && 240 241 grep "${pattern}" ${file} 242} 243 244test_expect_success 'global counter test/test1' ' 245 test_when_finished "rm trace.perf actual" && 246 test_config_global trace2.perfBrief 1 && 247 test_config_global trace2.perfTarget "$(pwd)/trace.perf" && 248 249 # Use the counter "test1" and add n integers. 250 test-tool trace2 200counter 1 2 3 4 5 && 251 252 perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual && 253 254 have_counter_event "main" "counter" "test" "test1" 15 actual 255' 256 257test_expect_success PTHREADS 'global counter test/test2' ' 258 test_when_finished "rm trace.perf actual" && 259 test_config_global trace2.perfBrief 1 && 260 test_config_global trace2.perfTarget "$(pwd)/trace.perf" && 261 262 # Add 2 integers to the counter "test2" in each of 3 threads. 263 test-tool trace2 201counter 7 13 3 && 264 265 perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual && 266 267 # So we should have 3 per-thread events of 5 each. 268 have_counter_event "th01:ut_201" "th_counter" "test" "test2" 20 actual && 269 have_counter_event "th02:ut_201" "th_counter" "test" "test2" 20 actual && 270 have_counter_event "th03:ut_201" "th_counter" "test" "test2" 20 actual && 271 272 # And we should have a single event with the total across all threads. 273 have_counter_event "main" "counter" "test" "test2" 60 actual 274' 275 276test_expect_success 'unsafe URLs are redacted by default' ' 277 test_when_finished \ 278 "rm -r actual trace.perf unredacted.perf clone clone2" && 279 280 test_config_global \ 281 "url.$(pwd).insteadOf" https://user:pwd@example.com/ && 282 test_config_global trace2.configParams "core.*,remote.*.url" && 283 284 GIT_TRACE2_PERF="$(pwd)/trace.perf" \ 285 git clone https://user:pwd@example.com/ clone && 286 ! grep user:pwd trace.perf && 287 288 GIT_TRACE2_REDACT=0 GIT_TRACE2_PERF="$(pwd)/unredacted.perf" \ 289 git clone https://user:pwd@example.com/ clone2 && 290 perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <unredacted.perf >actual && 291 grep "d0|main|start|.* clone https://user:pwd@example.com" actual && 292 grep "d0|main|def_param|.*|remote.origin.url:https://user:pwd@example.com" actual 293' 294 295# Confirm that the requested command produces a "cmd_name" and a 296# set of "def_param" events. 297# 298try_simple () { 299 test_when_finished "rm prop.perf actual" && 300 301 cmd=$1 && 302 cmd_name=$2 && 303 304 test_config_global "trace2.configParams" "cfg.prop.*" && 305 test_config_global "trace2.envvars" "ENV_PROP_FOO,ENV_PROP_BAR" && 306 307 test_config_global "cfg.prop.foo" "red" && 308 309 ENV_PROP_FOO=blue \ 310 GIT_TRACE2_PERF="$(pwd)/prop.perf" \ 311 $cmd && 312 perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <prop.perf >actual && 313 grep "d0|main|cmd_name|.*|$cmd_name" actual && 314 grep "d0|main|def_param|.*|cfg.prop.foo:red" actual && 315 grep "d0|main|def_param|.*|ENV_PROP_FOO:blue" actual 316} 317 318# Representative mainstream builtin Git command dispatched 319# in run_builtin() in git.c 320# 321test_expect_success 'expect def_params for normal builtin command' ' 322 try_simple "git version" "version" 323' 324 325# Representative query command dispatched in handle_options() 326# in git.c 327# 328test_expect_success 'expect def_params for query command' ' 329 try_simple "git --man-path" "_query_" 330' 331 332# remote-curl.c does not use the builtin setup in git.c, so confirm 333# that executables built from remote-curl.c emit def_params. 334# 335# Also tests the dashed-command handling where "git foo" silently 336# spawns "git-foo". Make sure that both commands should emit 337# def_params. 338# 339# Pass bogus arguments to remote-https and allow the command to fail 340# because we don't actually have a remote to fetch from. We just want 341# to see the run-dashed code run an executable built from 342# remote-curl.c rather than git.c. Confirm that we get def_param 343# events from both layers. 344# 345test_expect_success LIBCURL \ 346 'expect def_params for remote-curl and _run_dashed_' ' 347 test_when_finished "rm prop.perf actual" && 348 349 test_config_global "trace2.configParams" "cfg.prop.*" && 350 test_config_global "trace2.envvars" "ENV_PROP_FOO,ENV_PROP_BAR" && 351 352 test_config_global "cfg.prop.foo" "red" && 353 354 test_might_fail env \ 355 ENV_PROP_FOO=blue \ 356 GIT_TRACE2_PERF="$(pwd)/prop.perf" \ 357 git remote-http x y && 358 359 perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <prop.perf >actual && 360 361 grep "d0|main|cmd_name|.*|_run_dashed_" actual && 362 grep "d0|main|def_param|.*|cfg.prop.foo:red" actual && 363 grep "d0|main|def_param|.*|ENV_PROP_FOO:blue" actual && 364 365 grep "d1|main|cmd_name|.*|remote-curl" actual && 366 grep "d1|main|def_param|.*|cfg.prop.foo:red" actual && 367 grep "d1|main|def_param|.*|ENV_PROP_FOO:blue" actual 368' 369 370# Similarly, `git-http-fetch` is not built from git.c so do a 371# trivial fetch so that the main git.c run-dashed code spawns 372# an executable built from http-fetch.c. Confirm that we get 373# def_param events from both layers. 374# 375test_expect_success LIBCURL \ 376 'expect def_params for http-fetch and _run_dashed_' ' 377 test_when_finished "rm prop.perf actual" && 378 379 test_config_global "trace2.configParams" "cfg.prop.*" && 380 test_config_global "trace2.envvars" "ENV_PROP_FOO,ENV_PROP_BAR" && 381 382 test_config_global "cfg.prop.foo" "red" && 383 384 test_might_fail env \ 385 ENV_PROP_FOO=blue \ 386 GIT_TRACE2_PERF="$(pwd)/prop.perf" \ 387 git http-fetch --stdin file:/// <<-EOF && 388 EOF 389 390 perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <prop.perf >actual && 391 392 grep "d0|main|cmd_name|.*|_run_dashed_" actual && 393 grep "d0|main|def_param|.*|cfg.prop.foo:red" actual && 394 grep "d0|main|def_param|.*|ENV_PROP_FOO:blue" actual && 395 396 grep "d1|main|cmd_name|.*|http-fetch" actual && 397 grep "d1|main|def_param|.*|cfg.prop.foo:red" actual && 398 grep "d1|main|def_param|.*|ENV_PROP_FOO:blue" actual 399' 400 401# Historically, alias expansion explicitly emitted the def_param 402# events (independent of whether the command was a builtin, a Git 403# command or arbitrary shell command) so that it wasn't dependent 404# upon the unpeeling of the alias. Let's make sure that we preserve 405# the net effect. 406# 407test_expect_success 'expect def_params during git alias expansion' ' 408 test_when_finished "rm prop.perf actual" && 409 410 test_config_global "trace2.configParams" "cfg.prop.*" && 411 test_config_global "trace2.envvars" "ENV_PROP_FOO,ENV_PROP_BAR" && 412 413 test_config_global "cfg.prop.foo" "red" && 414 415 test_config_global "alias.xxx" "version" && 416 417 ENV_PROP_FOO=blue \ 418 GIT_TRACE2_PERF="$(pwd)/prop.perf" \ 419 git xxx && 420 421 perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <prop.perf >actual && 422 423 # "git xxx" is first mapped to "git-xxx" and the child will fail. 424 grep "d0|main|cmd_name|.*|_run_dashed_ (_run_dashed_)" actual && 425 426 # We unpeel that and substitute "version" into "xxx" (giving 427 # "git version") and update the cmd_name event. 428 grep "d0|main|cmd_name|.*|_run_git_alias_ (_run_dashed_/_run_git_alias_)" actual && 429 430 # These def_param events could be associated with either of the 431 # above cmd_name events. It does not matter. 432 grep "d0|main|def_param|.*|cfg.prop.foo:red" actual && 433 grep "d0|main|def_param|.*|ENV_PROP_FOO:blue" actual && 434 435 # The "git version" child sees a different cmd_name hierarchy. 436 # Also test the def_param (only for completeness). 437 grep "d1|main|cmd_name|.*|version (_run_dashed_/_run_git_alias_/version)" actual && 438 grep "d1|main|def_param|.*|cfg.prop.foo:red" actual && 439 grep "d1|main|def_param|.*|ENV_PROP_FOO:blue" actual 440' 441 442test_expect_success 'expect def_params during shell alias expansion' ' 443 test_when_finished "rm prop.perf actual" && 444 445 test_config_global "trace2.configParams" "cfg.prop.*" && 446 test_config_global "trace2.envvars" "ENV_PROP_FOO,ENV_PROP_BAR" && 447 448 test_config_global "cfg.prop.foo" "red" && 449 450 test_config_global "alias.xxx" "!git version" && 451 452 ENV_PROP_FOO=blue \ 453 GIT_TRACE2_PERF="$(pwd)/prop.perf" \ 454 git xxx && 455 456 perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <prop.perf >actual && 457 458 # "git xxx" is first mapped to "git-xxx" and the child will fail. 459 grep "d0|main|cmd_name|.*|_run_dashed_ (_run_dashed_)" actual && 460 461 # We unpeel that and substitute "git version" for "git xxx" (as a 462 # shell command. Another cmd_name event is emitted as we unpeel. 463 grep "d0|main|cmd_name|.*|_run_shell_alias_ (_run_dashed_/_run_shell_alias_)" actual && 464 465 # These def_param events could be associated with either of the 466 # above cmd_name events. It does not matter. 467 grep "d0|main|def_param|.*|cfg.prop.foo:red" actual && 468 grep "d0|main|def_param|.*|ENV_PROP_FOO:blue" actual && 469 470 # We get the following only because we used a git command for the 471 # shell command. In general, it could have been a shell script and 472 # we would see nothing. 473 # 474 # The child knows the cmd_name hierarchy so it includes it. 475 grep "d1|main|cmd_name|.*|version (_run_dashed_/_run_shell_alias_/version)" actual && 476 grep "d1|main|def_param|.*|cfg.prop.foo:red" actual && 477 grep "d1|main|def_param|.*|ENV_PROP_FOO:blue" actual 478' 479 480test_expect_success 'expect def_params during nested git alias expansion' ' 481 test_when_finished "rm prop.perf actual" && 482 483 test_config_global "trace2.configParams" "cfg.prop.*" && 484 test_config_global "trace2.envvars" "ENV_PROP_FOO,ENV_PROP_BAR" && 485 486 test_config_global "cfg.prop.foo" "red" && 487 488 test_config_global "alias.xxx" "yyy" && 489 test_config_global "alias.yyy" "version" && 490 491 ENV_PROP_FOO=blue \ 492 GIT_TRACE2_PERF="$(pwd)/prop.perf" \ 493 git xxx && 494 495 perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <prop.perf >actual && 496 497 # "git xxx" is first mapped to "git-xxx" and try to spawn "git-xxx" 498 # and the child will fail. 499 grep "d0|main|cmd_name|.*|_run_dashed_ (_run_dashed_)" actual && 500 grep "d0|main|child_start|.*|.* class:dashed argv:\[git-xxx\]" actual && 501 502 # We unpeel that and substitute "yyy" into "xxx" (giving "git yyy") 503 # and spawn "git-yyy" and the child will fail. 504 grep "d0|main|alias|.*|alias:xxx argv:\[yyy\]" actual && 505 grep "d0|main|cmd_name|.*|_run_dashed_ (_run_dashed_/_run_dashed_)" actual && 506 grep "d0|main|child_start|.*|.* class:dashed argv:\[git-yyy\]" actual && 507 508 # We unpeel that and substitute "version" into "xxx" (giving 509 # "git version") and update the cmd_name event. 510 grep "d0|main|alias|.*|alias:yyy argv:\[version\]" actual && 511 grep "d0|main|cmd_name|.*|_run_git_alias_ (_run_dashed_/_run_dashed_/_run_git_alias_)" actual && 512 513 # These def_param events could be associated with any of the 514 # above cmd_name events. It does not matter. 515 grep "d0|main|def_param|.*|cfg.prop.foo:red" actual >actual.matches && 516 grep "d0|main|def_param|.*|ENV_PROP_FOO:blue" actual && 517 518 # However, we do not want them repeated each time we unpeel. 519 test_line_count = 1 actual.matches && 520 521 # The "git version" child sees a different cmd_name hierarchy. 522 # Also test the def_param (only for completeness). 523 grep "d1|main|cmd_name|.*|version (_run_dashed_/_run_dashed_/_run_git_alias_/version)" actual && 524 grep "d1|main|def_param|.*|cfg.prop.foo:red" actual && 525 grep "d1|main|def_param|.*|ENV_PROP_FOO:blue" actual 526' 527 528test_done