test-lib-functions-tg.sh: introduce TopGit-specific test functions library
[topgit/pro.git] / t / test-lib.sh
blobf21b808cb6c34a577a859c910c269ff537b13307
1 # Test libe caching support
2 # Copyright (C) 2016,2017 Kyle J. McKay.
3 # All rights reserved.
4 # License GPLv2+
6 if [ "$1" = "--cache" ]; then
7 # export all state to $PWD/TG-TEST-CACHE
8 # then return a suitable value for 'TESTLIB_CACHE'
10 # CACHE_VARS is a list of variable names to cache but only if they
11 # are actually set.
13 # EXPORT_VARS is a list of variables that should be exported.
15 # UNSET_VARS is a list of variables that should always be unset
16 # it will automatically have unwanted GIT_XXX vars added to it
18 CACHE_VARS="GIT_MERGE_VERBOSITY GIT_MERGE_AUTOEDIT \
19 GIT_CONFIG_NOSYSTEM GIT_ATTR_NOSYSTEM GIT_TRACE_BARE \
20 debug verbose verbose_only test_count trace LANG LC_ALL \
21 TZ _x05 _x40 _z40 EMPTY_TREE EMPTY_BLOB LF u200c color \
22 immediate TESTLIB_TEST_LONG run_list help quiet \
23 say_color_error say_color_skip say_color_warn say_color_pass \
24 say_color_info say_color_ TERM BASH_XTRACEFD \
25 test_failure test_count test_fixed test_broken test_success \
26 test_external_has_tap last_verbose GIT_MINIMUM_VERSION \
27 TG_TEST_INSTALLED uname_s test_prereq TG_GIT_MINIMUM_VERSION \
28 TG_INST_BINDIR TG_INST_CMDDIR TG_INST_HOOKSDIR TG_VERSION \
29 TG_INST_SHAREDIR git_version tg_version UNAME_S \
30 lazily_tested_prereq satisfied_prereq PATH TESTLIB_TEST_CMP \
31 GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_PATH DIFF \
32 GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL GIT_TEMPLATE_DIR \
33 EMPTY_DIRECTORY EDITOR TESTLIB_DIRECTORY TEST_DIRECTORY \
34 TEST_OUTPUT_DIRECTORY PAGER root SHELL_PATH PERL_PATH \
35 TESTLIB_NO_TOLERATE TESTLIB_TEST_CHAIN_LINT"
37 EXPORT_VARS="PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM \
38 GIT_ATTR_NOSYSTEM GIT_MERGE_VERBOSITY GIT_MERGE_AUTOEDIT \
39 GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME GIT_COMMITTER_EMAIL TZ \
40 GIT_COMMITTER_NAME EDITOR GIT_TRACE_BARE LANG LC_ALL PAGER \
41 _x05 _x40 _z40 EMPTY_TREE EMPTY_BLOB LF u200c UNAME_S \
42 TERM SHELL_PATH PERL_PATH GIT_PATH DIFF TG_TEST_INSTALLED \
43 test_prereq TESTLIB_NO_TOLERATE TESTLIB_TEST_LONG \
44 GIT_CEILING_DIRECTORIES TG_FULL_PATH"
46 UNSET_VARS="VISUAL EMAIL LANGUAGE COLUMNS XDG_CONFIG_HOME GITPERLLIB \
47 CDPATH GREP_OPTIONS UNZIP TESTLIB_EXIT_OK last_verbose"
49 # strip off --cache
50 shift
52 # set UNAME_S if needed
53 : "${UNAME_S:=$(uname -s)}"
55 # run the standard init but avoid doing any --tee processing now
56 . ./test-lib-main.sh
57 TESTLIB_TEST_TEE_STARTED=done
58 test_lib_main_init_generic "$@" || exit $?
59 unset TESTLIB_TEST_TEE_STARTED
61 if [ -n "$lazily_testable_prereq" ]; then
62 # run all the "lazy" prereq tests now in a new subdir
63 # (set up on the "--root" if selected) using setup code
64 # taken (and modified) from test-lib-main.sh so that the
65 # lazy prereqs get the same answer the would when not cached
66 TRASH_DIRECTORY="cachetest"
67 test -n "$root" && TRASH_DIRECTORY="$root/$TRASH_DIRECTORY"
68 case "$TRASH_DIRECTORY" in
69 /*) ;; # absolute path is good
70 *) TRASH_DIRECTORY="$TEST_OUTPUT_DIRECTORY/$TRASH_DIRECTORY" ;;
71 esac
72 ! [ -e "$TRASH_DIRECTORY" ] || rm -fr "$TRASH_DIRECTORY" ||
73 fatal "FATAL: Cannot prepare cache test area"
74 mkdir -p "$TRASH_DIRECTORY" && [ -d "$TRASH_DIRECTORY" ] ||
75 fatal "cannot mkdir -p $TRASH_DIRECTORY"
76 savepwd="$PWD"
77 savehome="$HOME"
78 cd -P "$TRASH_DIRECTORY" || fatal "cannot cd to $TRASH_DIRECTORY"
79 git init --quiet --template="$EMPTY_DIRECTORY" >/dev/null 2>&1 ||
80 fatal "cannot run git init"
81 HOME="$TRASH_DIRECTORY"
82 GNUPGHOME="$HOME/gnupg-home-not-used"
83 export HOME GNUPGHOME
84 for lp in $lazily_testable_prereq; do
85 ! { eval "lpscript=\$test_prereq_lazily_$lp" &&
86 (t() { eval "$lpscript";}; t) >/dev/null 2>&1;} || test_set_prereq $lp
87 lazily_tested_prereq="$lazily_tested_prereq$lp "
88 done
89 HOME="$savehome"
90 cd "$savepwd" || fatal "cannot cd to $savepwd"
91 rm -rf "$TRASH_DIRECTORY"
92 unset savepwd savehome TRASH_DIRECTORY GNUPGHOME
95 # Add most GIT_XXX vars (variation of code from test-lib-main.sh)
96 UNSET_VARS="$UNSET_VARS $("$PERL_PATH" -e '
97 my @env = keys %ENV;
98 my $ok = join("|", qw(
99 TRACE
100 DEBUG
101 USE_LOOKUP
102 TEST
103 .*_TEST
104 MINIMUM_VERSION
105 PATH
106 PROVE
107 UNZIP
108 PERF_
109 CURL_VERBOSE
110 TRACE_CURL
111 CEILING_DIRECTORIES
113 my @vars = grep(/^GIT_/ && !/^GIT_($ok)/o, @env);
114 print join(" ", @vars);
117 # stores the single-quoted value of the variable name passed as
118 # the first argument into the variable name passed as the second
119 # (use quotevar 3 varname "$value" to quote a value directly)
120 quotevar() {
121 eval "set -- \"\${$1}\" \"$2\""
122 case "$1" in *"'"*)
123 set -- "$(printf '%s\nZ\n' "$1" | sed "s/'/'\\\''/g")" "$2"
124 set -- "${1%??}" "$2"
125 esac
126 eval "$2=\"'$1'\""
128 # return true if variable name passed as the first argument is
129 # set even if to an empty value
130 isvarset() {
131 eval "test \"z\${$1+set}\" = \"zset\""
133 quotevar PWD PWD_SQ
134 quotevar TESTLIB_DIRECTORY TD_SQ
136 echo unset $UNSET_VARS "&&"
137 while read vname && [ -n "$vname" ]; do
138 ! isvarset $vname || { quotevar "$vname" qv; printf '%s=%s &&\n' "$vname" "$qv"; }
139 done <<-EOT
140 $(echo $CACHE_VARS $EXPORT_VARS | LC_ALL=C sed 'y/ /\n/' | LC_ALL=C sort -u)
141 say_color_reset
143 echo export $EXPORT_VARS "&&"
144 printf '%s\n' \
145 "cd $PWD_SQ &&" \
146 ". $TD_SQ/test-lib-functions-tg.sh &&" \
147 ". $TD_SQ/test-lib-functions.sh &&" \
148 ". $TD_SQ/test-lib-main.sh &&"
149 echo "TESTLIB_CACHE_ACTIVE=1"
150 } >TG-TEST-CACHE
151 printf ". %s/TG-TEST-CACHE || { echo 'error: missing '\'%s'/TG-TEST-CACHE'\' >&2; exit 1; }\n" "$PWD_SQ" "$PWD_SQ"
152 TESTLIB_EXIT_OK=1
153 exit 0
156 # usage: whats_the_dir [-P | -L] [--] path-to-something varname
157 # determine path-to-something's directory and store it into varname
158 # without "-P" or "-L" a relative dirname may be returned
159 whats_the_dir() {
160 # determine "$1"'s directory and store it into the var name passed as "$2"
161 if [ "z$1" = "z-P" -o "z$1" = "z-L" ]; then
162 if [ "z$2" = "z--" ]; then
163 set -- "$3" "$4" "$1"
164 else
165 set -- "$2" "$3" "$1"
167 elif [ "z$1" = "z--" ]; then
168 shift
170 case "$1" in *"/"*);;*) set -- "./$1" "$2" "$3"; esac
171 while [ -L "$1" ]; do
172 set -- "$(readlink "$1")" "$2" "$3" "$1"
173 case "$1" in "/"*);;*)
174 set -- "${4%/*}/$1" "$2" "$3"
175 esac
176 done
177 set -- "${1%/*}" "$2" "$3"
178 if [ "z$3" != "z" ] && [ -d "$1" ] &&
179 ! case "$1" in [!/]*|*"/./"*|*"/."|*"/../"*|*"/..") ! :; esac; then
180 [ "z$3" = "z-P" ] || set -- "$1" "$2"
181 if [ "z$3" = "z" -a \( "z$1" = "z." -o "z$1" = "z$PWD" \) ]; then
182 set -- "$PWD" "$2"
183 else
184 set -- "$(cd "$1" && pwd $3)" "$2"
187 eval "$2=\"$1\""
190 [ -z "$TESTLIB_CACHE" ] || eval "$TESTLIB_CACHE" || exit $?
191 if [ -n "$TESTLIB_CACHE_ACTIVE" ]; then
192 # Everything should have been restored by the eval of "$TESTLIB_CACHE"
193 # Remove the leftover variables used to trigger use of the cache
194 unset TESTLIB_CACHE TESTLIB_CACHE_ACTIVE
196 # Handle --tee now if needed
197 test_lib_main_init_tee "$@"
199 # We must also still perform per-test initialization though
200 test_lib_main_init_specific "$@"
201 else
202 # Normal, non-cached case where we run the init function
203 whats_the_dir -- "${TEST_DIRECTORY:-.}/test-lib.sh" testlib_dir_
204 . "$testlib_dir_/test-lib-main.sh" &&
205 unset _testlib_dir_ &&
206 test_lib_main_init "$@"