diff options
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/meson.build | 20 | ||||
-rw-r--r-- | src/test/test-chown-rec.c | 160 | ||||
-rw-r--r-- | src/test/test-exec-util.c | 43 | ||||
-rw-r--r-- | src/test/test-format-table.c | 42 | ||||
-rw-r--r-- | src/test/test-proc-cmdline.c | 96 | ||||
-rw-r--r-- | src/test/test-process-util.c | 9 | ||||
-rw-r--r-- | src/test/test-set-disable-mempool.c | 55 | ||||
-rw-r--r-- | src/test/test-string-util.c | 116 |
8 files changed, 518 insertions, 23 deletions
diff --git a/src/test/meson.build b/src/test/meson.build index 0405fac52..d08e61223 100644 --- a/src/test/meson.build +++ b/src/test/meson.build @@ -67,6 +67,11 @@ tests += [ # libmount, # libblkid]], # +# [['src/test/test-chown-rec.c'], +# [libcore, +# libshared], +# []], +# # [['src/test/test-job-type.c'], # [libcore, # libshared], @@ -426,6 +431,10 @@ tests += [ [], []], + [['src/test/test-set-disable-mempool.c'], + [], + [threads]], + #if 0 /// UNNEEDED in elogind # [['src/test/test-bitmap.c'], # [], @@ -943,9 +952,16 @@ tests += [ [['src/libelogind/sd-login/test-login.c'], [], []], -] #if 0 /// UNNEEDED in elogind +# [['src/libelogind/sd-device/test-udev-device-thread.c'], +# [libbasic, +# libshared_static, +# libudev], +# [threads]], +# ] +# +# # if cxx.found() # tests += [ # [['src/libelogind/sd-bus/test-bus-vtable-cc.cc'], @@ -953,6 +969,8 @@ tests += [ # []] # ] # endif +#else +] #endif // 0 ############################################################ diff --git a/src/test/test-chown-rec.c b/src/test/test-chown-rec.c new file mode 100644 index 000000000..f79577f44 --- /dev/null +++ b/src/test/test-chown-rec.c @@ -0,0 +1,160 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +//#include <sys/xattr.h> + +//#include "alloc-util.h" +//#include "chown-recursive.h" +//#include "fileio.h" +//#include "log.h" +//#include "rm-rf.h" +//#include "string-util.h" +//#include "tests.h" + +static const uint8_t acl[] = { + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0x07, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x07, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x10, 0x00, 0x07, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x05, 0x00, + 0xff, 0xff, 0xff, 0xff, +}; + +static const uint8_t default_acl[] = { + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x04, 0x00, 0x07, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x07, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x07, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x05, 0x00, + 0xff, 0xff, 0xff, 0xff, +}; + +static bool has_xattr(const char *p) { + char buffer[sizeof(acl) * 4]; + + if (lgetxattr(p, "system.posix_acl_access", buffer, sizeof(buffer)) < 0) { + if (IN_SET(errno, EOPNOTSUPP, ENOTTY, ENODATA, ENOSYS)) + return false; + } + + return true; +} + +static void test_chown_recursive(void) { + _cleanup_(rm_rf_physical_and_freep) char *t = NULL; + struct stat st; + const char *p; + + umask(022); + assert_se(mkdtemp_malloc(NULL, &t) >= 0); + + p = strjoina(t, "/dir"); + assert_se(mkdir(p, 0777) >= 0); + assert_se(lstat(p, &st) >= 0); + assert_se(S_ISDIR(st.st_mode)); + assert_se((st.st_mode & 07777) == 0755); + assert_se(st.st_uid == 0); + assert_se(st.st_gid == 0); + assert_se(!has_xattr(p)); + + p = strjoina(t, "/dir/symlink"); + assert_se(symlink("../../", p) >= 0); + assert_se(lstat(p, &st) >= 0); + assert_se(S_ISLNK(st.st_mode)); + assert_se((st.st_mode & 07777) == 0777); + assert_se(st.st_uid == 0); + assert_se(st.st_gid == 0); + assert_se(!has_xattr(p)); + + p = strjoina(t, "/dir/reg"); + assert_se(mknod(p, S_IFREG|0777, 0) >= 0); + assert_se(lstat(p, &st) >= 0); + assert_se(S_ISREG(st.st_mode)); + assert_se((st.st_mode & 07777) == 0755); + assert_se(st.st_uid == 0); + assert_se(st.st_gid == 0); + assert_se(!has_xattr(p)); + + p = strjoina(t, "/dir/sock"); + assert_se(mknod(p, S_IFSOCK|0777, 0) >= 0); + assert_se(lstat(p, &st) >= 0); + assert_se(S_ISSOCK(st.st_mode)); + assert_se((st.st_mode & 07777) == 0755); + assert_se(st.st_uid == 0); + assert_se(st.st_gid == 0); + assert_se(!has_xattr(p)); + + p = strjoina(t, "/dir/fifo"); + assert_se(mknod(p, S_IFIFO|0777, 0) >= 0); + assert_se(lstat(p, &st) >= 0); + assert_se(S_ISFIFO(st.st_mode)); + assert_se((st.st_mode & 07777) == 0755); + assert_se(st.st_uid == 0); + assert_se(st.st_gid == 0); + assert_se(!has_xattr(p)); + + /* We now apply an xattr to the dir, and check it again */ + p = strjoina(t, "/dir"); + assert_se(setxattr(p, "system.posix_acl_access", acl, sizeof(acl), 0) >= 0); + assert_se(setxattr(p, "system.posix_acl_default", default_acl, sizeof(default_acl), 0) >= 0); + assert_se(lstat(p, &st) >= 0); + assert_se(S_ISDIR(st.st_mode)); + assert_se((st.st_mode & 07777) == 0775); /* acl change changed the mode too */ + assert_se(st.st_uid == 0); + assert_se(st.st_gid == 0); + assert_se(has_xattr(p)); + + assert_se(path_chown_recursive(t, 1, 2) >= 0); + + p = strjoina(t, "/dir"); + assert_se(lstat(p, &st) >= 0); + assert_se(S_ISDIR(st.st_mode)); + assert_se((st.st_mode & 07777) == 0775); + assert_se(st.st_uid == 1); + assert_se(st.st_gid == 2); + assert_se(!has_xattr(p)); + + p = strjoina(t, "/dir/symlink"); + assert_se(lstat(p, &st) >= 0); + assert_se(S_ISLNK(st.st_mode)); + assert_se((st.st_mode & 07777) == 0777); + assert_se(st.st_uid == 1); + assert_se(st.st_gid == 2); + assert_se(!has_xattr(p)); + + p = strjoina(t, "/dir/reg"); + assert_se(lstat(p, &st) >= 0); + assert_se(S_ISREG(st.st_mode)); + assert_se((st.st_mode & 07777) == 0755); + assert_se(st.st_uid == 1); + assert_se(st.st_gid == 2); + assert_se(!has_xattr(p)); + + p = strjoina(t, "/dir/sock"); + assert_se(lstat(p, &st) >= 0); + assert_se(S_ISSOCK(st.st_mode)); + assert_se((st.st_mode & 07777) == 0755); + assert_se(st.st_uid == 1); + assert_se(st.st_gid == 2); + assert_se(!has_xattr(p)); + + p = strjoina(t, "/dir/fifo"); + assert_se(lstat(p, &st) >= 0); + assert_se(S_ISFIFO(st.st_mode)); + assert_se((st.st_mode & 07777) == 0755); + assert_se(st.st_uid == 1); + assert_se(st.st_gid == 2); + assert_se(!has_xattr(p)); +} + +int main(int argc, char *argv[]) { + log_set_max_level(LOG_DEBUG); + log_parse_environment(); + log_open(); + + if (geteuid() != 0) + return EXIT_TEST_SKIP; + + test_chown_recursive(); + + return EXIT_SUCCESS; +} diff --git a/src/test/test-exec-util.c b/src/test/test-exec-util.c index 030328391..24f8cd36e 100644 --- a/src/test/test-exec-util.c +++ b/src/test/test-exec-util.c @@ -16,6 +16,7 @@ #include "fs-util.h" #include "log.h" #include "macro.h" +//#include "path-util.h" #include "rm-rf.h" #include "string-util.h" #include "strv.h" @@ -115,9 +116,9 @@ static void test_execute_directory(bool gather_stdout) { assert_se(chmod(mask2e, 0755) == 0); if (gather_stdout) - execute_directories(dirs, DEFAULT_TIMEOUT_USEC, ignore_stdout, ignore_stdout_args, NULL); + execute_directories(dirs, DEFAULT_TIMEOUT_USEC, ignore_stdout, ignore_stdout_args, NULL, NULL); else - execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL, NULL, NULL); + execute_directories(dirs, DEFAULT_TIMEOUT_USEC, NULL, NULL, NULL, NULL); assert_se(chdir(template_lo) == 0); assert_se(access("it_works", F_OK) >= 0); @@ -182,7 +183,7 @@ static void test_execution_order(void) { assert_se(chmod(override, 0755) == 0); assert_se(chmod(masked, 0755) == 0); - execute_directories(dirs, DEFAULT_TIMEOUT_USEC, ignore_stdout, ignore_stdout_args, NULL); + execute_directories(dirs, DEFAULT_TIMEOUT_USEC, ignore_stdout, ignore_stdout_args, NULL, NULL); assert_se(read_full_file(output, &contents, NULL) >= 0); assert_se(streq(contents, "30-override\n80-foo\n90-bar\nlast\n")); @@ -264,7 +265,7 @@ static void test_stdout_gathering(void) { assert_se(chmod(name2, 0755) == 0); assert_se(chmod(name3, 0755) == 0); - r = execute_directories(dirs, DEFAULT_TIMEOUT_USEC, gather_stdout, args, NULL); + r = execute_directories(dirs, DEFAULT_TIMEOUT_USEC, gather_stdout, args, NULL, NULL); assert_se(r >= 0); log_info("got: %s", output); @@ -276,7 +277,7 @@ static void test_stdout_gathering(void) { static void test_environment_gathering(void) { char template[] = "/tmp/test-exec-util.XXXXXXX", **p; const char *dirs[] = {template, NULL}; - const char *name, *name2, *name3; + const char *name, *name2, *name3, *old; int r; char **tmp = NULL; /* this is only used in the forked process, no cleanup here */ @@ -322,7 +323,32 @@ static void test_environment_gathering(void) { assert_se(chmod(name2, 0755) == 0); assert_se(chmod(name3, 0755) == 0); - r = execute_directories(dirs, DEFAULT_TIMEOUT_USEC, gather_environment, args, NULL); + /* When booting in containers or without initramfs there might not be + * any PATH in the environ and if there is no PATH /bin/sh built-in + * PATH may leak and override systemd's DEFAULT_PATH which is not + * good. Force our own PATH in environment, to prevent expansion of sh + * built-in $PATH */ + old = getenv("PATH"); + r = setenv("PATH", "no-sh-built-in-path", 1); + assert_se(r >= 0); + + r = execute_directories(dirs, DEFAULT_TIMEOUT_USEC, gather_environment, args, NULL, NULL); + assert_se(r >= 0); + + STRV_FOREACH(p, env) + log_info("got env: \"%s\"", *p); + + assert_se(streq(strv_env_get(env, "A"), "22:23:24")); + assert_se(streq(strv_env_get(env, "B"), "12")); + assert_se(streq(strv_env_get(env, "C"), "001")); + assert_se(streq(strv_env_get(env, "PATH"), "no-sh-built-in-path:/no/such/file")); + + /* now retest with "default" path passed in, as created by + * manager_default_environment */ + env = strv_free(env); + env = strv_new("PATH=" DEFAULT_PATH, NULL); + + r = execute_directories(dirs, DEFAULT_TIMEOUT_USEC, gather_environment, args, NULL, env); assert_se(r >= 0); STRV_FOREACH(p, env) @@ -331,7 +357,10 @@ static void test_environment_gathering(void) { assert_se(streq(strv_env_get(env, "A"), "22:23:24")); assert_se(streq(strv_env_get(env, "B"), "12")); assert_se(streq(strv_env_get(env, "C"), "001")); - assert_se(endswith(strv_env_get(env, "PATH"), ":/no/such/file")); + assert_se(streq(strv_env_get(env, "PATH"), DEFAULT_PATH ":/no/such/file")); + + /* reset environ PATH */ + (void) setenv("PATH", old, 1); } #endif // 0 diff --git a/src/test/test-format-table.c b/src/test/test-format-table.c index adcc41416..f94cdf624 100644 --- a/src/test/test-format-table.c +++ b/src/test/test-format-table.c @@ -5,6 +5,33 @@ #include "string-util.h" #include "time-util.h" +/// Additional includes needed by elogind +#include "locale-util.h" + +static void test_issue_9549(void) { + _cleanup_(table_unrefp) Table *table = NULL; + _cleanup_free_ char *formatted = NULL; + + assert_se(table = table_new("NAME", "TYPE", "RO", "USAGE", "CREATED", "MODIFIED")); + assert_se(table_set_align_percent(table, TABLE_HEADER_CELL(3), 100) >= 0); + assert_se(table_add_many(table, + TABLE_STRING, "foooo", + TABLE_STRING, "raw", + TABLE_BOOLEAN, false, + TABLE_SIZE, (uint64_t) (673.7*1024*1024), + TABLE_STRING, "Wed 2018-07-11 00:10:33 JST", + TABLE_STRING, "Wed 2018-07-11 00:16:00 JST") >= 0); + + table_set_width(table, 75); + assert_se(table_format(table, &formatted) >= 0); + + printf("%s\n", formatted); + assert_se(streq(formatted, + "NAME TYPE RO USAGE CREATED MODIFIED \n" + "foooo raw no 673.6M Wed 2018-07-11 00:10:33 J… Wed 2018-07-11 00:16:00 JST\n" + )); +} + int main(int argc, char *argv[]) { _cleanup_(table_unrefp) Table *t = NULL; @@ -50,6 +77,10 @@ int main(int argc, char *argv[]) { table_set_width(t, 12); assert_se(table_format(t, &formatted) >= 0); + +#if 1 /// elogind supports systems with non-UTF-8 locales, the next would fail there + if (is_locale_utf8()) { +#endif // 1 printf("%s\n", formatted); assert_se(streq(formatted, @@ -80,6 +111,9 @@ int main(int argc, char *argv[]) { "… … …\n")); formatted = mfree(formatted); +#if 1 /// elogind supports systems with non-UTF-8 locales, the previous would fail there + } +#endif // 1 table_set_width(t, (size_t) -1); assert_se(table_set_sort(t, (size_t) 0, (size_t) 2, (size_t) -1) >= 0); @@ -96,6 +130,9 @@ int main(int argc, char *argv[]) { table_set_header(t, false); +#if 1 /// elogind supports systems with non-UTF-8 locales, the next would fail there + if (is_locale_utf8()) { +#endif // 1 assert_se(table_add_many(t, TABLE_STRING, "fäää", TABLE_STRING, "uuu", @@ -134,6 +171,11 @@ int main(int argc, char *argv[]) { " yes fäää yes fäää fäää \n" " yes xxx yes xxx xxx \n" "5min 5min \n")); +#if 1 /// elogind supports systems with non-UTF-8 locales, the previous would fail there + } +#endif // 1 + + test_issue_9549(); return 0; } diff --git a/src/test/test-proc-cmdline.c b/src/test/test-proc-cmdline.c index 275c377cc..d77c7f641 100644 --- a/src/test/test-proc-cmdline.c +++ b/src/test/test-proc-cmdline.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #include "alloc-util.h" +//#include "env-util.h" #include "log.h" #include "macro.h" #include "proc-cmdline.h" @@ -19,29 +20,69 @@ static int parse_item(const char *key, const char *value, void *data) { } static void test_proc_cmdline_parse(void) { - assert_se(proc_cmdline_parse(parse_item, &obj, true) >= 0); + log_info("/* %s */", __func__); + + assert_se(proc_cmdline_parse(parse_item, &obj, PROC_CMDLINE_STRIP_RD_PREFIX) >= 0); } #if 0 /// UNNEEDED by elogind -static void test_runlevel_to_target(void) { - in_initrd_force(false); - assert_se(streq_ptr(runlevel_to_target(NULL), NULL)); - assert_se(streq_ptr(runlevel_to_target("unknown-runlevel"), NULL)); - assert_se(streq_ptr(runlevel_to_target("rd.unknown-runlevel"), NULL)); - assert_se(streq_ptr(runlevel_to_target("3"), SPECIAL_MULTI_USER_TARGET)); - assert_se(streq_ptr(runlevel_to_target("rd.rescue"), NULL)); +static void test_proc_cmdline_override(void) { + log_info("/* %s */", __func__); - in_initrd_force(true); - assert_se(streq_ptr(runlevel_to_target(NULL), NULL)); - assert_se(streq_ptr(runlevel_to_target("unknown-runlevel"), NULL)); - assert_se(streq_ptr(runlevel_to_target("rd.unknown-runlevel"), NULL)); - assert_se(streq_ptr(runlevel_to_target("3"), NULL)); - assert_se(streq_ptr(runlevel_to_target("rd.rescue"), SPECIAL_RESCUE_TARGET)); + assert_se(putenv((char*) "SYSTEMD_PROC_CMDLINE=foo_bar=quux wuff-piep=tuet zumm") == 0); + + /* Test if the override works */ + _cleanup_free_ char *line = NULL, *value = NULL; + assert_se(proc_cmdline(&line) >= 0); + + /* Test if parsing makes uses of the override */ + assert_se(streq(line, "foo_bar=quux wuff-piep=tuet zumm")); + assert_se(proc_cmdline_get_key("foo_bar", 0, &value) > 0 && streq_ptr(value, "quux")); +} + +static int parse_item_given(const char *key, const char *value, void *data) { + assert_se(key); + assert_se(data); + + bool *strip = data; + + log_info("%s: option <%s> = <%s>", __func__, key, strna(value)); + if (streq(key, "foo_bar")) + assert_se(streq(value, "quux")); + else if (streq(key, "wuff-piep")) + assert_se(streq(value, "tuet ")); + else if (in_initrd() && *strip && streq(key, "zumm")) + assert_se(!value); + else if (in_initrd() && !*strip && streq(key, "rd.zumm")) + assert_se(!value); + else + assert_not_reached("Bad key!"); + + return 0; +} + +static void test_proc_cmdline_given(bool flip_initrd) { + log_info("/* %s (flip: %s) */", __func__, yes_no(flip_initrd)); + + if (flip_initrd) + in_initrd_force(!in_initrd()); + + bool t = true, f = false; + assert_se(proc_cmdline_parse_given("foo_bar=quux wuff-piep=\"tuet \" rd.zumm", + parse_item_given, &t, PROC_CMDLINE_STRIP_RD_PREFIX) >= 0); + + assert_se(proc_cmdline_parse_given("foo_bar=quux wuff-piep=\"tuet \" rd.zumm", + parse_item_given, &f, 0) >= 0); + + + if (flip_initrd) + in_initrd_force(!in_initrd()); } static void test_proc_cmdline_get_key(void) { _cleanup_free_ char *value = NULL; + log_info("/* %s */", __func__); putenv((char*) "SYSTEMD_PROC_CMDLINE=foo_bar=quux wuff-piep=tuet zumm"); assert_se(proc_cmdline_get_key("", 0, &value) == -EINVAL); @@ -79,6 +120,7 @@ static void test_proc_cmdline_get_key(void) { static void test_proc_cmdline_get_bool(void) { bool value = false; + log_info("/* %s */", __func__); putenv((char*) "SYSTEMD_PROC_CMDLINE=foo_bar bar-waldo=1 x_y-z=0 quux=miep"); assert_se(proc_cmdline_get_bool("", &value) == -EINVAL); @@ -96,6 +138,7 @@ static void test_proc_cmdline_get_bool(void) { #endif // 0 static void test_proc_cmdline_key_streq(void) { + log_info("/* %s */", __func__); assert_se(proc_cmdline_key_streq("", "")); assert_se(proc_cmdline_key_streq("a", "a")); @@ -113,6 +156,7 @@ static void test_proc_cmdline_key_streq(void) { #if 0 /// UNNEEDED by elogind static void test_proc_cmdline_key_startswith(void) { + log_info("/* %s */", __func__); assert_se(proc_cmdline_key_startswith("", "")); assert_se(proc_cmdline_key_startswith("x", "")); @@ -126,6 +170,24 @@ static void test_proc_cmdline_key_startswith(void) { assert_se(proc_cmdline_key_startswith("foo-bar", "foo_")); assert_se(!proc_cmdline_key_startswith("foo-bar", "foo_xx")); } + +static void test_runlevel_to_target(void) { + log_info("/* %s */", __func__); + + in_initrd_force(false); + assert_se(streq_ptr(runlevel_to_target(NULL), NULL)); + assert_se(streq_ptr(runlevel_to_target("unknown-runlevel"), NULL)); + assert_se(streq_ptr(runlevel_to_target("rd.unknown-runlevel"), NULL)); + assert_se(streq_ptr(runlevel_to_target("3"), SPECIAL_MULTI_USER_TARGET)); + assert_se(streq_ptr(runlevel_to_target("rd.rescue"), NULL)); + + in_initrd_force(true); + assert_se(streq_ptr(runlevel_to_target(NULL), NULL)); + assert_se(streq_ptr(runlevel_to_target("unknown-runlevel"), NULL)); + assert_se(streq_ptr(runlevel_to_target("rd.unknown-runlevel"), NULL)); + assert_se(streq_ptr(runlevel_to_target("3"), NULL)); + assert_se(streq_ptr(runlevel_to_target("rd.rescue"), SPECIAL_RESCUE_TARGET)); +} #endif // 0 int main(void) { @@ -133,6 +195,12 @@ int main(void) { log_open(); test_proc_cmdline_parse(); +#if 0 /// UNNEEDED by elogind + test_proc_cmdline_override(); + test_proc_cmdline_given(false); + /* Repeat the same thing, but now flip our ininitrdness */ + test_proc_cmdline_given(true); +#endif // 0 test_proc_cmdline_key_streq(); #if 0 /// UNNEEDED by elogind test_proc_cmdline_key_startswith(); diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c index f19875dae..6f0472dc0 100644 --- a/src/test/test-process-util.c +++ b/src/test/test-process-util.c @@ -27,6 +27,9 @@ #include "util.h" #include "virt.h" +/// Additional includes needed by elogind +#include "locale-util.h" + static void test_get_process_comm(pid_t pid) { struct stat st; _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL; @@ -113,12 +116,18 @@ static void test_get_process_comm_escape(void) { test_get_process_comm_escape_one("foo", "foo"); test_get_process_comm_escape_one("012345678901234", "012345678901234"); test_get_process_comm_escape_one("0123456789012345", "012345678901234"); +#if 1 /// elogind supports systems with non-UTF-8 locales, the next would fail there + if (is_locale_utf8()) { +#endif // 1 test_get_process_comm_escape_one("äöüß", "\\303\\244\\303…"); test_get_process_comm_escape_one("xäöüß", "x\\303\\244…"); test_get_process_comm_escape_one("xxäöüß", "xx\\303\\244…"); test_get_process_comm_escape_one("xxxäöüß", "xxx\\303\\244…"); test_get_process_comm_escape_one("xxxxäöüß", "xxxx\\303\\244…"); test_get_process_comm_escape_one("xxxxxäöüß", "xxxxx\\303…"); +#if 1 /// elogind supports systems with non-UTF-8 locales, the previous would fail there + } +#endif // 1 assert_se(prctl(PR_SET_NAME, saved) >= 0); } diff --git a/src/test/test-set-disable-mempool.c b/src/test/test-set-disable-mempool.c new file mode 100644 index 000000000..b259c9532 --- /dev/null +++ b/src/test/test-set-disable-mempool.c @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include <pthread.h> + +#include "process-util.h" +#include "set.h" +//#include "tests.h" + +#define NUM 100 + +static void* thread(void *p) { + Set **s = p; + + assert_se(s); + assert_se(*s); + + assert_se(!is_main_thread()); + assert_se(set_size(*s) == NUM); + *s = set_free(*s); + + return NULL; +} + +static void test_one(const char *val) { + pthread_t t; + int x[NUM] = {}; + unsigned i; + Set *s; + + log_info("Testing with SYSTEMD_MEMPOOL=%s", val); + assert_se(setenv("SYSTEMD_MEMPOOL", val, true) == 0); + assert_se(is_main_thread()); + + assert_se(s = set_new(NULL)); + for (i = 0; i < NUM; i++) + assert_se(set_put(s, &x[i])); + + assert_se(pthread_create(&t, NULL, thread, &s) == 0); + assert_se(pthread_join(t, NULL) == 0); + + assert_se(!s); +} + +int main(int argc, char *argv[]) { + log_set_max_level(LOG_DEBUG); + log_parse_environment(); + log_open(); + + test_one("0"); + /* The value $SYSTEMD_MEMPOOL= is cached. So the following + * test should also succeed. */ + test_one("1"); + + return 0; +} diff --git a/src/test/test-string-util.c b/src/test/test-string-util.c index 202af8bcc..54f9b29ef 100644 --- a/src/test/test-string-util.c +++ b/src/test/test-string-util.c @@ -5,6 +5,7 @@ #include "macro.h" #include "string-util.h" #include "strv.h" +//#include "tests.h" #include "utf8.h" static void test_string_erase(void) { @@ -30,6 +31,64 @@ static void test_string_erase(void) { assert_se(x[9] == '\0'); } +static void test_free_and_strndup_one(char **t, const char *src, size_t l, const char *expected, bool change) { + int r; + + log_debug("%s: \"%s\", \"%s\", %zd (expect \"%s\", %s)", + __func__, strnull(*t), strnull(src), l, strnull(expected), yes_no(change)); + + r = free_and_strndup(t, src, l); + assert_se(streq_ptr(*t, expected)); + assert_se(r == change); /* check that change occurs only when necessary */ +} + +static void test_free_and_strndup(void) { + static const struct test_case { + const char *src; + size_t len; + const char *expected; + } cases[] = { + {"abc", 0, ""}, + {"abc", 0, ""}, + {"abc", 1, "a"}, + {"abc", 2, "ab"}, + {"abc", 3, "abc"}, + {"abc", 4, "abc"}, + {"abc", 5, "abc"}, + {"abc", 5, "abc"}, + {"abc", 4, "abc"}, + {"abc", 3, "abc"}, + {"abc", 2, "ab"}, + {"abc", 1, "a"}, + {"abc", 0, ""}, + + {"", 0, ""}, + {"", 1, ""}, + {"", 2, ""}, + {"", 0, ""}, + {"", 1, ""}, + {"", 2, ""}, + {"", 2, ""}, + {"", 1, ""}, + {"", 0, ""}, + + {NULL, 0, NULL}, + + {"foo", 3, "foo"}, + {"foobar", 6, "foobar"}, + }; + + _cleanup_free_ char *t = NULL; + const char *prev_expected = t; + + for (unsigned i = 0; i < ELEMENTSOF(cases); i++) { + test_free_and_strndup_one(&t, + cases[i].src, cases[i].len, cases[i].expected, + !streq_ptr(cases[i].expected, prev_expected)); + prev_expected = t; + } +} + #if 0 /// UNNEEDED by elogind static void test_ascii_strcasecmp_n(void) { @@ -112,6 +171,9 @@ static void test_cellescape(void) { assert_se(streq(cellescape(buf, 1, "\020"), "")); assert_se(streq(cellescape(buf, 2, "\020"), ".")); assert_se(streq(cellescape(buf, 3, "\020"), "..")); +#if 1 /// elogind supports systems with non-UTF-8 locales, the next would fail there + if (is_locale_utf8()) { +#endif // 1 assert_se(streq(cellescape(buf, 4, "\020"), "…")); assert_se(streq(cellescape(buf, 5, "\020"), "\\020")); @@ -119,26 +181,47 @@ static void test_cellescape(void) { assert_se(streq(cellescape(buf, 6, "1234\020"), "12…")); assert_se(streq(cellescape(buf, 7, "1234\020"), "123…")); assert_se(streq(cellescape(buf, 8, "1234\020"), "1234…")); +#if 1 /// elogind supports systems with non-UTF-8 locales, the previous would fail there + } +#endif // 1 assert_se(streq(cellescape(buf, 9, "1234\020"), "1234\\020")); assert_se(streq(cellescape(buf, 1, "\t\n"), "")); assert_se(streq(cellescape(buf, 2, "\t\n"), ".")); assert_se(streq(cellescape(buf, 3, "\t\n"), "..")); +#if 1 /// elogind supports systems with non-UTF-8 locales, the next would fail there + if (is_locale_utf8()) { +#endif // 1 assert_se(streq(cellescape(buf, 4, "\t\n"), "…")); +#if 1 /// elogind supports systems with non-UTF-8 locales, the previous would fail there + } +#endif // 1 assert_se(streq(cellescape(buf, 5, "\t\n"), "\\t\\n")); +#if 1 /// elogind supports systems with non-UTF-8 locales, the next would fail there + if (is_locale_utf8()) { +#endif // 1 assert_se(streq(cellescape(buf, 5, "1234\t\n"), "1…")); assert_se(streq(cellescape(buf, 6, "1234\t\n"), "12…")); assert_se(streq(cellescape(buf, 7, "1234\t\n"), "123…")); assert_se(streq(cellescape(buf, 8, "1234\t\n"), "1234…")); +#if 1 /// elogind supports systems with non-UTF-8 locales, the previous would fail there + } +#endif // 1 assert_se(streq(cellescape(buf, 9, "1234\t\n"), "1234\\t\\n")); +#if 1 /// elogind supports systems with non-UTF-8 locales, the next would fail there + if (is_locale_utf8()) { +#endif // 1 assert_se(streq(cellescape(buf, 4, "x\t\020\n"), "…")); assert_se(streq(cellescape(buf, 5, "x\t\020\n"), "x…")); assert_se(streq(cellescape(buf, 6, "x\t\020\n"), "x…")); assert_se(streq(cellescape(buf, 7, "x\t\020\n"), "x\\t…")); assert_se(streq(cellescape(buf, 8, "x\t\020\n"), "x\\t…")); assert_se(streq(cellescape(buf, 9, "x\t\020\n"), "x\\t…")); +#if 1 /// elogind supports systems with non-UTF-8 locales, the previous would fail there + } +#endif // 1 assert_se(streq(cellescape(buf, 10, "x\t\020\n"), "x\\t\\020\\n")); assert_se(streq(cellescape(buf, 6, "1\011"), "1\\t")); @@ -497,11 +580,39 @@ static void test_memory_startswith(void) { assert_se(streq(memory_startswith("xxx", 4, "x"), "xx")); assert_se(streq(memory_startswith("xxx", 4, "xx"), "x")); assert_se(streq(memory_startswith("xxx", 4, "xxx"), "")); +#if 0 /// This is not used anywhere in elogind and thus masked. assert_se(!memory_startswith("xxx", 4, "xxxx")); +#endif // 0 } +#if 0 /// This is not used anywhere in elogind and thus masked. +static void test_memory_startswith_no_case(void) { + assert_se(streq(memory_startswith_no_case("", 0, ""), "")); + assert_se(streq(memory_startswith_no_case("", 1, ""), "")); + assert_se(streq(memory_startswith_no_case("x", 2, ""), "x")); + assert_se(streq(memory_startswith_no_case("X", 2, ""), "X")); + assert_se(!memory_startswith_no_case("", 1, "X")); + assert_se(!memory_startswith_no_case("", 1, "xxxxXXXX")); + assert_se(streq(memory_startswith_no_case("xxx", 4, "X"), "xx")); + assert_se(streq(memory_startswith_no_case("XXX", 4, "x"), "XX")); + assert_se(streq(memory_startswith_no_case("XXX", 4, "X"), "XX")); + assert_se(streq(memory_startswith_no_case("xxx", 4, "XX"), "x")); + assert_se(streq(memory_startswith_no_case("XXX", 4, "xx"), "X")); + assert_se(streq(memory_startswith_no_case("XXX", 4, "XX"), "X")); + assert_se(streq(memory_startswith_no_case("xxx", 4, "XXX"), "")); + assert_se(streq(memory_startswith_no_case("XXX", 4, "xxx"), "")); + assert_se(streq(memory_startswith_no_case("XXX", 4, "XXX"), "")); + + assert_se(memory_startswith_no_case((char[2]){'x', 'x'}, 2, "xx")); + assert_se(memory_startswith_no_case((char[2]){'x', 'X'}, 2, "xX")); + assert_se(memory_startswith_no_case((char[2]){'X', 'x'}, 2, "Xx")); + assert_se(memory_startswith_no_case((char[2]){'X', 'X'}, 2, "XX")); +} +#endif // 0 + int main(int argc, char *argv[]) { test_string_erase(); + test_free_and_strndup(); #if 0 /// UNNEEDED by elogind test_ascii_strcasecmp_n(); test_ascii_strcasecmp_nn(); @@ -533,6 +644,9 @@ int main(int argc, char *argv[]) { test_first_word(); test_strlen_ptr(); test_memory_startswith(); - +#if 0 /// This is not used anywhere in elogind and thus masked. + test_memory_startswith_no_case(); +#endif // 0 + return 0; } |