summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--locale/Makefile2
-rw-r--r--locale/tst-localedef-path-norm.c237
2 files changed, 128 insertions, 111 deletions
diff --git a/locale/Makefile b/locale/Makefile
index c315683b3f..eb55750496 100644
--- a/locale/Makefile
+++ b/locale/Makefile
@@ -116,3 +116,5 @@ include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left))
$(objpfx)tst-locale-locpath.out : tst-locale-locpath.sh $(objpfx)locale
$(SHELL) $< '$(common-objpfx)' '$(test-wrapper-env)' '$(run-program-env)' > $@; \
$(evaluate-test)
+
+$(objpfx)tst-localedef-path-norm: $(shared-thread-library)
diff --git a/locale/tst-localedef-path-norm.c b/locale/tst-localedef-path-norm.c
index 68995a415d..77cf5b07a8 100644
--- a/locale/tst-localedef-path-norm.c
+++ b/locale/tst-localedef-path-norm.c
@@ -29,6 +29,7 @@
present, regardless of verbosity. POSIX requires that any warnings cause the
exit status to be non-zero. */
+#include <array_length.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -37,9 +38,10 @@
#include <support/check.h>
#include <support/support.h>
#include <support/xunistd.h>
+#include <support/xthread.h>
/* Full path to localedef. */
-char *prog;
+static const char *prog;
/* Execute localedef in a subprocess. */
static void
@@ -63,12 +65,13 @@ struct test_closure
/* Run localedef with DATA.ARGV arguments (NULL terminated), and expect path to
the compiled locale is "DATA.COMPLOCALEDIR/DATA.EXP". */
-static void
-run_test (struct test_closure data)
+static void *
+run_test (void *closure)
{
- const char * const *args = data.argv;
- const char *exp = data.exp;
- const char *complocaledir = data.complocaledir;
+ struct test_closure *data = closure;
+ const char * const *args = data->argv;
+ const char *exp = data->exp;
+ const char *complocaledir = data->complocaledir;
struct stat64 fs;
/* Expected output path. */
@@ -82,8 +85,14 @@ run_test (struct test_closure data)
/* Verify path is present and is a directory. */
xstat (path, &fs);
- TEST_VERIFY_EXIT (S_ISDIR (fs.st_mode));
- printf ("info: Directory '%s' exists.\n", path);
+ if (!S_ISDIR (fs.st_mode))
+ {
+ support_record_failure ();
+ printf ("error: Directory '%s' does not exist.\n", path);
+ return (void *) -1ULL;
+ }
+
+ return NULL;
}
static int
@@ -99,139 +108,145 @@ do_test (void)
#define ABSDIR "/output"
xmkdirp (ABSDIR, 0777);
- /* It takes ~10 seconds to serially execute 9 localedef test. We
- could run the compilations in parallel if we want to reduce test
- time. We don't want to split this out into distinct tests because
- it would require multiple chroots. Batching the same localedef
- tests saves disk space during testing. */
+ /* It takes ~10 seconds to serially execute 9 localedef test. We run the
+ compilations in parallel to reduce test time. We don't want to split
+ this out into distinct tests because it would require multiple chroots.
+ Batching the same localedef tests saves disk space during testing. */
+ struct test_closure tests[] =
+ {
/* Test 1: Expected normalization.
Run localedef and expect output in $(complocaledir)/en_US1.utf8,
with normalization changing UTF-8 to utf8. */
- run_test ((struct test_closure)
- {
- .argv = { prog,
- "--no-archive",
- "-i", "en_US",
- "-f", "UTF-8",
- "en_US1.UTF-8", NULL },
- .exp = "en_US1.utf8",
- .complocaledir = support_complocaledir_prefix
- });
-
+ {
+ .argv = { (const char *const) prog,
+ "--no-archive",
+ "-i", "en_US",
+ "-f", "UTF-8",
+ "en_US1.UTF-8", NULL },
+ .exp = "en_US1.utf8",
+ .complocaledir = support_complocaledir_prefix
+ },
/* Test 2: No normalization past '@'.
Run localedef and expect output in $(complocaledir)/en_US2.utf8@tEsT,
with normalization changing UTF-8@tEsT to utf8@tEsT (everything after
@ is untouched). */
- run_test ((struct test_closure)
- {
- .argv = { prog,
- "--no-archive",
- "-i", "en_US",
- "-f", "UTF-8",
- "en_US2.UTF-8@tEsT", NULL },
- .exp = "en_US2.utf8@tEsT",
- .complocaledir = support_complocaledir_prefix
- });
-
+ {
+ .argv = { prog,
+ "--no-archive",
+ "-i", "en_US",
+ "-f", "UTF-8",
+ "en_US2.UTF-8@tEsT", NULL },
+ .exp = "en_US2.utf8@tEsT",
+ .complocaledir = support_complocaledir_prefix
+ },
/* Test 3: No normalization past '@' despite period.
Run localedef and expect output in $(complocaledir)/en_US3@tEsT.UTF-8,
with normalization changing nothing (everything after @ is untouched)
despite there being a period near the end. */
- run_test ((struct test_closure)
- {
- .argv = { prog,
- "--no-archive",
- "-i", "en_US",
- "-f", "UTF-8",
- "en_US3@tEsT.UTF-8", NULL },
- .exp = "en_US3@tEsT.UTF-8",
- .complocaledir = support_complocaledir_prefix
- });
-
+ {
+ .argv = { prog,
+ "--no-archive",
+ "-i", "en_US",
+ "-f", "UTF-8",
+ "en_US3@tEsT.UTF-8", NULL },
+ .exp = "en_US3@tEsT.UTF-8",
+ .complocaledir = support_complocaledir_prefix
+ },
/* Test 4: Normalize numeric codeset by adding 'iso' prefix.
Run localedef and expect output in $(complocaledir)/en_US4.88591,
with normalization changing 88591 to iso88591. */
- run_test ((struct test_closure)
- {
- .argv = { prog,
- "--no-archive",
- "-i", "en_US",
- "-f", "UTF-8",
- "en_US4.88591", NULL },
- .exp = "en_US4.iso88591",
- .complocaledir = support_complocaledir_prefix
- });
-
+ {
+ .argv = { prog,
+ "--no-archive",
+ "-i", "en_US",
+ "-f", "UTF-8",
+ "en_US4.88591", NULL },
+ .exp = "en_US4.iso88591",
+ .complocaledir = support_complocaledir_prefix
+ },
/* Test 5: Don't add 'iso' prefix if first char is alpha.
Run localedef and expect output in $(complocaledir)/en_US5.a88591,
with normalization changing nothing. */
- run_test ((struct test_closure)
- {
- .argv = { prog,
- "--no-archive",
- "-i", "en_US",
- "-f", "UTF-8",
- "en_US5.a88591", NULL },
- .exp = "en_US5.a88591",
- .complocaledir = support_complocaledir_prefix
- });
-
+ {
+ .argv = { prog,
+ "--no-archive",
+ "-i", "en_US",
+ "-f", "UTF-8",
+ "en_US5.a88591", NULL },
+ .exp = "en_US5.a88591",
+ .complocaledir = support_complocaledir_prefix
+ },
/* Test 6: Don't add 'iso' prefix if last char is alpha.
Run localedef and expect output in $(complocaledir)/en_US6.88591a,
with normalization changing nothing. */
- run_test ((struct test_closure)
- {
- .argv = { prog,
- "--no-archive",
- "-i", "en_US",
- "-f", "UTF-8",
- "en_US6.88591a", NULL },
- .exp = "en_US6.88591a",
- .complocaledir = support_complocaledir_prefix
- });
-
+ {
+ .argv = { prog,
+ "--no-archive",
+ "-i", "en_US",
+ "-f", "UTF-8",
+ "en_US6.88591a", NULL },
+ .exp = "en_US6.88591a",
+ .complocaledir = support_complocaledir_prefix
+ },
/* Test 7: Don't normalize anything with an absolute path.
Run localedef and expect output in ABSDIR/en_US7.UTF-8,
with normalization changing nothing. */
- run_test ((struct test_closure)
- {
- .argv = { prog,
- "--no-archive",
- "-i", "en_US",
- "-f", "UTF-8",
- ABSDIR "/en_US7.UTF-8", NULL },
- .exp = "en_US7.UTF-8",
- .complocaledir = ABSDIR
- });
-
+ {
+ .argv = { prog,
+ "--no-archive",
+ "-i", "en_US",
+ "-f", "UTF-8",
+ ABSDIR "/en_US7.UTF-8", NULL },
+ .exp = "en_US7.UTF-8",
+ .complocaledir = ABSDIR
+ },
/* Test 8: Don't normalize anything with an absolute path.
Run localedef and expect output in ABSDIR/en_US8.UTF-8@tEsT,
with normalization changing nothing. */
- run_test ((struct test_closure)
- {
- .argv = { prog,
- "--no-archive",
- "-i", "en_US",
- "-f", "UTF-8",
- ABSDIR "/en_US8.UTF-8@tEsT", NULL },
- .exp = "en_US8.UTF-8@tEsT",
- .complocaledir = ABSDIR
- });
-
+ {
+ .argv = { prog,
+ "--no-archive",
+ "-i", "en_US",
+ "-f", "UTF-8",
+ ABSDIR "/en_US8.UTF-8@tEsT", NULL },
+ .exp = "en_US8.UTF-8@tEsT",
+ .complocaledir = ABSDIR
+ },
/* Test 9: Don't normalize anything with an absolute path.
Run localedef and expect output in ABSDIR/en_US9@tEsT.UTF-8,
with normalization changing nothing. */
- run_test ((struct test_closure)
- {
- .argv = { prog,
- "--no-archive",
- "-i", "en_US",
- "-f", "UTF-8",
- ABSDIR "/en_US9@tEsT.UTF-8", NULL },
- .exp = "en_US9@tEsT.UTF-8",
- .complocaledir = ABSDIR
- });
+ {
+ .argv = { prog,
+ "--no-archive",
+ "-i", "en_US",
+ "-f", "UTF-8",
+ ABSDIR "/en_US9@tEsT.UTF-8", NULL },
+ .exp = "en_US9@tEsT.UTF-8",
+ .complocaledir = ABSDIR
+ }
+ };
+
+ /* Do not run more threads than the maximum of online CPUs. */
+ size_t ntests = array_length (tests);
+ long int cpus = sysconf (_SC_NPROCESSORS_ONLN);
+ cpus = cpus == -1 ? 1 : cpus;
+ printf ("info: cpus=%ld ntests=%zu\n", cpus, ntests);
+
+ pthread_t thr[ntests];
+
+ for (int i = 0; i < ntests; i += cpus)
+ {
+ int max = i + cpus;
+ if (max > ntests)
+ max = ntests;
+
+ for (int j = i; j < max; j++)
+ thr[j] = xpthread_create (NULL, run_test, &tests[j]);
+
+ for (int j = i; j < max; j++)
+ TEST_VERIFY (xpthread_join (thr[j]) == NULL);
+ }
return 0;
}