Merge branch 'ab/test-env'
authorJunio C Hamano <gitster@pobox.com>
Thu, 25 Jul 2019 20:59:20 +0000 (13:59 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 25 Jul 2019 20:59:20 +0000 (13:59 -0700)
Many GIT_TEST_* environment variables control various aspects of
how our tests are run, but a few followed "non-empty is true, empty
or unset is false" while others followed the usual "there are a few
ways to spell true, like yes, on, etc., and also ways to spell
false, like no, off, etc." convention.

* ab/test-env:
env--helper: mark a file-local symbol as static
tests: make GIT_TEST_FAIL_PREREQS a boolean
tests: replace test_tristate with "git env--helper"
tests README: re-flow a previously changed paragraph
tests: make GIT_TEST_GETTEXT_POISON a boolean
t6040 test: stop using global "script" variable
config.c: refactor die_bad_number() to not call gettext() early
env--helper: new undocumented builtin wrapping git_env_*()
config tests: simplify include cycle test

24 files changed:
.gitignore
Makefile
builtin.h
builtin/env--helper.c [new file with mode: 0644]
ci/lib.sh
config.c
gettext.c
git-sh-i18n.sh
git.c
po/README
t/README
t/lib-git-daemon.sh
t/lib-git-svn.sh
t/lib-httpd.sh
t/t0000-basic.sh
t/t0017-env-helper.sh [new file with mode: 0755]
t/t0205-gettext-poison.sh
t/t1305-config-include.sh
t/t5512-ls-remote.sh
t/t6040-tracking-info.sh
t/t7201-co.sh
t/t9902-completion.sh
t/test-lib-functions.sh
t/test-lib.sh
index e096e0a51c19966eb743454fab50d232441008ca..069c190ba078a7fe4ac3b42db67c6d1221939249 100644 (file)
@@ -58,6 +58,7 @@
 /git-difftool
 /git-difftool--helper
 /git-describe
+/git-env--helper
 /git-fast-export
 /git-fast-import
 /git-fetch
index 11ccea40716d9bbcef731f093e530a9b1aee0013..b11cdd4fe79234b57211d236930b0798416b8e6c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1062,6 +1062,7 @@ BUILTIN_OBJS += builtin/diff-index.o
 BUILTIN_OBJS += builtin/diff-tree.o
 BUILTIN_OBJS += builtin/diff.o
 BUILTIN_OBJS += builtin/difftool.o
+BUILTIN_OBJS += builtin/env--helper.o
 BUILTIN_OBJS += builtin/fast-export.o
 BUILTIN_OBJS += builtin/fetch-pack.o
 BUILTIN_OBJS += builtin/fetch.o
index 3d449a021002540f1183166c3cfb1dfce765b75b..5cf5df69f72fd5a660f4dfc8981387f1bcc9c7cc 100644 (file)
--- a/builtin.h
+++ b/builtin.h
@@ -160,6 +160,7 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix);
 int cmd_diff(int argc, const char **argv, const char *prefix);
 int cmd_diff_tree(int argc, const char **argv, const char *prefix);
 int cmd_difftool(int argc, const char **argv, const char *prefix);
+int cmd_env__helper(int argc, const char **argv, const char *prefix);
 int cmd_fast_export(int argc, const char **argv, const char *prefix);
 int cmd_fetch(int argc, const char **argv, const char *prefix);
 int cmd_fetch_pack(int argc, const char **argv, const char *prefix);
