1# Library of functions shared by all tests scripts, included by 2# test-lib.sh. 3# 4# Copyright (c) 2005 Junio C Hamano 5# 6# This program is free software: you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation, either version 2 of the License, or 9# (at your option) any later version. 10# 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with this program. If not, see http://www.gnu.org/licenses/ . 18 19# The semantics of the editor variables are that of invoking 20# sh -c "$EDITOR \"$@\"" files ... 21# 22# If our trash directory contains shell metacharacters, they will be 23# interpreted if we just set $EDITOR directly, so do a little dance with 24# environment variables to work around this. 25# 26# In particular, quoting isn't enough, as the path may contain the same quote 27# that we're using. 28test_set_editor () { 29 FAKE_EDITOR="$1" 30 export FAKE_EDITOR 31 EDITOR='"$FAKE_EDITOR"' 32 export EDITOR 33} 34 35test_decode_color () { 36 awk ' 37 function name(n) { 38 if (n == 0) return "RESET"; 39 if (n == 1) return "BOLD"; 40 if (n == 2) return "FAINT"; 41 if (n == 3) return "ITALIC"; 42 if (n == 7) return "REVERSE"; 43 if (n == 30) return "BLACK"; 44 if (n == 31) return "RED"; 45 if (n == 32) return "GREEN"; 46 if (n == 33) return "YELLOW"; 47 if (n == 34) return "BLUE"; 48 if (n == 35) return "MAGENTA"; 49 if (n == 36) return "CYAN"; 50 if (n == 37) return "WHITE"; 51 if (n == 40) return "BLACK"; 52 if (n == 41) return "BRED"; 53 if (n == 42) return "BGREEN"; 54 if (n == 43) return "BYELLOW"; 55 if (n == 44) return "BBLUE"; 56 if (n == 45) return "BMAGENTA"; 57 if (n == 46) return "BCYAN"; 58 if (n == 47) return "BWHITE"; 59 } 60 { 61 while (match($0, /\033\[[0-9;]*m/) != 0) { 62 printf "%s<", substr($0, 1, RSTART-1); 63 codes = substr($0, RSTART+2, RLENGTH-3); 64 if (length(codes) == 0) 65 printf "%s", name(0) 66 else { 67 n = split(codes, ary, ";"); 68 sep = ""; 69 for (i = 1; i <= n; i++) { 70 printf "%s%s", sep, name(ary[i]); 71 sep = ";" 72 } 73 } 74 printf ">"; 75 $0 = substr($0, RSTART + RLENGTH, length($0) - RSTART - RLENGTH + 1); 76 } 77 print 78 } 79 ' 80} 81 82lf_to_nul () { 83 perl -pe 'y/\012/\000/' 84} 85 86nul_to_q () { 87 perl -pe 'y/\000/Q/' 88} 89 90q_to_nul () { 91 perl -pe 'y/Q/\000/' 92} 93 94q_to_cr () { 95 tr Q '\015' 96} 97 98q_to_tab () { 99 tr Q '\011' 100} 101 102qz_to_tab_space () { 103 tr QZ '\011\040' 104} 105 106append_cr () { 107 sed -e 's/$/Q/' | tr Q '\015' 108} 109 110remove_cr () { 111 tr '\015' Q | sed -e 's/Q$//' 112} 113 114# In some bourne shell implementations, the "unset" builtin returns 115# nonzero status when a variable to be unset was not set in the first 116# place. 117# 118# Use sane_unset when that should not be considered an error. 119 120sane_unset () { 121 unset "$@" 122 return 0 123} 124 125test_tick () { 126 if test -z "${test_tick+set}" 127 then 128 test_tick=1112911993 129 else 130 test_tick=$(($test_tick + 60)) 131 fi 132 GIT_COMMITTER_DATE="$test_tick -0700" 133 GIT_AUTHOR_DATE="$test_tick -0700" 134 export GIT_COMMITTER_DATE GIT_AUTHOR_DATE 135} 136 137# Stop execution and start a shell. This is useful for debugging tests. 138# 139# Be sure to remove all invocations of this command before submitting. 140# WARNING: the shell invoked by this helper does not have the same environment 141# as the one running the tests (shell variables and functions are not 142# available, and the options below further modify the environment). As such, 143# commands copied from a test script might behave differently than when 144# running the test. 145# 146# Usage: test_pause [options] 147# -t 148# Use your original TERM instead of test-lib.sh's "dumb". 149# This usually restores color output in the invoked shell. 150# -s 151# Invoke $SHELL instead of $TEST_SHELL_PATH. 152# -h 153# Use your original HOME instead of test-lib.sh's "$TRASH_DIRECTORY". 154# This allows you to use your regular shell environment and Git aliases. 155# CAUTION: running commands copied from a test script into the paused shell 156# might result in files in your HOME being overwritten. 157# -a 158# Shortcut for -t -s -h 159 160test_pause () { 161 PAUSE_TERM=$TERM && 162 PAUSE_SHELL=$TEST_SHELL_PATH && 163 PAUSE_HOME=$HOME && 164 while test $# != 0 165 do 166 case "$1" in 167 -t) 168 PAUSE_TERM="$USER_TERM" 169 ;; 170 -s) 171 PAUSE_SHELL="$SHELL" 172 ;; 173 -h) 174 PAUSE_HOME="$USER_HOME" 175 ;; 176 -a) 177 PAUSE_TERM="$USER_TERM" 178 PAUSE_SHELL="$SHELL" 179 PAUSE_HOME="$USER_HOME" 180 ;; 181 *) 182 break 183 ;; 184 esac 185 shift 186 done && 187 TERM="$PAUSE_TERM" HOME="$PAUSE_HOME" "$PAUSE_SHELL" <&6 >&5 2>&7 188} 189 190# Wrap git with a debugger. Adding this to a command can make it easier 191# to understand what is going on in a failing test. 192# 193# Usage: debug [options] <git command> 194# -d <debugger> 195# --debugger=<debugger> 196# Use <debugger> instead of GDB 197# -t 198# Use your original TERM instead of test-lib.sh's "dumb". 199# This usually restores color output in the debugger. 200# WARNING: the command being debugged might behave differently than when 201# running the test. 202# 203# Examples: 204# debug git checkout master 205# debug --debugger=nemiver git $ARGS 206# debug -d "valgrind --tool=memcheck --track-origins=yes" git $ARGS 207debug () { 208 GIT_DEBUGGER=1 && 209 DEBUG_TERM=$TERM && 210 while test $# != 0 211 do 212 case "$1" in 213 -t) 214 DEBUG_TERM="$USER_TERM" 215 ;; 216 -d) 217 GIT_DEBUGGER="$2" && 218 shift 219 ;; 220 --debugger=*) 221 GIT_DEBUGGER="${1#*=}" 222 ;; 223 *) 224 break 225 ;; 226 esac 227 shift 228 done && 229 230 dotfiles=".gdbinit .lldbinit" 231 232 for dotfile in $dotfiles 233 do 234 dotfile="$USER_HOME/$dotfile" && 235 test -f "$dotfile" && cp "$dotfile" "$HOME" || : 236 done && 237 238 TERM="$DEBUG_TERM" GIT_DEBUGGER="${GIT_DEBUGGER}" "$@" <&6 >&5 2>&7 && 239 240 for dotfile in $dotfiles 241 do 242 rm -f "$HOME/$dotfile" 243 done 244} 245 246# Usage: test_commit [options] <message> [<file> [<contents> [<tag>]]] 247# -C <dir>: 248# Run all git commands in directory <dir> 249# --notick 250# Do not call test_tick before making a commit 251# --append 252# Use ">>" instead of ">" when writing "<contents>" to "<file>" 253# --printf 254# Use "printf" instead of "echo" when writing "<contents>" to 255# "<file>", use this to write escape sequences such as "\0", a 256# trailing "\n" won't be added automatically. This option 257# supports nothing but the FORMAT of printf(1), i.e. no custom 258# ARGUMENT(s). 259# --signoff 260# Invoke "git commit" with --signoff 261# --author <author> 262# Invoke "git commit" with --author <author> 263# --no-tag 264# Do not tag the resulting commit 265# --annotate 266# Create an annotated tag with "--annotate -m <message>". Calls 267# test_tick between making the commit and tag, unless --notick 268# is given. 269# 270# This will commit a file with the given contents and the given commit 271# message, and tag the resulting commit with the given tag name. 272# 273# <file>, <contents>, and <tag> all default to <message>. 274 275test_commit () { 276 notick= && 277 echo=echo && 278 append= && 279 author= && 280 signoff= && 281 indir= && 282 tag=light && 283 while test $# != 0 284 do 285 case "$1" in 286 --notick) 287 notick=yes 288 ;; 289 --printf) 290 echo=printf 291 ;; 292 --append) 293 append=yes 294 ;; 295 --author) 296 author="$2" 297 shift 298 ;; 299 --signoff) 300 signoff="$1" 301 ;; 302 --date) 303 notick=yes 304 GIT_COMMITTER_DATE="$2" 305 GIT_AUTHOR_DATE="$2" 306 shift 307 ;; 308 -C) 309 indir="$2" 310 shift 311 ;; 312 --no-tag) 313 tag=none 314 ;; 315 --annotate) 316 tag=annotate 317 ;; 318 *) 319 break 320 ;; 321 esac 322 shift 323 done && 324 indir=${indir:+"$indir"/} && 325 file=${2:-"$1.t"} && 326 if test -n "$append" 327 then 328 $echo "${3-$1}" >>"$indir$file" 329 else 330 $echo "${3-$1}" >"$indir$file" 331 fi && 332 git ${indir:+ -C "$indir"} add "$file" && 333 if test -z "$notick" 334 then 335 test_tick 336 fi && 337 git ${indir:+ -C "$indir"} commit \ 338 ${author:+ --author "$author"} \ 339 $signoff -m "$1" && 340 case "$tag" in 341 none) 342 ;; 343 light) 344 git ${indir:+ -C "$indir"} tag "${4:-$1}" 345 ;; 346 annotate) 347 if test -z "$notick" 348 then 349 test_tick 350 fi && 351 git ${indir:+ -C "$indir"} tag -a -m "$1" "${4:-$1}" 352 ;; 353 esac 354} 355 356# Call test_merge with the arguments "<message> <commit>", where <commit> 357# can be a tag pointing to the commit-to-merge. 358 359test_merge () { 360 label="$1" && 361 shift && 362 test_tick && 363 git merge -m "$label" "$@" && 364 git tag "$label" 365} 366 367# Efficiently create <nr> commits, each with a unique number (from 1 to <nr> 368# by default) in the commit message. 369# 370# Usage: test_commit_bulk [options] <nr> 371# -C <dir>: 372# Run all git commands in directory <dir> 373# --ref=<n>: 374# ref on which to create commits (default: HEAD) 375# --start=<n>: 376# number commit messages from <n> (default: 1) 377# --message=<msg>: 378# use <msg> as the commit mesasge (default: "commit %s") 379# --filename=<fn>: 380# modify <fn> in each commit (default: %s.t) 381# --contents=<string>: 382# place <string> in each file (default: "content %s") 383# --id=<string>: 384# shorthand to use <string> and %s in message, filename, and contents 385# 386# The message, filename, and contents strings are evaluated by printf, with the 387# first "%s" replaced by the current commit number. So you can do: 388# 389# test_commit_bulk --filename=file --contents="modification %s" 390# 391# to have every commit touch the same file, but with unique content. 392# 393test_commit_bulk () { 394 tmpfile=.bulk-commit.input 395 indir=. 396 ref=HEAD 397 n=1 398 message='commit %s' 399 filename='%s.t' 400 contents='content %s' 401 while test $# -gt 0 402 do 403 case "$1" in 404 -C) 405 indir=$2 406 shift 407 ;; 408 --ref=*) 409 ref=${1#--*=} 410 ;; 411 --start=*) 412 n=${1#--*=} 413 ;; 414 --message=*) 415 message=${1#--*=} 416 ;; 417 --filename=*) 418 filename=${1#--*=} 419 ;; 420 --contents=*) 421 contents=${1#--*=} 422 ;; 423 --id=*) 424 message="${1#--*=} %s" 425 filename="${1#--*=}-%s.t" 426 contents="${1#--*=} %s" 427 ;; 428 -*) 429 BUG "invalid test_commit_bulk option: $1" 430 ;; 431 *) 432 break 433 ;; 434 esac 435 shift 436 done 437 total=$1 438 439 add_from= 440 if git -C "$indir" rev-parse --quiet --verify "$ref" 441 then 442 add_from=t 443 fi 444 445 while test "$total" -gt 0 446 do 447 test_tick && 448 echo "commit $ref" 449 printf 'author %s <%s> %s\n' \ 450 "$GIT_AUTHOR_NAME" \ 451 "$GIT_AUTHOR_EMAIL" \ 452 "$GIT_AUTHOR_DATE" 453 printf 'committer %s <%s> %s\n' \ 454 "$GIT_COMMITTER_NAME" \ 455 "$GIT_COMMITTER_EMAIL" \ 456 "$GIT_COMMITTER_DATE" 457 echo "data <<EOF" 458 printf "$message\n" $n 459 echo "EOF" 460 if test -n "$add_from" 461 then 462 echo "from $ref^0" 463 add_from= 464 fi 465 printf "M 644 inline $filename\n" $n 466 echo "data <<EOF" 467 printf "$contents\n" $n 468 echo "EOF" 469 echo 470 n=$((n + 1)) 471 total=$((total - 1)) 472 done >"$tmpfile" 473 474 git -C "$indir" \ 475 -c fastimport.unpacklimit=0 \ 476 fast-import <"$tmpfile" || return 1 477 478 # This will be left in place on failure, which may aid debugging. 479 rm -f "$tmpfile" 480 481 # If we updated HEAD, then be nice and update the index and working 482 # tree, too. 483 if test "$ref" = "HEAD" 484 then 485 git -C "$indir" checkout -f HEAD || return 1 486 fi 487 488} 489 490# This function helps systems where core.filemode=false is set. 491# Use it instead of plain 'chmod +x' to set or unset the executable bit 492# of a file in the working directory and add it to the index. 493 494test_chmod () { 495 chmod "$@" && 496 git update-index --add "--chmod=$@" 497} 498 499# Get the modebits from a file or directory, ignoring the setgid bit (g+s). 500# This bit is inherited by subdirectories at their creation. So we remove it 501# from the returning string to prevent callers from having to worry about the 502# state of the bit in the test directory. 503# 504test_modebits () { 505 ls -ld "$1" | sed -e 's|^\(..........\).*|\1|' \ 506 -e 's|^\(......\)S|\1-|' -e 's|^\(......\)s|\1x|' 507} 508 509# Unset a configuration variable, but don't fail if it doesn't exist. 510test_unconfig () { 511 config_dir= 512 if test "$1" = -C 513 then 514 shift 515 config_dir=$1 516 shift 517 fi 518 git ${config_dir:+-C "$config_dir"} config --unset-all "$@" 519 config_status=$? 520 case "$config_status" in 521 5) # ok, nothing to unset 522 config_status=0 523 ;; 524 esac 525 return $config_status 526} 527 528# Set git config, automatically unsetting it after the test is over. 529test_config () { 530 config_dir= 531 if test "$1" = -C 532 then 533 shift 534 config_dir=$1 535 shift 536 fi 537 test_when_finished "test_unconfig ${config_dir:+-C '$config_dir'} '$1'" && 538 git ${config_dir:+-C "$config_dir"} config "$@" 539} 540 541test_config_global () { 542 test_when_finished "test_unconfig --global '$1'" && 543 git config --global "$@" 544} 545 546write_script () { 547 { 548 echo "#!${2-"$SHELL_PATH"}" && 549 cat 550 } >"$1" && 551 chmod +x "$1" 552} 553 554# Use test_set_prereq to tell that a particular prerequisite is available. 555# The prerequisite can later be checked for in two ways: 556# 557# - Explicitly using test_have_prereq. 558# 559# - Implicitly by specifying the prerequisite tag in the calls to 560# test_expect_{success,failure} and test_external{,_without_stderr}. 561# 562# The single parameter is the prerequisite tag (a simple word, in all 563# capital letters by convention). 564 565test_unset_prereq () { 566 ! test_have_prereq "$1" || 567 satisfied_prereq="${satisfied_prereq% $1 *} ${satisfied_prereq#* $1 }" 568} 569 570test_set_prereq () { 571 if test -n "$GIT_TEST_FAIL_PREREQS_INTERNAL" 572 then 573 case "$1" in 574 # The "!" case is handled below with 575 # test_unset_prereq() 576 !*) 577 ;; 578 # (Temporary?) whitelist of things we can't easily 579 # pretend not to support 580 SYMLINKS) 581 ;; 582 # Inspecting whether GIT_TEST_FAIL_PREREQS is on 583 # should be unaffected. 584 FAIL_PREREQS) 585 ;; 586 *) 587 return 588 esac 589 fi 590 591 case "$1" in 592 !*) 593 test_unset_prereq "${1#!}" 594 ;; 595 *) 596 satisfied_prereq="$satisfied_prereq$1 " 597 ;; 598 esac 599} 600satisfied_prereq=" " 601lazily_testable_prereq= lazily_tested_prereq= 602 603# Usage: test_lazy_prereq PREREQ 'script' 604test_lazy_prereq () { 605 lazily_testable_prereq="$lazily_testable_prereq$1 " 606 eval test_prereq_lazily_$1=\$2 607} 608 609test_run_lazy_prereq_ () { 610 script=' 611mkdir -p "$TRASH_DIRECTORY/prereq-test-dir-'"$1"'" && 612( 613 cd "$TRASH_DIRECTORY/prereq-test-dir-'"$1"'" &&'"$2"' 614)' 615 say >&3 "checking prerequisite: $1" 616 say >&3 "$script" 617 test_eval_ "$script" 618 eval_ret=$? 619 rm -rf "$TRASH_DIRECTORY/prereq-test-dir-$1" 620 if test "$eval_ret" = 0; then 621 say >&3 "prerequisite $1 ok" 622 else 623 say >&3 "prerequisite $1 not satisfied" 624 fi 625 return $eval_ret 626} 627 628test_have_prereq () { 629 # prerequisites can be concatenated with ',' 630 save_IFS=$IFS 631 IFS=, 632 set -- $* 633 IFS=$save_IFS 634 635 total_prereq=0 636 ok_prereq=0 637 missing_prereq= 638 639 for prerequisite 640 do 641 case "$prerequisite" in 642 !*) 643 negative_prereq=t 644 prerequisite=${prerequisite#!} 645 ;; 646 *) 647 negative_prereq= 648 esac 649 650 case " $lazily_tested_prereq " in 651 *" $prerequisite "*) 652 ;; 653 *) 654 case " $lazily_testable_prereq " in 655 *" $prerequisite "*) 656 eval "script=\$test_prereq_lazily_$prerequisite" && 657 if test_run_lazy_prereq_ "$prerequisite" "$script" 658 then 659 test_set_prereq $prerequisite 660 fi 661 lazily_tested_prereq="$lazily_tested_prereq$prerequisite " 662 esac 663 ;; 664 esac 665 666 total_prereq=$(($total_prereq + 1)) 667 case "$satisfied_prereq" in 668 *" $prerequisite "*) 669 satisfied_this_prereq=t 670 ;; 671 *) 672 satisfied_this_prereq= 673 esac 674 675 case "$satisfied_this_prereq,$negative_prereq" in 676 t,|,t) 677 ok_prereq=$(($ok_prereq + 1)) 678 ;; 679 *) 680 # Keep a list of missing prerequisites; restore 681 # the negative marker if necessary. 682 prerequisite=${negative_prereq:+!}$prerequisite 683 if test -z "$missing_prereq" 684 then 685 missing_prereq=$prerequisite 686 else 687 missing_prereq="$prerequisite,$missing_prereq" 688 fi 689 esac 690 done 691 692 test $total_prereq = $ok_prereq 693} 694 695test_declared_prereq () { 696 case ",$test_prereq," in 697 *,$1,*) 698 return 0 699 ;; 700 esac 701 return 1 702} 703 704test_verify_prereq () { 705 test -z "$test_prereq" || 706 expr >/dev/null "$test_prereq" : '[A-Z0-9_,!]*$' || 707 BUG "'$test_prereq' does not look like a prereq" 708} 709 710test_expect_failure () { 711 test_start_ 712 test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq= 713 test "$#" = 2 || 714 BUG "not 2 or 3 parameters to test-expect-failure" 715 test_verify_prereq 716 export test_prereq 717 if ! test_skip "$@" 718 then 719 say >&3 "checking known breakage of $TEST_NUMBER.$test_count '$1': $2" 720 if test_run_ "$2" expecting_failure 721 then 722 test_known_broken_ok_ "$1" 723 else 724 test_known_broken_failure_ "$1" 725 fi 726 fi 727 test_finish_ 728} 729 730test_expect_success () { 731 test_start_ 732 test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq= 733 test "$#" = 2 || 734 BUG "not 2 or 3 parameters to test-expect-success" 735 test_verify_prereq 736 export test_prereq 737 if ! test_skip "$@" 738 then 739 say >&3 "expecting success of $TEST_NUMBER.$test_count '$1': $2" 740 if test_run_ "$2" 741 then 742 test_ok_ "$1" 743 else 744 test_failure_ "$@" 745 fi 746 fi 747 test_finish_ 748} 749 750# test_external runs external test scripts that provide continuous 751# test output about their progress, and succeeds/fails on 752# zero/non-zero exit code. It outputs the test output on stdout even 753# in non-verbose mode, and announces the external script with "# run 754# <n>: ..." before running it. When providing relative paths, keep in 755# mind that all scripts run in "trash directory". 756# Usage: test_external description command arguments... 757# Example: test_external 'Perl API' perl ../path/to/test.pl 758test_external () { 759 test "$#" = 4 && { test_prereq=$1; shift; } || test_prereq= 760 test "$#" = 3 || 761 BUG "not 3 or 4 parameters to test_external" 762 descr="$1" 763 shift 764 test_verify_prereq 765 export test_prereq 766 if ! test_skip "$descr" "$@" 767 then 768 # Announce the script to reduce confusion about the 769 # test output that follows. 770 say_color "" "# run $test_count: $descr ($*)" 771 # Export TEST_DIRECTORY, TRASH_DIRECTORY and GIT_TEST_LONG 772 # to be able to use them in script 773 export TEST_DIRECTORY TRASH_DIRECTORY GIT_TEST_LONG 774 # Run command; redirect its stderr to &4 as in 775 # test_run_, but keep its stdout on our stdout even in 776 # non-verbose mode. 777 "$@" 2>&4 778 if test "$?" = 0 779 then 780 if test $test_external_has_tap -eq 0; then 781 test_ok_ "$descr" 782 else 783 say_color "" "# test_external test $descr was ok" 784 test_success=$(($test_success + 1)) 785 fi 786 else 787 if test $test_external_has_tap -eq 0; then 788 test_failure_ "$descr" "$@" 789 else 790 say_color error "# test_external test $descr failed: $@" 791 test_failure=$(($test_failure + 1)) 792 fi 793 fi 794 fi 795} 796 797# Like test_external, but in addition tests that the command generated 798# no output on stderr. 799test_external_without_stderr () { 800 # The temporary file has no (and must have no) security 801 # implications. 802 tmp=${TMPDIR:-/tmp} 803 stderr="$tmp/git-external-stderr.$$.tmp" 804 test_external "$@" 4> "$stderr" 805 test -f "$stderr" || error "Internal error: $stderr disappeared." 806 descr="no stderr: $1" 807 shift 808 say >&3 "# expecting no stderr from previous command" 809 if test ! -s "$stderr" 810 then 811 rm "$stderr" 812 813 if test $test_external_has_tap -eq 0; then 814 test_ok_ "$descr" 815 else 816 say_color "" "# test_external_without_stderr test $descr was ok" 817 test_success=$(($test_success + 1)) 818 fi 819 else 820 if test "$verbose" = t 821 then 822 output=$(echo; echo "# Stderr is:"; cat "$stderr") 823 else 824 output= 825 fi 826 # rm first in case test_failure exits. 827 rm "$stderr" 828 if test $test_external_has_tap -eq 0; then 829 test_failure_ "$descr" "$@" "$output" 830 else 831 say_color error "# test_external_without_stderr test $descr failed: $@: $output" 832 test_failure=$(($test_failure + 1)) 833 fi 834 fi 835} 836 837# debugging-friendly alternatives to "test [-f|-d|-e]" 838# The commands test the existence or non-existence of $1 839test_path_is_file () { 840 test "$#" -ne 1 && BUG "1 param" 841 if ! test -f "$1" 842 then 843 echo "File $1 doesn't exist" 844 false 845 fi 846} 847 848test_path_is_dir () { 849 test "$#" -ne 1 && BUG "1 param" 850 if ! test -d "$1" 851 then 852 echo "Directory $1 doesn't exist" 853 false 854 fi 855} 856 857test_path_exists () { 858 test "$#" -ne 1 && BUG "1 param" 859 if ! test -e "$1" 860 then 861 echo "Path $1 doesn't exist" 862 false 863 fi 864} 865 866# Check if the directory exists and is empty as expected, barf otherwise. 867test_dir_is_empty () { 868 test "$#" -ne 1 && BUG "1 param" 869 test_path_is_dir "$1" && 870 if test -n "$(ls -a1 "$1" | egrep -v '^\.\.?$')" 871 then 872 echo "Directory '$1' is not empty, it contains:" 873 ls -la "$1" 874 return 1 875 fi 876} 877 878# Check if the file exists and has a size greater than zero 879test_file_not_empty () { 880 test "$#" = 2 && BUG "2 param" 881 if ! test -s "$1" 882 then 883 echo "'$1' is not a non-empty file." 884 false 885 fi 886} 887 888test_path_is_missing () { 889 test "$#" -ne 1 && BUG "1 param" 890 if test -e "$1" 891 then 892 echo "Path exists:" 893 ls -ld "$1" 894 if test $# -ge 1 895 then 896 echo "$*" 897 fi 898 false 899 fi 900} 901 902# test_line_count checks that a file has the number of lines it 903# ought to. For example: 904# 905# test_expect_success 'produce exactly one line of output' ' 906# do something >output && 907# test_line_count = 1 output 908# ' 909# 910# is like "test $(wc -l <output) = 1" except that it passes the 911# output through when the number of lines is wrong. 912 913test_line_count () { 914 if test $# != 3 915 then 916 BUG "not 3 parameters to test_line_count" 917 elif ! test $(wc -l <"$3") "$1" "$2" 918 then 919 echo "test_line_count: line count for $3 !$1 $2" 920 cat "$3" 921 return 1 922 fi 923} 924 925# SYNOPSIS: 926# test_stdout_line_count <bin-ops> <value> <cmd> [<args>...] 927# 928# test_stdout_line_count checks that the output of a command has the number 929# of lines it ought to. For example: 930# 931# test_stdout_line_count = 3 git ls-files -u 932# test_stdout_line_count -gt 10 ls 933test_stdout_line_count () { 934 local ops val trashdir && 935 if test "$#" -le 3 936 then 937 BUG "expect 3 or more arguments" 938 fi && 939 ops="$1" && 940 val="$2" && 941 shift 2 && 942 if ! trashdir="$(git rev-parse --git-dir)/trash"; then 943 BUG "expect to be run inside a worktree" 944 fi && 945 mkdir -p "$trashdir" && 946 "$@" >"$trashdir/output" && 947 test_line_count "$ops" "$val" "$trashdir/output" 948} 949 950 951test_file_size () { 952 test "$#" -ne 1 && BUG "1 param" 953 test-tool path-utils file-size "$1" 954} 955 956# Returns success if a comma separated string of keywords ($1) contains a 957# given keyword ($2). 958# Examples: 959# `list_contains "foo,bar" bar` returns 0 960# `list_contains "foo" bar` returns 1 961 962list_contains () { 963 case ",$1," in 964 *,$2,*) 965 return 0 966 ;; 967 esac 968 return 1 969} 970 971# Returns success if the arguments indicate that a command should be 972# accepted by test_must_fail(). If the command is run with env, the env 973# and its corresponding variable settings will be stripped before we 974# test the command being run. 975test_must_fail_acceptable () { 976 if test "$1" = "env" 977 then 978 shift 979 while test $# -gt 0 980 do 981 case "$1" in 982 *?=*) 983 shift 984 ;; 985 *) 986 break 987 ;; 988 esac 989 done 990 fi 991 992 case "$1" in 993 git|__git*|test-tool|test_terminal) 994 return 0 995 ;; 996 *) 997 return 1 998 ;; 999 esac 1000} 1001 1002# This is not among top-level (test_expect_success | test_expect_failure) 1003# but is a prefix that can be used in the test script, like: 1004# 1005# test_expect_success 'complain and die' ' 1006# do something && 1007# do something else && 1008# test_must_fail git checkout ../outerspace 1009# ' 1010# 1011# Writing this as "! git checkout ../outerspace" is wrong, because 1012# the failure could be due to a segv. We want a controlled failure. 1013# 1014# Accepts the following options: 1015# 1016# ok=<signal-name>[,<...>]: 1017# Don't treat an exit caused by the given signal as error. 1018# Multiple signals can be specified as a comma separated list. 1019# Currently recognized signal names are: sigpipe, success. 1020# (Don't use 'success', use 'test_might_fail' instead.) 1021# 1022# Do not use this to run anything but "git" and other specific testable 1023# commands (see test_must_fail_acceptable()). We are not in the 1024# business of vetting system supplied commands -- in other words, this 1025# is wrong: 1026# 1027# test_must_fail grep pattern output 1028# 1029# Instead use '!': 1030# 1031# ! grep pattern output 1032 1033test_must_fail () { 1034 case "$1" in 1035 ok=*) 1036 _test_ok=${1#ok=} 1037 shift 1038 ;; 1039 *) 1040 _test_ok= 1041 ;; 1042 esac 1043 if ! test_must_fail_acceptable "$@" 1044 then 1045 echo >&7 "test_must_fail: only 'git' is allowed: $*" 1046 return 1 1047 fi 1048 "$@" 2>&7 1049 exit_code=$? 1050 if test $exit_code -eq 0 && ! list_contains "$_test_ok" success 1051 then 1052 echo >&4 "test_must_fail: command succeeded: $*" 1053 return 1 1054 elif test_match_signal 13 $exit_code && list_contains "$_test_ok" sigpipe 1055 then 1056 return 0 1057 elif test $exit_code -gt 129 && test $exit_code -le 192 1058 then 1059 echo >&4 "test_must_fail: died by signal $(($exit_code - 128)): $*" 1060 return 1 1061 elif test $exit_code -eq 127 1062 then 1063 echo >&4 "test_must_fail: command not found: $*" 1064 return 1 1065 elif test $exit_code -eq 126 1066 then 1067 echo >&4 "test_must_fail: valgrind error: $*" 1068 return 1 1069 fi 1070 return 0 1071} 7>&2 2>&4 1072 1073# Similar to test_must_fail, but tolerates success, too. This is 1074# meant to be used in contexts like: 1075# 1076# test_expect_success 'some command works without configuration' ' 1077# test_might_fail git config --unset all.configuration && 1078# do something 1079# ' 1080# 1081# Writing "git config --unset all.configuration || :" would be wrong, 1082# because we want to notice if it fails due to segv. 1083# 1084# Accepts the same options as test_must_fail. 1085 1086test_might_fail () { 1087 test_must_fail ok=success "$@" 2>&7 1088} 7>&2 2>&4 1089 1090# Similar to test_must_fail and test_might_fail, but check that a 1091# given command exited with a given exit code. Meant to be used as: 1092# 1093# test_expect_success 'Merge with d/f conflicts' ' 1094# test_expect_code 1 git merge "merge msg" B master 1095# ' 1096 1097test_expect_code () { 1098 want_code=$1 1099 shift 1100 "$@" 2>&7 1101 exit_code=$? 1102 if test $exit_code = $want_code 1103 then 1104 return 0 1105 fi 1106 1107 echo >&4 "test_expect_code: command exited with $exit_code, we wanted $want_code $*" 1108 return 1 1109} 7>&2 2>&4 1110 1111# test_cmp is a helper function to compare actual and expected output. 1112# You can use it like: 1113# 1114# test_expect_success 'foo works' ' 1115# echo expected >expected && 1116# foo >actual && 1117# test_cmp expected actual 1118# ' 1119# 1120# This could be written as either "cmp" or "diff -u", but: 1121# - cmp's output is not nearly as easy to read as diff -u 1122# - not all diff versions understand "-u" 1123 1124test_cmp () { 1125 test "$#" -ne 2 && BUG "2 param" 1126 eval "$GIT_TEST_CMP" '"$@"' 1127} 1128 1129# Check that the given config key has the expected value. 1130# 1131# test_cmp_config [-C <dir>] <expected-value> 1132# [<git-config-options>...] <config-key> 1133# 1134# for example to check that the value of core.bar is foo 1135# 1136# test_cmp_config foo core.bar 1137# 1138test_cmp_config () { 1139 local GD && 1140 if test "$1" = "-C" 1141 then 1142 shift && 1143 GD="-C $1" && 1144 shift 1145 fi && 1146 printf "%s\n" "$1" >expect.config && 1147 shift && 1148 git $GD config "$@" >actual.config && 1149 test_cmp expect.config actual.config 1150} 1151 1152# test_cmp_bin - helper to compare binary files 1153 1154test_cmp_bin () { 1155 test "$#" -ne 2 && BUG "2 param" 1156 cmp "$@" 1157} 1158 1159# Wrapper for grep which used to be used for 1160# GIT_TEST_GETTEXT_POISON=false. Only here as a shim for other 1161# in-flight changes. Should not be used and will be removed soon. 1162test_i18ngrep () { 1163 eval "last_arg=\${$#}" 1164 1165 test -f "$last_arg" || 1166 BUG "test_i18ngrep requires a file to read as the last parameter" 1167 1168 if test $# -lt 2 || 1169 { test "x!" = "x$1" && test $# -lt 3 ; } 1170 then 1171 BUG "too few parameters to test_i18ngrep" 1172 fi 1173 1174 if test "x!" = "x$1" 1175 then 1176 shift 1177 ! grep "$@" && return 0 1178 1179 echo >&4 "error: '! grep $@' did find a match in:" 1180 else 1181 grep "$@" && return 0 1182 1183 echo >&4 "error: 'grep $@' didn't find a match in:" 1184 fi 1185 1186 if test -s "$last_arg" 1187 then 1188 cat >&4 "$last_arg" 1189 else 1190 echo >&4 "<File '$last_arg' is empty>" 1191 fi 1192 1193 return 1 1194} 1195 1196# Call any command "$@" but be more verbose about its 1197# failure. This is handy for commands like "test" which do 1198# not output anything when they fail. 1199verbose () { 1200 "$@" && return 0 1201 echo >&4 "command failed: $(git rev-parse --sq-quote "$@")" 1202 return 1 1203} 1204 1205# Check if the file expected to be empty is indeed empty, and barfs 1206# otherwise. 1207 1208test_must_be_empty () { 1209 test "$#" -ne 1 && BUG "1 param" 1210 test_path_is_file "$1" && 1211 if test -s "$1" 1212 then 1213 echo "'$1' is not empty, it contains:" 1214 cat "$1" 1215 return 1 1216 fi 1217} 1218 1219# Tests that its two parameters refer to the same revision, or if '!' is 1220# provided first, that its other two parameters refer to different 1221# revisions. 1222test_cmp_rev () { 1223 local op='=' wrong_result=different 1224 1225 if test $# -ge 1 && test "x$1" = 'x!' 1226 then 1227 op='!=' 1228 wrong_result='the same' 1229 shift 1230 fi 1231 if test $# != 2 1232 then 1233 BUG "test_cmp_rev requires two revisions, but got $#" 1234 else 1235 local r1 r2 1236 r1=$(git rev-parse --verify "$1") && 1237 r2=$(git rev-parse --verify "$2") || return 1 1238 1239 if ! test "$r1" "$op" "$r2" 1240 then 1241 cat >&4 <<-EOF 1242 error: two revisions point to $wrong_result objects: 1243 '$1': $r1 1244 '$2': $r2 1245 EOF 1246 return 1 1247 fi 1248 fi 1249} 1250 1251# Compare paths respecting core.ignoreCase 1252test_cmp_fspath () { 1253 if test "x$1" = "x$2" 1254 then 1255 return 0 1256 fi 1257 1258 if test true != "$(git config --get --type=bool core.ignorecase)" 1259 then 1260 return 1 1261 fi 1262 1263 test "x$(echo "$1" | tr A-Z a-z)" = "x$(echo "$2" | tr A-Z a-z)" 1264} 1265 1266# Print a sequence of integers in increasing order, either with 1267# two arguments (start and end): 1268# 1269# test_seq 1 5 -- outputs 1 2 3 4 5 one line at a time 1270# 1271# or with one argument (end), in which case it starts counting 1272# from 1. 1273 1274test_seq () { 1275 case $# in 1276 1) set 1 "$@" ;; 1277 2) ;; 1278 *) BUG "not 1 or 2 parameters to test_seq" ;; 1279 esac 1280 test_seq_counter__=$1 1281 while test "$test_seq_counter__" -le "$2" 1282 do 1283 echo "$test_seq_counter__" 1284 test_seq_counter__=$(( $test_seq_counter__ + 1 )) 1285 done 1286} 1287 1288# This function can be used to schedule some commands to be run 1289# unconditionally at the end of the test to restore sanity: 1290# 1291# test_expect_success 'test core.capslock' ' 1292# git config core.capslock true && 1293# test_when_finished "git config --unset core.capslock" && 1294# hello world 1295# ' 1296# 1297# That would be roughly equivalent to 1298# 1299# test_expect_success 'test core.capslock' ' 1300# git config core.capslock true && 1301# hello world 1302# git config --unset core.capslock 1303# ' 1304# 1305# except that the greeting and config --unset must both succeed for 1306# the test to pass. 1307# 1308# Note that under --immediate mode, no clean-up is done to help diagnose 1309# what went wrong. 1310 1311test_when_finished () { 1312 # We cannot detect when we are in a subshell in general, but by 1313 # doing so on Bash is better than nothing (the test will 1314 # silently pass on other shells). 1315 test "${BASH_SUBSHELL-0}" = 0 || 1316 BUG "test_when_finished does nothing in a subshell" 1317 test_cleanup="{ $* 1318 } && (exit \"\$eval_ret\"); eval_ret=\$?; $test_cleanup" 1319} 1320 1321# This function can be used to schedule some commands to be run 1322# unconditionally at the end of the test script, e.g. to stop a daemon: 1323# 1324# test_expect_success 'test git daemon' ' 1325# git daemon & 1326# daemon_pid=$! && 1327# test_atexit 'kill $daemon_pid' && 1328# hello world 1329# ' 1330# 1331# The commands will be executed before the trash directory is removed, 1332# i.e. the atexit commands will still be able to access any pidfiles or 1333# socket files. 1334# 1335# Note that these commands will be run even when a test script run 1336# with '--immediate' fails. Be careful with your atexit commands to 1337# minimize any changes to the failed state. 1338 1339test_atexit () { 1340 # We cannot detect when we are in a subshell in general, but by 1341 # doing so on Bash is better than nothing (the test will 1342 # silently pass on other shells). 1343 test "${BASH_SUBSHELL-0}" = 0 || 1344 BUG "test_atexit does nothing in a subshell" 1345 test_atexit_cleanup="{ $* 1346 } && (exit \"\$eval_ret\"); eval_ret=\$?; $test_atexit_cleanup" 1347} 1348 1349# Deprecated wrapper for "git init", use "git init" directly instead 1350# Usage: test_create_repo <directory> 1351test_create_repo () { 1352 git init "$@" 1353} 1354 1355# This function helps on symlink challenged file systems when it is not 1356# important that the file system entry is a symbolic link. 1357# Use test_ln_s_add instead of "ln -s x y && git add y" to add a 1358# symbolic link entry y to the index. 1359 1360test_ln_s_add () { 1361 if test_have_prereq SYMLINKS 1362 then 1363 ln -s "$1" "$2" && 1364 git update-index --add "$2" 1365 else 1366 printf '%s' "$1" >"$2" && 1367 ln_s_obj=$(git hash-object -w "$2") && 1368 git update-index --add --cacheinfo 120000 $ln_s_obj "$2" && 1369 # pick up stat info from the file 1370 git update-index "$2" 1371 fi 1372} 1373 1374# This function writes out its parameters, one per line 1375test_write_lines () { 1376 printf "%s\n" "$@" 1377} 1378 1379perl () { 1380 command "$PERL_PATH" "$@" 2>&7 1381} 7>&2 2>&4 1382 1383# Given the name of an environment variable with a bool value, normalize 1384# its value to a 0 (true) or 1 (false or empty string) return code. 1385# 1386# test_bool_env GIT_TEST_HTTPD <default-value> 1387# 1388# Return with code corresponding to the given default value if the variable 1389# is unset. 1390# Abort the test script if either the value of the variable or the default 1391# are not valid bool values. 1392 1393test_bool_env () { 1394 if test $# != 2 1395 then 1396 BUG "test_bool_env requires two parameters (variable name and default value)" 1397 fi 1398 1399 git env--helper --type=bool --default="$2" --exit-code "$1" 1400 ret=$? 1401 case $ret in 1402 0|1) # unset or valid bool value 1403 ;; 1404 *) # invalid bool value or something unexpected 1405 error >&7 "test_bool_env requires bool values both for \$$1 and for the default fallback" 1406 ;; 1407 esac 1408 return $ret 1409} 1410 1411# Exit the test suite, either by skipping all remaining tests or by 1412# exiting with an error. If our prerequisite variable $1 falls back 1413# on a default assume we were opportunistically trying to set up some 1414# tests and we skip. If it is explicitly "true", then we report a failure. 1415# 1416# The error/skip message should be given by $2. 1417# 1418test_skip_or_die () { 1419 if ! test_bool_env "$1" false 1420 then 1421 skip_all=$2 1422 test_done 1423 fi 1424 error "$2" 1425} 1426 1427# The following mingw_* functions obey POSIX shell syntax, but are actually 1428# bash scripts, and are meant to be used only with bash on Windows. 1429 1430# A test_cmp function that treats LF and CRLF equal and avoids to fork 1431# diff when possible. 1432mingw_test_cmp () { 1433 # Read text into shell variables and compare them. If the results 1434 # are different, use regular diff to report the difference. 1435 local test_cmp_a= test_cmp_b= 1436 1437 # When text came from stdin (one argument is '-') we must feed it 1438 # to diff. 1439 local stdin_for_diff= 1440 1441 # Since it is difficult to detect the difference between an 1442 # empty input file and a failure to read the files, we go straight 1443 # to diff if one of the inputs is empty. 1444 if test -s "$1" && test -s "$2" 1445 then 1446 # regular case: both files non-empty 1447 mingw_read_file_strip_cr_ test_cmp_a <"$1" 1448 mingw_read_file_strip_cr_ test_cmp_b <"$2" 1449 elif test -s "$1" && test "$2" = - 1450 then 1451 # read 2nd file from stdin 1452 mingw_read_file_strip_cr_ test_cmp_a <"$1" 1453 mingw_read_file_strip_cr_ test_cmp_b 1454 stdin_for_diff='<<<"$test_cmp_b"' 1455 elif test "$1" = - && test -s "$2" 1456 then 1457 # read 1st file from stdin 1458 mingw_read_file_strip_cr_ test_cmp_a 1459 mingw_read_file_strip_cr_ test_cmp_b <"$2" 1460 stdin_for_diff='<<<"$test_cmp_a"' 1461 fi 1462 test -n "$test_cmp_a" && 1463 test -n "$test_cmp_b" && 1464 test "$test_cmp_a" = "$test_cmp_b" || 1465 eval "diff -u \"\$@\" $stdin_for_diff" 1466} 1467 1468# $1 is the name of the shell variable to fill in 1469mingw_read_file_strip_cr_ () { 1470 # Read line-wise using LF as the line separator 1471 # and use IFS to strip CR. 1472 local line 1473 while : 1474 do 1475 if IFS=$'\r' read -r -d $'\n' line 1476 then 1477 # good 1478 line=$line$'\n' 1479 else 1480 # we get here at EOF, but also if the last line 1481 # was not terminated by LF; in the latter case, 1482 # some text was read 1483 if test -z "$line" 1484 then 1485 # EOF, really 1486 break 1487 fi 1488 fi 1489 eval "$1=\$$1\$line" 1490 done 1491} 1492 1493# Like "env FOO=BAR some-program", but run inside a subshell, which means 1494# it also works for shell functions (though those functions cannot impact 1495# the environment outside of the test_env invocation). 1496test_env () { 1497 ( 1498 while test $# -gt 0 1499 do 1500 case "$1" in 1501 *=*) 1502 eval "${1%%=*}=\${1#*=}" 1503 eval "export ${1%%=*}" 1504 shift 1505 ;; 1506 *) 1507 "$@" 2>&7 1508 exit 1509 ;; 1510 esac 1511 done 1512 ) 1513} 7>&2 2>&4 1514 1515# Returns true if the numeric exit code in "$2" represents the expected signal 1516# in "$1". Signals should be given numerically. 1517test_match_signal () { 1518 if test "$2" = "$((128 + $1))" 1519 then 1520 # POSIX 1521 return 0 1522 elif test "$2" = "$((256 + $1))" 1523 then 1524 # ksh 1525 return 0 1526 fi 1527 return 1 1528} 1529 1530# Read up to "$1" bytes (or to EOF) from stdin and write them to stdout. 1531test_copy_bytes () { 1532 perl -e ' 1533 my $len = $ARGV[1]; 1534 while ($len > 0) { 1535 my $s; 1536 my $nread = sysread(STDIN, $s, $len); 1537 die "cannot read: $!" unless defined($nread); 1538 last unless $nread; 1539 print $s; 1540 $len -= $nread; 1541 } 1542 ' - "$1" 1543} 1544 1545# run "$@" inside a non-git directory 1546nongit () { 1547 test -d non-repo || 1548 mkdir non-repo || 1549 return 1 1550 1551 ( 1552 GIT_CEILING_DIRECTORIES=$(pwd) && 1553 export GIT_CEILING_DIRECTORIES && 1554 cd non-repo && 1555 "$@" 2>&7 1556 ) 1557} 7>&2 2>&4 1558 1559# These functions are historical wrappers around "test-tool pkt-line" 1560# for older tests. Use "test-tool pkt-line" itself in new tests. 1561packetize () { 1562 if test $# -gt 0 1563 then 1564 packet="$*" 1565 printf '%04x%s' "$((4 + ${#packet}))" "$packet" 1566 else 1567 test-tool pkt-line pack 1568 fi 1569} 1570 1571packetize_raw () { 1572 test-tool pkt-line pack-raw-stdin 1573} 1574 1575depacketize () { 1576 test-tool pkt-line unpack 1577} 1578 1579# Converts base-16 data into base-8. The output is given as a sequence of 1580# escaped octals, suitable for consumption by 'printf'. 1581hex2oct () { 1582 perl -ne 'printf "\\%03o", hex for /../g' 1583} 1584 1585# Set the hash algorithm in use to $1. Only useful when testing the testsuite. 1586test_set_hash () { 1587 test_hash_algo="$1" 1588} 1589 1590# Detect the hash algorithm in use. 1591test_detect_hash () { 1592 test_hash_algo="${GIT_TEST_DEFAULT_HASH:-sha1}" 1593} 1594 1595# Load common hash metadata and common placeholder object IDs for use with 1596# test_oid. 1597test_oid_init () { 1598 test -n "$test_hash_algo" || test_detect_hash && 1599 test_oid_cache <"$TEST_DIRECTORY/oid-info/hash-info" && 1600 test_oid_cache <"$TEST_DIRECTORY/oid-info/oid" 1601} 1602 1603# Load key-value pairs from stdin suitable for use with test_oid. Blank lines 1604# and lines starting with "#" are ignored. Keys must be shell identifier 1605# characters. 1606# 1607# Examples: 1608# rawsz sha1:20 1609# rawsz sha256:32 1610test_oid_cache () { 1611 local tag rest k v && 1612 1613 { test -n "$test_hash_algo" || test_detect_hash; } && 1614 while read tag rest 1615 do 1616 case $tag in 1617 \#*) 1618 continue;; 1619 ?*) 1620 # non-empty 1621 ;; 1622 *) 1623 # blank line 1624 continue;; 1625 esac && 1626 1627 k="${rest%:*}" && 1628 v="${rest#*:}" && 1629 1630 if ! expr "$k" : '[a-z0-9][a-z0-9]*$' >/dev/null 1631 then 1632 BUG 'bad hash algorithm' 1633 fi && 1634 eval "test_oid_${k}_$tag=\"\$v\"" 1635 done 1636} 1637 1638# Look up a per-hash value based on a key ($1). The value must have been loaded 1639# by test_oid_init or test_oid_cache. 1640test_oid () { 1641 local algo="${test_hash_algo}" && 1642 1643 case "$1" in 1644 --hash=*) 1645 algo="${1#--hash=}" && 1646 shift;; 1647 *) 1648 ;; 1649 esac && 1650 1651 local var="test_oid_${algo}_$1" && 1652 1653 # If the variable is unset, we must be missing an entry for this 1654 # key-hash pair, so exit with an error. 1655 if eval "test -z \"\${$var+set}\"" 1656 then 1657 BUG "undefined key '$1'" 1658 fi && 1659 eval "printf '%s' \"\${$var}\"" 1660} 1661 1662# Insert a slash into an object ID so it can be used to reference a location 1663# under ".git/objects". For example, "deadbeef..." becomes "de/adbeef..". 1664test_oid_to_path () { 1665 local basename=${1#??} 1666 echo "${1%$basename}/$basename" 1667} 1668 1669# Choose a port number based on the test script's number and store it in 1670# the given variable name, unless that variable already contains a number. 1671test_set_port () { 1672 local var=$1 port 1673 1674 if test $# -ne 1 || test -z "$var" 1675 then 1676 BUG "test_set_port requires a variable name" 1677 fi 1678 1679 eval port=\$$var 1680 case "$port" in 1681 "") 1682 # No port is set in the given env var, use the test 1683 # number as port number instead. 1684 # Remove not only the leading 't', but all leading zeros 1685 # as well, so the arithmetic below won't (mis)interpret 1686 # a test number like '0123' as an octal value. 1687 port=${this_test#${this_test%%[1-9]*}} 1688 if test "${port:-0}" -lt 1024 1689 then 1690 # root-only port, use a larger one instead. 1691 port=$(($port + 10000)) 1692 fi 1693 ;; 1694 *[!0-9]*|0*) 1695 error >&7 "invalid port number: $port" 1696 ;; 1697 *) 1698 # The user has specified the port. 1699 ;; 1700 esac 1701 1702 # Make sure that parallel '--stress' test jobs get different 1703 # ports. 1704 port=$(($port + ${GIT_TEST_STRESS_JOB_NR:-0})) 1705 eval $var=$port 1706} 1707 1708# Tests for the hidden file attribute on Windows 1709test_path_is_hidden () { 1710 test_have_prereq MINGW || 1711 BUG "test_path_is_hidden can only be used on Windows" 1712 1713 # Use the output of `attrib`, ignore the absolute path 1714 case "$("$SYSTEMROOT"/system32/attrib "$1")" in *H*?:*) return 0;; esac 1715 return 1 1716} 1717 1718# Check that the given command was invoked as part of the 1719# trace2-format trace on stdin. 1720# 1721# test_subcommand [!] <command> <args>... < <trace> 1722# 1723# For example, to look for an invocation of "git upload-pack 1724# /path/to/repo" 1725# 1726# GIT_TRACE2_EVENT=event.log git fetch ... && 1727# test_subcommand git upload-pack "$PATH" <event.log 1728# 1729# If the first parameter passed is !, this instead checks that 1730# the given command was not called. 1731# 1732test_subcommand () { 1733 local negate= 1734 if test "$1" = "!" 1735 then 1736 negate=t 1737 shift 1738 fi 1739 1740 local expr=$(printf '"%s",' "$@") 1741 expr="${expr%,}" 1742 1743 if test -n "$negate" 1744 then 1745 ! grep "\[$expr\]" 1746 else 1747 grep "\[$expr\]" 1748 fi 1749} 1750 1751# Check that the given command was invoked as part of the 1752# trace2-format trace on stdin. 1753# 1754# test_region [!] <category> <label> git <command> <args>... 1755# 1756# For example, to look for trace2_region_enter("index", "do_read_index", repo) 1757# in an invocation of "git checkout HEAD~1", run 1758# 1759# GIT_TRACE2_EVENT="$(pwd)/trace.txt" GIT_TRACE2_EVENT_NESTING=10 \ 1760# git checkout HEAD~1 && 1761# test_region index do_read_index <trace.txt 1762# 1763# If the first parameter passed is !, this instead checks that 1764# the given region was not entered. 1765# 1766test_region () { 1767 local expect_exit=0 1768 if test "$1" = "!" 1769 then 1770 expect_exit=1 1771 shift 1772 fi 1773 1774 grep -e '"region_enter".*"category":"'"$1"'","label":"'"$2"\" "$3" 1775 exitcode=$? 1776 1777 if test $exitcode != $expect_exit 1778 then 1779 return 1 1780 fi 1781 1782 grep -e '"region_leave".*"category":"'"$1"'","label":"'"$2"\" "$3" 1783 exitcode=$? 1784 1785 if test $exitcode != $expect_exit 1786 then 1787 return 1 1788 fi 1789 1790 return 0 1791} 1792 1793# Print the destination of symlink(s) provided as arguments. Basically 1794# the same as the readlink command, but it's not available everywhere. 1795test_readlink () { 1796 perl -le 'print readlink($_) for @ARGV' "$@" 1797} 1798