Skip to main content

ic_testkit/pic/
diagnostics.rs

1use candid::Principal;
2use pocket_ic::PocketIc;
3
4use super::startup;
5
6/// Reusable PocketIC failure diagnostics.
7pub trait PocketIcDiagnosticsExt {
8    /// Print status and canister-log context for a failed test operation.
9    fn dump_canister_debug(&self, canister_id: Principal, context: &str);
10}
11
12impl PocketIcDiagnosticsExt for PocketIc {
13    /// Dump basic PocketIC status and log context for one canister.
14    fn dump_canister_debug(&self, canister_id: Principal, context: &str) {
15        eprintln!("{context}: debug for canister {canister_id}");
16
17        match self.canister_status(canister_id, None) {
18            Ok(status) => eprintln!("canister_status: {status:?}"),
19            Err(err) => {
20                let message = err.to_string();
21                if startup::is_dead_instance_transport_error(&message) {
22                    eprintln!("canister_status unavailable: PocketIC instance no longer reachable");
23                    return;
24                }
25                eprintln!("canister_status failed: {err:?}");
26            }
27        }
28
29        match self.fetch_canister_logs(canister_id, Principal::anonymous()) {
30            Ok(records) => {
31                if records.is_empty() {
32                    eprintln!("canister logs: <empty>");
33                } else {
34                    for record in records {
35                        eprintln!("canister log: {record:?}");
36                    }
37                }
38            }
39            Err(err) => {
40                let message = err.to_string();
41                if startup::is_dead_instance_transport_error(&message) {
42                    eprintln!(
43                        "fetch_canister_logs unavailable: PocketIC instance no longer reachable"
44                    );
45                    return;
46                }
47                eprintln!("fetch_canister_logs failed: {err:?}");
48            }
49        }
50    }
51}