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 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//! - host-only transactional artifacts, Wasm builds, and freshness helpers in
13//!   [`artifacts`];
14//! - shared bounded artifact inspection and verified executable APIs through
15//!   the complete upstream [`ic_host_tools`] crate;
16//! - marker parsing, aggregation, comparison, and reports in [`benchmark`];
17//! - canister-side marker emission in [`performance`];
18//! - deterministic test principals through [`Fake`].
19//!
20//! The [`pocket_ic`], [`pic`], [`artifacts`] and [`ic_host_tools`] exports are unavailable when
21//! compiling for `wasm32`; benchmark data types and marker emission remain
22//! available to canister code.
23
24pub mod benchmark;
25
26#[cfg(not(target_arch = "wasm32"))]
27mod batch;
28
29#[cfg(not(target_arch = "wasm32"))]
30mod timing;
31
32#[cfg(not(target_arch = "wasm32"))]
33pub mod artifacts;
34
35#[cfg(not(target_arch = "wasm32"))]
36pub use pocket_ic;
37
38#[cfg(not(target_arch = "wasm32"))]
39pub use ic_host_tools;
40
41#[cfg(not(target_arch = "wasm32"))]
42pub mod pic;
43
44pub mod performance;
45
46#[cfg(all(test, unix, not(target_arch = "wasm32")))]
47mod test_executable;
48
49use candid::Principal;
50
51/// Deterministic principal generator for tests.
52///
53/// Values are derived directly from a numeric seed, making fixtures stable
54/// without embedding textual principal literals.
55pub struct Fake;
56
57impl Fake {
58    /// Deterministically derive a [`Principal`] from `seed`.
59    #[must_use]
60    pub fn principal(seed: u32) -> Principal {
61        let mut buf = [0u8; 29];
62        buf[..4].copy_from_slice(&seed.to_be_bytes());
63
64        Principal::from_slice(&buf)
65    }
66}
67
68#[cfg(test)]
69mod tests {
70    use super::*;
71
72    #[test]
73    fn fake_principal_is_deterministic_and_unique() {
74        let p1 = Fake::principal(7);
75        let p2 = Fake::principal(7);
76        let q = Fake::principal(8);
77
78        assert_eq!(p1, p2, "Fake::principal should be deterministic");
79        assert_ne!(p1, q, "Fake::principal should differ for different seeds");
80
81        let bytes = p1.as_slice();
82        assert_eq!(bytes.len(), 29, "Principal must be 29 bytes");
83    }
84}