ic-testkit 0.85.1

PocketIC-oriented test utilities for IC canister tests
Documentation
#[test]
fn cleanup_preserves_causes_and_senders_and_continues_after_each_failure() {
    use super::{ControllerSnapshot, SnapshotCleanupFailure, cleanup_captured_snapshots};
    use crate::pocket_ic::{ClientError, ErrorCode, RejectCode, RejectResponse};
    use ic_platform_types::principal::ExternalPrincipal as Principal;

    let ids = [1, 2, 3, 4].map(|byte| Principal::from_slice(&[byte]));
    let sender = Some(Principal::anonymous());
    let snapshots = ids
        .map(|id| {
            (
                id,
                ControllerSnapshot {
                    snapshot_id: vec![7],
                    sender,
                },
            )
        })
        .into_iter()
        .collect::<std::collections::BTreeMap<_, _>>();
    let rejection = RejectResponse {
        reject_code: RejectCode::CanisterReject,
        reject_message: "cleanup rejected".into(),
        error_code: ErrorCode::CanisterCalledTrap,
        certified: false,
    };
    let mut calls = Vec::new();
    let failures = cleanup_captured_snapshots(snapshots, |id, selected_sender, snapshot_id| {
        assert_eq!(snapshot_id, [7]);
        calls.push((id, selected_sender));
        if id == ids[1] {
            return Err(ClientError::Canister(rejection.clone()));
        }
        if id == ids[2] {
            return Err(ClientError::Protocol("synthetic cleanup failure".into()));
        }
        Ok(())
    });
    assert_eq!(calls, ids.map(|id| (id, sender)));
    let [
        SnapshotCleanupFailure {
            canister_id: rejected_id,
            sender: rejected_sender,
            source: rejected,
            snapshot_id: rejected_snapshot,
        },
        SnapshotCleanupFailure {
            canister_id: panicked_id,
            sender: panicked_sender,
            source: panicked,
            snapshot_id: panicked_snapshot,
        },
    ] = failures.as_slice()
    else {
        panic!("expected both cleanup failures: {failures:?}");
    };
    assert_eq!(*rejected_id, ids[1]);
    assert_eq!(rejected_snapshot, &[7]);
    assert_eq!(panicked_snapshot, &[7]);
    assert_eq!(*rejected_sender, sender);
    let ClientError::Canister(response) = rejected.as_ref() else {
        panic!("expected rejection: {rejected:?}");
    };
    assert_eq!(response, &rejection);
    assert_eq!(*panicked_id, ids[2]);
    assert_eq!(*panicked_sender, sender);
    let ClientError::Protocol(source) = panicked.as_ref() else {
        panic!("expected operation failure: {panicked:?}");
    };
    assert_eq!(source, "synthetic cleanup failure");
}