Remove the live-provider test tier - #17
Conversation
These tests never ran anywhere. Neither CI workflow sets a single provider key, so tests/integration always skipped; running it needed five paid accounts; and every per-provider test pointed at an in-process mock Lago, so it could not prove Lago accepts an event even when it did run. They also never shipped to clients — the wheel is built from src/ only. Adapter behaviour stays pinned by the captured real responses under tests/unit/adapters/fixtures/, which is what the unit tests assert against. CONTRIBUTING now says so explicitly, so the removal does not read as "provider shapes are unverified", and the add-a-provider recipe loses its "add a live integration test" step. Live verification moves to a driver script pointed at a real Lago instance: that is the only way to exercise what these tests could not — llm_cost against a dynamic charge, and precise_total_amount_cents being accepted.
ancorcruz
left a comment
There was a problem hiding this comment.
Review — dropping the live tier
Agreed on the substance: eight of the nine files are skipif-gated on provider credentials, CI runs only tests/unit, so they were dead weight in the repo and the captured fixtures are the better contract. No objection to those going.
One file in the set isn't a live-provider test, flagged inline: test_outage_replay.py has no skipif and needs no credentials — it spins a local HTTPServer on 127.0.0.1 that toggles 503→200. It runs anywhere, and it covers exactly the queue paths #18 rewrites.
Separately, and worth fixing at the repo level: none of these three PRs has run CI. ci.yml triggers on pull_request: branches: [main], which filters on the PR's base. All three PRs in this stack target other branches in the stack, so there are zero workflow runs on any of them:
feature/cloudflare-gateway-connector runs=14
chore/drop-live-test-tier runs=0
fix/queue-subscription-and-pricing runs=0
fix/gateway-and-gemini-attribution runs=0
That means the four blocker fixes in #18 have no automated verification at all. Splitting the work into a stack was the right move, but it silently opted the whole stack out of CI — the one thing that made #13's size tolerable.
I ran the CI job locally against each branch in turn. All three are clean:
| branch | ruff | format | mypy | pytest |
|---|---|---|---|---|
chore/drop-live-test-tier |
pass | pass | pass | 513 passed |
fix/queue-subscription-and-pricing |
pass | pass | pass | 531 passed |
fix/gateway-and-gemini-attribution |
pass | pass | pass | 533 passed |
Dropping the branches: [main] filter from the pull_request trigger (keeping it on push) would cover any stacked PR from here on.
| return s, f"http://127.0.0.1:{s.server_port}" | ||
|
|
||
|
|
||
| def test_outage_replay_preserves_order_and_count(): |
There was a problem hiding this comment.
Keep this one — it's the only file in the set that isn't a live-provider test, and it covers what #18 changes.
Checked all nine: eight carry a skipif gated on provider or Lago credentials. This one has no skipif and no credentials — _spawn() starts a local HTTPServer on 127.0.0.1:0 whose failing flag returns 503, so both tests run offline, in-process, in about a second.
What they assert is the queue's contract under an outage: 200 events buffered through a failure window arrive in order and complete (test_outage_replay_preserves_order_and_count), and a long outage at the buffer cap drops the oldest then drains the rest (test_long_outage_at_buffer_cap_drops_oldest_then_drains).
That is the same surface #18 reworks — _PERMANENT_STATUSES, _send_individually, _replay_failed ordering, the overflow path. #18's own unit tests are good and cover the specific regressions, but they drive EventQueue directly with fake senders; this is the only thing in the repo that exercises buffer → HTTP → retry → recovery end to end against a real socket. Deleting it in the PR immediately beneath the one that rewrites those paths is the wrong order.
Since CI only runs tests/unit, this file has never actually run in CI either — so the fix is to move it rather than keep it where it is. tests/unit/test_queue_outage.py (or a tests/local/ that CI also runs) gets it executing for the first time. It takes ~1s and needs no network.
The other eight: no argument, they should go.
There was a problem hiding this comment.
You are right, and I got this one wrong. I lumped all nine files together as "the live tier" without checking each for a skipif — test_outage_replay.py has none, needs no credentials, spins a local HTTPServer and runs in about a second. Deleting it in the PR directly beneath the one rewriting _PERMANENT_STATUSES, _send_individually and _replay_failed ordering is exactly the wrong order, and it was the only thing in the repo exercising buffer → HTTP → retry → recovery against a real socket.
Restoring it as tests/unit/test_queue_outage.py, which also gets it running in CI for the first time. Two notes while doing that: the same file exists in the JS stack and its deletion is still unmerged, so I will drop that deletion from the open JS PR rather than delete-then-restore there; and one of its two tests asserts oldest-dropped-first at the buffer cap, which is now also covered by the FIFO-ordering test #18 added — worth keeping both, since only this one goes through a socket.
|
On CI: you are right, and it is the more serious of the two. Dropping the |
Not a response to a review comment — a decision to delete a test tier that never ran anywhere.
Neither CI workflow sets a single provider key, so
tests/integrationalways skipped. Running it needed five paid accounts. And each per-provider test pointed at an in-process mock Lago, so it could not prove Lago accepts an event even when it did run. None of it ever shipped to clients either — the package is built fromsrc/only.Adapter behaviour stays pinned by the captured real responses under
tests/unit/adapters/fixtures/, which is what the unit tests assert against; CONTRIBUTING now says that explicitly so the removal doesn't read as "provider shapes are unverified". Live verification moves to a driver script pointed at a real Lago — the only way to exercise what these tests couldn't:llm_costagainst a dynamic charge, andprecise_total_amount_centsbeing accepted.Reviewing this one is just checking that nothing else referenced the directory:
git grep tests/integrationcomes back empty outside CHANGELOG history.