Skip to content

Commit

Permalink
Merge branch "ab/test-env"
Browse files Browse the repository at this point in the history
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
  • Loading branch information
gitster committed Jul 25, 2019
2 parents 9c9b961 + 08a8ac8 commit 023ff4c
Show file tree
Hide file tree
Showing 24 changed files with 298 additions and 127 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
/git-difftool
/git-difftool--helper
/git-describe
/git-env--helper
/git-fast-export
/git-fast-import
/git-fetch
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions builtin.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
95 changes: 95 additions & 0 deletions builtin/env--helper.c
Original file line number Diff line number Diff line change
@@ -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;
}
2 changes: 1 addition & 1 deletion ci/lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
28 changes: 19 additions & 9 deletions config.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}

Expand Down
6 changes: 2 additions & 4 deletions gettext.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
4 changes: 3 additions & 1 deletion git-sh-i18n.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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@@"
Expand Down
1 change: 1 addition & 0 deletions git.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
Expand Down
2 changes: 1 addition & 1 deletion po/README
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 6 additions & 6 deletions t/README
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand All @@ -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.
Expand Down
7 changes: 3 additions & 4 deletions t/lib-git-daemon.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,15 @@
#
# 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
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
Expand Down Expand Up @@ -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
}
Expand Down
11 changes: 4 additions & 7 deletions t/lib-git-svn.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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 () {
Expand Down Expand Up @@ -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
Expand Down
15 changes: 7 additions & 8 deletions t/lib-httpd.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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 | \
Expand All @@ -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

Expand Down Expand Up @@ -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
}

Expand Down
Loading

0 comments on commit 023ff4c

Please sign in to comment.