diff --git a/builtin/env--helper.c b/builtin/env--helper.c
new file mode 100644 (file)
index 0000000..23c214f
--- /dev/null
@@ -0,0 +1,95 @@
+#include "builtin.h"
+#include "config.h"
+#include "parse-options.h"
+
+static char const * const env__helper_usage[] = {
+       N_("git env--helper --type=[bool|ulong] <options> <env-var>"),
+       NULL
+};
+
+static enum {
+       ENV_HELPER_TYPE_BOOL = 1,
+       ENV_HELPER_TYPE_ULONG
+} cmdmode = 0;
+
+static int option_parse_type(const struct option *opt, const char *arg,
+                            int unset)
+{
+       if (!strcmp(arg, "bool"))
+               cmdmode = ENV_HELPER_TYPE_BOOL;
+       else if (!strcmp(arg, "ulong"))
+               cmdmode = ENV_HELPER_TYPE_ULONG;
+       else
+               die(_("unrecognized --type argument, %s"), arg);
+
+       return 0;
+}
+
+int cmd_env__helper(int argc, const char **argv, const char *prefix)
+{
+       int exit_code = 0;
+       const char *env_variable = NULL;
+       const char *env_default = NULL;
+       int ret;
+       int ret_int, default_int;
+       unsigned long ret_ulong, default_ulong;
+       struct option opts[] = {
+               OPT_CALLBACK_F(0, "type", &cmdmode, N_("type"),
+                              N_("value is given this type"), PARSE_OPT_NONEG,
+                              option_parse_type),
+               OPT_STRING(0, "default", &env_default, N_("value"),
+                          N_("default for git_env_*(...) to fall back on")),
+               OPT_BOOL(0, "exit-code", &exit_code,
+                        N_("be quiet only use git_env_*() value as exit code")),
+               OPT_END(),
+       };
+
+       argc = parse_options(argc, argv, prefix, opts, env__helper_usage,
+                            PARSE_OPT_KEEP_UNKNOWN);
+       if (env_default && !*env_default)
+               usage_with_options(env__helper_usage, opts);
+       if (!cmdmode)
+               usage_with_options(env__helper_usage, opts);
+       if (argc != 1)
+               usage_with_options(env__helper_usage, opts);
+       env_variable = argv[0];
+
+       switch (cmdmode) {
+       case ENV_HELPER_TYPE_BOOL:
+               if (env_default) {
+                       default_int = git_parse_maybe_bool(env_default);
+                       if (default_int == -1) {
+                               error(_("option `--default' expects a boolean value with `--type=bool`, not `%s`"),
+                                     env_default);
+                               usage_with_options(env__helper_usage, opts);
+                       }
+               } else {
+                       default_int = 0;
+               }
+               ret_int = git_env_bool(env_variable, default_int);
+               if (!exit_code)
+                       puts(ret_int ? "true" : "false");
+               ret = ret_int;
+               break;
+       case ENV_HELPER_TYPE_ULONG:
+               if (env_default) {
+                       if (!git_parse_ulong(env_default, &default_ulong)) {
+                               error(_("option `--default' expects an unsigned long value with `--type=ulong`, not `%s`"),
+                                     env_default);
+                               usage_with_options(env__helper_usage, opts);
+                       }
+               } else {
+                       default_ulong = 0;
+               }
+               ret_ulong = git_env_ulong(env_variable, default_ulong);
+               if (!exit_code)
+                       printf("%lu\n", ret_ulong);
+               ret = ret_ulong;
+               break;
+       default:
+               BUG("unknown <type> value");
+               break;
+       }
+
+       return !ret;
+}
index 0c7171a17354fd6dba5017e443b3d1b936f73e34..44db2d5cbb2241c7bd3ffd69d15a73c1fd4357ae 100755 (executable)
--- a/ci/lib.sh
+++ b/ci/lib.sh
@@ -186,7 +186,7 @@ osx-clang|osx-gcc)
        export GIT_SKIP_TESTS="t9810 t9816"
        ;;
 GIT_TEST_GETTEXT_POISON)
-       export GIT_TEST_GETTEXT_POISON=YesPlease
+       export GIT_TEST_GETTEXT_POISON=true
        ;;
 esac
 
index faa57e436cf4fc6d84580f3940bafdb4896c7658..ed7f58e0fcf221733165f3dd6a9d095d727a0a5e 100644 (file)
--- a/config.c
+++ b/config.c
@@ -973,34 +973,44 @@ int git_parse_ssize_t(const char *value, ssize_t *ret)
 NORETURN
 static void die_bad_number(const char *name, const char *value)
 {
-       const char * error_type = (errno == ERANGE)? _("out of range"):_("invalid unit");
+       const char *error_type = (errno == ERANGE) ?
+               N_("out of range") : N_("invalid unit");
+       const char *bad_numeric = N_("bad numeric config value '%s' for '%s': %s");
 
        if (!value)
                value = "";
 
+       if (!strcmp(name, "GIT_TEST_GETTEXT_POISON"))
+               /*
+                * We explicitly *don't* use _() here since it would
+                * cause an infinite loop with _() needing to call
+                * use_gettext_poison(). This is why marked up
+                * translations with N_() above.
+                */
+               die(bad_numeric, value, name, error_type);
+
        if (!(cf && cf->name))
-               die(_("bad numeric config value '%s' for '%s': %s"),
-                   value, name, error_type);
+               die(_(bad_numeric), value, name, _(error_type));
 
        switch (cf->origin_type) {
        case CONFIG_ORIGIN_BLOB:
                die(_("bad numeric config value '%s' for '%s' in blob %s: %s"),
-                   value, name, cf->name, error_type);
+                   value, name, cf->name, _(error_type));
        case CONFIG_ORIGIN_FILE:
                die(_("bad numeric config value '%s' for '%s' in file %s: %s"),
-                   value, name, cf->name, error_type);
+                   value, name, cf->name, _(error_type));
        case CONFIG_ORIGIN_STDIN:
                die(_("bad numeric config value '%s' for '%s' in standard input: %s"),
-                   value, name, error_type);
+                   value, name, _(error_type));
        case CONFIG_ORIGIN_SUBMODULE_BLOB:
                die(_("bad numeric config value '%s' for '%s' in submodule-blob %s: %s"),
-                   value, name, cf->name, error_type);
+                   value, name, cf->name, _(error_type));
        case CONFIG_ORIGIN_CMDLINE:
                die(_("bad numeric config value '%s' for '%s' in command line %s: %s"),
-                   value, name, cf->name, error_type);
+                   value, name, cf->name, _(error_type));
        default:
                die(_("bad numeric config value '%s' for '%s' in %s: %s"),
-                   value, name, cf->name, error_type);
+                   value, name, cf->name, _(error_type));
        }
 }
 
