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
59 changes: 59 additions & 0 deletions harness/src/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,65 @@ const TRAP_MESSAGE_EQUIVALENTS: Array<
"unreachable",
["Unreachable code should not be executed"],
],
// Wasmtime's supplementary corpus uses the bare canonical core-trap name
// (crates/environ/src/trap_encoding.rs:138), unlike the official corpus's
// longer form above. The runtime still exposes raw engine text through
// mapCoreException, so this is the same core `unreachable` operation.
[
"wasm `unreachable` instruction executed",
[
"guest trapped: unreachable",
"guest trapped: unreachable executed",
"guest trapped: Unreachable code should not be executed",
],
],
// definitions.py:2344-2355 gives inc-at-2^16 and dec-below-zero the same
// trap operation. Pinned Wasmtime deliberately names that shared category
// BackpressureOverflow (crates/environ/src/trap_encoding.rs:254-256).
["backpressure counter overflow", ["backpressure counter underflow"]],
// definitions.py:2445-2452 rejects exactly resolve_delivered(); these are
// the pinned Wasmtime category and runtime call-site spellings for it.
[
"`subtask.cancel` called after terminal status delivered",
["subtask.cancel on a subtask whose resolution was already delivered"],
],
// definitions.py:2512,2566,2618 has one condition for a synchronous
// read/write/cancel on an end in a waitable set. Keep the runtime spellings
// explicit so unrelated synchronous-operation diagnostics cannot match.
[
"waitable cannot be used synchronously while added to a waitable set",
[
"future.cancel-write: synchronous cancel on an end that is in a waitable set",
"future.cancel-read: synchronous cancel on an end that is in a waitable set",
"stream.cancel-write: synchronous cancel on an end that is in a waitable set",
"stream.cancel-read: synchronous cancel on an end that is in a waitable set",
"synchronous future copy on an end that is in a waitable set",
"synchronous stream copy on an end that is in a waitable set",
],
],
// Pinned Wasmtime's guest_read/guest_write terminal-state checks
// (futures_and_streams.rs:3512-3514,3757-3759) and the runtime's CopyState.DONE
// checks (runtime/src/intrinsics/stream_builtins.ts:156-161) are identical;
// only the preposition differs. Do not include the future-write OR-category,
// whose message combines a successful prior write with peer drop.
[
"cannot read after being notified that the writable end dropped",
["cannot read from stream after being notified that the writable end dropped"],
],
[
"cannot write after being notified that the readable end dropped",
["cannot write to stream after being notified that the readable end dropped"],
],
// The same-instance non-numeric guard is the exact check on both sides:
// runtime/src/task/streams.ts:587-591,708-711,725-728 and pinned Wasmtime
// futures_and_streams.rs:3330-3335. Future/stream names are diagnostic only.
[
"cannot read from and write to intra-component future/stream with non-numeric payload",
[
"cannot read from and write to intra-component future",
"cannot read from and write to intra-component stream",
],
],
];

// Exported for the unit-test suite (tests/runner_unit_test.ts) to pin the
Expand Down
116 changes: 0 additions & 116 deletions harness/src/wasmtime-expectations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,48 +115,6 @@ export const WASMTIME_EXPECTATION_GROUPS: readonly WasmtimeExpectationGroup[] =
{
class: "diagnostic-mismatch",
files: [
{
file: "async/backpressure-overflow.json",
rows: [{
lines: [36],
cause:
'Error: expected trap "backpressure counter overflow", got "backpressure counter underflow"',
status: "failed",
}],
},
{
file: "async/cancel-host.json",
rows: [{
lines: [256],
cause:
'Error: expected trap "`subtask.cancel` called after terminal status delivered", got "subtask.cancel on a subtask whose resolution was already delivered"',
status: "failed",
}],
},
{
file: "async/cancel-sync-and-waitable.json",
rows: [{
lines: [68],
cause:
'Error: expected trap "waitable cannot be used synchronously while added to a waitable set", got "future.cancel-write: synchronous cancel on an end that is in a waitable set"',
status: "failed",
}, {
lines: [121],
cause:
'Error: expected trap "waitable cannot be used synchronously while added to a waitable set", got "future.cancel-read: synchronous cancel on an end that is in a waitable set"',
status: "failed",
}, {
lines: [174],
cause:
'Error: expected trap "waitable cannot be used synchronously while added to a waitable set", got "stream.cancel-write: synchronous cancel on an end that is in a waitable set"',
status: "failed",
}, {
lines: [227],
cause:
'Error: expected trap "waitable cannot be used synchronously while added to a waitable set", got "stream.cancel-read: synchronous cancel on an end that is in a waitable set"',
status: "failed",
}],
},
{
file: "async/future-read.json",
rows: [{
Expand All @@ -166,70 +124,15 @@ export const WASMTIME_EXPECTATION_GROUPS: readonly WasmtimeExpectationGroup[] =
status: "failed",
}],
},
{
file: "async/intra-futures.json",
rows: [{
lines: [55],
cause:
'Error: expected trap "cannot read from and write to intra-component future/stream with non-numeric payload", got "cannot read from and write to intra-component future"',
status: "failed",
}],
},
{
file: "async/intra-streams.json",
rows: [{
lines: [56],
cause:
'Error: expected trap "cannot read from and write to intra-component future/stream with non-numeric payload", got "cannot read from and write to intra-component stream"',
status: "failed",
}],
},
{
file: "async/stream-cancel-finished-op.json",
rows: [{
lines: [232, 234, 236],
cause:
'Error: expected trap "cannot read after being notified that the writable end dropped", got "cannot read from stream after being notified that the writable end dropped"',
status: "failed",
}, {
lines: [239, 241, 243],
cause:
'Error: expected trap "cannot write after being notified that the readable end dropped", got "cannot write to stream after being notified that the readable end dropped"',
status: "failed",
}, {
lines: [247, 249, 251],
cause:
'Error: expected trap "cannot write after being notified that the readable end dropped", got "cannot write to future after previous write succeeded or readable end dropped"',
status: "failed",
}],
},
{
file: "async/subtask-wait.json",
rows: [{
lines: [82],
cause:
'Error: expected trap "wasm `unreachable` instruction executed", got "guest trapped: unreachable"',
status: "failed",
}],
},
{
file: "async/sync-and-async-waitable.json",
rows: [{
lines: [123],
cause:
'Error: expected trap "waitable cannot be used synchronously while added to a waitable set", got "synchronous future copy on an end that is in a waitable set"',
status: "failed",
}],
},
{
file: "async/sync-call-context-trap.json",
rows: [{
lines: [47],
cause:
'Error: expected trap "wasm `unreachable` instruction executed", got "guest trapped: unreachable"',
status: "failed",
}],
},
{
file: "async/task-return-traps.json",
rows: [{
Expand All @@ -256,16 +159,6 @@ export const WASMTIME_EXPECTATION_GROUPS: readonly WasmtimeExpectationGroup[] =
cause:
'Error: expected trap "cannot write after being notified that the readable end dropped", got "cannot write to future after previous write succeeded or readable end dropped"',
status: "failed",
}, {
lines: [643, 645, 647, 649],
cause:
'Error: expected trap "cannot write after being notified that the readable end dropped", got "cannot write to stream after being notified that the readable end dropped"',
status: "failed",
}, {
lines: [652, 654, 658, 660],
cause:
'Error: expected trap "cannot read after being notified that the writable end dropped", got "cannot read from stream after being notified that the writable end dropped"',
status: "failed",
}],
},
{
Expand Down Expand Up @@ -295,15 +188,6 @@ export const WASMTIME_EXPECTATION_GROUPS: readonly WasmtimeExpectationGroup[] =
status: "failed",
}],
},
{
file: "trap.json",
rows: [{
lines: [30],
cause:
'Error: expected trap "wasm `unreachable` instruction executed", got "guest trapped: unreachable"',
status: "failed",
}],
},
{
file: "types.json",
rows: [{
Expand Down
63 changes: 63 additions & 0 deletions harness/tests/runner_unit_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,3 +262,66 @@ Deno.test("trapMatches: an unrelated engine trap message does not falsely match
"unrelated trap",
);
});

Deno.test("trapMatches: verified diagnostic equivalents match only their named operations", () => {
const equivalents: Array<[string, string]> = [
["backpressure counter overflow", "backpressure counter underflow"],
[
"`subtask.cancel` called after terminal status delivered",
"subtask.cancel on a subtask whose resolution was already delivered",
],
[
"waitable cannot be used synchronously while added to a waitable set",
"future.cancel-read: synchronous cancel on an end that is in a waitable set",
],
[
"waitable cannot be used synchronously while added to a waitable set",
"synchronous stream copy on an end that is in a waitable set",
],
[
"cannot read after being notified that the writable end dropped",
"cannot read from stream after being notified that the writable end dropped",
],
[
"cannot write after being notified that the readable end dropped",
"cannot write to stream after being notified that the readable end dropped",
],
[
"cannot read from and write to intra-component future/stream with non-numeric payload",
"cannot read from and write to intra-component future",
],
[
"wasm `unreachable` instruction executed",
"guest trapped: unreachable",
],
];
for (const [expected, actual] of equivalents) {
assertEq(trapMatches(expected, actual), true, `${expected} / ${actual}`);
}
});

Deno.test("trapMatches: narrow diagnostic rows reject adjacent but different traps", () => {
const nonEquivalents: Array<[string, string]> = [
["integer overflow", "integer underflow"],
["backpressure counter overflow", "reference count overflow"],
[
"waitable cannot be used synchronously while added to a waitable set",
"wasm trap: deadlock detected: event loop cannot make further progress",
],
[
"cannot write after being notified that the readable end dropped",
"cannot write to future after previous write succeeded or readable end dropped",
],
[
"cannot read from and write to intra-component future/stream with non-numeric payload",
"cannot have concurrent operations active on a future/stream",
],
[
"uncaught exception propagated out of component",
"guest trapped: unreachable",
],
];
for (const [expected, actual] of nonEquivalents) {
assertEq(trapMatches(expected, actual), false, `${expected} / ${actual}`);
}
});
Loading