diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index aad8448..7b23d1e 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -FROM denoland/deno:2.8.1 +FROM denoland/deno:2.9.4 # Install tools RUN apt-get update && \ diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index f1f76f0..f06fd3a 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -17,10 +17,10 @@ jobs: with: fetch-depth: 0 - - name: Setup Deno v2.8.1 + - name: Setup Deno v2.9.4 uses: denoland/setup-deno@v2 with: - deno-version: v2.8.1 + deno-version: v2.9.4 - name: Setup LCOV run: sudo apt install -y lcov @@ -45,7 +45,7 @@ jobs: strategy: fail-fast: false matrix: - deno-version: [v1.46.3, v2.8.1] + deno-version: [v1.46.3, v2.9.4] os: [ ubuntu-latest, windows-latest ] runs-on: ${{ matrix.os }} diff --git a/.github/workflows/sonar.yml b/.github/workflows/sonar.yml index 2f8f471..11985cb 100644 --- a/.github/workflows/sonar.yml +++ b/.github/workflows/sonar.yml @@ -33,10 +33,10 @@ jobs: ref: ${{ steps.pr.outputs.head_sha }} fetch-depth: 0 - - name: Setup Deno v2.8.1 + - name: Setup Deno v2.9.4 uses: denoland/setup-deno@v2 with: - deno-version: v2.8.1 + deno-version: v2.9.4 - name: Setup LCOV run: sudo apt install -y lcov diff --git a/tests/deps.ts b/tests/deps.ts index b68c6a3..4a2d8a8 100644 --- a/tests/deps.ts +++ b/tests/deps.ts @@ -23,6 +23,6 @@ export { beforeAll, afterEach } from 'jsr:@std/testing@1.0.19/bdd'; -export { delay } from 'jsr:@std/async@1.4.0/delay'; +export { delay } from 'jsr:@std/async@1.5.0/delay'; export { load } from 'jsr:@std/dotenv@0.225.7'; export * as mf from 'https://deno.land/x/mock_fetch@0.3.0/mod.ts'; \ No newline at end of file diff --git a/tests/utils/timed-match.test.ts b/tests/utils/timed-match.test.ts index 1000528..dd1ca01 100644 --- a/tests/utils/timed-match.test.ts +++ b/tests/utils/timed-match.test.ts @@ -7,9 +7,36 @@ const okInput = "a"; const nokRE = "^(([a-z])+.)+[A-Z]([a-z])+$"; const nokInput = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; -const COLD_TIME = 500; -const WARM_TIME = 50; -const TIMEOUT = 950; // 50ms margin for worker thread to finish +const COLD_TIME = 900; +const WARM_TIME = 150; +const TIMEOUT = 900; // margin for worker thread to finish + +// TimedMatch.setMaxTimeLimit has no getter; track the value tests intend to +// use so warmUpWorker() can restore it after temporarily raising it. +let intendedMaxTimeLimit = 1000; +const setMaxTimeLimit = (value: number) => { + intendedMaxTimeLimit = value; + TimedMatch.setMaxTimeLimit(value); +}; + +// A freshly (re)created worker pays a one-time JIT/module-instrumentation +// cost on its FIRST real regex dispatch (much larger under `deno test +// --coverage`, which also instruments the worker module). Calls after that +// on the same worker are fast (see the warm loop below). Issue a cheap +// throwaway match right after the worker is (re)created so that cost is +// paid during warm-up instead of during a timing-sensitive assertion. +// +// The warm-up dispatch itself must not be allowed to exceed the *current* +// maxTimeLimit: doing so would make TimedMatch treat the warm-up call as a +// timeout, recreate the worker again, and add an entry to the blacklist - +// potentially evicting the entry a test just set up (maxBlackListed is set +// to 1 in several tests). Temporarily raise the limit for the warm-up call +// only, then restore whatever the test currently expects. +const warmUpWorker = () => { + TimedMatch.setMaxTimeLimit(5000); + TimedMatch.tryMatch([okRE], okInput); + TimedMatch.setMaxTimeLimit(intendedMaxTimeLimit); +}; const getTimer = (timer: number) => (timer - Date.now()) * -1; @@ -21,7 +48,8 @@ describe("Timed-Match tests:", function () { beforeEach(() => { TimedMatch.clearBlackList(); TimedMatch.setMaxBlackListed(50); - TimedMatch.setMaxTimeLimit(1000); + setMaxTimeLimit(1000); + warmUpWorker(); }); afterAll(() => { @@ -48,6 +76,7 @@ describe("Timed-Match tests:", function () { timer = Date.now(); TimedMatch.tryMatch([nokRE], nokInput); assertTrue(getTimer(timer) > TIMEOUT); + warmUpWorker(); timer = Date.now(); TimedMatch.tryMatch([okRE], okInput);