cargo/tests/testsuite/cache_messages.rs
Alex Crichton daa1bce283 Enable pipelined compilation by default
This commit enables pipelined compilation by default in Cargo now that
the requisite support has been stablized in rust-lang/rust#62766. This
involved minor updates in a number of locations here and there, but
nothing of meat has changed from the original implementation (just
tweaks to how rustc is called).
2019-07-31 14:56:24 -07:00

383 lines
11 KiB
Rust

use crate::support::{clippy_is_available, is_nightly, process, project, registry::Package};
use std::path::Path;
fn as_str(bytes: &[u8]) -> &str {
std::str::from_utf8(bytes).expect("valid utf-8")
}
#[cargo_test]
fn simple() {
if !is_nightly() {
// --json-rendered is unstable
return;
}
// A simple example that generates two warnings (unused functions).
let p = project()
.file(
"src/lib.rs",
"
fn a() {}
fn b() {}
",
)
.build();
let agnostic_path = Path::new("src").join("lib.rs");
let agnostic_path_s = agnostic_path.to_str().unwrap();
// Capture what rustc actually emits. This is done to avoid relying on the
// exact message formatting in rustc.
let rustc_output = process("rustc")
.cwd(p.root())
.args(&["--crate-type=lib", agnostic_path_s])
.exec_with_output()
.expect("rustc to run");
assert!(rustc_output.stdout.is_empty());
assert!(rustc_output.status.success());
// -q so the output is the same as rustc (no "Compiling" or "Finished").
let cargo_output1 = p
.cargo("check -Zcache-messages -q --color=never")
.masquerade_as_nightly_cargo()
.exec_with_output()
.expect("cargo to run");
assert_eq!(as_str(&rustc_output.stderr), as_str(&cargo_output1.stderr));
assert!(cargo_output1.stdout.is_empty());
// Check that the cached version is exactly the same.
let cargo_output2 = p
.cargo("check -Zcache-messages -q")
.masquerade_as_nightly_cargo()
.exec_with_output()
.expect("cargo to run");
assert_eq!(as_str(&rustc_output.stderr), as_str(&cargo_output2.stderr));
assert!(cargo_output2.stdout.is_empty());
}
// same as `simple`, except everything is using the short format
#[cargo_test]
fn simple_short() {
if !is_nightly() {
// --json-rendered is unstable
return;
}
let p = project()
.file(
"src/lib.rs",
"
fn a() {}
fn b() {}
",
)
.build();
let agnostic_path = Path::new("src").join("lib.rs");
let agnostic_path_s = agnostic_path.to_str().unwrap();
let rustc_output = process("rustc")
.cwd(p.root())
.args(&["--crate-type=lib", agnostic_path_s, "--error-format=short"])
.exec_with_output()
.expect("rustc to run");
assert!(rustc_output.stdout.is_empty());
assert!(rustc_output.status.success());
let cargo_output1 = p
.cargo("check -Zcache-messages -q --color=never --message-format=short")
.masquerade_as_nightly_cargo()
.exec_with_output()
.expect("cargo to run");
assert_eq!(as_str(&rustc_output.stderr), as_str(&cargo_output1.stderr));
// assert!(cargo_output1.stdout.is_empty());
let cargo_output2 = p
.cargo("check -Zcache-messages -q --message-format=short")
.masquerade_as_nightly_cargo()
.exec_with_output()
.expect("cargo to run");
println!("{}", String::from_utf8_lossy(&cargo_output2.stdout));
assert_eq!(as_str(&rustc_output.stderr), as_str(&cargo_output2.stderr));
assert!(cargo_output2.stdout.is_empty());
}
#[cargo_test]
fn color() {
if !is_nightly() {
// --json-rendered is unstable
return;
}
// Check enabling/disabling color.
let p = project().file("src/lib.rs", "fn a() {}").build();
let agnostic_path = Path::new("src").join("lib.rs");
let agnostic_path_s = agnostic_path.to_str().unwrap();
// Capture the original color output.
let rustc_output = process("rustc")
.cwd(p.root())
.args(&["--crate-type=lib", agnostic_path_s, "--color=always"])
.exec_with_output()
.expect("rustc to run");
assert!(rustc_output.status.success());
let rustc_color = as_str(&rustc_output.stderr);
assert!(rustc_color.contains("\x1b["));
// Capture the original non-color output.
let rustc_output = process("rustc")
.cwd(p.root())
.args(&["--crate-type=lib", agnostic_path_s])
.exec_with_output()
.expect("rustc to run");
let rustc_nocolor = as_str(&rustc_output.stderr);
assert!(!rustc_nocolor.contains("\x1b["));
// First pass, non-cached, with color, should be the same.
let cargo_output1 = p
.cargo("check -Zcache-messages -q --color=always")
.masquerade_as_nightly_cargo()
.exec_with_output()
.expect("cargo to run");
assert_eq!(rustc_color, as_str(&cargo_output1.stderr));
// Replay cached, with color.
let cargo_output2 = p
.cargo("check -Zcache-messages -q --color=always")
.masquerade_as_nightly_cargo()
.exec_with_output()
.expect("cargo to run");
assert_eq!(rustc_color, as_str(&cargo_output2.stderr));
// Replay cached, no color.
let cargo_output_nocolor = p
.cargo("check -Zcache-messages -q --color=never")
.masquerade_as_nightly_cargo()
.exec_with_output()
.expect("cargo to run");
assert_eq!(rustc_nocolor, as_str(&cargo_output_nocolor.stderr));
}
#[cargo_test]
fn cached_as_json() {
if !is_nightly() {
// --json-rendered is unstable
return;
}
// Check that cached JSON output is the same.
let p = project().file("src/lib.rs", "fn a() {}").build();
// Grab the non-cached output, feature disabled.
// NOTE: When stabilizing, this will need to be redone.
let cargo_output = p
.cargo("check --message-format=json")
.exec_with_output()
.expect("cargo to run");
assert!(cargo_output.status.success());
let orig_cargo_out = as_str(&cargo_output.stdout);
assert!(orig_cargo_out.contains("compiler-message"));
p.cargo("clean").run();
// Check JSON output, not fresh.
let cargo_output1 = p
.cargo("check -Zcache-messages --message-format=json")
.masquerade_as_nightly_cargo()
.exec_with_output()
.expect("cargo to run");
assert_eq!(as_str(&cargo_output1.stdout), orig_cargo_out);
// Check JSON output, fresh.
let cargo_output2 = p
.cargo("check -Zcache-messages --message-format=json")
.masquerade_as_nightly_cargo()
.exec_with_output()
.expect("cargo to run");
// The only difference should be this field.
let fix_fresh = as_str(&cargo_output2.stdout).replace("\"fresh\":true", "\"fresh\":false");
assert_eq!(fix_fresh, orig_cargo_out);
}
#[cargo_test]
fn clears_cache_after_fix() {
if !is_nightly() {
// --json-rendered is unstable
return;
}
// Make sure the cache is invalidated when there is no output.
let p = project().file("src/lib.rs", "fn asdf() {}").build();
// Fill the cache.
p.cargo("check -Zcache-messages")
.masquerade_as_nightly_cargo()
.with_stderr_contains("[..]asdf[..]")
.run();
let cpath = p
.glob("target/debug/.fingerprint/foo-*/output")
.next()
.unwrap()
.unwrap();
assert!(std::fs::read_to_string(cpath).unwrap().contains("asdf"));
// Fix it.
p.change_file("src/lib.rs", "");
p.cargo("check -Zcache-messages")
.masquerade_as_nightly_cargo()
.with_stdout("")
.with_stderr(
"\
[CHECKING] foo [..]
[FINISHED] [..]
",
)
.run();
assert_eq!(p.glob("target/debug/.fingerprint/foo-*/output").count(), 0);
// And again, check the cache is correct.
p.cargo("check -Zcache-messages")
.masquerade_as_nightly_cargo()
.with_stdout("")
.with_stderr(
"\
[FINISHED] [..]
",
)
.run();
}
#[cargo_test]
fn rustdoc() {
if !is_nightly() {
// --json-rendered is unstable
return;
}
// Create a warning in rustdoc.
let p = project()
.file(
"src/lib.rs",
"
#![warn(private_doc_tests)]
/// asdf
/// ```
/// let x = 1;
/// ```
fn f() {}
",
)
.build();
// At this time, rustdoc does not support --json-rendered=termcolor. So it
// will always be uncolored with -Zcache-messages.
let rustdoc_output = p
.cargo("doc -Zcache-messages -q")
.masquerade_as_nightly_cargo()
.exec_with_output()
.expect("rustdoc to run");
assert!(rustdoc_output.status.success());
let rustdoc_stderr = as_str(&rustdoc_output.stderr);
assert!(rustdoc_stderr.contains("private"));
// Invert this when --json-rendered is added.
assert!(!rustdoc_stderr.contains("\x1b["));
assert_eq!(p.glob("target/debug/.fingerprint/foo-*/output").count(), 1);
// Check the cached output.
let rustdoc_output = p
.cargo("doc -Zcache-messages -q")
.masquerade_as_nightly_cargo()
.exec_with_output()
.expect("rustdoc to run");
assert_eq!(as_str(&rustdoc_output.stderr), rustdoc_stderr);
}
#[cargo_test]
fn fix() {
if !is_nightly() {
// --json-rendered is unstable
return;
}
// Make sure `fix` is not broken by caching.
let p = project().file("src/lib.rs", "pub fn try() {}").build();
p.cargo("fix --edition --allow-no-vcs -Zcache-messages")
.masquerade_as_nightly_cargo()
.run();
assert_eq!(p.read_file("src/lib.rs"), "pub fn r#try() {}");
}
#[cargo_test]
fn clippy() {
if !is_nightly() {
// --json-rendered is unstable
eprintln!("skipping test: requires nightly");
return;
}
if !clippy_is_available() {
return;
}
// Caching clippy output.
// This is just a random clippy lint (assertions_on_constants) that
// hopefully won't change much in the future.
let p = project()
.file("src/lib.rs", "pub fn f() { assert!(true); }")
.build();
p.cargo("clippy-preview -Zunstable-options -Zcache-messages")
.masquerade_as_nightly_cargo()
.with_stderr_contains("[..]assert!(true)[..]")
.run();
// Again, reading from the cache.
p.cargo("clippy-preview -Zunstable-options -Zcache-messages")
.masquerade_as_nightly_cargo()
.with_stderr_contains("[..]assert!(true)[..]")
.run();
// FIXME: Unfortunately clippy is sharing the same hash with check. This
// causes the cache to be reused when it shouldn't.
p.cargo("check -Zcache-messages")
.masquerade_as_nightly_cargo()
.with_stderr_contains("[..]assert!(true)[..]") // This should not be here.
.run();
}
#[cargo_test]
fn very_verbose() {
if !is_nightly() {
// --json-rendered is unstable
return;
}
// Handle cap-lints in dependencies.
Package::new("bar", "1.0.0")
.file("src/lib.rs", "fn not_used() {}")
.publish();
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[dependencies]
bar = "1.0"
"#,
)
.file("src/lib.rs", "")
.build();
p.cargo("check -Zcache-messages -vv")
.masquerade_as_nightly_cargo()
.with_stderr_contains("[..]not_used[..]")
.run();
p.cargo("check -Zcache-messages")
.masquerade_as_nightly_cargo()
.with_stderr("[FINISHED] [..]")
.run();
p.cargo("check -Zcache-messages -vv")
.masquerade_as_nightly_cargo()
.with_stderr_contains("[..]not_used[..]")
.run();
}