From: Johannes Schindelin <Johannes.Schindelin@gmx.de>
To: Johannes Schindelin via GitGitGadget <gitgitgadget@gmail.com>
Cc: git@vger.kernel.org
Subject: Re: [PATCH] tests: replace mingw_test_cmp with a helper in C
Date: Fri, 29 Jul 2022 16:54:47 +0200 (CEST) [thread overview]
Message-ID: <06n1s2n7-o827-0244-50s2-rrq50s42oqn5@tzk.qr> (raw)
In-Reply-To: <pull.1309.git.1659106382128.gitgitgadget@gmail.com>
Hi,
On Fri, 29 Jul 2022, Johannes Schindelin via GitGitGadget wrote:
> From: Johannes Schindelin <johannes.schindelin@gmx.de>
>
> This helper is more performant than running the `mingw_test_cmp` code
> with with MSYS2's Bash. And a lot more readable.
Ooops... s/with with/with/
Ciao,
Dscho
>
> 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 <johannes.schindelin@gmx.de>
> ---
> tests: replace mingw_test_cmp with a helper in C
>
> On the heels of sending a patch to fix a performance regression due to a
> mis-use of test_cmp
> [https://lore.kernel.org/git/b9203ea247776332e4b6f519aa27d541207adc2f.1659097724.git.gitgitgadget@gmail.com/],
> I was curious to see whether Git for Windows had the same issue. And it
> does not
> [https://github.com/git-for-windows/git/runs/7556381815?check_suite_focus=true#step:5:127]:
> it passes t5351 in 22 seconds, even while using test_cmp to compare pack
> files
> [https://github.com/git-for-windows/git/blob/3922f62f0d5991e9fe0a0817ebf89a91339c7705/t/t5351-unpack-large-objects.sh#L90].
>
> The answer is of course that a test helper written in C is much faster
> than writing the same in Bash, especially on Windows. This is especially
> sad when said Bash code is only used on Windows. So I pulled out this
> helper from the years-long effort to let Git for Windows use BusyBox'
> ash to run the test suite. The result is this patch, which has been in
> Git for Windows since June 2018.
>
> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1309%2Fdscho%2Fmingw-test-cmp-v1
> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1309/dscho/mingw-test-cmp-v1
> Pull-Request: https://github.com/gitgitgadget/git/pull/1309
>
> Makefile | 1 +
> t/helper/test-cmp.c | 73 +++++++++++++++++++++++++++++++++++++++++
> t/helper/test-tool.c | 1 +
> t/helper/test-tool.h | 1 +
> t/test-lib-functions.sh | 68 +-------------------------------------
> t/test-lib.sh | 2 +-
> 6 files changed, 78 insertions(+), 68 deletions(-)
> create mode 100644 t/helper/test-cmp.c
>
> diff --git a/Makefile b/Makefile
> index 1624471badc..45f108e43a1 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -723,6 +723,7 @@ TEST_BUILTINS_OBJS += test-advise.o
> TEST_BUILTINS_OBJS += test-bitmap.o
> TEST_BUILTINS_OBJS += test-bloom.o
> TEST_BUILTINS_OBJS += test-chmtime.o
> +TEST_BUILTINS_OBJS += test-cmp.o
> TEST_BUILTINS_OBJS += test-config.o
> TEST_BUILTINS_OBJS += test-crontab.o
> TEST_BUILTINS_OBJS += test-csprng.o
> diff --git a/t/helper/test-cmp.c b/t/helper/test-cmp.c
> new file mode 100644
> index 00000000000..1c646a54bf6
> --- /dev/null
> +++ b/t/helper/test-cmp.c
> @@ -0,0 +1,73 @@
> +#include "test-tool.h"
> +#include "git-compat-util.h"
> +#include "strbuf.h"
> +#include "gettext.h"
> +#include "parse-options.h"
> +#include "run-command.h"
> +
> +#ifdef WIN32
> +#define NO_SUCH_DIR "\\\\.\\GLOBALROOT\\invalid"
> +#else
> +#define NO_SUCH_DIR "/dev/null"
> +#endif
> +
> +static int run_diff(const char *path1, const char *path2)
> +{
> + const char *argv[] = {
> + "diff", "--no-index", NULL, NULL, NULL
> + };
> + const char *env[] = {
> + "GIT_PAGER=cat",
> + "GIT_DIR=" NO_SUCH_DIR,
> + "HOME=" NO_SUCH_DIR,
> + NULL
> + };
> +
> + argv[2] = path1;
> + argv[3] = path2;
> + return run_command_v_opt_cd_env(argv,
> + RUN_COMMAND_NO_STDIN | RUN_GIT_CMD,
> + NULL, env);
> +}
> +
> +int cmd__cmp(int argc, const char **argv)
> +{
> + FILE *f0, *f1;
> + struct strbuf b0 = STRBUF_INIT, b1 = STRBUF_INIT;
> +
> + if (argc != 3)
> + die("Require exactly 2 arguments, got %d", argc);
> +
> + if (!(f0 = !strcmp(argv[1], "-") ? stdin : fopen(argv[1], "r")))
> + return error_errno("could not open '%s'", argv[1]);
> + if (!(f1 = !strcmp(argv[2], "-") ? stdin : fopen(argv[2], "r"))) {
> + fclose(f0);
> + return error_errno("could not open '%s'", argv[2]);
> + }
> +
> + for (;;) {
> + int r0 = strbuf_getline(&b0, f0);
> + int r1 = strbuf_getline(&b1, f1);
> +
> + if (r0 == EOF) {
> + fclose(f0);
> + fclose(f1);
> + strbuf_release(&b0);
> + strbuf_release(&b1);
> + if (r1 == EOF)
> + return 0;
> +cmp_failed:
> + if (!run_diff(argv[1], argv[2]))
> + die("Huh? 'diff --no-index %s %s' succeeded",
> + argv[1], argv[2]);
> + return 1;
> + }
> + if (r1 == EOF || strbuf_cmp(&b0, &b1)) {
> + fclose(f0);
> + fclose(f1);
> + strbuf_release(&b0);
> + strbuf_release(&b1);
> + goto cmp_failed;
> + }
> + }
> +}
> diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
> index 318fdbab0c3..3334de248a1 100644
> --- a/t/helper/test-tool.c
> +++ b/t/helper/test-tool.c
> @@ -18,6 +18,7 @@ static struct test_cmd cmds[] = {
> { "bitmap", cmd__bitmap },
> { "bloom", cmd__bloom },
> { "chmtime", cmd__chmtime },
> + { "cmp", cmd__cmp },
> { "config", cmd__config },
> { "crontab", cmd__crontab },
> { "csprng", cmd__csprng },
> diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
> index bb799271631..e1104898cc3 100644
> --- a/t/helper/test-tool.h
> +++ b/t/helper/test-tool.h
> @@ -8,6 +8,7 @@ int cmd__advise_if_enabled(int argc, const char **argv);
> int cmd__bitmap(int argc, const char **argv);
> int cmd__bloom(int argc, const char **argv);
> int cmd__chmtime(int argc, const char **argv);
> +int cmd__cmp(int argc, const char **argv);
> int cmd__config(int argc, const char **argv);
> int cmd__crontab(int argc, const char **argv);
> int cmd__csprng(int argc, const char **argv);
> diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
> index 8c44856eaec..28eddbc8e36 100644
> --- a/t/test-lib-functions.sh
> +++ b/t/test-lib-functions.sh
> @@ -1240,7 +1240,7 @@ test_expect_code () {
>
> test_cmp () {
> test "$#" -ne 2 && BUG "2 param"
> - eval "$GIT_TEST_CMP" '"$@"'
> + GIT_ALLOC_LIMIT=0 eval "$GIT_TEST_CMP" '"$@"'
> }
>
> # Check that the given config key has the expected value.
> @@ -1541,72 +1541,6 @@ test_skip_or_die () {
> error "$2"
> }
>
> -# The following mingw_* functions obey POSIX shell syntax, but are actually
> -# bash scripts, and are meant to be used only with bash on Windows.
> -
> -# A test_cmp function that treats LF and CRLF equal and avoids to fork
> -# diff when possible.
> -mingw_test_cmp () {
> - # Read text into shell variables and compare them. If the results
> - # are different, use regular diff to report the difference.
> - local test_cmp_a= test_cmp_b=
> -
> - # When text came from stdin (one argument is '-') we must feed it
> - # to diff.
> - local stdin_for_diff=
> -
> - # Since it is difficult to detect the difference between an
> - # empty input file and a failure to read the files, we go straight
> - # to diff if one of the inputs is empty.
> - if test -s "$1" && test -s "$2"
> - then
> - # regular case: both files non-empty
> - mingw_read_file_strip_cr_ test_cmp_a <"$1"
> - mingw_read_file_strip_cr_ test_cmp_b <"$2"
> - elif test -s "$1" && test "$2" = -
> - then
> - # read 2nd file from stdin
> - mingw_read_file_strip_cr_ test_cmp_a <"$1"
> - mingw_read_file_strip_cr_ test_cmp_b
> - stdin_for_diff='<<<"$test_cmp_b"'
> - elif test "$1" = - && test -s "$2"
> - then
> - # read 1st file from stdin
> - mingw_read_file_strip_cr_ test_cmp_a
> - mingw_read_file_strip_cr_ test_cmp_b <"$2"
> - stdin_for_diff='<<<"$test_cmp_a"'
> - fi
> - test -n "$test_cmp_a" &&
> - test -n "$test_cmp_b" &&
> - test "$test_cmp_a" = "$test_cmp_b" ||
> - eval "diff -u \"\$@\" $stdin_for_diff"
> -}
> -
> -# $1 is the name of the shell variable to fill in
> -mingw_read_file_strip_cr_ () {
> - # Read line-wise using LF as the line separator
> - # and use IFS to strip CR.
> - local line
> - while :
> - do
> - if IFS=$'\r' read -r -d $'\n' line
> - then
> - # good
> - line=$line$'\n'
> - else
> - # we get here at EOF, but also if the last line
> - # was not terminated by LF; in the latter case,
> - # some text was read
> - if test -z "$line"
> - then
> - # EOF, really
> - break
> - fi
> - fi
> - eval "$1=\$$1\$line"
> - done
> -}
> -
> # Like "env FOO=BAR some-program", but run inside a subshell, which means
> # it also works for shell functions (though those functions cannot impact
> # the environment outside of the test_env invocation).
> diff --git a/t/test-lib.sh b/t/test-lib.sh
> index 7726d1da88a..220c259e796 100644
> --- a/t/test-lib.sh
> +++ b/t/test-lib.sh
> @@ -1546,7 +1546,7 @@ case $uname_s in
> test_set_prereq SED_STRIPS_CR
> test_set_prereq GREP_STRIPS_CR
> test_set_prereq WINDOWS
> - GIT_TEST_CMP=mingw_test_cmp
> + GIT_TEST_CMP="test-tool cmp"
> ;;
> *CYGWIN*)
> test_set_prereq POSIXPERM
>
> base-commit: 23b219f8e3f2adfb0441e135f0a880e6124f766c
> --
> gitgitgadget
>
>
next prev parent reply other threads:[~2022-07-29 14:54 UTC|newest]
Thread overview: 58+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-29 14:53 [PATCH] tests: replace mingw_test_cmp with a helper in C Johannes Schindelin via GitGitGadget
2022-07-29 14:54 ` Johannes Schindelin [this message]
2022-07-29 16:44 ` Junio C Hamano
2022-09-06 13:10 ` Johannes Schindelin
2022-09-07 12:09 ` René Scharfe
2022-09-07 16:25 ` Junio C Hamano
2022-09-07 21:45 ` Re* " Junio C Hamano
2022-09-07 22:39 ` René Scharfe
2022-09-08 0:03 ` Junio C Hamano
2022-09-08 8:59 ` René Scharfe
2022-09-08 15:26 ` Ævar Arnfjörð Bjarmason
2022-09-08 20:54 ` Johannes Schindelin
2022-09-08 21:09 ` Junio C Hamano
2022-09-06 13:10 ` [PATCH v2 0/2] " Johannes Schindelin via GitGitGadget
2022-09-06 13:10 ` [PATCH v2 1/2] t0021: use Windows-friendly `pwd` Johannes Schindelin via GitGitGadget
2022-09-06 13:10 ` [PATCH v2 2/2] tests: replace mingw_test_cmp with a helper in C Johannes Schindelin via GitGitGadget
2022-09-07 11:57 ` Ævar Arnfjörð Bjarmason
2022-09-07 12:24 ` Ævar Arnfjörð Bjarmason
2022-09-07 19:45 ` Junio C Hamano
2022-09-07 9:04 ` [PATCH v2 0/2] " Johannes Schindelin
2022-11-12 22:07 ` [PATCH v3 " Johannes Schindelin via GitGitGadget
2022-11-12 22:07 ` [PATCH v3 1/2] t0021: use Windows-friendly `pwd` Johannes Schindelin via GitGitGadget
2022-11-12 22:07 ` [PATCH v3 2/2] tests(mingw): avoid very slow `mingw_test_cmp` Johannes Schindelin via GitGitGadget
2022-11-13 4:51 ` Taylor Blau
2022-11-14 13:34 ` Johannes Schindelin
2022-11-18 23:15 ` Junio C Hamano
2022-11-19 2:53 ` Taylor Blau
2022-11-19 12:03 ` Ævar Arnfjörð Bjarmason
2022-11-19 8:18 ` Johannes Sixt
2022-11-19 17:50 ` René Scharfe
2022-11-20 9:29 ` Torsten Bögershausen
2022-11-21 17:49 ` Johannes Sixt
2022-11-21 3:13 ` Junio C Hamano
2022-11-14 9:53 ` Phillip Wood
2022-11-14 13:47 ` Johannes Schindelin
2022-11-14 11:55 ` Ævar Arnfjörð Bjarmason
2022-11-14 14:02 ` Johannes Schindelin
2022-11-14 15:23 ` Ævar Arnfjörð Bjarmason
2022-11-18 23:19 ` Junio C Hamano
2022-11-19 2:56 ` Taylor Blau
2022-11-19 11:54 ` Ævar Arnfjörð Bjarmason
2022-11-21 3:17 ` Junio C Hamano
2022-11-14 14:06 ` [PATCH v4 0/2] tests(mingw): avoid super-slow mingw_test_cmp Johannes Schindelin via GitGitGadget
2022-11-14 14:06 ` [PATCH v4 1/2] t0021: use Windows-friendly `pwd` Johannes Schindelin via GitGitGadget
2022-11-14 14:06 ` [PATCH v4 2/2] tests(mingw): avoid very slow `mingw_test_cmp` Johannes Schindelin via GitGitGadget
2022-11-14 22:40 ` Taylor Blau
2022-11-18 13:32 ` Johannes Schindelin
2022-11-18 18:14 ` Taylor Blau
2022-11-20 23:36 ` Johannes Schindelin
2022-11-21 0:07 ` Taylor Blau
2022-12-06 15:07 ` [PATCH v5 0/2] tests(mingw): avoid super-slow mingw_test_cmp Johannes Schindelin via GitGitGadget
2022-12-06 15:07 ` [PATCH v5 1/2] t0021: use Windows-friendly `pwd` Johannes Schindelin via GitGitGadget
2022-12-06 15:07 ` [PATCH v5 2/2] tests(mingw): avoid very slow `mingw_test_cmp` Johannes Schindelin via GitGitGadget
2022-12-06 18:55 ` Ævar Arnfjörð Bjarmason
2022-12-06 21:52 ` Johannes Sixt
2022-12-06 21:54 ` René Scharfe
2022-12-07 4:33 ` Junio C Hamano
2022-12-07 1:31 ` Taylor Blau
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=06n1s2n7-o827-0244-50s2-rrq50s42oqn5@tzk.qr \
--to=johannes.schindelin@gmx.de \
--cc=git@vger.kernel.org \
--cc=gitgitgadget@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).