2020-04-30 20:15:52 +02:00
|
|
|
package estimator
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
2022-04-20 20:54:37 +02:00
|
|
|
"time"
|
2022-04-20 21:27:34 +02:00
|
|
|
"sync"
|
|
|
|
"sync/atomic"
|
2020-06-09 14:13:30 +02:00
|
|
|
|
2020-12-19 17:37:48 +01:00
|
|
|
"github.com/jech/galene/rtptime"
|
2020-04-30 20:15:52 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestEstimator(t *testing.T) {
|
2020-06-09 14:13:30 +02:00
|
|
|
now := rtptime.Jiffies()
|
2022-04-20 21:27:34 +02:00
|
|
|
e := new(now, time.Second)
|
2020-04-30 20:15:52 +02:00
|
|
|
|
|
|
|
e.estimate(now)
|
2020-05-31 23:47:12 +02:00
|
|
|
e.Accumulate(42)
|
|
|
|
e.Accumulate(128)
|
2020-06-09 14:13:30 +02:00
|
|
|
e.estimate(now + rtptime.JiffiesPerSec)
|
|
|
|
rate, packetRate :=
|
2020-12-19 17:38:47 +01:00
|
|
|
e.estimate(now + (rtptime.JiffiesPerSec*1001)/1000)
|
2020-04-30 20:15:52 +02:00
|
|
|
|
|
|
|
if rate != 42+128 {
|
|
|
|
t.Errorf("Expected %v, got %v", 42+128, rate)
|
|
|
|
}
|
2020-06-03 22:37:43 +02:00
|
|
|
if packetRate != 2 {
|
|
|
|
t.Errorf("Expected 2, got %v", packetRate)
|
|
|
|
}
|
2020-05-31 23:54:55 +02:00
|
|
|
|
|
|
|
totalP, totalB := e.Totals()
|
|
|
|
if totalP != 2 {
|
|
|
|
t.Errorf("Expected 2, got %v", totalP)
|
|
|
|
}
|
|
|
|
if totalB != 42+128 {
|
|
|
|
t.Errorf("Expected %v, got %v", 42+128, totalB)
|
|
|
|
}
|
2020-06-03 22:37:43 +02:00
|
|
|
|
|
|
|
e.Accumulate(12)
|
|
|
|
|
|
|
|
totalP, totalB = e.Totals()
|
|
|
|
if totalP != 3 {
|
|
|
|
t.Errorf("Expected 2, got %v", totalP)
|
|
|
|
}
|
|
|
|
if totalB != 42+128+12 {
|
|
|
|
t.Errorf("Expected %v, got %v", 42+128, totalB)
|
|
|
|
}
|
|
|
|
|
2020-04-30 20:15:52 +02:00
|
|
|
}
|
2022-04-20 21:27:34 +02:00
|
|
|
|
|
|
|
func TestEstimatorMany(t *testing.T) {
|
|
|
|
now := rtptime.Jiffies()
|
|
|
|
e := new(now, time.Second)
|
|
|
|
|
|
|
|
for i := 0; i < 10000; i++ {
|
|
|
|
e.Accumulate(42)
|
|
|
|
now += rtptime.JiffiesPerSec / 1000
|
|
|
|
b, p := e.estimate(now)
|
|
|
|
if i >= 1000 {
|
|
|
|
if p != 1000 || b != p*42 {
|
|
|
|
t.Errorf("Got %v %v (%v), expected %v %v",
|
|
|
|
p, b, 1000, i, p*42,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestEstimatorParallel(t *testing.T) {
|
|
|
|
now := make([]uint64, 1)
|
|
|
|
now[0] = rtptime.Jiffies()
|
|
|
|
getNow := func() uint64 {
|
|
|
|
return atomic.LoadUint64(&now[0])
|
|
|
|
}
|
|
|
|
addNow := func(v uint64) {
|
|
|
|
atomic.AddUint64(&now[0], v)
|
|
|
|
}
|
|
|
|
e := new(getNow(), time.Second)
|
|
|
|
estimate := func() (uint32, uint32) {
|
|
|
|
e.mu.Lock()
|
|
|
|
defer e.mu.Unlock()
|
|
|
|
return e.estimate(getNow())
|
|
|
|
}
|
|
|
|
|
|
|
|
f := func(n int) {
|
|
|
|
for i := 0; i < 10000; i++ {
|
|
|
|
e.Accumulate(42)
|
|
|
|
addNow(rtptime.JiffiesPerSec / 1000)
|
|
|
|
b, p := estimate()
|
|
|
|
if i >= 1000 {
|
|
|
|
if b != p * 42 {
|
|
|
|
t.Errorf("%v: Got %v %v (%v), expected %v %v",
|
|
|
|
n, p, b, i, 1000, p*42,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
for i := 0; i < 16; i++ {
|
|
|
|
wg.Add(1)
|
|
|
|
go func(i int) {
|
|
|
|
f(i)
|
|
|
|
wg.Done()
|
|
|
|
}(i)
|
|
|
|
}
|
|
|
|
wg.Wait()
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkEstimator(b *testing.B) {
|
|
|
|
e := New(time.Second)
|
|
|
|
|
|
|
|
e.Estimate()
|
|
|
|
time.Sleep(time.Millisecond)
|
|
|
|
e.Estimate()
|
|
|
|
b.ResetTimer()
|
|
|
|
|
|
|
|
for i := 0; i < 1000 * b.N; i++ {
|
|
|
|
e.Accumulate(100)
|
|
|
|
|
|
|
|
}
|
|
|
|
e.Estimate()
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkEstimatorParallel(b *testing.B) {
|
|
|
|
e := New(time.Second)
|
|
|
|
|
|
|
|
e.Estimate()
|
|
|
|
time.Sleep(time.Millisecond)
|
|
|
|
e.Estimate()
|
|
|
|
b.ResetTimer()
|
|
|
|
|
|
|
|
b.RunParallel(func (pb *testing.PB) {
|
|
|
|
for pb.Next() {
|
|
|
|
for i := 0; i < 1000; i++ {
|
|
|
|
e.Accumulate(100)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
e.Estimate()
|
|
|
|
}
|