Files
core/test/dever-cli-tests/native_release/targets.rs
T

224 lines
7.4 KiB
Rust

use super::*;
use dever_cli::toolchain::runtime_pack::RuntimePack;
use dever_runtime::config::RuntimeProfile;
#[test]
#[cfg(target_arch = "x86_64")]
fn target_resource_namespaces_are_bound_to_the_signed_release_version() {
use dever_cli::toolchain::{
Artifact, Extension, ExtensionKind, ReleaseManifest, Version, validate_catalog,
};
let mut manifest = ReleaseManifest::new(
Version::parse("0.1.4").unwrap(),
vec![Artifact {
path: "dever-core".into(),
bytes: 1,
sha256: "0".repeat(64),
}],
);
manifest.extensions.push(Extension {
kind: ExtensionKind::Target,
target: BuildTarget::LinuxAarch64,
artifacts: vec![Artifact {
path: "sandbox/linux-aarch64/lib/libc.so.6".into(),
bytes: 1,
sha256: "0".repeat(64),
}],
});
validate_catalog(&manifest).unwrap();
manifest.version = Version::parse("0.1.5").unwrap();
assert!(
validate_catalog(&manifest)
.unwrap_err()
.contains("resource namespace")
);
manifest.extensions[0].artifacts[0].path = "process-runtime/linux-aarch64/lib/libc.so.6".into();
validate_catalog(&manifest).unwrap();
manifest.version = Version::parse("0.1.4").unwrap();
assert!(
validate_catalog(&manifest)
.unwrap_err()
.contains("resource namespace")
);
}
#[cfg(target_arch = "x86_64")]
pub(super) fn cross_author() -> Author {
let mut author = Author::new();
let target = BuildTarget::LinuxAarch64;
let input = |name: &str, bytes: Vec<u8>| {
let source = format!("inputs/arm-{name}");
fs::write(author.root.join(&source), bytes).unwrap();
json!({"source":source, "sha256":sha256_file(&author.root.join(source)).unwrap()})
};
let mut profiles = json!({});
for profile in ["base", "sqlite", "postgres", "both"] {
profiles[profile] = input(profile, native_objects::archive(target, profile));
}
let link = |name: &str, bytes| {
let mut artifact = input(name, bytes);
artifact["path"] = json!(name);
artifact
};
author.settings["native_targets"] = json!({"linux-aarch64": {
"profiles":profiles,
"start":[link("start.o", native_objects::object(target))],
"libraries":[link("system.a", native_objects::archive(target, "system.o"))],
"end":[link("end.o", native_objects::object(target))],
}});
author
}
#[test]
fn target_names_and_serde_are_exact() {
for (name, target, triple) in [
(
"linux-x86_64",
BuildTarget::LinuxX86_64,
"x86_64-unknown-linux-gnu",
),
(
"linux-aarch64",
BuildTarget::LinuxAarch64,
"aarch64-unknown-linux-gnu",
),
] {
assert_eq!(name.parse::<BuildTarget>().unwrap(), target);
assert_eq!(target.platform(), name);
assert_eq!(target.triple(), triple);
assert_eq!(
serde_json::to_string(&target).unwrap(),
format!("\"{name}\"")
);
}
for invalid in [
"",
"arm64",
"Linux-aarch64",
"linux-arm64",
"aarch64-unknown-linux-gnu",
"linux-aarch64 ",
] {
assert!(invalid.parse::<BuildTarget>().is_err());
assert!(serde_json::from_value::<BuildTarget>(json!(invalid)).is_err());
}
}
#[test]
#[cfg(target_arch = "x86_64")]
fn host_core_packages_both_native_targets_with_separate_profiles_and_signed_closures() {
let author = cross_author();
author.save();
let output = author.directory.path().join("cross-release");
let manifest = packaging::create(&author.root, &output).unwrap();
assert_eq!(manifest.platform, "linux-x86_64");
assert_signed(&author, &output);
for target in [BuildTarget::LinuxX86_64, BuildTarget::LinuxAarch64] {
let closure = runtime_pack::validate(&output, env!("CARGO_PKG_VERSION"), target).unwrap();
for input in closure {
assert!(
manifest
.artifacts
.iter()
.chain(
manifest
.extensions
.iter()
.flat_map(|extension| &extension.artifacts)
)
.any(|artifact| artifact.path == input.path
&& artifact.sha256 == input.sha256
&& artifact.bytes == input.bytes)
);
}
for profile in [
RuntimeProfile {
sqlite: false,
postgres: false,
},
RuntimeProfile {
sqlite: true,
postgres: false,
},
RuntimeProfile {
sqlite: false,
postgres: true,
},
RuntimeProfile {
sqlite: true,
postgres: true,
},
] {
assert_eq!(
RuntimePack::load(&output, profile, target).unwrap().target,
target
);
}
}
let profile = RuntimeProfile {
sqlite: false,
postgres: false,
};
let arm = RuntimePack::load(&output, profile, BuildTarget::LinuxAarch64).unwrap();
let host = RuntimePack::load(&output, profile, BuildTarget::LinuxX86_64).unwrap();
assert_ne!(arm.identity, host.identity);
fs::write(
output.join("runtime/linux-aarch64/archives/base.a"),
b"tampered",
)
.unwrap();
assert!(RuntimePack::load(&output, profile, BuildTarget::LinuxAarch64).is_err());
RuntimePack::load(&output, profile, BuildTarget::LinuxX86_64).unwrap();
}
#[test]
#[cfg(target_arch = "x86_64")]
fn target_packs_reject_wrong_architecture_and_duplicate_host_declarations() {
for (slot, source) in [
("/native_targets/linux-aarch64/start/0", "start.o"),
("/native_targets/linux-aarch64/profiles/base", "base"),
] {
let mut author = cross_author();
let replacement = if source.ends_with(".o") {
native_objects::object(BuildTarget::LinuxX86_64)
} else {
native_objects::archive(BuildTarget::LinuxX86_64, "wrong.o")
};
fs::write(
author.root.join(format!("inputs/arm-{source}")),
replacement,
)
.unwrap();
author.settings.pointer_mut(slot).unwrap()["sha256"] =
json!(sha256_file(&author.root.join(format!("inputs/arm-{source}"))).unwrap());
assert!(
author
.reject()
.contains("relocatable ELF object for linux-aarch64")
);
}
let mut author = cross_author();
author.settings["native_targets"]["linux-x86_64"] =
author.settings["native_targets"]["linux-aarch64"].clone();
assert!(author.reject().contains("duplicate release destination"));
}
#[test]
#[cfg(target_arch = "x86_64")]
fn missing_target_pack_never_uses_host_inputs() {
let author = Author::new();
author.save();
let output = author.directory.path().join("host-release");
packaging::create(&author.root, &output).unwrap();
let error = RuntimePack::load(
&output,
RuntimeProfile {
sqlite: false,
postgres: false,
},
BuildTarget::LinuxAarch64,
)
.err()
.unwrap();
assert!(error.contains("linux-aarch64"), "{error}");
}