diff options
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/test-conf-parser.c | 234 | ||||
-rw-r--r-- | src/test/test-fdset.c | 53 | ||||
-rw-r--r-- | src/test/test-hashmap-plain.c | 2 | ||||
-rw-r--r-- | src/test/test-json.c | 96 | ||||
-rw-r--r-- | src/test/test-path-util.c | 76 | ||||
-rw-r--r-- | src/test/test-pty.c | 1 | ||||
-rw-r--r-- | src/test/test-udev.c | 7 | ||||
-rw-r--r-- | src/test/test-unit-file.c | 19 | ||||
-rw-r--r-- | src/test/test-util.c | 55 |
9 files changed, 522 insertions, 21 deletions
diff --git a/src/test/test-conf-parser.c b/src/test/test-conf-parser.c new file mode 100644 index 0000000000..463906d304 --- /dev/null +++ b/src/test/test-conf-parser.c @@ -0,0 +1,234 @@ +/*** + This file is part of systemd. + + Copyright 2015 Ronny Chevalier + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include "conf-parser.h" +#include "macro.h" +#include "util.h" +#include "strv.h" +#include "log.h" + +static void test_config_parse_path_one(const char *rvalue, const char *expected) { + char *path = NULL; + + assert_se(config_parse_path("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue, &path, NULL) >= 0); + assert_se(streq_ptr(expected, path)); + + free(path); +} + +static void test_config_parse_log_level_one(const char *rvalue, int expected) { + int log_level = 0; + + assert_se(config_parse_log_level("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue, &log_level, NULL) >= 0); + assert_se(expected == log_level); +} + +static void test_config_parse_log_facility_one(const char *rvalue, int expected) { + int log_facility = 0; + + assert_se(config_parse_log_facility("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue, &log_facility, NULL) >= 0); + assert_se(expected == log_facility); +} + +static void test_config_parse_iec_size_one(const char *rvalue, size_t expected) { + size_t iec_size = 0; + + assert_se(config_parse_iec_size("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue, &iec_size, NULL) >= 0); + assert_se(expected == iec_size); +} + +static void test_config_parse_si_size_one(const char *rvalue, size_t expected) { + size_t si_size = 0; + + assert_se(config_parse_si_size("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue, &si_size, NULL) >= 0); + assert_se(expected == si_size); +} + +static void test_config_parse_int_one(const char *rvalue, int expected) { + int v = -1; + + assert_se(config_parse_int("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue, &v, NULL) >= 0); + assert_se(expected == v); +} + +static void test_config_parse_unsigned_one(const char *rvalue, unsigned expected) { + unsigned v = 0; + + assert_se(config_parse_unsigned("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue, &v, NULL) >= 0); + assert_se(expected == v); +} + +static void test_config_parse_strv_one(const char *rvalue, char **expected) { + char **strv = 0; + + assert_se(config_parse_strv("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue, &strv, NULL) >= 0); + assert_se(strv_equal(expected, strv)); + + strv_free(strv); +} + +static void test_config_parse_mode_one(const char *rvalue, mode_t expected) { + mode_t v = 0; + + assert_se(config_parse_mode("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue, &v, NULL) >= 0); + assert_se(expected == v); +} + +static void test_config_parse_sec_one(const char *rvalue, usec_t expected) { + usec_t v = 0; + + assert_se(config_parse_sec("unit", "filename", 1, "section", 1, "lvalue", 0, rvalue, &v, NULL) >= 0); + assert_se(expected == v); +} + +static void test_config_parse_nsec_one(const char *rvalue, nsec_t expected) { + nsec_t v = 0; + + assert_se(config_parse_nsec("unit", "filename", 1, "nsection", 1, "lvalue", 0, rvalue, &v, NULL) >= 0); + assert_se(expected == v); +} + +static void test_config_parse_path(void) { + test_config_parse_path_one("/path", "/path"); + test_config_parse_path_one("/path//////////", "/path"); + test_config_parse_path_one("///path/foo///bar////bar//", "/path/foo/bar/bar"); + + test_config_parse_path_one("not_absolute/path", NULL); +} + +static void test_config_parse_log_level(void) { + test_config_parse_log_level_one("debug", LOG_DEBUG); + test_config_parse_log_level_one("info", LOG_INFO); + + test_config_parse_log_level_one("garbage", 0); +} + +static void test_config_parse_log_facility(void) { + test_config_parse_log_facility_one("mail", LOG_MAIL); + test_config_parse_log_facility_one("user", LOG_USER); + + test_config_parse_log_facility_one("garbage", 0); +} + +static void test_config_parse_iec_size(void) { + test_config_parse_iec_size_one("1024", 1024); + test_config_parse_iec_size_one("2K", 2048); + test_config_parse_iec_size_one("10M", 10 * 1024 * 1024); + test_config_parse_iec_size_one("1G", 1 * 1024 * 1024 * 1024); + test_config_parse_iec_size_one("0G", 0); + test_config_parse_iec_size_one("0", 0); + + test_config_parse_iec_size_one("-982", 0); + test_config_parse_iec_size_one("49874444198739873000000G", 0); + test_config_parse_iec_size_one("garbage", 0); +} + +static void test_config_parse_si_size(void) { + test_config_parse_si_size_one("1024", 1024); + test_config_parse_si_size_one("2K", 2000); + test_config_parse_si_size_one("10M", 10 * 1000 * 1000); + test_config_parse_si_size_one("1G", 1 * 1000 * 1000 * 1000); + test_config_parse_si_size_one("0G", 0); + test_config_parse_si_size_one("0", 0); + + test_config_parse_si_size_one("-982", 0); + test_config_parse_si_size_one("49874444198739873000000G", 0); + test_config_parse_si_size_one("garbage", 0); +} + +static void test_config_parse_int(void) { + test_config_parse_int_one("1024", 1024); + test_config_parse_int_one("-1024", -1024); + test_config_parse_int_one("0", 0); + + test_config_parse_int_one("99999999999999999999999999999999999999999999999999999999", -1); + test_config_parse_int_one("-99999999999999999999999999999999999999999999999999999999", -1); + test_config_parse_int_one("1G", -1); + test_config_parse_int_one("garbage", -1); +} + +static void test_config_parse_unsigned(void) { + test_config_parse_unsigned_one("10241024", 10241024); + test_config_parse_unsigned_one("1024", 1024); + test_config_parse_unsigned_one("0", 0); + + test_config_parse_unsigned_one("99999999999999999999999999999999999999999999999999999999", 0); + test_config_parse_unsigned_one("1G", 0); + test_config_parse_unsigned_one("garbage", 0); + test_config_parse_unsigned_one("1000garbage", 0); +} + +static void test_config_parse_strv(void) { + test_config_parse_strv_one("", STRV_MAKE_EMPTY); + test_config_parse_strv_one("foo", STRV_MAKE("foo")); + test_config_parse_strv_one("foo bar foo", STRV_MAKE("foo", "bar", "foo")); + test_config_parse_strv_one("\"foo bar\" foo", STRV_MAKE("foo bar", "foo")); +} + +static void test_config_parse_mode(void) { + test_config_parse_mode_one("777", 0777); + test_config_parse_mode_one("644", 0644); + + test_config_parse_mode_one("-777", 0); + test_config_parse_mode_one("999", 0); + test_config_parse_mode_one("garbage", 0); + test_config_parse_mode_one("777garbage", 0); + test_config_parse_mode_one("777 garbage", 0); +} + +static void test_config_parse_sec(void) { + test_config_parse_sec_one("1", 1 * USEC_PER_SEC); + test_config_parse_sec_one("1s", 1 * USEC_PER_SEC); + test_config_parse_sec_one("100ms", 100 * USEC_PER_MSEC); + test_config_parse_sec_one("5min 20s", 5 * 60 * USEC_PER_SEC + 20 * USEC_PER_SEC); + + test_config_parse_sec_one("-1", 0); + test_config_parse_sec_one("10foo", 0); + test_config_parse_sec_one("garbage", 0); +} + +static void test_config_parse_nsec(void) { + test_config_parse_nsec_one("1", 1); + test_config_parse_nsec_one("1s", 1 * NSEC_PER_SEC); + test_config_parse_nsec_one("100ms", 100 * NSEC_PER_MSEC); + test_config_parse_nsec_one("5min 20s", 5 * 60 * NSEC_PER_SEC + 20 * NSEC_PER_SEC); + + test_config_parse_nsec_one("-1", 0); + test_config_parse_nsec_one("10foo", 0); + test_config_parse_nsec_one("garbage", 0); +} + +int main(int argc, char **argv) { + log_parse_environment(); + log_open(); + + test_config_parse_path(); + test_config_parse_log_level(); + test_config_parse_log_facility(); + test_config_parse_iec_size(); + test_config_parse_si_size(); + test_config_parse_int(); + test_config_parse_unsigned(); + test_config_parse_strv(); + test_config_parse_mode(); + test_config_parse_sec(); + test_config_parse_nsec(); + + return 0; +} diff --git a/src/test/test-fdset.c b/src/test/test-fdset.c index 91df7eb663..242c5d9dc2 100644 --- a/src/test/test-fdset.c +++ b/src/test/test-fdset.c @@ -154,6 +154,56 @@ static void test_fdset_iterate(void) { unlink(name); } +static void test_fdset_isempty(void) { + int fd; + _cleanup_fdset_free_ FDSet *fdset = NULL; + char name[] = "/tmp/test-fdset_isempty.XXXXXX"; + + fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + assert_se(fd >= 0); + + fdset = fdset_new(); + assert_se(fdset); + + assert_se(fdset_isempty(fdset)); + assert_se(fdset_put(fdset, fd) >= 0); + assert_se(!fdset_isempty(fdset)); + + unlink(name); +} + +static void test_fdset_steal_first(void) { + int fd; + _cleanup_fdset_free_ FDSet *fdset = NULL; + char name[] = "/tmp/test-fdset_steal_first.XXXXXX"; + + fd = mkostemp_safe(name, O_RDWR|O_CLOEXEC); + assert_se(fd >= 0); + + fdset = fdset_new(); + assert_se(fdset); + + assert_se(fdset_steal_first(fdset) < 0); + assert_se(fdset_put(fdset, fd) >= 0); + assert_se(fdset_steal_first(fdset) == fd); + assert_se(fdset_steal_first(fdset) < 0); + assert_se(fdset_put(fdset, fd) >= 0); + + unlink(name); +} + +static void test_fdset_new_array(void) { + int fds[] = {10, 11, 12, 13}; + _cleanup_fdset_free_ FDSet *fdset = NULL; + + assert_se(fdset_new_array(&fdset, fds, 4) >= 0); + assert_se(fdset_size(fdset) == 4); + assert_se(fdset_contains(fdset, 10)); + assert_se(fdset_contains(fdset, 11)); + assert_se(fdset_contains(fdset, 12)); + assert_se(fdset_contains(fdset, 13)); +} + int main(int argc, char *argv[]) { test_fdset_new_fill(); test_fdset_put_dup(); @@ -161,6 +211,9 @@ int main(int argc, char *argv[]) { test_fdset_close_others(); test_fdset_remove(); test_fdset_iterate(); + test_fdset_isempty(); + test_fdset_steal_first(); + test_fdset_new_array(); return 0; } diff --git a/src/test/test-hashmap-plain.c b/src/test/test-hashmap-plain.c index 84b508f874..c1a5ccf1f5 100644 --- a/src/test/test-hashmap-plain.c +++ b/src/test/test-hashmap-plain.c @@ -682,7 +682,7 @@ static void test_hashmap_get2(void) { r = hashmap_get2(m, key_orig, &key_copy); assert_se(streq(r, val)); assert_se(key_orig != key_copy); - assert_se(streq(key_orig, key_orig)); + assert_se(streq(key_orig, key_copy)); r = hashmap_get2(m, "no such key", NULL); assert_se(r == NULL); diff --git a/src/test/test-json.c b/src/test/test-json.c index 24dc7003bc..1058c583c3 100644 --- a/src/test/test-json.c +++ b/src/test/test-json.c @@ -72,6 +72,97 @@ static void test_one(const char *data, ...) { va_end(ap); } +typedef void (*Test)(JsonVariant *); + +static void test_file(const char *data, Test test) { + _cleanup_json_variant_unref_ JsonVariant *v = NULL; + int r; + + r = json_parse(data, &v); + assert_se(r == 0); + assert_se(v != NULL); + assert_se(v->type == JSON_VARIANT_OBJECT); + + if (test) + test(v); +} + +static void test_1(JsonVariant *v) { + JsonVariant *p, *q; + unsigned i; + + /* 3 keys + 3 values */ + assert_se(v->size == 6); + + /* has k */ + p = json_variant_value(v, "k"); + assert_se(p && p->type == JSON_VARIANT_STRING); + + /* k equals v */ + assert_se(streq(json_variant_string(p), "v")); + + /* has foo */ + p = json_variant_value(v, "foo"); + assert_se(p && p->type == JSON_VARIANT_ARRAY && p->size == 3); + + /* check foo[0] = 1, foo[1] = 2, foo[2] = 3 */ + for (i = 0; i < 3; ++i) { + q = json_variant_element(p, i); + assert_se(q && q->type == JSON_VARIANT_INTEGER && json_variant_integer(q) == (i+1)); + } + + /* has bar */ + p = json_variant_value(v, "bar"); + assert_se(p && p->type == JSON_VARIANT_OBJECT && p->size == 2); + + /* zap is null */ + q = json_variant_value(p, "zap"); + assert_se(q && q->type == JSON_VARIANT_NULL); +} + +static void test_2(JsonVariant *v) { + JsonVariant *p, *q; + + /* 2 keys + 2 values */ + assert_se(v->size == 4); + + /* has mutant */ + p = json_variant_value(v, "mutant"); + assert_se(p && p->type == JSON_VARIANT_ARRAY && p->size == 4); + + /* mutant[0] == 1 */ + q = json_variant_element(p, 0); + assert_se(q && q->type == JSON_VARIANT_INTEGER && json_variant_integer(q) == 1); + + /* mutant[1] == null */ + q = json_variant_element(p, 1); + assert_se(q && q->type == JSON_VARIANT_NULL); + + /* mutant[2] == "1" */ + q = json_variant_element(p, 2); + assert_se(q && q->type == JSON_VARIANT_STRING && streq(json_variant_string(q), "1")); + + /* mutant[3] == JSON_VARIANT_OBJECT */ + q = json_variant_element(p, 3); + assert_se(q && q->type == JSON_VARIANT_OBJECT && q->size == 2); + + /* has 1 */ + p = json_variant_value(q, "1"); + assert_se(p && p->type == JSON_VARIANT_ARRAY && p->size == 2); + + /* "1"[0] == 1 */ + q = json_variant_element(p, 0); + assert_se(q && q->type == JSON_VARIANT_INTEGER && json_variant_integer(q) == 1); + + /* "1"[1] == "1" */ + q = json_variant_element(p, 1); + assert_se(q && q->type == JSON_VARIANT_STRING && streq(json_variant_string(q), "1")); + + /* has blah */ + p = json_variant_value(v, "blah"); + assert_se(p && p->type == JSON_VARIANT_REAL && fabs(json_variant_real(p) - 1.27) < 0.001); +} + int main(int argc, char *argv[]) { test_one("x", -EINVAL); @@ -102,5 +193,10 @@ int main(int argc, char *argv[]) { test_one("\"\\udc00\\udc00\"", -EINVAL); test_one("\"\\ud801\\udc37\"", JSON_STRING, "\xf0\x90\x90\xb7", JSON_END); + test_one("[1, 2]", JSON_ARRAY_OPEN, JSON_INTEGER, (intmax_t) 1, JSON_COMMA, JSON_INTEGER, (intmax_t) 2, JSON_ARRAY_CLOSE, JSON_END); + + test_file("{\"k\": \"v\", \"foo\": [1, 2, 3], \"bar\": {\"zap\": null}}", test_1); + test_file("{\"mutant\": [1, null, \"1\", {\"1\": [1, \"1\"]}], \"blah\": 1.27}", test_2); + return 0; } diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c index 09f0f2f89e..0045ae6824 100644 --- a/src/test/test-path-util.c +++ b/src/test/test-path-util.c @@ -21,6 +21,7 @@ #include <stdio.h> #include <unistd.h> +#include <sys/mount.h> #include "path-util.h" #include "util.h" @@ -88,21 +89,9 @@ static void test_path(void) { test_parent("/aa///file...", "/aa///"); test_parent("file.../", NULL); - assert_se(path_is_mount_point("/", true) > 0); - assert_se(path_is_mount_point("/", false) > 0); - fd = open("/", O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY); assert_se(fd >= 0); - assert_se(fd_is_mount_point(fd) > 0); - - assert_se(path_is_mount_point("/proc", true) > 0); - assert_se(path_is_mount_point("/proc", false) > 0); - - assert_se(path_is_mount_point("/proc/1", true) == 0); - assert_se(path_is_mount_point("/proc/1", false) == 0); - - assert_se(path_is_mount_point("/sys", true) > 0); - assert_se(path_is_mount_point("/sys", false) > 0); + assert_se(fd_is_mount_point(fd, "/", 0) > 0); { char p1[] = "aaa/bbb////ccc"; @@ -322,6 +311,66 @@ static void test_prefix_root(void) { test_prefix_root_one("/foo///", "//bar", "/foo/bar"); } +static void test_path_is_mount_point(void) { + int fd, rt, rf, rlt, rlf; + char tmp_dir[] = "/tmp/test-path-is-mount-point-XXXXXX"; + _cleanup_free_ char *file1 = NULL, *file2 = NULL, *link1 = NULL, *link2 = NULL; + + assert_se(path_is_mount_point("/", AT_SYMLINK_FOLLOW) > 0); + assert_se(path_is_mount_point("/", 0) > 0); + + assert_se(path_is_mount_point("/proc", AT_SYMLINK_FOLLOW) > 0); + assert_se(path_is_mount_point("/proc", 0) > 0); + + assert_se(path_is_mount_point("/proc/1", AT_SYMLINK_FOLLOW) == 0); + assert_se(path_is_mount_point("/proc/1", 0) == 0); + + assert_se(path_is_mount_point("/sys", AT_SYMLINK_FOLLOW) > 0); + assert_se(path_is_mount_point("/sys", 0) > 0); + + /* file mountpoints */ + assert_se(mkdtemp(tmp_dir) != NULL); + file1 = path_join(NULL, tmp_dir, "file1"); + assert_se(file1); + file2 = path_join(NULL, tmp_dir, "file2"); + assert_se(file2); + fd = open(file1, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, 0664); + assert_se(fd > 0); + close(fd); + fd = open(file2, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, 0664); + assert_se(fd > 0); + close(fd); + link1 = path_join(NULL, tmp_dir, "link1"); + assert_se(link1); + assert_se(symlink("file1", link1) == 0); + link2 = path_join(NULL, tmp_dir, "link2"); + assert_se(link1); + assert_se(symlink("file2", link2) == 0); + + assert_se(path_is_mount_point(file1, AT_SYMLINK_FOLLOW) == 0); + assert_se(path_is_mount_point(file1, 0) == 0); + assert_se(path_is_mount_point(link1, AT_SYMLINK_FOLLOW) == 0); + assert_se(path_is_mount_point(link1, 0) == 0); + + /* this test will only work as root */ + if (mount(file1, file2, NULL, MS_BIND, NULL) >= 0) { + rf = path_is_mount_point(file2, 0); + rt = path_is_mount_point(file2, AT_SYMLINK_FOLLOW); + rlf = path_is_mount_point(link2, 0); + rlt = path_is_mount_point(link2, AT_SYMLINK_FOLLOW); + + assert_se(umount(file2) == 0); + + assert_se(rf == 1); + assert_se(rt == 1); + assert_se(rlf == 0); + assert_se(rlt == 1); + } else + printf("Skipping bind mount file test: %m\n"); + + assert_se(rm_rf(tmp_dir, REMOVE_ROOT|REMOVE_PHYSICAL) == 0); +} + int main(int argc, char **argv) { test_path(); test_find_binary(argv[0], true); @@ -333,6 +382,7 @@ int main(int argc, char **argv) { test_strv_resolve(); test_path_startswith(); test_prefix_root(); + test_path_is_mount_point(); return 0; } diff --git a/src/test/test-pty.c b/src/test/test-pty.c index b5f4d4f094..f8807c9150 100644 --- a/src/test/test-pty.c +++ b/src/test/test-pty.c @@ -27,6 +27,7 @@ #include "pty.h" #include "util.h" +#include "signal-util.h" static const char sndmsg[] = "message\n"; static const char rcvmsg[] = "message\r\n"; diff --git a/src/test/test-udev.c b/src/test/test-udev.c index 23b7faa939..f3953fe26a 100644 --- a/src/test/test-udev.c +++ b/src/test/test-udev.c @@ -120,11 +120,6 @@ int main(int argc, char *argv[]) { sigfillset(&mask); sigprocmask(SIG_SETMASK, &mask, &sigmask_orig); - event->fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC); - if (event->fd_signal < 0) { - fprintf(stderr, "error creating signalfd\n"); - goto out; - } /* do what devtmpfs usually provides us */ if (udev_device_get_devnode(dev) != NULL) { @@ -153,8 +148,6 @@ int main(int argc, char *argv[]) { 3 * USEC_PER_SEC, USEC_PER_SEC, NULL); out: - if (event != NULL && event->fd_signal >= 0) - close(event->fd_signal); mac_selinux_finish(); return err ? EXIT_FAILURE : EXIT_SUCCESS; diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c index a9711ac9f5..31b12d50d7 100644 --- a/src/test/test-unit-file.c +++ b/src/test/test-unit-file.c @@ -225,6 +225,15 @@ static void test_config_parse_exec(void) { check_execcommand(c1, "/sbin/find", NULL, ";", "x", false); + log_info("/* encoded semicolon */"); + r = config_parse_exec(NULL, "fake", 5, "section", 1, + "LValue", 0, + "/bin/find \\073", + &c, NULL); + assert_se(r >= 0); + c1 = c1->command_next; + check_execcommand(c1, "/bin/find", NULL, "\\073", NULL, false); + log_info("/* spaces in the filename */"); r = config_parse_exec(NULL, "fake", 5, "section", 1, "LValue", 0, @@ -296,6 +305,16 @@ static void test_config_parse_exec(void) { c1 = c1->command_next; check_execcommand(c1, "/path ", NULL, NULL, NULL, false); + log_info("/* quoted backslashes */"); + r = config_parse_exec(NULL, "fake", 5, "section", 1, + "LValue", 0, + "/bin/grep '\\w+\\K'", + &c, NULL); + assert_se(r >= 0); + c1 = c1->command_next; + check_execcommand(c1, "/bin/grep", NULL, "\\w+\\K", NULL, false); + + log_info("/* trailing backslash: \\ */"); /* backslash is invalid */ r = config_parse_exec(NULL, "fake", 4, "section", 1, diff --git a/src/test/test-util.c b/src/test/test-util.c index 9af3e757e3..e0269821d7 100644 --- a/src/test/test-util.c +++ b/src/test/test-util.c @@ -39,6 +39,7 @@ #include "virt.h" #include "process-util.h" #include "hostname-util.h" +#include "signal-util.h" static void test_streq_ptr(void) { assert_se(streq_ptr(NULL, NULL)); @@ -549,6 +550,59 @@ static void test_hostname_is_valid(void) { assert_se(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")); } +static void test_read_hostname_config(void) { + char path[] = "/tmp/hostname.XXXXXX"; + char *hostname; + int fd; + + fd = mkostemp_safe(path, O_RDWR|O_CLOEXEC); + assert(fd > 0); + close(fd); + + /* simple hostname */ + write_string_file(path, "foo"); + assert_se(read_hostname_config(path, &hostname) == 0); + assert_se(streq(hostname, "foo")); + free(hostname); + hostname = NULL; + + /* with comment */ + write_string_file(path, "# comment\nfoo"); + assert_se(read_hostname_config(path, &hostname) == 0); + assert_se(hostname); + assert_se(streq(hostname, "foo")); + free(hostname); + hostname = NULL; + + /* with comment and extra whitespace */ + write_string_file(path, "# comment\n\n foo "); + assert_se(read_hostname_config(path, &hostname) == 0); + assert_se(hostname); + assert_se(streq(hostname, "foo")); + free(hostname); + hostname = NULL; + + /* cleans up name */ + write_string_file(path, "!foo/bar.com"); + assert_se(read_hostname_config(path, &hostname) == 0); + assert_se(hostname); + assert_se(streq(hostname, "foobar.com")); + free(hostname); + hostname = NULL; + + /* no value set */ + hostname = (char*) 0x1234; + write_string_file(path, "# nothing here\n"); + assert_se(read_hostname_config(path, &hostname) == -ENOENT); + assert_se(hostname == (char*) 0x1234); /* does not touch argument on error */ + + /* nonexisting file */ + assert_se(read_hostname_config("/non/existing", &hostname) == -ENOENT); + assert_se(hostname == (char*) 0x1234); /* does not touch argument on error */ + + unlink(path); +} + static void test_u64log2(void) { assert_se(u64log2(0) == 0); assert_se(u64log2(8) == 3); @@ -1481,6 +1535,7 @@ int main(int argc, char *argv[]) { test_foreach_word_quoted(); test_memdup_multiply(); test_hostname_is_valid(); + test_read_hostname_config(); test_u64log2(); test_protect_errno(); test_parse_size(); |