Print this page
4964 nl_langinfo(CRNCYSTR) returns wrong alignment character
4999 libc test suite enhancements
Reviewed by: Jason King <jason.brian.king@gmail.com>
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Igor Kozhukhov <ikozhukhov@gmail.com>
Approved by: TBD
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/test/libc-tests/tests/newlocale/newlocale_test.c
+++ new/usr/src/test/libc-tests/tests/newlocale/newlocale_test.c
1 1 /*
2 2 * This file and its contents are supplied under the terms of the
3 3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 4 * You may only use this file in accordance with the terms of version
5 5 * 1.0 of the CDDL.
6 6 *
7 7 * A full copy of the text of the CDDL should have accompanied this
8 8 * source. A copy of the CDDL is also available via the Internet at
9 9 * http://www.illumos.org/license/CDDL.
10 10 */
11 11
12 12 /*
13 13 * Copyright 2014 Garrett D'Amore <garrett@damore.org>
14 14 */
15 15
16 16 /*
17 17 * This program tests that newlocale and uselocale work properly in
18 18 * multi-threaded programs. In order for it to work, it requires that
19 19 * some additional locales be installed.
20 20 */
21 21
22 22 #include <stdio.h>
23 23 #include <stdlib.h>
24 24 #include <string.h>
25 25 #include <locale.h>
26 26 #include <libintl.h>
27 27 #include <langinfo.h>
28 28 #include <nl_types.h>
29 29 #include <err.h>
30 30 #include <unistd.h>
31 31 #include <pthread.h>
32 32
33 33 int debug = 0;
34 34
35 35 /*
36 36 * Note that on some platforms, different symbols are used. For example,
37 37 * MacOS Mavericks uses "Eu" for Euro symbol, instead of €. If the locale
38 38 * data changes, then this program will need to update to reflect that.
39 39 */
40 40 struct ldata {
41 41 const char *locale;
42 42 const char *day1;
43 43 const char *cursym;
44 44 } ldata[] = {
45 45 { "C", "Sunday", "" },
46 46 { "en_US.UTF-8", "Sunday", "$" },
47 47 { "de_DE.UTF-8", "Sonntag", "€" },
48 48 { "ru_RU.UTF-8", "воскресенье", "руб." },
49 49 { "ja_JP.UTF-8", "日曜日", "¥" },
50 50 };
↓ open down ↓ |
50 lines elided |
↑ open up ↑ |
51 51
52 52 #define NUM_LDATA 5
53 53 #define NUMTHR 20
54 54 #define NUMITR 200
55 55
56 56 static void
57 57 test_start(const char *testName, const char *format, ...)
58 58 {
59 59 va_list args;
60 60
61 - (void) printf("TEST STARTING %s: ", testName);
61 + (void) printf("TEST STARTING %s (%s): ", testName, ARCH);
62 62
63 63 va_start(args, format);
64 64 (void) vprintf(format, args);
65 65 va_end(args);
66 66 (void) fflush(stdout);
67 67 }
68 68
69 69 static void
70 70 test_failed(const char *testName, const char *format, ...)
71 71 {
72 72 va_list args;
73 73
74 - (void) printf("TEST FAILED %s: ", testName);
74 + (void) printf("TEST FAILED %s (%s): ", testName, ARCH);
75 75
76 76 va_start(args, format);
77 77 (void) vprintf(format, args);
78 78 va_end(args);
79 + (void) printf("\n");
79 80
80 81 (void) exit(-1);
81 82 }
82 83
83 84 static void
84 85 test_passed(const char *testName)
85 86 {
86 - (void) printf("TEST PASS: %s\n", testName);
87 + (void) printf("TEST PASS: %s (%s)\n", testName, ARCH);
87 88 (void) fflush(stdout);
88 89 }
89 90
90 91 void *
91 -testlocale_thr(void *ptr)
92 +testlocale_thr_one(void *ptr)
92 93 {
93 94 locale_t cloc, loc;
94 95 struct lconv *lc;
95 96 char *day;
96 97 char *tname = ptr;
97 98
98 99 for (int i = 0; i < NUMITR; i++) {
99 100 struct ldata *l = &ldata[i % NUM_LDATA];
100 101 cloc = uselocale(NULL);
101 102
102 103 loc = newlocale(LC_ALL_MASK, l->locale, NULL);
103 104 if (loc == NULL) {
104 105 test_failed("newlocale %s failed", l->locale);
105 106 }
106 107 day = nl_langinfo_l(DAY_1, loc);
107 108 if (strcmp(day, l->day1) != 0) {
108 109 test_failed(tname, "newlocale data mismatch (%s != %s)",
109 110 day, l->day1);
110 111 }
111 112 if (debug)
112 113 (void) printf("DAY1: %s\n", day);
113 114
114 115 day = nl_langinfo(DAY_1);
115 116 if (strcmp(day, "Sunday") != 0) {
116 117 test_failed(tname, "C locale day wrong %s != Sunday",
117 118 day);
118 119 }
119 120 lc = localeconv();
120 121 if (strcmp(lc->currency_symbol, "") != 0) {
121 122 test_failed(tname, "C cursym mismatch (%s != %s)",
122 123 lc->currency_symbol, "");
123 124 }
124 125
125 126 /* we sleep a random bit to mix it up */
126 127 (void) usleep(rand() % 10);
127 128
128 129 (void) uselocale(loc);
129 130 day = nl_langinfo(DAY_1);
130 131 if (strcmp(day, l->day1) != 0) {
131 132 test_failed(tname, "uselocale data mismatch (%s != %s)",
132 133 day, l->day1);
133 134 }
134 135
135 136 lc = localeconv();
136 137 if (strcmp(lc->currency_symbol, l->cursym) != 0) {
137 138 test_failed(tname, "uselocal cursym %s != %s",
138 139 lc->currency_symbol, l->cursym);
139 140 }
140 141 if (debug)
141 142 (void) printf("CSYM: %s\n", lc->currency_symbol);
142 143
143 144 /* we sleep a random bit to mix it up */
144 145 (void) usleep(rand() % 10);
145 146
146 147 if (uselocale(cloc) != loc) {
147 148 test_failed(tname, "revert old locale mismatch");
148 149 }
↓ open down ↓ |
47 lines elided |
↑ open up ↑ |
149 150 freelocale(loc);
150 151 if (uselocale(LC_GLOBAL_LOCALE) != cloc) {
151 152 test_failed(tname, "revert GLOBAL_LOCALE mismatch");
152 153 }
153 154 }
154 155 return (NULL);
155 156 }
156 157
157 158
158 159 void
159 -testlocale(void)
160 +test_newlocale_threaded(void)
160 161 {
161 - char *tname = "newlocale/uselocale";
162 + char *tname = "newlocale_threaded";
162 163 pthread_t tid[NUMTHR];
163 164
164 165 test_start(tname, "running %d threads %d iterations\n", NUMTHR, NUMITR);
165 166
166 167 for (int i = 0; i < NUMTHR; i++) {
167 - (void) pthread_create(&tid[i], NULL, testlocale_thr, tname);
168 + (void) pthread_create(&tid[i], NULL, testlocale_thr_one, tname);
168 169 }
169 170
170 171 for (int i = 0; i < NUMTHR; i++) {
171 172 (void) pthread_join(tid[i], NULL);
172 173 }
173 174 test_passed(tname);
174 175 }
175 176
177 +void
178 +test_newlocale_negative(void)
179 +{
180 +
181 + locale_t loc, bad;
182 + char *day;
183 + char *tname = "newlocale_negative";
184 +
185 + test_start(tname, "verify proper failure handling\n");
186 + loc = newlocale(LC_ALL_MASK, "de_DE.UTF-8", NULL);
187 + if (loc == NULL) {
188 + test_failed(tname, "cannot set de_DE.UTF-8");
189 + }
190 + day = nl_langinfo_l(DAY_1, loc);
191 + if (strcmp(day, "Sonntag") != 0) {
192 + test_failed(tname, "incorrect Sonntag != %s", day);
193 + }
194 +
195 + bad = newlocale(LC_ALL_MASK, "cn_US.BIZRRE", loc);
196 + if (bad != NULL) {
197 + test_failed(tname, "passed setting bogus locale");
198 + }
199 + day = nl_langinfo_l(DAY_1, loc);
200 + if (strcmp(day, "Sonntag") != 0) {
201 + test_failed(tname, "incorrect Sonntag != %s", day);
202 + }
203 + test_passed(tname);
204 +}
205 +
206 +void
207 +test_newlocale_categories(void)
208 +{
209 + locale_t loc;
210 + char *day, *cur, *yes;
211 + char *tname = "newlocale_categories";
212 +
213 + test_start(tname, "verify different category behavior\n");
214 +
215 + loc = NULL;
216 + loc = newlocale(LC_TIME_MASK, "de_DE.UTF-8", loc);
217 + loc = newlocale(LC_MESSAGES_MASK, "ru_RU.UTF-8", loc);
218 + loc = newlocale(LC_MONETARY_MASK, "en_US.UTF-8", loc);
219 +
220 + if (loc == NULL) {
221 + test_failed(tname, "failed to set locale");
222 + }
223 +
224 + day = nl_langinfo_l(DAY_1, loc);
225 + if ((day == NULL) || (strcmp(day, "Sonntag") != 0)) {
226 + test_failed(tname, "day1 mismatch %s != %s", day, "Sonntag");
227 + }
228 + yes = nl_langinfo_l(YESSTR, loc);
229 + if ((yes == NULL) || (strcmp(yes, "да") != 0)) {
230 + test_failed(tname, "currency mismatch");
231 + }
232 + cur = nl_langinfo_l(CRNCYSTR, loc);
233 + if ((cur == NULL) || (strcmp(cur, "-$") != 0)) {
234 + test_failed(tname, "currency mismatch [%s] != [%s]", cur, "-$");
235 + }
236 +
237 + test_passed(tname);
238 +}
239 +
240 +void
241 +test_newlocale_composite(void)
242 +{
243 + locale_t loc;
244 + char *day, *cur, *yes;
245 + char *tname = "newlocale_composite";
246 +
247 + test_start(tname, "verify composite locale behavior\n");
248 +
249 + /* order: CTYPE/NUMERIC/TIME/COLLATE/MONETARY/MESSAGES */
250 + loc = newlocale(LC_ALL_MASK,
251 + "C/C/de_DE.UTF-8/C/en_US.UTF-8/ru_RU.UTF-8", NULL);
252 +
253 + if (loc == NULL) {
254 + test_failed(tname, "failed to set composite locale");
255 + }
256 +
257 + day = nl_langinfo_l(DAY_1, loc);
258 + if ((day == NULL) || (strcmp(day, "Sonntag") != 0)) {
259 + test_failed(tname, "day1 mismatch %s != %s", day, "Sonntag");
260 + }
261 + yes = nl_langinfo_l(YESSTR, loc);
262 + if ((yes == NULL) || (strcmp(yes, "да") != 0)) {
263 + test_failed(tname, "currency mismatch");
264 + }
265 + cur = nl_langinfo_l(CRNCYSTR, loc);
266 + if ((cur == NULL) || (strcmp(cur, "-$") != 0)) {
267 + test_failed(tname, "currency mismatch [%s] != [%s]", cur, "-$");
268 + }
269 +
270 + test_passed(tname);
271 +}
272 +
176 273 int
177 274 main(int argc, char **argv)
178 275 {
179 276 int optc;
180 277
181 278 while ((optc = getopt(argc, argv, "d")) != EOF) {
182 279 switch (optc) {
183 280 case 'd':
184 281 debug++;
185 282 break;
186 283 default:
187 284 (void) fprintf(stderr, "Usage: %s [-d]\n", argv[0]);
188 285 exit(1);
189 286 }
190 287 }
191 288
192 - testlocale();
289 + test_newlocale_threaded();
290 + test_newlocale_negative();
291 + test_newlocale_categories();
292 + test_newlocale_composite();
193 293
194 294 exit(0);
195 295 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX