type DynamicBanScore struct {
lastUnix int64
transient float64
- persistent uint64
+ persistent uint32
mtx sync.Mutex
}
// scores.
//
// This function is safe for concurrent access.
-func (s *DynamicBanScore) Int() uint64 {
+func (s *DynamicBanScore) Int() uint32 {
s.mtx.Lock()
r := s.int(time.Now())
s.mtx.Unlock()
// passed as parameters. The resulting score is returned.
//
// This function is safe for concurrent access.
-func (s *DynamicBanScore) Increase(persistent, transient uint64) uint64 {
+func (s *DynamicBanScore) Increase(persistent, transient uint32) uint32 {
s.mtx.Lock()
r := s.increase(persistent, transient, time.Now())
s.mtx.Unlock()
//
// This function is not safe for concurrent access. It is intended to be used
// internally and during testing.
-func (s *DynamicBanScore) int(t time.Time) uint64 {
+func (s *DynamicBanScore) int(t time.Time) uint32 {
dt := t.Unix() - s.lastUnix
if s.transient < 1 || dt < 0 || Lifetime < dt {
return s.persistent
}
- return s.persistent + uint64(s.transient*decayFactor(dt))
+ return s.persistent + uint32(s.transient*decayFactor(dt))
}
// increase increases the persistent, the decaying or both scores by the values
// resulting score is returned.
//
// This function is not safe for concurrent access.
-func (s *DynamicBanScore) increase(persistent, transient uint64, t time.Time) uint64 {
+func (s *DynamicBanScore) increase(persistent, transient uint32, t time.Time) uint32 {
s.persistent += persistent
tu := t.Unix()
dt := tu - s.lastUnix
s.transient += float64(transient)
s.lastUnix = tu
}
- return s.persistent + uint64(s.transient)
+ return s.persistent + uint32(s.transient)
}
--- /dev/null
+package trust
+
+import (
+ "math"
+ "testing"
+ "time"
+)
+
+func TestInt(t *testing.T) {
+ var banScoreIntTests = []struct {
+ bs DynamicBanScore
+ timeLapse int64
+ wantValue uint32
+ }{
+ {bs: DynamicBanScore{lastUnix: 0, transient: 50, persistent: 50}, timeLapse: 1, wantValue: 99},
+ {bs: DynamicBanScore{lastUnix: 0, transient: 50, persistent: 50}, timeLapse: Lifetime, wantValue: 50},
+ {bs: DynamicBanScore{lastUnix: 0, transient: 50, persistent: 50}, timeLapse: Lifetime + 1, wantValue: 50},
+ {bs: DynamicBanScore{lastUnix: 0, transient: 50, persistent: 50}, timeLapse: -1, wantValue: 50},
+ {bs: DynamicBanScore{lastUnix: 0, transient: 0, persistent: 0}, timeLapse: Lifetime + 1, wantValue: 0},
+ {bs: DynamicBanScore{lastUnix: 0, transient: 0, persistent: math.MaxUint32}, timeLapse: 0, wantValue: math.MaxUint32},
+ {bs: DynamicBanScore{lastUnix: 0, transient: math.MaxUint32, persistent: 0}, timeLapse: Lifetime + 1, wantValue: 0},
+ {bs: DynamicBanScore{lastUnix: 0, transient: math.MaxUint32, persistent: 0}, timeLapse: 60, wantValue: math.MaxUint32 / 2},
+ {bs: DynamicBanScore{lastUnix: 0, transient: math.MaxUint32, persistent: math.MaxUint32}, timeLapse: 0, wantValue: math.MaxUint32 - 1},
+ }
+
+ Init()
+ for i, intTest := range banScoreIntTests {
+ rst := intTest.bs.int(time.Unix(intTest.timeLapse, 0))
+ if rst != intTest.wantValue {
+ t.Fatal("test ban score int err.", "num:", i, "want:", intTest.wantValue, "got:", rst)
+ }
+ }
+}
+
+func TestIncrease(t *testing.T) {
+ var banScoreIncreaseTests = []struct {
+ bs DynamicBanScore
+ transientAdd uint32
+ persistentAdd uint32
+ timeLapse int64
+ wantValue uint32
+ }{
+ {bs: DynamicBanScore{lastUnix: 0, transient: 50, persistent: 50}, transientAdd: 50, persistentAdd: 50, timeLapse: 1, wantValue: 199},
+ {bs: DynamicBanScore{lastUnix: 0, transient: 50, persistent: 50}, transientAdd: 50, persistentAdd: 50, timeLapse: Lifetime, wantValue: 150},
+ {bs: DynamicBanScore{lastUnix: 0, transient: 50, persistent: 50}, transientAdd: 50, persistentAdd: 50, timeLapse: Lifetime + 1, wantValue: 150},
+ {bs: DynamicBanScore{lastUnix: 0, transient: 50, persistent: 50}, transientAdd: 50, persistentAdd: 50, timeLapse: -1, wantValue: 200},
+ {bs: DynamicBanScore{lastUnix: 0, transient: 0, persistent: 0}, transientAdd: math.MaxUint32, persistentAdd: 0, timeLapse: 60, wantValue: math.MaxUint32},
+ {bs: DynamicBanScore{lastUnix: 0, transient: 0, persistent: 0}, transientAdd: 0, persistentAdd: math.MaxUint32, timeLapse: 60, wantValue: math.MaxUint32},
+ {bs: DynamicBanScore{lastUnix: 0, transient: 0, persistent: 0}, transientAdd: 0, persistentAdd: math.MaxUint32, timeLapse: Lifetime + 1, wantValue: math.MaxUint32},
+ {bs: DynamicBanScore{lastUnix: 0, transient: 0, persistent: 0}, transientAdd: math.MaxUint32, persistentAdd: 0, timeLapse: Lifetime + 1, wantValue: math.MaxUint32},
+ {bs: DynamicBanScore{lastUnix: 0, transient: math.MaxUint32, persistent: 0}, transientAdd: math.MaxUint32, persistentAdd: 0, timeLapse: Lifetime + 1, wantValue: math.MaxUint32},
+ {bs: DynamicBanScore{lastUnix: 0, transient: math.MaxUint32, persistent: 0}, transientAdd: math.MaxUint32, persistentAdd: 0, timeLapse: 0, wantValue: math.MaxUint32 - 1},
+ {bs: DynamicBanScore{lastUnix: 0, transient: 0, persistent: math.MaxUint32}, transientAdd: math.MaxUint32, persistentAdd: 0, timeLapse: Lifetime + 1, wantValue: math.MaxUint32 - 1},
+ }
+
+ Init()
+ for i, incTest := range banScoreIncreaseTests {
+ rst := incTest.bs.increase(incTest.persistentAdd, incTest.transientAdd, time.Unix(incTest.timeLapse, 0))
+ if rst != incTest.wantValue {
+ t.Fatal("test ban score int err.", "num:", i, "want:", incTest.wantValue, "got:", rst)
+ }
+ }
+}
+
+func TestReset(t *testing.T) {
+ var bs DynamicBanScore
+ if bs.Int() != 0 {
+ t.Errorf("Initial state is not zero.")
+ }
+ bs.Increase(100, 0)
+ r := bs.Int()
+ if r != 100 {
+ t.Errorf("Unexpected result %d after ban score increase.", r)
+ }
+ bs.Reset()
+ if bs.Int() != 0 {
+ t.Errorf("Failed to reset ban score.")
+ }
+}