use crate::{
cargo_config::{CargoConfigs, TargetDefinitionLocation, TargetTriple, TargetTripleSource},
config::elements::{CustomTestGroup, TestGroup},
platform::{BuildPlatforms, HostPlatform, PlatformLibdir, TargetPlatform},
};
use camino::{Utf8Path, Utf8PathBuf};
use camino_tempfile::Utf8TempDir;
use camino_tempfile_ext::prelude::*;
use guppy::{
PackageId,
graph::{PackageGraph, cargo::BuildPlatform},
};
use nextest_filtering::BinaryQuery;
use nextest_metadata::{RustBinaryId, RustTestBinaryKind};
use serde::Deserialize;
use target_spec::{Platform, TargetFeatures};
pub(in crate::config) fn temp_workspace(
temp_dir: &Utf8TempDir,
config_contents: &str,
) -> PackageGraph {
temp_dir
.child(".config/nextest.toml")
.write_str(config_contents)
.expect("error writing config file");
PackageGraph::from_json(single_package_metadata(temp_dir.path()).to_string())
.expect("error creating package graph")
}
fn single_package_metadata(workspace_root: &Utf8Path) -> serde_json::Value {
let package_id = "path+file:///test-package#test-package@0.1.0";
let target_dir = workspace_root.join("target");
serde_json::json!({
"packages": [{
"name": "test-package",
"version": "0.1.0",
"id": package_id,
"license": null,
"license_file": null,
"description": null,
"source": null,
"dependencies": [],
"targets": [{
"kind": ["lib"],
"crate_types": ["lib"],
"name": "test_package",
"src_path": workspace_root.join("src").join("lib.rs"),
"edition": "2024",
"doc": true,
"doctest": true,
"test": true,
}],
"features": {},
"manifest_path": workspace_root.join("Cargo.toml"),
"metadata": null,
"publish": null,
"authors": [],
"categories": [],
"keywords": [],
"readme": null,
"repository": null,
"homepage": null,
"documentation": null,
"edition": "2024",
"links": null,
"default_run": null,
"rust_version": null,
}],
"workspace_members": [package_id],
"workspace_default_members": [package_id],
"resolve": {
"nodes": [{
"id": package_id,
"dependencies": [],
"deps": [],
"features": [],
}],
"root": package_id,
},
"target_directory": target_dir,
"build_directory": target_dir,
"version": 1,
"workspace_root": workspace_root,
"metadata": null,
})
}
pub(in crate::config) struct BinaryQueryCreator<'a> {
package_id: &'a PackageId,
binary_id: RustBinaryId,
kind: RustTestBinaryKind,
binary_name: &'a str,
platform: BuildPlatform,
}
#[derive(Clone, Copy, Debug)]
pub(in crate::config) enum ConfigErrorKind {
NotFound,
Message,
}
impl BinaryQueryCreator<'_> {
pub(in crate::config) fn to_query(&self) -> BinaryQuery<'_> {
BinaryQuery {
package_id: self.package_id,
binary_id: &self.binary_id,
kind: &self.kind,
binary_name: self.binary_name,
platform: self.platform,
}
}
}
pub(in crate::config) fn binary_query<'a>(
graph: &'a PackageGraph,
package_id: &'a PackageId,
kind: &str,
binary_name: &'a str,
platform: BuildPlatform,
) -> BinaryQueryCreator<'a> {
let package_name = graph.metadata(package_id).unwrap().name();
let kind = RustTestBinaryKind::new(kind.to_owned());
let binary_id = RustBinaryId::from_parts(package_name, &kind, binary_name);
BinaryQueryCreator {
package_id,
binary_id,
kind,
binary_name,
platform,
}
}
pub(in crate::config) fn build_platforms() -> BuildPlatforms {
BuildPlatforms {
host: HostPlatform {
platform: Platform::new("x86_64-unknown-linux-gnu", TargetFeatures::Unknown).unwrap(),
libdir: PlatformLibdir::Available(Utf8PathBuf::from(
"/home/fake/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib",
)),
},
target: Some(TargetPlatform {
triple: TargetTriple {
platform: Platform::new("aarch64-apple-darwin", TargetFeatures::Unknown).unwrap(),
source: TargetTripleSource::Env,
location: TargetDefinitionLocation::Builtin,
},
libdir: PlatformLibdir::Available(Utf8PathBuf::from(
"/home/fake/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/aarch64-apple-darwin/lib",
)),
}),
}
}
pub(in crate::config) fn custom_build_platforms(workspace_dir: &Utf8Path) -> BuildPlatforms {
let configs = CargoConfigs::new_with_isolation(
Vec::<String>::new(),
workspace_dir,
workspace_dir,
Vec::new(),
)
.unwrap();
let host_platform = Platform::new("x86_64-unknown-linux-gnu", TargetFeatures::Unknown).unwrap();
let fixture = Utf8PathBuf::from(
std::env::var("NEXTEST_WORKSPACE_ROOT")
.expect("NEXTEST_WORKSPACE_ROOT is set (running under cargo nextest run)"),
)
.join("fixtures/custom-target/my-target.json");
let triple = TargetTriple::find(&configs, Some(fixture.as_str()), &host_platform)
.expect("custom platform parsed")
.expect("custom platform found");
assert!(
triple.platform.is_custom(),
"returned triple should be custom (was: {triple:?}"
);
assert_eq!(
triple.platform.triple_str(),
"my-target",
"triple_str matches"
);
let host = HostPlatform {
platform: host_platform,
libdir: PlatformLibdir::Available(Utf8PathBuf::from(
"/home/fake/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib",
)),
};
let target = TargetPlatform {
triple,
libdir: PlatformLibdir::Available(Utf8PathBuf::from(
"/home/fake/.rustup/toolchains/my-target/lib/rustlib/my-target/lib",
)),
};
BuildPlatforms {
host,
target: Some(target),
}
}
pub(in crate::config) fn test_group(name: &str) -> TestGroup {
TestGroup::Custom(custom_test_group(name))
}
pub(in crate::config) fn custom_test_group(name: &str) -> CustomTestGroup {
CustomTestGroup::new(name.into())
.unwrap_or_else(|error| panic!("invalid custom test group {name}: {error}"))
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq)]
pub(in crate::config) struct MietteJsonReport {
pub(in crate::config) message: String,
pub(in crate::config) labels: Vec<MietteJsonLabel>,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq)]
pub(in crate::config) struct MietteJsonLabel {
pub(in crate::config) label: String,
pub(in crate::config) span: MietteJsonSpan,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq)]
pub(in crate::config) struct MietteJsonSpan {
pub(in crate::config) offset: usize,
pub(in crate::config) length: usize,
}