Skip to content

Commit bb9c71f

Browse files
committed
auto merge of #8722 : graydon/rust/2013-08-23-test-shard, r=msullivan
This makes it relatively easy for us to split testsuite load between machines in buildbot. I've added buildbot-side support for setting up builders with -a.b suffixes (eg. linux-64-opt-vg-0.5, linux-64-opt-vg-1.5, linux-64-opt-vg-2.5, linux-64-opt-vg-3.5, linux-64-opt-vg-4.5 causes the valgrind-supervised testsuite to split 5 ways across hosts).
2 parents 8bf65a1 + 2fb5c49 commit bb9c71f

File tree

4 files changed

+60
-6
lines changed

4 files changed

+60
-6
lines changed

mk/tests.mk

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,24 @@ TEST_RATCHET_NOISE_PERCENT=10.0
7373

7474
# Whether to ratchet or merely save benchmarks
7575
ifdef CFG_RATCHET_BENCH
76-
CRATE_TEST_BENCH_ARGS=\
76+
CRATE_TEST_EXTRA_ARGS=\
7777
--test $(TEST_BENCH) \
7878
--ratchet-metrics $(call TEST_RATCHET_FILE,$(1),$(2),$(3),$(4)) \
7979
--ratchet-noise-percent $(TEST_RATCHET_NOISE_PERCENT)
8080
else
81-
CRATE_TEST_BENCH_ARGS=\
81+
CRATE_TEST_EXTRA_ARGS=\
8282
--test $(TEST_BENCH) \
8383
--save-metrics $(call TEST_RATCHET_FILE,$(1),$(2),$(3),$(4))
8484
endif
8585

86+
# If we're sharding the testsuite between parallel testers,
87+
# pass this argument along to the compiletest and crate test
88+
# invocations.
89+
ifdef TEST_SHARD
90+
CTEST_TESTARGS += --test-shard=$(TEST_SHARD)
91+
CRATE_TEST_EXTRA_ARGS += --test-shard=$(TEST_SHARD)
92+
endif
93+
8694
define DEF_TARGET_COMMANDS
8795

8896
ifdef CFG_UNIXY_$(1)
@@ -401,7 +409,7 @@ $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \
401409
@$$(call E, run: $$<)
402410
$$(Q)$$(call CFG_RUN_TEST_$(2),$$<,$(2),$(3)) $$(TESTARGS) \
403411
--logfile $$(call TEST_LOG_FILE,$(1),$(2),$(3),$(4)) \
404-
$$(call CRATE_TEST_BENCH_ARGS,$(1),$(2),$(3),$(4)) \
412+
$$(call CRATE_TEST_EXTRA_ARGS,$(1),$(2),$(3),$(4)) \
405413
&& touch $$@
406414
endef
407415

@@ -415,7 +423,7 @@ $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \
415423
@$(CFG_ADB) shell '(cd $(CFG_ADB_TEST_DIR); LD_LIBRARY_PATH=. \
416424
./$$(notdir $$<) \
417425
--logfile $(CFG_ADB_TEST_DIR)/check-stage$(1)-T-$(2)-H-$(3)-$(4).log \
418-
$$(call CRATE_TEST_BENCH_ARGS,$(1),$(2),$(3),$(4)))' \
426+
$$(call CRATE_TEST_EXTRA_ARGS,$(1),$(2),$(3),$(4)))' \
419427
> tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).tmp
420428
@cat tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).tmp
421429
@touch tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).log

src/compiletest/common.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ pub struct config {
6868
// Percent change in metrics to consider noise
6969
ratchet_noise_percent: Option<f64>,
7070

71+
// "Shard" of the testsuite to run: this has the form of
72+
// two numbers (a,b), and causes only those tests with
73+
// positional order equal to a mod b to run.
74+
test_shard: Option<(uint,uint)>,
75+
7176
// A command line to prefix program execution with,
7277
// for running under valgrind
7378
runtool: Option<~str>,

src/compiletest/compiletest.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ pub fn parse_config(args: ~[~str]) -> config {
7575
optopt("", "target", "the target to build for", "TARGET"),
7676
optopt("", "adb-path", "path to the android debugger", "PATH"),
7777
optopt("", "adb-test-dir", "path to tests for the android debugger", "PATH"),
78+
optopt("", "test-shard", "run shard A, of B shards, worth of the testsuite", "A.B"),
7879
optflag("h", "help", "show this message"),
7980
];
8081

@@ -148,6 +149,7 @@ pub fn parse_config(args: ~[~str]) -> config {
148149
~"") { true }
149150
else { false }
150151
} else { false },
152+
test_shard: test::opt_shard(getopts::opt_maybe_str(matches, "test-shard")),
151153
verbose: getopts::opt_present(matches, "verbose")
152154
}
153155
}
@@ -172,6 +174,10 @@ pub fn log_config(config: &config) {
172174
logv(c, fmt!("adb_path: %s", config.adb_path));
173175
logv(c, fmt!("adb_test_dir: %s", config.adb_test_dir));
174176
logv(c, fmt!("adb_device_status: %b", config.adb_device_status));
177+
match config.test_shard {
178+
None => logv(c, ~"test_shard: (all)"),
179+
Some((a,b)) => logv(c, fmt!("test_shard: %u.%u", a, b))
180+
}
175181
logv(c, fmt!("verbose: %b", config.verbose));
176182
logv(c, fmt!("\n"));
177183
}
@@ -234,6 +240,7 @@ pub fn test_opts(config: &config) -> test::TestOpts {
234240
ratchet_metrics: config.ratchet_metrics.clone(),
235241
ratchet_noise_percent: config.ratchet_noise_percent.clone(),
236242
save_metrics: config.save_metrics.clone(),
243+
test_shard: config.test_shard.clone()
237244
}
238245
}
239246

