Show egress/ingress levels in the registry; freeze checks at the verdict
Registry: the "last result" column now also shows, per level (egress,
ingress), how many of the recorded checks of the latest cycle succeeded, split
by check family (tcp-22 and tcp-443 are both "tcp"). One grouped query per
chunk of addresses; new fields last_cycle_id, egress, ingress in
GET /admin/registry; the dashboard renders them under the verdict.
Verdict integrity (migration 0010):
- the prober is handed an address once per site and attempt, not on every
poll, so results are no longer overwritten by later probe rounds;
- UpsertCheckIfOpen refuses writes once the address is aggregating or has its
verdict, or for an older attempt; senders get {"ok":true,"ignored":N} and a
result_dropped event is recorded;
- the checking window counts from checking_started_at, not from assigned_at;
- checks.recorded_at (server clock) and checks.after_verdict (flag for rows
written after the verdict in existing data);
- the verdict rule is a pure function (computeVerdict) and the aggregated
event carries the egress/ingress check counts.
Rebuilt bin/control-api and bin/admin-dashboard to match. Plans and summaries
are in docs/changes; README, API, USAGE, DASHBOARD and DIAGRAMS are updated.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
db73409e8f
commit
864208238f
34 files changed
+1570
-72
No files matched your search
@@ -590,6 +590,38 @@ func TestRegistryPageAndDetail(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestRegistryPageShowsEgressIngressLevels proves the list shows, under the
|
||||
// verdict, "ok из total" per level and per check family, coloured by outcome,
|
||||
// and omits the block for an address with no recorded cycle.
|
||||
func TestRegistryPageShowsEgressIngressLevels(t *testing.T) {
|
||||
fake, caURL := newFakeControlAPI(t)
|
||||
now := time.Now()
|
||||
fake.registry["9.9.9.9"] = registryItem{
|
||||
IPAddress: "9.9.9.9", FirstSeenAt: now, LastSeenAt: now, TotalCycles: 1, LastResult: "partial",
|
||||
LastCycleID: 1,
|
||||
Egress: levelResult{Total: 5, OK: 5, ByType: []typeStat{{"https", 3, 3}, {"icmp", 2, 2}}},
|
||||
Ingress: levelResult{Total: 4, OK: 3, ByType: []typeStat{{"icmp", 1, 1}, {"tcp", 3, 2}}},
|
||||
}
|
||||
fake.registry["8.8.8.8"] = registryItem{IPAddress: "8.8.8.8", FirstSeenAt: now, LastSeenAt: now}
|
||||
ts := newTestServer(t, caURL)
|
||||
|
||||
body := get(t, ts, "/registry")
|
||||
for _, want := range []string{
|
||||
"Egress", "Ingress",
|
||||
`stat stat-ok">5 из 5<`, `stat stat-part">3 из 4<`,
|
||||
`chip chip-ok">https 3 из 3<`, `chip chip-ok">icmp 2 из 2<`,
|
||||
`chip chip-part">tcp 2 из 3<`,
|
||||
"цикла 1",
|
||||
} {
|
||||
if !strings.Contains(body, want) {
|
||||
t.Fatalf("expected %q in registry page, got:\n%s", want, body)
|
||||
}
|
||||
}
|
||||
if strings.Count(body, `class="levels"`) != 1 {
|
||||
t.Fatalf("expected the levels block only for the address with checks, got:\n%s", body)
|
||||
}
|
||||
}
|
||||
|
||||
// TestRegistryFilterByQueryAndStatus proves the ?q=&status= params on
|
||||
// /registry narrow the list by address substring and by LastResult, and
|
||||
// that the filter form echoes the applied values back into its inputs.
|
||||
|
||||
Reference in new issue
Block a user