check / check (push) Canceled after 0s
Each handler took the latest time per key in a batch and inserted it as a new row's first_seen, so a key updated twice in one batch, seconds apart, was stored first seen at the later time, and the IP lookup could answer with a prefix first_seen after the route's last_seen. The prefix handler now keeps the earliest time of all of the batch's updates for each prefix. The AS, peer and peering handlers keep the earliest and the latest time per key in database.SeenTimes, and GetOrCreateASNBatch, UpdatePeerBatch and RecordPeering store a new row first seen at the earliest and last seen at the latest. A stored row still has only its last_seen set, to the latest. Model: opus-5-5
60 lines
1.6 KiB
Go
60 lines
1.6 KiB
Go
package routewatch
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"git.eeqj.de/sneak/routewatch/internal/database"
|
|
"git.eeqj.de/sneak/routewatch/internal/logger"
|
|
)
|
|
|
|
// peerBatchStore keeps the peers of the last UpdatePeerBatch call. The
|
|
// database has no read of the peer table, so the peer handler's test checks
|
|
// what the handler writes.
|
|
type peerBatchStore struct {
|
|
*mockStore
|
|
|
|
peers map[string]database.PeerUpdate
|
|
}
|
|
|
|
func (s *peerBatchStore) UpdatePeerBatch(
|
|
peers map[string]database.PeerUpdate,
|
|
) error {
|
|
s.peers = peers
|
|
|
|
return nil
|
|
}
|
|
|
|
// TestPeerHandlerWritesTheEarliestAndLatestTimesOfANewPeer handles two updates
|
|
// from one peer, the second 5 seconds after the first, in one batch. The peer
|
|
// handler writes the peer first seen at the time of the first update and last
|
|
// seen at the time of the second.
|
|
func TestPeerHandlerWritesTheEarliestAndLatestTimesOfANewPeer(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
store := &peerBatchStore{mockStore: newMockStore()}
|
|
|
|
// Built without NewPeerHandler's flush goroutine, so the test flushes
|
|
// itself.
|
|
h := &PeerHandler{db: store, logger: logger.New()}
|
|
|
|
first := peerAnnouncement(testPeerIP, testV4Prefix)
|
|
second := peerAnnouncement(testPeerIP, testV4Prefix)
|
|
second.ParsedTimestamp = first.ParsedTimestamp.Add(secondUpdateAfter)
|
|
|
|
h.HandleMessage(first)
|
|
h.HandleMessage(second)
|
|
h.flushBatch()
|
|
|
|
seen := store.peers[testPeerIP].Seen
|
|
|
|
if !seen.First.Equal(first.ParsedTimestamp) {
|
|
t.Errorf("first_seen of peer %s = %s, want %s", testPeerIP,
|
|
seen.First, first.ParsedTimestamp)
|
|
}
|
|
|
|
if !seen.Last.Equal(second.ParsedTimestamp) {
|
|
t.Errorf("last_seen of peer %s = %s, want %s", testPeerIP,
|
|
seen.Last, second.ParsedTimestamp)
|
|
}
|
|
}
|