874b6f20c2
Основа — Horizon (MIT). История апстрима не переносится: этот репозиторий ведёт свою.
146 lines
5.4 KiB
Rust
146 lines
5.4 KiB
Rust
//! Each scenario runs in its own process so Java discovery sees a controlled environment.
|
|
use horizon_prepare::java;
|
|
use std::{env, fs, path::Path, process::Command};
|
|
|
|
const TEST: &str = "selects_a_compatible_compiler_and_runtime";
|
|
const CHILD: &str = "HORIZON_JAVA_SELECTION_CHILD";
|
|
const ROOT: &str = "HORIZON_JAVA_SELECTION_ROOT";
|
|
|
|
fn tool(bin: &Path, name: &str) -> std::path::PathBuf {
|
|
bin.join(format!("{name}{}", env::consts::EXE_SUFFIX))
|
|
}
|
|
|
|
#[test]
|
|
fn selects_a_compatible_compiler_and_runtime() {
|
|
if let Ok(scenario) = env::var(CHILD) {
|
|
let root = std::path::PathBuf::from(env::var_os(ROOT).unwrap());
|
|
if scenario.ends_with("error") {
|
|
// Use a future compiler version to keep real installed JDKs out of the result.
|
|
let error = java::find(255, &[]).err().expect("accepted an old runtime");
|
|
let runtime = if scenario == "legacy-runtime-error" {
|
|
8
|
|
} else {
|
|
21
|
|
};
|
|
assert!(error.contains(&format!("java {runtime} (")), "{error}");
|
|
return;
|
|
}
|
|
let jdk = if scenario == "runtime-only" {
|
|
java::find_runtime(25, &[])
|
|
} else {
|
|
java::find(25, &[])
|
|
}
|
|
.unwrap();
|
|
let expected = root.join(if scenario == "runtime-only" {
|
|
"jre25"
|
|
} else if scenario == "target-release" {
|
|
"newer"
|
|
} else {
|
|
"jdk25"
|
|
});
|
|
for (actual, name) in [(&jdk.javac, "javac"), (&jdk.java, "java")] {
|
|
if scenario == "runtime-only" && name == "javac" {
|
|
continue;
|
|
}
|
|
assert_eq!(
|
|
fs::canonicalize(actual).unwrap(),
|
|
fs::canonicalize(tool(&expected.join("bin"), name)).unwrap()
|
|
);
|
|
}
|
|
assert_eq!(
|
|
fs::canonicalize(jdk.home()).unwrap(),
|
|
fs::canonicalize(expected).unwrap()
|
|
);
|
|
let log_path = root.join(format!("{scenario}.log"));
|
|
let log = fs::File::create(&log_path).unwrap();
|
|
jdk.java(&[], None, &log).unwrap();
|
|
assert_eq!(fs::read_to_string(log_path).unwrap().trim(), "java 25.0.1");
|
|
return;
|
|
}
|
|
|
|
let root = env::temp_dir().join(format!("horizon-java-selection-{}", std::process::id()));
|
|
fs::create_dir_all(&root).unwrap();
|
|
let probe = tool(&root, "probe");
|
|
let output = Command::new("rustc")
|
|
.arg(Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/support/java_probe.rs"))
|
|
.arg("-o")
|
|
.arg(&probe)
|
|
.output()
|
|
.unwrap();
|
|
assert!(
|
|
output.status.success(),
|
|
"{}",
|
|
String::from_utf8_lossy(&output.stderr)
|
|
);
|
|
for (home, compiler, runtime) in [
|
|
("jre21", None, "21.0.1"),
|
|
("jre25", None, "25.0.1"),
|
|
("jdk21", Some("21.0.1"), "21.0.1"),
|
|
("jdk25", Some("25.0.1"), "25.0.1"),
|
|
("mixed", Some("25.0.1"), "21.0.1"),
|
|
("failing", Some("25.0.1"), "25.0.1"),
|
|
("newer", Some("26-ea+1"), "25.0.1"),
|
|
("future", Some("255.0.1"), "21.0.1"),
|
|
("legacy", Some("255.0.1"), "1.8.0_442"),
|
|
] {
|
|
let bin = root.join(home).join("bin");
|
|
fs::create_dir_all(&bin).unwrap();
|
|
for (name, version) in [("javac", compiler), ("java", Some(runtime))] {
|
|
if let Some(version) = version {
|
|
fs::copy(&probe, tool(&bin, name)).unwrap();
|
|
fs::write(bin.join(format!("{name}.version")), version).unwrap();
|
|
}
|
|
}
|
|
}
|
|
fs::write(root.join("failing/bin/java.exit"), "7").unwrap();
|
|
let scenarios = vec![
|
|
("runtime-only", Some("jre25"), vec!["jre21", "jre25"]),
|
|
("older-runtime", None, vec!["jre21", "jdk25"]),
|
|
("older-jdk", None, vec!["jdk21", "jdk25"]),
|
|
("incompatible-home", Some("mixed"), vec!["jdk25"]),
|
|
("failed-runtime", Some("failing"), vec!["jdk25"]),
|
|
("target-release", Some("newer"), vec![]),
|
|
("runtime-error", Some("future"), vec![]),
|
|
("legacy-runtime-error", Some("legacy"), vec![]),
|
|
];
|
|
#[cfg(unix)]
|
|
let scenarios = {
|
|
let mut scenarios = scenarios;
|
|
let bin = root.join("shims/bin");
|
|
fs::create_dir_all(&bin).unwrap();
|
|
std::os::unix::fs::symlink(tool(&root.join("jdk25/bin"), "javac"), tool(&bin, "javac"))
|
|
.unwrap();
|
|
std::os::unix::fs::symlink(tool(&root.join("jre21/bin"), "java"), tool(&bin, "java"))
|
|
.unwrap();
|
|
scenarios.push(("symlinked-path", None, vec!["shims"]));
|
|
scenarios
|
|
};
|
|
for (scenario, home, path) in scenarios {
|
|
let mut child = Command::new(env::current_exe().unwrap());
|
|
child
|
|
.args(["--exact", TEST, "--nocapture"])
|
|
.env(CHILD, scenario)
|
|
.env(ROOT, &root)
|
|
.env(
|
|
"PATH",
|
|
env::join_paths(path.iter().map(|home| root.join(home).join("bin"))).unwrap(),
|
|
)
|
|
.env("HOME", &root)
|
|
.env("USERPROFILE", &root)
|
|
.env("ProgramFiles", &root)
|
|
.env("ProgramW6432", &root)
|
|
.env_remove("JAVA_HOME");
|
|
if let Some(home) = home {
|
|
child.env("JAVA_HOME", root.join(home));
|
|
}
|
|
let output = child.output().unwrap();
|
|
assert!(
|
|
output.status.success(),
|
|
"{scenario}:\n{}\n{}",
|
|
String::from_utf8_lossy(&output.stdout),
|
|
String::from_utf8_lossy(&output.stderr)
|
|
);
|
|
}
|
|
fs::remove_dir_all(root).unwrap();
|
|
}
|