Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion conformance/driver-ct/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ name = "compat"
path = "src/bin/compat.rs"

[dependencies]
component-test-runner = { workspace = true }
component-test-runner = { workspace = true, features = ["wizer"] }
polymorph-webcrypto-wasmtime = { path = "../../rust/wasmtime" }
wasmtime = { version = "47", features = ["component-model", "component-model-async", "async", "runtime"] }
wasmtime-wasi = "47"
Expand Down
20 changes: 19 additions & 1 deletion conformance/driver-ct/justfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ ct-tools := root + "/target/ct-tools"
ct := ct-tools + "/bin/component-test"
ct-runner := ct-tools + "/bin/ct-runner"
guest := root + "/target/wasm32-wasip2/release/conformance_guest_ct.wasm"
guest-wizened := root + "/target/conformance-guest-ct-wizened.wasm"
signing := root + "/target/wasm32-wasip2/release/conformance_signing_guest_ct.wasm"
provider := root + "/target/wasm32-wasip2/release/polymorph_webcrypto_guest_provider.wasm"
composed := root + "/target/conformance-composed-ct.wasm"
Expand Down Expand Up @@ -363,9 +364,26 @@ build-provider:
# aggregate's cross-check against targets.toml. The signing suite never
# runs composed: its world imports ecdsa-sign, so it cannot even link
# against the provider (the class-d recipe asserts exactly that).
#
# The suite is wizer-pre-initialized BEFORE composition: ct-runner's
# default fresh-instance-per-case containment pays the suite's registry
# construction per case, which dominated this leg's wall time; the
# wizened suite is born with the registry built, keeping per-case
# isolation at a fraction of the cost (the residual per-case tax is the
# census handle lift — measured ~2.6x less total CPU on this corpus).
# The order is forced from both sides: wasmtime-wizer cannot process
# the composed bundle (nested components with modules), and the bare
# suite's `polymorph:webcrypto/*` imports keep the shipped plain-suite
# `component-test wizen` out — so the driver's own `--wizen` mode
# (`wizen_with` over the same full-support linker the wasmtime leg
# runs) wizens the bare suite, and `wac plug` composes the result.
# --suite-artifact keeps the envelope identity and tags on the
# canonical bare artifact; the wizened enumeration is census-identical
# (the aggregate's lock binding gates that on every run).
run-composed: build build-provider _ct-tools
mkdir -p results
wac plug {{guest}} --plug {{provider}} -o {{composed}}
{{root}}/target/release/ct-driver {{guest}} --wizen {{guest-wizened}}
wac plug {{guest-wizened}} --plug {{provider}} -o {{composed}}
{{ct-runner}} {{composed}} --jobs 8 --jsonl \
--suite-artifact {{guest}} \
--missing ecdsa-sign --target composed > results/composed.jsonl
Expand Down
66 changes: 45 additions & 21 deletions conformance/driver-ct/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//!
//! Usage: ct-driver <suite.wasm> [--jsonl] [--missing f1,f2,...]
//! [--jobs N] [--cases-per-instance N] [--target key] [--only substring]
//! [--enumerate]
//! [--enumerate] [--wizen <out.wasm>]

use std::path::PathBuf;
use std::process::ExitCode;
Expand Down Expand Up @@ -48,6 +48,25 @@ impl RunnerView for Data {
}
}

fn make_data() -> Data {
Data {
wasi: WasiCtxBuilder::new().inherit_stderr().build(),
table: ResourceTable::new(),
ct: CtCtx::default(),
webcrypto: WasiWebcryptoCtx::default(),
}
}

/// The full-support target: every gated interface enabled.
fn configure_linker(linker: &mut wasmtime::component::Linker<Data>) -> wasmtime::Result<()> {
let mut options = LinkOptions::default();
options
.sha1_checked(true)
.rsa_sign(true)
.rsa_oaep_decrypt(true);
add_to_linker_with_options(linker, &options)
}

fn main() -> ExitCode {
match run() {
Ok(code) => code,
Expand All @@ -67,6 +86,7 @@ fn run() -> Result<ExitCode> {
let mut target: String = "wasmtime-rustcrypto".into();
let mut only: Option<String> = None;
let mut enumerate = false;
let mut wizen_out: Option<PathBuf> = None;
let mut args = std::env::args().skip(1);
while let Some(arg) = args.next() {
match arg.as_str() {
Expand Down Expand Up @@ -101,6 +121,12 @@ fn run() -> Result<ExitCode> {
}
"--jsonl" => mode = OutputMode::Jsonl,
"--enumerate" => enumerate = true,
"--wizen" => {
wizen_out =
Some(PathBuf::from(args.next().ok_or_else(|| {
anyhow::anyhow!("--wizen needs an output path")
})?));
}
_ if suite.is_none() => suite = Some(PathBuf::from(arg)),
other => bail!("unexpected argument `{other}`"),
}
Expand All @@ -109,7 +135,7 @@ fn run() -> Result<ExitCode> {
anyhow::anyhow!(
"usage: ct-driver <suite.wasm> [--jsonl] [--missing f1,f2,...] \
[--jobs N] [--cases-per-instance N] [--target key] [--only substring] \
[--enumerate]"
[--enumerate] [--wizen <out.wasm>]"
)
})?;
let suite_name = suite
Expand All @@ -118,25 +144,23 @@ fn run() -> Result<ExitCode> {
.unwrap_or("suite")
.to_string();

let runner = Runner::with_data(
&suite,
|| Data {
wasi: WasiCtxBuilder::new().inherit_stderr().build(),
table: ResourceTable::new(),
ct: CtCtx::default(),
webcrypto: WasiWebcryptoCtx::default(),
},
|linker| {
// The full-support target: every gated interface enabled.
let mut options = LinkOptions::default();
options
.sha1_checked(true)
.rsa_sign(true)
.rsa_oaep_decrypt(true);
add_to_linker_with_options(linker, &options)
},
)
.map_err(|e| anyhow::anyhow!("{e:#}"))?;
// Wizen mode: pre-initialize the suite — its own `all()` runs here,
// once, and the built registry is snapshotted into the emitted
// artifact, so every future instance skips registry construction.
// The suites import `polymorph:webcrypto/*`, which only this driver's
// linker can satisfy (`component-test wizen` serves plain suites
// only), hence `wizen_with` with the same store data and linker
// setup the run path uses.
if let Some(out) = wizen_out {
let bytes = std::fs::read(&suite)?;
let wizened = component_test_runner::wizen::wizen_with(&bytes, make_data, configure_linker)
.map_err(|e| anyhow::anyhow!("{e:#}"))?;
std::fs::write(&out, wizened)?;
return Ok(ExitCode::SUCCESS);
}

let runner = Runner::with_data(&suite, make_data, configure_linker)
.map_err(|e| anyhow::anyhow!("{e:#}"))?;

// The suite's full case enumeration (one name per line): the
// `lock --leaves` input that pins the generated rows' leaves.
Expand Down
Loading