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//! caller-owned managed-server startup, and a small time conversion. It does
7//! not provide a simulator wrapper or a host-wide runtime lock.
8//!
9//! The crate also provides:
10//!
11//! - host-only transactional artifacts, Wasm builds, and freshness helpers in
12//! [`artifacts`];
13//! - marker parsing, aggregation, comparison, and reports in [`benchmark`];
14//! - canister-side marker emission in [`performance`];
15//! - deterministic test principals through [`Fake`].
16//!
17//! The [`pic`] and [`artifacts`] modules are unavailable when compiling for
18//! `wasm32`; benchmark data types and marker emission remain available to
19//! canister code.
20
21pub mod benchmark;
22
23#[cfg(not(target_arch = "wasm32"))]
24mod timing;
25
26#[cfg(not(target_arch = "wasm32"))]
27pub mod artifacts;
28
29#[cfg(not(target_arch = "wasm32"))]
30pub mod pic;
31
32pub mod performance;
33use candid::Principal;
34
35/// Deterministic principal generator for tests.
36///
37/// Values are derived directly from a numeric seed, making fixtures stable
38/// without embedding textual principal literals.
39pub struct Fake;
40
41impl Fake {
42 /// Deterministically derive a [`Principal`] from `seed`.
43 #[must_use]
44 pub fn principal(seed: u32) -> Principal {
45 let mut buf = [0u8; 29];
46 buf[..4].copy_from_slice(&seed.to_be_bytes());
47
48 Principal::from_slice(&buf)
49 }
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}