summaryrefslogtreecommitdiffstats
path: root/vendor/ui_test/src/config.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/ui_test/src/config.rs')
-rw-r--r--vendor/ui_test/src/config.rs196
1 files changed, 196 insertions, 0 deletions
diff --git a/vendor/ui_test/src/config.rs b/vendor/ui_test/src/config.rs
new file mode 100644
index 000000000..6f24cce90
--- /dev/null
+++ b/vendor/ui_test/src/config.rs
@@ -0,0 +1,196 @@
+use regex::bytes::Regex;
+
+use crate::{dependencies::build_dependencies, CommandBuilder, Filter, Match, Mode};
+pub use color_eyre;
+use color_eyre::eyre::Result;
+use std::{
+ ffi::OsString,
+ num::NonZeroUsize,
+ path::{Path, PathBuf},
+};
+
+#[derive(Debug, Clone)]
+/// Central datastructure containing all information to run the tests.
+pub struct Config {
+ /// Arguments passed to the binary that is executed.
+ /// These arguments are passed *after* the args inserted via `//@compile-flags:`.
+ pub trailing_args: Vec<OsString>,
+ /// Host triple; usually will be auto-detected.
+ pub host: Option<String>,
+ /// `None` to run on the host, otherwise a target triple
+ pub target: Option<String>,
+ /// Filters applied to stderr output before processing it.
+ /// By default contains a filter for replacing backslashes with regular slashes.
+ /// On windows, contains a filter to replace `\n` with `\r\n`.
+ pub stderr_filters: Filter,
+ /// Filters applied to stdout output before processing it.
+ /// On windows, contains a filter to replace `\n` with `\r\n`.
+ pub stdout_filters: Filter,
+ /// The folder in which to start searching for .rs files
+ pub root_dir: PathBuf,
+ /// The mode in which to run the tests.
+ pub mode: Mode,
+ /// The binary to actually execute.
+ pub program: CommandBuilder,
+ /// The command to run to obtain the cfgs that the output is supposed to
+ pub cfgs: CommandBuilder,
+ /// What to do in case the stdout/stderr output differs from the expected one.
+ /// By default, errors in case of conflict, but emits a message informing the user
+ /// that running `cargo test -- -- --bless` will automatically overwrite the
+ /// `.stdout` and `.stderr` files with the latest output.
+ pub output_conflict_handling: OutputConflictHandling,
+ /// Path to a `Cargo.toml` that describes which dependencies the tests can access.
+ pub dependencies_crate_manifest_path: Option<PathBuf>,
+ /// The command to run can be changed from `cargo` to any custom command to build the
+ /// dependencies in `dependencies_crate_manifest_path`
+ pub dependency_builder: CommandBuilder,
+ /// How many threads to use for running tests. Defaults to number of cores
+ pub num_test_threads: NonZeroUsize,
+ /// Where to dump files like the binaries compiled from tests.
+ /// Defaults to `target/ui` in the current directory.
+ pub out_dir: PathBuf,
+ /// The default edition to use on all tests
+ pub edition: Option<String>,
+}
+
+impl Config {
+ /// Create a configuration for testing the output of running
+ /// `rustc` on the test files.
+ pub fn rustc(root_dir: PathBuf) -> Self {
+ Self {
+ trailing_args: vec![],
+ host: None,
+ target: None,
+ stderr_filters: vec![
+ (Match::Exact(vec![b'\\']), b"/"),
+ #[cfg(windows)]
+ (Match::Exact(vec![b'\r']), b""),
+ ],
+ stdout_filters: vec![
+ #[cfg(windows)]
+ (Match::Exact(vec![b'\r']), b""),
+ ],
+ root_dir,
+ mode: Mode::Fail {
+ require_patterns: true,
+ },
+ program: CommandBuilder::rustc(),
+ cfgs: CommandBuilder::cfgs(),
+ output_conflict_handling: OutputConflictHandling::Error(
+ "cargo test -- -- --bless".into(),
+ ),
+ dependencies_crate_manifest_path: None,
+ dependency_builder: CommandBuilder::cargo(),
+ num_test_threads: std::thread::available_parallelism().unwrap(),
+ out_dir: std::env::current_dir().unwrap().join("target/ui"),
+ edition: Some("2021".into()),
+ }
+ }
+
+ /// Create a configuration for testing the output of running
+ /// `cargo` on the test `Cargo.toml` files.
+ pub fn cargo(root_dir: PathBuf) -> Self {
+ Self {
+ program: CommandBuilder::cargo(),
+ edition: None,
+ ..Self::rustc(root_dir)
+ }
+ }
+
+ /// Replace all occurrences of a path in stderr with a byte string.
+ pub fn path_stderr_filter(
+ &mut self,
+ path: &Path,
+ replacement: &'static (impl AsRef<[u8]> + ?Sized),
+ ) {
+ let pattern = path.canonicalize().unwrap();
+ self.stderr_filters
+ .push((pattern.parent().unwrap().into(), replacement.as_ref()));
+ }
+
+ /// Replace all occurrences of a regex pattern in stderr with a byte string.
+ pub fn stderr_filter(
+ &mut self,
+ pattern: &str,
+ replacement: &'static (impl AsRef<[u8]> + ?Sized),
+ ) {
+ self.stderr_filters
+ .push((Regex::new(pattern).unwrap().into(), replacement.as_ref()));
+ }
+
+ /// Replace all occurrences of a regex pattern in stdout with a byte string.
+ pub fn stdout_filter(
+ &mut self,
+ pattern: &str,
+ replacement: &'static (impl AsRef<[u8]> + ?Sized),
+ ) {
+ self.stdout_filters
+ .push((Regex::new(pattern).unwrap().into(), replacement.as_ref()));
+ }
+
+ pub(crate) fn build_dependencies_and_link_them(&mut self) -> Result<()> {
+ let dependencies = build_dependencies(self)?;
+ for (name, artifacts) in dependencies.dependencies {
+ for dependency in artifacts {
+ self.program.args.push("--extern".into());
+ let mut dep = OsString::from(&name);
+ dep.push("=");
+ dep.push(dependency);
+ self.program.args.push(dep);
+ }
+ }
+ for import_path in dependencies.import_paths {
+ self.program.args.push("-L".into());
+ self.program.args.push(import_path.into());
+ }
+ Ok(())
+ }
+
+ /// Make sure we have the host and target triples.
+ pub fn fill_host_and_target(&mut self) -> Result<()> {
+ if self.host.is_none() {
+ self.host = Some(
+ rustc_version::VersionMeta::for_command(std::process::Command::new(
+ &self.program.program,
+ ))
+ .map_err(|err| {
+ color_eyre::eyre::Report::new(err).wrap_err(format!(
+ "failed to parse rustc version info: {}",
+ self.program.display()
+ ))
+ })?
+ .host,
+ );
+ }
+ if self.target.is_none() {
+ self.target = Some(self.host.clone().unwrap());
+ }
+ Ok(())
+ }
+
+ pub(crate) fn has_asm_support(&self) -> bool {
+ static ASM_SUPPORTED_ARCHS: &[&str] = &[
+ "x86", "x86_64", "arm", "aarch64", "riscv32",
+ "riscv64",
+ // These targets require an additional asm_experimental_arch feature.
+ // "nvptx64", "hexagon", "mips", "mips64", "spirv", "wasm32",
+ ];
+ ASM_SUPPORTED_ARCHS
+ .iter()
+ .any(|arch| self.target.as_ref().unwrap().contains(arch))
+ }
+}
+
+#[derive(Debug, Clone)]
+/// The different options for what to do when stdout/stderr files differ from the actual output.
+pub enum OutputConflictHandling {
+ /// The default: emit a diff of the expected/actual output.
+ ///
+ /// The string should be a command that can be executed to bless all tests.
+ Error(String),
+ /// Ignore mismatches in the stderr/stdout files.
+ Ignore,
+ /// Instead of erroring if the stderr/stdout differs from the expected
+ /// automatically replace it with the found output (after applying filters).
+ Bless,
+}