765 lines
23 KiB
Rust
765 lines
23 KiB
Rust
use super::*;
|
|
|
|
#[test]
|
|
fn build_env_rootfs_uses_selected_non_live_rootfs() {
|
|
let tmp = tempfile::tempdir().unwrap();
|
|
let expected = tmp.path().canonicalize().unwrap();
|
|
|
|
assert_eq!(
|
|
build_cmd::build_env_rootfs(tmp.path()),
|
|
expected.to_string_lossy()
|
|
);
|
|
assert_eq!(build_cmd::build_env_rootfs(Path::new("/")), "/");
|
|
}
|
|
|
|
#[test]
|
|
fn clean_build_workspace_removes_build_and_source_cache_dirs() -> Result<()> {
|
|
let rootfs = tempfile::tempdir().context("Failed to create temp rootfs")?;
|
|
let mut cfg = config::Config::for_rootfs(rootfs.path());
|
|
cfg.build_dir = rootfs.path().join("tmp/build");
|
|
cfg.cache_dir = rootfs.path().join("tmp/sources");
|
|
|
|
fs::create_dir_all(&cfg.build_dir)
|
|
.with_context(|| format!("Failed to create {}", cfg.build_dir.display()))?;
|
|
fs::create_dir_all(&cfg.cache_dir)
|
|
.with_context(|| format!("Failed to create {}", cfg.cache_dir.display()))?;
|
|
|
|
let mut build_file = fs::File::create(cfg.build_dir.join("artifact.txt"))?;
|
|
build_file.write_all(b"build data")?;
|
|
build_file.flush()?;
|
|
|
|
let mut source_file = fs::File::create(cfg.cache_dir.join("source.tar.zst"))?;
|
|
source_file.write_all(b"source data")?;
|
|
source_file.flush()?;
|
|
|
|
clean_build_workspace(&cfg)?;
|
|
|
|
assert!(!cfg.build_dir.exists());
|
|
assert!(!cfg.cache_dir.exists());
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn clean_build_workspace_noops_when_dirs_are_missing() -> Result<()> {
|
|
let rootfs = tempfile::tempdir().context("Failed to create temp rootfs")?;
|
|
let mut cfg = config::Config::for_rootfs(rootfs.path());
|
|
cfg.build_dir = rootfs.path().join("tmp/build");
|
|
cfg.cache_dir = rootfs.path().join("tmp/sources");
|
|
|
|
clean_build_workspace(&cfg)?;
|
|
|
|
assert!(!cfg.build_dir.exists());
|
|
assert!(!cfg.cache_dir.exists());
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn clean_build_source_dirs_removes_build_dir_only() -> Result<()> {
|
|
let rootfs = tempfile::tempdir().context("Failed to create temp rootfs")?;
|
|
let mut cfg = config::Config::for_rootfs(rootfs.path());
|
|
cfg.build_dir = rootfs.path().join("tmp/build");
|
|
cfg.cache_dir = rootfs.path().join("tmp/sources");
|
|
|
|
fs::create_dir_all(&cfg.build_dir)
|
|
.with_context(|| format!("Failed to create {}", cfg.build_dir.display()))?;
|
|
fs::create_dir_all(&cfg.cache_dir)
|
|
.with_context(|| format!("Failed to create {}", cfg.cache_dir.display()))?;
|
|
|
|
clean_build_source_dirs(&cfg)?;
|
|
|
|
assert!(!cfg.build_dir.exists());
|
|
assert!(cfg.cache_dir.exists());
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn clean_build_source_dirs_noops_when_build_dir_missing() -> Result<()> {
|
|
let rootfs = tempfile::tempdir().context("Failed to create temp rootfs")?;
|
|
let mut cfg = config::Config::for_rootfs(rootfs.path());
|
|
cfg.build_dir = rootfs.path().join("tmp/build");
|
|
cfg.cache_dir = rootfs.path().join("tmp/sources");
|
|
|
|
fs::create_dir_all(&cfg.cache_dir)
|
|
.with_context(|| format!("Failed to create {}", cfg.cache_dir.display()))?;
|
|
|
|
clean_build_source_dirs(&cfg)?;
|
|
|
|
assert!(!cfg.build_dir.exists());
|
|
assert!(cfg.cache_dir.exists());
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn binary_archive_staging_uses_config_build_dir_instead_of_process_tmpdir() -> Result<()> {
|
|
let rootfs = tempfile::tempdir().context("Failed to create temp rootfs")?;
|
|
let pkg_dir = tempfile::tempdir().context("Failed to create temp package dir")?;
|
|
let archive_path = pkg_dir.path().join("pkg-1.0-1-x86_64.depot.pkg.tar.zst");
|
|
|
|
let file = fs::File::create(&archive_path)
|
|
.with_context(|| format!("Failed to create {}", archive_path.display()))?;
|
|
let encoder =
|
|
zstd::stream::write::Encoder::new(file, 3).context("Failed to create zstd encoder")?;
|
|
let mut tar = tar::Builder::new(encoder);
|
|
let payload = b"hello";
|
|
let mut header = tar::Header::new_gnu();
|
|
header.set_path("usr/bin/hello").unwrap();
|
|
header.set_size(payload.len() as u64);
|
|
header.set_mode(0o755);
|
|
header.set_cksum();
|
|
tar.append(&header, &payload[..]).unwrap();
|
|
let encoder = tar.into_inner().unwrap();
|
|
encoder.finish().unwrap();
|
|
|
|
let mut cfg = config::Config::for_rootfs(rootfs.path());
|
|
cfg.build_dir = rootfs.path().join("var/cache/depot/build");
|
|
|
|
let staged = extract_package_archive_to_staging(&cfg, &archive_path)?;
|
|
|
|
assert!(staged.path().starts_with(staging_temp_root(&cfg)));
|
|
assert!(staged.path().join("usr/bin/hello").exists());
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
#[cfg(unix)]
|
|
fn child_install_command_includes_lib32_only_flag_when_requested() -> Result<()> {
|
|
use std::os::unix::fs::PermissionsExt;
|
|
|
|
let temp = tempfile::tempdir().context("Failed to create temp dir")?;
|
|
let script_path = temp.path().join("capture-lib32-child-install.sh");
|
|
let args_path = temp.path().join("args.txt");
|
|
let script = format!(
|
|
"#!/bin/sh\nprintf '%s\\n' \"$@\" > \"{}\"\n",
|
|
args_path.display()
|
|
);
|
|
fs::write(&script_path, script)
|
|
.with_context(|| format!("Failed to write {}", script_path.display()))?;
|
|
fs::set_permissions(&script_path, fs::Permissions::from_mode(0o755))
|
|
.with_context(|| format!("Failed to chmod {}", script_path.display()))?;
|
|
|
|
run_install_command_with_program(
|
|
&script_path,
|
|
&[PathBuf::from("/tmp/pkg.toml")],
|
|
Path::new("/"),
|
|
ChildInstallCommandOptions {
|
|
no_deps: true,
|
|
assume_yes: true,
|
|
no_flags: false,
|
|
cross_prefix: None,
|
|
clean: false,
|
|
lib32_only: true,
|
|
install_test_deps: false,
|
|
install_context: None,
|
|
dep_chain: None,
|
|
},
|
|
)?;
|
|
|
|
let captured_args = fs::read_to_string(&args_path)
|
|
.with_context(|| format!("Failed to read {}", args_path.display()))?;
|
|
assert!(captured_args.lines().any(|line| line == "--lib32-only"));
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn direct_install_checks_manual_sources_before_dependency_resolution() -> Result<()> {
|
|
let rootfs = tempfile::tempdir().context("Failed to create temp rootfs")?;
|
|
let spec_dir = tempfile::tempdir().context("Failed to create temp spec dir")?;
|
|
let spec_path = spec_dir.path().join("demo.toml");
|
|
fs::write(
|
|
&spec_path,
|
|
r#"[package]
|
|
name = "demo"
|
|
version = "1.0.0"
|
|
revision = 1
|
|
description = "demo"
|
|
homepage = "https://example.test/demo"
|
|
license = "MIT"
|
|
|
|
[build]
|
|
type = "custom"
|
|
|
|
[dependencies]
|
|
runtime = ["definitely-missing-dep"]
|
|
optional = []
|
|
|
|
[[manual_sources]]
|
|
file = "missing.patch"
|
|
"#,
|
|
)?;
|
|
|
|
let mut config = config::Config::for_rootfs(rootfs.path());
|
|
config.build_dir = rootfs.path().join("var/cache/depot/build");
|
|
config.cache_dir = rootfs.path().join("var/cache/depot/sources");
|
|
config.db_dir = rootfs.path().join("var/lib/depot");
|
|
|
|
ui::set_assume_yes(true);
|
|
let result = run_direct_install_request(
|
|
DirectInstallOptions {
|
|
rootfs: rootfs.path(),
|
|
no_deps: false,
|
|
no_flags: false,
|
|
cross_prefix: None,
|
|
clean: false,
|
|
dry_run: false,
|
|
lib32_only: false,
|
|
install_test_deps: false,
|
|
},
|
|
&config,
|
|
spec_path,
|
|
);
|
|
ui::set_assume_yes(false);
|
|
|
|
let err = result.expect_err("missing manual source should fail before dependency install");
|
|
assert!(
|
|
err.to_string()
|
|
.contains("Manual source not found: missing.patch")
|
|
);
|
|
assert!(
|
|
!err.to_string()
|
|
.contains("Could not find package spec for dependency")
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn build_command_checks_manual_sources_before_dependency_resolution() -> Result<()> {
|
|
let _guard = assume_yes_test_lock();
|
|
let temp = tempfile::tempdir().context("Failed to create temp dir")?;
|
|
let rootfs = temp.path().join("rootfs");
|
|
let spec_dir = temp.path().join("packages").join("demo");
|
|
fs::create_dir_all(&rootfs)?;
|
|
fs::create_dir_all(&spec_dir)?;
|
|
|
|
let spec_path = spec_dir.join("demo.toml");
|
|
fs::write(
|
|
&spec_path,
|
|
r#"[package]
|
|
name = "demo"
|
|
version = "1.0.0"
|
|
revision = 1
|
|
description = "demo"
|
|
homepage = "https://example.test/demo"
|
|
license = "MIT"
|
|
|
|
[[source]]
|
|
url = "https://example.test/demo-1.0.0.tar.gz"
|
|
sha256 = "skip"
|
|
extract_dir = "demo-1.0.0"
|
|
|
|
[build]
|
|
type = "custom"
|
|
|
|
[dependencies]
|
|
build = ["definitely-missing-dep"]
|
|
runtime = []
|
|
optional = []
|
|
|
|
[[manual_sources]]
|
|
file = "missing.patch"
|
|
"#,
|
|
)?;
|
|
|
|
let result = run(Cli {
|
|
command: Commands::Build(BuildArgs {
|
|
rootfs_args: rootfs_args(rootfs),
|
|
prompt_args: prompt_args(true),
|
|
build_exec_args: build_exec_args(),
|
|
lib32_args: lib32_args(),
|
|
spec_pos: Some(spec_path),
|
|
spec: None,
|
|
install: false,
|
|
install_deps: true,
|
|
cleanup_deps: false,
|
|
}),
|
|
});
|
|
|
|
let err = result.expect_err("missing manual source should fail before dependency install");
|
|
assert!(
|
|
err.to_string()
|
|
.contains("Manual source not found: missing.patch")
|
|
);
|
|
assert!(
|
|
!err.to_string()
|
|
.contains("Failed to resolve required build tool package")
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn source_build_warning_messages_include_dependency_context() {
|
|
let plan = planner::ExecutionPlan {
|
|
steps: vec![
|
|
planner::PlannedStep {
|
|
package: "dep-src".into(),
|
|
action: planner::PlanAction::BuildAndInstall,
|
|
origin: planner::PlanOrigin::Source {
|
|
path: PathBuf::from("/tmp/dep-src.toml"),
|
|
local_sibling: false,
|
|
},
|
|
requested_by: vec!["dependency dep-src".into(), "app needs dep-src".into()],
|
|
},
|
|
planner::PlannedStep {
|
|
package: "dep-bin".into(),
|
|
action: planner::PlanAction::InstallBinary,
|
|
origin: planner::PlanOrigin::Binary {
|
|
repo_name: "core".into(),
|
|
record: Box::new(test_binary_repo_record(
|
|
"dep-bin",
|
|
"dep-bin-1.0-1-x86_64.tar.zst",
|
|
)),
|
|
},
|
|
requested_by: vec!["app needs dep-bin".into()],
|
|
},
|
|
],
|
|
};
|
|
|
|
assert_eq!(
|
|
source_build_warning_messages(&plan),
|
|
vec!["dep-src (requested dependency 'dep-src', needed by 'app')".to_string()]
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn planned_source_build_prereqs_check_manual_sources_before_confirmation() -> Result<()> {
|
|
let rootfs = tempfile::tempdir().context("Failed to create temp rootfs")?;
|
|
let spec_dir = tempfile::tempdir().context("Failed to create temp spec dir")?;
|
|
let spec_path = spec_dir.path().join("demo.toml");
|
|
fs::write(
|
|
&spec_path,
|
|
r#"[package]
|
|
name = "demo"
|
|
version = "1.0.0"
|
|
revision = 1
|
|
description = "demo"
|
|
homepage = "https://example.test/demo"
|
|
license = "MIT"
|
|
|
|
[[source]]
|
|
url = "https://example.test/demo-1.0.0.tar.gz"
|
|
sha256 = "skip"
|
|
extract_dir = "demo-1.0.0"
|
|
|
|
[build]
|
|
type = "custom"
|
|
|
|
[dependencies]
|
|
build = []
|
|
runtime = []
|
|
optional = []
|
|
|
|
[[manual_sources]]
|
|
file = "missing.patch"
|
|
"#,
|
|
)?;
|
|
|
|
let config = config::Config::for_rootfs(rootfs.path());
|
|
let plan = planner::ExecutionPlan {
|
|
steps: vec![planner::PlannedStep {
|
|
package: "demo".into(),
|
|
action: planner::PlanAction::BuildAndInstall,
|
|
origin: planner::PlanOrigin::Source {
|
|
path: spec_path,
|
|
local_sibling: true,
|
|
},
|
|
requested_by: vec!["requested spec".into()],
|
|
}],
|
|
};
|
|
|
|
let err = validate_source_build_prereqs_for_plan(&plan, rootfs.path(), &config)
|
|
.expect_err("missing local manual source should fail before confirmation");
|
|
assert!(
|
|
err.to_string()
|
|
.contains("Manual source not found: missing.patch")
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn cleanup_targets_keep_runtime_dependencies_for_build_install() {
|
|
let plan = planner::ExecutionPlan {
|
|
steps: vec![
|
|
planner::PlannedStep {
|
|
package: "zlib".into(),
|
|
action: planner::PlanAction::InstallBinary,
|
|
origin: planner::PlanOrigin::Source {
|
|
path: PathBuf::from("packages/core/zlib/zlib.toml"),
|
|
local_sibling: false,
|
|
},
|
|
requested_by: vec!["cmake needs zlib".into(), "llvm-runtime needs zlib".into()],
|
|
},
|
|
planner::PlannedStep {
|
|
package: "cmake".into(),
|
|
action: planner::PlanAction::InstallBinary,
|
|
origin: planner::PlanOrigin::Source {
|
|
path: PathBuf::from("packages/core/cmake/cmake.toml"),
|
|
local_sibling: false,
|
|
},
|
|
requested_by: vec!["dependency cmake".into()],
|
|
},
|
|
planner::PlannedStep {
|
|
package: "llvm-runtime".into(),
|
|
action: planner::PlanAction::InstallBinary,
|
|
origin: planner::PlanOrigin::Source {
|
|
path: PathBuf::from("packages/core/llvm-runtime/llvm-runtime.toml"),
|
|
local_sibling: false,
|
|
},
|
|
requested_by: vec!["dependency llvm-runtime".into()],
|
|
},
|
|
],
|
|
};
|
|
let mut tracker = AutoInstalledDependencyTracker::default();
|
|
tracker.record_plan(&plan, &["cmake".into()], AutoInstalledDependencyKind::Build);
|
|
tracker.record_plan(
|
|
&plan,
|
|
&["llvm-runtime".into()],
|
|
AutoInstalledDependencyKind::Runtime,
|
|
);
|
|
|
|
assert_eq!(tracker.cleanup_targets(false), vec!["cmake".to_string()]);
|
|
assert_eq!(
|
|
tracker.cleanup_targets(true),
|
|
vec![
|
|
"llvm-runtime".to_string(),
|
|
"cmake".to_string(),
|
|
"zlib".to_string()
|
|
]
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn build_type_runs_automatic_tests_matches_builder_behavior() {
|
|
assert!(build_type_runs_automatic_tests(&test_package_spec(
|
|
package::BuildType::Autotools,
|
|
None,
|
|
&[]
|
|
)));
|
|
assert!(build_type_runs_automatic_tests(&test_package_spec(
|
|
package::BuildType::Perl,
|
|
None,
|
|
&[]
|
|
)));
|
|
assert!(build_type_runs_automatic_tests(&test_package_spec(
|
|
package::BuildType::Meson,
|
|
None,
|
|
&[]
|
|
)));
|
|
assert!(build_type_runs_automatic_tests(&test_package_spec(
|
|
package::BuildType::CMake,
|
|
None,
|
|
&[]
|
|
)));
|
|
}
|
|
|
|
#[test]
|
|
fn requested_test_deps_prompt_can_disable_tests() -> Result<()> {
|
|
let _guard = assume_yes_test_lock();
|
|
let mut spec = test_package_spec(package::BuildType::Meson, None, &[]);
|
|
spec.dependencies.test = vec!["pytest".into()];
|
|
|
|
ui::set_assume_yes(true);
|
|
let prompted = maybe_prompt_to_skip_tests_for_missing_requested_deps(
|
|
&mut spec,
|
|
&["pytest".into()],
|
|
"Requested test dependencies are missing",
|
|
)?;
|
|
ui::set_assume_yes(false);
|
|
|
|
assert!(prompted);
|
|
assert!(spec.build.flags.skip_tests);
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn requested_test_deps_prompt_is_ignored_for_non_automatic_test_builders() -> Result<()> {
|
|
let _guard = assume_yes_test_lock();
|
|
let mut spec = test_package_spec(package::BuildType::Custom, None, &[]);
|
|
spec.dependencies.test = vec!["pytest".into()];
|
|
|
|
ui::set_assume_yes(true);
|
|
let prompted = maybe_prompt_to_skip_tests_for_missing_requested_deps(
|
|
&mut spec,
|
|
&["pytest".into()],
|
|
"Requested test dependencies are missing",
|
|
)?;
|
|
ui::set_assume_yes(false);
|
|
|
|
assert!(!prompted);
|
|
assert!(!spec.build.flags.skip_tests);
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn requested_test_deps_prompt_is_ignored_for_multilib_builds() -> Result<()> {
|
|
let _guard = assume_yes_test_lock();
|
|
let mut spec = test_package_spec(package::BuildType::Meson, None, &[]);
|
|
spec.build.flags.build_32 = true;
|
|
spec.dependencies.test = vec!["pytest".into()];
|
|
|
|
ui::set_assume_yes(true);
|
|
let prompted = maybe_prompt_to_skip_tests_for_missing_requested_deps(
|
|
&mut spec,
|
|
&["pytest".into()],
|
|
"Requested test dependencies are missing",
|
|
)?;
|
|
ui::set_assume_yes(false);
|
|
|
|
assert!(!prompted);
|
|
assert!(!spec.build.flags.skip_tests);
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn should_not_install_test_deps_for_cli_lib32_only_builds() {
|
|
let mut spec = test_package_spec(package::BuildType::Meson, None, &[]);
|
|
spec.dependencies.lib32 = Some(package::DependencyGroup {
|
|
build: Vec::new(),
|
|
runtime: Vec::new(),
|
|
test: vec!["lib32-pytest".into()],
|
|
optional: Vec::new(),
|
|
groups: Vec::new(),
|
|
});
|
|
|
|
assert!(!should_install_test_deps(
|
|
&spec,
|
|
true,
|
|
deps::RequestedOutputs::Lib32Only
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn build_command_requires_install_deps_flag_for_missing_dependencies() -> Result<()> {
|
|
let _guard = assume_yes_test_lock();
|
|
let temp = tempfile::tempdir().context("Failed to create temp dir")?;
|
|
let rootfs = temp.path().join("rootfs");
|
|
let repo_root = temp.path().join("packages");
|
|
let app_dir = repo_root.join("app");
|
|
let dep_dir = repo_root.join("dep");
|
|
fs::create_dir_all(&rootfs)?;
|
|
fs::create_dir_all(&app_dir)?;
|
|
fs::create_dir_all(&dep_dir)?;
|
|
|
|
let app_spec = app_dir.join("app.toml");
|
|
fs::write(
|
|
&app_spec,
|
|
r#"[package]
|
|
name = "app"
|
|
version = "1.0.0"
|
|
revision = 1
|
|
description = "app"
|
|
homepage = "https://example.test/app"
|
|
license = "MIT"
|
|
|
|
[[source]]
|
|
url = "https://example.test/app-1.0.0.tar.gz"
|
|
sha256 = "skip"
|
|
extract_dir = "app-1.0.0"
|
|
|
|
[build]
|
|
type = "custom"
|
|
|
|
[dependencies]
|
|
build = ["dep"]
|
|
runtime = []
|
|
optional = []
|
|
"#,
|
|
)
|
|
.with_context(|| format!("Failed to write {}", app_spec.display()))?;
|
|
|
|
let dep_spec = dep_dir.join("dep.toml");
|
|
fs::write(
|
|
&dep_spec,
|
|
r#"[package]
|
|
name = "dep"
|
|
version = "1.0.0"
|
|
revision = 1
|
|
description = "dep"
|
|
homepage = "https://example.test/dep"
|
|
license = "MIT"
|
|
|
|
[[source]]
|
|
url = "https://example.test/dep-1.0.0.tar.gz"
|
|
sha256 = "skip"
|
|
extract_dir = "dep-1.0.0"
|
|
|
|
[build]
|
|
type = "custom"
|
|
|
|
[dependencies]
|
|
build = []
|
|
runtime = []
|
|
optional = []
|
|
"#,
|
|
)
|
|
.with_context(|| format!("Failed to write {}", dep_spec.display()))?;
|
|
|
|
let config = config::Config::for_rootfs(&rootfs);
|
|
register_required_development_package_if_configured(&config, &rootfs)?;
|
|
|
|
let result = run(Cli {
|
|
command: Commands::Build(BuildArgs {
|
|
rootfs_args: rootfs_args(rootfs.clone()),
|
|
prompt_args: prompt_args(true),
|
|
build_exec_args: build_exec_args(),
|
|
lib32_args: lib32_args(),
|
|
spec_pos: Some(app_spec),
|
|
spec: None,
|
|
install: false,
|
|
install_deps: false,
|
|
cleanup_deps: false,
|
|
}),
|
|
});
|
|
ui::set_assume_yes(false);
|
|
|
|
let err = result.expect_err("build should require --install-deps when deps are missing");
|
|
assert!(err.to_string().contains("Re-run with --install-deps"));
|
|
Ok(())
|
|
}
|
|
|
|
#[test]
|
|
fn make_lib32_build_spec_uses_only_lib32_flag_rules() {
|
|
let mut base = test_package_spec(package::BuildType::Custom, None, &[]);
|
|
base.build.flags.cflags = vec!["-O2".into()];
|
|
base.build.flags.replace_cflags = vec!["-O2=>-O3".into()];
|
|
base.build.flags.cflags_lib32 = vec!["-m32".into()];
|
|
base.build.flags.replace_cflags_lib32 = vec!["-m32=>-mstackrealign".into()];
|
|
base.build.flags.cxxflags = vec!["-O2".into()];
|
|
base.build.flags.replace_cxxflags = vec!["-O2=>-O3".into()];
|
|
base.build.flags.cxxflags_lib32 = vec!["-fno-rtti".into()];
|
|
base.build.flags.replace_cxxflags_lib32 = vec!["-fno-rtti=>-fno-exceptions".into()];
|
|
|
|
let lib32 = make_lib32_build_spec(&base);
|
|
|
|
assert!(lib32.build.flags.lib32_variant);
|
|
assert_eq!(lib32.build.flags.cflags, vec!["-m32"]);
|
|
assert_eq!(
|
|
lib32.build.flags.replace_cflags,
|
|
vec!["-m32=>-mstackrealign"]
|
|
);
|
|
assert_eq!(lib32.build.flags.cxxflags, vec!["-fno-rtti"]);
|
|
assert_eq!(
|
|
lib32.build.flags.replace_cxxflags,
|
|
vec!["-fno-rtti=>-fno-exceptions"]
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn make_lib32_package_spec_uses_lib32_dependency_override() {
|
|
let mut base = test_package_spec(package::BuildType::Custom, None, &[]);
|
|
base.dependencies.runtime = vec!["zlib".into()];
|
|
base.dependencies.lib32 = Some(package::DependencyGroup {
|
|
build: vec!["gcc-multilib".into()],
|
|
runtime: vec!["lib32-zlib".into()],
|
|
test: Vec::new(),
|
|
optional: vec!["lib32-gtk-doc".into()],
|
|
groups: Vec::new(),
|
|
});
|
|
|
|
let lib32 = make_lib32_package_spec(&base);
|
|
|
|
assert_eq!(lib32.package.name, "lib32-pkg");
|
|
assert_eq!(lib32.dependencies.build, vec!["gcc-multilib"]);
|
|
assert_eq!(lib32.dependencies.runtime, vec!["lib32-zlib", "pkg"]);
|
|
assert_eq!(lib32.dependencies.optional, vec!["lib32-gtk-doc"]);
|
|
}
|
|
|
|
#[test]
|
|
fn make_lib32_package_spec_does_not_inherit_primary_alternatives() {
|
|
let mut base = test_package_spec(package::BuildType::Custom, None, &[]);
|
|
base.alternatives.provides = vec!["editor".into()];
|
|
base.alternatives.conflicts = vec!["nano".into()];
|
|
base.alternatives.replaces = vec!["vi".into()];
|
|
|
|
let lib32 = make_lib32_package_spec(&base);
|
|
|
|
assert_eq!(lib32.package.name, "lib32-pkg");
|
|
assert!(lib32.alternatives.provides.is_empty());
|
|
assert!(lib32.alternatives.conflicts.is_empty());
|
|
assert!(lib32.alternatives.replaces.is_empty());
|
|
}
|
|
|
|
#[test]
|
|
fn requested_outputs_prefers_lib32_only_spec_flag() {
|
|
let mut spec = test_package_spec(package::BuildType::Custom, None, &[]);
|
|
spec.build.flags.lib32_only = true;
|
|
|
|
assert_eq!(
|
|
requested_outputs(&spec, false),
|
|
deps::RequestedOutputs::Lib32Only
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn expand_install_requests_for_groups_uses_source_specs() -> Result<()> {
|
|
let temp = tempfile::tempdir()?;
|
|
let rootfs = temp.path().join("rootfs");
|
|
let repo_root = temp.path().join("repos");
|
|
let core = repo_root.join("core").join("foo");
|
|
let desktop = repo_root.join("desktop").join("bar");
|
|
fs::create_dir_all(&rootfs)?;
|
|
fs::create_dir_all(&core)?;
|
|
fs::create_dir_all(&desktop)?;
|
|
|
|
let foo_spec = core.join("foo.toml");
|
|
fs::write(
|
|
&foo_spec,
|
|
r#"[package]
|
|
name = "foo"
|
|
version = "1.0.0"
|
|
revision = 1
|
|
description = "foo"
|
|
homepage = "https://example.test/foo"
|
|
license = "MIT"
|
|
|
|
[[source]]
|
|
url = "https://example.test/foo-1.0.0.tar.gz"
|
|
sha256 = "skip"
|
|
extract_dir = "foo-1.0.0"
|
|
|
|
[build]
|
|
type = "custom"
|
|
|
|
[dependencies]
|
|
groups = ["base"]
|
|
runtime = []
|
|
optional = []
|
|
"#,
|
|
)?;
|
|
|
|
let bar_spec = desktop.join("bar.toml");
|
|
fs::write(
|
|
&bar_spec,
|
|
r#"[package]
|
|
name = "bar"
|
|
version = "1.0.0"
|
|
revision = 1
|
|
description = "bar"
|
|
homepage = "https://example.test/bar"
|
|
license = "MIT"
|
|
|
|
[[source]]
|
|
url = "https://example.test/bar-1.0.0.tar.gz"
|
|
sha256 = "skip"
|
|
extract_dir = "bar-1.0.0"
|
|
|
|
[build]
|
|
type = "custom"
|
|
|
|
[dependencies]
|
|
groups = ["base", "desktop"]
|
|
runtime = []
|
|
optional = []
|
|
"#,
|
|
)?;
|
|
|
|
let mut config = config::Config::for_rootfs(&rootfs);
|
|
config.repo_clone_dir = repo_root;
|
|
config.binary_repos.clear();
|
|
|
|
let (expanded, groups) =
|
|
expand_install_requests_for_groups(&config, &rootfs, &[PathBuf::from("base")])?;
|
|
|
|
assert_eq!(groups, vec!["base".to_string()]);
|
|
assert_eq!(expanded, vec![PathBuf::from("bar"), PathBuf::from("foo")]);
|
|
Ok(())
|
|
}
|