| //! Tests for `-Zbuild-analysis`. |
| |
| use crate::prelude::*; |
| |
| use cargo_test_support::basic_manifest; |
| use cargo_test_support::compare::assert_e2e; |
| use cargo_test_support::paths::log_file; |
| use cargo_test_support::project; |
| use cargo_test_support::str; |
| |
| #[cargo_test] |
| fn gated() { |
| let p = project() |
| .file("Cargo.toml", &basic_manifest("foo", "0.0.0")) |
| .file("src/lib.rs", "") |
| .build(); |
| |
| p.cargo("check") |
| .env("CARGO_BUILD_ANALYSIS_ENABLED", "true") |
| .masquerade_as_nightly_cargo(&["build-analysis"]) |
| .with_stderr_data(str![[r#" |
| [WARNING] ignoring 'build.analysis' config, pass `-Zbuild-analysis` to enable it |
| [CHECKING] foo v0.0.0 ([ROOT]/foo) |
| [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s |
| |
| "#]]) |
| .run(); |
| } |
| |
| #[cargo_test] |
| fn one_logfile_per_invocation() { |
| let p = project() |
| .file("Cargo.toml", &basic_manifest("foo", "0.0.0")) |
| .file("src/lib.rs", "") |
| .build(); |
| |
| // First invocation |
| p.cargo("check -Zbuild-analysis") |
| .env("CARGO_BUILD_ANALYSIS_ENABLED", "true") |
| .masquerade_as_nightly_cargo(&["build-analysis"]) |
| .with_stderr_data(str![[r#" |
| [CHECKING] foo v0.0.0 ([ROOT]/foo) |
| [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s |
| |
| "#]]) |
| .run(); |
| |
| let _ = get_log(0); |
| |
| // Second invocation |
| p.cargo("check -Zbuild-analysis") |
| .env("CARGO_BUILD_ANALYSIS_ENABLED", "true") |
| .masquerade_as_nightly_cargo(&["build-analysis"]) |
| .with_stderr_data(str![[r#" |
| [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s |
| |
| "#]]) |
| .run(); |
| |
| let _ = get_log(1); |
| } |
| |
| #[cargo_test] |
| fn log_msg_build_started() { |
| let p = project() |
| .file("Cargo.toml", &basic_manifest("foo", "0.0.0")) |
| .file("src/lib.rs", "") |
| .build(); |
| |
| p.cargo("check -Zbuild-analysis") |
| .env("CARGO_BUILD_ANALYSIS_ENABLED", "true") |
| .masquerade_as_nightly_cargo(&["build-analysis"]) |
| .run(); |
| |
| assert_e2e().eq( |
| &get_log(0), |
| str![[r#" |
| [ |
| { |
| "cwd": "[ROOT]/foo", |
| "host": "[HOST_TARGET]", |
| "jobs": "{...}", |
| "num_cpus": "{...}", |
| "profile": "dev", |
| "reason": "build-started", |
| "run_id": "[..]T[..]Z-[..]", |
| "rustc_version": "1.[..]", |
| "rustc_version_verbose": "{...}", |
| "target_dir": "[ROOT]/foo/target", |
| "timestamp": "[..]T[..]Z", |
| "workspace_root": "[ROOT]/foo" |
| }, |
| "{...}" |
| ] |
| "#]] |
| .is_json() |
| .against_jsonlines(), |
| ); |
| } |
| |
| #[cargo_test] |
| fn log_msg_timing_info() { |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.0" |
| edition = "2015" |
| |
| [dependencies] |
| bar = { path = "bar" } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.0")) |
| .file("bar/src/lib.rs", "") |
| .build(); |
| |
| p.cargo("check -Zbuild-analysis") |
| .env("CARGO_BUILD_ANALYSIS_ENABLED", "true") |
| .masquerade_as_nightly_cargo(&["build-analysis"]) |
| .run(); |
| |
| assert_e2e().eq( |
| &get_log(0), |
| str![[r#" |
| [ |
| "{...}", |
| { |
| "elapsed": "{...}", |
| "index": 0, |
| "reason": "unit-started", |
| "run_id": "[..]T[..]Z-[..]", |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "elapsed": "{...}", |
| "index": 0, |
| "reason": "unit-rmeta-finished", |
| "run_id": "[..]T[..]Z-[..]", |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "elapsed": "{...}", |
| "index": 0, |
| "reason": "unit-finished", |
| "run_id": "[..]T[..]Z-[..]", |
| "timestamp": "[..]T[..]Z", |
| "unblocked": [ |
| 1 |
| ] |
| }, |
| { |
| "elapsed": "{...}", |
| "index": 1, |
| "reason": "unit-started", |
| "run_id": "[..]T[..]Z-[..]", |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "elapsed": "{...}", |
| "index": 1, |
| "reason": "unit-rmeta-finished", |
| "run_id": "[..]T[..]Z-[..]", |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "elapsed": "{...}", |
| "index": 1, |
| "reason": "unit-finished", |
| "run_id": "[..]T[..]Z-[..]", |
| "timestamp": "[..]T[..]Z" |
| } |
| ] |
| "#]] |
| .is_json() |
| .against_jsonlines(), |
| ); |
| } |
| |
| #[cargo_test(nightly, reason = "rustc --json=timings is unstable")] |
| fn log_msg_timing_info_section_timings() { |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.0" |
| edition = "2015" |
| |
| [dependencies] |
| bar = { path = "bar" } |
| "#, |
| ) |
| .file("src/main.rs", "fn main() {}") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.0")) |
| .file("bar/src/lib.rs", "") |
| .build(); |
| |
| p.cargo("check -Zbuild-analysis -Zsection-timings") |
| .env("CARGO_BUILD_ANALYSIS_ENABLED", "true") |
| .masquerade_as_nightly_cargo(&["build-analysis", "section-timings"]) |
| .run(); |
| |
| assert_e2e().eq( |
| &get_log(0), |
| str![[r#" |
| [ |
| "{...}", |
| { |
| "elapsed": "{...}", |
| "index": 0, |
| "reason": "unit-started", |
| "run_id": "[..]T[..]Z-[..]", |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "elapsed": "{...}", |
| "index": 0, |
| "reason": "unit-section-started", |
| "run_id": "[..]T[..]Z-[..]", |
| "section": "codegen", |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "elapsed": "{...}", |
| "index": 0, |
| "reason": "unit-rmeta-finished", |
| "run_id": "[..]T[..]Z-[..]", |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "elapsed": "{...}", |
| "index": 0, |
| "reason": "unit-section-finished", |
| "run_id": "[..]T[..]Z-[..]", |
| "section": "codegen", |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "elapsed": "{...}", |
| "index": 0, |
| "reason": "unit-section-started", |
| "run_id": "[..]T[..]Z-[..]", |
| "section": "link", |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "elapsed": "{...}", |
| "index": 0, |
| "reason": "unit-section-finished", |
| "run_id": "[..]T[..]Z-[..]", |
| "section": "link", |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "elapsed": "{...}", |
| "index": 0, |
| "reason": "unit-finished", |
| "run_id": "[..]T[..]Z-[..]", |
| "timestamp": "[..]T[..]Z", |
| "unblocked": [ |
| 1 |
| ] |
| }, |
| { |
| "elapsed": "{...}", |
| "index": 1, |
| "reason": "unit-started", |
| "run_id": "[..]T[..]Z-[..]", |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "elapsed": "{...}", |
| "index": 1, |
| "reason": "unit-section-started", |
| "run_id": "[..]T[..]Z-[..]", |
| "section": "codegen", |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "elapsed": "{...}", |
| "index": 1, |
| "reason": "unit-rmeta-finished", |
| "run_id": "[..]T[..]Z-[..]", |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "elapsed": "{...}", |
| "index": 1, |
| "reason": "unit-section-finished", |
| "run_id": "[..]T[..]Z-[..]", |
| "section": "codegen", |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "elapsed": "{...}", |
| "index": 1, |
| "reason": "unit-section-started", |
| "run_id": "[..]T[..]Z-[..]", |
| "section": "link", |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "elapsed": "{...}", |
| "index": 1, |
| "reason": "unit-section-finished", |
| "run_id": "[..]T[..]Z-[..]", |
| "section": "link", |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "elapsed": "{...}", |
| "index": 1, |
| "reason": "unit-finished", |
| "run_id": "[..]T[..]Z-[..]", |
| "timestamp": "[..]T[..]Z" |
| } |
| ] |
| "#]] |
| .is_json() |
| .against_jsonlines(), |
| ); |
| } |
| |
| #[cargo_test] |
| fn log_rebuild_reason_fresh_build() { |
| let p = project() |
| .file("Cargo.toml", &basic_manifest("foo", "0.0.0")) |
| .file("src/lib.rs", "") |
| .build(); |
| |
| p.cargo("check -Zbuild-analysis") |
| .env("CARGO_BUILD_ANALYSIS_ENABLED", "true") |
| .masquerade_as_nightly_cargo(&["build-analysis"]) |
| .with_stderr_data(str![[r#" |
| [CHECKING] foo v0.0.0 ([ROOT]/foo) |
| [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s |
| |
| "#]]) |
| .run(); |
| |
| assert_e2e().eq( |
| &get_log(0), |
| str![[r#" |
| [ |
| "{...}", |
| { |
| "...": "{...}", |
| "reason": "unit-graph-finished" |
| }, |
| { |
| "index": 0, |
| "reason": "unit-fingerprint", |
| "run_id": "[..]T[..]Z-[..]", |
| "status": "new", |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "...": "{...}", |
| "reason": "unit-started" |
| }, |
| "{...}" |
| ] |
| "#]] |
| .is_json() |
| .against_jsonlines(), |
| ); |
| } |
| |
| #[cargo_test] |
| fn log_rebuild_reason_file_changed() { |
| // Test that changing a file logs the appropriate rebuild reason |
| let p = project() |
| .file("Cargo.toml", &basic_manifest("foo", "0.0.0")) |
| .file("src/lib.rs", "") |
| .build(); |
| |
| p.cargo("check -Zbuild-analysis") |
| .env("CARGO_BUILD_ANALYSIS_ENABLED", "true") |
| .masquerade_as_nightly_cargo(&["build-analysis"]) |
| .run(); |
| |
| assert_e2e().eq( |
| &get_log(0), |
| str![[r#" |
| [ |
| "{...}", |
| { |
| "...": "{...}", |
| "reason": "unit-graph-finished" |
| }, |
| { |
| "index": 0, |
| "reason": "unit-fingerprint", |
| "run_id": "[..]T[..]Z-[..]", |
| "status": "new", |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "...": "{...}", |
| "reason": "unit-started" |
| }, |
| "{...}" |
| ] |
| "#]] |
| .is_json() |
| .against_jsonlines(), |
| ); |
| |
| // Change source file |
| p.change_file("src/lib.rs", "//! comment"); |
| |
| p.cargo("check -Zbuild-analysis") |
| .env("CARGO_BUILD_ANALYSIS_ENABLED", "true") |
| .masquerade_as_nightly_cargo(&["build-analysis"]) |
| .with_stderr_data(str![[r#" |
| [CHECKING] foo v0.0.0 ([ROOT]/foo) |
| [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s |
| |
| "#]]) |
| .run(); |
| |
| // File changes SHOULD log rebuild-reason |
| assert_e2e().eq( |
| &get_log(1), |
| str![[r#" |
| [ |
| "{...}", |
| { |
| "...": "{...}", |
| "reason": "unit-graph-finished" |
| }, |
| { |
| "cause": { |
| "dirty_reason": "fs-status-outdated", |
| "fs_status": "stale-item", |
| "reference": "[ROOT]/foo/target/debug/.fingerprint/foo-[HASH]/dep-lib-foo", |
| "reference_mtime": "{...}", |
| "stale": "[ROOT]/foo/src/lib.rs", |
| "stale_item": "changed-file", |
| "stale_mtime": "{...}" |
| }, |
| "index": 0, |
| "reason": "unit-fingerprint", |
| "run_id": "[..]T[..]Z-[..]", |
| "status": "dirty", |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "...": "{...}", |
| "reason": "unit-started" |
| }, |
| "{...}" |
| ] |
| "#]] |
| .is_json() |
| .against_jsonlines(), |
| ); |
| } |
| |
| #[cargo_test] |
| fn log_rebuild_reason_no_rebuild() { |
| let p = project() |
| .file("Cargo.toml", &basic_manifest("foo", "0.0.0")) |
| .file("src/lib.rs", "") |
| .build(); |
| |
| // First build |
| p.cargo("check -Zbuild-analysis") |
| .env("CARGO_BUILD_ANALYSIS_ENABLED", "true") |
| .masquerade_as_nightly_cargo(&["build-analysis"]) |
| .run(); |
| |
| assert_e2e().eq( |
| &get_log(0), |
| str![[r#" |
| [ |
| "{...}", |
| { |
| "...": "{...}", |
| "reason": "unit-graph-finished" |
| }, |
| { |
| "index": 0, |
| "reason": "unit-fingerprint", |
| "run_id": "[..]T[..]Z-[..]", |
| "status": "new", |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "...": "{...}", |
| "reason": "unit-started" |
| }, |
| "{...}" |
| ] |
| "#]] |
| .is_json() |
| .against_jsonlines(), |
| ); |
| |
| // Second build without changes |
| p.cargo("check -Zbuild-analysis") |
| .env("CARGO_BUILD_ANALYSIS_ENABLED", "true") |
| .masquerade_as_nightly_cargo(&["build-analysis"]) |
| .with_stderr_data(str![[r#" |
| [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s |
| |
| "#]]) |
| .run(); |
| |
| // Should NOT contain any rebuild-reason messages since nothing rebuilt |
| assert_e2e().eq( |
| &get_log(1), |
| str![[r#" |
| [ |
| "{...}", |
| { |
| "...": "{...}", |
| "reason": "unit-graph-finished" |
| }, |
| { |
| "index": 0, |
| "reason": "unit-fingerprint", |
| "run_id": "[..]T[..]Z-[..]", |
| "status": "fresh", |
| "timestamp": "[..]T[..]Z" |
| } |
| ] |
| "#]] |
| .is_json() |
| .against_jsonlines(), |
| ); |
| } |
| |
| #[cargo_test] |
| fn log_msg_unit_graph() { |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.0" |
| edition = "2015" |
| |
| [dependencies] |
| bar = { path = "bar" } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("build.rs", "fn main() {}") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.0")) |
| .file("bar/src/lib.rs", "") |
| .build(); |
| |
| // `cargo doc` generates more units than `cargo check` |
| // * check bar |
| // * build foo build.rs |
| // * run foo build.rs |
| // * doc foo |
| // * doc bar |
| p.cargo("doc -Zbuild-analysis") |
| .env("CARGO_BUILD_ANALYSIS_ENABLED", "true") |
| .masquerade_as_nightly_cargo(&["build-analysis", "section-timings"]) |
| .run(); |
| |
| assert_e2e().eq( |
| &get_log(0), |
| str![[r#" |
| [ |
| "{...}", |
| { |
| "elapsed": "{...}", |
| "reason": "unit-graph-started", |
| "run_id": "[..]T[..]Z-[..]", |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "index": 0, |
| "mode": "check", |
| "package_id": "path+[ROOTURL]/foo/bar#0.0.0", |
| "platform": "[HOST_TARGET]", |
| "reason": "unit-registered", |
| "run_id": "[..]T[..]Z-[..]", |
| "target": { |
| "kind": "lib", |
| "name": "bar" |
| }, |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "index": 1, |
| "mode": "doc", |
| "package_id": "path+[ROOTURL]/foo/bar#0.0.0", |
| "platform": "[HOST_TARGET]", |
| "reason": "unit-registered", |
| "run_id": "[..]T[..]Z-[..]", |
| "target": { |
| "kind": "lib", |
| "name": "bar" |
| }, |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "dependencies": [ |
| 0, |
| 1, |
| 4 |
| ], |
| "index": 2, |
| "mode": "doc", |
| "package_id": "path+[ROOTURL]/foo#0.0.0", |
| "platform": "[HOST_TARGET]", |
| "reason": "unit-registered", |
| "requested": true, |
| "run_id": "[..]T[..]Z-[..]", |
| "target": { |
| "kind": "lib", |
| "name": "foo" |
| }, |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "index": 3, |
| "mode": "build", |
| "package_id": "path+[ROOTURL]/foo#0.0.0", |
| "platform": "[HOST_TARGET]", |
| "reason": "unit-registered", |
| "run_id": "[..]T[..]Z-[..]", |
| "target": { |
| "kind": "build-script", |
| "name": "build-script-build" |
| }, |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "dependencies": [ |
| 3 |
| ], |
| "index": 4, |
| "mode": "run-custom-build", |
| "package_id": "path+[ROOTURL]/foo#0.0.0", |
| "platform": "[HOST_TARGET]", |
| "reason": "unit-registered", |
| "run_id": "[..]T[..]Z-[..]", |
| "target": { |
| "kind": "build-script", |
| "name": "build-script-build" |
| }, |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "elapsed": "{...}", |
| "reason": "unit-graph-finished", |
| "run_id": "[..]T[..]Z-[..]", |
| "timestamp": "[..]T[..]Z" |
| }, |
| "{...}" |
| ] |
| "#]] |
| .is_json() |
| .against_jsonlines(), |
| ); |
| } |
| |
| #[cargo_test] |
| fn log_msg_resolution_events() { |
| let p = project() |
| .file( |
| "Cargo.toml", |
| r#" |
| [package] |
| name = "foo" |
| version = "0.0.0" |
| edition = "2015" |
| |
| [dependencies] |
| bar = { path = "bar" } |
| "#, |
| ) |
| .file("src/lib.rs", "") |
| .file("build.rs", "fn main() {}") |
| .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.0")) |
| .file("bar/src/lib.rs", "") |
| .build(); |
| |
| p.cargo("doc -Zbuild-analysis") |
| .env("CARGO_BUILD_ANALYSIS_ENABLED", "true") |
| .masquerade_as_nightly_cargo(&["build-analysis", "section-timings"]) |
| .run(); |
| |
| assert_e2e().eq( |
| &get_log(0), |
| str![[r#" |
| [ |
| "{...}", |
| { |
| "elapsed": "{...}", |
| "reason": "resolution-started", |
| "run_id": "[..]T[..]Z-[..]", |
| "timestamp": "[..]T[..]Z" |
| }, |
| { |
| "elapsed": "{...}", |
| "reason": "resolution-finished", |
| "run_id": "[..]T[..]Z-[..]", |
| "timestamp": "[..]T[..]Z" |
| }, |
| "{...}" |
| ] |
| "#]] |
| .is_json() |
| .against_jsonlines(), |
| ); |
| } |
| |
| fn get_log(idx: usize) -> String { |
| std::fs::read_to_string(log_file(idx)).unwrap() |
| } |