]>
Commit | Line | Data |
---|---|---|
92954ffa | 1 | /* Test for localedef path name handling and normalization. |
99de869b | 2 | Copyright (C) 2020 Free Software Foundation, Inc. |
92954ffa CD |
3 | This file is part of the GNU C Library. |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Lesser General Public | |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Lesser General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Lesser General Public | |
16 | License along with the GNU C Library; if not, see | |
17 | <https://www.gnu.org/licenses/>. */ | |
18 | ||
19 | /* The test runs localedef with various named paths to test for expected | |
20 | behaviours dealing with codeset name normalization. That is to say that use | |
21 | of UTF-8, and it's variations, are normalized to utf8. Likewise that values | |
22 | after the @ are not normalized and left as-is. The test needs to run | |
23 | localedef with known input values and then check that the generated path | |
24 | matches the expected value after normalization. */ | |
25 | ||
26 | /* Note: In some cases adding -v (verbose) to localedef changes the exit | |
27 | status to a non-zero value because some warnings are only enabled in verbose | |
28 | mode. This should probably be changed so warnings are either present or not | |
29 | present, regardless of verbosity. POSIX requires that any warnings cause the | |
30 | exit status to be non-zero. */ | |
31 | ||
32 | #include <sys/types.h> | |
33 | #include <sys/stat.h> | |
34 | #include <unistd.h> | |
35 | ||
36 | #include <support/capture_subprocess.h> | |
37 | #include <support/check.h> | |
38 | #include <support/support.h> | |
39 | #include <support/xunistd.h> | |
40 | ||
41 | /* Full path to localedef. */ | |
42 | char *prog; | |
43 | ||
44 | /* Execute localedef in a subprocess. */ | |
45 | static void | |
46 | execv_wrapper (void *args) | |
47 | { | |
48 | char **argv = args; | |
49 | ||
50 | execv (prog, argv); | |
51 | FAIL_EXIT1 ("execv: %m"); | |
52 | } | |
53 | ||
54 | struct test_closure | |
55 | { | |
56 | /* Arguments for running localedef. */ | |
57 | const char *const argv[16]; | |
58 | /* Expected directory name for compiled locale. */ | |
59 | const char *exp; | |
60 | /* Expected path to compiled locale. */ | |
61 | const char *complocaledir; | |
62 | }; | |
63 | ||
64 | /* Run localedef with DATA.ARGV arguments (NULL terminated), and expect path to | |
65 | the compiled locale is "DATA.COMPLOCALEDIR/DATA.EXP". */ | |
66 | static void | |
67 | run_test (struct test_closure data) | |
68 | { | |
69 | const char * const *args = data.argv; | |
70 | const char *exp = data.exp; | |
71 | const char *complocaledir = data.complocaledir; | |
72 | struct stat64 fs; | |
73 | ||
74 | /* Expected output path. */ | |
75 | const char *path = xasprintf ("%s/%s", complocaledir, exp); | |
76 | ||
77 | /* Run test. */ | |
78 | struct support_capture_subprocess result; | |
79 | result = support_capture_subprocess (execv_wrapper, (void *)args); | |
80 | support_capture_subprocess_check (&result, "execv", 0, sc_allow_none); | |
81 | support_capture_subprocess_free (&result); | |
82 | ||
83 | /* Verify path is present and is a directory. */ | |
84 | xstat (path, &fs); | |
85 | TEST_VERIFY_EXIT (S_ISDIR (fs.st_mode)); | |
86 | printf ("info: Directory '%s' exists.\n", path); | |
87 | } | |
88 | ||
89 | static int | |
90 | do_test (void) | |
91 | { | |
92 | /* We are running as root inside the container. */ | |
93 | prog = xasprintf ("%s/localedef", support_bindir_prefix); | |
94 | ||
6f0baacf CD |
95 | /* We need an arbitrary absolute path for localedef output. |
96 | Writing to a non-default absolute path disables any kind | |
92954ffa CD |
97 | of path normalization since we expect the user wants the path |
98 | exactly as they specified it. */ | |
6f0baacf CD |
99 | #define ABSDIR "/output" |
100 | xmkdirp (ABSDIR, 0777); | |
92954ffa CD |
101 | |
102 | /* It takes ~10 seconds to serially execute 9 localedef test. We | |
103 | could run the compilations in parallel if we want to reduce test | |
104 | time. We don't want to split this out into distinct tests because | |
105 | it would require multiple chroots. Batching the same localedef | |
106 | tests saves disk space during testing. */ | |
107 | ||
108 | /* Test 1: Expected normalization. | |
6f0baacf | 109 | Run localedef and expect output in $(complocaledir)/en_US1.utf8, |
92954ffa CD |
110 | with normalization changing UTF-8 to utf8. */ |
111 | run_test ((struct test_closure) | |
112 | { | |
113 | .argv = { prog, | |
114 | "--no-archive", | |
115 | "-i", "en_US", | |
116 | "-f", "UTF-8", | |
117 | "en_US1.UTF-8", NULL }, | |
118 | .exp = "en_US1.utf8", | |
119 | .complocaledir = support_complocaledir_prefix | |
120 | }); | |
121 | ||
122 | /* Test 2: No normalization past '@'. | |
6f0baacf | 123 | Run localedef and expect output in $(complocaledir)/en_US2.utf8@tEsT, |
92954ffa CD |
124 | with normalization changing UTF-8@tEsT to utf8@tEsT (everything after |
125 | @ is untouched). */ | |
126 | run_test ((struct test_closure) | |
127 | { | |
128 | .argv = { prog, | |
129 | "--no-archive", | |
130 | "-i", "en_US", | |
131 | "-f", "UTF-8", | |
132 | "en_US2.UTF-8@tEsT", NULL }, | |
133 | .exp = "en_US2.utf8@tEsT", | |
134 | .complocaledir = support_complocaledir_prefix | |
135 | }); | |
136 | ||
137 | /* Test 3: No normalization past '@' despite period. | |
6f0baacf | 138 | Run localedef and expect output in $(complocaledir)/en_US3@tEsT.UTF-8, |
92954ffa CD |
139 | with normalization changing nothing (everything after @ is untouched) |
140 | despite there being a period near the end. */ | |
141 | run_test ((struct test_closure) | |
142 | { | |
143 | .argv = { prog, | |
144 | "--no-archive", | |
145 | "-i", "en_US", | |
146 | "-f", "UTF-8", | |
147 | "en_US3@tEsT.UTF-8", NULL }, | |
148 | .exp = "en_US3@tEsT.UTF-8", | |
149 | .complocaledir = support_complocaledir_prefix | |
150 | }); | |
151 | ||
152 | /* Test 4: Normalize numeric codeset by adding 'iso' prefix. | |
6f0baacf | 153 | Run localedef and expect output in $(complocaledir)/en_US4.88591, |
92954ffa CD |
154 | with normalization changing 88591 to iso88591. */ |
155 | run_test ((struct test_closure) | |
156 | { | |
157 | .argv = { prog, | |
158 | "--no-archive", | |
159 | "-i", "en_US", | |
160 | "-f", "UTF-8", | |
161 | "en_US4.88591", NULL }, | |
162 | .exp = "en_US4.iso88591", | |
163 | .complocaledir = support_complocaledir_prefix | |
164 | }); | |
165 | ||
166 | /* Test 5: Don't add 'iso' prefix if first char is alpha. | |
6f0baacf | 167 | Run localedef and expect output in $(complocaledir)/en_US5.a88591, |
92954ffa CD |
168 | with normalization changing nothing. */ |
169 | run_test ((struct test_closure) | |
170 | { | |
171 | .argv = { prog, | |
172 | "--no-archive", | |
173 | "-i", "en_US", | |
174 | "-f", "UTF-8", | |
175 | "en_US5.a88591", NULL }, | |
176 | .exp = "en_US5.a88591", | |
177 | .complocaledir = support_complocaledir_prefix | |
178 | }); | |
179 | ||
180 | /* Test 6: Don't add 'iso' prefix if last char is alpha. | |
6f0baacf | 181 | Run localedef and expect output in $(complocaledir)/en_US6.88591a, |
92954ffa CD |
182 | with normalization changing nothing. */ |
183 | run_test ((struct test_closure) | |
184 | { | |
185 | .argv = { prog, | |
186 | "--no-archive", | |
187 | "-i", "en_US", | |
188 | "-f", "UTF-8", | |
189 | "en_US6.88591a", NULL }, | |
190 | .exp = "en_US6.88591a", | |
191 | .complocaledir = support_complocaledir_prefix | |
192 | }); | |
193 | ||
194 | /* Test 7: Don't normalize anything with an absolute path. | |
6f0baacf | 195 | Run localedef and expect output in ABSDIR/en_US7.UTF-8, |
92954ffa CD |
196 | with normalization changing nothing. */ |
197 | run_test ((struct test_closure) | |
198 | { | |
199 | .argv = { prog, | |
200 | "--no-archive", | |
201 | "-i", "en_US", | |
202 | "-f", "UTF-8", | |
6f0baacf | 203 | ABSDIR "/en_US7.UTF-8", NULL }, |
92954ffa | 204 | .exp = "en_US7.UTF-8", |
6f0baacf | 205 | .complocaledir = ABSDIR |
92954ffa CD |
206 | }); |
207 | ||
208 | /* Test 8: Don't normalize anything with an absolute path. | |
6f0baacf | 209 | Run localedef and expect output in ABSDIR/en_US8.UTF-8@tEsT, |
92954ffa CD |
210 | with normalization changing nothing. */ |
211 | run_test ((struct test_closure) | |
212 | { | |
213 | .argv = { prog, | |
214 | "--no-archive", | |
215 | "-i", "en_US", | |
216 | "-f", "UTF-8", | |
6f0baacf | 217 | ABSDIR "/en_US8.UTF-8@tEsT", NULL }, |
92954ffa | 218 | .exp = "en_US8.UTF-8@tEsT", |
6f0baacf | 219 | .complocaledir = ABSDIR |
92954ffa CD |
220 | }); |
221 | ||
222 | /* Test 9: Don't normalize anything with an absolute path. | |
6f0baacf | 223 | Run localedef and expect output in ABSDIR/en_US9@tEsT.UTF-8, |
92954ffa CD |
224 | with normalization changing nothing. */ |
225 | run_test ((struct test_closure) | |
226 | { | |
227 | .argv = { prog, | |
228 | "--no-archive", | |
229 | "-i", "en_US", | |
230 | "-f", "UTF-8", | |
6f0baacf | 231 | ABSDIR "/en_US9@tEsT.UTF-8", NULL }, |
92954ffa | 232 | .exp = "en_US9@tEsT.UTF-8", |
6f0baacf | 233 | .complocaledir = ABSDIR |
92954ffa CD |
234 | }); |
235 | ||
236 | return 0; | |
237 | } | |
238 | ||
d96cb376 | 239 | #define TIMEOUT 30 |
92954ffa | 240 | #include <support/test-driver.c> |