]> git.ipfire.org Git - thirdparty/git.git/commitdiff
t/helper/fsmonitor-client: create IPC client to talk to FSMonitor Daemon
authorJeff Hostetler <jeffhost@microsoft.com>
Fri, 25 Mar 2022 18:03:03 +0000 (18:03 +0000)
committerJunio C Hamano <gitster@pobox.com>
Fri, 25 Mar 2022 23:04:16 +0000 (16:04 -0700)
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>
Makefile
t/helper/test-fsmonitor-client.c [new file with mode: 0644]
t/helper/test-tool.c
t/helper/test-tool.h

index 26567d4f7722b41c3d70cf9d38f4a89ecbb57d32..daa21bed6c3b477945e769e66f30aac9c7e35e2a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -716,6 +716,7 @@ TEST_BUILTINS_OBJS += test-dump-split-index.o
 TEST_BUILTINS_OBJS += test-dump-untracked-cache.o
 TEST_BUILTINS_OBJS += test-example-decorate.o
 TEST_BUILTINS_OBJS += test-fast-rebase.o
+TEST_BUILTINS_OBJS += test-fsmonitor-client.o
 TEST_BUILTINS_OBJS += test-genrandom.o
 TEST_BUILTINS_OBJS += test-genzeros.o
 TEST_BUILTINS_OBJS += test-getcwd.o
diff --git a/t/helper/test-fsmonitor-client.c b/t/helper/test-fsmonitor-client.c
new file mode 100644 (file)
index 0000000..3062c8a
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * test-fsmonitor-client.c: client code to send commands/requests to
+ * a `git fsmonitor--daemon` daemon.
+ */
+
+#include "test-tool.h"
+#include "cache.h"
+#include "parse-options.h"
+#include "fsmonitor-ipc.h"
+
+#ifndef HAVE_FSMONITOR_DAEMON_BACKEND
+int cmd__fsmonitor_client(int argc, const char **argv)
+{
+       die("fsmonitor--daemon not available on this platform");
+}
+#else
+
+/*
+ * Read the `.git/index` to get the last token written to the
+ * FSMonitor Index Extension.
+ */
+static const char *get_token_from_index(void)
+{
+       struct index_state *istate = the_repository->index;
+
+       if (do_read_index(istate, the_repository->index_file, 0) < 0)
+               die("unable to read index file");
+       if (!istate->fsmonitor_last_update)
+               die("index file does not have fsmonitor extension");
+
+       return istate->fsmonitor_last_update;
+}
+
+/*
+ * Send an IPC query to a `git-fsmonitor--daemon` daemon and
+ * ask for the changes since the given token or from the last
+ * token in the index extension.
+ *
+ * This will implicitly start a daemon process if necessary.  The
+ * daemon process will persist after we exit.
+ */
+static int do_send_query(const char *token)
+{
+       struct strbuf answer = STRBUF_INIT;
+       int ret;
+
+       if (!token || !*token)
+               token = get_token_from_index();
+
+       ret = fsmonitor_ipc__send_query(token, &answer);
+       if (ret < 0)
+               die("could not query fsmonitor--daemon");
+
+       write_in_full(1, answer.buf, answer.len);
+       strbuf_release(&answer);
+
+       return 0;
+}
+
+/*
+ * Send a "flush" command to the `git-fsmonitor--daemon` (if running)
+ * and tell it to flush its cache.
+ *
+ * This feature is primarily used by the test suite to simulate a loss of
+ * sync with the filesystem where we miss kernel events.
+ */
+static int do_send_flush(void)
+{
+       struct strbuf answer = STRBUF_INIT;
+       int ret;
+
+       ret = fsmonitor_ipc__send_command("flush", &answer);
+       if (ret)
+               return ret;
+
+       write_in_full(1, answer.buf, answer.len);
+       strbuf_release(&answer);
+
+       return 0;
+}
+
+int cmd__fsmonitor_client(int argc, const char **argv)
+{
+       const char *subcmd;
+       const char *token = NULL;
+
+       const char * const fsmonitor_client_usage[] = {
+               "test-tool fsmonitor-client query [<token>]",
+               "test-tool fsmonitor-client flush",
+               NULL,
+       };
+
+       struct option options[] = {
+               OPT_STRING(0, "token", &token, "token",
+                          "command token to send to the server"),
+               OPT_END()
+       };
+
+       argc = parse_options(argc, argv, NULL, options, fsmonitor_client_usage, 0);
+
+       if (argc != 1)
+               usage_with_options(fsmonitor_client_usage, options);
+
+       subcmd = argv[0];
+
+       setup_git_directory();
+
+       if (!strcmp(subcmd, "query"))
+               return !!do_send_query(token);
+
+       if (!strcmp(subcmd, "flush"))
+               return !!do_send_flush();
+
+       die("Unhandled subcommand: '%s'", subcmd);
+}
+#endif
index e6ec69cf326a3babac7bac7df9a03026b0c16d5a..0424f7adf5d69cc2596a58ee3ef33f1826dfc621 100644 (file)
@@ -32,6 +32,7 @@ static struct test_cmd cmds[] = {
        { "dump-untracked-cache", cmd__dump_untracked_cache },
        { "example-decorate", cmd__example_decorate },
        { "fast-rebase", cmd__fast_rebase },
+       { "fsmonitor-client", cmd__fsmonitor_client },
        { "genrandom", cmd__genrandom },
        { "genzeros", cmd__genzeros },
        { "getcwd", cmd__getcwd },
index 20756eefddac8394b9e9f2625909f1833b2fec02..c876e8246fbdff9ddf43e5b4ec46944406f9d33d 100644 (file)
@@ -23,6 +23,7 @@ int cmd__dump_untracked_cache(int argc, const char **argv);
 int cmd__dump_reftable(int argc, const char **argv);
 int cmd__example_decorate(int argc, const char **argv);
 int cmd__fast_rebase(int argc, const char **argv);
+int cmd__fsmonitor_client(int argc, const char **argv);
 int cmd__genrandom(int argc, const char **argv);
 int cmd__genzeros(int argc, const char **argv);
 int cmd__getcwd(int argc, const char **argv);