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.
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.
14 use std::hashmap::HashMap;
15 use std::{io, libc, os, result, run, str};
16 use extra::tempfile::mkdtemp;
17 use std::run::ProcessOutput;
18 use installed_packages::list_installed_packages;
20 use package_id::{PkgId};
21 use version::{ExactRevision, NoVersion, Version};
22 use path_util::{target_executable_in_workspace, target_library_in_workspace,
23 target_test_in_workspace, target_bench_in_workspace,
24 make_dir_rwx, U_RWX, library_in_workspace,
25 built_bench_in_workspace, built_test_in_workspace,
26 built_library_in_workspace, built_executable_in_workspace,
27 installed_library_in_workspace, rust_path};
30 /// Returns the last-modified date as an Option
31 fn datestamp(p: &Path) -> Option<libc::time_t> {
32 p.stat().map(|stat| stat.st_mtime)
35 fn fake_ctxt(sysroot_opt: Option<@Path>) -> Ctx {
37 sysroot_opt: sysroot_opt,
39 dep_cache: @mut HashMap::new()
43 fn fake_pkg() -> PkgId {
45 let remote = RemotePath(Path(sn));
47 local_path: normalize(remote.clone()),
54 fn git_repo_pkg() -> PkgId {
55 let remote = RemotePath(Path("mockgithub.com/catamorphism/test-pkg"));
57 local_path: normalize(remote.clone()),
59 short_name: ~"test_pkg",
64 fn writeFile(file_path: &Path, contents: &str) {
65 let out: @io::Writer =
66 result::unwrap(io::file_writer(file_path,
67 [io::Create, io::Truncate]));
68 out.write_line(contents);
71 fn mk_empty_workspace(short_name: &LocalPath, version: &Version) -> Path {
72 let workspace_dir = mkdtemp(&os::tmpdir(), "test").expect("couldn't create temp dir");
73 mk_workspace(&workspace_dir, short_name, version);
77 fn mk_workspace(workspace: &Path, short_name: &LocalPath, version: &Version) -> Path {
78 // include version number in directory name
79 let package_dir = workspace.push("src").push(fmt!("%s-%s",
80 short_name.to_str(), version.to_str()));
81 assert!(os::mkdir_recursive(&package_dir, U_RWX));
85 fn mk_temp_workspace(short_name: &LocalPath, version: &Version) -> Path {
86 let package_dir = mk_empty_workspace(short_name,
87 version).push("src").push(fmt!("%s-%s",
91 debug!("Created %s and does it exist? %?", package_dir.to_str(),
92 os::path_is_dir(&package_dir));
93 // Create main, lib, test, and bench files
94 debug!("mk_workspace: creating %s", package_dir.to_str());
95 assert!(os::mkdir_recursive(&package_dir, U_RWX));
96 debug!("Created %s and does it exist? %?", package_dir.to_str(),
97 os::path_is_dir(&package_dir));
98 // Create main, lib, test, and bench files
100 writeFile(&package_dir.push("main.rs"),
101 "fn main() { let _x = (); }");
102 writeFile(&package_dir.push("lib.rs"),
103 "pub fn f() { let _x = (); }");
104 writeFile(&package_dir.push("test.rs"),
105 "#[test] pub fn f() { (); }");
106 writeFile(&package_dir.push("bench.rs"),
107 "#[bench] pub fn f() { (); }");
111 /// Should create an empty git repo in p, relative to the tmp dir, and return the new
113 fn init_git_repo(p: &Path) -> Path {
114 assert!(!p.is_absolute());
115 let tmp = mkdtemp(&os::tmpdir(), "git_local").expect("couldn't create temp dir");
116 let work_dir = tmp.push_rel(p);
117 let work_dir_for_opts = work_dir.clone();
118 assert!(os::mkdir_recursive(&work_dir, U_RWX));
119 debug!("Running: git init in %s", work_dir.to_str());
120 let opts = run::ProcessOptions {
122 dir: Some(&work_dir_for_opts),
127 let mut prog = run::Process::new("git", [~"init"], opts);
128 let mut output = prog.finish_with_output();
129 if output.status == 0 {
130 // Add stuff to the dir so that git tag succeeds
131 writeFile(&work_dir.push("README"), "");
132 prog = run::Process::new("git", [~"add", ~"README"], opts);
133 output = prog.finish_with_output();
134 if output.status == 0 {
135 prog = run::Process::new("git", [~"commit", ~"-m", ~"whatever"], opts);
136 output = prog.finish_with_output();
137 if output.status == 0 {
141 fail!("Couldn't commit in %s", work_dir.to_str());
145 fail!("Couldn't add in %s", work_dir.to_str());
149 fail!("Couldn't initialize git repository in %s", work_dir.to_str())
153 fn add_git_tag(repo: &Path, tag: ~str) {
154 assert!(repo.is_absolute());
155 let mut prog = run::Process::new("git", [~"add", ~"-A"],
156 run::ProcessOptions { env: None,
162 let output = prog.finish_with_output();
163 if output.status != 0 {
164 fail!("Couldn't add all files in %s", repo.to_str())
166 prog = run::Process::new("git", [~"commit", ~"-m", ~"whatever"],
167 run::ProcessOptions { env: None,
173 let output = prog.finish_with_output();
174 if output.status != 0 {
175 fail!("Couldn't commit in %s", repo.to_str())
178 prog = run::Process::new("git", [~"tag", tag.clone()],
179 run::ProcessOptions { env: None,
185 let output = prog.finish_with_output();
186 if output.status != 0 {
187 fail!("Couldn't add git tag %s in %s", tag, repo.to_str())
191 fn is_rwx(p: &Path) -> bool {
192 use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
195 None => return false,
197 ((m & S_IRUSR as uint) == S_IRUSR as uint
198 && (m & S_IWUSR as uint) == S_IWUSR as uint
199 && (m & S_IXUSR as uint) == S_IXUSR as uint)
203 fn test_sysroot() -> Path {
204 // Totally gross hack but it's just for test cases.
205 // Infer the sysroot from the exe name and pray that it's right.
206 // (Did I mention it was a gross hack?)
207 let self_path = os::self_exe_path().expect("Couldn't get self_exe path");
211 fn command_line_test(args: &[~str], cwd: &Path) -> ProcessOutput {
212 command_line_test_with_env(args, cwd, None)
215 /// Runs `rustpkg` (based on the directory that this executable was
216 /// invoked from) with the given arguments, in the given working directory.
217 /// Returns the process's output.
218 fn command_line_test_with_env(args: &[~str], cwd: &Path, env: Option<~[(~str, ~str)]>)
220 let cmd = test_sysroot().push("bin").push("rustpkg").to_str();
221 debug!("About to run command: %? %? in %s", cmd, args, cwd.to_str());
222 assert!(os::path_is_dir(&*cwd));
223 let cwd = (*cwd).clone();
224 let mut prog = run::Process::new(cmd, args, run::ProcessOptions {
225 env: env.map(|v| v.slice(0, v.len())),
231 let output = prog.finish_with_output();
232 debug!("Output from command %s with args %? was %s {%s}[%?]",
233 cmd, args, str::from_bytes(output.output),
234 str::from_bytes(output.error),
237 By the way, rustpkg *won't* return a nonzero exit code if it fails --
239 So tests that use this need to check the existence of a file
240 to make sure the command succeeded
242 if output.status != 0 {
243 fail!("Command %s %? failed with exit code %?",
244 cmd, args, output.status);
249 fn create_local_package(pkgid: &PkgId) -> Path {
250 let parent_dir = mk_temp_workspace(&pkgid.local_path, &pkgid.version);
251 debug!("Created empty package dir for %s, returning %s", pkgid.to_str(), parent_dir.to_str());
252 parent_dir.pop().pop()
255 fn create_local_package_in(pkgid: &PkgId, pkgdir: &Path) -> Path {
257 let package_dir = pkgdir.push("src").push(pkgid.to_str());
259 // Create main, lib, test, and bench files
260 assert!(os::mkdir_recursive(&package_dir, U_RWX));
261 debug!("Created %s and does it exist? %?", package_dir.to_str(),
262 os::path_is_dir(&package_dir));
263 // Create main, lib, test, and bench files
265 writeFile(&package_dir.push("main.rs"),
266 "fn main() { let _x = (); }");
267 writeFile(&package_dir.push("lib.rs"),
268 "pub fn f() { let _x = (); }");
269 writeFile(&package_dir.push("test.rs"),
270 "#[test] pub fn f() { (); }");
271 writeFile(&package_dir.push("bench.rs"),
272 "#[bench] pub fn f() { (); }");
276 fn create_local_package_with_test(pkgid: &PkgId) -> Path {
277 debug!("Dry run -- would create package %s with test");
278 create_local_package(pkgid) // Already has tests???
281 fn create_local_package_with_dep(pkgid: &PkgId, subord_pkgid: &PkgId) -> Path {
282 let package_dir = create_local_package(pkgid);
283 create_local_package_in(subord_pkgid, &package_dir);
284 // Write a main.rs file into pkgid that references subord_pkgid
285 writeFile(&package_dir.push("src").push(pkgid.to_str()).push("main.rs"),
286 fmt!("extern mod %s;\nfn main() {}",
287 subord_pkgid.short_name));
288 // Write a lib.rs file into subord_pkgid that has something in it
289 writeFile(&package_dir.push("src").push(subord_pkgid.to_str()).push("lib.rs"),
291 debug!("Dry run -- would create packages %s and %s in %s",
293 subord_pkgid.to_str(),
294 package_dir.to_str());
298 fn create_local_package_with_custom_build_hook(pkgid: &PkgId,
299 custom_build_hook: &str) -> Path {
300 debug!("Dry run -- would create package %s with custom build hook %s",
301 pkgid.to_str(), custom_build_hook);
302 create_local_package(pkgid)
303 // actually write the pkg.rs with the custom build hook
307 fn assert_lib_exists(repo: &Path, short_name: &str, v: Version) {
308 debug!("assert_lib_exists: repo = %s, short_name = %s", repo.to_str(), short_name);
309 let lib = target_library_in_workspace(&(PkgId {
310 version: v, ..PkgId::new(short_name, repo)}
312 debug!("assert_lib_exists: checking whether %s exists", lib.to_str());
313 assert!(os::path_exists(&lib));
314 assert!(is_rwx(&lib));
317 fn assert_executable_exists(repo: &Path, short_name: &str) {
318 debug!("assert_executable_exists: repo = %s, short_name = %s", repo.to_str(), short_name);
319 let exec = target_executable_in_workspace(&PkgId::new(short_name, repo), repo);
320 assert!(os::path_exists(&exec));
321 assert!(is_rwx(&exec));
324 fn assert_built_executable_exists(repo: &Path, short_name: &str) {
325 debug!("assert_built_executable_exists: repo = %s, short_name = %s", repo.to_str(), short_name);
326 let exec = built_executable_in_workspace(&PkgId::new(short_name, repo),
327 repo).expect("assert_built_executable_exists failed");
328 assert!(os::path_exists(&exec));
329 assert!(is_rwx(&exec));
332 fn command_line_test_output(args: &[~str]) -> ~[~str] {
333 let mut result = ~[];
334 let p_output = command_line_test(args, &os::getcwd());
335 let test_output = str::from_bytes(p_output.output);
336 for test_output.split_iter('\n').advance |s| {
337 result.push(s.to_owned());
342 fn command_line_test_output_with_env(args: &[~str], env: ~[(~str, ~str)]) -> ~[~str] {
343 let mut result = ~[];
344 let p_output = command_line_test_with_env(args, &os::getcwd(), Some(env));
345 let test_output = str::from_bytes(p_output.output);
346 for test_output.split_iter('\n').advance |s| {
347 result.push(s.to_owned());
352 // assumes short_name and local_path are one and the same -- I should fix
353 fn lib_output_file_name(workspace: &Path, parent: &str, short_name: &str) -> Path {
354 debug!("lib_output_file_name: given %s and parent %s and short name %s",
355 workspace.to_str(), parent, short_name);
356 library_in_workspace(&normalize(RemotePath(Path(short_name))),
360 "build").expect("lib_output_file_name")
363 fn output_file_name(workspace: &Path, short_name: &str) -> Path {
364 workspace.push(fmt!("%s%s", short_name, os::EXE_SUFFIX))
367 fn touch_source_file(workspace: &Path, pkgid: &PkgId) {
368 use conditions::bad_path::cond;
369 let pkg_src_dir = workspace.push("src").push(pkgid.to_str());
370 let contents = os::list_dir_path(&pkg_src_dir);
371 for contents.iter().advance |p| {
372 if p.filetype() == Some(~".rs") {
373 // should be able to do this w/o a process
374 if run::process_output("touch", [p.to_str()]).status != 0 {
375 let _ = cond.raise((pkg_src_dir.clone(), ~"Bad path"));
382 /// Add a blank line at the end
383 fn frob_source_file(workspace: &Path, pkgid: &PkgId) {
384 use conditions::bad_path::cond;
385 let pkg_src_dir = workspace.push("src").push(pkgid.to_str());
386 let contents = os::list_dir_path(&pkg_src_dir);
387 let mut maybe_p = None;
388 for contents.iter().advance |p| {
389 if p.filetype() == Some(~".rs") {
396 let w = io::file_writer(p, &[io::Append]);
398 Err(s) => { let _ = cond.raise((p.clone(), fmt!("Bad path: %s", s))); }
399 Ok(w) => w.write_line("")
402 None => fail!(fmt!("frob_source_file failed to find a source file in %s",
403 pkg_src_dir.to_str()))
407 // FIXME(#7249): these tests fail on multi-platform builds, so for now they're
410 #[test] #[ignore(cfg(target_arch = "x86"))]
411 fn test_make_dir_rwx() {
412 let temp = &os::tmpdir();
413 let dir = temp.push("quux");
414 assert!(!os::path_exists(&dir) ||
415 os::remove_dir_recursive(&dir));
416 debug!("Trying to make %s", dir.to_str());
417 assert!(make_dir_rwx(&dir));
418 assert!(os::path_is_dir(&dir));
419 assert!(is_rwx(&dir));
420 assert!(os::remove_dir_recursive(&dir));
423 #[test] #[ignore(cfg(target_arch = "x86"))]
424 fn test_install_valid() {
425 use path_util::installed_library_in_workspace;
427 let sysroot = test_sysroot();
428 debug!("sysroot = %s", sysroot.to_str());
429 let ctxt = fake_ctxt(Some(@sysroot));
430 let temp_pkg_id = fake_pkg();
431 let temp_workspace = mk_temp_workspace(&temp_pkg_id.local_path, &NoVersion).pop().pop();
432 debug!("temp_workspace = %s", temp_workspace.to_str());
433 // should have test, bench, lib, and main
434 ctxt.install(&temp_workspace, &temp_pkg_id);
435 // Check that all files exist
436 let exec = target_executable_in_workspace(&temp_pkg_id, &temp_workspace);
437 debug!("exec = %s", exec.to_str());
438 assert!(os::path_exists(&exec));
439 assert!(is_rwx(&exec));
441 let lib = installed_library_in_workspace(temp_pkg_id.short_name, &temp_workspace);
442 debug!("lib = %?", lib);
443 assert!(lib.map_default(false, |l| os::path_exists(l)));
444 assert!(lib.map_default(false, |l| is_rwx(l)));
446 // And that the test and bench executables aren't installed
447 assert!(!os::path_exists(&target_test_in_workspace(&temp_pkg_id, &temp_workspace)));
448 let bench = target_bench_in_workspace(&temp_pkg_id, &temp_workspace);
449 debug!("bench = %s", bench.to_str());
450 assert!(!os::path_exists(&bench));
453 #[test] #[ignore(cfg(target_arch = "x86"))]
454 fn test_install_invalid() {
455 use conditions::nonexistent_package::cond;
456 use cond1 = conditions::missing_pkg_files::cond;
458 let ctxt = fake_ctxt(None);
459 let pkgid = fake_pkg();
460 let temp_workspace = mkdtemp(&os::tmpdir(), "test").expect("couldn't create temp dir");
461 let mut error_occurred = false;
462 let mut error1_occurred = false;
464 error1_occurred = true;
467 error_occurred = true;
468 temp_workspace.clone()
470 ctxt.install(&temp_workspace, &pkgid);
473 assert!(error_occurred && error1_occurred);
476 // Tests above should (maybe) be converted to shell out to rustpkg, too
478 // FIXME: #7956: temporarily disabled
479 #[ignore(cfg(target_arch = "x86"))]
480 fn test_install_git() {
481 let sysroot = test_sysroot();
482 debug!("sysroot = %s", sysroot.to_str());
483 let temp_pkg_id = git_repo_pkg();
484 let repo = init_git_repo(&Path(temp_pkg_id.local_path.to_str()));
485 let repo_subdir = repo.push("mockgithub.com").push("catamorphism").push("test_pkg");
486 writeFile(&repo_subdir.push("main.rs"),
487 "fn main() { let _x = (); }");
488 writeFile(&repo_subdir.push("lib.rs"),
489 "pub fn f() { let _x = (); }");
490 writeFile(&repo_subdir.push("test.rs"),
491 "#[test] pub fn f() { (); }");
492 writeFile(&repo_subdir.push("bench.rs"),
493 "#[bench] pub fn f() { (); }");
494 add_git_tag(&repo_subdir, ~"0.1"); // this has the effect of committing the files
496 debug!("test_install_git: calling rustpkg install %s in %s",
497 temp_pkg_id.local_path.to_str(), repo.to_str());
498 // should have test, bench, lib, and main
499 command_line_test([~"install", temp_pkg_id.local_path.to_str()], &repo);
500 // Check that all files exist
501 debug!("Checking for files in %s", repo.to_str());
502 let exec = target_executable_in_workspace(&temp_pkg_id, &repo);
503 debug!("exec = %s", exec.to_str());
504 assert!(os::path_exists(&exec));
505 assert!(is_rwx(&exec));
507 built_library_in_workspace(&temp_pkg_id,
508 &repo).expect("test_install_git: built lib should exist");
509 let lib = target_library_in_workspace(&temp_pkg_id, &repo);
510 debug!("lib = %s", lib.to_str());
511 assert!(os::path_exists(&lib));
512 assert!(is_rwx(&lib));
513 let built_test = built_test_in_workspace(&temp_pkg_id,
514 &repo).expect("test_install_git: built test should exist");
515 assert!(os::path_exists(&built_test));
516 let built_bench = built_bench_in_workspace(&temp_pkg_id,
517 &repo).expect("test_install_git: built bench should exist");
518 assert!(os::path_exists(&built_bench));
519 // And that the test and bench executables aren't installed
520 let test = target_test_in_workspace(&temp_pkg_id, &repo);
521 assert!(!os::path_exists(&test));
522 debug!("test = %s", test.to_str());
523 let bench = target_bench_in_workspace(&temp_pkg_id, &repo);
524 debug!("bench = %s", bench.to_str());
525 assert!(!os::path_exists(&bench));
528 #[test] #[ignore(cfg(target_arch = "x86"))]
529 fn test_package_ids_must_be_relative_path_like() {
530 use conditions::bad_pkg_id::cond;
534 - One identifier, with no slashes
535 - Several slash-delimited things, with no / at the root
539 - Absolute path (as per os::is_absolute)
543 let whatever = PkgId::new("foo", &os::getcwd());
545 assert_eq!(~"foo-0.1", whatever.to_str());
546 assert!("github.com/catamorphism/test_pkg-0.1" ==
547 PkgId::new("github.com/catamorphism/test-pkg", &os::getcwd()).to_str());
549 do cond.trap(|(p, e)| {
550 assert!("" == p.to_str());
551 assert!("0-length pkgid" == e);
554 let x = PkgId::new("", &os::getcwd());
555 assert_eq!(~"foo-0.1", x.to_str());
558 do cond.trap(|(p, e)| {
559 assert_eq!(p.to_str(), os::make_absolute(&Path("foo/bar/quux")).to_str());
560 assert!("absolute pkgid" == e);
563 let z = PkgId::new(os::make_absolute(&Path("foo/bar/quux")).to_str(),
565 assert_eq!(~"foo-0.1", z.to_str());
570 // FIXME: #7956: temporarily disabled
571 #[ignore(cfg(target_arch = "x86"))]
572 fn test_package_version() {
573 let local_path = "mockgithub.com/catamorphism/test_pkg_version";
574 let repo = init_git_repo(&Path(local_path));
575 let repo_subdir = repo.push("mockgithub.com").push("catamorphism").push("test_pkg_version");
576 debug!("Writing files in: %s", repo_subdir.to_str());
577 writeFile(&repo_subdir.push("main.rs"),
578 "fn main() { let _x = (); }");
579 writeFile(&repo_subdir.push("lib.rs"),
580 "pub fn f() { let _x = (); }");
581 writeFile(&repo_subdir.push("test.rs"),
582 "#[test] pub fn f() { (); }");
583 writeFile(&repo_subdir.push("bench.rs"),
584 "#[bench] pub fn f() { (); }");
585 add_git_tag(&repo_subdir, ~"0.4");
587 let temp_pkg_id = PkgId::new("mockgithub.com/catamorphism/test_pkg_version", &repo);
588 match temp_pkg_id.version {
589 ExactRevision(~"0.4") => (),
590 _ => fail!(fmt!("test_package_version: package version was %?, expected Some(0.4)",
591 temp_pkg_id.version))
593 // This should look at the prefix, clone into a workspace, then build.
594 command_line_test([~"install", ~"mockgithub.com/catamorphism/test_pkg_version"],
596 assert!(match built_library_in_workspace(&temp_pkg_id,
598 Some(p) => p.to_str().ends_with(fmt!("0.4%s", os::consts::DLL_SUFFIX)),
601 assert!(built_executable_in_workspace(&temp_pkg_id, &repo)
602 == Some(repo.push("build").
603 push("mockgithub.com").
604 push("catamorphism").
605 push("test_pkg_version").
606 push("test_pkg_version")));
609 fn test_package_request_version() {
610 let local_path = "mockgithub.com/catamorphism/test_pkg_version";
611 let repo = init_git_repo(&Path(local_path));
612 let repo_subdir = repo.push("mockgithub.com").push("catamorphism").push("test_pkg_version");
613 debug!("Writing files in: %s", repo_subdir.to_str());
614 writeFile(&repo_subdir.push("main.rs"),
615 "fn main() { let _x = (); }");
616 writeFile(&repo_subdir.push("lib.rs"),
617 "pub fn f() { let _x = (); }");
618 writeFile(&repo_subdir.push("test.rs"),
619 "#[test] pub fn f() { (); }");
620 writeFile(&repo_subdir.push("bench.rs"),
621 "#[bench] pub fn f() { (); }");
622 writeFile(&repo_subdir.push("version-0.3-file.txt"), "hi");
623 add_git_tag(&repo_subdir, ~"0.3");
624 writeFile(&repo_subdir.push("version-0.4-file.txt"), "hello");
625 add_git_tag(&repo_subdir, ~"0.4");
629 let pkg_src = PkgSrc::new(&repo, &repo, &temp_pkg_id);
630 match temp_pkg_id.version {
631 ExactRevision(~"0.3") => {
632 debug!("Version matches, calling fetch_git");
633 match pkg_src.fetch_git() {
635 debug!("does version-0.3-file exist?");
636 assert!(os::path_exists(&p.push("version-0.3-file.txt")));
637 debug!("does version-0.4-file exist?");
638 assert!(!os::path_exists(&p.push("version-0.4-file.txt")));
641 None => fail!("test_package_request_version: fetch_git failed")
644 ExactRevision(n) => {
645 fail!("n is %? and %? %s %?", n, n, if n == ~"0.3" { "==" } else { "!=" }, "0.3");
647 _ => fail!(fmt!("test_package_version: package version was %?, expected ExactRevision(0.3)",
648 temp_pkg_id.version))
652 command_line_test([~"install", fmt!("%s#0.3", local_path)], &repo);
654 assert!(match installed_library_in_workspace("test_pkg_version", &repo.push(".rust")) {
656 debug!("installed: %s", p.to_str());
657 p.to_str().ends_with(fmt!("0.3%s", os::consts::DLL_SUFFIX))
661 let temp_pkg_id = PkgId::new("mockgithub.com/catamorphism/test_pkg_version#0.3", &repo);
662 assert!(target_executable_in_workspace(&temp_pkg_id, &repo.push(".rust"))
663 == repo.push(".rust").push("bin").push("test_pkg_version"));
665 assert!(os::path_exists(&repo.push(".rust").push("src")
666 .push("mockgithub.com").push("catamorphism")
667 .push("test_pkg_version-0.3")
668 .push("version-0.3-file.txt")));
669 assert!(!os::path_exists(&repo.push(".rust").push("src")
670 .push("mockgithub.com").push("catamorphism")
671 .push("test_pkg_version-0.3")
672 .push("version-0.4-file.txt")));
676 #[ignore (reason = "http-client not ported to rustpkg yet")]
677 fn rustpkg_install_url_2() {
678 let temp_dir = mkdtemp(&os::tmpdir(), "rustpkg_install_url_2").expect("rustpkg_install_url_2");
679 command_line_test([~"install", ~"github.com/mozilla-servo/rust-http-client"],
683 // FIXME: #7956: temporarily disabled
684 fn rustpkg_library_target() {
685 let foo_repo = init_git_repo(&Path("foo"));
686 let package_dir = foo_repo.push("foo");
688 debug!("Writing files in: %s", package_dir.to_str());
689 writeFile(&package_dir.push("main.rs"),
690 "fn main() { let _x = (); }");
691 writeFile(&package_dir.push("lib.rs"),
692 "pub fn f() { let _x = (); }");
693 writeFile(&package_dir.push("test.rs"),
694 "#[test] pub fn f() { (); }");
695 writeFile(&package_dir.push("bench.rs"),
696 "#[bench] pub fn f() { (); }");
698 add_git_tag(&package_dir, ~"1.0");
699 command_line_test([~"install", ~"foo"], &foo_repo);
700 assert_lib_exists(&foo_repo, "foo", ExactRevision(~"1.0"));
704 fn rustpkg_local_pkg() {
705 let dir = create_local_package(&PkgId::new("foo", &os::getcwd()));
706 command_line_test([~"install", ~"foo"], &dir);
707 assert_executable_exists(&dir, "foo");
711 #[ignore] // XXX Failing on dist-linux bot
712 fn package_script_with_default_build() {
713 let dir = create_local_package(&PkgId::new("fancy-lib", &os::getcwd()));
714 debug!("dir = %s", dir.to_str());
715 let source = test_sysroot().pop().pop().pop().push("src").push("librustpkg").
716 push("testsuite").push("pass").push("src").push("fancy-lib").push("pkg.rs");
717 debug!("package_script_with_default_build: %s", source.to_str());
718 if !os::copy_file(&source,
719 & dir.push("src").push("fancy_lib-0.1").push("pkg.rs")) {
720 fail!("Couldn't copy file");
722 command_line_test([~"install", ~"fancy-lib"], &dir);
723 assert_lib_exists(&dir, "fancy-lib", NoVersion);
724 assert!(os::path_exists(&dir.push("build").push("fancy_lib").push("generated.rs")));
728 fn rustpkg_build_no_arg() {
729 let tmp = mkdtemp(&os::tmpdir(), "rustpkg_build_no_arg").expect("rustpkg_build_no_arg failed");
730 let package_dir = tmp.push("src").push("foo");
731 assert!(os::mkdir_recursive(&package_dir, U_RWX));
733 writeFile(&package_dir.push("main.rs"),
734 "fn main() { let _x = (); }");
735 debug!("build_no_arg: dir = %s", package_dir.to_str());
736 command_line_test([~"build"], &package_dir);
737 assert_built_executable_exists(&tmp, "foo");
741 fn rustpkg_install_no_arg() {
742 let tmp = mkdtemp(&os::tmpdir(),
743 "rustpkg_install_no_arg").expect("rustpkg_build_no_arg failed");
744 let package_dir = tmp.push("src").push("foo");
745 assert!(os::mkdir_recursive(&package_dir, U_RWX));
746 writeFile(&package_dir.push("lib.rs"),
747 "fn main() { let _x = (); }");
748 debug!("install_no_arg: dir = %s", package_dir.to_str());
749 command_line_test([~"install"], &package_dir);
750 assert_lib_exists(&tmp, "foo", NoVersion);
754 fn rustpkg_clean_no_arg() {
755 let tmp = mkdtemp(&os::tmpdir(), "rustpkg_clean_no_arg").expect("rustpkg_clean_no_arg failed");
756 let package_dir = tmp.push("src").push("foo");
757 assert!(os::mkdir_recursive(&package_dir, U_RWX));
759 writeFile(&package_dir.push("main.rs"),
760 "fn main() { let _x = (); }");
761 debug!("clean_no_arg: dir = %s", package_dir.to_str());
762 command_line_test([~"build"], &package_dir);
763 assert_built_executable_exists(&tmp, "foo");
764 command_line_test([~"clean"], &package_dir);
765 assert!(!built_executable_in_workspace(&PkgId::new("foo", &package_dir),
766 &tmp).map_default(false, |m| { os::path_exists(m) }));
770 #[ignore (reason = "Un-ignore when #7071 is fixed")]
771 fn rust_path_test() {
772 let dir_for_path = mkdtemp(&os::tmpdir(), "more_rust").expect("rust_path_test failed");
773 let dir = mk_workspace(&dir_for_path, &normalize(RemotePath(Path("foo"))), &NoVersion);
774 debug!("dir = %s", dir.to_str());
775 writeFile(&dir.push("main.rs"), "fn main() { let _x = (); }");
777 let cwd = os::getcwd();
778 debug!("cwd = %s", cwd.to_str());
779 let mut prog = run::Process::new("rustpkg",
780 [~"install", ~"foo"],
781 run::ProcessOptions { env: Some(&[(~"RUST_PATH",
782 dir_for_path.to_str())]),
788 prog.finish_with_output();
789 assert_executable_exists(&dir_for_path, "foo");
793 fn rust_path_contents() {
794 let dir = mkdtemp(&os::tmpdir(), "rust_path").expect("rust_path_contents failed");
795 let abc = &dir.push("A").push("B").push("C");
796 assert!(os::mkdir_recursive(&abc.push(".rust"), U_RWX));
797 assert!(os::mkdir_recursive(&abc.pop().push(".rust"), U_RWX));
798 assert!(os::mkdir_recursive(&abc.pop().pop().push(".rust"), U_RWX));
799 assert!(do os::change_dir_locked(&dir.push("A").push("B").push("C")) {
801 let cwd = os::getcwd().push(".rust");
802 let parent = cwd.pop().pop().push(".rust");
803 let grandparent = cwd.pop().pop().pop().push(".rust");
804 assert!(p.contains(&cwd));
805 assert!(p.contains(&parent));
806 assert!(p.contains(&grandparent));
807 for p.iter().advance() |a_path| {
808 assert!(!a_path.components.is_empty());
814 fn rust_path_parse() {
815 os::setenv("RUST_PATH", "/a/b/c:/d/e/f:/g/h/i");
816 let paths = rust_path();
817 assert!(paths.contains(&Path("/g/h/i")));
818 assert!(paths.contains(&Path("/d/e/f")));
819 assert!(paths.contains(&Path("/a/b/c")));
820 os::unsetenv("RUST_PATH");
825 let dir = mkdtemp(&os::tmpdir(), "test_list").expect("test_list failed");
826 let foo = PkgId::new("foo", &dir);
827 create_local_package_in(&foo, &dir);
828 let bar = PkgId::new("bar", &dir);
829 create_local_package_in(&bar, &dir);
830 let quux = PkgId::new("quux", &dir);
831 create_local_package_in(&quux, &dir);
833 // NOTE Not really great output, though...
834 // NOTE do any tests need to be unignored?
835 command_line_test([~"install", ~"foo"], &dir);
836 let env_arg = ~[(~"RUST_PATH", dir.to_str())];
837 debug!("RUST_PATH = %s", dir.to_str());
838 let list_output = command_line_test_output_with_env([~"list"], env_arg.clone());
839 assert!(list_output.iter().any(|x| x.starts_with("libfoo_")));
841 command_line_test([~"install", ~"bar"], &dir);
842 let list_output = command_line_test_output_with_env([~"list"], env_arg.clone());
843 assert!(list_output.iter().any(|x| x.starts_with("libfoo_")));
844 assert!(list_output.iter().any(|x| x.starts_with("libbar_")));
846 command_line_test([~"install", ~"quux"], &dir);
847 let list_output = command_line_test_output_with_env([~"list"], env_arg);
848 assert!(list_output.iter().any(|x| x.starts_with("libfoo_")));
849 assert!(list_output.iter().any(|x| x.starts_with("libbar_")));
850 assert!(list_output.iter().any(|x| x.starts_with("libquux_")));
854 fn install_remove() {
855 let dir = mkdtemp(&os::tmpdir(), "install_remove").expect("install_remove");
856 let foo = PkgId::new("foo", &dir);
857 let bar = PkgId::new("bar", &dir);
858 let quux = PkgId::new("quux", &dir);
859 create_local_package_in(&foo, &dir);
860 create_local_package_in(&bar, &dir);
861 create_local_package_in(&quux, &dir);
862 let rust_path_to_use = ~[(~"RUST_PATH", dir.to_str())];
863 command_line_test([~"install", ~"foo"], &dir);
864 command_line_test([~"install", ~"bar"], &dir);
865 command_line_test([~"install", ~"quux"], &dir);
866 let list_output = command_line_test_output_with_env([~"list"], rust_path_to_use.clone());
867 assert!(list_output.iter().any(|x| x.starts_with("foo")));
868 assert!(list_output.iter().any(|x| x.starts_with("bar")));
869 assert!(list_output.iter().any(|x| x.starts_with("quux")));
870 command_line_test([~"uninstall", ~"foo"], &dir);
871 let list_output = command_line_test_output_with_env([~"list"], rust_path_to_use.clone());
872 assert!(!list_output.iter().any(|x| x.starts_with("foo")));
873 assert!(list_output.iter().any(|x| x.starts_with("bar")));
874 assert!(list_output.iter().any(|x| x.starts_with("quux")));
878 fn install_check_duplicates() {
879 // should check that we don't install two packages with the same full name *and* version
880 // ("Is already installed -- doing nothing")
881 // check invariant that there are no dups in the pkg database
882 let dir = mkdtemp(&os::tmpdir(), "install_remove").expect("install_remove");
883 let foo = PkgId::new("foo", &dir);
884 create_local_package_in(&foo, &dir);
886 command_line_test([~"install", ~"foo"], &dir);
887 command_line_test([~"install", ~"foo"], &dir);
888 let mut contents = ~[];
889 let check_dups = |p: &PkgId| {
890 if contents.contains(p) {
891 fail!("package %s appears in `list` output more than once", p.local_path.to_str());
894 contents.push((*p).clone());
898 list_installed_packages(check_dups);
902 #[ignore(reason = "Workcache not yet implemented -- see #7075")]
904 let p_id = PkgId::new("foo", &os::getcwd());
905 let workspace = create_local_package(&p_id);
906 command_line_test([~"build", ~"foo"], &workspace);
907 let date = datestamp(&built_library_in_workspace(&p_id,
908 &workspace).expect("no_rebuilding"));
909 command_line_test([~"build", ~"foo"], &workspace);
910 let newdate = datestamp(&built_library_in_workspace(&p_id,
911 &workspace).expect("no_rebuilding (2)"));
912 assert_eq!(date, newdate);
916 #[ignore(reason = "Workcache not yet implemented -- see #7075")]
917 fn no_rebuilding_dep() {
918 let p_id = PkgId::new("foo", &os::getcwd());
919 let dep_id = PkgId::new("bar", &os::getcwd());
920 let workspace = create_local_package_with_dep(&p_id, &dep_id);
921 command_line_test([~"build", ~"foo"], &workspace);
922 let bar_date = datestamp(&lib_output_file_name(&workspace,
925 let foo_date = datestamp(&output_file_name(&workspace, "foo"));
926 assert!(bar_date < foo_date);
930 fn do_rebuild_dep_dates_change() {
931 let p_id = PkgId::new("foo", &os::getcwd());
932 let dep_id = PkgId::new("bar", &os::getcwd());
933 let workspace = create_local_package_with_dep(&p_id, &dep_id);
934 command_line_test([~"build", ~"foo"], &workspace);
935 let bar_date = datestamp(&lib_output_file_name(&workspace, "build", "bar"));
936 touch_source_file(&workspace, &dep_id);
937 command_line_test([~"build", ~"foo"], &workspace);
938 let new_bar_date = datestamp(&lib_output_file_name(&workspace, "build", "bar"));
939 assert!(new_bar_date > bar_date);
943 fn do_rebuild_dep_only_contents_change() {
944 let p_id = PkgId::new("foo", &os::getcwd());
945 let dep_id = PkgId::new("bar", &os::getcwd());
946 let workspace = create_local_package_with_dep(&p_id, &dep_id);
947 command_line_test([~"build", ~"foo"], &workspace);
948 let bar_date = datestamp(&lib_output_file_name(&workspace, "build", "bar"));
949 frob_source_file(&workspace, &dep_id);
950 // should adjust the datestamp
951 command_line_test([~"build", ~"foo"], &workspace);
952 let new_bar_date = datestamp(&lib_output_file_name(&workspace, "build", "bar"));
953 assert!(new_bar_date > bar_date);
957 #[ignore(reason = "list not yet implemented")]
959 let workspace = create_local_package(&PkgId::new("foo#0.1", &os::getcwd()));
960 create_local_package(&PkgId::new("foo#0.2", &os::getcwd()));
961 command_line_test([~"install", ~"foo#0.1"], &workspace);
962 let output = command_line_test_output([~"list"]);
963 // make sure output includes versions
964 assert!(!output.iter().any(|x| x == &~"foo#0.2"));
968 #[ignore(reason = "do not yet implemented")]
969 fn test_build_hooks() {
970 let workspace = create_local_package_with_custom_build_hook(&PkgId::new("foo", &os::getcwd()),
972 command_line_test([~"do", ~"foo", ~"frob"], &workspace);
977 #[ignore(reason = "info not yet implemented")]
979 let expected_info = ~"package foo"; // fill in
980 let workspace = create_local_package(&PkgId::new("foo", &os::getcwd()));
981 let output = command_line_test([~"info", ~"foo"], &workspace);
982 assert_eq!(str::from_bytes(output.output), expected_info);
986 #[ignore(reason = "test not yet implemented")]
987 fn test_rustpkg_test() {
988 let expected_results = ~"1 out of 1 tests passed"; // fill in
989 let workspace = create_local_package_with_test(&PkgId::new("foo", &os::getcwd()));
990 let output = command_line_test([~"test", ~"foo"], &workspace);
991 assert_eq!(str::from_bytes(output.output), expected_results);
995 #[ignore(reason = "uninstall not yet implemented")]
996 fn test_uninstall() {
997 let workspace = create_local_package(&PkgId::new("foo", &os::getcwd()));
998 let _output = command_line_test([~"info", ~"foo"], &workspace);
999 command_line_test([~"uninstall", ~"foo"], &workspace);
1000 let output = command_line_test([~"list"], &workspace);
1001 assert!(!str::from_bytes(output.output).contains("foo"));