You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
e2e/qa: stop counting devices that cannot accept users as failures (#4168)
## Summary of Changes
Mainnet Beta QA failed 7 times over Aug 8-10; three (infra runs
31248009915, 31266248546, 31286128831) had one cause.
`qa_alldevices_unicast_test.go` checks device readiness at five sites,
but each increments `FailedTests` *before* that check, so the carve-out
suppressed only the log line. `laconic-{dfw,mia,was}-sw01` have been
activated at `max_users=0` since Aug 6 and the CLI refuses those
connects outright; against `cmh-mn-qa01`'s 13-device pool that read as
21-29% on a 20% per-host gate.
Gating that counter is not enough: `Success()` also requires non-zero
packet counts, which a device that never connected cannot produce.
Not-ready devices are therefore excluded from `ComputeFailureStats`
entirely — per-host denominator included — behind a new `Device.Ready()`
replacing the condition previously spelled out at six call sites.
Exclusion opens a fail-open path worth reviewing closely: the rate is
then measured over a shrinking pool, and with *every* device excluded it
is `0/0`, where `NaN > threshold` is false. Coverage is now gated on the
skipped rate against `-skipped-threshold` (default 0.5), fleet-wide
**and** per host — one metro draining is a few percent of the fleet but
all of a host's pool, and per-host is the gate that fires in practice.
Testing nothing fails independently of that threshold, which
`-skipped-threshold=1` would otherwise switch off. The gate uses
`t.Errorf`, not `t.Fatalf`, so the publishers still run: the skipped
count lands as `devices_skipped` beside `devices_tested` in InfluxDB and
ClickHouse, the latter via an idempotent `ADD COLUMN IF NOT EXISTS`,
best-effort so a writer without ALTER rights still gets its per-device
rows in.
`Ready()` is deliberately a subset of
`is_device_eligible_for_provisioning`: a device at `users_count +
reserved_seats >= max_users` hits the same CLI rejection and still
counts as a failure, but fixing that means re-adding the capacity check
#3697 removed, so it is a follow-up.
Separately, `client_unicast.go` wrapped an always-nil `lastErr`, so
every failure this weekend read `failed to ping after 3 retries:
%!w(<nil>)`. It now reports packet counts.
## Testing Verification
`go test ./e2e/internal/qa/...` and `golangci-lint run --build-tags=qa
./e2e/...` pass. The new subtests fail against the unfixed aggregation:
the mainnet shape reports `total=6 failed=3` for `total=3 failed=0`, and
a host whose whole pool is drained was absent from `PerHost` rather than
visible there as zero coverage.
Not verified: the `qa`-tagged tests need live fleet access, so nothing
here runs against the real fleet and no run has written a
`devices_skipped` row yet. Mainnet has 5 of ~92 non-transit devices
unusable today, well under the 0.5 default.
Two pre-existing holes on the same axis go to separate PRs: a not-ready
device still consumes a batch host slot, which on the two-host devnet
run can trip the `fewer than 2 clients connected` fatal, and the Grafana
active-device filter fails open on a query error but not on an empty
successful response.
Copy file name to clipboardExpand all lines: CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -40,6 +40,7 @@ All notable changes to this project will be documented in this file.
40
40
-`doublezero feed create` and `doublezero feed update` now read back every `--exchange` and `--group` argument, so a feed cannot name a metro or a multicast group that the ledger does not carry. A base58 argument used to pass straight through with no read, so `--group 4Nd1mBQtrMJVYVfKf2PJy9NZUZdTAsp7D4xWLs4gDB4T` created a feed whose group nobody can join. A code was always read back, so only the pubkey form changes. (#4172)
41
41
- E2E/QA
42
42
-`TestQA_MulticastSettlement`'s `validate_instant_allocation_price_matches_chain` no longer names a specific `doublezero_solana_version` in its skip path. Both the comment and the skip message said the pin was `0.5.10-1`; testnet has since moved to `0.5.11-1`, so a reader was told the pin was merely behind when in fact `instant_allocation_price` is in no release yet. They now name what actually gates the field — a doublezero-offchain release carrying doublezero-offchain#405 — and where the pin lives, neither of which goes stale as versions move. Comment and message only, no behaviour change.
43
+
- `TestQA_AllDevices_UnicastConnectivity` no longer counts a device that cannot accept users against its failure thresholds. Five sites already checked `activated && max_users > 0` and logged `Ignoring <x> failure for device not ready for users`, but each incremented `FailedTests` before the check, so the carve-out suppressed only the log line while the device still counted as failed — and gating that counter alone would not have been enough, since `Success()` also requires a non-zero packet count a device that never connected cannot produce. Such devices are now excluded from `ComputeFailureStats` entirely, per-host denominator included. This is what failed mainnet-beta QA three times over 2026-08-08/09: `laconic-dfw-sw01`, `laconic-mia-sw01` and `laconic-was-sw01` have been activated at `max_users=0` since 08-06, the client CLI refuses those connects outright, and `cmh-mn-qa01` draws from a 13-device pool, so three unusable devices read as a 21-29% per-host rate against the 20% gate. The excluded codes are now reported in test output, so a skip is distinguishable from a pass. The exclusion is deliberately a subset of the program's `is_device_eligible_for_provisioning`: a device at `users_count + reserved_seats >= max_users` hits the same CLI rejection and still counts as a failure, since narrowing that too would restore the capacity pre-filtering #3697 removed. A run that could not attempt more than half of the devices assigned to it — fleet-wide or on any single host — now fails (`-skipped-threshold`, default 0.5) rather than reporting green over the remnant, and testing nothing at all fails regardless of that threshold, where previously the rate was `0/0` and `NaN > threshold` passed silently. The gate is per host as well because a drained metro is a few percent of the fleet but all of one host's coverage. The count also publishes as `devices_skipped` next to `devices_tested` in InfluxDB and ClickHouse, so a collapse that stays under the threshold shows up on the dashboard and not only in the test log. Separately, a ping that never gets a reply reports its packet counts rather than `failed to ping after 3 retries: %!w(<nil>)`; the wrapped error was always nil, because the retry loop returns early on any real failure. (#4168)
0 commit comments