Subject: [PATCH] test: make SYMLINKS prerequisite more robust

From: Junio C Hamano <[email-masked]>
Date: Wed, 08 Feb 2023 11:40:04 -0800

I see many failures around SYMLINKS prerequisite in Windows tests.
There are too many to point at, but the pattern seems to be the
same.  Here is one example:

  https://github.com/git/git/actions/runs/4127147009/jobs/7130175639#step:5:502

where "ln -s x y && test -h y" succeeds and declares SYMLINKS
lazy prerequisite is satisfied, but then it fails to run

	"ln -s unrelated DS && git update-index --add DS"

with:

	error: readlink("DS"): Function not implemented

I wonder if something like this is in order?

----- >8 -----

We should not just ensure "ln -s" and "test -h" works, but readlink
yields the expected value.

Signed-off-by: Junio C Hamano <[email-masked]>
---
 Makefile                 |  1 +
 t/helper/test-readlink.c | 19 +++++++++++++++++++
 t/helper/test-tool.c     |  1 +
 t/helper/test-tool.h     |  1 +
 t/test-lib.sh            |  3 ++-
 5 files changed, 24 insertions(+), 1 deletion(-)
 create mode 100644 t/helper/test-readlink.c

diff --git a/Makefile b/Makefile
index 45bd6ac9c3..2261e56d31 100644
--- a/Makefile
+++ b/Makefile
@@ -837,6 +837,7 @@ TEST_BUILTINS_OBJS += test-reach.o
 TEST_BUILTINS_OBJS += test-read-cache.o
 TEST_BUILTINS_OBJS += test-read-graph.o
 TEST_BUILTINS_OBJS += test-read-midx.o
+TEST_BUILTINS_OBJS += test-readlink.o
 TEST_BUILTINS_OBJS += test-ref-store.o
 TEST_BUILTINS_OBJS += test-reftable.o
 TEST_BUILTINS_OBJS += test-regex.o
diff --git a/t/helper/test-readlink.c b/t/helper/test-readlink.c
new file mode 100644
index 0000000000..c300dc8a1a
--- /dev/null
+++ b/t/helper/test-readlink.c
@@ -0,0 +1,19 @@
+#include "test-tool.h"
+#include "strbuf.h"
+
+static const char *usage_msg = "test-tool readlink file";
+
+int cmd__readlink(int ac, const char **av)
+{
+	struct strbuf buf;
+	int ret;
+
+	if (ac != 2 || !av[1])
+		usage(usage_msg);
+
+	ret = strbuf_readlink(&buf, av[1], 0);
+	if (!ret)
+		printf("%s\n", buf.buf);
+	strbuf_release(&buf);
+	return ret;
+}
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index abe8a785eb..12054d13d4 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -64,6 +64,7 @@ static struct test_cmd cmds[] = {
 	{ "read-cache", cmd__read_cache },
 	{ "read-graph", cmd__read_graph },
 	{ "read-midx", cmd__read_midx },
+	{ "readlink", cmd__readlink },
 	{ "ref-store", cmd__ref_store },
 	{ "reftable", cmd__reftable },
 	{ "rot13-filter", cmd__rot13_filter },
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index ea2672436c..efe382d48e 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -57,6 +57,7 @@ int cmd__reach(int argc, const char **argv);
 int cmd__read_cache(int argc, const char **argv);
 int cmd__read_graph(int argc, const char **argv);
 int cmd__read_midx(int argc, const char **argv);
+int cmd__readlink(int argc, const char **argv);
 int cmd__ref_store(int argc, const char **argv);
 int cmd__rot13_filter(int argc, const char **argv);
 int cmd__reftable(int argc, const char **argv);
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 01e88781dd..c8094f643b 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -1773,7 +1773,8 @@ test_lazy_prereq PIPE '
 
 test_lazy_prereq SYMLINKS '
 	# test whether the filesystem supports symbolic links
-	ln -s x y && test -h y
+	ln -s x y && test -h y && test-tool readlink y >/dev/null &&
+	test "$(test-tool readlink y)" = x
 '
 
 test_lazy_prereq SYMLINKS_WINDOWS '
-- 
2.39.1-418-g7876265d61