From: Zbigniew Jędrzejewski-Szmek Date: Tue, 5 May 2026 11:21:30 +0000 (+0200) Subject: test-homectl-prompts: add manual test to exercise prompt functionality X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=392846b370dcde7142f854ac38c15292522966a2;p=thirdparty%2Fsystemd.git test-homectl-prompts: add manual test to exercise prompt functionality The prompt for groups is nice. The prompt for a shell could use some love. Looking at this is much easier if we can invoke the code outside in isolation. I wrote this when looking at https://github.com/systemd/systemd/pull/41947, where I wanted to see how the homectl prompt works with the changes. --- diff --git a/src/home/meson.build b/src/home/meson.build index 8c644842c14..600f00b4ac9 100644 --- a/src/home/meson.build +++ b/src/home/meson.build @@ -47,11 +47,14 @@ systemd_homed_sources += [homed_gperf_c] homectl_sources = files( 'homectl-fido2.c', 'homectl-pkcs11.c', - 'homectl-prompts.c', 'homectl-recovery-key.c', 'homectl.c', ) +homectl_extract = files( + 'homectl-prompts.c', +) + pam_systemd_home_sources = files( 'home-util.c', 'pam_systemd_home.c', @@ -86,6 +89,7 @@ executables += [ 'name' : 'homectl', 'public' : true, 'sources' : homectl_sources, + 'extract' : homectl_extract, 'objects' : ['systemd-homed'], 'dependencies' : [ libdl, @@ -94,6 +98,11 @@ executables += [ threads, ], }, + test_template + { + 'sources' : files('test-homectl-prompts.c'), + 'objects' : ['homectl'], + 'type' : 'manual', + }, test_template + { 'sources' : files('test-homed-regression-31896.c'), 'type' : 'manual', diff --git a/src/home/test-homectl-prompts.c b/src/home/test-homectl-prompts.c new file mode 100644 index 00000000000..aaa81cc78a8 --- /dev/null +++ b/src/home/test-homectl-prompts.c @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "alloc-util.h" +#include "format-table.h" +#include "help-util.h" +#include "homectl-prompts.h" +#include "main-func.h" +#include "options.h" +#include "string-util.h" +#include "strv.h" +#include "tests.h" +#include "verbs.h" + +static int help(void) { + _cleanup_(table_unrefp) Table *options = NULL, *verbs = NULL; + int r; + + r = option_parser_get_help_table(&options); + if (r < 0) + return r; + + r = verbs_get_help_table(&verbs); + if (r < 0) + return r; + + (void) table_sync_column_widths(0, options, verbs); + + help_cmdline("[OPTIONS...] VERB [USERNAME]"); + help_abstract("Exercise homectl prompt functions in isolation."); + + help_section("Verbs"); + r = table_print_or_warn(verbs); + if (r < 0) + return r; + + help_section("Options"); + return table_print_or_warn(options); +} + +VERB(verb_groups, "groups", "[USER]", VERB_ANY, 2, 0, "Select groups"); +static int verb_groups(int argc, char *argv[], uintptr_t _data, void *userdata) { + assert(argv); + + const char *username = argv[1] ?: "test"; + int r; + + _cleanup_strv_free_ char **t = NULL; + + r = prompt_groups(username, &t); + if (r < 0) + return r; + + _cleanup_free_ char *s = ASSERT_PTR(strv_join(t, ", ")); + log_info("groups: %s → %s", username, s); + return 0; +} + +VERB(verb_shell, "shell", "[USER]", VERB_ANY, 2, 0, "Select shell"); +static int verb_shell(int argc, char *argv[], uintptr_t _data, void *userdata) { + assert(argv); + + const char *username = argv[1] ?: "test"; + int r; + + _cleanup_free_ char *s = NULL; + + r = prompt_shell(username, &s); + if (r < 0) + return r; + + log_info("shell: %s → %s", username, strnull(s)); + return 0; +} + +static int parse_argv(int argc, char **argv, char ***remaining_args) { + assert(argc >= 0); + assert(argv); + assert(remaining_args); + + OptionParser opts = { argc, argv }; + + FOREACH_OPTION_OR_RETURN(c, &opts) + switch (c) { + + OPTION_COMMON_HELP: + return help(); + } + + *remaining_args = option_parser_get_args(&opts); + return 1; +} + +static int run(int argc, char **argv) { + int r; + + test_setup_logging(LOG_DEBUG); + + char **args = NULL; + r = parse_argv(argc, argv, &args); + if (r <= 0) + return r; + + return dispatch_verb_with_args(args, /* userdata= */ NULL); +} + +DEFINE_MAIN_FUNCTION(run);