t0051: test GIT_TRACE to a windows named pipe

Create a test-tool helper to create the server side of a windows named pipe, wait for a client connection, and copy data written to the pipe to stdout. Create t0051 test to route GIT_TRACE output of a command to a named pipe using the above test-tool helper. Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff Hostetler committed Sep 11, 2018 at 13:06 UTC 06ba9d03e34ffb5fe3ca71343ceef925a447771b
5 files changed +96
Makefile
+1
@@ -731,6 +731,7 @@ TEST_BUILTINS_OBJS += test-submodule-config.o
731 TEST_BUILTINS_OBJS += test-subprocess.o
732 TEST_BUILTINS_OBJS += test-urlmatch-normalization.o
733 TEST_BUILTINS_OBJS += test-wildmatch.o
734 +TEST_BUILTINS_OBJS += test-windows-named-pipe.o
735 TEST_BUILTINS_OBJS += test-write-cache.o
736
737 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
t/helper/test-tool.c
+3
@@ -41,6 +41,9 @@ static struct test_cmd cmds[] = {
41 { "subprocess", cmd__subprocess },
42 { "urlmatch-normalization", cmd__urlmatch_normalization },
43 { "wildmatch", cmd__wildmatch },
44 +#ifdef GIT_WINDOWS_NATIVE
45 + { "windows-named-pipe", cmd__windows_named_pipe },
46 +#endif
47 { "write-cache", cmd__write_cache },
48 };
49
t/helper/test-tool.h
+3
@@ -35,6 +35,9 @@ int cmd__submodule_config(int argc, const char **argv);
35 int cmd__subprocess(int argc, const char **argv);
36 int cmd__urlmatch_normalization(int argc, const char **argv);
37 int cmd__wildmatch(int argc, const char **argv);
38 +#ifdef GIT_WINDOWS_NATIVE
39 +int cmd__windows_named_pipe(int argc, const char **argv);
40 +#endif
41 int cmd__write_cache(int argc, const char **argv);
42
43 #endif
t/helper/test-windows-named-pipe.c new
+72
@@ -0,0 +1,72 @@
1 +#include "test-tool.h"
2 +#include "git-compat-util.h"
3 +#include "strbuf.h"
4 +
5 +#ifdef GIT_WINDOWS_NATIVE
6 +static const char *usage_string = "<pipe-filename>";
7 +
8 +#define TEST_BUFSIZE (4096)
9 +
10 +int cmd__windows_named_pipe(int argc, const char **argv)
11 +{
12 + const char *filename;
13 + struct strbuf pathname = STRBUF_INIT;
14 + int err;
15 + HANDLE h;
16 + BOOL connected;
17 + char buf[TEST_BUFSIZE + 1];
18 +
19 + if (argc < 2)
20 + goto print_usage;
21 + filename = argv[1];
22 + if (strchr(filename, '/') || strchr(filename, '\\'))
23 + goto print_usage;
24 + strbuf_addf(&pathname, "//./pipe/%s", filename);
25 +
26 + /*
27 + * Create a single instance of the server side of the named pipe.
28 + * This will allow exactly one client instance to connect to it.
29 + */
30 + h = CreateNamedPipeA(
31 + pathname.buf,
32 + PIPE_ACCESS_INBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE,
33 + PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
34 + PIPE_UNLIMITED_INSTANCES,
35 + TEST_BUFSIZE, TEST_BUFSIZE, 0, NULL);
36 + if (h == INVALID_HANDLE_VALUE) {
37 + err = err_win_to_posix(GetLastError());
38 + fprintf(stderr, "CreateNamedPipe failed: %s\n",
39 + strerror(err));
40 + return err;
41 + }
42 +
43 + connected = ConnectNamedPipe(h, NULL)
44 + ? TRUE
45 + : (GetLastError() == ERROR_PIPE_CONNECTED);
46 + if (!connected) {
47 + err = err_win_to_posix(GetLastError());
48 + fprintf(stderr, "ConnectNamedPipe failed: %s\n",
49 + strerror(err));
50 + CloseHandle(h);
51 + return err;
52 + }
53 +
54 + while (1) {
55 + DWORD nbr;
56 + BOOL success = ReadFile(h, buf, TEST_BUFSIZE, &nbr, NULL);
57 + if (!success || nbr == 0)
58 + break;
59 + buf[nbr] = 0;
60 +
61 + write(1, buf, nbr);
62 + }
63 +
64 + DisconnectNamedPipe(h);
65 + CloseHandle(h);
66 + return 0;
67 +
68 +print_usage:
69 + fprintf(stderr, "usage: %s %s\n", argv[0], usage_string);
70 + return 1;
71 +}
72 +#endif
t/t0051-windows-named-pipe.sh new
+17
@@ -0,0 +1,17 @@
1 +#!/bin/sh
2 +
3 +test_description='Windows named pipes'
4 +
5 +. ./test-lib.sh
6 +
7 +test_expect_failure MINGW 'o_append write to named pipe' '
8 + GIT_TRACE="$(pwd)/expect" git status >/dev/null 2>&1 &&
9 + { test-tool windows-named-pipe t0051 >actual 2>&1 & } &&
10 + pid=$! &&
11 + sleep 1 &&
12 + GIT_TRACE=//./pipe/t0051 git status >/dev/null 2>warning &&
13 + wait $pid &&
14 + test_cmp expect actual
15 +'
16 +
17 +test_done