Keep a trailing AS set out of the origin and the peerings (closes #75)
check / check (push) Canceled after 0s
check / check (push) Canceled after 0s
A path that ends in an AS set of several members, such as [64496, 64497, [64498, 64499]], now has no origin: its route is stored with origin 0 (none), and no member of the set is in a peering. A set of one member counts as that AS. An announcement with an empty path is still not stored. ASPath keeps such a set apart from the sequence and gives the origin. The prefix and AS handlers take the origin from it; the peering handler uses the sequence only. The stored AS path still lists the set's members at the end. The prefix and prefix length pages show origin 0 as no known origin, the IP lookup asks no WHOIS lookup for it, and the README says what it means. Model: opus-5-5
This commit is contained in:
@@ -331,6 +331,63 @@ func TestPrefixDetailShowsOriginNames(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestPagesSayOriginZeroIsNoKnownOrigin stores a route with origin 0, as the
|
||||
// prefix handler stores a route whose AS path ends in an AS set of several
|
||||
// members, and checks that the prefix page and the prefix length page say it
|
||||
// has no known origin, without a link to AS0 or the description of the
|
||||
// reserved AS 0 (https://git.eeqj.de/sneak/routewatch/issues/75).
|
||||
func TestPagesSayOriginZeroIsNoKnownOrigin(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
db, err := database.New(&config.Config{StateDir: t.TempDir()}, logger.New())
|
||||
if err != nil {
|
||||
t.Fatalf("database.New: %v", err)
|
||||
}
|
||||
|
||||
t.Cleanup(func() { _ = db.Close() })
|
||||
|
||||
err = db.UpsertLiveRouteBatch([]*database.LiveRoute{{
|
||||
ID: uuid.New(), Prefix: testPrefixV4, MaskLength: 24, IPVersion: 4,
|
||||
OriginASN: 0, PeerIP: testPeerV4, ASPath: []int{64500, 64501, 64502},
|
||||
NextHop: testPeerV4, LastUpdated: time.Date(2026, 1, 2, 3, 4, 5, 0, time.UTC),
|
||||
}})
|
||||
if err != nil {
|
||||
t.Fatalf("UpsertLiveRouteBatch: %v", err)
|
||||
}
|
||||
|
||||
reserved, ok := asinfo.Get(0)
|
||||
if !ok {
|
||||
t.Fatal("AS0 is not in the AS info data")
|
||||
}
|
||||
|
||||
s := New(db, streamer.New(logger.New(), metrics.New()), logger.New(), &config.Config{})
|
||||
|
||||
for _, path := range []string{"/prefix/" + testPrefixV4, "/prefixlength/24"} {
|
||||
rec := httptest.NewRecorder()
|
||||
s.router.ServeHTTP(rec, httptest.NewRequestWithContext(
|
||||
t.Context(), http.MethodGet, path, nil))
|
||||
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("%s: status %d, want %d; body %s",
|
||||
path, rec.Code, http.StatusOK, rec.Body)
|
||||
}
|
||||
|
||||
page := rec.Body.String()
|
||||
|
||||
if !strings.Contains(page, "No known origin") {
|
||||
t.Errorf("%s does not say the route has no known origin", path)
|
||||
}
|
||||
|
||||
if strings.Contains(page, `href="/as/0"`) {
|
||||
t.Errorf("%s links to AS0", path)
|
||||
}
|
||||
|
||||
if strings.Contains(page, html.EscapeString(reserved.Description)) {
|
||||
t.Errorf("%s shows AS0's description %q", path, reserved.Description)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// shortRequestDeadline is the deadline the tests below give a request. The
|
||||
// server's 30-second limit and the stats handlers' 4-second limit inherit it,
|
||||
// so the tests do not wait for either.
|
||||
|
||||
Reference in New Issue
Block a user