summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/meson.build20
-rw-r--r--src/test/test-chown-rec.c160
-rw-r--r--src/test/test-exec-util.c43
-rw-r--r--src/test/test-format-table.c42
-rw-r--r--src/test/test-proc-cmdline.c96
-rw-r--r--src/test/test-process-util.c9
-rw-r--r--src/test/test-set-disable-mempool.c55
-rw-r--r--src/test/test-string-util.c116
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;
}