Auto merge of #32348 - brson:cargotest, r=alexcrichton

Introduce 'cargotest' and the check-cargotest buildstep

This is a new suite of tests that verifies that the compiler builds specific revisions of select crates from crates.io.

It does not run by default. It is intended that bors runs these tests against all PRs, and gates on them. In this way we will make it harder still to break important swaths of the ecosystem, even on nightly.

This is a very basic implementation intended for feedback. The biggest thing it probably should do but doesn't is use a lockfile for every project it builds.

r? @alexcrichton cc @rust-lang/lang @rust-lang/libs
This commit is contained in:
bors 2016-03-23 01:03:04 -07:00
commit d6af19b89c
8 changed files with 529 additions and 0 deletions

View File

@ -16,3 +16,11 @@ pub fn linkcheck(build: &Build, stage: u32, host: &str) {
build.run(build.tool_cmd(&compiler, "linkchecker") build.run(build.tool_cmd(&compiler, "linkchecker")
.arg(build.out.join(host).join("doc"))); .arg(build.out.join(host).join("doc")));
} }
pub fn cargotest(build: &Build, stage: u32, host: &str) {
let ref compiler = Compiler::new(stage, host);
build.run(build.tool_cmd(compiler, "cargotest")
.env("RUSTC", build.compiler_path(compiler))
.env("RUSTDOC", build.rustdoc(compiler))
.arg(&build.cargo));
}

View File

