summaryrefslogtreecommitdiffstats
path: root/src/tools/rustdoc-gui-test
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
commit9835e2ae736235810b4ea1c162ca5e65c547e770 (patch)
tree3fcebf40ed70e581d776a8a4c65923e8ec20e026 /src/tools/rustdoc-gui-test
parentReleasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff)
downloadrustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz
rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/tools/rustdoc-gui-test')
-rw-r--r--src/tools/rustdoc-gui-test/Cargo.toml9
-rw-r--r--src/tools/rustdoc-gui-test/src/config.rs62
-rw-r--r--src/tools/rustdoc-gui-test/src/main.rs162
3 files changed, 233 insertions, 0 deletions
diff --git a/src/tools/rustdoc-gui-test/Cargo.toml b/src/tools/rustdoc-gui-test/Cargo.toml
new file mode 100644
index 000000000..f0c5b3671
--- /dev/null
+++ b/src/tools/rustdoc-gui-test/Cargo.toml
@@ -0,0 +1,9 @@
+[package]
+name = "rustdoc-gui-test"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+compiletest = { path = "../compiletest" }
+getopts = "0.2"
+walkdir = "2"
diff --git a/src/tools/rustdoc-gui-test/src/config.rs b/src/tools/rustdoc-gui-test/src/config.rs
new file mode 100644
index 000000000..dc4c56a5e
--- /dev/null
+++ b/src/tools/rustdoc-gui-test/src/config.rs
@@ -0,0 +1,62 @@
+use getopts::Options;
+use std::{env, path::PathBuf};
+
+pub(crate) struct Config {
+ pub(crate) nodejs: PathBuf,
+ pub(crate) npm: PathBuf,
+ pub(crate) rust_src: PathBuf,
+ pub(crate) out_dir: PathBuf,
+ pub(crate) initial_cargo: PathBuf,
+ pub(crate) jobs: String,
+ pub(crate) test_args: Vec<PathBuf>,
+ pub(crate) goml_files: Vec<PathBuf>,
+ pub(crate) rustc: PathBuf,
+ pub(crate) rustdoc: PathBuf,
+ pub(crate) verbose: bool,
+}
+
+impl Config {
+ pub(crate) fn from_args(args: Vec<String>) -> Self {
+ let mut opts = Options::new();
+ opts.reqopt("", "nodejs", "absolute path of nodejs", "PATH")
+ .reqopt("", "npm", "absolute path of npm", "PATH")
+ .reqopt("", "out-dir", "output path of doc compilation", "PATH")
+ .reqopt("", "rust-src", "root source of the rust source", "PATH")
+ .reqopt(
+ "",
+ "initial-cargo",
+ "path to cargo to use for compiling tests/rustdoc-gui/src/*",
+ "PATH",
+ )
+ .reqopt("", "jobs", "jobs arg of browser-ui-test", "JOBS")
+ .optflag("", "verbose", "run tests verbosely, showing all output")
+ .optmulti("", "test-arg", "args for browser-ui-test", "FLAGS")
+ .optmulti("", "goml-file", "goml files for testing with browser-ui-test", "LIST");
+
+ let (argv0, args_) = args.split_first().unwrap();
+ if args.len() == 1 || args[1] == "-h" || args[1] == "--help" {
+ let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0);
+ println!("{}", opts.usage(&message));
+ std::process::exit(1);
+ }
+
+ let matches = &match opts.parse(args_) {
+ Ok(m) => m,
+ Err(f) => panic!("{:?}", f),
+ };
+
+ Self {
+ nodejs: matches.opt_str("nodejs").map(PathBuf::from).expect("nodejs isn't available"),
+ npm: matches.opt_str("npm").map(PathBuf::from).expect("npm isn't available"),
+ rust_src: matches.opt_str("rust-src").map(PathBuf::from).unwrap(),
+ out_dir: matches.opt_str("out-dir").map(PathBuf::from).unwrap(),
+ initial_cargo: matches.opt_str("initial-cargo").map(PathBuf::from).unwrap(),
+ jobs: matches.opt_str("jobs").unwrap(),
+ goml_files: matches.opt_strs("goml-file").iter().map(PathBuf::from).collect(),
+ test_args: matches.opt_strs("test-arg").iter().map(PathBuf::from).collect(),
+ rustc: env::var("RUSTC").map(PathBuf::from).unwrap(),
+ rustdoc: env::var("RUSTDOC").map(PathBuf::from).unwrap(),
+ verbose: matches.opt_present("verbose"),
+ }
+ }
+}
diff --git a/src/tools/rustdoc-gui-test/src/main.rs b/src/tools/rustdoc-gui-test/src/main.rs
new file mode 100644
index 000000000..8dc18dfae
--- /dev/null
+++ b/src/tools/rustdoc-gui-test/src/main.rs
@@ -0,0 +1,162 @@
+use compiletest::header::TestProps;
+use config::Config;
+use std::path::{Path, PathBuf};
+use std::process::Command;
+use std::sync::Arc;
+use std::{env, fs};
+
+mod config;
+
+fn get_browser_ui_test_version_inner(npm: &Path, global: bool) -> Option<String> {
+ let mut command = Command::new(&npm);
+ command.arg("list").arg("--parseable").arg("--long").arg("--depth=0");
+ if global {
+ command.arg("--global");
+ }
+ let lines = command
+ .output()
+ .map(|output| String::from_utf8_lossy(&output.stdout).into_owned())
+ .unwrap_or(String::new());
+ lines
+ .lines()
+ .find_map(|l| l.split(':').nth(1)?.strip_prefix("browser-ui-test@"))
+ .map(|v| v.to_owned())
+}
+
+fn get_browser_ui_test_version(npm: &Path) -> Option<String> {
+ get_browser_ui_test_version_inner(npm, false)
+ .or_else(|| get_browser_ui_test_version_inner(npm, true))
+}
+
+fn compare_browser_ui_test_version(installed_version: &str, src: &Path) {
+ match fs::read_to_string(
+ src.join("src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version"),
+ ) {
+ Ok(v) => {
+ if v.trim() != installed_version {
+ eprintln!(
+ "⚠️ Installed version of browser-ui-test (`{}`) is different than the \
+ one used in the CI (`{}`)",
+ installed_version, v
+ );
+ eprintln!(
+ "You can install this version using `npm update browser-ui-test` or by using \
+ `npm install browser-ui-test@{}`",
+ v,
+ );
+ }
+ }
+ Err(e) => eprintln!("Couldn't find the CI browser-ui-test version: {:?}", e),
+ }
+}
+
+fn find_librs<P: AsRef<Path>>(path: P) -> Option<PathBuf> {
+ for entry in walkdir::WalkDir::new(path) {
+ let entry = entry.ok()?;
+ if entry.file_type().is_file() && entry.file_name() == "lib.rs" {
+ return Some(entry.path().to_path_buf());
+ }
+ }
+ None
+}
+
+// FIXME: move `bootstrap::util::try_run` into `build_helper` crate
+// and use that one instead of creating this function.
+fn try_run(cmd: &mut Command, print_cmd_on_fail: bool) -> bool {
+ let status = match cmd.status() {
+ Ok(status) => status,
+ Err(e) => panic!("failed to execute command: {:?}\nerror: {}", cmd, e),
+ };
+ if !status.success() && print_cmd_on_fail {
+ println!(
+ "\n\ncommand did not execute successfully: {:?}\n\
+ expected success, got: {}\n\n",
+ cmd, status
+ );
+ }
+ status.success()
+}
+
+fn main() {
+ let config = Arc::new(Config::from_args(env::args().collect()));
+
+ // The goal here is to check if the necessary packages are installed, and if not, we
+ // panic.
+ match get_browser_ui_test_version(&config.npm) {
+ Some(version) => {
+ // We also check the version currently used in CI and emit a warning if it's not the
+ // same one.
+ compare_browser_ui_test_version(&version, &config.rust_src);
+ }
+ None => {
+ eprintln!(
+ r#"
+error: rustdoc-gui test suite cannot be run because npm `browser-ui-test` dependency is missing.
+
+If you want to install the `browser-ui-test` dependency, run `npm install browser-ui-test`
+"#,
+ );
+
+ panic!("Cannot run rustdoc-gui tests");
+ }
+ }
+
+ let src_path = config.rust_src.join("tests/rustdoc-gui/src");
+ for entry in src_path.read_dir().expect("read_dir call failed") {
+ if let Ok(entry) = entry {
+ let path = entry.path();
+
+ if !path.is_dir() {
+ continue;
+ }
+
+ let mut cargo = Command::new(&config.initial_cargo);
+ cargo
+ .arg("doc")
+ .arg("--target-dir")
+ .arg(&config.out_dir)
+ .env("RUSTC_BOOTSTRAP", "1")
+ .env("RUSTDOC", &config.rustdoc)
+ .env("RUSTC", &config.rustc)
+ .current_dir(path);
+
+ if let Some(librs) = find_librs(entry.path()) {
+ let compiletest_c = compiletest::common::Config {
+ edition: None,
+ mode: compiletest::common::Mode::Rustdoc,
+ ..Default::default()
+ };
+
+ let test_props = TestProps::from_file(&librs, None, &compiletest_c);
+
+ if !test_props.compile_flags.is_empty() {
+ cargo.env("RUSTDOCFLAGS", test_props.compile_flags.join(" "));
+ }
+
+ if let Some(flags) = &test_props.run_flags {
+ cargo.arg(flags);
+ }
+ }
+
+ try_run(&mut cargo, config.verbose);
+ }
+ }
+
+ let mut command = Command::new(&config.nodejs);
+ command
+ .arg(config.rust_src.join("src/tools/rustdoc-gui/tester.js"))
+ .arg("--jobs")
+ .arg(&config.jobs)
+ .arg("--doc-folder")
+ .arg(config.out_dir.join("doc"))
+ .arg("--tests-folder")
+ .arg(config.rust_src.join("tests/rustdoc-gui"));
+
+ for file in &config.goml_files {
+ command.arg("--file").arg(file);
+ }
+
+ command.args(&config.test_args);
+
+ try_run(&mut command, config.verbose);
+}