From 1830e7cb68c42496e40ed4bdb20dee903c5c802e Mon Sep 17 00:00:00 2001 From: sneak Date: Sun, 4 Oct 2026 12:39:56 +0000 Subject: [PATCH] test: load the popup's libraries once per test file, not on every boot (closes #428) Every popup boot in the tests resets jest's module registry so that src/ loads fresh, and that also reloaded ethers, libsodium-wrappers-sumo, qrcode and ethereum-blockies-base64 each time. tests/support/popupBoot.js now loads those four once per test file and registers them once with jest.doMock(), which jest.resetModules() keeps, so every boot gets the same copies. No test or assertion changed. make test takes 8-13s on the shared build host, down from 17-25s, measured in alternating runs before and after the change. Model: opus-5-5 --- Dockerfile | 11 +++++------ TODO.md | 9 +++++++++ script/test | 12 ++++++------ tests/support/popupBoot.js | 20 ++++++++++++++++++++ 4 files changed, 40 insertions(+), 12 deletions(-) diff --git a/Dockerfile b/Dockerfile index 97bd6bd..02f2c90 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,12 +8,11 @@ WORKDIR /app # image sets it. ENV AUTISTMASK_LINT_NATIVE=1 -# script/test's default 30s bound is the host figure, against a suite that -# takes 23-29s there with three jest workers. In here the same suite starts on -# a cold jest cache and shares the runner with the rest of the build, so 30s -# is too tight — it killed a healthy suite at 30.6s on a cold CI cache. 180s -# still catches a hang in three minutes and cannot be tripped by a suite that -# is merely running on contended hardware. +# script/test's default 30s bound is the host figure. In here the same suite +# starts on a cold jest cache and shares the runner with the rest of the build, +# so 30s is too tight — it killed a healthy suite at 30.6s on a cold CI cache. +# 180s still catches a hang in three minutes and cannot be tripped by a suite +# that is merely running on contended hardware. ENV AUTISTMASK_TEST_TIMEOUT=180 # script/bootstrap installs all prerequisites (make via apt here; node diff --git a/TODO.md b/TODO.md index b7734b1..b68b5a0 100644 --- a/TODO.md +++ b/TODO.md @@ -45,6 +45,15 @@ but the review is broader than any of them. # Completed Steps +- 2026-10-04: `make test` takes 8-13s on the shared build host, down from + 17-25s, measured in alternating runs before and after the change + ([#428](https://git.eeqj.de/sneak/AutistMask/issues/428)). Each popup boot in + the tests (`tests/support/popupBoot.js`) resets jest's module registry so that + everything under `src/` loads fresh, and that also reloaded `ethers`, + `libsodium-wrappers-sumo`, `qrcode` and `ethereum-blockies-base64` every time. + Those four libraries are now loaded once per test file and handed to every + boot. No test or assertion changed. + - 2026-10-04: A token whose scale is unknown reads the same on the Send screen as on the confirmation screen ([#377](https://git.eeqj.de/sneak/AutistMask/issues/377)). When two addresses' diff --git a/script/test b/script/test index ebe015c..72fc6f1 100755 --- a/script/test +++ b/script/test @@ -5,12 +5,12 @@ # many-core shared host one per core took gigabytes of RAM per run. # # The timeout bounds a hung suite; it is not a performance budget. On the busy -# shared build host the suite takes 23-29s with three workers, so -# REPO_POLICIES' 30s cap is tight there, not comfortable. Inside the image the -# same suite also pays a cold jest cache and shares the runner with the rest of -# the build, which is not what that budget describes, so the Dockerfile raises -# the bound through AUTISTMASK_TEST_TIMEOUT. A cap a healthy suite can trip on a -# cold cache produces a red that means nothing, and teaches "just run it again". +# shared build host the suite takes 8-13s with three workers, inside +# REPO_POLICIES' 20s budget. Inside the image the same suite also pays a cold +# jest cache and shares the runner with the rest of the build, which is not what +# that budget describes, so the Dockerfile raises the bound through +# AUTISTMASK_TEST_TIMEOUT. A cap a healthy suite can trip on a cold cache +# produces a red that means nothing, and teaches "just run it again". set -eu ROOT="$(cd "$(dirname "$0")/.." && pwd -P)" diff --git a/tests/support/popupBoot.js b/tests/support/popupBoot.js index e8dcebb..68fce1d 100644 --- a/tests/support/popupBoot.js +++ b/tests/support/popupBoot.js @@ -20,6 +20,26 @@ const path = require("path"); const { makeStorageStub } = require("./storageStub"); +// The four libraries the popup loads from node_modules, loaded once per test +// file and handed to every boot. jest.resetModules() in bootPopup() empties the +// module cache but keeps what jest.doMock() registered, so these registrations +// hold for every boot in the file and the libraries are not loaded again. None +// of them holds popup state; everything under src/ is still loaded fresh on +// each boot. +// +// A test's own mock of one of them: a jest.doMock() made inside the test +// replaces the registration here, as it would for any module. A top-of-file +// jest.mock() is what the require() below gets, so it is kept, but its factory +// runs once per file and every boot shares the same mock object. +const ethers = require("ethers"); +const sodium = require("libsodium-wrappers-sumo"); +const QRCode = require("qrcode"); +const makeBlockie = require("ethereum-blockies-base64"); +jest.doMock("ethers", () => ethers); +jest.doMock("libsodium-wrappers-sumo", () => sodium); +jest.doMock("qrcode", () => QRCode); +jest.doMock("ethereum-blockies-base64", () => makeBlockie); + const POPUP_HTML = fs.readFileSync( path.join(__dirname, "..", "..", "src", "popup", "index.html"), "utf8", -- 2.54.0