Skip to content

chore: one round per platform instead of checkup - #51

Merged
Harted merged 5 commits into
mainfrom
chore/test-rounds
Aug 30, 2026
Merged

chore: one round per platform instead of checkup#51
Harted merged 5 commits into
mainfrom
chore/test-rounds

Conversation

@Harted

@Harted Harted commented Aug 30, 2026

Copy link
Copy Markdown
Member

checkup was lint, typecheck, unit and e2e behind one name, and it said nothing about what a platform can actually run. Three rounds say it:

test:all:mac everything here, ending with the hardware specs
test:all:windows everything here, and socat is not here
test:all:linux everything, plus the two that wait for a person

Each puts the unattended work first, so the only thing left when it stops is the part that needs someone at the keyboard.

checkup was also the command CONTRIBUTING told a contributor to run before pushing, five times over. The rounds are far too heavy for that: they package, they take screenshots, two of them wait for hardware. So the pre-push name is verify, with exactly what checkup had, and CONTRIBUTING points at it.

The command table there grew the four suites that were missing from it as well: scan-perf, privileged-port, and the three rounds.

Harted and others added 5 commits August 30, 2026 13:35
`checkup` was lint, typecheck, unit and e2e behind one name, and it said
nothing about what a platform can actually run. Three rounds say it:

  test:all:mac      everything here, ending with the hardware specs
  test:all:windows  everything here, and socat is not here
  test:all:linux    everything, plus the two that wait for a person

Each puts the unattended work first, so the only thing left when it stops
is the part that needs someone at the keyboard.

The name a contributor runs before pushing is `verify`, with exactly what
`checkup` had. The rounds are for cutting a release: they package, they
take screenshots, and two of them wait for hardware.
assertOpenable built its device paths with path.join, which is the host's
join. The string it builds is a Linux device quoted back to the reader, not
a path on the machine running the check, so on Windows the unit suite got
\dev\ttyACM0 and failed.

The join in unreadablePorts stays as it is: that one does touch the running
machine, and there it should follow the platform.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014HBuLkUjywRUCPxQSuSUSB
Closing a real COM port took about 4.5s on the Windows VM these specs run
on, against a 5s wait in the test. The whole hardware suite lost that race:
disconnectClient failed outright, and the two disconnects in the reconnect
spec would have failed the same way had maxFailures let the run get there.

Measured with a temporary timer: the disconnect completed at 5314ms with
only "Disconnected from server" in the snackbars, so close() called back on
its own and the app's own 5s watchdog never fired. Slow, not stuck.

The watchdog in modbusClient.disconnect still sits at 5000ms, right on top
of an operation that takes ~4.5s here. Left alone: that is app behaviour,
and it may well be this VM's USB passthrough rather than the app.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014HBuLkUjywRUCPxQSuSUSB
Both hardware specs stopped at a page.pause() for someone to pick the COM
port by hand. That is why the suite sat outside every round on this
platform: an unattended run waited forever, and a release round could not
include it.

The board is identified by USB vendor id, read from the same serialport the
app uses. Not by manufacturer: on Windows that reads "Microsoft", because
the generic usbser driver claims the device, while vendorId still says 2341.
Only the two genuine Arduino ids count. A clone presents the id of whatever
bridge it carries, and those chips sit on hundreds of unrelated adapters, so
matching them would let the suite read registers off a random dongle. The
failure prints every port it saw, so extending the list is obvious.

Two boards fails rather than guesses. No board skips the suite, so a machine
without hardware does not block a release round.

test:all:windows now ends with the hardware specs, like the other two
rounds. Measured: 32 passed in 1.6m, no keyboard.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014HBuLkUjywRUCPxQSuSUSB
The hardware specs paused for a flat 5s or 10s after clicking read and then
asserted. Both were guesses, and one of them was wrong: the illegal-address
test timed out at 30s on Linux, four runs out of four.

Two things were hiding in there.

The read that follows enabling read-configuration is dropped when it arrives
too soon after the toggle. setReadConfiguration waits for Mui-selected, but
that class lands before the app can serve a read. Measured on the Arduino:
10ms before the click still fails, 100ms passes. READ_SETTLE_MS gives it 250ms.
This works around the race rather than fixing it -- clicking Read by hand
within that window loses the read too.

And two assertions proved nothing. Both this suite and connectAndRead checked
rowCount > 0, which stays true when the read fails completely, because the grid
keeps the rows it built from the config. They now wait for an actual cell value,
which is both stricter and faster.

The suite drops from 1.5m to under a minute: the illegal-address test from a
30s timeout to 2.5s, the re-read from 5.5s to 1s.

The 2000ms after connect stays. That one is not a guess -- the board reboots on
DTR when the port opens.
@Harted
Harted marked this pull request as ready for review August 30, 2026 17:46
@Harted
Harted merged commit 9ca804c into main Aug 30, 2026
1 check passed
@Harted
Harted deleted the chore/test-rounds branch August 30, 2026 17:46
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.

1 participant