]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-specifier.c
core: introduce %R specifier for pretty hostname
[thirdparty/systemd.git] / src / test / test-specifier.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include "alloc-util.h"
4 #include "log.h"
5 #include "specifier.h"
6 #include "stat-util.h"
7 #include "stdio-util.h"
8 #include "string-util.h"
9 #include "strv.h"
10 #include "tests.h"
11
12 static void test_specifier_escape_one(const char *a, const char *b) {
13 _cleanup_free_ char *x = NULL;
14
15 x = specifier_escape(a);
16 assert_se(streq_ptr(x, b));
17 }
18
19 TEST(specifier_escape) {
20 test_specifier_escape_one(NULL, NULL);
21 test_specifier_escape_one("", "");
22 test_specifier_escape_one("%", "%%");
23 test_specifier_escape_one("foo bar", "foo bar");
24 test_specifier_escape_one("foo%bar", "foo%%bar");
25 test_specifier_escape_one("%%%%%", "%%%%%%%%%%");
26 }
27
28 static void test_specifier_escape_strv_one(char **a, char **b) {
29 _cleanup_strv_free_ char **x = NULL;
30
31 assert_se(specifier_escape_strv(a, &x) >= 0);
32 assert_se(strv_equal(x, b));
33 }
34
35 TEST(specifier_escape_strv) {
36 test_specifier_escape_strv_one(NULL, NULL);
37 test_specifier_escape_strv_one(STRV_MAKE(NULL), STRV_MAKE(NULL));
38 test_specifier_escape_strv_one(STRV_MAKE(""), STRV_MAKE(""));
39 test_specifier_escape_strv_one(STRV_MAKE("foo"), STRV_MAKE("foo"));
40 test_specifier_escape_strv_one(STRV_MAKE("%"), STRV_MAKE("%%"));
41 test_specifier_escape_strv_one(STRV_MAKE("foo", "%", "foo%", "%foo", "foo%foo", "quux", "%%%"),
42 STRV_MAKE("foo", "%%", "foo%%", "%%foo", "foo%%foo", "quux", "%%%%%%"));
43 }
44
45 /* Any specifier functions which don't need an argument. */
46 static const Specifier specifier_table[] = {
47 COMMON_SYSTEM_SPECIFIERS,
48
49 COMMON_CREDS_SPECIFIERS,
50 { 'h', specifier_user_home, NULL },
51
52 COMMON_TMP_SPECIFIERS,
53 {}
54 };
55
56 TEST(specifier_printf) {
57 static const Specifier table[] = {
58 { 'X', specifier_string, (char*) "AAAA" },
59 { 'Y', specifier_string, (char*) "BBBB" },
60 { 'e', specifier_string, NULL },
61 COMMON_SYSTEM_SPECIFIERS,
62 {}
63 };
64
65 _cleanup_free_ char *w = NULL;
66 int r;
67
68 r = specifier_printf("xxx a=%X b=%Y e=%e yyy", SIZE_MAX, table, NULL, NULL, &w);
69 assert_se(r >= 0);
70 assert_se(w);
71
72 puts(w);
73 assert_se(streq(w, "xxx a=AAAA b=BBBB e= yyy"));
74
75 free(w);
76 r = specifier_printf("machine=%m, boot=%b, host=%H, pretty=%R, version=%v, arch=%a, empty=%e", SIZE_MAX, table, NULL, NULL, &w);
77 assert_se(r >= 0);
78 assert_se(w);
79 puts(w);
80
81 w = mfree(w);
82 specifier_printf("os=%o, os-version=%w, build=%B, variant=%W, empty=%e%e%e", SIZE_MAX, table, NULL, NULL, &w);
83 if (w)
84 puts(w);
85 }
86
87 TEST(specifier_real_path) {
88 static const Specifier table[] = {
89 { 'p', specifier_string, "/dev/initctl" },
90 { 'y', specifier_real_path, "/dev/initctl" },
91 { 'Y', specifier_real_directory, "/dev/initctl" },
92 { 'w', specifier_real_path, "/dev/tty" },
93 { 'W', specifier_real_directory, "/dev/tty" },
94 {}
95 };
96
97 _cleanup_free_ char *w = NULL;
98 int r;
99
100 r = specifier_printf("p=%p y=%y Y=%Y w=%w W=%W", SIZE_MAX, table, NULL, NULL, &w);
101 assert_se(r >= 0 || r == -ENOENT);
102 assert_se(w || r == -ENOENT);
103 puts(strnull(w));
104
105 /* /dev/initctl should normally be a symlink to /run/initctl */
106 if (files_same("/dev/initctl", "/run/initctl", 0) > 0)
107 assert_se(streq(w, "p=/dev/initctl y=/run/initctl Y=/run w=/dev/tty W=/dev"));
108 }
109
110 TEST(specifier_real_path_missing_file) {
111 static const Specifier table[] = {
112 { 'p', specifier_string, "/dev/-no-such-file--" },
113 { 'y', specifier_real_path, "/dev/-no-such-file--" },
114 { 'Y', specifier_real_directory, "/dev/-no-such-file--" },
115 {}
116 };
117
118 _cleanup_free_ char *w = NULL;
119 int r;
120
121 r = specifier_printf("p=%p y=%y", SIZE_MAX, table, NULL, NULL, &w);
122 assert_se(r == -ENOENT);
123
124 r = specifier_printf("p=%p Y=%Y", SIZE_MAX, table, NULL, NULL, &w);
125 assert_se(r == -ENOENT);
126 }
127
128 TEST(specifiers) {
129 for (const Specifier *s = specifier_table; s->specifier; s++) {
130 char spec[3];
131 _cleanup_free_ char *resolved = NULL;
132
133 xsprintf(spec, "%%%c", s->specifier);
134
135 assert_se(specifier_printf(spec, SIZE_MAX, specifier_table, NULL, NULL, &resolved) >= 0);
136
137 log_info("%%%c → %s", s->specifier, resolved);
138 }
139 }
140
141 DEFINE_TEST_MAIN(LOG_DEBUG);