check / check (push) Canceled after 0s
Takes .golangci.yml, .dockerignore, .gitignore, .editorconfig, the workflow and REPO_POLICIES.md from sneak/prompts 0653579, with this repository's own entries after the shared content. Lint (golangci-lint v2.14.0) and test are Dockerfile phases that script/lint and script/test build alone with a new CACHEBUST value, keeping Go's and golangci-lint's caches; the image build depends on both. make fmt and make fmt-check also format the markdown with prettier, pinned in yarn.lock. The agent guidance moves to AGENTS.md. The Go code is fixed for what the new configuration finds, and the AS and prefix detail reads now return the rows' error after their loops. Model: opus-5-5
226 lines
3.9 KiB
Go
226 lines
3.9 KiB
Go
package asinfo_test
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"git.eeqj.de/sneak/routewatch/pkg/asinfo"
|
|
)
|
|
|
|
func TestGet(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
asn int
|
|
wantOK bool
|
|
wantDesc string
|
|
}{
|
|
{
|
|
name: "AS1 Level 3",
|
|
asn: 1,
|
|
wantOK: true,
|
|
wantDesc: "Level 3 Parent, LLC",
|
|
},
|
|
{
|
|
name: "AS15169 Google",
|
|
asn: 15169,
|
|
wantOK: true,
|
|
wantDesc: "Google LLC",
|
|
},
|
|
{
|
|
name: "Non-existent AS",
|
|
asn: 999999999,
|
|
wantOK: false,
|
|
},
|
|
{
|
|
name: "AS0 IANA Reserved",
|
|
asn: 0,
|
|
wantOK: true,
|
|
wantDesc: "Internet Assigned Numbers Authority",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
info, ok := asinfo.Get(tt.asn)
|
|
if ok != tt.wantOK {
|
|
t.Errorf("Get(%d) ok = %v, want %v", tt.asn, ok, tt.wantOK)
|
|
|
|
return
|
|
}
|
|
|
|
if ok && info.Description != tt.wantDesc {
|
|
t.Errorf("Get(%d) description = %q, want %q",
|
|
tt.asn, info.Description, tt.wantDesc)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetDescription(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
asn int
|
|
want string
|
|
}{
|
|
{1, "Level 3 Parent, LLC"},
|
|
{999999999, ""},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run("", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
got := asinfo.GetDescription(tt.asn)
|
|
if got != tt.want {
|
|
t.Errorf("GetDescription(%d) = %q, want %q", tt.asn, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetHandle(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
asn int
|
|
want string
|
|
}{
|
|
{1, "LVLT"},
|
|
{0, "IANA-RSVD"},
|
|
{999999999, ""},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run("", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
got := asinfo.GetHandle(tt.asn)
|
|
if got != tt.want {
|
|
t.Errorf("GetHandle(%d) = %q, want %q", tt.asn, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestTotal(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
total := asinfo.Total()
|
|
if total < 100000 {
|
|
t.Errorf("Total() = %d, expected > 100000", total)
|
|
}
|
|
|
|
// Verify it's consistent
|
|
total2 := asinfo.Total()
|
|
if total2 != total {
|
|
t.Errorf("Total() returned different values: %d vs %d", total, total2)
|
|
}
|
|
}
|
|
|
|
func TestSearch(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
query string
|
|
wantMin int
|
|
}{
|
|
{
|
|
name: "Search for Google",
|
|
query: "Google",
|
|
wantMin: 1,
|
|
},
|
|
{
|
|
name: "Search for University",
|
|
query: "University",
|
|
wantMin: 10,
|
|
},
|
|
{
|
|
name: "Empty search",
|
|
query: "",
|
|
wantMin: 0,
|
|
},
|
|
{
|
|
name: "Non-existent org",
|
|
query: "XYZABC123456",
|
|
wantMin: 0,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
results := asinfo.Search(tt.query)
|
|
if len(results) < tt.wantMin {
|
|
t.Errorf("Search(%q) returned %d results, want at least %d",
|
|
tt.query, len(results), tt.wantMin)
|
|
}
|
|
|
|
// Verify all results contain the query
|
|
if tt.query != "" {
|
|
for _, r := range results {
|
|
if !strings.Contains(r.Handle, tt.query) &&
|
|
!strings.Contains(r.Description, tt.query) {
|
|
t.Errorf("Search result ASN %d doesn't contain query %q",
|
|
r.ASN, tt.query)
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDataIntegrity(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// Verify no duplicate ASNs
|
|
all := asinfo.All()
|
|
seen := make(map[int]bool)
|
|
|
|
for _, info := range all {
|
|
if seen[info.ASN] {
|
|
t.Errorf("Duplicate ASN found: %d", info.ASN)
|
|
}
|
|
|
|
seen[info.ASN] = true
|
|
}
|
|
|
|
// Verify all entries have required fields
|
|
for _, info := range all {
|
|
if info.Handle == "" && info.ASN != 0 {
|
|
t.Errorf("ASN %d has empty handle", info.ASN)
|
|
}
|
|
|
|
if info.Description == "" {
|
|
t.Errorf("ASN %d has empty description", info.ASN)
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkGet(b *testing.B) {
|
|
// Common ASNs to lookup
|
|
asns := []int{1, 15169, 13335, 32934, 8075, 16509}
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := range b.N {
|
|
asinfo.Get(asns[i%len(asns)])
|
|
}
|
|
}
|
|
|
|
func BenchmarkSearch(b *testing.B) {
|
|
queries := []string{"Google", "Amazon", "Microsoft", "University"}
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := range b.N {
|
|
asinfo.Search(queries[i%len(queries)])
|
|
}
|
|
}
|