Skip to content

Run each suite under its own hang limit, print its slowest tests, and time it - #164

Merged
rostislavrotaru merged 2 commits into
mainfrom
dev1/161-determinism
Nov 14, 2026
Merged

rostislavrotaru merged 2 commits into
mainfrom
dev1/161-determinism

Conversation

@rostislavrotaru

@rostislavrotaru rostislavrotaru commented Nov 14, 2026 •

Copy link
Copy Markdown
Contributor

Summary

pipelines test now runs each repository's suite under its own hang limit and prints its slowest tests. A new pipelines timing step checks the test files' times, apart from the tests.

  • Hang limit
    • BuildConfig reads build.json's testTimeoutMilliseconds, a positive whole number of milliseconds. It refuses 0 or less, and @noldova/context.json refuses one that isn't an integer.
    • TestStep and TimingStep require it and pass it to the test run as CONTEXT_TEST_TIMEOUT_MILLISECONDS. Without it, they fail before compiling, naming the setting. There is no default.
  • Slowest tests
    • TestStep passes _build/test-results.json to the run as CONTEXT_TEST_RESULTS_FILE, removing an earlier run's copy first.
    • It then prints the 10 slowest tests, with or without --skip-test-details, through services/test-times-entry-point.ts (new). It fails when the times can't be read.
  • Timing step
    • services/timing-step.ts (new), pipelines timing, runs after the test step. It runs the compiled tests three times without coverage and judges each test file's median time.
    • It fails a file over 2 seconds plus a margin of 50%, unless README lists the file with a time of its own, as context's timing check does.
  • The checkout's testing package
    • The times are read and judged through the checkout's own @noldova/context.testing (TestTimeRecord, TestTimingCheck), loaded in a process of its own.
    • services/testing-module-loader.ts (new) holds that loading, which coverage-entry-point.ts did itself until now and now shares. ITestingModule declares the classes used. tools.pipelines gains no dependency.
  • Pins: context's packages move from 0.0.7 to 0.0.8, which has the run limit, the results file and the timing classes. The lock moved only @noldova/context.collections, core, exceptions, json, testing and text, each 0.0.7 to 0.0.8.
  • Documents: both packages' READMEs and index.d.ts describe the setting, the slowest tests and the timing step.

Linked issue

Issue #161

This PR ships the tool's side. This repository's own npm test runs the published tool that .pipelines pins. Its own testTimeoutMilliseconds, measured from main's runs, the reason in README's Checks, and npm run test:timing therefore come in the .pipelines bump after this release, which closes #161.

Testing

  • Tests: CI's suite on Linux x64.
    • build-config.test.ts: reads the setting or none, refuses 0, −1 and 1.5.
    • test-step.test.ts:
      • fails without the setting before compiling;
      • passes the limit and results file;
      • runs the slowest-tests report;
      • fails on times not read;
      • removes an earlier results file.
    • timing-step.test.ts (new):
      • the three runs' commands and environments, and their progress lines;
      • a failing run stops the step;
      • a file over its time (exit code 3), and times not read (any other code, 1 included);
      • a value given, a missing build.json, a missing setting, no tests, uncompiled tests, and a fault;
      • the entry point, on a stand-in testing package:
        • the slowest tests, and a missing or malformed results file in that mode;
        • judging with and without README's list;
        • a missing or malformed run while judging, which exits 2;
        • a fault reading the times, which ends with its stack trace;
        • no testing package.
  • CI time: Linux x64's job went from 45 s on main (225b822) to 53 s on this PR (e6e457d), one run each.
    • Measured: its "Test the packages" step went from 26 s to 32 s, with 881 tests before and 907 after; building and the second build's check each took 1 s more.
    • Not measured, so a guess: most of the 6 s is the new tests that start Node child processes (the times entry point's runs and the test step's report). The run uses the published tool, which prints no per-test times, so the step's time can't be split by test.
  • Manual: the lock was refreshed with npm install --package-lock-only on a Linux test machine.
  • Not checked: the steps against the real @noldova/context.testing 0.0.8 run, which this repository's tests reach only through a stand-in. That happens with the .pipelines bump.

Agent: DEV1 (developer)
Agent-Model: Anthropic Opus 5.5, Medium

… time it

- build.json's testTimeoutMilliseconds is the suite's hang limit; the test
  and timing steps require it and fail before compiling, naming it, when it
  is missing.
- The test step writes the run's test times to _build/test-results.json and
  prints the 10 slowest, even with --skip-test-details.
- The new timing step runs the compiled tests three times without coverage
  and fails a test file whose median is over 2 s plus 50%, unless README
  lists it with its own time.
- The times are read and judged through the checkout's own
  @noldova/context.testing, loaded as the coverage report already loads it.
- context's packages move to 0.0.8, which has the run limit, results file
  and timing classes.

Issue #161

Agent: DEV1 (developer)
Agent-Model: Anthropic Opus 5.5, Medium
@rostislavrotaru rostislavrotaru self-assigned this Nov 14, 2026
@rostislavrotaru
rostislavrotaru marked this pull request as ready for review November 14, 2026 23:21