src/libextra/test.rs

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ use std::task;
3838
use std::to_str::ToStr;
3939
use std::f64;
4040
use std::os;
41+
use std::uint;
4142

4243

4344
// The name of a test. By convention this follows the rules for rust
@@ -164,6 +165,7 @@ pub struct TestOpts {
164165
ratchet_metrics: Option<Path>,
165166
ratchet_noise_percent: Option<f64>,
166167
save_metrics: Option<Path>,
168+
test_shard: Option<(uint,uint)>,
167169
logfile: Option<Path>
168170
}
169171

@@ -184,7 +186,9 @@ fn optgroups() -> ~[getopts::groups::OptGroup] {
184186
"Tests within N% of the recorded metrics will be \
185187
considered as passing", "PERCENTAGE"),
186188
groups::optopt("", "logfile", "Write logs to the specified file instead \
187-
of stdout", "PATH")]
189+
of stdout", "PATH"),
190+
groups::optopt("", "test-shard", "run shard A, of B shards, worth of the testsuite",
191+
"A.B")]
188192
}
189193

190194
fn usage(binary: &str, helpstr: &str) -> ! {
@@ -255,6 +259,9 @@ pub fn parse_opts(args: &[~str]) -> OptRes {
255259
let save_metrics = getopts::opt_maybe_str(&matches, "save-metrics");
256260
let save_metrics = save_metrics.map_move(|s| Path(s));
257261

262+
let test_shard = getopts::opt_maybe_str(&matches, "test-shard");
263+
let test_shard = opt_shard(test_shard);
264+
258265
let test_opts = TestOpts {
259266
filter: filter,
260267
run_ignored: run_ignored,
@@ -263,12 +270,29 @@ pub fn parse_opts(args: &[~str]) -> OptRes {
263270
ratchet_metrics: ratchet_metrics,
264271
ratchet_noise_percent: ratchet_noise_percent,
265272
save_metrics: save_metrics,
273+
test_shard: test_shard,
266274
logfile: logfile
267275
};
268276

269277
either::Left(test_opts)
270278
}
271279

280+
pub fn opt_shard(maybestr: Option<~str>) -> Option<(uint,uint)> {
281+
match maybestr {
282+
None => None,
283+
Some(s) => {
284+
match s.split_iter('.').to_owned_vec() {
285+
[a, b] => match (uint::from_str(a), uint::from_str(b)) {
286+
(Some(a), Some(b)) => Some((a,b)),
287+
_ => None
288+
},
289+
_ => None
290+
}
291+
}
292+
}
293+
}
294+
295+
272296
#[deriving(Clone, Eq)]
273297
pub struct BenchSamples {
274298
ns_iter_summ: stats::Summary,
@@ -772,7 +796,15 @@ pub fn filter_tests(
772796
}
773797
sort::quick_sort(filtered, lteq);
774798

775-
filtered
799+
// Shard the remaining tests, if sharding requested.
800+
match opts.test_shard {
801+
None => filtered,
802+
Some((a,b)) =>
803+
filtered.move_iter().enumerate()
804+
.filter(|&(i,_)| i % b == a)
805+
.map(|(_,t)| t)
806+
.to_owned_vec()
807+
}
776808
}
777809

778810
struct TestFuture {
@@ -1234,6 +1266,7 @@ mod tests {
12341266
ratchet_noise_percent: None,
12351267
ratchet_metrics: None,
12361268
save_metrics: None,
1269+
test_shard: None
12371270
};
12381271

12391272
let tests = ~[
@@ -1272,6 +1305,7 @@ mod tests {
12721305
ratchet_noise_percent: None,
12731306
ratchet_metrics: None,
12741307
save_metrics: None,
1308+
test_shard: None
12751309
};
12761310
12771311
let names =

0 commit comments

Comments
 (0)