Every time in UTC, and every day as YYYY-MM-DD (closes #313)
check / check (push) Waiting to run
check / check (push) Waiting to run
Every time the program stores, logs or compares is in UTC, whatever TZ says, and AbuseIPDB's day in `reputation.json` is a `YYYY-MM-DD` date. Times read from a state file are converted to UTC as they are read, so a file is written back with `Z` times only. A test runs `sww waf` with `TZ=Pacific/Kiritimati` and checks the process line, the request line and `clients.json`. `SPEC.md` states the rule and `AGENTS.md` makes it an iron rule. - The rate limit's `day` and `day_bytes` buckets keep a start time: each is a 24-hour bucket begun at an instant, not a calendar day. - New dependency `cloud.google.com/go`, of which only `civil` is built. - No migration: a `reputation.json` holding the old day form fails to load, naming the file. Model: opus-5-5
This commit was merged in pull request #317.
This commit is contained in:
1 parent
f7e3190654
commit
9bcbe5a3c8
11 files changed
+256
-22
No files matched your search
@@ -202,6 +202,43 @@ func TestDailyBudgetKeptAcrossARestartAndWholeAgainAsTheDayEnds(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestChecksAreCountedInUTCDaysWhateverTheClocksZone(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
synctest.Test(t, func(t *testing.T) {
|
||||
// A clock 14 hours ahead of UTC, whose day starts at 10:00 UTC.
|
||||
ahead := time.FixedZone("UTC+14", 14*60*60)
|
||||
p := abuseIPDBParams()
|
||||
p.DailyBudget = 1
|
||||
p.Now = func() time.Time { return time.Now().In(ahead) }
|
||||
abuseIPDB := &abuseIPDBStandIn{scores: map[string]int64{suspect: 100}}
|
||||
checker := newAbuseIPDB(abuseIPDB, p)
|
||||
|
||||
// At 09:00 UTC the one check is spent.
|
||||
time.Sleep(9 * time.Hour)
|
||||
hitFrom(t, checker, suspect, true)
|
||||
synctest.Wait()
|
||||
wantBudgetLeft(t, checker, 0)
|
||||
|
||||
// At 11:00 UTC the clock's day has changed, but the UTC day has not.
|
||||
time.Sleep(2 * time.Hour)
|
||||
wantBudgetLeft(t, checker, 0)
|
||||
|
||||
encoded, err := json.Marshal(checker.Snapshot())
|
||||
if err != nil {
|
||||
t.Fatalf("encode: %v", err)
|
||||
}
|
||||
|
||||
if !strings.Contains(string(encoded), `"day":"2000-01-01"`) {
|
||||
t.Errorf("reputation.json would hold %s, want the day 2000-01-01", encoded)
|
||||
}
|
||||
|
||||
// At 00:00 UTC the budget is whole again.
|
||||
time.Sleep(13 * time.Hour)
|
||||
wantBudgetLeft(t, checker, 1)
|
||||
})
|
||||
}
|
||||
|
||||
func TestFailedCheckGivesNoScoreAndNoClientIsCheckedForAMinute(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
Reference in new issue
Block a user