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.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2026-05-05 22:06:41 +02:00
parent 764d9d5ddb
commit 392846b370
2 changed files with 116 additions and 1 deletions
+10 -1
View File
@@ -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',
+106
View File
@@ -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);