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, bounded readiness polling, and a small time conversion. It does not provide a
8//! simulator wrapper or a host-wide runtime lock.
9//!
10//! The crate also provides:
11//!
12//! - bounded artifact inspection through [`ic_host_artifacts`], filesystem
13//!   operations through [`ic_host_fs`], verified execution through
14//!   [`ic_host_process`];
15//! - marker parsing, aggregation, comparison, and reports in [`benchmark`];
16//! - canister-side marker emission in [`performance`];
17//! - deterministic test principals through [`Fake`].
18//!
19//! The [`pocket_ic`], [`pic`] and host-library exports are unavailable
20//! when compiling for `wasm32`; benchmark data types and marker emission remain
21//! available to canister code.
22
23pub mod benchmark;
24
25#[cfg(not(target_arch = "wasm32"))]
26pub use pocket_ic;
27
28#[cfg(not(target_arch = "wasm32"))]
29pub use {ic_host_artifacts, ic_host_fs, ic_host_process};
30
31#[cfg(not(target_arch = "wasm32"))]
32pub mod pic;
33
34pub mod performance;
35
36#[cfg(all(test, unix, not(target_arch = "wasm32")))]
37mod test_executable;
38
39use candid::Principal;
40
41/// Deterministic principal generator for tests.
42///
43/// Values are derived directly from a numeric seed, making fixtures stable
44/// without embedding textual principal literals.
45pub struct Fake;
46
47impl Fake {
48    /// Deterministically derive a [`Principal`] from `seed`.
49    #[must_use]
50    pub fn principal(seed: u32) -> Principal {
51        let mut buf = [0u8; 29];
52        buf[..4].copy_from_slice(&seed.to_be_bytes());
53
54        Principal::from_slice(&buf)
55    }
56}
57
58#[cfg(test)]
59mod tests {
60    use super::*;
61
62    #[test]
63    fn fake_principal_is_deterministic_and_unique() {
64        let p1 = Fake::principal(7);
65        let p2 = Fake::principal(7);
66        let q = Fake::principal(8);
67
68        assert_eq!(p1, p2, "Fake::principal should be deterministic");
69        assert_ne!(p1, q, "Fake::principal should differ for different seeds");
70
71        let bytes = p1.as_slice();
72        assert_eq!(bytes.len(), 29, "Principal must be 29 bytes");
73    }
74}