index 3f2aca5c3b16d39375fab9b6203c67ae16209023..35d2c1218db2e27a6ac07fbf3c1244987e3e3021 100644 (file)
--- a/gettext.c
+++ b/gettext.c
@@ -68,10 +68,8 @@ const char *get_preferred_languages(void)
 int use_gettext_poison(void)
 {
        static int poison_requested = -1;
-       if (poison_requested == -1) {
-               const char *v = getenv("GIT_TEST_GETTEXT_POISON");
-               poison_requested = v && strlen(v) ? 1 : 0;
-       }
+       if (poison_requested == -1)
+               poison_requested = git_env_bool("GIT_TEST_GETTEXT_POISON", 0);
        return poison_requested;
 }
 
index e1d917fd2796d1f2d952c509cb79d8cafe0cf89e..8eef60b43fd47a4a679c5c77ae2f9c5ab5907951 100644 (file)
@@ -17,7 +17,9 @@ export TEXTDOMAINDIR
 
 # First decide what scheme to use...
 GIT_INTERNAL_GETTEXT_SH_SCHEME=fallthrough
-if test -n "$GIT_TEST_GETTEXT_POISON"
+if test -n "$GIT_TEST_GETTEXT_POISON" &&
+           git env--helper --type=bool --default=0 --exit-code \
+               GIT_TEST_GETTEXT_POISON
 then
        GIT_INTERNAL_GETTEXT_SH_SCHEME=poison
 elif test -n "@@USE_GETTEXT_SCHEME@@"
