98 lines
2.7 KiB
Go
98 lines
2.7 KiB
Go
package main
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestRateWindowLatestNeedsTwoBuckets(t *testing.T) {
|
|
w := newRateWindow(4)
|
|
if got := w.latest(rxRatePPS); got != 0 {
|
|
t.Errorf("empty ring gave %v, want 0", got)
|
|
}
|
|
w.push(counterSet{t: time.Now(), s: sample{rxFrames: 100}})
|
|
if got := w.latest(rxRatePPS); got != 0 {
|
|
t.Errorf("one bucket gave %v, want 0", got)
|
|
}
|
|
}
|
|
|
|
// The newest pair alone, so a step in the rate shows at once instead of being
|
|
// averaged against everything still in the ring.
|
|
func TestRateWindowLatestUsesNewestPair(t *testing.T) {
|
|
w := newRateWindow(4)
|
|
t0 := time.Now()
|
|
w.push(counterSet{t: t0, s: sample{rxFrames: 100}})
|
|
w.push(counterSet{t: t0.Add(time.Second), s: sample{rxFrames: 300}})
|
|
if got := w.latest(rxRatePPS); got != 200 {
|
|
t.Errorf("rate = %v, want 200", got)
|
|
}
|
|
w.push(counterSet{t: t0.Add(2 * time.Second), s: sample{rxFrames: 400}})
|
|
if got := w.latest(rxRatePPS); got != 100 {
|
|
t.Errorf("rate = %v, want 100 rather than the mean of the ring", got)
|
|
}
|
|
}
|
|
|
|
func TestRateWindowLatestIgnoresZeroSpan(t *testing.T) {
|
|
w := newRateWindow(4)
|
|
t0 := time.Now()
|
|
w.push(counterSet{t: t0, s: sample{rxFrames: 100}})
|
|
w.push(counterSet{t: t0, s: sample{rxFrames: 300}})
|
|
if got := w.latest(rxRatePPS); got != 0 {
|
|
t.Errorf("rate = %v, want 0", got)
|
|
}
|
|
}
|
|
|
|
// Which counter feeds which bucket is the whole taxonomy the panel reports, so
|
|
// it is pinned here rather than left to whoever reads errsBetween next.
|
|
func TestErrsBetweenBuckets(t *testing.T) {
|
|
n := counterSet{
|
|
s: sample{
|
|
lost: 1, late: 7,
|
|
crcErr: 2, badMagic: 3, badLen: 4,
|
|
txErrs: 6, rxErrs: 5,
|
|
},
|
|
drops: 9,
|
|
nic: 8,
|
|
}
|
|
got := errsBetween(counterSet{}, n)
|
|
want := errs{lost: 1, corrupt: 2 + 3 + 4, link: 8 + 5, internal: 9 + 7 + 6}
|
|
if got != want {
|
|
t.Errorf("errsBetween = %+v, want %+v", got, want)
|
|
}
|
|
if got.total() != 45 {
|
|
t.Errorf("total = %d, want 45", got.total())
|
|
}
|
|
}
|
|
|
|
// A reset re-bases from a fresh capture while the ring still holds buckets from
|
|
// just before it, so the newest bucket must not be left behind the new origin.
|
|
func TestResetDoesNotUnderflowTotals(t *testing.T) {
|
|
d := &direction{
|
|
win: newRateWindow(8),
|
|
cable: newCableStats(),
|
|
rxStats: []*rxStats{{}},
|
|
}
|
|
|
|
d.rxStats[0].frames.Store(100)
|
|
d.rxStats[0].bytes.Store(6400)
|
|
d.sample()
|
|
|
|
d.rxStats[0].frames.Store(150)
|
|
d.rxStats[0].bytes.Store(9600)
|
|
d.reset()
|
|
|
|
v := d.displayView()
|
|
if v.rxFrames != 0 {
|
|
t.Errorf("rxFrames = %d, want 0", v.rxFrames)
|
|
}
|
|
if v.rxBytes != 0 {
|
|
t.Errorf("rxBytes = %d, want 0", v.rxBytes)
|
|
}
|
|
|
|
// The rolling window and the rates are about now rather than since the
|
|
// reset, so the buckets from before it have to survive.
|
|
if got := d.win.count(); got < 2 {
|
|
t.Errorf("ring holds %d buckets after reset, want the pre-reset history kept", got)
|
|
}
|
|
}
|