123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- // Copyright (c) 2018 Shivaram Lingamneni <slingamn@cs.stanford.edu>
- // released under the MIT license
-
- package irc
-
- import (
- "testing"
- "time"
- )
-
- type mockTime struct {
- now time.Time
- sleepList []time.Duration
- lastCheckedSleep int
- }
-
- func (mt *mockTime) Now() (now time.Time) {
- return mt.now
- }
-
- func (mt *mockTime) Sleep(dur time.Duration) {
- mt.sleepList = append(mt.sleepList, dur)
- mt.pause(dur)
- }
-
- func (mt *mockTime) pause(dur time.Duration) {
- mt.now = mt.now.Add(dur)
- }
-
- func (mt *mockTime) lastSleep() (slept bool, duration time.Duration) {
- if mt.lastCheckedSleep == len(mt.sleepList)-1 {
- slept = false
- return
- }
-
- slept = true
- mt.lastCheckedSleep += 1
- duration = mt.sleepList[mt.lastCheckedSleep]
- return
- }
-
- func newFakelagForTesting(window time.Duration, burstLimit uint, throttleMessagesPerWindow uint, cooldown time.Duration) (*Fakelag, *mockTime) {
- fl := Fakelag{}
- fl.config = FakelagConfig{
- Enabled: true,
- Window: window,
- BurstLimit: burstLimit,
- MessagesPerWindow: throttleMessagesPerWindow,
- Cooldown: cooldown,
- }
- mt := new(mockTime)
- mt.now, _ = time.Parse("Mon Jan 2 15:04:05 -0700 MST 2006", "Mon Jan 2 15:04:05 -0700 MST 2006")
- mt.lastCheckedSleep = -1
- fl.nowFunc = mt.Now
- fl.sleepFunc = mt.Sleep
- return &fl, mt
- }
-
- func TestFakelag(t *testing.T) {
- window, _ := time.ParseDuration("1s")
- fl, mt := newFakelagForTesting(window, 3, 2, window)
-
- fl.Touch()
- slept, _ := mt.lastSleep()
- if slept {
- t.Fatalf("should not have slept")
- }
-
- interval, _ := time.ParseDuration("100ms")
- for i := 0; i < 2; i++ {
- mt.pause(interval)
- fl.Touch()
- slept, _ := mt.lastSleep()
- if slept {
- t.Fatalf("should not have slept")
- }
- }
-
- mt.pause(interval)
- fl.Touch()
- if fl.state != FakelagThrottled {
- t.Fatalf("should be throttled")
- }
- slept, duration := mt.lastSleep()
- if !slept {
- t.Fatalf("should have slept due to fakelag")
- }
- expected, _ := time.ParseDuration("400ms")
- if duration != expected {
- t.Fatalf("incorrect sleep time: %v != %v", expected, duration)
- }
-
- // send another message without a pause; we should have to sleep for 500 msec
- fl.Touch()
- if fl.state != FakelagThrottled {
- t.Fatalf("should be throttled")
- }
- slept, duration = mt.lastSleep()
- expected, _ = time.ParseDuration("500ms")
- if duration != expected {
- t.Fatalf("incorrect sleep time: %v != %v", duration, expected)
- }
-
- mt.pause(interval * 6)
- fl.Touch()
- if fl.state != FakelagThrottled {
- t.Fatalf("should still be throttled")
- }
- slept, duration = mt.lastSleep()
- if duration != 0 {
- t.Fatalf("we paused for long enough that we shouldn't sleep here")
- }
-
- mt.pause(window * 2)
- fl.Touch()
- if fl.state != FakelagBursting {
- t.Fatalf("should be bursting again")
- }
- slept, _ = mt.lastSleep()
- if slept {
- t.Fatalf("should not have slept")
- }
- }
-
- func TestSuspend(t *testing.T) {
- window, _ := time.ParseDuration("1s")
- fl, _ := newFakelagForTesting(window, 3, 2, window)
- assertEqual(fl.config.Enabled, true, t)
-
- // suspend idempotently disables
- fl.Suspend()
- assertEqual(fl.config.Enabled, false, t)
- fl.Suspend()
- assertEqual(fl.config.Enabled, false, t)
- // unsuspend idempotently enables
- fl.Unsuspend()
- assertEqual(fl.config.Enabled, true, t)
- fl.Unsuspend()
- assertEqual(fl.config.Enabled, true, t)
- fl.Suspend()
- assertEqual(fl.config.Enabled, false, t)
-
- fl2, _ := newFakelagForTesting(window, 3, 2, window)
- fl2.config.Enabled = false
-
- // if we were never enabled, suspend and unsuspend are both no-ops
- fl2.Suspend()
- assertEqual(fl2.config.Enabled, false, t)
- fl2.Suspend()
- assertEqual(fl2.config.Enabled, false, t)
- fl2.Unsuspend()
- assertEqual(fl2.config.Enabled, false, t)
- fl2.Unsuspend()
- assertEqual(fl2.config.Enabled, false, t)
- }
|