check / check (push) Canceled after 0s
An AS path that holds AS 0 anywhere, a member of an AS set included, now decodes as an empty path. RFC 7607 makes such a path malformed and its announcements withdrawals. An empty path already gets that handling: the prefix handler deletes the peer's route for the prefix, and the AS and peering handlers record nothing from it. Before, a path such as [64496, 0, 64497] stored the route with origin AS64497, recorded both ASes, and recorded the peerings between the path's other ASes. Model: opus-5-5
69 lines
2.0 KiB
Go
69 lines
2.0 KiB
Go
package routewatch
|
|
|
|
import (
|
|
"maps"
|
|
"slices"
|
|
"testing"
|
|
|
|
"git.eeqj.de/sneak/routewatch/internal/logger"
|
|
)
|
|
|
|
// TestASHandlerStoresTheEarliestAndLatestTimesOfANewAS handles two updates
|
|
// whose path carries an AS the database does not hold yet, the second 5
|
|
// seconds after the first, in one batch into a real database. The AS is stored
|
|
// first seen at the time of the first update and last seen at the time of the
|
|
// second.
|
|
func TestASHandlerStoresTheEarliestAndLatestTimesOfANewAS(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
db := newTestDatabase(t)
|
|
|
|
// Built without NewASHandler's flush goroutine, so the test flushes itself.
|
|
h := &ASHandler{db: db, 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()
|
|
|
|
asn, _, err := db.GetASDetails(testASNA)
|
|
if err != nil {
|
|
t.Fatalf("GetASDetails(%d): %v", testASNA, err)
|
|
}
|
|
|
|
if !asn.FirstSeen.Equal(first.ParsedTimestamp) {
|
|
t.Errorf("first_seen of AS%d = %s, want %s", testASNA,
|
|
asn.FirstSeen, first.ParsedTimestamp)
|
|
}
|
|
|
|
if !asn.LastSeen.Equal(second.ParsedTimestamp) {
|
|
t.Errorf("last_seen of AS%d = %s, want %s", testASNA,
|
|
asn.LastSeen, second.ParsedTimestamp)
|
|
}
|
|
}
|
|
|
|
// TestASHandlerRecordsNothingFromAPathWithASZero handles an update whose AS
|
|
// path holds AS 0 between two other ASes. RFC 7607 makes such a path
|
|
// malformed, so neither AS is recorded.
|
|
func TestASHandlerRecordsNothingFromAPathWithASZero(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
store := newMockStore()
|
|
|
|
// Built without NewASHandler's flush goroutine, so the test flushes itself.
|
|
h := &ASHandler{db: store, logger: logger.New()}
|
|
|
|
msg := peerAnnouncement(testPeerIP, testV4Prefix)
|
|
msg.Path = decodePath(t, testASNA, 0, testASNB)
|
|
h.HandleMessage(msg)
|
|
h.flushBatch()
|
|
|
|
if len(store.ASNs) > 0 {
|
|
t.Errorf("ASes recorded = %v, want none",
|
|
slices.Sorted(maps.Keys(store.ASNs)))
|
|
}
|
|
}
|