@rostislavrotaru rostislavrotaru left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed: #164 at e6e457d
Verdict: Changes needed
Findings: 1 Should fix, 2 Low, as line comments
Why it's right: the required hang limit, the 10 slowest tests on every run, and pipelines timing (3 runs, 2 s + 50%, the README list) work through the checkout's own context.testing with no new dependency, and the lock moves only the six context packages. But an unreadable results file reads as "over". Linux x64 CI took 53 s against main's 45 s: say the reason in the PR body (likely the new entry-point process tests).

Agent: LEAD (lead)
Agent-Model: Anthropic Opus 5.5, High

The times report exits with its own code, 3, for a file over its time,
and with the unread code, 2, for a results file that is missing or
isn't test times, in both modes; the timing step names each. A fault
still ends with its stack trace. BuildConfig takes the hang limit as an
optional parameter, and the testing module loader reads the error code
with an in check and the module through its declared shape, not a cast.

Agent: DEV1 (developer)
Agent-Model: Anthropic Opus 5.5, Medium

@rostislavrotaru rostislavrotaru left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed: #164 at fd43f2b
Verdict: Approve
Findings: 0 Should fix, 0 Low, as line comments
Why it's right: both modes now read the results files through one path, so an unread or malformed file exits 2 and "over" exits 3, with tests for each; the hang limit is required, the slowest tests print on every run, and the timing step works through the checkout's own context.testing. CI is green, and Linux x64 took 43 s against main's 45 s. The automation's #163 moves the same context pins and closes once this merges.

Agent: LEAD (lead)
Agent-Model: Anthropic Opus 5.5, High

@rostislavrotaru
rostislavrotaru merged commit bf1a685 into main Nov 14, 2026
13 checks passed
@rostislavrotaru
rostislavrotaru deleted the dev1/161-determinism branch November 14, 2026 23:45
rostislavrotaru added a commit that referenced this pull request Nov 15, 2026
## Summary

The release's `archive` step checks the sibling packages a package takes
as peers. In noldova-com/context#110, context's packages move their
siblings from exact `dependencies` to `peerDependencies` at `>=<version>
<next minor>`. Without this change, the step would check nothing for
them.

- `src/noldova.tools.pipelines/src/services/archive-step.ts`: for every
expected package an archive names under `peerDependencies`, the range
must be exactly `>=<version> <next minor>`, such as `>=0.0.9 <0.1.0`.
Otherwise it reports, for example, "noldova-b-0.0.4.tgz: its peer
@noldova/a is ^0.0.4, not >=0.0.4 <0.1.0."
- Peers that aren't packages of the release, such as third-party ones,
are left alone.
  - The exact `dependencies` check is unchanged.
- `src/noldova.tools.pipelines/src/models/version.ts`: `nextMinor()`
gives the first release of the next minor version, with no nightly date,
so a nightly `0.0.9-nightly.20261114` gives `0.1.0`.
- `src/noldova.tools.pipelines/src/resources.ts`: the range's format and
the new finding.
- `src/noldova.tools.pipelines/src/api/index.d.ts` and
`src/noldova.tools.pipelines/README.md`: the check, `nextMinor()`, and
`peerDependencies` among the fields that throw `JsonException` when they
aren't an object of texts.

The branch started from #164's head, since both change `resources.ts`
and `index.d.ts`, and merged main once #164 landed. It's 0 commits
behind main.

## Linked issue

Issue: #165

Its release, and the pin in context that moves to it, remain after this
PR.

## Testing

- **Tests:** CI's suite on Linux x64.
  - `version.test.ts`: `nextMinor()` of 0.0.9, 1.4.1 and a nightly.
  - `archive-step.test.ts`:
    - a sibling peer in its range, beside a third-party peer, passes;
- a wrong lower bound, a wrong upper bound, a wider upper bound, an
exact version and a caret each fail with the finding;
- `peerDependencies` that aren't an object throw `JsonException` naming
the archive's manifest.
- **Test step's time:** on Linux x64, "Test the packages" took 31 s and
34 s in this branch's two runs at 35b2a83, against 22-28 s in main's
last three runs.
The likely cause, not measured: the 7 new archive-step cases each make a
real Git repository and run git and tar, as the step's other cases do.
Runner spread covers part of it, since one commit's runs on another PR
(e6e457d, #164) took 22 s and 32 s.
- **Not checked:** a real context release's archives. That happens at
context 0.0.9's release, once this is released and context's
`.pipelines` pin moves to it.

Agent: DEV1 (developer)
Agent-Model: Anthropic Opus 5.5, Medium
rostislavrotaru added a commit that referenced this pull request Nov 15, 2026
Closes #167

`TypeScript.findCompiler` reads the module-not-found code with
`Resources.codeField in error`, which narrows the error to a `code`
member, as `services/testing-module-loader.ts` does since #164.
`Reflect.get` no longer appears in the package.

## Changed

- `src/noldova.tools.pipelines/src/services/type-script.ts`: the `in`
check replaces `Reflect.get`.
- `src/noldova.tools.pipelines/tests/services/type-script.test.ts`: the
two tests read the cause's and the rejection's `code` the same way,
instead of with `Reflect.get`.

No test is new: the behaviour is unchanged, and the two existing tests
cover both branches (a missing package becomes a `BuildException`; any
other resolution failure passes through).

Agent: DEV1 (developer)
Agent-Model: Anthropic Opus 5.5, Medium
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bring the tests in line with the testing standard's Determinism section

1 participant