mirror of
https://github.com/MeshCore-Beacon/beacon-server.git
synced 2026-10-20 12:11:58 +00:00
Stats endpoints read hourly rollup tables filled once per closed hour by one advisory-locked task, instead of materialized views that re-scanned every observation on each refresh. IATA-set tables give exact distinct counts for any IATA set or region. Cleanup holds raw rows for unrolled hours (up to 24h). Adds /stats/series; ingest keeps packet observation counts, observer last IATA, channel message counts and trace tag summaries. 001_baseline.sql is rewritten, so pre-release 2.0 databases must be recreated. See docs/historical-stats.md.
55 lines
1.5 KiB
Go
55 lines
1.5 KiB
Go
// Copyright 2026 Beacon Contributors
|
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
package ingest
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/MeshCore-Beacon/beacon-server/internal/api"
|
|
"github.com/meshcore-go/meshcore-go"
|
|
)
|
|
|
|
type endpointLookupDB struct {
|
|
*stubDB
|
|
calls [][][]byte
|
|
}
|
|
|
|
func (d *endpointLookupDB) ResolveEndpointHashes(_ context.Context, _ string, hashes [][]byte) (map[string][]api.ResolvedPathEntry, error) {
|
|
d.calls = append(d.calls, hashes)
|
|
return nil, nil
|
|
}
|
|
func endpointTestPacket() *meshcore.Packet {
|
|
return &meshcore.Packet{Header: meshcore.MakeHeader(meshcore.RouteTypeFlood, meshcore.PayloadTypeTxtMsg, 0), Payload: append([]byte{0xbb, 0xaa, 0, 0}, make([]byte, 16)...)}
|
|
}
|
|
func TestEndpointLookupsOnlyForLiveHearings(t *testing.T) {
|
|
r := newRepeatHarness(t, true)
|
|
d := &endpointLookupDB{stubDB: r.db}
|
|
r.w.db = d
|
|
packet := endpointTestPacket()
|
|
hear := func(inserted bool, path byte) {
|
|
d.observationInserted = inserted
|
|
packet.Path = []byte{path}
|
|
packet.PathLength = 1
|
|
r.w.handlePacket(r.ctx, "YOW", "0102", packetEnvelope(t, packet))
|
|
}
|
|
hear(true, 0x11)
|
|
first := len(d.calls)
|
|
if first == 0 {
|
|
t.Fatal("first hearing missing endpoint lookup")
|
|
}
|
|
hear(false, 0x11)
|
|
if len(d.calls) != first {
|
|
t.Fatal("suppressed copy resolved endpoints")
|
|
}
|
|
hear(false, 0x22)
|
|
if len(d.calls) != 2*first {
|
|
t.Fatal("new path missing endpoint lookup")
|
|
}
|
|
hear(false, 0x22)
|
|
if len(d.calls) != 2*first {
|
|
t.Fatal("suppressed repeat resolved endpoints")
|
|
}
|
|
}
|