diff --git a/git.c b/git.c
index f4c0478f320fba5e919238c0af19890cb9185242..a9604768578f608ea5268365d2006b57c1f73d86 100644 (file)
--- a/git.c
+++ b/git.c
@@ -500,6 +500,7 @@ static struct cmd_struct commands[] = {
        { "diff-index", cmd_diff_index, RUN_SETUP | NO_PARSEOPT },
        { "diff-tree", cmd_diff_tree, RUN_SETUP | NO_PARSEOPT },
        { "difftool", cmd_difftool, RUN_SETUP_GENTLY },
+       { "env--helper", cmd_env__helper },
        { "fast-export", cmd_fast_export, RUN_SETUP },
        { "fetch", cmd_fetch, RUN_SETUP },
        { "fetch-pack", cmd_fetch_pack, RUN_SETUP | NO_PARSEOPT },
index aa704ffcb7f70af2c42494a2f26eeef17c5eed67..07595d369b0ab3cd3a90cef74cae81661f9cb95f 100644 (file)
--- a/po/README
+++ b/po/README
@@ -293,7 +293,7 @@ To smoke out issues like these, Git tested with a translation mode that
 emits gibberish on every call to gettext. To use it run the test suite
 with it, e.g.:
 
-    cd t && GIT_TEST_GETTEXT_POISON=YesPlease prove -j 9 ./t[0-9]*.sh
+    cd t && GIT_TEST_GETTEXT_POISON=true prove -j 9 ./t[0-9]*.sh
 
 If tests break with it you should inspect them manually and see if
 what you're translating is sane, i.e. that you're not translating
index 9747971d58e1a5efaa85a8ce00772c82d7c5aba7..60d5b77bccd952ffe8128a62827d7a15e728f614 100644 (file)
--- a/t/README
+++ b/t/README
@@ -334,7 +334,7 @@ that cannot be easily covered by a few specific test cases. These
 could be enabled by running the test suite with correct GIT_TEST_
 environment set.
 
-GIT_TEST_FAIL_PREREQS<non-empty?> fails all prerequisites. This is
+GIT_TEST_FAIL_PREREQS=<boolean> fails all prerequisites. This is
 useful for discovering issues with the tests where say a later test
 implicitly depends on an optional earlier test.
 
@@ -343,11 +343,11 @@ whether this mode is active, and e.g. skip some tests that are hard to
 refactor to deal with it. The "SYMLINKS" prerequisite is currently
 excluded as so much relies on it, but this might change in the future.
 
-GIT_TEST_GETTEXT_POISON=<non-empty?> turns all strings marked for
-translation into gibberish if non-empty (think "test -n"). Used for
-spotting those tests that need to be marked with a C_LOCALE_OUTPUT
-prerequisite when adding more strings for translation. See "Testing
-marked strings" in po/README for details.
+GIT_TEST_GETTEXT_POISON=<boolean> turns all strings marked for
+translation into gibberish if true. Used for spotting those tests that
+need to be marked with a C_LOCALE_OUTPUT prerequisite when adding more
+strings for translation. See "Testing marked strings" in po/README for
+details.
 
 GIT_TEST_SPLIT_INDEX=<boolean> forces split-index mode on the whole
 test suite. Accept any boolean values that are accepted by git-config.
index 7b3407134e1a776de7a030bce98f0248fe6cd42f..fb8f8870801eb56e1ada818fd1b2ccdf10a4600d 100644 (file)
@@ -15,8 +15,7 @@
 #
 #      test_done
 
-test_tristate GIT_TEST_GIT_DAEMON
-if test "$GIT_TEST_GIT_DAEMON" = false
+if ! git env--helper --type=bool --default=true --exit-code GIT_TEST_GIT_DAEMON
 then
        skip_all="git-daemon testing disabled (unset GIT_TEST_GIT_DAEMON to enable)"
        test_done
@@ -24,7 +23,7 @@ fi
 
 if test_have_prereq !PIPE
 then
-       test_skip_or_die $GIT_TEST_GIT_DAEMON "file system does not support FIFOs"
+       test_skip_or_die GIT_TEST_GIT_DAEMON "file system does not support FIFOs"
 fi
 
 test_set_port LIB_GIT_DAEMON_PORT
@@ -73,7 +72,7 @@ start_git_daemon() {
                kill "$GIT_DAEMON_PID"
                wait "$GIT_DAEMON_PID"
                unset GIT_DAEMON_PID
-               test_skip_or_die $GIT_TEST_GIT_DAEMON \
+               test_skip_or_die GIT_TEST_GIT_DAEMON \
                        "git daemon failed to start"
        fi
 }
index c1271d686372dfd46d640a84ebec3971933ed4f2..5d4ae629e14e668279a559527876685689cae61c 100644 (file)
@@ -69,14 +69,12 @@ svn_cmd () {
 maybe_start_httpd () {
        loc=${1-svn}
 
-       test_tristate GIT_SVN_TEST_HTTPD
-       case $GIT_SVN_TEST_HTTPD in
-       true)
+       if git env--helper --type=bool --default=false --exit-code GIT_TEST_HTTPD
+       then
                . "$TEST_DIRECTORY"/lib-httpd.sh
                LIB_HTTPD_SVN="$loc"
                start_httpd
-               ;;
-       esac
+       fi
 }
 
 convert_to_rev_db () {
@@ -106,8 +104,7 @@ EOF
 }
 
 require_svnserve () {
-       test_tristate GIT_TEST_SVNSERVE
-       if ! test "$GIT_TEST_SVNSERVE" = true
+       if ! git env--helper --type=bool --default=false --exit-code GIT_TEST_SVNSERVE
        then
                skip_all='skipping svnserve test. (set $GIT_TEST_SVNSERVE to enable)'
                test_done
index b3cc62bd36f26f776b307607a941b01c547c404d..0d985758c6dd85e801404860ee82c5e93f1b51d9 100644 (file)
@@ -41,15 +41,14 @@ then
        test_done
 fi
 
-test_tristate GIT_TEST_HTTPD
-if test "$GIT_TEST_HTTPD" = false
+if ! git env--helper --type=bool --default=true --exit-code GIT_TEST_HTTPD
 then
        skip_all="Network testing disabled (unset GIT_TEST_HTTPD to enable)"
        test_done
 fi
 
 if ! test_have_prereq NOT_ROOT; then
-       test_skip_or_die $GIT_TEST_HTTPD \
+       test_skip_or_die GIT_TEST_HTTPD \
                "Cannot run httpd tests as root"
 fi
 
@@ -95,7 +94,7 @@ GIT_TRACE=$GIT_TRACE; export GIT_TRACE
 
 if ! test -x "$LIB_HTTPD_PATH"
 then
-       test_skip_or_die $GIT_TEST_HTTPD "no web server found at '$LIB_HTTPD_PATH'"
+       test_skip_or_die GIT_TEST_HTTPD "no web server found at '$LIB_HTTPD_PATH'"
 fi
 
 HTTPD_VERSION=$($LIB_HTTPD_PATH -v | \
@@ -107,19 +106,19 @@ then
        then
                if ! test $HTTPD_VERSION -ge 2
                then
-                       test_skip_or_die $GIT_TEST_HTTPD \
+                       test_skip_or_die GIT_TEST_HTTPD \
                                "at least Apache version 2 is required"
                fi
                if ! test -d "$DEFAULT_HTTPD_MODULE_PATH"
                then
-                       test_skip_or_die $GIT_TEST_HTTPD \
+                       test_skip_or_die GIT_TEST_HTTPD \
                                "Apache module directory not found"
                fi
 
                LIB_HTTPD_MODULE_PATH="$DEFAULT_HTTPD_MODULE_PATH"
        fi
 else
-       test_skip_or_die $GIT_TEST_HTTPD \
+       test_skip_or_die GIT_TEST_HTTPD \
                "Could not identify web server at '$LIB_HTTPD_PATH'"
 fi
 
@@ -184,7 +183,7 @@ start_httpd() {
        if test $? -ne 0
        then
                cat "$HTTPD_ROOT_PATH"/error.log >&4 2>/dev/null
-               test_skip_or_die $GIT_TEST_HTTPD "web server setup failed"
+               test_skip_or_die GIT_TEST_HTTPD "web server setup failed"
        fi
 }
 
index 31de7e90f3b38d304e952bee68119a0100bbbfb6..e89438e619b010d8eb36bcfa54de8d49cd373180 100755 (executable)
@@ -726,7 +726,7 @@ donthaveit=yes
 test_expect_success DONTHAVEIT 'unmet prerequisite causes test to be skipped' '
        donthaveit=no
 '
-if test -z "$GIT_TEST_FAIL_PREREQS" -a $haveit$donthaveit != yesyes
+if test -z "$GIT_TEST_FAIL_PREREQS_INTERNAL" -a $haveit$donthaveit != yesyes
 then
        say "bug in test framework: prerequisite tags do not work reliably"
        exit 1
@@ -747,7 +747,7 @@ donthaveiteither=yes
 test_expect_success DONTHAVEIT,HAVEIT 'unmet prerequisites causes test to be skipped' '
        donthaveiteither=no
 '
-if test -z "$GIT_TEST_FAIL_PREREQS" -a $haveit$donthaveit$donthaveiteither != yesyesyes
+if test -z "$GIT_TEST_FAIL_PREREQS_INTERNAL" -a $haveit$donthaveit$donthaveiteither != yesyesyes
 then
        say "bug in test framework: multiple prerequisite tags do not work reliably"
        exit 1
@@ -763,7 +763,7 @@ test_expect_success !LAZY_TRUE 'missing lazy prereqs skip tests' '
        donthavetrue=no
 '
 
-if test -z "$GIT_TEST_FAIL_PREREQS" -a "$havetrue$donthavetrue" != yesyes
+if test -z "$GIT_TEST_FAIL_PREREQS_INTERNAL" -a "$havetrue$donthavetrue" != yesyes
 then
        say 'bug in test framework: lazy prerequisites do not work'
        exit 1
@@ -779,7 +779,7 @@ test_expect_success LAZY_FALSE 'missing negative lazy prereqs will skip' '
        havefalse=no
 '
 
-if test -z "$GIT_TEST_FAIL_PREREQS" -a "$nothavefalse$havefalse" != yesyes
+if test -z "$GIT_TEST_FAIL_PREREQS_INTERNAL" -a "$nothavefalse$havefalse" != yesyes
 then
        say 'bug in test framework: negative lazy prerequisites do not work'
        exit 1
@@ -790,7 +790,7 @@ test_expect_success 'tests clean up after themselves' '
        test_when_finished clean=yes
 '
 
-if test -z "$GIT_TEST_FAIL_PREREQS" -a $clean != yes
+if test -z "$GIT_TEST_FAIL_PREREQS_INTERNAL" -a $clean != yes
 then
        say "bug in test framework: basic cleanup command does not work reliably"
        exit 1
diff --git a/t/t0017-env-helper.sh b/t/t0017-env-helper.sh
new file mode 100755 (executable)
index 0000000..c1ecf6a
--- /dev/null
@@ -0,0 +1,99 @@
+#!/bin/sh
+
+test_description='test env--helper'
+
+. ./test-lib.sh
+
+
+test_expect_success 'env--helper usage' '
+       test_must_fail git env--helper &&
+       test_must_fail git env--helper --type=bool &&
+       test_must_fail git env--helper --type=ulong &&
+       test_must_fail git env--helper --type=bool &&
+       test_must_fail git env--helper --type=bool --default &&
+       test_must_fail git env--helper --type=bool --default= &&
+       test_must_fail git env--helper --defaultxyz
+'
+
+test_expect_success 'env--helper bad default values' '
+       test_must_fail git env--helper --type=bool --default=1xyz MISSING &&
+       test_must_fail git env--helper --type=ulong --default=1xyz MISSING
+'
+
+test_expect_success 'env--helper --type=bool' '
+       # Test various --default bool values
+       echo true >expected &&
+       git env--helper --type=bool --default=1 MISSING >actual &&
+       test_cmp expected actual &&
+       git env--helper --type=bool --default=yes MISSING >actual &&
+       test_cmp expected actual &&
+       git env--helper --type=bool --default=true MISSING >actual &&
+       test_cmp expected actual &&
+       echo false >expected &&
+       test_must_fail git env--helper --type=bool --default=0 MISSING >actual &&
+       test_cmp expected actual &&
+       test_must_fail git env--helper --type=bool --default=no MISSING >actual &&
+       test_cmp expected actual &&
+       test_must_fail git env--helper --type=bool --default=false MISSING >actual &&
+       test_cmp expected actual &&
+
+       # No output with --exit-code
+       git env--helper --type=bool --default=true --exit-code MISSING >actual.out 2>actual.err &&
+       test_must_be_empty actual.out &&
+       test_must_be_empty actual.err &&
+       test_must_fail git env--helper --type=bool --default=false --exit-code MISSING >actual.out 2>actual.err &&
+       test_must_be_empty actual.out &&
+       test_must_be_empty actual.err &&
+
+       # Existing variable
+       EXISTS=true git env--helper --type=bool --default=false --exit-code EXISTS >actual.out 2>actual.err &&
+       test_must_be_empty actual.out &&
+       test_must_be_empty actual.err &&
+       test_must_fail \
+               env EXISTS=false \
+               git env--helper --type=bool --default=true --exit-code EXISTS >actual.out 2>actual.err &&
+       test_must_be_empty actual.out &&
+       test_must_be_empty actual.err
+'
+
+test_expect_success 'env--helper --type=ulong' '
+       echo 1234567890 >expected &&
+       git env--helper --type=ulong --default=1234567890 MISSING >actual.out 2>actual.err &&
+       test_cmp expected actual.out &&
+       test_must_be_empty actual.err &&
+
+       echo 0 >expected &&
+       test_must_fail git env--helper --type=ulong --default=0 MISSING >actual &&
+       test_cmp expected actual &&
+
+       git env--helper --type=ulong --default=1234567890 --exit-code MISSING >actual.out 2>actual.err &&
+       test_must_be_empty actual.out &&
+       test_must_be_empty actual.err &&
+
+       EXISTS=1234567890 git env--helper --type=ulong --default=0 EXISTS --exit-code >actual.out 2>actual.err &&
+       test_must_be_empty actual.out &&
+       test_must_be_empty actual.err &&
+
+       echo 1234567890 >expected &&
+       EXISTS=1234567890 git env--helper --type=ulong --default=0 EXISTS >actual.out 2>actual.err &&
+       test_cmp expected actual.out &&
+       test_must_be_empty actual.err
+'
+
+test_expect_success 'env--helper reads config thanks to trace2' '
+       mkdir home &&
+       git config -f home/.gitconfig include.path cycle &&
+       git config -f home/cycle include.path .gitconfig &&
+
+       test_must_fail \
+               env HOME="$(pwd)/home" GIT_TEST_GETTEXT_POISON=false \
+               git config -l 2>err &&
+       grep "exceeded maximum include depth" err &&
+
+       test_must_fail \
+               env HOME="$(pwd)/home" GIT_TEST_GETTEXT_POISON=true \
+               git -C cycle env--helper --type=bool --default=0 --exit-code GIT_TEST_GETTEXT_POISON 2>err &&
+       grep "# GETTEXT POISON #" err
+'
+
+test_done
index a06269f38ae555f952b83b6fbc38374a725293d1..f9fa16ad8363a9e1c8611f37b5945f43ee2053c9 100755 (executable)
@@ -5,7 +5,7 @@
 
 test_description='Gettext Shell poison'
 
-GIT_TEST_GETTEXT_POISON=YesPlease
+GIT_TEST_GETTEXT_POISON=true
 export GIT_TEST_GETTEXT_POISON
 . ./lib-gettext.sh
 
@@ -31,4 +31,9 @@ test_expect_success 'eval_gettext: our eval_gettext() fallback has poison semant
     test_cmp expect actual
 '
 
+test_expect_success "gettext: invalid GIT_TEST_GETTEXT_POISON value doesn't infinitely loop" "
+       test_must_fail env GIT_TEST_GETTEXT_POISON=xyz git version 2>error &&
+       grep \"fatal: bad numeric config value 'xyz' for 'GIT_TEST_GETTEXT_POISON': invalid unit\" error
+"
+
 test_done
index 9571e366f801ea347845eef9736c92197fbdba08..d20b4d150d42c9fd6c14eb5f36e01a442d045cee 100755 (executable)
@@ -349,20 +349,13 @@ test_expect_success 'conditional include, onbranch, implicit /** for /' '
 '
 
 test_expect_success 'include cycles are detected' '
-       cat >.gitconfig <<-\EOF &&
-       [test]value = gitconfig
-       [include]path = cycle
-       EOF
-       cat >cycle <<-\EOF &&
-       [test]value = cycle
-       [include]path = .gitconfig
-       EOF
-       cat >expect <<-\EOF &&
-       gitconfig
-       cycle
-       EOF
-       test_must_fail git config --get-all test.value 2>stderr &&
-       test_i18ngrep "exceeded maximum include depth" stderr
+       git init --bare cycle &&
+       git -C cycle config include.path cycle &&
+       git config -f cycle/cycle include.path config &&
+       test_must_fail \
+               env GIT_TEST_GETTEXT_POISON=false \
+               git -C cycle config --get-all test.value 2>stderr &&
+       grep "exceeded maximum include depth" stderr
 '
 
 test_done
index e3c4a48c8536e46e0aa36b4d862b3876617335a4..43e1d8d4d2a45c5cff87d64b32ccc2814f5579e3 100755 (executable)
@@ -267,8 +267,7 @@ test_expect_success 'ls-remote --symref omits filtered-out matches' '
 '
 
 test_lazy_prereq GIT_DAEMON '
-       test_tristate GIT_TEST_GIT_DAEMON &&
-       test "$GIT_TEST_GIT_DAEMON" != false
+       git env--helper --type=bool --default=true --exit-code GIT_TEST_GIT_DAEMON
 '
 
 # This test spawns a daemon, so run it only if the user would be OK with
index febf63f28a54cd6a1e54e7322830e3ddfbfa9af3..ad1922b999b18d8437cc48c139a862ab5f59425d 100755 (executable)
@@ -38,7 +38,7 @@ test_expect_success setup '
        advance h
 '
 
-script='s/^..\(b.\) *[0-9a-f]* \(.*\)$/\1 \2/p'
+t6040_script='s/^..\(b.\) *[0-9a-f]* \(.*\)$/\1 \2/p'
 cat >expect <<\EOF
 b1 [ahead 1, behind 1] d
 b2 [ahead 1, behind 1] d
@@ -53,7 +53,7 @@ test_expect_success 'branch -v' '
                cd test &&
                git branch -v
        ) |
-       sed -n -e "$script" >actual &&
+       sed -n -e "$t6040_script" >actual &&
        test_i18ncmp expect actual
 '
 
@@ -71,7 +71,7 @@ test_expect_success 'branch -vv' '
                cd test &&
                git branch -vv
        ) |
-       sed -n -e "$script" >actual &&
+       sed -n -e "$t6040_script" >actual &&
        test_i18ncmp expect actual
 '
 
index 5990299fc9555d54a59a5de462864a7a98e83e45..b696bae5f534e82609f8dd0d27e6f9abb85cd7cc 100755 (executable)
@@ -249,7 +249,7 @@ test_expect_success 'checkout to detach HEAD (with advice declined)' '
 test_expect_success 'checkout to detach HEAD' '
        git config advice.detachedHead true &&
        git checkout -f renamer && git clean -f &&
-       GIT_TEST_GETTEXT_POISON= git checkout renamer^ 2>messages &&
+       GIT_TEST_GETTEXT_POISON=false git checkout renamer^ 2>messages &&
        grep "HEAD is now at 7329388" messages &&
        test_line_count -gt 1 messages &&
        H=$(git rev-parse --verify HEAD) &&
index 43cf313a1c09ad8fb223ba775d5548c3f00c339c..75512c340366f3034c58effb62c8796d0b1463a8 100755 (executable)
@@ -1706,7 +1706,7 @@ test_expect_success 'sourcing the completion script clears cached commands' '
 '
 
 test_expect_success 'sourcing the completion script clears cached merge strategies' '
-       GIT_TEST_GETTEXT_POISON= &&
+       GIT_TEST_GETTEXT_POISON=false &&
        __git_compute_merge_strategies &&
        verbose test -n "$__git_merge_strategies" &&
        . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
index 7308f679229044030336922515a4e2870e6451d1..27b81276fc22569249bb5e83dcf4ba95e9823a57 100644 (file)
@@ -309,7 +309,7 @@ test_unset_prereq () {
 }
 
 test_set_prereq () {
-       if test -n "$GIT_TEST_FAIL_PREREQS"
+       if test -n "$GIT_TEST_FAIL_PREREQS_INTERNAL"
        then
                case "$1" in
                # The "!" case is handled below with
@@ -1050,62 +1050,20 @@ perl () {
        command "$PERL_PATH" "$@" 2>&7
 } 7>&2 2>&4
 
-# Is the value one of the various ways to spell a boolean true/false?
-test_normalize_bool () {
-       git -c magic.variable="$1" config --bool magic.variable 2>/dev/null
-}
-
-# Given a variable $1, normalize the value of it to one of "true",
-# "false", or "auto" and store the result to it.
-#
-#     test_tristate GIT_TEST_HTTPD
-#
-# A variable set to an empty string is set to 'false'.
-# A variable set to 'false' or 'auto' keeps its value.
-# Anything else is set to 'true'.
-# An unset variable defaults to 'auto'.
-#
-# The last rule is to allow people to set the variable to an empty
-# string and export it to decline testing the particular feature
-# for versions both before and after this change.  We used to treat
-# both unset and empty variable as a signal for "do not test" and
-# took any non-empty string as "please test".
-
-test_tristate () {
-       if eval "test x\"\${$1+isset}\" = xisset"
-       then
-               # explicitly set
-               eval "
-                       case \"\$$1\" in
-                       '')     $1=false ;;
-                       auto)   ;;
-                       *)      $1=\$(test_normalize_bool \$$1 || echo true) ;;
-                       esac
-               "
-       else
-               eval "$1=auto"
-       fi
-}
-
 # Exit the test suite, either by skipping all remaining tests or by
