Store a new row's earliest timestamp as first_seen (closes #112)
check / check (push) Canceled after 0s
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
This commit was merged in pull request #137.
This commit is contained in:
@@ -26,6 +26,10 @@ const (
|
||||
testV6Prefix = "2001:db8:1::/48"
|
||||
)
|
||||
|
||||
// secondUpdateAfter is how long after the first update the tests of first_seen
|
||||
// and last_seen send the second, in the same batch.
|
||||
const secondUpdateAfter = 5 * time.Second
|
||||
|
||||
// TestPrefixHandlerStoresPrefixesTheIPLookupFinds runs announcements and
|
||||
// withdrawals through the prefix handler into a real database and looks the
|
||||
// addresses up. The prefixes are written the way the feed sends them: IPv6
|
||||
@@ -83,6 +87,49 @@ func TestPrefixHandlerStoresPrefixesTheIPLookupFinds(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestPrefixHandlerStoresANewPrefixFirstSeenAtItsEarliestUpdate announces a
|
||||
// prefix the database does not hold yet twice in one batch, the second time 5
|
||||
// seconds after the first, through the prefix handler into a real database. The
|
||||
// prefix is stored first seen at the time of the first announcement, whether
|
||||
// the two come from two peers or from one, and the IP lookup answers with that
|
||||
// time.
|
||||
func TestPrefixHandlerStoresANewPrefixFirstSeenAtItsEarliestUpdate(
|
||||
t *testing.T,
|
||||
) {
|
||||
t.Parallel()
|
||||
|
||||
const otherPeerIP = "2001:db8:ffff::2"
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
firstPeer, secondPeer string
|
||||
}{
|
||||
{name: "two peers", firstPeer: testPeerIP, secondPeer: otherPeerIP},
|
||||
{name: "one peer", firstPeer: testPeerIP, secondPeer: testPeerIP},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
first := peerAnnouncement(tt.firstPeer, testV4Prefix)
|
||||
second := peerAnnouncement(tt.secondPeer, testV4Prefix)
|
||||
second.ParsedTimestamp = first.ParsedTimestamp.Add(secondUpdateAfter)
|
||||
db := handleBatches(t, [][]*ristypes.RISMessage{{first, second}})
|
||||
|
||||
info, err := db.GetIPInfo("192.0.2.1")
|
||||
if err != nil {
|
||||
t.Fatalf("GetIPInfo(192.0.2.1): %v", err)
|
||||
}
|
||||
|
||||
if !info.FirstSeen.Equal(first.ParsedTimestamp) {
|
||||
t.Errorf("first_seen of %s = %s, want %s", testV4Prefix,
|
||||
info.FirstSeen, first.ParsedTimestamp)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestPrefixHandlerAppliesEachPeersLastUpdateInABatch runs updates for one
|
||||
// prefix through the prefix handler into a real database. All updates carry the
|
||||
// same timestamp, as updates within one second of the feed do. Within a batch,
|
||||
|
||||
Reference in New Issue
Block a user