Skip to content

Commit 2eeb499

Browse files
committed
test: index shards at 1, not 0
This has no tests because it's near impossible to test -- since TestFn uses `proc`s, they can not be cloned or tested for equality. The only way to really test this is making sure that for a given number of shards `a`, sharding from 1 to `a` yields the complete set of tests. But `filter_tests` takes its vector by value and `proc`s cannot be compared. [breaking-change] Closes #10898
1 parent 63287ee commit 2eeb499

File tree

3 files changed

+60
-22
lines changed

3 files changed

+60
-22
lines changed

src/libtest/lib.rs

+37-22
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
3333
html_root_url = "http://static.rust-lang.org/doc/master")]
3434

35-
#![feature(asm, macro_rules)]
35+
#![feature(asm, macro_rules, phase)]
3636
#![deny(deprecated_owned_vector)]
3737

3838
extern crate collections;
@@ -83,7 +83,7 @@ pub mod stats;
8383
// colons. This way if some test runner wants to arrange the tests
8484
// hierarchically it may.
8585

86-
#[deriving(Clone)]
86+
#[deriving(Clone, Eq, TotalEq, Hash)]
8787
pub enum TestName {
8888
StaticTestName(&'static str),
8989
DynTestName(StrBuf)
@@ -156,6 +156,19 @@ impl TestFn {
156156
}
157157
}
158158

159+
impl fmt::Show for TestFn {
160+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
161+
f.write(match *self {
162+
StaticTestFn(..) => "StaticTestFn(..)",
163+
StaticBenchFn(..) => "StaticBenchFn(..)",
164+
StaticMetricFn(..) => "StaticMetricFn(..)",
165+
DynTestFn(..) => "DynTestFn(..)",
166+
DynMetricFn(..) => "DynMetricFn(..)",
167+
DynBenchFn(..) => "DynBenchFn(..)"
168+
}.as_bytes())
169+
}
170+
}
171+
159172
/// Manager of the benchmarking runs.
160173
///
161174
/// This is feed into functions marked with `#[bench]` to allow for
@@ -170,13 +183,14 @@ pub struct Bencher {
170183

171184
// The definition of a single test. A test runner will run a list of
172185
// these.
173-
#[deriving(Clone)]
186+
#[deriving(Clone, Show, Eq, TotalEq, Hash)]
174187
pub struct TestDesc {
175188
pub name: TestName,
176189
pub ignore: bool,
177190
pub should_fail: bool,
178191
}
179192

193+
#[deriving(Show)]
180194
pub struct TestDescAndFn {
181195
pub desc: TestDesc,
182196
pub testfn: TestFn,
@@ -242,15 +256,9 @@ pub fn test_main(args: &[StrBuf], tests: Vec<TestDescAndFn> ) {
242256
pub fn test_main_static(args: &[StrBuf], tests: &[TestDescAndFn]) {
243257
let owned_tests = tests.iter().map(|t| {
244258
match t.testfn {
245-
StaticTestFn(f) =>
246-
TestDescAndFn { testfn: StaticTestFn(f), desc: t.desc.clone() },
247-
248-
StaticBenchFn(f) =>
249-
TestDescAndFn { testfn: StaticBenchFn(f), desc: t.desc.clone() },
250-
251-
_ => {
252-
fail!("non-static tests passed to test::test_main_static");
253-
}
259+
StaticTestFn(f) => TestDescAndFn { testfn: StaticTestFn(f), desc: t.desc.clone() },
260+
StaticBenchFn(f) => TestDescAndFn { testfn: StaticBenchFn(f), desc: t.desc.clone() },
261+
_ => fail!("non-static tests passed to test::test_main_static")
254262
}
255263
}).collect();
256264
test_main(args, owned_tests)
@@ -419,8 +427,15 @@ pub fn opt_shard(maybestr: Option<StrBuf>) -> Option<(uint,uint)> {
419427
None => None,
420428
Some(s) => {
421429
let mut it = s.as_slice().split('.');
422-
match (it.next().and_then(from_str), it.next().and_then(from_str), it.next()) {
423-
(Some(a), Some(b), None) => Some((a, b)),
430+
match (it.next().and_then(from_str::<uint>), it.next().and_then(from_str::<uint>),
431+
it.next()) {
432+
(Some(a), Some(b), None) => {
433+
if a <= 0 || a > b {
434+
fail!("tried to run shard {a}.{b}, but {a} is out of bounds \
435+
(should be between 1 and {b}", a=a, b=b)
436+
}
437+
Some((a, b))
438+
}
424439
_ => None,
425440
}
426441
}
@@ -739,10 +754,9 @@ pub fn fmt_bench_samples(bs: &BenchSamples) -> StrBuf {
739754
}
740755

741756
// A simple console test runner
742-
pub fn run_tests_console(opts: &TestOpts,
743-
tests: Vec<TestDescAndFn> ) -> io::IoResult<bool> {
744-
fn callback<T: Writer>(event: &TestEvent,
745-
st: &mut ConsoleTestState<T>) -> io::IoResult<()> {
757+
pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn> ) -> io::IoResult<bool> {
758+
759+
fn callback<T: Writer>(event: &TestEvent, st: &mut ConsoleTestState<T>) -> io::IoResult<()> {
746760
match (*event).clone() {
747761
TeFiltered(ref filtered_tests) => st.write_run_start(filtered_tests.len()),
748762
TeWait(ref test, padding) => st.write_test_start(test, padding),
@@ -778,6 +792,7 @@ pub fn run_tests_console(opts: &TestOpts,
778792
}
779793
}
780794
}
795+
781796
let mut st = try!(ConsoleTestState::new(opts, None::<StdWriter>));
782797
fn len_if_padded(t: &TestDescAndFn) -> uint {
783798
match t.testfn.padding() {
@@ -933,9 +948,7 @@ fn get_concurrency() -> uint {
933948
}
934949
}
935950

936-
pub fn filter_tests(
937-
opts: &TestOpts,
938-
tests: Vec<TestDescAndFn> ) -> Vec<TestDescAndFn> {
951+
pub fn filter_tests(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> Vec<TestDescAndFn> {
939952
let mut filtered = tests;
940953

941954
// Remove tests that don't match the test filter
@@ -973,7 +986,9 @@ pub fn filter_tests(
973986
None => filtered,
974987
Some((a,b)) => {
975988
filtered.move_iter().enumerate()
976-
.filter(|&(i,_)| i % b == a)
989+
// note: using a - 1 so that the valid shards, for example, are
990+
// 1.2 and 2.2 instead of 0.2 and 1.2
991+
.filter(|&(i,_)| i % b == (a - 1))
977992
.map(|(_,t)| t)
978993
.collect()
979994
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
-include ../tools.mk
2+
3+
all:
4+
# Running all the shards should hit every test
5+
$(RUSTC) --test main.rs
6+
$(call RUN,main) --test-shard 1.2 | grep "test_1 ... ok"
7+
$(call RUN,main) --test-shard 2.2 | grep "test_2 ... ok"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![crate_type = "lib"]
12+
13+
#[test]
14+
fn test_1() { }
15+
#[test]
16+
fn test_2() { }

0 commit comments

Comments
 (0)