blob: e6eebaf87f817b2e0796440333ec4e0f7ea518e9 [file] [log] [blame]
//! Tests for `build.build-dir` config property.
//!
//! The testing strategy for build-dir functionality is primarily checking if directories / files
//! are in the expected locations.
//! The rational is that other tests will verify each individual feature, while the tests in this
//! file verify the files saved to disk are in the correct locations according to the `build-dir`
//! configuration.
//!
//! Tests check if directories match some "layout" by using [`assert_build_dir_layout`] and
//! [`assert_artifact_dir_layout`].
use std::path::PathBuf;
use crate::prelude::*;
use cargo_test_support::{paths, project, str};
use cargo_test_support::{prelude::*, Project};
use std::env::consts::{DLL_PREFIX, DLL_SUFFIX, EXE_SUFFIX};
#[cargo_test]
fn verify_build_dir_is_disabled_by_feature_flag() {
let p = project()
.file("src/main.rs", r#"fn main() { println!("Hello, World!") }"#)
.file(
".cargo/config.toml",
r#"
[build]
build-dir = "build-dir"
"#,
)
.build();
p.cargo("build")
.masquerade_as_nightly_cargo(&["build-dir"])
.enable_mac_dsym()
.run();
assert_build_dir_layout(p.root().join("target"), "debug");
assert_exists(&p.root().join(format!("target/debug/foo{EXE_SUFFIX}")));
assert_exists(&p.root().join("target/debug/foo.d"));
assert_not_exists(&p.root().join("build-dir"));
}
#[cargo_test]
fn binary_with_debug() {
let p = project()
.file("src/main.rs", r#"fn main() { println!("Hello, World!") }"#)
.file(
".cargo/config.toml",
r#"
[build]
target-dir = "target-dir"
build-dir = "build-dir"
"#,
)
.build();
p.cargo("build -Z build-dir")
.masquerade_as_nightly_cargo(&["build-dir"])
.enable_mac_dsym()
.run();
assert_build_dir_layout(p.root().join("build-dir"), "debug");
assert_artifact_dir_layout(p.root().join("target-dir"), "debug");
assert_exists_patterns_with_base_dir(
&p.root(),
&[
// Check the pre-uplifted binary in the build-dir
&format!("build-dir/debug/deps/foo*{EXE_SUFFIX}"),
"build-dir/debug/deps/foo*.d",
// Verify the binary was copied to the target-dir
&format!("target-dir/debug/foo{EXE_SUFFIX}"),
"target-dir/debug/foo.d",
],
);
assert_not_exists(&p.root().join("target"));
}
#[cargo_test]
fn binary_with_release() {
let p = project()
.file("src/main.rs", r#"fn main() { println!("Hello, World!") }"#)
.file(
".cargo/config.toml",
r#"
[build]
target-dir = "target-dir"
build-dir = "build-dir"
"#,
)
.build();
p.cargo("build --release -Z build-dir")
.masquerade_as_nightly_cargo(&["build-dir"])
.enable_mac_dsym()
.run();
assert_build_dir_layout(p.root().join("build-dir"), "release");
assert_exists(&p.root().join(format!("target-dir/release/foo{EXE_SUFFIX}")));
assert_exists_patterns_with_base_dir(
&p.root(),
&[
// Check the pre-uplifted binary in the build-dir
&format!("build-dir/release/deps/foo*{EXE_SUFFIX}"),
"build-dir/release/deps/foo*.d",
// Verify the binary was copied to the target-dir
&format!("target-dir/release/foo{EXE_SUFFIX}"),
"target-dir/release/foo.d",
],
);
}
#[cargo_test]
fn libs() {
// https://doc.rust-lang.org/reference/linkage.html#r-link.staticlib
let (staticlib_prefix, staticlib_suffix) =
if cfg!(target_os = "windows") && cfg!(target_env = "msvc") {
("", ".lib")
} else {
("lib", ".a")
};
// (crate-type, list of final artifacts)
let lib_types = [
("lib", ["libfoo.rlib", "libfoo.d"]),
(
"dylib",
[
&format!("{DLL_PREFIX}foo{DLL_SUFFIX}"),
&format!("{DLL_PREFIX}foo.d"),
],
),
(
"cdylib",
[
&format!("{DLL_PREFIX}foo{DLL_SUFFIX}"),
&format!("{DLL_PREFIX}foo.d"),
],
),
(
"staticlib",
[
&format!("{staticlib_prefix}foo{staticlib_suffix}"),
&format!("{staticlib_prefix}foo.d"),
],
),
];
for (lib_type, expected_files) in lib_types {
let p = project()
.file("src/lib.rs", r#"fn foo() { println!("Hello, World!") }"#)
.file(
"Cargo.toml",
&format!(
r#"
[package]
name = "foo"
version = "0.0.1"
authors = []
edition = "2015"
[lib]
crate-type = ["{lib_type}"]
"#
),
)
.file(
".cargo/config.toml",
r#"
[build]
target-dir = "target-dir"
build-dir = "build-dir"
"#,
)
.build();
p.cargo("build -Z build-dir")
.masquerade_as_nightly_cargo(&["build-dir"])
.enable_mac_dsym()
.run();
assert_build_dir_layout(p.root().join("build-dir"), "debug");
// Verify lib artifacts were copied into the artifact dir
assert_exists_patterns_with_base_dir(&p.root().join("target-dir/debug"), &expected_files);
}
}
#[cargo_test]
fn should_default_to_target() {
let p = project()
.file("src/main.rs", r#"fn main() { println!("Hello, World!") }"#)
.build();
p.cargo("build -Z build-dir")
.masquerade_as_nightly_cargo(&["build-dir"])
.enable_mac_dsym()
.run();
assert_build_dir_layout(p.root().join("target"), "debug");
assert_exists(&p.root().join(format!("target/debug/foo{EXE_SUFFIX}")));
}
#[cargo_test]
fn should_respect_env_var() {
let p = project()
.file("src/main.rs", r#"fn main() { println!("Hello, World!") }"#)
.build();
p.cargo("build -Z build-dir")
.masquerade_as_nightly_cargo(&["build-dir"])
.env("CARGO_BUILD_BUILD_DIR", "build-dir")
.enable_mac_dsym()
.run();
assert_build_dir_layout(p.root().join("build-dir"), "debug");
assert_exists(&p.root().join(format!("target/debug/foo{EXE_SUFFIX}")));
}
#[cargo_test]
fn build_script_should_output_to_build_dir() {
let p = project()
.file("src/main.rs", r#"fn main() { println!("Hello, World!") }"#)
.file(
"build.rs",
r#"
fn main() {
std::fs::write(
format!("{}/foo.txt", std::env::var("OUT_DIR").unwrap()),
"Hello, world!",
)
.unwrap();
}
"#,
)
.file(
".cargo/config.toml",
r#"
[build]
target-dir = "target-dir"
build-dir = "build-dir"
"#,
)
.build();
p.cargo("build -Z build-dir")
.masquerade_as_nightly_cargo(&["build-dir"])
.enable_mac_dsym()
.run();
assert_build_dir_layout(p.root().join("build-dir"), "debug");
assert_exists_patterns_with_base_dir(
&p.root(),
&[
&format!("build-dir/debug/build/foo-*/build-script-build{EXE_SUFFIX}"),
"build-dir/debug/build/foo-*/out/foo.txt", // Verify OUT_DIR
],
);
}
#[cargo_test]
fn cargo_tmpdir_should_output_to_build_dir() {
let p = project()
.file("src/main.rs", r#"fn main() { println!("Hello, World!") }"#)
.file(
"tests/foo.rs",
r#"
#[test]
fn test() {
std::fs::write(
format!("{}/foo.txt", env!("CARGO_TARGET_TMPDIR")),
"Hello, world!",
)
.unwrap();
}
"#,
)
.file(
".cargo/config.toml",
r#"
[build]
target-dir = "target-dir"
build-dir = "build-dir"
"#,
)
.build();
p.cargo("test -Z build-dir")
.masquerade_as_nightly_cargo(&["build-dir"])
.enable_mac_dsym()
.run();
assert_build_dir_layout(p.root().join("build-dir"), "debug");
assert_exists(&p.root().join(format!("build-dir/tmp/foo.txt")));
}
#[cargo_test]
fn examples_should_output_to_build_dir_and_uplift_to_target_dir() {
let p = project()
.file("src/main.rs", r#"fn main() { println!("Hello, World!") }"#)
.file("examples/foo.rs", r#"fn main() { }"#)
.file(
".cargo/config.toml",
r#"
[build]
target-dir = "target-dir"
build-dir = "build-dir"
"#,
)
.build();
p.cargo("build --examples -Z build-dir")
.masquerade_as_nightly_cargo(&["build-dir"])
.enable_mac_dsym()
.run();
assert_build_dir_layout(p.root().join("build-dir"), "debug");
assert_exists_patterns_with_base_dir(
&p.root(),
&[
// uplifted (target-dir)
&format!("target-dir/debug/examples/foo{EXE_SUFFIX}"),
"target-dir/debug/examples/foo.d",
// pre-uplifted (build-dir)
&format!("build-dir/debug/examples/foo*{EXE_SUFFIX}"),
"build-dir/debug/examples/foo*.d",
],
);
}
#[cargo_test]
fn benches_should_output_to_build_dir() {
let p = project()
.file("src/main.rs", r#"fn main() { println!("Hello, World!") }"#)
.file("benches/foo.rs", r#"fn main() { }"#)
.file(
".cargo/config.toml",
r#"
[build]
target-dir = "target-dir"
build-dir = "build-dir"
"#,
)
.build();
p.cargo("build --bench=foo -Z build-dir")
.masquerade_as_nightly_cargo(&["build-dir"])
.enable_mac_dsym()
.run();
assert_build_dir_layout(p.root().join("build-dir"), "debug");
assert_exists_patterns_with_base_dir(
&p.root(),
&[
&format!("build-dir/debug/deps/foo*{EXE_SUFFIX}"),
"build-dir/debug/deps/foo*.d",
],
);
}
#[cargo_test]
fn cargo_doc_should_output_to_target_dir() {
let p = project()
.file("src/main.rs", r#"fn main() { println!("Hello, World!") }"#)
.file(
".cargo/config.toml",
r#"
[build]
target-dir = "target-dir"
build-dir = "build-dir"
"#,
)
.build();
p.cargo("doc -Z build-dir")
.masquerade_as_nightly_cargo(&["build-dir"])
.enable_mac_dsym()
.run();
let docs_dir = p.root().join("target-dir/doc");
assert_exists(&docs_dir);
assert_exists(&docs_dir.join("foo/index.html"));
}
#[cargo_test]
fn cargo_package_should_build_in_build_dir_and_output_to_target_dir() {
let p = project()
.file("src/main.rs", r#"fn main() { println!("Hello, World!") }"#)
.file(
".cargo/config.toml",
r#"
[build]
target-dir = "target-dir"
build-dir = "build-dir"
"#,
)
.build();
p.cargo("package -Z build-dir")
.masquerade_as_nightly_cargo(&["build-dir"])
.enable_mac_dsym()
.run();
assert_build_dir_layout(p.root().join("build-dir"), "debug");
let package_artifact_dir = p.root().join("target-dir/package");
assert_exists(&package_artifact_dir);
assert_exists(&package_artifact_dir.join("foo-0.0.1.crate"));
assert!(package_artifact_dir.join("foo-0.0.1.crate").is_file());
let package_build_dir = p.root().join("build-dir/package");
assert_exists(&package_build_dir);
assert_exists(&package_build_dir.join("foo-0.0.1"));
assert!(package_build_dir.join("foo-0.0.1").is_dir());
}
#[cargo_test]
fn cargo_clean_should_clean_the_target_dir_and_build_dir() {
let p = project()
.file("src/main.rs", r#"fn main() { println!("Hello, World!") }"#)
.file(
".cargo/config.toml",
r#"
[build]
target-dir = "target-dir"
build-dir = "build-dir"
"#,
)
.build();
p.cargo("build -Z build-dir")
.masquerade_as_nightly_cargo(&["build-dir"])
.enable_mac_dsym()
.run();
assert_build_dir_layout(p.root().join("build-dir"), "debug");
p.cargo("clean -Z build-dir")
.masquerade_as_nightly_cargo(&["build-dir"])
.enable_mac_dsym()
.run();
assert_not_exists(&p.root().join("build-dir"));
assert_not_exists(&p.root().join("target-dir"));
}
#[cargo_test]
fn timings_report_should_output_to_target_dir() {
let p = project()
.file("src/main.rs", r#"fn main() { println!("Hello, World!") }"#)
.file(
".cargo/config.toml",
r#"
[build]
target-dir = "target-dir"
build-dir = "build-dir"
"#,
)
.build();
p.cargo("build --timings -Z build-dir")
.masquerade_as_nightly_cargo(&["build-dir"])
.enable_mac_dsym()
.run();
assert_exists(&p.root().join("target-dir/cargo-timings/cargo-timing.html"));
}
#[cargo_test(
nightly,
reason = "-Zfuture-incompat-test requires nightly (permanently)"
)]
fn future_incompat_should_output_to_build_dir() {
let p = project()
.file("src/main.rs", r#"fn main() { let x = 1; }"#)
.file(
".cargo/config.toml",
r#"
[build]
target-dir = "target-dir"
build-dir = "build-dir"
"#,
)
.build();
p.cargo("build -Z build-dir")
.masquerade_as_nightly_cargo(&["build-dir"])
.arg("--future-incompat-report")
.env("RUSTFLAGS", "-Zfuture-incompat-test")
.run();
assert_exists(&p.root().join("build-dir/.future-incompat-report.json"));
}
#[cargo_test]
fn template_should_error_for_invalid_variables() {
let p = project()
.file("src/main.rs", r#"fn main() { println!("Hello, World!") }"#)
.file(
".cargo/config.toml",
r#"
[build]
build-dir = "{fake}/build-dir"
target-dir = "target-dir"
"#,
)
.build();
p.cargo("build -Z build-dir")
.masquerade_as_nightly_cargo(&["build-dir"])
.enable_mac_dsym()
.with_status(101)
.with_stderr_data(str![[r#"
[ERROR] unexpected variable `fake` in build.build-dir path `{fake}/build-dir`
[HELP] available template variables are `{workspace-root}`, `{cargo-cache-home}`, `{workspace-path-hash}`
"#]])
.run();
}
#[cargo_test]
fn template_should_suggest_nearest_variable() {
let p = project()
.file("src/lib.rs", "")
.file(
".cargo/config.toml",
r#"
[build]
build-dir = "{workspace-ro}/build-dir"
"#,
)
.build();
p.cargo("build -Z build-dir")
.masquerade_as_nightly_cargo(&["build-dir"])
.with_status(101)
.with_stderr_data(str![[r#"
[ERROR] unexpected variable `workspace-ro` in build.build-dir path `{workspace-ro}/build-dir`
[HELP] a template variable with a similar name exists: `workspace-root`
"#]])
.run();
}
#[cargo_test]
fn template_workspace_root() {
let p = project()
.file("src/main.rs", r#"fn main() { println!("Hello, World!") }"#)
.file(
".cargo/config.toml",
r#"
[build]
build-dir = "{workspace-root}/build-dir"
target-dir = "target-dir"
"#,
)
.build();
p.cargo("build -Z build-dir")
.masquerade_as_nightly_cargo(&["build-dir"])
.enable_mac_dsym()
.run();
assert_build_dir_layout(p.root().join("build-dir"), "debug");
assert_artifact_dir_layout(p.root().join("target-dir"), "debug");
// Verify the binary was uplifted to the target-dir
assert_exists(&p.root().join(&format!("target-dir/debug/foo{EXE_SUFFIX}")));
}
#[cargo_test]
fn template_cargo_cache_home() {
let p = project()
.file("src/main.rs", r#"fn main() { println!("Hello, World!") }"#)
.file(
".cargo/config.toml",
r#"
[build]
build-dir = "{cargo-cache-home}/build-dir"
target-dir = "target-dir"
"#,
)
.build();
p.cargo("build -Z build-dir")
.masquerade_as_nightly_cargo(&["build-dir"])
.enable_mac_dsym()
.run();
assert_build_dir_layout(paths::home().join(".cargo/build-dir"), "debug");
assert_artifact_dir_layout(p.root().join("target-dir"), "debug");
// Verify the binary was uplifted to the target-dir
assert_exists(&p.root().join(&format!("target-dir/debug/foo{EXE_SUFFIX}")));
}
#[cargo_test]
fn template_workspace_path_hash() {
let p = project()
.file("src/main.rs", r#"fn main() { println!("Hello, World!") }"#)
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "1.0.0"
authors = []
edition = "2015"
"#,
)
.file(
".cargo/config.toml",
r#"
[build]
build-dir = "foo/{workspace-path-hash}/build-dir"
target-dir = "target-dir"
"#,
)
.build();
p.cargo("build -Z build-dir")
.masquerade_as_nightly_cargo(&["build-dir"])
.enable_mac_dsym()
.run();
let foo_dir = p.root().join("foo");
assert_exists(&foo_dir);
let hash_dir = parse_workspace_manifest_path_hash(&foo_dir);
let build_dir = hash_dir.as_path().join("build-dir");
assert_build_dir_layout(build_dir, "debug");
assert_artifact_dir_layout(p.root().join("target-dir"), "debug");
// Verify the binary was uplifted to the target-dir
assert_exists(&p.root().join(&format!("target-dir/debug/foo{EXE_SUFFIX}")));
}
/// Verify that the {workspace-path-hash} does not changes if cargo is run from inside of
/// a symlinked directory.
/// The test approach is to build a project twice from the non-symlinked directory and a symlinked
/// directory and then compare the build-dir paths.
#[cargo_test]
fn template_workspace_path_hash_should_handle_symlink() {
#[cfg(unix)]
use std::os::unix::fs::symlink;
#[cfg(windows)]
use std::os::windows::fs::symlink_dir as symlink;
let p = project()
.file("src/lib.rs", "")
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "1.0.0"
authors = []
edition = "2015"
"#,
)
.file(
".cargo/config.toml",
r#"
[build]
build-dir = "foo/{workspace-path-hash}/build-dir"
"#,
)
.build();
// Build from the non-symlinked directory
p.cargo("check -Z build-dir")
.masquerade_as_nightly_cargo(&["build-dir"])
.enable_mac_dsym()
.run();
// Parse and verify the hash dir created from the non-symlinked dir
let foo_dir = p.root().join("foo");
assert_exists(&foo_dir);
let original_hash_dir = parse_workspace_manifest_path_hash(&foo_dir);
verify_layouts(&p, &original_hash_dir);
// Create a symlink of the project root.
let mut symlinked_dir = p.root().clone();
symlinked_dir.pop();
symlinked_dir = symlinked_dir.join("symlink-dir");
symlink(p.root(), &symlinked_dir).unwrap();
// Remove the foo dir (which contains the build-dir) before we rebuild from a symlinked dir.
foo_dir.rm_rf();
// Run cargo from the symlinked dir
p.cargo("check -Z build-dir")
.cwd(&symlinked_dir)
.masquerade_as_nightly_cargo(&["build-dir"])
.enable_mac_dsym()
.run();
// Parse and verify the hash created from the symlinked dir
assert_exists(&foo_dir);
let symlink_hash_dir = parse_workspace_manifest_path_hash(&foo_dir);
verify_layouts(&p, &symlink_hash_dir);
// Verify the hash dir created from the symlinked and non-symlinked dirs are the same.
assert_eq!(original_hash_dir, symlink_hash_dir);
fn verify_layouts(p: &Project, build_dir_parent: &PathBuf) {
let build_dir = build_dir_parent.as_path().join("build-dir");
assert_build_dir_layout(build_dir, "debug");
assert_artifact_dir_layout(p.root().join("target"), "debug");
}
}
#[cargo_test]
fn template_should_handle_reject_unmatched_brackets() {
let p = project()
.file("src/lib.rs", "")
.file(
".cargo/config.toml",
r#"
[build]
build-dir = "foo/{bar"
"#,
)
.build();
p.cargo("build -Z build-dir")
.masquerade_as_nightly_cargo(&["build-dir"])
.with_status(101)
.with_stderr_data(str![[r#"
[ERROR] unexpected opening bracket `{` in build.build-dir path `foo/{bar`
"#]])
.run();
let p = project()
.file("src/lib.rs", "")
.file(
".cargo/config.toml",
r#"
[build]
build-dir = "foo/}bar"
"#,
)
.build();
p.cargo("build -Z build-dir")
.masquerade_as_nightly_cargo(&["build-dir"])
.with_status(101)
.with_stderr_data(str![[r#"
[ERROR] unexpected closing bracket `}` in build.build-dir path `foo/}bar`
"#]])
.run();
}
fn parse_workspace_manifest_path_hash(hash_dir: &PathBuf) -> PathBuf {
// Since the hash will change between test runs simply find the first directories and assume
// that is the hash dir. The format is a 2 char directory followed by the remaining hash in the
// inner directory (ie. `34/f9d02eb8411c05`)
let mut dirs = std::fs::read_dir(hash_dir).unwrap().into_iter();
let outer_hash_dir = dirs.next().unwrap().unwrap();
// Validate there are no other directories in `hash_dir`
assert!(
dirs.next().is_none(),
"Found multiple dir entries in {hash_dir:?}"
);
// Validate the outer hash dir hash is a directory and has the correct hash length
assert!(
outer_hash_dir.path().is_dir(),
"{outer_hash_dir:?} was not a directory"
);
assert_eq!(
outer_hash_dir.path().file_name().unwrap().len(),
2,
"Path {:?} should have been 2 chars",
outer_hash_dir.path().file_name()
);
let mut dirs = std::fs::read_dir(outer_hash_dir.path())
.unwrap()
.into_iter();
let inner_hash_dir = dirs.next().unwrap().unwrap();
// Validate there are no other directories in first hash dir
assert!(
dirs.next().is_none(),
"Found multiple dir entries in {outer_hash_dir:?}"
);
// Validate the outer hash dir hash is a directory and has the correct hash length
assert!(
inner_hash_dir.path().is_dir(),
"{inner_hash_dir:?} was not a directory"
);
assert_eq!(
inner_hash_dir.path().file_name().unwrap().len(),
14,
"Path {:?} should have been 2 chars",
inner_hash_dir.path().file_name()
);
return inner_hash_dir.path();
}
#[track_caller]
fn assert_build_dir_layout(path: PathBuf, profile: &str) {
assert_dir_layout(path, profile, true);
}
#[allow(dead_code)]
#[track_caller]
fn assert_artifact_dir_layout(path: PathBuf, profile: &str) {
assert_dir_layout(path, profile, false);
}
#[track_caller]
fn assert_dir_layout(path: PathBuf, profile: &str, is_build_dir: bool) {
println!("checking if {path:?} is a build directory ({is_build_dir})");
// For things that are in both `target` and the build directory we only check if they are
// present if `is_build_dir` is true.
if is_build_dir {
assert_eq!(
is_build_dir,
path.join(profile).is_dir(),
"Expected {:?} to exist and be a directory",
path.join(profile)
);
}
let error_message = |dir: &str| {
if is_build_dir {
format!("`{dir}` dir was expected but not found")
} else {
format!("`{dir}` dir was not expected but was found")
}
};
if is_build_dir {
assert_exists(&path.join(".rustc_info.json"));
} else {
assert_not_exists(&path.join(".rustc_info.json"));
}
assert_eq!(
is_build_dir,
path.join(profile).join("deps").is_dir(),
"{}",
error_message("deps")
);
assert_eq!(
is_build_dir,
path.join(profile).join("build").is_dir(),
"{}",
error_message("build")
);
assert_eq!(
is_build_dir,
path.join(profile).join("incremental").is_dir(),
"{}",
error_message("incremental")
);
assert_eq!(
is_build_dir,
path.join(profile).join(".fingerprint").is_dir(),
"{}",
error_message(".fingerprint")
);
}
#[track_caller]
fn assert_exists(path: &PathBuf) {
assert!(
path.exists(),
"Expected `{}` to exist but was not found.",
path.display()
);
}
#[track_caller]
fn assert_not_exists(path: &PathBuf) {
assert!(
!path.exists(),
"Expected `{}` to NOT exist but was found.",
path.display()
);
}
#[track_caller]
fn assert_exists_patterns_with_base_dir(base: &PathBuf, patterns: &[&str]) {
let root = base.to_str().unwrap();
let p: Vec<_> = patterns.iter().map(|p| format!("{root}/{p}")).collect();
let p: Vec<&str> = p.iter().map(|v| v.as_str()).collect();
assert_exists_patterns(&p);
}
#[track_caller]
fn assert_exists_patterns(patterns: &[&str]) {
for p in patterns {
assert_exists_pattern(p);
}
}
#[track_caller]
fn assert_exists_pattern(pattern: &str) {
use glob::glob;
let mut z = glob(pattern).unwrap();
assert!(
z.next().is_some(),
"Expected `{pattern}` to match existing file but was not found.",
)
}