Skip to main content

canic_testkit/pic/
readiness.rs

1use candid::Principal;
2use canic::{Error, dto::topology::SubnetRegistryResponse, ids::CanisterRole, protocol};
3
4use super::Pic;
5
6/// Wait until a PocketIC canister reports `canic_ready`.
7pub fn wait_until_ready(pic: &Pic, canister_id: Principal, tick_limit: usize) {
8    for _ in 0..tick_limit {
9        if let Ok(ready) = pic.query_call_as::<bool, _>(
10            canister_id,
11            Principal::anonymous(),
12            protocol::CANIC_READY,
13            (),
14        ) && ready
15        {
16            return;
17        }
18        pic.tick();
19    }
20
21    panic!("canister did not report ready in time: {canister_id}");
22}
23
24/// Resolve one role principal from root's subnet registry, polling until present.
25#[must_use]
26pub fn role_pid(pic: &Pic, root_id: Principal, role: &'static str, tick_limit: usize) -> Principal {
27    for _ in 0..tick_limit {
28        let registry: Result<Result<SubnetRegistryResponse, Error>, Error> = pic.query_call_as(
29            root_id,
30            Principal::anonymous(),
31            protocol::CANIC_SUBNET_REGISTRY,
32            (),
33        );
34
35        if let Ok(Ok(registry)) = registry
36            && let Some(pid) = registry
37                .0
38                .into_iter()
39                .find(|entry| entry.role == CanisterRole::new(role))
40                .map(|entry| entry.pid)
41        {
42            return pid;
43        }
44
45        pic.tick();
46    }
47
48    panic!("{role} canister must be registered");
49}