tests: fix two-tab collab baseline race + build the jspi harnesses in CI
1) pcbnew/eeschema two-tab 'a local move propagates A->B' read the pre-move baseline AFTER kicadCollabTestMoveFirst. The move is queued through CallAfter + the apply coroutine, and the drain can land between two consecutive page.evaluate round-trips — when it does (~50% under CI load, reproduced locally with --repeat-each) orig captures the ALREADY-MOVED position and the not-toBe poll waits on itself. Wire tracing showed the bridge working: the moved delta emits, nothing reverts. Fix: baseline from kicadCollabSnapshot BEFORE the move. 12/12 green at --repeat-each=4 (was ~50% red). 2) jspi-firefox suites 404'd their harness modules: jspi-stack and jspi-coroutine build via ad-hoc build.sh (Phase 3 Makefile wiring TODO) which CI never ran. Wire both into build-wasm-test.sh (its hash is already in the testapps cache key), and add the _pt pthread variant that index.html?pt=1 loads but nothing built. jspi-firefox 8/8 green locally. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PmR6goSk7JC17h7fkgGvHG
This commit is contained in:
parent
c0ed5d59a7
commit
db84293af1
4 changed files with 54 additions and 11 deletions
|
|
@ -117,6 +117,19 @@ fi
|
||||||
echo ""
|
echo ""
|
||||||
echo "=== Build complete ==="
|
echo "=== Build complete ==="
|
||||||
|
|
||||||
|
# JSPI micro-harnesses (jspi-stack, jspi-coroutine): still on their ad-hoc
|
||||||
|
# per-directory build.sh scripts (Makefile.wasm wiring is the Phase 3 TODO).
|
||||||
|
# Without this the jspi/ Playwright suites 404 their built .mjs modules on any
|
||||||
|
# machine that never ran the scripts by hand — which is exactly what CI is.
|
||||||
|
if [ -z "$TARGET" ]; then
|
||||||
|
echo ""
|
||||||
|
echo "=== JSPI micro-harnesses ==="
|
||||||
|
for harness in jspi-stack jspi-coroutine; do
|
||||||
|
echo "Building $harness..."
|
||||||
|
"$STANDALONE_DIR/$harness/build.sh"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -n "$TARGET" ]; then
|
if [ -n "$TARGET" ]; then
|
||||||
# Show just the built target
|
# Show just the built target
|
||||||
echo ""
|
echo ""
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,24 @@ ROOT="$(cd ../../../.. && pwd)"
|
||||||
EMXX="${EMXX:-$ROOT/tools/emsdk/upstream/emscripten/em++}"
|
EMXX="${EMXX:-$ROOT/tools/emsdk/upstream/emscripten/em++}"
|
||||||
LIBCTX="$ROOT/kicad/thirdparty/libcontext"
|
LIBCTX="$ROOT/kicad/thirdparty/libcontext"
|
||||||
|
|
||||||
"$EMXX" coroutine_jspi_test.cpp "$LIBCTX/libcontext.cpp" \
|
COMMON=(
|
||||||
-I"$LIBCTX" \
|
-I"$LIBCTX"
|
||||||
\
|
-O1
|
||||||
-O1 \
|
-fwasm-exceptions -sSUPPORT_LONGJMP=wasm -sWASM_LEGACY_EXCEPTIONS=1
|
||||||
-fwasm-exceptions -sSUPPORT_LONGJMP=wasm -sWASM_LEGACY_EXCEPTIONS=1 \
|
-sJSPI -sJSPI_EXPORTS=pcbjam_libctx_entry,main
|
||||||
-sJSPI -sJSPI_EXPORTS=pcbjam_libctx_entry,main \
|
-sMODULARIZE=1 -sEXPORT_ES6=1
|
||||||
-sMODULARIZE=1 -sEXPORT_ES6=1 -sENVIRONMENT=node,web \
|
-sALLOW_MEMORY_GROWTH=1
|
||||||
-sALLOW_MEMORY_GROWTH=1 \
|
)
|
||||||
|
|
||||||
|
"$EMXX" coroutine_jspi_test.cpp "$LIBCTX/libcontext.cpp" "${COMMON[@]}" \
|
||||||
|
-sENVIRONMENT=node,web \
|
||||||
-o coroutine_jspi_test.mjs
|
-o coroutine_jspi_test.mjs
|
||||||
|
|
||||||
echo "built: coroutine_jspi_test.mjs"
|
# pthread variant (index.html?pt=1 / run_pt.mjs) — same battery with the
|
||||||
|
# pthread runtime linked, mirroring jspi-stack's *_pt build.
|
||||||
|
"$EMXX" coroutine_jspi_test.cpp "$LIBCTX/libcontext.cpp" "${COMMON[@]}" \
|
||||||
|
-pthread -sPTHREAD_POOL_SIZE=2 -sPTHREAD_POOL_SIZE_STRICT=0 \
|
||||||
|
-sENVIRONMENT=node,web,worker \
|
||||||
|
-o coroutine_jspi_test_pt.mjs
|
||||||
|
|
||||||
|
echo "built: coroutine_jspi_test.mjs + coroutine_jspi_test_pt.mjs"
|
||||||
|
|
|
||||||
|
|
@ -254,9 +254,19 @@ test.describe("eeschema collab bridge — two tabs (BroadcastChannel)", () => {
|
||||||
await startCollab(tabA);
|
await startCollab(tabA);
|
||||||
await startCollab(tabB);
|
await startCollab(tabB);
|
||||||
|
|
||||||
|
// Read the pre-move baseline BEFORE triggering the move: TestMoveFirst
|
||||||
|
// queues the commit through CallAfter + the apply coroutine, and the drain
|
||||||
|
// can land between two consecutive page.evaluate round-trips. A GetPos
|
||||||
|
// taken after the call raced that drain (~50% under CI load) and captured
|
||||||
|
// the ALREADY-MOVED position, so the not-toBe poll waited on itself.
|
||||||
|
const preSnap = await tabA.evaluate(() => JSON.parse(window.Module.kicadCollabSnapshot()));
|
||||||
|
const prePos = new Map<string, string>(
|
||||||
|
preSnap.added.map((i: { id: string; x: number; y: number }) => [i.id, `${i.x},${i.y}`]),
|
||||||
|
);
|
||||||
const uuid = await tabA.evaluate(() => window.Module.kicadCollabTestMoveFirst(2_000_000, 0));
|
const uuid = await tabA.evaluate(() => window.Module.kicadCollabTestMoveFirst(2_000_000, 0));
|
||||||
expect(uuid).toMatch(/[0-9a-f-]{36}/);
|
expect(uuid).toMatch(/[0-9a-f-]{36}/);
|
||||||
const orig = await tabA.evaluate((id) => window.Module.kicadCollabGetPos(id), uuid);
|
const orig = prePos.get(uuid);
|
||||||
|
expect(orig, "moved item present in pre-move snapshot").toBeTruthy();
|
||||||
|
|
||||||
// Wait until tab A's item actually moved (guards against a no-op false pass).
|
// Wait until tab A's item actually moved (guards against a no-op false pass).
|
||||||
await expect
|
await expect
|
||||||
|
|
|
||||||
|
|
@ -460,9 +460,19 @@ test.describe("pcbnew collab bridge — two tabs (BroadcastChannel)", () => {
|
||||||
await startCollab(tabA);
|
await startCollab(tabA);
|
||||||
await startCollab(tabB);
|
await startCollab(tabB);
|
||||||
|
|
||||||
|
// Read the pre-move baseline BEFORE triggering the move: TestMoveFirst
|
||||||
|
// queues the commit through CallAfter + the apply coroutine, and the drain
|
||||||
|
// can land between two consecutive page.evaluate round-trips. A GetPos
|
||||||
|
// taken after the call raced that drain (~50% under CI load) and captured
|
||||||
|
// the ALREADY-MOVED position, so the not-toBe poll waited on itself.
|
||||||
|
const preSnap = await tabA.evaluate(() => JSON.parse(window.Module.kicadCollabSnapshot()));
|
||||||
|
const prePos = new Map<string, string>(
|
||||||
|
preSnap.added.map((i: { id: string; x: number; y: number }) => [i.id, `${i.x},${i.y}`]),
|
||||||
|
);
|
||||||
const uuid = await tabA.evaluate(() => window.Module.kicadCollabTestMoveFirst(2_000_000, 0));
|
const uuid = await tabA.evaluate(() => window.Module.kicadCollabTestMoveFirst(2_000_000, 0));
|
||||||
expect(uuid).toMatch(/[0-9a-f-]{36}/);
|
expect(uuid).toMatch(/[0-9a-f-]{36}/);
|
||||||
const orig = await tabA.evaluate((id) => window.Module.kicadCollabGetPos(id), uuid);
|
const orig = prePos.get(uuid);
|
||||||
|
expect(orig, "moved item present in pre-move snapshot").toBeTruthy();
|
||||||
|
|
||||||
await expect
|
await expect
|
||||||
.poll(() => tabA.evaluate((id) => window.Module.kicadCollabGetPos(id), uuid), {
|
.poll(() => tabA.evaluate((id) => window.Module.kicadCollabGetPos(id), uuid), {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue