package lookup_test import ( "net/netip" "slices" "testing" "testing/synctest" "time" "sneak.berlin/go/smallwebwaf/internal/lookup" ) func TestSnapshotHoldsEachAnswerAndWhenItWasLastUsed(t *testing.T) { t.Parallel() synctest.Test(t, func(t *testing.T) { _, clock, g := start() placed := netip.MustParsePrefix("203.0.113.9/32") notPlaced := netip.MustParsePrefix(unplaced + "/32") asked := clock.Now() wantCountry(t, g, placed, germany) wantCountry(t, g, notPlaced, "") clock.advance(time.Hour) wantCountry(t, g, placed, germany) want := []lookup.Answer{ {Client: notPlaced, Country: "", Answered: asked, Used: asked}, {Client: placed, Country: germany, Answered: asked, Used: asked.Add(time.Hour)}, } if got := g.Snapshot(); !slices.Equal(got, want) { t.Errorf("snapshot\n%+v\nwant\n%+v", got, want) } }) } func TestLoadedAnswersAreKeptFor7DaysFromWhenGeoJSGaveThem(t *testing.T) { t.Parallel() geojs, clock, g := start() now := clock.Now() kept := lookup.Answer{ Client: netip.MustParsePrefix("203.0.113.9/32"), Country: "FR", Answered: now.Add(-week + time.Second), Used: now.Add(-time.Hour), } stale := lookup.Answer{ Client: netip.MustParsePrefix("203.0.113.10/32"), Country: "FR", Answered: now.Add(-week), Used: now.Add(-time.Hour), } g.Load([]lookup.Answer{kept, stale}) if got := g.Snapshot(); !slices.Equal(got, []lookup.Answer{kept}) { t.Errorf("kept %+v, want only the answer GeoJS gave less than 7 days ago", got) } wantCountry(t, g, kept.Client, "FR") wantRequests(t, geojs, 0) } func TestLoadDropsTheAnswerUsedLongestAgoFirst(t *testing.T) { t.Parallel() const maxAnswers = 100000 _, clock, g := start() now := clock.Now() // lookups.json lists the answers by client. Here each was last used a // second before the one listed before it, so the last listed is the // one used longest ago, and the one dropped. answers := make([]lookup.Answer, maxAnswers+1) addr := netip.MustParseAddr("10.0.0.0") for i := range answers { answers[i] = lookup.Answer{ Client: netip.PrefixFrom(addr, addr.BitLen()), Country: germany, Answered: now, Used: now.Add(-time.Duration(i) * time.Second), } addr = addr.Next() } g.Load(answers) got := g.Snapshot() if len(got) != maxAnswers || got[0] != answers[0] || got[maxAnswers-1] != answers[maxAnswers-1] { t.Errorf("%d answers kept, from %s to %s; want %d, from %s to %s", len(got), got[0].Client, got[len(got)-1].Client, maxAnswers, answers[0].Client, answers[maxAnswers-1].Client) } }