diff options
author | Nick Mathewson <nickm@torproject.org> | 2020-08-12 12:36:54 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2020-10-07 08:00:49 -0400 |
commit | c5ba8b62219c9e8b895eedc4806176dfe10478b2 (patch) | |
tree | dcf274c2fae0602a92555c77a4e4e6e726baf478 /src/test/testing_common.c | |
parent | f5b94715479e9b7bef5675ab72c8b2e260bcb830 (diff) | |
download | tor-c5ba8b62219c9e8b895eedc4806176dfe10478b2.tar.gz tor-c5ba8b62219c9e8b895eedc4806176dfe10478b2.zip |
Parallelize src/test/test into chunks.
First, we introduce a flag to teach src/test/test to split its work
into chunks. Then we replace our invocation of src/test/test in our
"make check" target with a set of 8 scripts that invoke the first
8th of the tests, the second 8th, and so on.
This change makes our "make -kj4 check" target in our hardened
gitlab build more than twice as fast, since src/test/test was taking
the longest to finish.
Closes 40098.
Diffstat (limited to 'src/test/testing_common.c')
-rw-r--r-- | src/test/testing_common.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/src/test/testing_common.c b/src/test/testing_common.c index 2c9c4538b9..daa7aa524a 100644 --- a/src/test/testing_common.c +++ b/src/test/testing_common.c @@ -278,6 +278,8 @@ main(int c, const char **v) control_initialize_event_queue(); configure_backtrace_handler(get_version()); + unsigned num=1, den=1; + for (i_out = i = 1; i < c; ++i) { if (!strcmp(v[i], "--warn")) { loglevel = LOG_WARN; @@ -289,6 +291,19 @@ main(int c, const char **v) loglevel = LOG_DEBUG; } else if (!strcmp(v[i], "--accel")) { accel_crypto = 1; + } else if (!strcmp(v[i], "--fraction")) { + if (i+1 == c) { + printf("--fraction needs an argument.\n"); + return 1; + } + const char *fracstr = v[++i]; + char ch; + if (sscanf(fracstr, "%u/%u%c", &num, &den, &ch) != 2) { + printf("--fraction expects a fraction as an input.\n"); + } + if (den == 0 || num == 0 || num > den) { + printf("--fraction expects a valid fraction as an input.\n"); + } } else { v[i_out++] = v[i]; } @@ -363,6 +378,33 @@ main(int c, const char **v) smartlist_free(skip); } + if (den != 1) { + // count the tests. Linear but fast. + unsigned n_tests = 0; + struct testgroup_t *tg; + struct testcase_t *tc; + for (tg = testgroups; tg->prefix != NULL; ++tg) { + for (tc = tg->cases; tc->name != NULL; ++tc) { + ++n_tests; + } + } + // Which tests should we run? This can give iffy results if den is huge + // but it doesn't actually matter in practice. + unsigned tests_per_chunk = CEIL_DIV(n_tests, den); + unsigned start_at = (num-1) * tests_per_chunk; + + // Skip the tests that are outside of the range. + unsigned idx = 0; + for (tg = testgroups; tg->prefix != NULL; ++tg) { + for (tc = tg->cases; tc->name != NULL; ++tc) { + if (idx < start_at || idx >= start_at + tests_per_chunk) { + tc->flags |= TT_SKIP; + } + ++idx; + } + } + } + int have_failed = (tinytest_main(c, v, testgroups) != 0); free_pregenerated_keys(); |