Skip to content

Commit e9893db

Browse files
committed
tests: replace mingw_test_cmp with a helper in C
This helper is slightly more performant than the script with MSYS2's Bash. And a lot more readable. To accommodate t1050, which wants to compare files weighing in with 3MB (falling outside of t1050's malloc limit of 1.5MB), we simply lift the allocation limit by setting the environment variable GIT_ALLOC_LIMIT to zero when calling the helper. Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 781826d commit e9893db

File tree

6 files changed

+71
-68
lines changed

6 files changed

+71
-68
lines changed

Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,7 @@ TEST_BUILTINS_OBJS += test-bloom.o
789789
TEST_BUILTINS_OBJS += test-bundle-uri.o
790790
TEST_BUILTINS_OBJS += test-cache-tree.o
791791
TEST_BUILTINS_OBJS += test-chmtime.o
792+
TEST_BUILTINS_OBJS += test-cmp.o
792793
TEST_BUILTINS_OBJS += test-config.o
793794
TEST_BUILTINS_OBJS += test-crontab.o
794795
TEST_BUILTINS_OBJS += test-csprng.o

t/helper/test-cmp.c

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#include "test-tool.h"
2+
#include "git-compat-util.h"
3+
#include "strbuf.h"
4+
#include "gettext.h"
5+
#include "parse-options.h"
6+
#include "run-command.h"
7+
8+
#ifdef WIN32
9+
#define NO_SUCH_DIR "\\\\.\\GLOBALROOT\\invalid"
10+
#else
11+
#define NO_SUCH_DIR "/dev/null"
12+
#endif
13+
14+
static int run_diff(const char *path1, const char *path2)
15+
{
16+
struct child_process cmd = CHILD_PROCESS_INIT;
17+
18+
cmd.git_cmd = 1;
19+
cmd.no_stdin = 1;
20+
strvec_pushl(&cmd.args, "diff", "--no-index", path1, path2, NULL);
21+
strvec_pushl(&cmd.env, "GIT_PAGER=cat", "GIT_DIR=" NO_SUCH_DIR,
22+
"HOME=" NO_SUCH_DIR, NULL);
23+
return run_command(&cmd);
24+
}
25+
26+
int cmd__cmp(int argc, const char **argv)
27+
{
28+
FILE *f0, *f1;
29+
struct strbuf b0 = STRBUF_INIT, b1 = STRBUF_INIT;
30+
31+
if (argc != 3)
32+
die("Require exactly 2 arguments, got %d", argc);
33+
34+
if (!(f0 = !strcmp(argv[1], "-") ? stdin : fopen(argv[1], "r")))
35+
return error_errno("could not open '%s'", argv[1]);
36+
if (!(f1 = !strcmp(argv[2], "-") ? stdin : fopen(argv[2], "r"))) {
37+
fclose(f0);
38+
return error_errno("could not open '%s'", argv[2]);
39+
}
40+
41+
for (;;) {
42+
int r0 = strbuf_getline(&b0, f0);
43+
int r1 = strbuf_getline(&b1, f1);
44+
45+
if (r0 == EOF) {
46+
fclose(f0);
47+
fclose(f1);
48+
strbuf_release(&b0);
49+
strbuf_release(&b1);
50+
if (r1 == EOF)
51+
return 0;
52+
cmp_failed:
53+
if (!run_diff(argv[1], argv[2]))
54+
die("Huh? 'diff --no-index %s %s' succeeded",
55+
argv[1], argv[2]);
56+
return 1;
57+
}
58+
if (r1 == EOF || strbuf_cmp(&b0, &b1)) {
59+
fclose(f0);
60+
fclose(f1);
61+
strbuf_release(&b0);
62+
strbuf_release(&b1);
63+
goto cmp_failed;
64+
}
65+
}
66+
}