-# exiting with an error. If "$1" is "auto", we then we assume we were
-# opportunistically trying to set up some tests and we skip. If it is
-# "true", then we report a failure.
+# exiting with an error. If our prerequisite variable $1 falls back
+# on a default assume we were opportunistically trying to set up some
+# tests and we skip. If it is explicitly "true", then we report a failure.
 #
 # The error/skip message should be given by $2.
 #
 test_skip_or_die () {
-       case "$1" in
-       auto)
+       if ! git env--helper --type=bool --default=false --exit-code $1
+       then
                skip_all=$2
                test_done
-               ;;
-       true)
-               error "$2"
-               ;;
-       *)
-               error "BUG: test tristate is '$1' (real error: $2)"
-       esac
+       fi
+       error "$2"
 }
 
 # The following mingw_* functions obey POSIX shell syntax, but are actually
index d1ba33745a24c92411baca54604c853373b9bc39..30b07e310f59493616f766ea6cf7c45a335c9258 100644 (file)
@@ -1388,6 +1388,25 @@ yes () {
        done
 }
 
+# The GIT_TEST_FAIL_PREREQS code hooks into test_set_prereq(), and
+# thus needs to be set up really early, and set an internal variable
+# for convenience so the hot test_set_prereq() codepath doesn't need
+# to call "git env--helper". Only do that work if needed by seeing if
+# GIT_TEST_FAIL_PREREQS is set at all.
+GIT_TEST_FAIL_PREREQS_INTERNAL=
+if test -n "$GIT_TEST_FAIL_PREREQS"
+then
+       if git env--helper --type=bool --default=0 --exit-code GIT_TEST_FAIL_PREREQS
+       then
+               GIT_TEST_FAIL_PREREQS_INTERNAL=true
+               test_set_prereq FAIL_PREREQS
+       fi
+else
+       test_lazy_prereq FAIL_PREREQS '
+               git env--helper --type=bool --default=0 --exit-code GIT_TEST_FAIL_PREREQS
+       '
+fi
+
 # Fix some commands on Windows
 uname_s=$(uname -s)
 case $uname_s in
@@ -1442,11 +1461,9 @@ then
        unset GIT_TEST_GETTEXT_POISON_ORIG
 fi
 
-# Can we rely on git's output in the C locale?
-if test -z "$GIT_TEST_GETTEXT_POISON"
-then
-       test_set_prereq C_LOCALE_OUTPUT
-fi
+test_lazy_prereq C_LOCALE_OUTPUT '
+       ! git env--helper --type=bool --default=0 --exit-code GIT_TEST_GETTEXT_POISON
+'
 
 if test -z "$GIT_TEST_CHECK_CACHE_TREE"
 then
@@ -1606,7 +1623,3 @@ test_lazy_prereq SHA1 '
 test_lazy_prereq REBASE_P '
        test -z "$GIT_TEST_SKIP_REBASE_P"
 '
-
-test_lazy_prereq FAIL_PREREQS '
-       test -n "$GIT_TEST_FAIL_PREREQS"
-'