canic-host 0.110.32

Host-side App build and desired-state Fleet reconciliation library for Canic workspaces
Documentation
use super::*;
use crate::release_set::AppConfigSnapshot;
use canic_core::{ids::CanisterRole, role_contract::RoleContractFinding};
use std::time::Instant;

#[test]
fn batched_contracts_preserve_isolated_roles_order_and_rejections() {
    let path = Path::new(env!("CARGO_MANIFEST_DIR"))
        .join("../../apps/test/test-configs/generated-mixed-topology.toml");
    let config = AppConfigSnapshot::load(&path).unwrap();
    let mut roles = config
        .model()
        .deployable_roles()
        .into_iter()
        .collect::<Vec<_>>();
    roles.push(CanisterRole::owned("undeclared".to_string()));
    roles.push(CanisterRole::ROOT);
    roles.push(roles[0].clone());

    let started = Instant::now();
    let isolated = roles
        .iter()
        .map(|role| {
            if role.is_root() {
                return resolve_canonical_root_contract(config.model());
            }
            match validate_declared_role_package(
                &path,
                config.model(),
                role,
                PackageValidationMode::Passive,
                &CargoFeatureSelection::default(),
            ) {
                RolePackageValidation::Supported(evidence) => {
                    resolve_declared_role_package_contract(config.model(), &evidence)
                }
                RolePackageValidation::Unsupported(finding) => RoleContractResolution::Rejected {
                    errors: vec![finding],
                },
            }
        })
        .collect::<Vec<_>>();
    let isolated_elapsed = started.elapsed();
    let started = Instant::now();
    let batched = resolve_declared_role_contracts(
        &path,
        config.model(),
        &roles,
        PackageValidationMode::Passive,
    );
    eprintln!(
        "role contracts: isolated={isolated_elapsed:?}, batched={:?}",
        started.elapsed()
    );
    assert_eq!(batched, isolated);
    for (role, resolution) in roles.iter().zip(&batched) {
        if role.as_str() == "undeclared" {
            assert!(
                matches!(resolution, RoleContractResolution::Rejected { errors }
                if errors == &vec![RoleContractFinding::RoleUnknown { role: role.clone() }])
            );
        } else {
            assert!(
                matches!(resolution, RoleContractResolution::Resolved { contract }
                if &contract.role == role),
                "{role}: {resolution:?}"
            );
        }
    }
    assert!(resolve_declared_role_contracts(
        &path,
        config.model(),
        &[],
        PackageValidationMode::Passive,
    ).is_empty());
}