X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Ftest%2Ftest-util.c;h=875aeab3d582b20785d1bb8acfed4c090ed597eb;hp=cb0af4f6a12e9f7d340c05800b189a70f74ff573;hb=998b087f70505decbfe55afd27fc4ade3d60ce52;hpb=37d3ab1b7e114f0fb6dfb2e7273569b42794b76a diff --git a/src/test/test-util.c b/src/test/test-util.c index cb0af4f6a..875aeab3d 100644 --- a/src/test/test-util.c +++ b/src/test/test-util.c @@ -21,6 +21,10 @@ ***/ #include +#include +#include +#include +#include #include "util.h" @@ -43,6 +47,29 @@ static void test_first_word(void) { assert_se(!first_word("Hellooo", "Hello")); } +static void test_close_many(void) { + int fds[3]; + char name0[] = "/tmp/test-close-many.XXXXXX"; + char name1[] = "/tmp/test-close-many.XXXXXX"; + char name2[] = "/tmp/test-close-many.XXXXXX"; + + fds[0] = mkstemp(name0); + fds[1] = mkstemp(name1); + fds[2] = mkstemp(name2); + + close_many(fds, 2); + + assert_se(fcntl(fds[0], F_GETFD) == -1); + assert_se(fcntl(fds[1], F_GETFD) == -1); + assert_se(fcntl(fds[2], F_GETFD) >= 0); + + close_nointr_nofail(fds[2]); + + unlink(name0); + unlink(name1); + unlink(name2); +} + static void test_parse_boolean(void) { assert_se(parse_boolean("1") == 1); assert_se(parse_boolean("y") == 1); @@ -120,35 +147,85 @@ static void test_safe_atolli(void) { static void test_safe_atod(void) { int r; double d; + char *e; + + r = safe_atod("junk", &d); + assert_se(r == -EINVAL); r = safe_atod("0.2244", &d); assert_se(r == 0); assert_se(abs(d - 0.2244) < 0.000001); - r = safe_atod("junk", &d); + r = safe_atod("0,5", &d); + assert_se(r == -EINVAL); + + errno = 0; + strtod("0,5", &e); + assert_se(*e == ','); + + /* Check if this really is locale independent */ + setlocale(LC_NUMERIC, "de_DE.utf8"); + + r = safe_atod("0.2244", &d); + assert_se(r == 0); + assert_se(abs(d - 0.2244) < 0.000001); + + r = safe_atod("0,5", &d); + assert_se(r == -EINVAL); + + errno = 0; + assert_se(abs(strtod("0,5", &e) - 0.5) < 0.00001); + + /* And check again, reset */ + setlocale(LC_NUMERIC, "C"); + + r = safe_atod("0.2244", &d); + assert_se(r == 0); + assert_se(abs(d - 0.2244) < 0.000001); + + r = safe_atod("0,5", &d); assert_se(r == -EINVAL); + + errno = 0; + strtod("0,5", &e); + assert_se(*e == ','); } -static void test_strstrip(void) { - char *r; - char input[] = " hello, waldo. "; +static void test_strappend(void) { + _cleanup_free_ char *t1, *t2, *t3, *t4; - r = strstrip(input); - assert_se(streq(r, "hello, waldo.")); + t1 = strappend(NULL, NULL); + assert_se(streq(t1, "")); + + t2 = strappend(NULL, "suf"); + assert_se(streq(t2, "suf")); + + t3 = strappend("pre", NULL); + assert_se(streq(t3, "pre")); + + t4 = strappend("pre", "suf"); + assert_se(streq(t4, "presuf")); +} + +static void test_strstrip(void) { + char *r; + char input[] = " hello, waldo. "; + r = strstrip(input); + assert_se(streq(r, "hello, waldo.")); } static void test_delete_chars(void) { - char *r; - char input[] = " hello, waldo. abc"; + char *r; + char input[] = " hello, waldo. abc"; - r = delete_chars(input, WHITESPACE); - assert_se(streq(r, "hello,waldo.abc")); + r = delete_chars(input, WHITESPACE); + assert_se(streq(r, "hello,waldo.abc")); } static void test_in_charset(void) { - assert_se(in_charset("dddaaabbbcccc", "abcd")); - assert_se(!in_charset("dddaaabbbcccc", "abc f")); + assert_se(in_charset("dddaaabbbcccc", "abcd")); + assert_se(!in_charset("dddaaabbbcccc", "abc f")); } static void test_hexchar(void) { @@ -182,6 +259,18 @@ static void test_undecchar(void) { assert_se(undecchar('9') == 9); } +static void test_cescape(void) { + _cleanup_free_ char *escaped; + escaped = cescape("abc\\\"\b\f\n\r\t\v\003\177\234\313"); + assert_se(streq(escaped, "abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\003\\177\\234\\313")); +} + +static void test_cunescape(void) { + _cleanup_free_ char *unescaped; + unescaped = cunescape("abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\003\\177\\234\\313"); + assert_se(streq(unescaped, "abc\\\"\b\f\n\r\t\v\003\177\234\313")); +} + static void test_foreach_word(void) { char *w, *state; size_t l; @@ -261,14 +350,208 @@ static void test_memdup_multiply(void) { free(dup); } +static void test_bus_path_escape_one(const char *a, const char *b) { + _cleanup_free_ char *t = NULL, *x = NULL, *y = NULL; + + assert_se(t = bus_path_escape(a)); + assert_se(streq(t, b)); + + assert_se(x = bus_path_unescape(t)); + assert_se(streq(a, x)); + + assert_se(y = bus_path_unescape(b)); + assert_se(streq(a, y)); +} + +static void test_bus_path_escape(void) { + test_bus_path_escape_one("foo123bar", "foo123bar"); + test_bus_path_escape_one("foo.bar", "foo_2ebar"); + test_bus_path_escape_one("foo_2ebar", "foo_5f2ebar"); + test_bus_path_escape_one("", "_"); + test_bus_path_escape_one("_", "_5f"); + test_bus_path_escape_one("1", "_31"); + test_bus_path_escape_one(":1", "_3a1"); +} + +static void test_hostname_is_valid(void) { + assert(hostname_is_valid("foobar")); + assert(hostname_is_valid("foobar.com")); + assert(!hostname_is_valid("fööbar")); + assert(!hostname_is_valid("")); + assert(!hostname_is_valid(".")); + assert(!hostname_is_valid("..")); + assert(!hostname_is_valid("foobar.")); + assert(!hostname_is_valid(".foobar")); + assert(!hostname_is_valid("foo..bar")); + assert(!hostname_is_valid("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")); +} + +static void test_u64log2(void) { + assert(u64log2(0) == 0); + assert(u64log2(8) == 3); + assert(u64log2(9) == 3); + assert(u64log2(15) == 3); + assert(u64log2(16) == 4); + assert(u64log2(1024*1024) == 20); + assert(u64log2(1024*1024+5) == 20); +} + +static void test_get_process_comm(void) { + _cleanup_free_ char *a = NULL, *c = NULL, *d = NULL, *f = NULL, *i = NULL; + unsigned long long b; + pid_t e; + uid_t u; + gid_t g; + dev_t h; + int r; + + assert_se(get_process_comm(1, &a) >= 0); + log_info("pid1 comm: '%s'", a); + + assert_se(get_starttime_of_pid(1, &b) >= 0); + log_info("pid1 starttime: '%llu'", b); + + assert_se(get_process_cmdline(1, 0, true, &c) >= 0); + log_info("pid1 cmdline: '%s'", c); + + assert_se(get_process_cmdline(1, 8, false, &d) >= 0); + log_info("pid1 cmdline truncated: '%s'", d); + + assert_se(get_parent_of_pid(1, &e) >= 0); + log_info("pid1 ppid: '%llu'", (unsigned long long) e); + assert_se(e == 0); + + assert_se(is_kernel_thread(1) == 0); + + r = get_process_exe(1, &f); + assert_se(r >= 0 || r == -EACCES); + log_info("pid1 exe: '%s'", strna(f)); + + assert_se(get_process_uid(1, &u) == 0); + log_info("pid1 uid: '%llu'", (unsigned long long) u); + assert_se(u == 0); + + assert_se(get_process_gid(1, &g) == 0); + log_info("pid1 gid: '%llu'", (unsigned long long) g); + assert_se(g == 0); + + assert(get_ctty_devnr(1, &h) == -ENOENT); + + getenv_for_pid(1, "PATH", &i); + log_info("pid1 $PATH: '%s'", strna(i)); +} + +static void test_protect_errno(void) { + errno = 12; + { + PROTECT_ERRNO; + errno = 11; + } + assert(errno == 12); +} + +static void test_parse_bytes(void) { + off_t bytes; + + assert_se(parse_bytes("111", &bytes) == 0); + assert_se(bytes == 111); + + assert_se(parse_bytes(" 112 B", &bytes) == 0); + assert_se(bytes == 112); + + assert_se(parse_bytes("3 K", &bytes) == 0); + assert_se(bytes == 3*1024); + + assert_se(parse_bytes(" 4 M 11K", &bytes) == 0); + assert_se(bytes == 4*1024*1024 + 11 * 1024); + + assert_se(parse_bytes("3B3G", &bytes) == 0); + assert_se(bytes == 3ULL*1024*1024*1024 + 3); + + assert_se(parse_bytes("3B3G4T", &bytes) == 0); + assert_se(bytes == (4ULL*1024 + 3)*1024*1024*1024 + 3); + + assert_se(parse_bytes("12P", &bytes) == 0); + assert_se(bytes == 12ULL * 1024*1024*1024*1024*1024); + + assert_se(parse_bytes("3E 2P", &bytes) == 0); + assert_se(bytes == (3 * 1024 + 2ULL) * 1024*1024*1024*1024*1024); + + assert_se(parse_bytes("12X", &bytes) == -EINVAL); + + assert_se(parse_bytes("1024E", &bytes) == -ERANGE); + assert_se(parse_bytes("-1", &bytes) == -ERANGE); + assert_se(parse_bytes("-1024E", &bytes) == -ERANGE); + + assert_se(parse_bytes("-1024P", &bytes) == -ERANGE); + + assert_se(parse_bytes("-10B 20K", &bytes) == -ERANGE); +} + +static void test_strextend(void) { + _cleanup_free_ char *str = strdup("0123"); + strextend(&str, "456", "78", "9", NULL); + assert_se(streq(str, "0123456789")); +} + +static void test_strrep(void) { + _cleanup_free_ char *one, *three, *zero; + one = strrep("waldo", 1); + three = strrep("waldo", 3); + zero = strrep("waldo", 0); + + assert_se(streq(one, "waldo")); + assert_se(streq(three, "waldowaldowaldo")); + assert_se(streq(zero, "")); +} + +static void test_parse_user_at_host(void) { + _cleanup_free_ char *both = strdup("waldo@waldoscomputer"); + _cleanup_free_ char *onlyhost = strdup("mikescomputer"); + char *user = NULL, *host = NULL; + + parse_user_at_host(both, &user, &host); + assert_se(streq(user, "waldo")); + assert_se(streq(host, "waldoscomputer")); + + user = host = NULL; + parse_user_at_host(onlyhost, &user, &host); + assert_se(user == NULL); + assert_se(streq(host, "mikescomputer")); +} + +static void test_split_pair(void) { + _cleanup_free_ char *a = NULL, *b = NULL; + + assert_se(split_pair("", "", &a, &b) == -EINVAL); + assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL); + assert_se(split_pair("", "=", &a, &b) == -EINVAL); + assert_se(split_pair("foo=bar", "=", &a, &b) >= 0); + assert_se(streq(a, "foo")); + assert_se(streq(b, "bar")); + free(a); + free(b); + assert_se(split_pair("==", "==", &a, &b) >= 0); + assert_se(streq(a, "")); + assert_se(streq(b, "")); + free(a); + free(b); + + assert_se(split_pair("===", "==", &a, &b) >= 0); + assert_se(streq(a, "")); + assert_se(streq(b, "=")); +} + int main(int argc, char *argv[]) { test_streq_ptr(); test_first_word(); + test_close_many(); test_parse_boolean(); test_parse_pid(); test_parse_uid(); test_safe_atolli(); test_safe_atod(); + test_strappend(); test_strstrip(); test_delete_chars(); test_in_charset(); @@ -278,10 +561,22 @@ int main(int argc, char *argv[]) { test_unoctchar(); test_decchar(); test_undecchar(); + test_cescape(); + test_cunescape(); test_foreach_word(); test_foreach_word_quoted(); test_default_term_for_tty(); test_memdup_multiply(); + test_bus_path_escape(); + test_hostname_is_valid(); + test_u64log2(); + test_get_process_comm(); + test_protect_errno(); + test_parse_bytes(); + test_strextend(); + test_strrep(); + test_parse_user_at_host(); + test_split_pair(); return 0; }