Smoke test for git support

This commit is contained in:
Carl Lerche + Yehuda Katz 2014-06-12 15:51:16 -07:00 committed by Tim Carey-Smith
parent 9c101e39a4
commit 35e21c7600
11 changed files with 186 additions and 38 deletions

View File

@ -47,7 +47,7 @@ $(BIN_TARGETS): target/%: src/bin/%.rs $(HAMMER) $(TOML) $(LIBCARGO)
# === Tests
TEST_SRC = $(wildcard tests/*.rs)
TEST_SRC = $(shell find tests -name '*.rs')
TEST_DEPS = $(DEPS) -L libs/hamcrest-rust/target
target/tests/test-integration: $(HAMCREST) $(TEST_SRC) $(BIN_TARGETS)

View File

@ -13,7 +13,7 @@ use hammer::FlagConfig;
use cargo::{execute_main_without_stdin,CLIResult,CLIError,ToResult};
use cargo::ops;
use cargo::util::important_paths::find_project;
use cargo::util::ToCLI;
use cargo::util::{ToCLI,simple_human};
#[deriving(PartialEq,Clone,Decodable,Encodable)]
pub struct Options {

View File

@ -35,6 +35,7 @@ pub fn compile(manifest_path: &Path) -> CargoResult<()> {
let sources = try!(sources_for(&package));
try!(sources.update().wrap("unable to update sources"));
let summaries = try!(sources.list().wrap("unable to list packages from source"));
let resolved = try!(resolve(package.get_dependencies(), &summaries).wrap("unable to resolve dependencies"));

View File

@ -37,6 +37,7 @@ impl Show for GitSource {
impl Source for GitSource {
fn update(&self) -> CargoResult<()> {
log!(5, "updating git source `{}`", self.remote);
let repo = try!(self.remote.checkout(&self.db_path));
try!(repo.copy_to(self.reference.as_slice(), &self.checkout_path));
@ -44,6 +45,7 @@ impl Source for GitSource {
}
fn list(&self) -> CargoResult<Vec<Summary>> {
log!(5, "listing summaries in git source `{}`", self.remote);
let pkg = try!(read_manifest(&self.checkout_path, self.get_namespace()));
Ok(vec!(pkg.get_summary().clone()))
}
@ -53,6 +55,7 @@ impl Source for GitSource {
}
fn get(&self, package_ids: &[PackageId]) -> CargoResult<Vec<Package>> {
log!(5, "getting packages for package ids `{}` from `{}`", package_ids, self.remote);
// TODO: Support multiple manifests per repo
let pkg = try!(read_manifest(&self.checkout_path, self.remote.get_url()));

View File

@ -67,7 +67,7 @@ macro_rules! errln(
* GitRemote represents a remote repository. It gets cloned into a local GitDatabase.
*/
#[deriving(PartialEq,Clone)]
#[deriving(PartialEq,Clone,Show)]
pub struct GitRemote {
url: Url,
verbose: bool
@ -170,7 +170,7 @@ impl GitRemote {
}
fn fetch_into(&self, path: &Path) -> CargoResult<()> {
Ok(git!(*path, self.verbose, "fetch --force --quiet --tags {} refs/heads/*:refs/heads/*", self.url))
Ok(git!(*path, self.verbose, "fetch --force --quiet --tags {} refs/heads/*:refs/heads/*", self.fetch_location()))
}
fn clone_into(&self, path: &Path) -> CargoResult<()> {
@ -179,7 +179,14 @@ impl GitRemote {
try!(mkdir_recursive(path, UserDir).map_err(|err|
human_error(format!("Couldn't recursively create `{}`", dirname.display()), format!("path={}", dirname.display()), io_error(err))));
Ok(git!(dirname, self.verbose, "clone {} {} --bare --no-hardlinks --quiet", self.url, path.display()))
Ok(git!(dirname, self.verbose, "clone {} {} --bare --no-hardlinks --quiet", self.fetch_location(), path.display()))
}
fn fetch_location(&self) -> String {
match self.url.scheme.as_slice() {
"file" => self.url.path.clone(),
_ => self.url.to_str()
}
}
}
@ -254,9 +261,7 @@ impl GitCheckout {
}
fn git(path: &Path, verbose: bool, str: &str) -> ProcessBuilder {
if verbose {
errln!("Executing git {} @ {}", str, path.display());
}
debug!("Executing git {} @ {}", str, path.display());
process("git").args(str.split(' ').collect::<Vec<&str>>().as_slice()).cwd(path.clone())
}

View File

@ -116,14 +116,14 @@ impl CargoError {
CargoError { kind: HumanReadableError, desc: BoxedDescription(desc), detail: detail, .. } => {
CLIError::new(desc, detail, exit_code)
},
CargoError { kind: InternalError, desc: StaticDescription(desc), detail: None, .. } => {
CLIError::new("An unexpected error occurred", Some(desc), exit_code)
ref err @ CargoError { kind: InternalError, desc: StaticDescription(desc), detail: None, .. } => {
CLIError::new(format!("An unexpected error occurred: {}", err), Some(desc), exit_code)
},
CargoError { kind: InternalError, desc: StaticDescription(desc), detail: Some(detail), .. } => {
CLIError::new("An unexpected error occurred", Some(format!("{}\n{}", desc, detail)), exit_code)
ref err @ CargoError { kind: InternalError, desc: StaticDescription(desc), detail: Some(ref detail), .. } => {
CLIError::new(format!("An unexpected error occurred: {}", err), Some(format!("{}\n{}", desc, detail)), exit_code)
},
_ => {
CLIError::new("An unexpected error occurred", None::<&str>, exit_code)
ref err @ _ => {
CLIError::new(format!("An unexpected error occurred: {}", err), None::<&str>, exit_code)
}
}
}

View File

@ -13,7 +13,7 @@ use cargo::core::shell;
use cargo::util::{process,ProcessBuilder,CargoError};
use cargo::util::result::ProcessError;
static CARGO_INTEGRATION_TEST_DIR : &'static str = "cargo-integration-tests";
pub mod paths;
/*
*
@ -49,7 +49,7 @@ impl FileBuilder {
}
#[deriving(PartialEq,Clone)]
struct ProjectBuilder {
pub struct ProjectBuilder {
name: String,
root: Path,
files: Vec<FileBuilder>
@ -64,20 +64,32 @@ impl ProjectBuilder {
}
}
pub fn join<T: Str>(&self, name: &str, path: T) -> ProjectBuilder {
ProjectBuilder {
name: name.as_slice().to_str(),
root: self.root.join(path.as_slice()).clone(),
files: vec!()
}
}
pub fn root(&self) -> Path {
self.root.clone()
}
pub fn cargo_process(&self, program: &str) -> ProcessBuilder {
self.build();
pub fn process(&self, program: &str) -> ProcessBuilder {
process(program)
.cwd(self.root())
.env("HOME", Some(paths::home().display().to_str().as_slice()))
}
pub fn cargo_process(&self, program: &str) -> ProcessBuilder {
self.build();
self.process(program)
.extra_path(cargo_dir())
}
pub fn file<B: BytesContainer>(mut self, path: B, body: &str) -> ProjectBuilder {
self.files.push(FileBuilder::new(self.root.join(path), body));
pub fn file<B: BytesContainer, S: Str>(mut self, path: B, body: S) -> ProjectBuilder {
self.files.push(FileBuilder::new(self.root.join(path), body.as_slice()));
self
}
@ -115,7 +127,7 @@ impl ProjectBuilder {
// Generates a project layout
pub fn project(name: &str) -> ProjectBuilder {
ProjectBuilder::new(name, os::tmpdir().join(CARGO_INTEGRATION_TEST_DIR))
ProjectBuilder::new(name, paths::root().join(name))
}
// === Helpers ===
@ -130,6 +142,20 @@ pub fn rmdir_recursive(path: &Path) -> Result<(), String> {
.with_err_msg(format!("could not rm directory; path={}", path.display()))
}
pub fn main_file<T: Str>(println: T, deps: &[&str]) -> String {
let mut buf = String::new();
for dep in deps.iter() {
buf.push_str(format!("extern crate {};\n", dep).as_slice());
}
buf.push_str("fn main() { println!(");
buf.push_str(println.as_slice());
buf.push_str("); }\n");
buf.to_str()
}
trait ErrMsg<T> {
fn with_err_msg(self, val: String) -> Result<T, String>;
}

46
tests/support/paths.rs Normal file
View File

@ -0,0 +1,46 @@
use std::{io,os};
use std::io::IoResult;
use std::io::fs;
use cargo::util::realpath;
static CARGO_INTEGRATION_TEST_DIR : &'static str = "cargo-integration-tests";
pub fn root() -> Path {
realpath(&os::tmpdir().join(CARGO_INTEGRATION_TEST_DIR)).unwrap()
}
pub fn home() -> Path {
root().join("home")
}
pub trait PathExt {
fn rm_rf(&self) -> IoResult<()>;
fn mkdir_p(&self) -> IoResult<()>;
}
impl PathExt for Path {
/* Technically there is a potential race condition, but we don't
* care all that much for our tests
*/
fn rm_rf(&self) -> IoResult<()> {
if self.exists() {
fs::rmdir_recursive(self)
}
else {
Ok(())
}
}
fn mkdir_p(&self) -> IoResult<()> {
fs::mkdir_recursive(self, io::UserDir)
}
}
/**
* Ensure required test directories exist and are empty
*/
pub fn setup() {
debug!("path setup; root={}; home={}", root().display(), home().display());
root().rm_rf().unwrap();
home().mkdir_p().unwrap();
}

View File

@ -1,4 +1,4 @@
use support::{ResultTest,project,execs};
use support::{ResultTest,project,execs,main_file};
use hamcrest::{assert_that,existing_file};
use cargo;
use cargo::util::{process,realpath};
@ -284,18 +284,4 @@ test!(cargo_compile_with_nested_deps_longhand {
execs().with_stdout("test passed\n"));
})
fn main_file(println: &str, deps: &[&str]) -> String {
let mut buf = String::new();
for dep in deps.iter() {
buf.push_str(format!("extern crate {};\n", dep).as_slice());
}
buf.push_str("fn main() { println!(");
buf.push_str(println);
buf.push_str("); }\n");
buf.to_str()
}
// test!(compiling_project_with_invalid_manifest)

View File

@ -0,0 +1,79 @@
use support::{ProjectBuilder,ResultTest,project,execs,main_file};
use hamcrest::{assert_that,existing_file};
use cargo;
use cargo::util::{CargoResult,process};
fn setup() {
}
fn git_repo(name: &str, callback: |ProjectBuilder| -> ProjectBuilder) -> CargoResult<ProjectBuilder> {
let mut git_project = project(name);
git_project = callback(git_project);
git_project.build();
log!(5, "git init");
try!(git_project.process("git").args(["init"]).exec_with_output());
log!(5, "building git project");
log!(5, "git add .");
try!(git_project.process("git").args(["add", "."]).exec_with_output());
log!(5, "git commit");
try!(git_project.process("git").args(["commit", "-m", "Initial commit"]).exec_with_output());
Ok(git_project)
}
test!(cargo_compile_simple_git_dep {
let project = project("foo");
let git_project = git_repo("dep1", |project| {
project
.file("Cargo.toml", r#"
[project]
name = "dep1"
version = "0.5.0"
authors = ["carlhuda@example.com"]
[[lib]]
name = "dep1"
"#)
.file("src/dep1.rs", r#"
pub fn hello() -> &'static str {
"hello world"
}
"#)
}).assert();
let project = project
.file("Cargo.toml", format!(r#"
[project]
name = "foo"
version = "0.5.0"
authors = ["wycats@example.com"]
[dependencies.dep1]
version = "0.5.0"
git = "file://{}"
[[bin]]
name = "foo"
"#, git_project.root().display()))
.file("src/foo.rs", main_file(r#""{}", dep1::hello()"#, ["dep1"]));
let root = project.root();
let git_root = git_project.root();
assert_that(project.cargo_process("cargo-compile"),
execs()
.with_stdout(format!("Compiling dep1 v0.5.0 (file:{})\nCompiling foo v0.5.0 (file:{})\n",
git_root.display(), root.display()))
.with_stderr(""));
assert_that(&project.root().join("target/foo"), existing_file());
assert_that(
cargo::util::process("foo").extra_path(project.root().join("target")),
execs().with_stdout("hello world\n"));
})

View File

@ -8,16 +8,18 @@ extern crate hamcrest;
#[phase(plugin, link)]
extern crate log;
mod support;
macro_rules! test(
($name:ident $expr:expr) => (
#[test]
fn $name() {
::support::paths::setup();
setup();
$expr;
}
)
)
mod support;
mod test_cargo_compile;
mod test_cargo_compile_git_deps;
mod test_shell;