t/helper/test-tool.c

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ static struct test_cmd cmds[] = {
1616
{ "bundle-uri", cmd__bundle_uri },
1717
{ "cache-tree", cmd__cache_tree },
1818
{ "chmtime", cmd__chmtime },
19+
{ "cmp", cmd__cmp },
1920
{ "config", cmd__config },
2021
{ "crontab", cmd__crontab },
2122
{ "csprng", cmd__csprng },

t/helper/test-tool.h

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ int cmd__bloom(int argc, const char **argv);
99
int cmd__bundle_uri(int argc, const char **argv);
1010
int cmd__cache_tree(int argc, const char **argv);
1111
int cmd__chmtime(int argc, const char **argv);
12+
int cmd__cmp(int argc, const char **argv);
1213
int cmd__config(int argc, const char **argv);
1314
int cmd__crontab(int argc, const char **argv);
1415
int cmd__csprng(int argc, const char **argv);

t/test-lib-functions.sh

+1-67
Original file line numberDiff line numberDiff line change
@@ -1149,7 +1149,7 @@ test_expect_code () {
11491149

11501150
test_cmp () {
11511151
test "$#" -ne 2 && BUG "2 param"
1152-
eval "$GIT_TEST_CMP" '"$@"'
1152+
GIT_ALLOC_LIMIT=0 eval "$GIT_TEST_CMP" '"$@"'
11531153
}
11541154

11551155
# Check that the given config key has the expected value.
@@ -1450,72 +1450,6 @@ test_skip_or_die () {
14501450
error "$2"
14511451
}
14521452

1453-
# The following mingw_* functions obey POSIX shell syntax, but are actually
1454-
# bash scripts, and are meant to be used only with bash on Windows.
1455-
1456-
# A test_cmp function that treats LF and CRLF equal and avoids to fork
1457-
# diff when possible.
1458-
mingw_test_cmp () {
1459-
# Read text into shell variables and compare them. If the results
1460-
# are different, use regular diff to report the difference.
1461-
local test_cmp_a= test_cmp_b=
1462-
1463-
# When text came from stdin (one argument is '-') we must feed it
1464-
# to diff.
1465-
local stdin_for_diff=
1466-
1467-
# Since it is difficult to detect the difference between an
1468-
# empty input file and a failure to read the files, we go straight
1469-
# to diff if one of the inputs is empty.
1470-
if test -s "$1" && test -s "$2"
1471-
then
1472-
# regular case: both files non-empty
1473-
mingw_read_file_strip_cr_ test_cmp_a <"$1"
1474-
mingw_read_file_strip_cr_ test_cmp_b <"$2"
1475-
elif test -s "$1" && test "$2" = -
1476-
then
1477-
# read 2nd file from stdin
1478-
mingw_read_file_strip_cr_ test_cmp_a <"$1"
1479-
mingw_read_file_strip_cr_ test_cmp_b
1480-
stdin_for_diff='<<<"$test_cmp_b"'
1481-
elif test "$1" = - && test -s "$2"
1482-
then
1483-
# read 1st file from stdin
1484-
mingw_read_file_strip_cr_ test_cmp_a
1485-
mingw_read_file_strip_cr_ test_cmp_b <"$2"
1486-
stdin_for_diff='<<<"$test_cmp_a"'
1487-
fi
1488-
test -n "$test_cmp_a" &&
1489-
test -n "$test_cmp_b" &&
1490-
test "$test_cmp_a" = "$test_cmp_b" ||
1491-
eval "diff -u \"\$@\" $stdin_for_diff"
1492-
}
1493-
1494-
# $1 is the name of the shell variable to fill in
1495-
mingw_read_file_strip_cr_ () {
1496-
# Read line-wise using LF as the line separator
1497-
# and use IFS to strip CR.
1498-
local line
1499-
while :
1500-
do
1501-
if IFS=$'\r' read -r -d $'\n' line
1502-
then
1503-
# good
1504-
line=$line$'\n'
1505-
else
1506-
# we get here at EOF, but also if the last line
1507-
# was not terminated by LF; in the latter case,
1508-
# some text was read
1509-
if test -z "$line"
1510-
then
1511-
# EOF, really
1512-
break
1513-
fi
1514-
fi
1515-
eval "$1=\$$1\$line"
1516-
done
1517-
}
1518-
15191453
# Like "env FOO=BAR some-program", but run inside a subshell, which means
15201454
# it also works for shell functions (though those functions cannot impact
15211455
# the environment outside of the test_env invocation).

t/test-lib.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -1716,7 +1716,7 @@ case $uname_s in
17161716
test_set_prereq SED_STRIPS_CR
17171717
test_set_prereq GREP_STRIPS_CR
17181718
test_set_prereq WINDOWS
1719-
GIT_TEST_CMP=mingw_test_cmp
1719+
GIT_TEST_CMP="test-tool cmp"
17201720
;;
17211721
*CYGWIN*)
17221722
test_set_prereq POSIXPERM

0 commit comments

Comments
 (0)