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