@ -183,6 +183,9 @@ impl Build {
compile::tool(self, stage, target.target, compile::tool(self, stage, target.target,
"error_index_generator"); "error_index_generator");
} }
ToolCargoTest { stage } => {
compile::tool(self, stage, target.target, "cargotest");
}
DocBook { stage } => { DocBook { stage } => {
doc::rustbook(self, stage, target.target, "book", &doc_out); doc::rustbook(self, stage, target.target, "book", &doc_out);
} }
@ -210,6 +213,9 @@ impl Build {
CheckLinkcheck { stage } => { CheckLinkcheck { stage } => {
check::linkcheck(self, stage, target.target); check::linkcheck(self, stage, target.target);
} }
CheckCargoTest { stage } => {
check::cargotest(self, stage, target.target);
}
DistDocs { stage } => dist::docs(self, stage, target.target), DistDocs { stage } => dist::docs(self, stage, target.target),
DistMingw { _dummy } => dist::mingw(self, target.target), DistMingw { _dummy } => dist::mingw(self, target.target),

View File

@ -47,6 +47,7 @@ macro_rules! targets {
(tool_linkchecker, ToolLinkchecker { stage: u32 }), (tool_linkchecker, ToolLinkchecker { stage: u32 }),
(tool_rustbook, ToolRustbook { stage: u32 }), (tool_rustbook, ToolRustbook { stage: u32 }),
(tool_error_index, ToolErrorIndex { stage: u32 }), (tool_error_index, ToolErrorIndex { stage: u32 }),
(tool_cargotest, ToolCargoTest { stage: u32 }),
// Steps for long-running native builds. Ideally these wouldn't // Steps for long-running native builds. Ideally these wouldn't
// actually exist and would be part of build scripts, but for now // actually exist and would be part of build scripts, but for now
@ -73,6 +74,7 @@ macro_rules! targets {
// target to depend on a bunch of others. // target to depend on a bunch of others.
(check, Check { stage: u32, compiler: Compiler<'a> }), (check, Check { stage: u32, compiler: Compiler<'a> }),
(check_linkcheck, CheckLinkcheck { stage: u32 }), (check_linkcheck, CheckLinkcheck { stage: u32 }),
(check_cargotest, CheckCargoTest { stage: u32 }),
// Distribution targets, creating tarballs // Distribution targets, creating tarballs
(dist, Dist { stage: u32 }), (dist, Dist { stage: u32 }),
@ -292,6 +294,9 @@ impl<'a> Step<'a> {
Source::CheckLinkcheck { stage } => { Source::CheckLinkcheck { stage } => {
vec![self.tool_linkchecker(stage), self.doc(stage)] vec![self.tool_linkchecker(stage), self.doc(stage)]
} }
Source::CheckCargoTest { stage } => {
vec![self.tool_cargotest(stage)]
}
Source::ToolLinkchecker { stage } => { Source::ToolLinkchecker { stage } => {
vec![self.libstd(self.compiler(stage))] vec![self.libstd(self.compiler(stage))]
@ -300,6 +305,9 @@ impl<'a> Step<'a> {
Source::ToolRustbook { stage } => { Source::ToolRustbook { stage } => {
vec![self.librustc(self.compiler(stage))] vec![self.librustc(self.compiler(stage))]
} }
Source::ToolCargoTest { stage } => {
vec![self.libstd(self.compiler(stage))]
}
Source::DistDocs { stage } => vec![self.doc(stage)], Source::DistDocs { stage } => vec![self.doc(stage)],
Source::DistMingw { _dummy: _ } => Vec::new(), Source::DistMingw { _dummy: _ } => Vec::new(),

View File

@ -38,6 +38,8 @@ standalone-docs:
$(Q)$(BOOTSTRAP) --step doc-standalone $(Q)$(BOOTSTRAP) --step doc-standalone
check: check:
$(Q)$(BOOTSTRAP) --step check $(Q)$(BOOTSTRAP) --step check
cargotest:
$(Q)$(BOOTSTRAP) --step cargotest
dist: dist:
$(Q)$(BOOTSTRAP) --step dist $(Q)$(BOOTSTRAP) --step dist

28
src/tools/cargotest/Cargo.lock generated Normal file
View File

@ -0,0 +1,28 @@
[root]
name = "cargotest"
version = "0.1.0"
dependencies = [
"tempdir 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "libc"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rand"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tempdir"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
]

View File

@ -0,0 +1,11 @@
[package]
name = "cargotest"
version = "0.1.0"
authors = ["Brian Anderson <banderson@mozilla.com>"]
[dependencies]
tempdir = "0.3.4"
[[bin]]
name = "cargotest"
path = "main.rs"

View File

@ -0,0 +1,364 @@
[root]
name = "iron"
version = "0.3.0"
dependencies = [
"conduit-mime-types 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"error 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"modifier 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"plugin 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
"typemap 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bitflags"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "conduit-mime-types"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cookie"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"openssl 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "error"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"traitobject 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "gcc"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "gdi32-sys"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "hpack"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "httparse"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "hyper"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cookie 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"httparse 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
"solicit 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
"traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "kernel32-sys"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "language-tags"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lazy_static"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libressl-pnacl-sys"
version = "2.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"pnacl-build-helper 1.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "log"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "matches"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "mime"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "modifier"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "num_cpus"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "openssl"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys-extras 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "openssl-sys"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"gdi32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"libressl-pnacl-sys 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"user32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "openssl-sys-extras"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pkg-config"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "plugin"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"typemap 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pnacl-build-helper"
version = "1.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"tempdir 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustc-serialize"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rustc_version"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "semver"
version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "solicit"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"hpack 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tempdir"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "time"
version = "0.1.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "traitobject"
version = "0.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "traitobject"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "typeable"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "typemap"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unsafe-any 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicase"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-bidi"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-normalization"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unsafe-any"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"traitobject 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "url"
version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"uuid 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "user32-sys"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "uuid"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-build"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"

102
src/tools/cargotest/main.rs Normal file
View File

@ -0,0 +1,102 @@
// Copyright 2016 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.
extern crate tempdir;
use tempdir::TempDir;
use std::env;
use std::process::Command;
use std::path::Path;
use std::fs::File;
use std::io::Write;
const TEST_REPOS: &'static [(&'static str, &'static str, Option<&'static str>)] = &[
("https://github.com/rust-lang/cargo",
"ff02b156f094fb83e70acd965c83c9286411914e",
None),
("https://github.com/iron/iron",
"16c858ec2901e2992fe5e529780f59fa8ed12903",
Some(include_str!("lockfiles/iron-Cargo.lock")))
];
fn main() {
let ref cargo = env::args().collect::<Vec<_>>()[1];
let ref cargo = Path::new(cargo);
for &(repo, sha, lockfile) in TEST_REPOS.iter().rev() {
test_repo(cargo, repo, sha, lockfile);
}
}
fn test_repo(cargo: &Path, repo: &str, sha: &str, lockfile: Option<&str>) {
println!("testing {}", repo);
let dir = clone_repo(repo, sha);
if let Some(lockfile) = lockfile {
File::create(&dir.path().join("Cargo.lock")).expect("")
.write_all(lockfile.as_bytes()).expect("");
}
if !run_cargo_test(cargo, dir.path()) {
panic!("tests failed for {}", repo);
}
}
fn clone_repo(repo: &str, sha: &str) -> TempDir {
let dir = TempDir::new("cargotest").expect("");
let status = Command::new("git")
.arg("init")
.arg(dir.path())
.status()
.expect("");
assert!(status.success());
// Try progressively deeper fetch depths to find the commit
let mut found = false;
for depth in &[1, 10, 100, 1000, 100000] {
let status = Command::new("git")
.arg("fetch")
.arg(repo)
.arg("master")
.arg(&format!("--depth={}", depth))
.current_dir(dir.path())
.status()
.expect("");
assert!(status.success());
let status = Command::new("git")
.arg("reset")
.arg(sha)
.arg("--hard")
.current_dir(dir.path())
.status()
.expect("");
if status.success() {
found = true;
break;
}
}
if !found { panic!("unable to find commit {}", sha) }
dir
}
fn run_cargo_test(cargo_path: &Path, crate_path: &Path) -> bool {
let status = Command::new(cargo_path)
.arg("test")
// Disable rust-lang/cargo's cross-compile tests
.env("CFG_DISABLE_CROSS_TESTS", "1")
.current_dir(crate_path)
.status()
.expect("");
status.success()
}