Auto merge of #50466 - kennytm:rustbuild-stage0-lib-test, r=Mark-Simulacrum
rustbuild: Allow quick testing of libstd and libcore at stage0 This PR implemented two features: 1. Added a `--no-doc` flag to allow testing a crate *without* doc tests. In this mode, we don't need to build rustdoc, and thus we can skip building the stage2 compiler. (Ideally stage0 test should use the bootstrap rustdoc, but I don't want to mess up the core builder logic here) 2. Moved all libcore tests externally and added a tidy test to ensure we don't accidentally add `#[test]` into libcore. After this PR, one could run `./x.py test --stage 0 --no-doc src/libstd` to test `libstd` without building the compiler, thus enables us to quickly test new library features.
This commit is contained in:
@@ -64,6 +64,10 @@ The script accepts commands, flags, and arguments to determine what to do:
|
|||||||
# execute tests in the standard library in stage0
|
# execute tests in the standard library in stage0
|
||||||
./x.py test --stage 0 src/libstd
|
./x.py test --stage 0 src/libstd
|
||||||
|
|
||||||
|
# execute tests in the core and standard library in stage0,
|
||||||
|
# without running doc tests (thus avoid depending on building the compiler)
|
||||||
|
./x.py test --stage 0 --no-doc src/libcore src/libstd
|
||||||
|
|
||||||
# execute all doc tests
|
# execute all doc tests
|
||||||
./x.py test src/doc
|
./x.py test src/doc
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ use compile;
|
|||||||
use install;
|
use install;
|
||||||
use dist;
|
use dist;
|
||||||
use util::{exe, libdir, add_lib_path};
|
use util::{exe, libdir, add_lib_path};
|
||||||
use {Build, Mode};
|
use {Build, Mode, DocTests};
|
||||||
use cache::{INTERNER, Interned, Cache};
|
use cache::{INTERNER, Interned, Cache};
|
||||||
use check;
|
use check;
|
||||||
use test;
|
use test;
|
||||||
@@ -591,6 +591,8 @@ impl<'a> Builder<'a> {
|
|||||||
format!("{} {}", env::var("RUSTFLAGS").unwrap_or_default(), extra_args));
|
format!("{} {}", env::var("RUSTFLAGS").unwrap_or_default(), extra_args));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let want_rustdoc = self.doc_tests != DocTests::No;
|
||||||
|
|
||||||
// Customize the compiler we're running. Specify the compiler to cargo
|
// Customize the compiler we're running. Specify the compiler to cargo
|
||||||
// as our shim and then pass it some various options used to configure
|
// as our shim and then pass it some various options used to configure
|
||||||
// how the actual compiler itself is called.
|
// how the actual compiler itself is called.
|
||||||
@@ -607,7 +609,7 @@ impl<'a> Builder<'a> {
|
|||||||
.env("RUSTC_LIBDIR", self.rustc_libdir(compiler))
|
.env("RUSTC_LIBDIR", self.rustc_libdir(compiler))
|
||||||
.env("RUSTC_RPATH", self.config.rust_rpath.to_string())
|
.env("RUSTC_RPATH", self.config.rust_rpath.to_string())
|
||||||
.env("RUSTDOC", self.out.join("bootstrap/debug/rustdoc"))
|
.env("RUSTDOC", self.out.join("bootstrap/debug/rustdoc"))
|
||||||
.env("RUSTDOC_REAL", if cmd == "doc" || cmd == "test" {
|
.env("RUSTDOC_REAL", if cmd == "doc" || (cmd == "test" && want_rustdoc) {
|
||||||
self.rustdoc(compiler.host)
|
self.rustdoc(compiler.host)
|
||||||
} else {
|
} else {
|
||||||
PathBuf::from("/path/to/nowhere/rustdoc/not/required")
|
PathBuf::from("/path/to/nowhere/rustdoc/not/required")
|
||||||
@@ -624,7 +626,7 @@ impl<'a> Builder<'a> {
|
|||||||
if let Some(ref error_format) = self.config.rustc_error_format {
|
if let Some(ref error_format) = self.config.rustc_error_format {
|
||||||
cargo.env("RUSTC_ERROR_FORMAT", error_format);
|
cargo.env("RUSTC_ERROR_FORMAT", error_format);
|
||||||
}
|
}
|
||||||
if cmd != "build" && cmd != "check" {
|
if cmd != "build" && cmd != "check" && want_rustdoc {
|
||||||
cargo.env("RUSTDOC_LIBDIR", self.rustc_libdir(self.compiler(2, self.config.build)));
|
cargo.env("RUSTDOC_LIBDIR", self.rustc_libdir(self.compiler(2, self.config.build)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1407,4 +1409,39 @@ mod __test {
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_with_no_doc_stage0() {
|
||||||
|
let mut config = configure(&[], &[]);
|
||||||
|
config.stage = Some(0);
|
||||||
|
config.cmd = Subcommand::Test {
|
||||||
|
paths: vec!["src/libstd".into()],
|
||||||
|
test_args: vec![],
|
||||||
|
rustc_args: vec![],
|
||||||
|
fail_fast: true,
|
||||||
|
doc_tests: DocTests::No,
|
||||||
|
};
|
||||||
|
|
||||||
|
let build = Build::new(config);
|
||||||
|
let mut builder = Builder::new(&build);
|
||||||
|
|
||||||
|
let host = INTERNER.intern_str("A");
|
||||||
|
|
||||||
|
builder.run_step_descriptions(
|
||||||
|
&[StepDescription::from::<test::Crate>()],
|
||||||
|
&["src/libstd".into()],
|
||||||
|
);
|
||||||
|
|
||||||
|
// Ensure we don't build any compiler artifacts.
|
||||||
|
assert!(builder.cache.all::<compile::Rustc>().is_empty());
|
||||||
|
assert_eq!(first(builder.cache.all::<test::Crate>()), &[
|
||||||
|
test::Crate {
|
||||||
|
compiler: Compiler { host, stage: 0 },
|
||||||
|
target: host,
|
||||||
|
mode: Mode::Libstd,
|
||||||
|
test_kind: test::TestKind::Test,
|
||||||
|
krate: INTERNER.intern_str("std"),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ use std::process;
|
|||||||
|
|
||||||
use getopts::Options;
|
use getopts::Options;
|
||||||
|
|
||||||
use Build;
|
use {Build, DocTests};
|
||||||
use config::Config;
|
use config::Config;
|
||||||
use metadata;
|
use metadata;
|
||||||
use builder::Builder;
|
use builder::Builder;
|
||||||
@@ -62,7 +62,7 @@ pub enum Subcommand {
|
|||||||
test_args: Vec<String>,
|
test_args: Vec<String>,
|
||||||
rustc_args: Vec<String>,
|
rustc_args: Vec<String>,
|
||||||
fail_fast: bool,
|
fail_fast: bool,
|
||||||
doc_tests: bool,
|
doc_tests: DocTests,
|
||||||
},
|
},
|
||||||
Bench {
|
Bench {
|
||||||
paths: Vec<PathBuf>,
|
paths: Vec<PathBuf>,
|
||||||
@@ -171,7 +171,8 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`");
|
|||||||
"extra options to pass the compiler when running tests",
|
"extra options to pass the compiler when running tests",
|
||||||
"ARGS",
|
"ARGS",
|
||||||
);
|
);
|
||||||
opts.optflag("", "doc", "run doc tests");
|
opts.optflag("", "no-doc", "do not run doc tests");
|
||||||
|
opts.optflag("", "doc", "only run doc tests");
|
||||||
},
|
},
|
||||||
"bench" => { opts.optmulti("", "test-args", "extra arguments", "ARGS"); },
|
"bench" => { opts.optmulti("", "test-args", "extra arguments", "ARGS"); },
|
||||||
"clean" => { opts.optflag("", "all", "clean all build artifacts"); },
|
"clean" => { opts.optflag("", "all", "clean all build artifacts"); },
|
||||||
@@ -324,7 +325,13 @@ Arguments:
|
|||||||
test_args: matches.opt_strs("test-args"),
|
test_args: matches.opt_strs("test-args"),
|
||||||
rustc_args: matches.opt_strs("rustc-args"),
|
rustc_args: matches.opt_strs("rustc-args"),
|
||||||
fail_fast: !matches.opt_present("no-fail-fast"),
|
fail_fast: !matches.opt_present("no-fail-fast"),
|
||||||
doc_tests: matches.opt_present("doc"),
|
doc_tests: if matches.opt_present("doc") {
|
||||||
|
DocTests::Only
|
||||||
|
} else if matches.opt_present("no-doc") {
|
||||||
|
DocTests::No
|
||||||
|
} else {
|
||||||
|
DocTests::Yes
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"bench" => {
|
"bench" => {
|
||||||
@@ -411,10 +418,10 @@ impl Subcommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn doc_tests(&self) -> bool {
|
pub fn doc_tests(&self) -> DocTests {
|
||||||
match *self {
|
match *self {
|
||||||
Subcommand::Test { doc_tests, .. } => doc_tests,
|
Subcommand::Test { doc_tests, .. } => doc_tests,
|
||||||
_ => false,
|
_ => DocTests::Yes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -210,6 +210,16 @@ pub struct Compiler {
|
|||||||
host: Interned<String>,
|
host: Interned<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
||||||
|
pub enum DocTests {
|
||||||
|
// Default, run normal tests and doc tests.
|
||||||
|
Yes,
|
||||||
|
// Do not run any doc tests.
|
||||||
|
No,
|
||||||
|
// Only run doc tests.
|
||||||
|
Only,
|
||||||
|
}
|
||||||
|
|
||||||
/// Global configuration for the build system.
|
/// Global configuration for the build system.
|
||||||
///
|
///
|
||||||
/// This structure transitively contains all configuration for the build system.
|
/// This structure transitively contains all configuration for the build system.
|
||||||
@@ -233,7 +243,7 @@ pub struct Build {
|
|||||||
rustfmt_info: channel::GitInfo,
|
rustfmt_info: channel::GitInfo,
|
||||||
local_rebuild: bool,
|
local_rebuild: bool,
|
||||||
fail_fast: bool,
|
fail_fast: bool,
|
||||||
doc_tests: bool,
|
doc_tests: DocTests,
|
||||||
verbosity: usize,
|
verbosity: usize,
|
||||||
|
|
||||||
// Targets for which to build.
|
// Targets for which to build.
|
||||||
@@ -294,7 +304,7 @@ impl Crate {
|
|||||||
///
|
///
|
||||||
/// These entries currently correspond to the various output directories of the
|
/// These entries currently correspond to the various output directories of the
|
||||||
/// build system, with each mod generating output in a different directory.
|
/// build system, with each mod generating output in a different directory.
|
||||||
#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub enum Mode {
|
pub enum Mode {
|
||||||
/// Build the standard library, placing output in the "stageN-std" directory.
|
/// Build the standard library, placing output in the "stageN-std" directory.
|
||||||
Libstd,
|
Libstd,
|
||||||
|
|||||||
@@ -32,13 +32,13 @@ use dist;
|
|||||||
use native;
|
use native;
|
||||||
use tool::{self, Tool};
|
use tool::{self, Tool};
|
||||||
use util::{self, dylib_path, dylib_path_var};
|
use util::{self, dylib_path, dylib_path_var};
|
||||||
use Mode;
|
use {Mode, DocTests};
|
||||||
use toolstate::ToolState;
|
use toolstate::ToolState;
|
||||||
|
|
||||||
const ADB_TEST_DIR: &str = "/data/tmp/work";
|
const ADB_TEST_DIR: &str = "/data/tmp/work";
|
||||||
|
|
||||||
/// The two modes of the test runner; tests or benchmarks.
|
/// The two modes of the test runner; tests or benchmarks.
|
||||||
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone, PartialOrd, Ord)]
|
||||||
pub enum TestKind {
|
pub enum TestKind {
|
||||||
/// Run `cargo test`
|
/// Run `cargo test`
|
||||||
Test,
|
Test,
|
||||||
@@ -1407,13 +1407,13 @@ impl Step for CrateNotDefault {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct Crate {
|
pub struct Crate {
|
||||||
compiler: Compiler,
|
pub compiler: Compiler,
|
||||||
target: Interned<String>,
|
pub target: Interned<String>,
|
||||||
mode: Mode,
|
pub mode: Mode,
|
||||||
test_kind: TestKind,
|
pub test_kind: TestKind,
|
||||||
krate: Interned<String>,
|
pub krate: Interned<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Step for Crate {
|
impl Step for Crate {
|
||||||
@@ -1519,9 +1519,15 @@ impl Step for Crate {
|
|||||||
if test_kind.subcommand() == "test" && !builder.fail_fast {
|
if test_kind.subcommand() == "test" && !builder.fail_fast {
|
||||||
cargo.arg("--no-fail-fast");
|
cargo.arg("--no-fail-fast");
|
||||||
}
|
}
|
||||||
if builder.doc_tests {
|
match builder.doc_tests {
|
||||||
|
DocTests::Only => {
|
||||||
cargo.arg("--doc");
|
cargo.arg("--doc");
|
||||||
}
|
}
|
||||||
|
DocTests::No => {
|
||||||
|
cargo.args(&["--lib", "--bins", "--examples", "--tests", "--benches"]);
|
||||||
|
}
|
||||||
|
DocTests::Yes => {}
|
||||||
|
}
|
||||||
|
|
||||||
cargo.arg("-p").arg(krate);
|
cargo.arg("-p").arg(krate);
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,15 @@
|
|||||||
|
|
||||||
// Since libcore defines many fundamental lang items, all tests live in a
|
// Since libcore defines many fundamental lang items, all tests live in a
|
||||||
// separate crate, libcoretest, to avoid bizarre issues.
|
// separate crate, libcoretest, to avoid bizarre issues.
|
||||||
|
//
|
||||||
|
// Here we explicitly #[cfg]-out this whole crate when testing. If we don't do
|
||||||
|
// this, both the generated test artifact and the linked libtest (which
|
||||||
|
// transitively includes libcore) will both define the same set of lang items,
|
||||||
|
// and this will cause the E0152 "duplicate lang item found" error. See
|
||||||
|
// discussion in #50466 for details.
|
||||||
|
//
|
||||||
|
// This cfg won't affect doc tests.
|
||||||
|
#![cfg(not(test))]
|
||||||
|
|
||||||
#![stable(feature = "core", since = "1.6.0")]
|
#![stable(feature = "core", since = "1.6.0")]
|
||||||
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||||
|
|||||||
@@ -135,85 +135,3 @@ pub fn memrchr(x: u8, text: &[u8]) -> Option<usize> {
|
|||||||
// find the byte before the point the body loop stopped
|
// find the byte before the point the body loop stopped
|
||||||
text[..offset].iter().rposition(|elt| *elt == x)
|
text[..offset].iter().rposition(|elt| *elt == x)
|
||||||
}
|
}
|
||||||
|
|
||||||
// test fallback implementations on all platforms
|
|
||||||
#[test]
|
|
||||||
fn matches_one() {
|
|
||||||
assert_eq!(Some(0), memchr(b'a', b"a"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn matches_begin() {
|
|
||||||
assert_eq!(Some(0), memchr(b'a', b"aaaa"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn matches_end() {
|
|
||||||
assert_eq!(Some(4), memchr(b'z', b"aaaaz"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn matches_nul() {
|
|
||||||
assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn matches_past_nul() {
|
|
||||||
assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn no_match_empty() {
|
|
||||||
assert_eq!(None, memchr(b'a', b""));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn no_match() {
|
|
||||||
assert_eq!(None, memchr(b'a', b"xyz"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn matches_one_reversed() {
|
|
||||||
assert_eq!(Some(0), memrchr(b'a', b"a"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn matches_begin_reversed() {
|
|
||||||
assert_eq!(Some(3), memrchr(b'a', b"aaaa"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn matches_end_reversed() {
|
|
||||||
assert_eq!(Some(0), memrchr(b'z', b"zaaaa"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn matches_nul_reversed() {
|
|
||||||
assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn matches_past_nul_reversed() {
|
|
||||||
assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn no_match_empty_reversed() {
|
|
||||||
assert_eq!(None, memrchr(b'a', b""));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn no_match_reversed() {
|
|
||||||
assert_eq!(None, memrchr(b'a', b"xyz"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn each_alignment_reversed() {
|
|
||||||
let mut data = [1u8; 64];
|
|
||||||
let needle = 2;
|
|
||||||
let pos = 40;
|
|
||||||
data[pos] = needle;
|
|
||||||
for start in 0..16 {
|
|
||||||
assert_eq!(Some(pos - start), memrchr(needle, &data[start..]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
#![feature(reverse_bits)]
|
#![feature(reverse_bits)]
|
||||||
#![feature(inclusive_range_methods)]
|
#![feature(inclusive_range_methods)]
|
||||||
#![feature(iterator_find_map)]
|
#![feature(iterator_find_map)]
|
||||||
|
#![feature(slice_internals)]
|
||||||
|
|
||||||
extern crate core;
|
extern crate core;
|
||||||
extern crate test;
|
extern crate test;
|
||||||
@@ -74,4 +75,5 @@ mod result;
|
|||||||
mod slice;
|
mod slice;
|
||||||
mod str;
|
mod str;
|
||||||
mod str_lossy;
|
mod str_lossy;
|
||||||
|
mod time;
|
||||||
mod tuple;
|
mod tuple;
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[cfg(not(stage0))]
|
||||||
fn test_reverse_bits() {
|
fn test_reverse_bits() {
|
||||||
assert_eq!(A.reverse_bits().reverse_bits(), A);
|
assert_eq!(A.reverse_bits().reverse_bits(), A);
|
||||||
assert_eq!(B.reverse_bits().reverse_bits(), B);
|
assert_eq!(B.reverse_bits().reverse_bits(), B);
|
||||||
|
|||||||
@@ -550,3 +550,89 @@ fn sort_unstable() {
|
|||||||
v.sort_unstable();
|
v.sort_unstable();
|
||||||
assert!(v == [0xDEADBEEF]);
|
assert!(v == [0xDEADBEEF]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod memchr {
|
||||||
|
use core::slice::memchr::{memchr, memrchr};
|
||||||
|
|
||||||
|
// test fallback implementations on all platforms
|
||||||
|
#[test]
|
||||||
|
fn matches_one() {
|
||||||
|
assert_eq!(Some(0), memchr(b'a', b"a"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn matches_begin() {
|
||||||
|
assert_eq!(Some(0), memchr(b'a', b"aaaa"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn matches_end() {
|
||||||
|
assert_eq!(Some(4), memchr(b'z', b"aaaaz"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn matches_nul() {
|
||||||
|
assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn matches_past_nul() {
|
||||||
|
assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn no_match_empty() {
|
||||||
|
assert_eq!(None, memchr(b'a', b""));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn no_match() {
|
||||||
|
assert_eq!(None, memchr(b'a', b"xyz"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn matches_one_reversed() {
|
||||||
|
assert_eq!(Some(0), memrchr(b'a', b"a"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn matches_begin_reversed() {
|
||||||
|
assert_eq!(Some(3), memrchr(b'a', b"aaaa"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn matches_end_reversed() {
|
||||||
|
assert_eq!(Some(0), memrchr(b'z', b"zaaaa"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn matches_nul_reversed() {
|
||||||
|
assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn matches_past_nul_reversed() {
|
||||||
|
assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn no_match_empty_reversed() {
|
||||||
|
assert_eq!(None, memrchr(b'a', b""));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn no_match_reversed() {
|
||||||
|
assert_eq!(None, memrchr(b'a', b"xyz"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn each_alignment_reversed() {
|
||||||
|
let mut data = [1u8; 64];
|
||||||
|
let needle = 2;
|
||||||
|
let pos = 40;
|
||||||
|
data[pos] = needle;
|
||||||
|
for start in 0..16 {
|
||||||
|
assert_eq!(Some(pos - start), memrchr(needle, &data[start..]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
124
src/libcore/tests/time.rs
Normal file
124
src/libcore/tests/time.rs
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
use core::time::Duration;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn creation() {
|
||||||
|
assert!(Duration::from_secs(1) != Duration::from_secs(0));
|
||||||
|
assert_eq!(Duration::from_secs(1) + Duration::from_secs(2),
|
||||||
|
Duration::from_secs(3));
|
||||||
|
assert_eq!(Duration::from_millis(10) + Duration::from_secs(4),
|
||||||
|
Duration::new(4, 10 * 1_000_000));
|
||||||
|
assert_eq!(Duration::from_millis(4000), Duration::new(4, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn secs() {
|
||||||
|
assert_eq!(Duration::new(0, 0).as_secs(), 0);
|
||||||
|
assert_eq!(Duration::from_secs(1).as_secs(), 1);
|
||||||
|
assert_eq!(Duration::from_millis(999).as_secs(), 0);
|
||||||
|
assert_eq!(Duration::from_millis(1001).as_secs(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn nanos() {
|
||||||
|
assert_eq!(Duration::new(0, 0).subsec_nanos(), 0);
|
||||||
|
assert_eq!(Duration::new(0, 5).subsec_nanos(), 5);
|
||||||
|
assert_eq!(Duration::new(0, 1_000_000_001).subsec_nanos(), 1);
|
||||||
|
assert_eq!(Duration::from_secs(1).subsec_nanos(), 0);
|
||||||
|
assert_eq!(Duration::from_millis(999).subsec_nanos(), 999 * 1_000_000);
|
||||||
|
assert_eq!(Duration::from_millis(1001).subsec_nanos(), 1 * 1_000_000);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add() {
|
||||||
|
assert_eq!(Duration::new(0, 0) + Duration::new(0, 1),
|
||||||
|
Duration::new(0, 1));
|
||||||
|
assert_eq!(Duration::new(0, 500_000_000) + Duration::new(0, 500_000_001),
|
||||||
|
Duration::new(1, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn checked_add() {
|
||||||
|
assert_eq!(Duration::new(0, 0).checked_add(Duration::new(0, 1)),
|
||||||
|
Some(Duration::new(0, 1)));
|
||||||
|
assert_eq!(Duration::new(0, 500_000_000).checked_add(Duration::new(0, 500_000_001)),
|
||||||
|
Some(Duration::new(1, 1)));
|
||||||
|
assert_eq!(Duration::new(1, 0).checked_add(Duration::new(::core::u64::MAX, 0)), None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sub() {
|
||||||
|
assert_eq!(Duration::new(0, 1) - Duration::new(0, 0),
|
||||||
|
Duration::new(0, 1));
|
||||||
|
assert_eq!(Duration::new(0, 500_000_001) - Duration::new(0, 500_000_000),
|
||||||
|
Duration::new(0, 1));
|
||||||
|
assert_eq!(Duration::new(1, 0) - Duration::new(0, 1),
|
||||||
|
Duration::new(0, 999_999_999));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn checked_sub() {
|
||||||
|
let zero = Duration::new(0, 0);
|
||||||
|
let one_nano = Duration::new(0, 1);
|
||||||
|
let one_sec = Duration::new(1, 0);
|
||||||
|
assert_eq!(one_nano.checked_sub(zero), Some(Duration::new(0, 1)));
|
||||||
|
assert_eq!(one_sec.checked_sub(one_nano),
|
||||||
|
Some(Duration::new(0, 999_999_999)));
|
||||||
|
assert_eq!(zero.checked_sub(one_nano), None);
|
||||||
|
assert_eq!(zero.checked_sub(one_sec), None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn sub_bad1() {
|
||||||
|
let _ = Duration::new(0, 0) - Duration::new(0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn sub_bad2() {
|
||||||
|
let _ = Duration::new(0, 0) - Duration::new(1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn mul() {
|
||||||
|
assert_eq!(Duration::new(0, 1) * 2, Duration::new(0, 2));
|
||||||
|
assert_eq!(Duration::new(1, 1) * 3, Duration::new(3, 3));
|
||||||
|
assert_eq!(Duration::new(0, 500_000_001) * 4, Duration::new(2, 4));
|
||||||
|
assert_eq!(Duration::new(0, 500_000_001) * 4000,
|
||||||
|
Duration::new(2000, 4000));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn checked_mul() {
|
||||||
|
assert_eq!(Duration::new(0, 1).checked_mul(2), Some(Duration::new(0, 2)));
|
||||||
|
assert_eq!(Duration::new(1, 1).checked_mul(3), Some(Duration::new(3, 3)));
|
||||||
|
assert_eq!(Duration::new(0, 500_000_001).checked_mul(4), Some(Duration::new(2, 4)));
|
||||||
|
assert_eq!(Duration::new(0, 500_000_001).checked_mul(4000),
|
||||||
|
Some(Duration::new(2000, 4000)));
|
||||||
|
assert_eq!(Duration::new(::core::u64::MAX - 1, 0).checked_mul(2), None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn div() {
|
||||||
|
assert_eq!(Duration::new(0, 1) / 2, Duration::new(0, 0));
|
||||||
|
assert_eq!(Duration::new(1, 1) / 3, Duration::new(0, 333_333_333));
|
||||||
|
assert_eq!(Duration::new(99, 999_999_000) / 100,
|
||||||
|
Duration::new(0, 999_999_990));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn checked_div() {
|
||||||
|
assert_eq!(Duration::new(2, 0).checked_div(2), Some(Duration::new(1, 0)));
|
||||||
|
assert_eq!(Duration::new(1, 0).checked_div(2), Some(Duration::new(0, 500_000_000)));
|
||||||
|
assert_eq!(Duration::new(2, 0).checked_div(0), None);
|
||||||
|
}
|
||||||
@@ -481,119 +481,3 @@ impl<'a> Sum<&'a Duration> for Duration {
|
|||||||
iter.fold(Duration::new(0, 0), |a, b| a + *b)
|
iter.fold(Duration::new(0, 0), |a, b| a + *b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::Duration;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn creation() {
|
|
||||||
assert!(Duration::from_secs(1) != Duration::from_secs(0));
|
|
||||||
assert_eq!(Duration::from_secs(1) + Duration::from_secs(2),
|
|
||||||
Duration::from_secs(3));
|
|
||||||
assert_eq!(Duration::from_millis(10) + Duration::from_secs(4),
|
|
||||||
Duration::new(4, 10 * 1_000_000));
|
|
||||||
assert_eq!(Duration::from_millis(4000), Duration::new(4, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn secs() {
|
|
||||||
assert_eq!(Duration::new(0, 0).as_secs(), 0);
|
|
||||||
assert_eq!(Duration::from_secs(1).as_secs(), 1);
|
|
||||||
assert_eq!(Duration::from_millis(999).as_secs(), 0);
|
|
||||||
assert_eq!(Duration::from_millis(1001).as_secs(), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn nanos() {
|
|
||||||
assert_eq!(Duration::new(0, 0).subsec_nanos(), 0);
|
|
||||||
assert_eq!(Duration::new(0, 5).subsec_nanos(), 5);
|
|
||||||
assert_eq!(Duration::new(0, 1_000_000_001).subsec_nanos(), 1);
|
|
||||||
assert_eq!(Duration::from_secs(1).subsec_nanos(), 0);
|
|
||||||
assert_eq!(Duration::from_millis(999).subsec_nanos(), 999 * 1_000_000);
|
|
||||||
assert_eq!(Duration::from_millis(1001).subsec_nanos(), 1 * 1_000_000);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn add() {
|
|
||||||
assert_eq!(Duration::new(0, 0) + Duration::new(0, 1),
|
|
||||||
Duration::new(0, 1));
|
|
||||||
assert_eq!(Duration::new(0, 500_000_000) + Duration::new(0, 500_000_001),
|
|
||||||
Duration::new(1, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn checked_add() {
|
|
||||||
assert_eq!(Duration::new(0, 0).checked_add(Duration::new(0, 1)),
|
|
||||||
Some(Duration::new(0, 1)));
|
|
||||||
assert_eq!(Duration::new(0, 500_000_000).checked_add(Duration::new(0, 500_000_001)),
|
|
||||||
Some(Duration::new(1, 1)));
|
|
||||||
assert_eq!(Duration::new(1, 0).checked_add(Duration::new(::u64::MAX, 0)), None);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn sub() {
|
|
||||||
assert_eq!(Duration::new(0, 1) - Duration::new(0, 0),
|
|
||||||
Duration::new(0, 1));
|
|
||||||
assert_eq!(Duration::new(0, 500_000_001) - Duration::new(0, 500_000_000),
|
|
||||||
Duration::new(0, 1));
|
|
||||||
assert_eq!(Duration::new(1, 0) - Duration::new(0, 1),
|
|
||||||
Duration::new(0, 999_999_999));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn checked_sub() {
|
|
||||||
let zero = Duration::new(0, 0);
|
|
||||||
let one_nano = Duration::new(0, 1);
|
|
||||||
let one_sec = Duration::new(1, 0);
|
|
||||||
assert_eq!(one_nano.checked_sub(zero), Some(Duration::new(0, 1)));
|
|
||||||
assert_eq!(one_sec.checked_sub(one_nano),
|
|
||||||
Some(Duration::new(0, 999_999_999)));
|
|
||||||
assert_eq!(zero.checked_sub(one_nano), None);
|
|
||||||
assert_eq!(zero.checked_sub(one_sec), None);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test] #[should_panic]
|
|
||||||
fn sub_bad1() {
|
|
||||||
Duration::new(0, 0) - Duration::new(0, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test] #[should_panic]
|
|
||||||
fn sub_bad2() {
|
|
||||||
Duration::new(0, 0) - Duration::new(1, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn mul() {
|
|
||||||
assert_eq!(Duration::new(0, 1) * 2, Duration::new(0, 2));
|
|
||||||
assert_eq!(Duration::new(1, 1) * 3, Duration::new(3, 3));
|
|
||||||
assert_eq!(Duration::new(0, 500_000_001) * 4, Duration::new(2, 4));
|
|
||||||
assert_eq!(Duration::new(0, 500_000_001) * 4000,
|
|
||||||
Duration::new(2000, 4000));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn checked_mul() {
|
|
||||||
assert_eq!(Duration::new(0, 1).checked_mul(2), Some(Duration::new(0, 2)));
|
|
||||||
assert_eq!(Duration::new(1, 1).checked_mul(3), Some(Duration::new(3, 3)));
|
|
||||||
assert_eq!(Duration::new(0, 500_000_001).checked_mul(4), Some(Duration::new(2, 4)));
|
|
||||||
assert_eq!(Duration::new(0, 500_000_001).checked_mul(4000),
|
|
||||||
Some(Duration::new(2000, 4000)));
|
|
||||||
assert_eq!(Duration::new(::u64::MAX - 1, 0).checked_mul(2), None);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn div() {
|
|
||||||
assert_eq!(Duration::new(0, 1) / 2, Duration::new(0, 0));
|
|
||||||
assert_eq!(Duration::new(1, 1) / 3, Duration::new(0, 333_333_333));
|
|
||||||
assert_eq!(Duration::new(99, 999_999_000) / 100,
|
|
||||||
Duration::new(0, 999_999_990));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn checked_div() {
|
|
||||||
assert_eq!(Duration::new(2, 0).checked_div(2), Some(Duration::new(1, 0)));
|
|
||||||
assert_eq!(Duration::new(1, 0).checked_div(2), Some(Duration::new(0, 500_000_000)));
|
|
||||||
assert_eq!(Duration::new(2, 0).checked_div(0), None);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -330,10 +330,10 @@
|
|||||||
// with a rustc without jemalloc.
|
// with a rustc without jemalloc.
|
||||||
// FIXME(#44236) shouldn't need MSVC logic
|
// FIXME(#44236) shouldn't need MSVC logic
|
||||||
#![cfg_attr(all(not(target_env = "msvc"),
|
#![cfg_attr(all(not(target_env = "msvc"),
|
||||||
any(stage0, feature = "force_alloc_system")),
|
any(all(stage0, not(test)), feature = "force_alloc_system")),
|
||||||
feature(global_allocator))]
|
feature(global_allocator))]
|
||||||
#[cfg(all(not(target_env = "msvc"),
|
#[cfg(all(not(target_env = "msvc"),
|
||||||
any(stage0, feature = "force_alloc_system")))]
|
any(all(stage0, not(test)), feature = "force_alloc_system")))]
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
static ALLOC: alloc_system::System = alloc_system::System;
|
static ALLOC: alloc_system::System = alloc_system::System;
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ pub mod pal;
|
|||||||
pub mod deps;
|
pub mod deps;
|
||||||
pub mod ui_tests;
|
pub mod ui_tests;
|
||||||
pub mod unstable_book;
|
pub mod unstable_book;
|
||||||
|
pub mod libcoretest;
|
||||||
|
|
||||||
fn filter_dirs(path: &Path) -> bool {
|
fn filter_dirs(path: &Path) -> bool {
|
||||||
let skip = [
|
let skip = [
|
||||||
|
|||||||
34
src/tools/tidy/src/libcoretest.rs
Normal file
34
src/tools/tidy/src/libcoretest.rs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
//! Tidy check to ensure `#[test]` is not used directly inside `libcore`.
|
||||||
|
//!
|
||||||
|
//! `#![no_core]` libraries cannot be tested directly due to duplicating lang
|
||||||
|
//! item. All tests must be written externally in `libcore/tests`.
|
||||||
|
|
||||||
|
use std::path::Path;
|
||||||
|
use std::fs::read_to_string;
|
||||||
|
|
||||||
|
pub fn check(path: &Path, bad: &mut bool) {
|
||||||
|
let libcore_path = path.join("libcore");
|
||||||
|
super::walk(
|
||||||
|
&libcore_path,
|
||||||
|
&mut |subpath| t!(subpath.strip_prefix(&libcore_path)).starts_with("tests"),
|
||||||
|
&mut |subpath| {
|
||||||
|
if t!(read_to_string(subpath)).contains("#[test]") {
|
||||||
|
tidy_error!(
|
||||||
|
bad,
|
||||||
|
"{} contains #[test]; libcore tests must be placed inside `src/libcore/tests/`",
|
||||||
|
subpath.display()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -41,6 +41,7 @@ fn main() {
|
|||||||
features::check(&path, &mut bad, quiet);
|
features::check(&path, &mut bad, quiet);
|
||||||
pal::check(&path, &mut bad);
|
pal::check(&path, &mut bad);
|
||||||
unstable_book::check(&path, &mut bad);
|
unstable_book::check(&path, &mut bad);
|
||||||
|
libcoretest::check(&path, &mut bad);
|
||||||
if !args.iter().any(|s| *s == "--no-vendor") {
|
if !args.iter().any(|s| *s == "--no-vendor") {
|
||||||
deps::check(&path, &mut bad);
|
deps::check(&path, &mut bad);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user