Skip to content

fix: e2e harness restores the stack, runs via uv - #222

Merged
catinspace-au merged 5 commits into
mainfrom
fix/e2e-harness
Oct 11, 2026
Merged

catinspace-au merged 5 commits into
mainfrom
fix/e2e-harness

Conversation

@catinspace-au

Copy link
Copy Markdown
Contributor

Four harness defects that turned up running make test-e2e on the docker GA target. One PR, because they all sit in the same run.

  • make test-e2e, test-resilience and test-flows ran bare system python3, so a host without PyYAML or Playwright failed at setup. The search-to-rule test failed that way on the GA target. The scripts now declare pyyaml==6.0.3 and playwright==1.63.0 inline (PEP 723) and the targets run uv run --script, so a host needs uv and Google Chrome, nothing else.
  • The suite stopped every service and left only ClickHouse running. It now reads the compose project first and, on every way out (failure and SIGTERM included), starts each service that was running or had run to completion again from the compose files, project and environment it came from. A last verdict fails if one comes back on a different config hash.
  • "Sending 1000 events" sat for 323 s. The receiver answers once the loader has flushed the record (a 200 ms early-flush window), so one request at a time paid a flush per event. It now sends 16 at a time.
  • post.py never deleted its three ingest rows. It now deletes them after every claim, the console claim that reads them back included. A table still carrying the _timestamp_optimized projection refuses a lightweight DELETE with Code 344 on ClickHouse 26.3, and a query-level lightweight_mutation_projection_mode does not lift it, so it falls back to ALTER TABLE ... DELETE, polled for up to 60 s and reported rather than failed.

Done when CI is green here and a full make test-e2e on the GA target leaves the stack exactly as it found it.

Heads up: #143 touches the same harness and already conflicts with main in 30 files. This branch adds no new conflicted file, but both change the test teardown in scripts/test_e2e.py, so whichever lands second re-resolves it.

`make test-e2e`, `test-resilience` and `test-flows` run through `uv run --script`. The scripts declare PyYAML 6.0.3 and Playwright 1.63.0 inline (PEP 723), so a host needs uv and nothing else from PyPI.

The suite reads the compose project before it stops anything, then on every way out (a failure and a SIGTERM included) starts each service that was running or had run to completion again, from the compose files, project and environment it came from. A last verdict fails when one comes back on a different config hash. `make test-e2e` no longer leaves only ClickHouse running.

The data file goes to the ingest edge 16 requests at a time. The receiver answers once the loader has flushed the record, so one request at a time paid a flush per event, and 1000 events took 323 s.

post.py deletes its three ingest rows once every claim has run, the console claim that reads them back included. A table still carrying the `_timestamp_optimized` projection refuses a lightweight DELETE with Code 344, so it falls back to an `ALTER TABLE ... DELETE` mutation, polled for up to 60 s and reported rather than failed.
A container an older e2e run started is labelled with that run's override under `.tmp/`, which the run deletes when it finishes. Naming it in the restore made compose refuse the whole `up`, so the next run failed to put that container back. A file that no longer exists is now left out and named in the log, and the config hash check still decides whether the container came back as it was.
dfe-engine depends on both brokers, each optional and gated by its own compose profile, so the restore's `--profile "*"` started both and the second failed on port 9092. The restore now asks compose for every service those files define and enables only the profiles of the services it starts, which is the set the original `make ci` enabled.
`scripts/test_e2e.py.lock` and `scripts/test_flows.py.lock` (from `uv lock --script`) record every package with a sha256 per file, the transitive greenlet, pyee and typing-extensions included. The make targets and the shebang run `uv run --locked`, so a lock that no longer matches its script stops the run instead of resolving something new.

Renovate's pep723 manager is opt-in (`managerFilePatterns: []`) and has no artifact step, so it can move an inline pin but never rewrites the lock beside it. `make check-locks` runs `uv lock --check` on each script with uv 0.13.0, and CI runs it after the unit tests. A stdlib test asserts every script with inline metadata is pinned exactly, has a lock recording those pins, and is named by `check-locks`.
@catinspace-au
catinspace-au merged commit ca7e4ff into main Oct 11, 2026
7 checks passed
@catinspace-au
catinspace-au deleted the fix/e2e-harness branch October 11, 2026 03:02
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