AdGuardHome/internal/stats/stats_internal_test.go
Ainar Garipov 137d280032 Pull request 1729: upd-go
Merge in DNS/adguard-home from upd-go to master

Squashed commit of the following:

commit 0e13d6863a3d463289823a27414b427cb76be88c
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Feb 7 20:20:14 2023 +0300

    scripts: try increasing test timeout

commit 8e7d230e40de8f49a2b74a6d32a7fc78a361edab
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Feb 7 20:00:17 2023 +0300

    all: upd quic-go; imp atomic values

commit fae2b75b6990f2bd77e5c019a35a72322bac85f7
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Tue Feb 7 17:36:33 2023 +0300

    all: upd go, deps; imp atomic values
2023-02-08 13:39:04 +03:00

103 lines
2 KiB
Go

package stats
import (
"fmt"
"path/filepath"
"sync"
"sync/atomic"
"testing"
"time"
"github.com/AdguardTeam/golibs/testutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// TODO(e.burkov): Use more realistic data.
func TestStatsCollector(t *testing.T) {
ng := func(_ *unitDB) uint64 { return 0 }
units := make([]*unitDB, 720)
t.Run("hours", func(t *testing.T) {
statsData := statsCollector(units, 0, Hours, ng)
assert.Len(t, statsData, 720)
})
t.Run("days", func(t *testing.T) {
for i := 0; i != 25; i++ {
statsData := statsCollector(units, uint32(i), Days, ng)
require.Lenf(t, statsData, 30, "i=%d", i)
}
})
}
func TestStats_races(t *testing.T) {
var r uint32
idGen := func() (id uint32) { return atomic.LoadUint32(&r) }
conf := Config{
UnitID: idGen,
Filename: filepath.Join(t.TempDir(), "./stats.db"),
LimitDays: 1,
}
s, err := New(conf)
require.NoError(t, err)
s.Start()
startTime := time.Now()
testutil.CleanupAndRequireSuccess(t, s.Close)
writeFunc := func(start, fin *sync.WaitGroup, waitCh <-chan unit, i int) {
e := Entry{
Domain: fmt.Sprintf("example-%d.org", i),
Client: fmt.Sprintf("client_%d", i),
Result: Result(i)%(resultLast-1) + 1,
Time: uint32(time.Since(startTime).Milliseconds()),
}
start.Done()
defer fin.Done()
<-waitCh
s.Update(e)
}
readFunc := func(start, fin *sync.WaitGroup, waitCh <-chan unit) {
start.Done()
defer fin.Done()
<-waitCh
_, _ = s.getData(24)
}
const (
roundsNum = 3
writersNum = 10
readersNum = 5
)
for round := 0; round < roundsNum; round++ {
atomic.StoreUint32(&r, uint32(round))
startWG, finWG := &sync.WaitGroup{}, &sync.WaitGroup{}
waitCh := make(chan unit)
for i := 0; i < writersNum; i++ {
startWG.Add(1)
finWG.Add(1)
go writeFunc(startWG, finWG, waitCh, i)
}
for i := 0; i < readersNum; i++ {
startWG.Add(1)
finWG.Add(1)
go readFunc(startWG, finWG, waitCh)
}
startWG.Wait()
close(waitCh)
finWG.Wait()
}
}