Skip to main content

ic_testkit/
lib.rs

1//! Focused PocketIC test-harness utilities for Internet Computer canisters.
2//!
3//! `ic-testkit` keeps PocketIC itself visible: `pocket_ic` re-exports the
4//! complete upstream crate, while `pic` retains convenient runtime type
5//! re-exports and adds extension traits for typed Candid calls, generic
6//! installation, diagnostics, snapshots, startup errors, caller-owned
7//! managed-server startup and bounded readiness polling. It does not provide a
8//! simulator wrapper or a host-wide runtime lock.
9//!
10//! The crate also provides:
11//!
12//! - marker parsing, aggregation, comparison, and reports in [`benchmark`];
13//! - canister-side marker emission in `performance` (Wasm only);
14//! - deterministic test principals through [`Fake`].
15//!
16//! The `pocket_ic` and `pic` exports are unavailable
17//! when compiling for `wasm32`; benchmark data types and marker emission remain
18//! available to canister code.
19
20pub mod benchmark;
21
22#[cfg(not(target_arch = "wasm32"))]
23pub use pocket_ic;
24
25#[cfg(not(target_arch = "wasm32"))]
26pub mod pic;
27
28#[cfg(not(target_arch = "wasm32"))]
29pub mod testing;
30
31#[cfg(target_arch = "wasm32")]
32pub mod performance;
33
34use candid::Principal;
35
36/// Deterministic principal generator for tests.
37///
38/// Values are derived directly from a numeric seed, making fixtures stable
39/// without embedding textual principal literals.
40pub struct Fake;
41
42impl Fake {
43    /// Deterministically derive a [`Principal`] from `seed`.
44    #[must_use]
45    pub fn principal(seed: u32) -> Principal {
46        let mut buf = [0u8; 29];
47        buf[..4].copy_from_slice(&seed.to_be_bytes());
48
49        Principal::from_slice(&buf)
50    }
51}
52
53#[cfg(test)]
54mod tests {
55    use super::*;
56
57    #[test]
58    fn fake_principal_is_deterministic_and_unique() {
59        let p1 = Fake::principal(7);
60        let p2 = Fake::principal(7);
61        let q = Fake::principal(8);
62
63        assert_eq!(p1, p2, "Fake::principal should be deterministic");
64        assert_ne!(p1, q, "Fake::principal should differ for different seeds");
65
66        let bytes = p1.as_slice();
67        assert_eq!(bytes.len(), 29, "Principal must be 29 bytes");
68    }
69}