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, Tagged};
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 git_repo_pkg_with_tag(a_tag: ~str) -> PkgId {
65 let remote = RemotePath(Path("mockgithub.com/catamorphism/test-pkg"));
67 local_path: normalize(remote.clone()),
69 short_name: ~"test_pkg",
70 version: Tagged(a_tag)
74 fn writeFile(file_path: &Path, contents: &str) {
75 let out = io::file_writer(file_path, [io::Create, io::Truncate]).unwrap();
76 out.write_line(contents);
79 fn mk_empty_workspace(short_name: &LocalPath, version: &Version) -> Path {
80 let workspace_dir = mkdtemp(&os::tmpdir(), "test").expect("couldn't create temp dir");
81 mk_workspace(&workspace_dir, short_name, version);
85 fn mk_workspace(workspace: &Path, short_name: &LocalPath, version: &Version) -> Path {
86 // include version number in directory name
87 let package_dir = workspace.push("src").push(fmt!("%s-%s",
88 short_name.to_str(), version.to_str()));
89 assert!(os::mkdir_recursive(&package_dir, U_RWX));
93 fn mk_temp_workspace(short_name: &LocalPath, version: &Version) -> Path {
94 let package_dir = mk_empty_workspace(short_name,
95 version).push("src").push(fmt!("%s-%s",
99 debug!("Created %s and does it exist? %?", package_dir.to_str(),
100 os::path_is_dir(&package_dir));
101 // Create main, lib, test, and bench files
102 debug!("mk_workspace: creating %s", package_dir.to_str());
103 assert!(os::mkdir_recursive(&package_dir, U_RWX));
104 debug!("Created %s and does it exist? %?", package_dir.to_str(),
105 os::path_is_dir(&package_dir));
106 // Create main, lib, test, and bench files
108 writeFile(&package_dir.push("main.rs"),
109 "fn main() { let _x = (); }");
110 writeFile(&package_dir.push("lib.rs"),
111 "pub fn f() { let _x = (); }");
112 writeFile(&package_dir.push("test.rs"),
113 "#[test] pub fn f() { (); }");
114 writeFile(&package_dir.push("bench.rs"),
115 "#[bench] pub fn f() { (); }");
119 /// Should create an empty git repo in p, relative to the tmp dir, and return the new
121 fn init_git_repo(p: &Path) -> Path {
122 assert!(!p.is_absolute());
123 let tmp = mkdtemp(&os::tmpdir(), "git_local").expect("couldn't create temp dir");
124 let work_dir = tmp.push_rel(p);
125 let work_dir_for_opts = work_dir.clone();
126 assert!(os::mkdir_recursive(&work_dir, U_RWX));
127 debug!("Running: git init in %s", work_dir.to_str());
128 let opts = run::ProcessOptions {
130 dir: Some(&work_dir_for_opts),
135 let mut prog = run::Process::new("git", [~"init"], opts);
136 let mut output = prog.finish_with_output();
137 if output.status == 0 {
138 // Add stuff to the dir so that git tag succeeds
139 writeFile(&work_dir.push("README"), "");
140 prog = run::Process::new("git", [~"add", ~"README"], opts);
141 output = prog.finish_with_output();
142 if output.status == 0 {
143 prog = run::Process::new("git", [~"commit", ~"-m", ~"whatever"], opts);
144 output = prog.finish_with_output();
145 if output.status == 0 {
149 fail!("Couldn't commit in %s", work_dir.to_str());
153 fail!("Couldn't add in %s", work_dir.to_str());
157 fail!("Couldn't initialize git repository in %s", work_dir.to_str())
161 fn add_all_and_commit(repo: &Path) {
163 git_commit(repo, ~"floop");
166 fn git_commit(repo: &Path, msg: ~str) {
167 let mut prog = run::Process::new("git", [~"commit", ~"-m", msg],
168 run::ProcessOptions { env: None,
174 let output = prog.finish_with_output();
175 if output.status != 0 {
176 fail!("Couldn't commit in %s: output was %s", repo.to_str(),
177 str::from_bytes(output.output + output.error))
182 fn git_add_all(repo: &Path) {
183 let mut prog = run::Process::new("git", [~"add", ~"-A"],
184 run::ProcessOptions { env: None,
190 let output = prog.finish_with_output();
191 if output.status != 0 {
192 fail!("Couldn't add all files in %s: output was %s",
193 repo.to_str(), str::from_bytes(output.output + output.error))
197 fn add_git_tag(repo: &Path, tag: ~str) {
198 assert!(repo.is_absolute());
200 git_commit(repo, ~"whatever");
201 let mut prog = run::Process::new("git", [~"tag", tag.clone()],
202 run::ProcessOptions { env: None,
208 let output = prog.finish_with_output();
209 if output.status != 0 {
210 fail!("Couldn't add git tag %s in %s", tag, repo.to_str())
214 fn is_rwx(p: &Path) -> bool {
215 use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
218 None => return false,
220 ((m & S_IRUSR as uint) == S_IRUSR as uint
221 && (m & S_IWUSR as uint) == S_IWUSR as uint
222 && (m & S_IXUSR as uint) == S_IXUSR as uint)
226 fn test_sysroot() -> Path {
227 // Totally gross hack but it's just for test cases.
228 // Infer the sysroot from the exe name and pray that it's right.
229 // (Did I mention it was a gross hack?)
230 let self_path = os::self_exe_path().expect("Couldn't get self_exe path");
234 fn command_line_test(args: &[~str], cwd: &Path) -> ProcessOutput {
235 command_line_test_with_env(args, cwd, None)
238 /// Runs `rustpkg` (based on the directory that this executable was
239 /// invoked from) with the given arguments, in the given working directory.
240 /// Returns the process's output.
241 fn command_line_test_with_env(args: &[~str], cwd: &Path, env: Option<~[(~str, ~str)]>)
243 let cmd = test_sysroot().push("bin").push("rustpkg").to_str();
244 debug!("About to run command: %? %? in %s", cmd, args, cwd.to_str());
245 assert!(os::path_is_dir(&*cwd));
246 let cwd = (*cwd).clone();
247 let mut prog = run::Process::new(cmd, args, run::ProcessOptions {
248 env: env.map(|v| v.slice(0, v.len())),
254 let output = prog.finish_with_output();
255 debug!("Output from command %s with args %? was %s {%s}[%?]",
256 cmd, args, str::from_bytes(output.output),
257 str::from_bytes(output.error),
260 By the way, rustpkg *won't* return a nonzero exit code if it fails --
262 So tests that use this need to check the existence of a file
263 to make sure the command succeeded
265 if output.status != 0 {
266 fail!("Command %s %? failed with exit code %?",
267 cmd, args, output.status);
272 fn create_local_package(pkgid: &PkgId) -> Path {
273 let parent_dir = mk_temp_workspace(&pkgid.local_path, &pkgid.version);
274 debug!("Created empty package dir for %s, returning %s", pkgid.to_str(), parent_dir.to_str());
275 parent_dir.pop().pop()
278 fn create_local_package_in(pkgid: &PkgId, pkgdir: &Path) -> Path {
280 let package_dir = pkgdir.push("src").push(pkgid.to_str());
282 // Create main, lib, test, and bench files
283 assert!(os::mkdir_recursive(&package_dir, U_RWX));
284 debug!("Created %s and does it exist? %?", package_dir.to_str(),
285 os::path_is_dir(&package_dir));
286 // Create main, lib, test, and bench files
288 writeFile(&package_dir.push("main.rs"),
289 "fn main() { let _x = (); }");
290 writeFile(&package_dir.push("lib.rs"),
291 "pub fn f() { let _x = (); }");
292 writeFile(&package_dir.push("test.rs"),
293 "#[test] pub fn f() { (); }");
294 writeFile(&package_dir.push("bench.rs"),
295 "#[bench] pub fn f() { (); }");
299 fn create_local_package_with_test(pkgid: &PkgId) -> Path {
300 debug!("Dry run -- would create package %s with test");
301 create_local_package(pkgid) // Already has tests???
304 fn create_local_package_with_dep(pkgid: &PkgId, subord_pkgid: &PkgId) -> Path {
305 let package_dir = create_local_package(pkgid);
306 create_local_package_in(subord_pkgid, &package_dir);
307 // Write a main.rs file into pkgid that references subord_pkgid
308 writeFile(&package_dir.push("src").push(pkgid.to_str()).push("main.rs"),
309 fmt!("extern mod %s;\nfn main() {}",
310 subord_pkgid.short_name));
311 // Write a lib.rs file into subord_pkgid that has something in it
312 writeFile(&package_dir.push("src").push(subord_pkgid.to_str()).push("lib.rs"),
314 debug!("Dry run -- would create packages %s and %s in %s",
316 subord_pkgid.to_str(),
317 package_dir.to_str());
321 fn create_local_package_with_custom_build_hook(pkgid: &PkgId,
322 custom_build_hook: &str) -> Path {
323 debug!("Dry run -- would create package %s with custom build hook %s",
324 pkgid.to_str(), custom_build_hook);
325 create_local_package(pkgid)
326 // actually write the pkg.rs with the custom build hook
330 fn assert_lib_exists(repo: &Path, short_name: &str, v: Version) {
331 debug!("assert_lib_exists: repo = %s, short_name = %s", repo.to_str(), short_name);
332 let lib = target_library_in_workspace(&(PkgId {
333 version: v, ..PkgId::new(short_name, repo)}
335 debug!("assert_lib_exists: checking whether %s exists", lib.to_str());
336 assert!(os::path_exists(&lib));
337 assert!(is_rwx(&lib));
340 fn assert_executable_exists(repo: &Path, short_name: &str) {
341 debug!("assert_executable_exists: repo = %s, short_name = %s", repo.to_str(), short_name);
342 let exec = target_executable_in_workspace(&PkgId::new(short_name, repo), repo);
343 assert!(os::path_exists(&exec));
344 assert!(is_rwx(&exec));
347 fn assert_built_executable_exists(repo: &Path, short_name: &str) {
348 debug!("assert_built_executable_exists: repo = %s, short_name = %s", repo.to_str(), short_name);
349 let exec = built_executable_in_workspace(&PkgId::new(short_name, repo),
350 repo).expect("assert_built_executable_exists failed");
351 assert!(os::path_exists(&exec));
352 assert!(is_rwx(&exec));
355 fn command_line_test_output(args: &[~str]) -> ~[~str] {
356 let mut result = ~[];
357 let p_output = command_line_test(args, &os::getcwd());
358 let test_output = str::from_bytes(p_output.output);
359 for s in test_output.split_iter('\n') {
360 result.push(s.to_owned());
365 fn command_line_test_output_with_env(args: &[~str], env: ~[(~str, ~str)]) -> ~[~str] {
366 let mut result = ~[];
367 let p_output = command_line_test_with_env(args, &os::getcwd(), Some(env));
368 let test_output = str::from_bytes(p_output.output);
369 for s in test_output.split_iter('\n') {
370 result.push(s.to_owned());
375 // assumes short_name and local_path are one and the same -- I should fix
376 fn lib_output_file_name(workspace: &Path, parent: &str, short_name: &str) -> Path {
377 debug!("lib_output_file_name: given %s and parent %s and short name %s",
378 workspace.to_str(), parent, short_name);
379 library_in_workspace(&normalize(RemotePath(Path(short_name))),
383 "build").expect("lib_output_file_name")
386 fn output_file_name(workspace: &Path, short_name: &str) -> Path {
387 workspace.push(fmt!("%s%s", short_name, os::EXE_SUFFIX))
390 fn touch_source_file(workspace: &Path, pkgid: &PkgId) {
391 use conditions::bad_path::cond;
392 let pkg_src_dir = workspace.push("src").push(pkgid.to_str());
393 let contents = os::list_dir_path(&pkg_src_dir);
394 for p in contents.iter() {
395 if p.filetype() == Some(~".rs") {
396 // should be able to do this w/o a process
397 if run::process_output("touch", [p.to_str()]).status != 0 {
398 let _ = cond.raise((pkg_src_dir.clone(), ~"Bad path"));
405 /// Add a blank line at the end
406 fn frob_source_file(workspace: &Path, pkgid: &PkgId) {
407 use conditions::bad_path::cond;
408 let pkg_src_dir = workspace.push("src").push(pkgid.to_str());
409 let contents = os::list_dir_path(&pkg_src_dir);
410 let mut maybe_p = None;
411 for p in contents.iter() {
412 if p.filetype() == Some(~".rs") {
419 let w = io::file_writer(p, &[io::Append]);
421 Err(s) => { let _ = cond.raise((p.clone(), fmt!("Bad path: %s", s))); }
422 Ok(w) => w.write_line("")
425 None => fail!(fmt!("frob_source_file failed to find a source file in %s",
426 pkg_src_dir.to_str()))
430 // FIXME(#7249): these tests fail on multi-platform builds, so for now they're
433 #[test] #[ignore(cfg(target_arch = "x86"))]
434 fn test_make_dir_rwx() {
435 let temp = &os::tmpdir();
436 let dir = temp.push("quux");
437 assert!(!os::path_exists(&dir) ||
438 os::remove_dir_recursive(&dir));
439 debug!("Trying to make %s", dir.to_str());
440 assert!(make_dir_rwx(&dir));
441 assert!(os::path_is_dir(&dir));
442 assert!(is_rwx(&dir));
443 assert!(os::remove_dir_recursive(&dir));
446 #[test] #[ignore(cfg(target_arch = "x86"))]
447 fn test_install_valid() {
448 use path_util::installed_library_in_workspace;
450 let sysroot = test_sysroot();
451 debug!("sysroot = %s", sysroot.to_str());
452 let ctxt = fake_ctxt(Some(@sysroot));
453 let temp_pkg_id = fake_pkg();
454 let temp_workspace = mk_temp_workspace(&temp_pkg_id.local_path, &NoVersion).pop().pop();
455 debug!("temp_workspace = %s", temp_workspace.to_str());
456 // should have test, bench, lib, and main
457 ctxt.install(&temp_workspace, &temp_pkg_id);
458 // Check that all files exist
459 let exec = target_executable_in_workspace(&temp_pkg_id, &temp_workspace);
460 debug!("exec = %s", exec.to_str());
461 assert!(os::path_exists(&exec));
462 assert!(is_rwx(&exec));
464 let lib = installed_library_in_workspace(temp_pkg_id.short_name, &temp_workspace);
465 debug!("lib = %?", lib);
466 assert!(lib.map_default(false, |l| os::path_exists(l)));
467 assert!(lib.map_default(false, |l| is_rwx(l)));
469 // And that the test and bench executables aren't installed
470 assert!(!os::path_exists(&target_test_in_workspace(&temp_pkg_id, &temp_workspace)));
471 let bench = target_bench_in_workspace(&temp_pkg_id, &temp_workspace);
472 debug!("bench = %s", bench.to_str());
473 assert!(!os::path_exists(&bench));
476 #[test] #[ignore(cfg(target_arch = "x86"))]
477 fn test_install_invalid() {
478 use conditions::nonexistent_package::cond;
479 use cond1 = conditions::missing_pkg_files::cond;
481 let ctxt = fake_ctxt(None);
482 let pkgid = fake_pkg();
483 let temp_workspace = mkdtemp(&os::tmpdir(), "test").expect("couldn't create temp dir");
484 let mut error_occurred = false;
485 let mut error1_occurred = false;
487 error1_occurred = true;
490 error_occurred = true;
491 temp_workspace.clone()
493 ctxt.install(&temp_workspace, &pkgid);
496 assert!(error_occurred && error1_occurred);
499 // Tests above should (maybe) be converted to shell out to rustpkg, too
501 // FIXME: #7956: temporarily disabled
502 #[ignore(cfg(target_arch = "x86"))]
503 fn test_install_git() {
504 let sysroot = test_sysroot();
505 debug!("sysroot = %s", sysroot.to_str());
506 let temp_pkg_id = git_repo_pkg();
507 let repo = init_git_repo(&Path(temp_pkg_id.local_path.to_str()));
508 let repo_subdir = repo.push("mockgithub.com").push("catamorphism").push("test_pkg");
509 writeFile(&repo_subdir.push("main.rs"),
510 "fn main() { let _x = (); }");
511 writeFile(&repo_subdir.push("lib.rs"),
512 "pub fn f() { let _x = (); }");
513 writeFile(&repo_subdir.push("test.rs"),
514 "#[test] pub fn f() { (); }");
515 writeFile(&repo_subdir.push("bench.rs"),
516 "#[bench] pub fn f() { (); }");
517 add_git_tag(&repo_subdir, ~"0.1"); // this has the effect of committing the files
519 debug!("test_install_git: calling rustpkg install %s in %s",
520 temp_pkg_id.local_path.to_str(), repo.to_str());
521 // should have test, bench, lib, and main
522 command_line_test([~"install", temp_pkg_id.local_path.to_str()], &repo);
523 // Check that all files exist
524 debug!("Checking for files in %s", repo.to_str());
525 let exec = target_executable_in_workspace(&temp_pkg_id, &repo);
526 debug!("exec = %s", exec.to_str());
527 assert!(os::path_exists(&exec));
528 assert!(is_rwx(&exec));
530 built_library_in_workspace(&temp_pkg_id,
531 &repo).expect("test_install_git: built lib should exist");
532 let lib = target_library_in_workspace(&temp_pkg_id, &repo);
533 debug!("lib = %s", lib.to_str());
534 assert!(os::path_exists(&lib));
535 assert!(is_rwx(&lib));
536 let built_test = built_test_in_workspace(&temp_pkg_id,
537 &repo).expect("test_install_git: built test should exist");
538 assert!(os::path_exists(&built_test));
539 let built_bench = built_bench_in_workspace(&temp_pkg_id,
540 &repo).expect("test_install_git: built bench should exist");
541 assert!(os::path_exists(&built_bench));
542 // And that the test and bench executables aren't installed
543 let test = target_test_in_workspace(&temp_pkg_id, &repo);
544 assert!(!os::path_exists(&test));
545 debug!("test = %s", test.to_str());
546 let bench = target_bench_in_workspace(&temp_pkg_id, &repo);
547 debug!("bench = %s", bench.to_str());
548 assert!(!os::path_exists(&bench));
551 #[test] #[ignore(cfg(target_arch = "x86"))]
552 fn test_package_ids_must_be_relative_path_like() {
553 use conditions::bad_pkg_id::cond;
557 - One identifier, with no slashes
558 - Several slash-delimited things, with no / at the root
562 - Absolute path (as per os::is_absolute)
566 let whatever = PkgId::new("foo", &os::getcwd());
568 assert_eq!(~"foo-0.1", whatever.to_str());
569 assert!("github.com/catamorphism/test_pkg-0.1" ==
570 PkgId::new("github.com/catamorphism/test-pkg", &os::getcwd()).to_str());
572 do cond.trap(|(p, e)| {
573 assert!("" == p.to_str());
574 assert!("0-length pkgid" == e);
577 let x = PkgId::new("", &os::getcwd());
578 assert_eq!(~"foo-0.1", x.to_str());
581 do cond.trap(|(p, e)| {
582 assert_eq!(p.to_str(), os::make_absolute(&Path("foo/bar/quux")).to_str());
583 assert!("absolute pkgid" == e);
586 let z = PkgId::new(os::make_absolute(&Path("foo/bar/quux")).to_str(),
588 assert_eq!(~"foo-0.1", z.to_str());
593 // FIXME: #7956: temporarily disabled
594 #[ignore(cfg(target_arch = "x86"))]
595 fn test_package_version() {
596 let local_path = "mockgithub.com/catamorphism/test_pkg_version";
597 let repo = init_git_repo(&Path(local_path));
598 let repo_subdir = repo.push("mockgithub.com").push("catamorphism").push("test_pkg_version");
599 debug!("Writing files in: %s", repo_subdir.to_str());
600 writeFile(&repo_subdir.push("main.rs"),
601 "fn main() { let _x = (); }");
602 writeFile(&repo_subdir.push("lib.rs"),
603 "pub fn f() { let _x = (); }");
604 writeFile(&repo_subdir.push("test.rs"),
605 "#[test] pub fn f() { (); }");
606 writeFile(&repo_subdir.push("bench.rs"),
607 "#[bench] pub fn f() { (); }");
608 add_git_tag(&repo_subdir, ~"0.4");
610 let temp_pkg_id = PkgId::new("mockgithub.com/catamorphism/test_pkg_version", &repo);
611 match temp_pkg_id.version {
612 ExactRevision(~"0.4") => (),
613 _ => fail!(fmt!("test_package_version: package version was %?, expected Some(0.4)",
614 temp_pkg_id.version))
616 // This should look at the prefix, clone into a workspace, then build.
617 command_line_test([~"install", ~"mockgithub.com/catamorphism/test_pkg_version"],
619 assert!(match built_library_in_workspace(&temp_pkg_id,
621 Some(p) => p.to_str().ends_with(fmt!("0.4%s", os::consts::DLL_SUFFIX)),
624 assert!(built_executable_in_workspace(&temp_pkg_id, &repo)
625 == Some(repo.push("build").
626 push("mockgithub.com").
627 push("catamorphism").
628 push("test_pkg_version").
629 push("test_pkg_version")));
632 fn test_package_request_version() {
633 let local_path = "mockgithub.com/catamorphism/test_pkg_version";
634 let repo = init_git_repo(&Path(local_path));
635 let repo_subdir = repo.push("mockgithub.com").push("catamorphism").push("test_pkg_version");
636 debug!("Writing files in: %s", repo_subdir.to_str());
637 writeFile(&repo_subdir.push("main.rs"),
638 "fn main() { let _x = (); }");
639 writeFile(&repo_subdir.push("lib.rs"),
640 "pub fn f() { let _x = (); }");
641 writeFile(&repo_subdir.push("test.rs"),
642 "#[test] pub fn f() { (); }");
643 writeFile(&repo_subdir.push("bench.rs"),
644 "#[bench] pub fn f() { (); }");
645 writeFile(&repo_subdir.push("version-0.3-file.txt"), "hi");
646 add_git_tag(&repo_subdir, ~"0.3");
647 writeFile(&repo_subdir.push("version-0.4-file.txt"), "hello");
648 add_git_tag(&repo_subdir, ~"0.4");
650 command_line_test([~"install", fmt!("%s#0.3", local_path)], &repo);
652 assert!(match installed_library_in_workspace("test_pkg_version", &repo.push(".rust")) {
654 debug!("installed: %s", p.to_str());
655 p.to_str().ends_with(fmt!("0.3%s", os::consts::DLL_SUFFIX))
659 let temp_pkg_id = PkgId::new("mockgithub.com/catamorphism/test_pkg_version#0.3", &repo);
660 assert!(target_executable_in_workspace(&temp_pkg_id, &repo.push(".rust"))
661 == repo.push(".rust").push("bin").push("test_pkg_version"));
663 assert!(os::path_exists(&repo.push(".rust").push("src")
664 .push("mockgithub.com").push("catamorphism")
665 .push("test_pkg_version-0.3")
666 .push("version-0.3-file.txt")));
667 assert!(!os::path_exists(&repo.push(".rust").push("src")
668 .push("mockgithub.com").push("catamorphism")
669 .push("test_pkg_version-0.3")
670 .push("version-0.4-file.txt")));
674 #[ignore (reason = "http-client not ported to rustpkg yet")]
675 fn rustpkg_install_url_2() {
676 let temp_dir = mkdtemp(&os::tmpdir(), "rustpkg_install_url_2").expect("rustpkg_install_url_2");
677 command_line_test([~"install", ~"github.com/mozilla-servo/rust-http-client"],
681 // FIXME: #7956: temporarily disabled
683 fn rustpkg_library_target() {
684 let foo_repo = init_git_repo(&Path("foo"));
685 let package_dir = foo_repo.push("foo");
687 debug!("Writing files in: %s", package_dir.to_str());
688 writeFile(&package_dir.push("main.rs"),
689 "fn main() { let _x = (); }");
690 writeFile(&package_dir.push("lib.rs"),
691 "pub fn f() { let _x = (); }");
692 writeFile(&package_dir.push("test.rs"),
693 "#[test] pub fn f() { (); }");
694 writeFile(&package_dir.push("bench.rs"),
695 "#[bench] pub fn f() { (); }");
697 add_git_tag(&package_dir, ~"1.0");
698 command_line_test([~"install", ~"foo"], &foo_repo);
699 assert_lib_exists(&foo_repo, "foo", ExactRevision(~"1.0"));
703 fn rustpkg_local_pkg() {
704 let dir = create_local_package(&PkgId::new("foo", &os::getcwd()));
705 command_line_test([~"install", ~"foo"], &dir);
706 assert_executable_exists(&dir, "foo");
709 // FIXME: #7956: temporarily disabled
710 // Failing on dist-linux bot
713 fn package_script_with_default_build() {
714 let dir = create_local_package(&PkgId::new("fancy-lib", &os::getcwd()));
715 debug!("dir = %s", dir.to_str());
716 let source = test_sysroot().pop().pop().pop().push("src").push("librustpkg").
717 push("testsuite").push("pass").push("src").push("fancy-lib").push("pkg.rs");
718 debug!("package_script_with_default_build: %s", source.to_str());
719 if !os::copy_file(&source,
720 & dir.push("src").push("fancy_lib-0.1").push("pkg.rs")) {
721 fail!("Couldn't copy file");
723 command_line_test([~"install", ~"fancy-lib"], &dir);
724 assert_lib_exists(&dir, "fancy-lib", NoVersion);
725 assert!(os::path_exists(&dir.push("build").push("fancy_lib").push("generated.rs")));
729 fn rustpkg_build_no_arg() {
730 let tmp = mkdtemp(&os::tmpdir(), "rustpkg_build_no_arg").expect("rustpkg_build_no_arg failed");
731 let package_dir = tmp.push("src").push("foo");
732 assert!(os::mkdir_recursive(&package_dir, U_RWX));
734 writeFile(&package_dir.push("main.rs"),
735 "fn main() { let _x = (); }");
736 debug!("build_no_arg: dir = %s", package_dir.to_str());
737 command_line_test([~"build"], &package_dir);
738 assert_built_executable_exists(&tmp, "foo");
742 fn rustpkg_install_no_arg() {
743 let tmp = mkdtemp(&os::tmpdir(),
744 "rustpkg_install_no_arg").expect("rustpkg_build_no_arg failed");
745 let package_dir = tmp.push("src").push("foo");
746 assert!(os::mkdir_recursive(&package_dir, U_RWX));
747 writeFile(&package_dir.push("lib.rs"),
748 "fn main() { let _x = (); }");
749 debug!("install_no_arg: dir = %s", package_dir.to_str());
750 command_line_test([~"install"], &package_dir);
751 assert_lib_exists(&tmp, "foo", NoVersion);
755 fn rustpkg_clean_no_arg() {
756 let tmp = mkdtemp(&os::tmpdir(), "rustpkg_clean_no_arg").expect("rustpkg_clean_no_arg failed");
757 let package_dir = tmp.push("src").push("foo");
758 assert!(os::mkdir_recursive(&package_dir, U_RWX));
760 writeFile(&package_dir.push("main.rs"),
761 "fn main() { let _x = (); }");
762 debug!("clean_no_arg: dir = %s", package_dir.to_str());
763 command_line_test([~"build"], &package_dir);
764 assert_built_executable_exists(&tmp, "foo");
765 command_line_test([~"clean"], &package_dir);
766 assert!(!built_executable_in_workspace(&PkgId::new("foo", &package_dir),
767 &tmp).map_default(false, |m| { os::path_exists(m) }));
771 #[ignore (reason = "Specifying env doesn't work -- see #8028")]
772 fn rust_path_test() {
773 let dir_for_path = mkdtemp(&os::tmpdir(), "more_rust").expect("rust_path_test failed");
774 let dir = mk_workspace(&dir_for_path, &normalize(RemotePath(Path("foo"))), &NoVersion);
775 debug!("dir = %s", dir.to_str());
776 writeFile(&dir.push("main.rs"), "fn main() { let _x = (); }");
778 let cwd = os::getcwd();
779 debug!("cwd = %s", cwd.to_str());
780 debug!("Running command: cd %s; RUST_LOG=rustpkg RUST_PATH=%s rustpkg install foo",
781 cwd.to_str(), dir_for_path.to_str());
782 let mut prog = run::Process::new("rustpkg",
783 [~"install", ~"foo"],
784 run::ProcessOptions { env: Some(&[(~"RUST_LOG",
787 dir_for_path.to_str())]),
793 prog.finish_with_output();
794 assert_executable_exists(&dir_for_path, "foo");
798 fn rust_path_contents() {
799 use std::unstable::change_dir_locked;
801 let dir = mkdtemp(&os::tmpdir(), "rust_path").expect("rust_path_contents failed");
802 let abc = &dir.push("A").push("B").push("C");
803 assert!(os::mkdir_recursive(&abc.push(".rust"), U_RWX));
804 assert!(os::mkdir_recursive(&abc.pop().push(".rust"), U_RWX));
805 assert!(os::mkdir_recursive(&abc.pop().pop().push(".rust"), U_RWX));
806 assert!(do change_dir_locked(&dir.push("A").push("B").push("C")) {
808 let cwd = os::getcwd().push(".rust");
809 let parent = cwd.pop().pop().push(".rust");
810 let grandparent = cwd.pop().pop().pop().push(".rust");
811 assert!(p.contains(&cwd));
812 assert!(p.contains(&parent));
813 assert!(p.contains(&grandparent));
814 for a_path in p.iter() {
815 assert!(!a_path.components.is_empty());
821 fn rust_path_parse() {
822 os::setenv("RUST_PATH", "/a/b/c:/d/e/f:/g/h/i");
823 let paths = rust_path();
824 assert!(paths.contains(&Path("/g/h/i")));
825 assert!(paths.contains(&Path("/d/e/f")));
826 assert!(paths.contains(&Path("/a/b/c")));
827 os::unsetenv("RUST_PATH");
832 let dir = mkdtemp(&os::tmpdir(), "test_list").expect("test_list failed");
833 let foo = PkgId::new("foo", &dir);
834 create_local_package_in(&foo, &dir);
835 let bar = PkgId::new("bar", &dir);
836 create_local_package_in(&bar, &dir);
837 let quux = PkgId::new("quux", &dir);
838 create_local_package_in(&quux, &dir);
840 // NOTE Not really great output, though...
841 // NOTE do any tests need to be unignored?
842 command_line_test([~"install", ~"foo"], &dir);
843 let env_arg = ~[(~"RUST_PATH", dir.to_str())];
844 debug!("RUST_PATH = %s", dir.to_str());
845 let list_output = command_line_test_output_with_env([~"list"], env_arg.clone());
846 assert!(list_output.iter().any(|x| x.starts_with("libfoo_")));
848 command_line_test([~"install", ~"bar"], &dir);
849 let list_output = command_line_test_output_with_env([~"list"], env_arg.clone());
850 assert!(list_output.iter().any(|x| x.starts_with("libfoo_")));
851 assert!(list_output.iter().any(|x| x.starts_with("libbar_")));
853 command_line_test([~"install", ~"quux"], &dir);
854 let list_output = command_line_test_output_with_env([~"list"], env_arg);
855 assert!(list_output.iter().any(|x| x.starts_with("libfoo_")));
856 assert!(list_output.iter().any(|x| x.starts_with("libbar_")));
857 assert!(list_output.iter().any(|x| x.starts_with("libquux_")));
861 fn install_remove() {
862 let dir = mkdtemp(&os::tmpdir(), "install_remove").expect("install_remove");
863 let foo = PkgId::new("foo", &dir);
864 let bar = PkgId::new("bar", &dir);
865 let quux = PkgId::new("quux", &dir);
866 create_local_package_in(&foo, &dir);
867 create_local_package_in(&bar, &dir);
868 create_local_package_in(&quux, &dir);
869 let rust_path_to_use = ~[(~"RUST_PATH", dir.to_str())];
870 command_line_test([~"install", ~"foo"], &dir);
871 command_line_test([~"install", ~"bar"], &dir);
872 command_line_test([~"install", ~"quux"], &dir);
873 let list_output = command_line_test_output_with_env([~"list"], rust_path_to_use.clone());
874 assert!(list_output.iter().any(|x| x.starts_with("foo")));
875 assert!(list_output.iter().any(|x| x.starts_with("bar")));
876 assert!(list_output.iter().any(|x| x.starts_with("quux")));
877 command_line_test([~"uninstall", ~"foo"], &dir);
878 let list_output = command_line_test_output_with_env([~"list"], rust_path_to_use.clone());
879 assert!(!list_output.iter().any(|x| x.starts_with("foo")));
880 assert!(list_output.iter().any(|x| x.starts_with("bar")));
881 assert!(list_output.iter().any(|x| x.starts_with("quux")));
885 fn install_check_duplicates() {
886 // should check that we don't install two packages with the same full name *and* version
887 // ("Is already installed -- doing nothing")
888 // check invariant that there are no dups in the pkg database
889 let dir = mkdtemp(&os::tmpdir(), "install_remove").expect("install_remove");
890 let foo = PkgId::new("foo", &dir);
891 create_local_package_in(&foo, &dir);
893 command_line_test([~"install", ~"foo"], &dir);
894 command_line_test([~"install", ~"foo"], &dir);
895 let mut contents = ~[];
896 let check_dups = |p: &PkgId| {
897 if contents.contains(p) {
898 fail!("package %s appears in `list` output more than once", p.local_path.to_str());
901 contents.push((*p).clone());
905 list_installed_packages(check_dups);
909 #[ignore(reason = "Workcache not yet implemented -- see #7075")]
911 let p_id = PkgId::new("foo", &os::getcwd());
912 let workspace = create_local_package(&p_id);
913 command_line_test([~"build", ~"foo"], &workspace);
914 let date = datestamp(&built_library_in_workspace(&p_id,
915 &workspace).expect("no_rebuilding"));
916 command_line_test([~"build", ~"foo"], &workspace);
917 let newdate = datestamp(&built_library_in_workspace(&p_id,
918 &workspace).expect("no_rebuilding (2)"));
919 assert_eq!(date, newdate);
923 #[ignore(reason = "Workcache not yet implemented -- see #7075")]
924 fn no_rebuilding_dep() {
925 let p_id = PkgId::new("foo", &os::getcwd());
926 let dep_id = PkgId::new("bar", &os::getcwd());
927 let workspace = create_local_package_with_dep(&p_id, &dep_id);
928 command_line_test([~"build", ~"foo"], &workspace);
929 let bar_date = datestamp(&lib_output_file_name(&workspace,
932 let foo_date = datestamp(&output_file_name(&workspace, "foo"));
933 assert!(bar_date < foo_date);
937 fn do_rebuild_dep_dates_change() {
938 let p_id = PkgId::new("foo", &os::getcwd());
939 let dep_id = PkgId::new("bar", &os::getcwd());
940 let workspace = create_local_package_with_dep(&p_id, &dep_id);
941 command_line_test([~"build", ~"foo"], &workspace);
942 let bar_date = datestamp(&lib_output_file_name(&workspace, "build", "bar"));
943 touch_source_file(&workspace, &dep_id);
944 command_line_test([~"build", ~"foo"], &workspace);
945 let new_bar_date = datestamp(&lib_output_file_name(&workspace, "build", "bar"));
946 assert!(new_bar_date > bar_date);
950 fn do_rebuild_dep_only_contents_change() {
951 let p_id = PkgId::new("foo", &os::getcwd());
952 let dep_id = PkgId::new("bar", &os::getcwd());
953 let workspace = create_local_package_with_dep(&p_id, &dep_id);
954 command_line_test([~"build", ~"foo"], &workspace);
955 let bar_date = datestamp(&lib_output_file_name(&workspace, "build", "bar"));
956 frob_source_file(&workspace, &dep_id);
957 // should adjust the datestamp
958 command_line_test([~"build", ~"foo"], &workspace);
959 let new_bar_date = datestamp(&lib_output_file_name(&workspace, "build", "bar"));
960 assert!(new_bar_date > bar_date);
965 let workspace = create_local_package(&PkgId::new("foo#0.1", &os::getcwd()));
966 create_local_package(&PkgId::new("foo#0.2", &os::getcwd()));
967 command_line_test([~"install", ~"foo#0.1"], &workspace);
968 let output = command_line_test_output([~"list"]);
969 // make sure output includes versions
970 assert!(!output.iter().any(|x| x == &~"foo#0.2"));
974 #[ignore(reason = "do not yet implemented")]
975 fn test_build_hooks() {
976 let workspace = create_local_package_with_custom_build_hook(&PkgId::new("foo", &os::getcwd()),
978 command_line_test([~"do", ~"foo", ~"frob"], &workspace);
983 #[ignore(reason = "info not yet implemented")]
985 let expected_info = ~"package foo"; // fill in
986 let workspace = create_local_package(&PkgId::new("foo", &os::getcwd()));
987 let output = command_line_test([~"info", ~"foo"], &workspace);
988 assert_eq!(str::from_bytes(output.output), expected_info);
992 #[ignore(reason = "test not yet implemented")]
993 fn test_rustpkg_test() {
994 let expected_results = ~"1 out of 1 tests passed"; // fill in
995 let workspace = create_local_package_with_test(&PkgId::new("foo", &os::getcwd()));
996 let output = command_line_test([~"test", ~"foo"], &workspace);
997 assert_eq!(str::from_bytes(output.output), expected_results);
1001 fn test_uninstall() {
1002 let workspace = create_local_package(&PkgId::new("foo", &os::getcwd()));
1003 let _output = command_line_test([~"info", ~"foo"], &workspace);
1004 command_line_test([~"uninstall", ~"foo"], &workspace);
1005 let output = command_line_test([~"list"], &workspace);
1006 assert!(!str::from_bytes(output.output).contains("foo"));
1010 fn test_non_numeric_tag() {
1011 let temp_pkg_id = git_repo_pkg();
1012 let repo = init_git_repo(&Path(temp_pkg_id.local_path.to_str()));
1013 let repo_subdir = repo.push("mockgithub.com").push("catamorphism").push("test_pkg");
1014 writeFile(&repo_subdir.push("foo"), "foo");
1015 writeFile(&repo_subdir.push("lib.rs"),
1016 "pub fn f() { let _x = (); }");
1017 add_git_tag(&repo_subdir, ~"testbranch");
1018 writeFile(&repo_subdir.push("testbranch_only"), "hello");
1019 add_git_tag(&repo_subdir, ~"another_tag");
1020 writeFile(&repo_subdir.push("not_on_testbranch_only"), "bye bye");
1021 add_all_and_commit(&repo_subdir);
1024 command_line_test([~"install", fmt!("%s#testbranch", temp_pkg_id.remote_path.to_str())],
1026 let file1 = repo.push_many(["mockgithub.com", "catamorphism",
1027 "test_pkg", "testbranch_only"]);
1028 let file2 = repo.push_many(["mockgithub.com", "catamorphism", "test_pkg",
1030 assert!(os::path_exists(&file1));
1031 assert!(!os::path_exists(&file2));