Merge branch 'js/init-db-update-for-mingw'
[gitweb.git] / t / test-lib-functions.sh
index 4207af40777c69365dc395e800a7e4214beab076..681c41ba329a90db8c668fde4640025872f1e622 100644 (file)
@@ -42,6 +42,8 @@ test_decode_color () {
                function name(n) {
                        if (n == 0) return "RESET";
                        if (n == 1) return "BOLD";
+                       if (n == 2) return "FAINT";
+                       if (n == 3) return "ITALIC";
                        if (n == 7) return "REVERSE";
                        if (n == 30) return "BLACK";
                        if (n == 31) return "RED";
@@ -114,6 +116,13 @@ remove_cr () {
        tr '\015' Q | sed -e 's/Q$//'
 }
 
+# Generate an output of $1 bytes of all zeroes (NULs, not ASCII zeroes).
+# If $1 is 'infinity', output forever or until the receiving pipe stops reading,
+# whichever comes first.
+generate_zero_bytes () {
+       test-tool genzeros "$@"
+}
+
 # In some bourne shell implementations, the "unset" builtin returns
 # nonzero status when a variable to be unset was not set in the first
 # place.
@@ -416,14 +425,14 @@ test_declared_prereq () {
 test_verify_prereq () {
        test -z "$test_prereq" ||
        expr >/dev/null "$test_prereq" : '[A-Z0-9_,!]*$' ||
-       error "bug in the test script: '$test_prereq' does not look like a prereq"
+       BUG "'$test_prereq' does not look like a prereq"
 }
 
 test_expect_failure () {
        test_start_
        test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq=
        test "$#" = 2 ||
-       error "bug in the test script: not 2 or 3 parameters to test-expect-failure"
+       BUG "not 2 or 3 parameters to test-expect-failure"
        test_verify_prereq
        export test_prereq
        if ! test_skip "$@"
@@ -443,7 +452,7 @@ test_expect_success () {
        test_start_
        test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq=
        test "$#" = 2 ||
-       error "bug in the test script: not 2 or 3 parameters to test-expect-success"
+       BUG "not 2 or 3 parameters to test-expect-success"
        test_verify_prereq
        export test_prereq
        if ! test_skip "$@"
@@ -470,7 +479,7 @@ test_expect_success () {
 test_external () {
        test "$#" = 4 && { test_prereq=$1; shift; } || test_prereq=
        test "$#" = 3 ||
-       error >&5 "bug in the test script: not 3 or 4 parameters to test_external"
+       BUG "not 3 or 4 parameters to test_external"
        descr="$1"
        shift
        test_verify_prereq
@@ -584,6 +593,15 @@ test_dir_is_empty () {
        fi
 }
 
+# Check if the file exists and has a size greater than zero
+test_file_not_empty () {
+       if ! test -s "$1"
+       then
+               echo "'$1' is not a non-empty file."
+               false
+       fi
+}
+
 test_path_is_missing () {
        if test -e "$1"
        then
@@ -611,7 +629,7 @@ test_path_is_missing () {
 test_line_count () {
        if test $# != 3
        then
-               error "bug in the test script: not 3 parameters to test_line_count"
+               BUG "not 3 parameters to test_line_count"
        elif ! test $(wc -l <"$3") "$1" "$2"
        then
                echo "test_line_count: line count for $3 !$1 $2"
@@ -745,6 +763,29 @@ test_cmp() {
        $GIT_TEST_CMP "$@"
 }
 
+# Check that the given config key has the expected value.
+#
+#    test_cmp_config [-C <dir>] <expected-value>
+#                    [<git-config-options>...] <config-key>
+#
+# for example to check that the value of core.bar is foo
+#
+#    test_cmp_config foo core.bar
+#
+test_cmp_config() {
+       local GD &&
+       if test "$1" = "-C"
+       then
+               shift &&
+               GD="-C $1" &&
+               shift
+       fi &&
+       printf "%s\n" "$1" >expect.config &&
+       shift &&
+       git $GD config "$@" >actual.config &&
+       test_cmp expect.config actual.config
+}
+
 # test_cmp_bin - helper to compare binary files
 
 test_cmp_bin() {
@@ -753,31 +794,30 @@ test_cmp_bin() {
 
 # Use this instead of test_cmp to compare files that contain expected and
 # actual output from git commands that can be translated.  When running
-# under GETTEXT_POISON this pretends that the command produced expected
+# under GIT_TEST_GETTEXT_POISON this pretends that the command produced expected
 # results.
 test_i18ncmp () {
-       test -n "$GETTEXT_POISON" || test_cmp "$@"
+       ! test_have_prereq C_LOCALE_OUTPUT || test_cmp "$@"
 }
 
 # Use this instead of "grep expected-string actual" to see if the
 # output from a git command that can be translated either contains an
 # expected string, or does not contain an unwanted one.  When running
-# under GETTEXT_POISON this pretends that the command produced expected
+# under GIT_TEST_GETTEXT_POISON this pretends that the command produced expected
 # results.
 test_i18ngrep () {
        eval "last_arg=\${$#}"
 
        test -f "$last_arg" ||
-       error "bug in the test script: test_i18ngrep requires a file" \
-             "to read as the last parameter"
+       BUG "test_i18ngrep requires a file to read as the last parameter"
 
        if test $# -lt 2 ||
           { test "x!" = "x$1" && test $# -lt 3 ; }
        then
-               error "bug in the test script: too few parameters to test_i18ngrep"
+               BUG "too few parameters to test_i18ngrep"
        fi
 
-       if test -n "$GETTEXT_POISON"
+       if test_have_prereq !C_LOCALE_OUTPUT
        then
                # pretend success
                return 0
@@ -829,9 +869,23 @@ test_must_be_empty () {
 
 # Tests that its two parameters refer to the same revision
 test_cmp_rev () {
-       git rev-parse --verify "$1" >expect.rev &&
-       git rev-parse --verify "$2" >actual.rev &&
-       test_cmp expect.rev actual.rev
+       if test $# != 2
+       then
+               error "bug in the test script: test_cmp_rev requires two revisions, but got $#"
+       else
+               local r1 r2
+               r1=$(git rev-parse --verify "$1") &&
+               r2=$(git rev-parse --verify "$2") &&
+               if test "$r1" != "$r2"
+               then
+                       cat >&4 <<-EOF
+                       error: two revisions point to different objects:
+                         '$1': $r1
+                         '$2': $r2
+                       EOF
+                       return 1
+               fi
+       fi
 }
 
 # Print a sequence of integers in increasing order, either with
@@ -846,7 +900,7 @@ test_seq () {
        case $# in
        1)      set 1 "$@" ;;
        2)      ;;
-       *)      error "bug in the test script: not 1 or 2 parameters to test_seq" ;;
+       *)      BUG "not 1 or 2 parameters to test_seq" ;;
        esac
        test_seq_counter__=$1
        while test "$test_seq_counter__" -le "$2"
@@ -884,7 +938,7 @@ test_when_finished () {
        # doing so on Bash is better than nothing (the test will
        # silently pass on other shells).
        test "${BASH_SUBSHELL-0}" = 0 ||
-       error "bug in test script: test_when_finished does nothing in a subshell"
+       BUG "test_when_finished does nothing in a subshell"
        test_cleanup="{ $*
                } && (exit \"\$eval_ret\"); eval_ret=\$?; $test_cleanup"
 }
@@ -893,12 +947,13 @@ test_when_finished () {
 # Usage: test_create_repo <directory>
 test_create_repo () {
        test "$#" = 1 ||
-       error "bug in the test script: not 1 parameter to test-create-repo"
+       BUG "not 1 parameter to test-create-repo"
        repo="$1"
        mkdir -p "$repo"
        (
                cd "$repo" || error "Cannot setup test environment"
-               "$GIT_EXEC_PATH/git-init" "--template=$GIT_BUILD_DIR/templates/blt/" >&3 2>&4 ||
+               "${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" init \
+                       "--template=$GIT_BUILD_DIR/templates/blt/" >&3 2>&4 ||
                error "cannot run git init -- have you built things yet?"
                mv .git/hooks .git/hooks-disabled
        ) || exit
@@ -1155,3 +1210,111 @@ depacketize () {
                }
        '
 }
+
+# Set the hash algorithm in use to $1.  Only useful when testing the testsuite.
+test_set_hash () {
+       test_hash_algo="$1"
+}
+
+# Detect the hash algorithm in use.
+test_detect_hash () {
+       # Currently we only support SHA-1, but in the future this function will
+       # actually detect the algorithm in use.
+       test_hash_algo='sha1'
+}
+
+# Load common hash metadata and common placeholder object IDs for use with
+# test_oid.
+test_oid_init () {
+       test -n "$test_hash_algo" || test_detect_hash &&
+       test_oid_cache <"$TEST_DIRECTORY/oid-info/hash-info" &&
+       test_oid_cache <"$TEST_DIRECTORY/oid-info/oid"
+}
+
+# Load key-value pairs from stdin suitable for use with test_oid.  Blank lines
+# and lines starting with "#" are ignored.  Keys must be shell identifier
+# characters.
+#
+# Examples:
+# rawsz sha1:20
+# rawsz sha256:32
+test_oid_cache () {
+       local tag rest k v &&
+
+       { test -n "$test_hash_algo" || test_detect_hash; } &&
+       while read tag rest
+       do
+               case $tag in
+               \#*)
+                       continue;;
+               ?*)
+                       # non-empty
+                       ;;
+               *)
+                       # blank line
+                       continue;;
+               esac &&
+
+               k="${rest%:*}" &&
+               v="${rest#*:}" &&
+
+               if ! expr "$k" : '[a-z0-9][a-z0-9]*$' >/dev/null
+               then
+                       BUG 'bad hash algorithm'
+               fi &&
+               eval "test_oid_${k}_$tag=\"\$v\""
+       done
+}
+
+# Look up a per-hash value based on a key ($1).  The value must have been loaded
+# by test_oid_init or test_oid_cache.
+test_oid () {
+       local var="test_oid_${test_hash_algo}_$1" &&
+
+       # If the variable is unset, we must be missing an entry for this
+       # key-hash pair, so exit with an error.
+       if eval "test -z \"\${$var+set}\""
+       then
+               BUG "undefined key '$1'"
+       fi &&
+       eval "printf '%s' \"\${$var}\""
+}
+
+# Choose a port number based on the test script's number and store it in
+# the given variable name, unless that variable already contains a number.
+test_set_port () {
+       local var=$1 port
+
+       if test $# -ne 1 || test -z "$var"
+       then
+               BUG "test_set_port requires a variable name"
+       fi
+
+       eval port=\$$var
+       case "$port" in
+       "")
+               # No port is set in the given env var, use the test
+               # number as port number instead.
+               # Remove not only the leading 't', but all leading zeros
+               # as well, so the arithmetic below won't (mis)interpret
+               # a test number like '0123' as an octal value.
+               port=${this_test#${this_test%%[1-9]*}}
+               if test "${port:-0}" -lt 1024
+               then
+                       # root-only port, use a larger one instead.
+                       port=$(($port + 10000))
+               fi
+               ;;
+       *[!0-9]*|0*)
+               error >&7 "invalid port number: $port"
+               ;;
+       *)
+               # The user has specified the port.
+               ;;
+       esac
+
+       # Make sure that parallel '--stress' test jobs get different
+       # ports.
+       port=$(($port + ${GIT_TEST_STRESS_JOB_NR:-0}))
+       eval $var=$port
+}