use super::*;
use crate::{canister_build::CanisterBuildProfile, test_support::temp_dir};
use canic_contracts::ids::BuildNetwork;
use canic_core::role_contract::CanicFeatureKey;
#[test]
fn coordinator_declaration_pass_exports_candid_only_from_the_selected_leaf() {
let workspace_root = Path::new(env!("CARGO_MANIFEST_DIR")).join("../..");
let mut context = WorkspaceBuildContext {
role: FLEET_COORDINATOR_ROLE.to_string(),
profile: CanisterBuildProfile::Fast,
environment: "local".to_string(),
build_network: BuildNetwork::Local,
workspace_root: workspace_root.clone(),
icp_root: workspace_root,
config_path: PathBuf::from("canic.toml"),
local_replica: None,
refresh_canonical_infrastructure_did: false,
release_build_id: None,
};
let manifest = Path::new("/workspace/coordinator/Cargo.toml");
let local_command = coordinator_cargo_build_command(&context, manifest, true);
let local = local_command
.get_args()
.map(|argument| argument.to_string_lossy().into_owned())
.collect::<Vec<_>>();
assert_eq!(local.first().map(String::as_str), Some("rustc"));
assert!(local.contains(&"--locked".to_string()));
assert!(
local
.windows(2)
.any(|arguments| arguments == ["--cfg", "canic_export_candid"])
);
assert!(local.contains(&"--check-cfg=cfg(canic_export_candid)".to_string()));
assert_eq!(
local_command.get_envs().find(|(key, _)| {
*key == std::ffi::OsStr::new(canic_core::role_contract::CANONICAL_CANDID_BUILD_ENV)
}),
Some((
std::ffi::OsStr::new(canic_core::role_contract::CANONICAL_CANDID_BUILD_ENV),
Some(std::ffi::OsStr::new("1")),
))
);
context.build_network = BuildNetwork::Ic;
let ic = coordinator_cargo_build_command(&context, manifest, false)
.get_args()
.map(|argument| argument.to_string_lossy().into_owned())
.collect::<Vec<_>>();
assert_eq!(ic.first().map(String::as_str), Some("build"));
assert!(ic.contains(&"--locked".to_string()));
assert_eq!(
coordinator_cargo_build_command(&context, manifest, false)
.get_envs()
.find(|(key, _)| {
*key == std::ffi::OsStr::new(canic_core::role_contract::CANONICAL_CANDID_BUILD_ENV)
}),
Some((
std::ffi::OsStr::new(canic_core::role_contract::CANONICAL_CANDID_BUILD_ENV),
None,
))
);
}
#[test]
fn generated_fleet_coordinator_wrapper_satisfies_its_runtime_only_contract() {
let root = temp_dir("canic-generated-fleet-coordinator-contract");
let workspace_root = Path::new(env!("CARGO_MANIFEST_DIR")).join("../..");
let context = WorkspaceBuildContext {
role: FLEET_COORDINATOR_ROLE.to_string(),
profile: CanisterBuildProfile::Fast,
environment: "test".to_string(),
build_network: BuildNetwork::Ic,
workspace_root,
icp_root: root.clone(),
config_path: root.join("canic.toml"),
local_replica: None,
refresh_canonical_infrastructure_did: false,
release_build_id: None,
};
let source =
resolve_bootstrap_fleet_coordinator_source(&context).expect("generate Coordinator package");
assert!(
source
.canonical_did_path
.ends_with("canic/candid/fleet_coordinator.did")
);
assert_eq!(source.package_version, env!("CARGO_PKG_VERSION"));
let manifest_path = source.manifest_path;
let manifest = fs::read_to_string(&manifest_path).expect("read generated manifest");
let runtime = fs::read_to_string(
manifest_path
.parent()
.expect("wrapper manifest parent")
.join("src/lib.rs"),
)
.expect("read generated runtime");
assert!(manifest.contains("app = \"fleet_coordinator\""));
assert!(manifest.contains("role = \"fleet_coordinator\""));
assert!(manifest.contains("default-features = false"));
assert!(manifest.contains("features = [\"fleet-coordinator-canister\"]"));
assert!(!manifest.contains("[build-dependencies]"));
assert_eq!(
runtime,
"canic::start_fleet_coordinator!();\ncanic::finish!();\n"
);
let validation =
validate_built_in_fleet_coordinator_package(&manifest_path, PackageValidationMode::Build);
let RolePackageValidation::Supported(evidence) = validation else {
panic!("generated wrapper should satisfy the package contract: {validation:?}");
};
assert_eq!(
evidence.direct_features,
std::collections::BTreeSet::from([CanicFeatureKey::FleetCoordinatorCanister])
);
fs::remove_dir_all(root).expect("clean temp dir");
}