t/helper/fsmonitor-client: create IPC client to talk to FSMonitor Daemon

Create an IPC client to send query and flush commands to the daemon. Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff Hostetler committed Mar 25, 2022 at 18:03 UTC 148405fb27980a63bb532d11f9ab242280052355
4 files changed +119
Makefile
+1
@@ -716,6 +716,7 @@ TEST_BUILTINS_OBJS += test-dump-split-index.o
716 TEST_BUILTINS_OBJS += test-dump-untracked-cache.o
717 TEST_BUILTINS_OBJS += test-example-decorate.o
718 TEST_BUILTINS_OBJS += test-fast-rebase.o
719 +TEST_BUILTINS_OBJS += test-fsmonitor-client.o
720 TEST_BUILTINS_OBJS += test-genrandom.o
721 TEST_BUILTINS_OBJS += test-genzeros.o
722 TEST_BUILTINS_OBJS += test-getcwd.o
t/helper/test-fsmonitor-client.c new
+116
@@ -0,0 +1,116 @@
1 +/*
2 + * test-fsmonitor-client.c: client code to send commands/requests to
3 + * a `git fsmonitor--daemon` daemon.
4 + */
5 +
6 +#include "test-tool.h"
7 +#include "cache.h"
8 +#include "parse-options.h"
9 +#include "fsmonitor-ipc.h"
10 +
11 +#ifndef HAVE_FSMONITOR_DAEMON_BACKEND
12 +int cmd__fsmonitor_client(int argc, const char **argv)
13 +{
14 + die("fsmonitor--daemon not available on this platform");
15 +}
16 +#else
17 +
18 +/*
19 + * Read the `.git/index` to get the last token written to the
20 + * FSMonitor Index Extension.
21 + */
22 +static const char *get_token_from_index(void)
23 +{
24 + struct index_state *istate = the_repository->index;
25 +
26 + if (do_read_index(istate, the_repository->index_file, 0) < 0)
27 + die("unable to read index file");
28 + if (!istate->fsmonitor_last_update)
29 + die("index file does not have fsmonitor extension");
30 +
31 + return istate->fsmonitor_last_update;
32 +}
33 +
34 +/*
35 + * Send an IPC query to a `git-fsmonitor--daemon` daemon and
36 + * ask for the changes since the given token or from the last
37 + * token in the index extension.
38 + *
39 + * This will implicitly start a daemon process if necessary. The
40 + * daemon process will persist after we exit.
41 + */
42 +static int do_send_query(const char *token)
43 +{
44 + struct strbuf answer = STRBUF_INIT;
45 + int ret;
46 +
47 + if (!token || !*token)
48 + token = get_token_from_index();
49 +
50 + ret = fsmonitor_ipc__send_query(token, &answer);
51 + if (ret < 0)
52 + die("could not query fsmonitor--daemon");
53 +
54 + write_in_full(1, answer.buf, answer.len);
55 + strbuf_release(&answer);
56 +
57 + return 0;
58 +}
59 +
60 +/*
61 + * Send a "flush" command to the `git-fsmonitor--daemon` (if running)
62 + * and tell it to flush its cache.
63 + *
64 + * This feature is primarily used by the test suite to simulate a loss of
65 + * sync with the filesystem where we miss kernel events.
66 + */
67 +static int do_send_flush(void)
68 +{
69 + struct strbuf answer = STRBUF_INIT;
70 + int ret;
71 +
72 + ret = fsmonitor_ipc__send_command("flush", &answer);
73 + if (ret)
74 + return ret;
75 +
76 + write_in_full(1, answer.buf, answer.len);
77 + strbuf_release(&answer);
78 +
79 + return 0;
80 +}
81 +
82 +int cmd__fsmonitor_client(int argc, const char **argv)
83 +{
84 + const char *subcmd;
85 + const char *token = NULL;
86 +
87 + const char * const fsmonitor_client_usage[] = {
88 + "test-tool fsmonitor-client query [<token>]",
89 + "test-tool fsmonitor-client flush",
90 + NULL,
91 + };
92 +
93 + struct option options[] = {
94 + OPT_STRING(0, "token", &token, "token",
95 + "command token to send to the server"),
96 + OPT_END()
97 + };
98 +
99 + argc = parse_options(argc, argv, NULL, options, fsmonitor_client_usage, 0);
100 +
101 + if (argc != 1)
102 + usage_with_options(fsmonitor_client_usage, options);
103 +
104 + subcmd = argv[0];
105 +
106 + setup_git_directory();
107 +
108 + if (!strcmp(subcmd, "query"))
109 + return !!do_send_query(token);
110 +
111 + if (!strcmp(subcmd, "flush"))
112 + return !!do_send_flush();
113 +
114 + die("Unhandled subcommand: '%s'", subcmd);
115 +}
116 +#endif
t/helper/test-tool.c
+1
@@ -32,6 +32,7 @@ static struct test_cmd cmds[] = {
32 { "dump-untracked-cache", cmd__dump_untracked_cache },
33 { "example-decorate", cmd__example_decorate },
34 { "fast-rebase", cmd__fast_rebase },
35 + { "fsmonitor-client", cmd__fsmonitor_client },
36 { "genrandom", cmd__genrandom },
37 { "genzeros", cmd__genzeros },
38 { "getcwd", cmd__getcwd },
t/helper/test-tool.h
+1
@@ -23,6 +23,7 @@ int cmd__dump_untracked_cache(int argc, const char **argv);
23 int cmd__dump_reftable(int argc, const char **argv);
24 int cmd__example_decorate(int argc, const char **argv);
25 int cmd__fast_rebase(int argc, const char **argv);
26 +int cmd__fsmonitor_client(int argc, const char **argv);
27 int cmd__genrandom(int argc, const char **argv);
28 int cmd__genzeros(int argc, const char **argv);
29 int cmd__getcwd(int argc, const char **argv);