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