]>
Commit | Line | Data |
---|---|---|
53e1b683 | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
d4205751 | 2 | |
844ec79b | 3 | #include <errno.h> |
2d5bdf5b | 4 | #include <fcntl.h> |
cf0fbc49 TA |
5 | #include <locale.h> |
6 | #include <unistd.h> | |
d4205751 | 7 | |
07630cea LP |
8 | #include "sd-messages.h" |
9 | ||
b5efdb8a | 10 | #include "alloc-util.h" |
3ffd4af2 LP |
11 | #include "catalog.h" |
12 | #include "fd-util.h" | |
627d2bac | 13 | #include "fs-util.h" |
d4205751 | 14 | #include "log.h" |
844ec79b | 15 | #include "macro.h" |
d9b6baa6 | 16 | #include "path-util.h" |
07630cea | 17 | #include "string-util.h" |
d9b6baa6 YW |
18 | #include "strv.h" |
19 | #include "tests.h" | |
e4de7287 | 20 | #include "tmpfile-util.h" |
3ffd4af2 | 21 | #include "util.h" |
d4205751 | 22 | |
d9b6baa6 | 23 | static char** catalog_dirs = NULL; |
143bfdaf HHPF |
24 | static const char *no_catalog_dirs[] = { |
25 | "/bin/hopefully/with/no/catalog", | |
26 | NULL | |
27 | }; | |
28 | ||
627d2bac ZJS |
29 | static Hashmap* test_import(const char* contents, ssize_t size, int code) { |
30 | _cleanup_(unlink_tempfilep) char name[] = "/tmp/test-catalog.XXXXXX"; | |
2d5bdf5b | 31 | _cleanup_close_ int fd; |
9d85882a SW |
32 | Hashmap *h; |
33 | ||
34 | if (size < 0) | |
35 | size = strlen(contents); | |
36 | ||
37 | assert_se(h = hashmap_new(&catalog_hash_ops)); | |
2d5bdf5b | 38 | |
646853bd | 39 | fd = mkostemp_safe(name); |
787784c4 | 40 | assert_se(fd >= 0); |
844ec79b ZJS |
41 | assert_se(write(fd, contents, size) == size); |
42 | ||
627d2bac | 43 | assert_se(catalog_import_file(h, name) == code); |
844ec79b | 44 | |
9d85882a SW |
45 | return h; |
46 | } | |
844ec79b | 47 | |
9d85882a SW |
48 | static void test_catalog_import_invalid(void) { |
49 | _cleanup_hashmap_free_free_free_ Hashmap *h = NULL; | |
844ec79b | 50 | |
9d85882a | 51 | h = test_import("xxx", -1, -EINVAL); |
787784c4 | 52 | assert_se(hashmap_isempty(h)); |
9d85882a | 53 | } |
844ec79b | 54 | |
9d85882a SW |
55 | static void test_catalog_import_badid(void) { |
56 | _cleanup_hashmap_free_free_free_ Hashmap *h = NULL; | |
57 | const char *input = | |
844ec79b ZJS |
58 | "-- 0027229ca0644181a76c4e92458afaff dededededededededededededededede\n" \ |
59 | "Subject: message\n" \ | |
60 | "\n" \ | |
9d85882a SW |
61 | "payload\n"; |
62 | h = test_import(input, -1, -EINVAL); | |
63 | } | |
844ec79b | 64 | |
9d85882a SW |
65 | static void test_catalog_import_one(void) { |
66 | _cleanup_hashmap_free_free_free_ Hashmap *h = NULL; | |
67 | char *payload; | |
68 | Iterator j; | |
844ec79b | 69 | |
9d85882a | 70 | const char *input = |
844ec79b ZJS |
71 | "-- 0027229ca0644181a76c4e92458afaff dededededededededededededededed\n" \ |
72 | "Subject: message\n" \ | |
73 | "\n" \ | |
9d85882a SW |
74 | "payload\n"; |
75 | const char *expect = | |
76 | "Subject: message\n" \ | |
77 | "\n" \ | |
78 | "payload\n"; | |
844ec79b | 79 | |
9d85882a | 80 | h = test_import(input, -1, 0); |
787784c4 | 81 | assert_se(hashmap_size(h) == 1); |
d4205751 | 82 | |
9d85882a | 83 | HASHMAP_FOREACH(payload, h, j) { |
06466a7f ZJS |
84 | printf("expect: %s\n", expect); |
85 | printf("actual: %s\n", payload); | |
9d85882a SW |
86 | assert_se(streq(expect, payload)); |
87 | } | |
844ec79b ZJS |
88 | } |
89 | ||
c059b62f SW |
90 | static void test_catalog_import_merge(void) { |
91 | _cleanup_hashmap_free_free_free_ Hashmap *h = NULL; | |
92 | char *payload; | |
93 | Iterator j; | |
94 | ||
95 | const char *input = | |
96 | "-- 0027229ca0644181a76c4e92458afaff dededededededededededededededed\n" \ | |
97 | "Subject: message\n" \ | |
98 | "Defined-By: me\n" \ | |
99 | "\n" \ | |
100 | "payload\n" \ | |
101 | "\n" \ | |
102 | "-- 0027229ca0644181a76c4e92458afaff dededededededededededededededed\n" \ | |
103 | "Subject: override subject\n" \ | |
104 | "X-Header: hello\n" \ | |
105 | "\n" \ | |
106 | "override payload\n"; | |
107 | ||
108 | const char *combined = | |
109 | "Subject: override subject\n" \ | |
110 | "X-Header: hello\n" \ | |
111 | "Subject: message\n" \ | |
112 | "Defined-By: me\n" \ | |
113 | "\n" \ | |
114 | "override payload\n"; | |
115 | ||
116 | h = test_import(input, -1, 0); | |
117 | assert_se(hashmap_size(h) == 1); | |
118 | ||
119 | HASHMAP_FOREACH(payload, h, j) { | |
120 | assert_se(streq(combined, payload)); | |
121 | } | |
122 | } | |
123 | ||
124 | static void test_catalog_import_merge_no_body(void) { | |
125 | _cleanup_hashmap_free_free_free_ Hashmap *h = NULL; | |
126 | char *payload; | |
127 | Iterator j; | |
128 | ||
129 | const char *input = | |
130 | "-- 0027229ca0644181a76c4e92458afaff dededededededededededededededed\n" \ | |
131 | "Subject: message\n" \ | |
132 | "Defined-By: me\n" \ | |
133 | "\n" \ | |
134 | "payload\n" \ | |
135 | "\n" \ | |
136 | "-- 0027229ca0644181a76c4e92458afaff dededededededededededededededed\n" \ | |
137 | "Subject: override subject\n" \ | |
138 | "X-Header: hello\n" \ | |
139 | "\n"; | |
140 | ||
141 | const char *combined = | |
142 | "Subject: override subject\n" \ | |
143 | "X-Header: hello\n" \ | |
144 | "Subject: message\n" \ | |
145 | "Defined-By: me\n" \ | |
146 | "\n" \ | |
147 | "payload\n"; | |
148 | ||
149 | h = test_import(input, -1, 0); | |
150 | assert_se(hashmap_size(h) == 1); | |
151 | ||
152 | HASHMAP_FOREACH(payload, h, j) { | |
153 | assert_se(streq(combined, payload)); | |
154 | } | |
155 | } | |
156 | ||
627d2bac | 157 | static void test_catalog_update(const char *database) { |
844ec79b | 158 | int r; |
844ec79b | 159 | |
844ec79b ZJS |
160 | /* Test what happens if there are no files. */ |
161 | r = catalog_update(database, NULL, NULL); | |
f201daec | 162 | assert_se(r == 0); |
844ec79b | 163 | |
143bfdaf HHPF |
164 | /* Test what happens if there are no files in the directory. */ |
165 | r = catalog_update(database, NULL, no_catalog_dirs); | |
f201daec | 166 | assert_se(r == 0); |
143bfdaf HHPF |
167 | |
168 | /* Make sure that we at least have some files loaded or the | |
d9b6baa6 YW |
169 | * catalog_list below will fail. */ |
170 | r = catalog_update(database, NULL, (const char * const *) catalog_dirs); | |
f201daec | 171 | assert_se(r == 0); |
844ec79b ZJS |
172 | } |
173 | ||
c7332b08 | 174 | static void test_catalog_file_lang(void) { |
4b8268f8 | 175 | _cleanup_free_ char *lang = NULL, *lang2 = NULL, *lang3 = NULL, *lang4 = NULL; |
c7332b08 ZJS |
176 | |
177 | assert_se(catalog_file_lang("systemd.de_DE.catalog", &lang) == 1); | |
178 | assert_se(streq(lang, "de_DE")); | |
179 | ||
180 | assert_se(catalog_file_lang("systemd..catalog", &lang2) == 0); | |
181 | assert_se(lang2 == NULL); | |
182 | ||
183 | assert_se(catalog_file_lang("systemd.fr.catalog", &lang2) == 1); | |
184 | assert_se(streq(lang2, "fr")); | |
185 | ||
186 | assert_se(catalog_file_lang("systemd.fr.catalog.gz", &lang3) == 0); | |
187 | assert_se(lang3 == NULL); | |
188 | ||
189 | assert_se(catalog_file_lang("systemd.01234567890123456789012345678901.catalog", &lang3) == 0); | |
190 | assert_se(lang3 == NULL); | |
191 | ||
192 | assert_se(catalog_file_lang("systemd.0123456789012345678901234567890.catalog", &lang3) == 1); | |
193 | assert_se(streq(lang3, "0123456789012345678901234567890")); | |
4b8268f8 ZJS |
194 | |
195 | assert_se(catalog_file_lang("/x/y/systemd.catalog", &lang4) == 0); | |
196 | assert_se(lang4 == NULL); | |
197 | ||
198 | assert_se(catalog_file_lang("/x/y/systemd.ru_RU.catalog", &lang4) == 1); | |
199 | assert_se(streq(lang4, "ru_RU")); | |
c7332b08 ZJS |
200 | } |
201 | ||
844ec79b | 202 | int main(int argc, char *argv[]) { |
627d2bac | 203 | _cleanup_(unlink_tempfilep) char database[] = "/tmp/test-catalog.XXXXXX"; |
3332004e | 204 | _cleanup_free_ char *text = NULL; |
844ec79b | 205 | int r; |
d4205751 LP |
206 | |
207 | setlocale(LC_ALL, "de_DE.UTF-8"); | |
208 | ||
6d7c4033 | 209 | test_setup_logging(LOG_DEBUG); |
d4205751 | 210 | |
d9b6baa6 YW |
211 | /* If test-catalog is located at the build directory, then use catalogs in that. |
212 | * If it is not, e.g. installed by systemd-tests package, then use installed catalogs. */ | |
49cdae63 | 213 | catalog_dirs = STRV_MAKE(get_catalog_dir()); |
d9b6baa6 YW |
214 | |
215 | assert_se(access(catalog_dirs[0], F_OK) >= 0); | |
216 | log_notice("Using catalog directory '%s'", catalog_dirs[0]); | |
217 | ||
4b8268f8 ZJS |
218 | test_catalog_file_lang(); |
219 | ||
9d85882a SW |
220 | test_catalog_import_invalid(); |
221 | test_catalog_import_badid(); | |
222 | test_catalog_import_one(); | |
c059b62f SW |
223 | test_catalog_import_merge(); |
224 | test_catalog_import_merge_no_body(); | |
d4205751 | 225 | |
627d2bac ZJS |
226 | assert_se(mkostemp_safe(database) >= 0); |
227 | ||
228 | test_catalog_update(database); | |
54b7254c | 229 | |
844ec79b ZJS |
230 | r = catalog_list(stdout, database, true); |
231 | assert_se(r >= 0); | |
d4205751 | 232 | |
844ec79b ZJS |
233 | r = catalog_list(stdout, database, false); |
234 | assert_se(r >= 0); | |
d4205751 | 235 | |
844ec79b | 236 | assert_se(catalog_get(database, SD_MESSAGE_COREDUMP, &text) >= 0); |
d4205751 LP |
237 | printf(">>>%s<<<\n", text); |
238 | ||
d4205751 LP |
239 | return 0; |
240 | } |