Skip to main content

ic_testkit/artifacts/
mod.rs

1//! Host-side artifact discovery, freshness, and Wasm build helpers.
2//!
3//! These functions keep integration-test artifacts in caller-selected target
4//! directories and contain no application-specific package or profile policy.
5//! Independent Wasm batches remain sequential; [`WasmBuildSession`] adds
6//! explicit cross-call resolution reuse, while [`WasmBuildInputSnapshot`]
7//! prepares a fixed specification set for concurrent readers. Both require a
8//! caller-held source lease.
9//!
10//! Successful Wasm and generic artifact records retain their read-only exact
11//! paths against cache replacement and pruning. Retain the record (or a clone)
12//! through consumption; paths and artifact descriptors alone carry no ownership.
13//! Batch reports own their successful records even when later entries fail.
14//!
15//! ```no_run
16//! use ic_testkit::artifacts::{
17//!     ArtifactCacheOutcome, ArtifactCachePreparation, ArtifactCacheSpec,
18//!     WasmBuildSpec, build_wasm_canisters_cached, prepare_artifact_cache,
19//!     resolve_cargo_build_inputs,
20//! };
21//! use ic_testkit::ic_host_artifacts::artifact::hash_reader;
22//! use ic_testkit::ic_host_process::tool::{AdmittedTool, ExecutionContext, OutputLimits};
23//! use std::path::Path;
24//!
25//! // The caller holds its source lease and configures the Cargo shim and actual
26//! // compiler identity on spec. The admitted optimizer accepts INPUT -o OUTPUT.
27//! fn build_deployable(
28//!     spec: &WasmBuildSpec, post_cache: &Path, destination: &Path,
29//!     optimizer: &AdmittedTool, context: &ExecutionContext<'_>, limits: OutputLimits,
30//!     max_output_bytes: usize,
31//! ) -> Result<Vec<u8>, Box<dyn std::error::Error>>
32//! {
33//!     let resolved = resolve_cargo_build_inputs(spec)?;
34//!     let wasm = build_wasm_canisters_cached(spec)?;
35//!     let input = &wasm.record().artifacts()[0];
36//!     let post_spec = ArtifactCacheSpec::new(post_cache, "deploy", "optimizer/v1")
37//!         .with_cargo_build_inputs("cargo", spec, &resolved)
38//!         .with_input("wasm", input)
39//!         .with_tool("optimizer", optimizer.path())
40//!         .with_arguments(["<input>", "-o", "<output>"])
41//!         .with_environment(context.environment.iter().cloned())
42//!         .with_identity_bytes("optimizer-cwd", context.current_dir.as_os_str().as_encoded_bytes())
43//!         .with_output("deploy", destination);
44//!     let deploy = match prepare_artifact_cache(&post_spec)? {
45//!         ArtifactCachePreparation::Reused(record) => ArtifactCacheOutcome::Reused(record),
46//!         ArtifactCachePreparation::Build(transaction) => {
47//!             let output = transaction.output_path("deploy")?;
48//!             optimizer.run(&[input.into(), "-o".into(), output.clone().into()], context, limits)?;
49//!             hash_reader(std::fs::File::open(&output)?, max_output_bytes as u64)?;
50//!             transaction.commit()?
51//!         }
52//!     };
53//!     drop(wasm); // The post-link transaction has finished consuming the input.
54//!     let bytes = ic_testkit::ic_host_fs::read::read_file(
55//!         deploy.record().artifacts()[0].path(), max_output_bytes)?;
56//!     drop(deploy); // Reading is complete; maintenance may now reclaim it.
57//!     Ok(bytes)
58//! }
59//! ```
60
61mod cache_fs;
62mod digest;
63mod icp;
64mod transaction;
65mod transaction_batch;
66mod wasm;
67mod wasm_batch;
68mod wasm_cache;
69mod workspace;
70
71#[cfg(test)]
72mod test_support;
73
74#[cfg(all(test, unix))]
75mod host_tests;
76
77pub use cache_fs::{ArtifactCacheMaintenance, ArtifactCachePrunePolicy, ArtifactCachePruneReport};
78pub use digest::InputDigest;
79pub use icp::{
80    WatchedInputSnapshot, icp_artifact_ready_for_build, icp_artifact_ready_with_snapshot,
81};
82pub use transaction::{
83    ArtifactBuildTransaction, ArtifactCacheArtifact, ArtifactCacheError, ArtifactCacheOutcome,
84    ArtifactCachePreparation, ArtifactCacheRecord, ArtifactCacheSpec, ArtifactCacheTimings,
85    ArtifactOutputValidation, prepare_artifact_cache, prune_artifact_cache,
86};
87pub use transaction_batch::{
88    ArtifactCacheBatchContractError, ArtifactCacheBatchEntry, ArtifactCacheBatchFailedEntry,
89    ArtifactCacheBatchFailure, ArtifactCacheBatchFailurePhase, ArtifactCacheBatchFailureTimings,
90    ArtifactCacheBatchMetrics, ArtifactCacheBatchOutcomeEntry, ArtifactCacheBatchReport,
91    LabeledArtifactCacheSpec, build_artifact_caches_batch,
92};
93pub use wasm::{wasm_artifacts_ready, wasm_path};
94pub use wasm_batch::{
95    LabeledWasmBuildSpec, WasmBuildBatchConfig, WasmBuildBatchContractError, WasmBuildBatchEntry,
96    WasmBuildBatchFailure, WasmBuildBatchMaintenanceEntry, WasmBuildBatchMetrics,
97    WasmBuildBatchOutcomeEntry, WasmBuildBatchProgressEvent, WasmBuildBatchReport,
98    WasmBuildInputSnapshot, WasmBuildInputSnapshotMetrics, WasmBuildSession,
99    WasmBuildSessionMetrics, build_wasm_canisters_cached_batch,
100    build_wasm_canisters_cached_batch_with_config,
101    build_wasm_canisters_cached_batch_with_config_and_progress,
102    build_wasm_canisters_cached_batch_with_progress,
103};
104pub use wasm_cache::{
105    CargoBuildInput, ResolvedCargoBuildInputs, SharedIncrementalTargetInspection,
106    SharedIncrementalTargetMaintenance, SharedIncrementalTargetMaintenanceConfig,
107    SharedIncrementalTargetMaintenanceFailureMode, SharedIncrementalTargetMaintenanceOutcome,
108    SharedIncrementalTargetPrunePolicy, WasmBuildCacheMode, WasmBuildError,
109    WasmBuildFailureDetails, WasmBuildFailurePhase, WasmBuildFailureTimings, WasmBuildOutcome,
110    WasmBuildOutputStream, WasmBuildPhase, WasmBuildProgressConfig, WasmBuildProgressEvent,
111    WasmBuildProgressOutcome, WasmBuildProgressPhase, WasmBuildRecord, WasmBuildSpec,
112    WasmBuildTimings, WasmInputResolutionTimings, build_wasm_canisters_cached,
113    build_wasm_canisters_cached_with_progress, inspect_shared_incremental_target,
114    maintain_shared_incremental_target, maintain_shared_incremental_target_at_most_every,
115    prune_wasm_build_cache, resolve_cargo_build_inputs,
116};
117pub use workspace::{test_target_dir, workspace_root_for};