frostfs-node/pkg/services/metrics/store_test.go

155 lines
2.7 KiB
Go

package metrics
import (
"sync"
"testing"
"github.com/nspcc-dev/neofs-api-go/refs"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/bucket"
"github.com/spaolacci/murmur3"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
)
type (
fakeKV struct {
key []byte
val []byte
}
fakeBucket struct {
sync.RWMutex
kv []fakeKV
items map[uint64]int
}
)
func keyFromBytes(b []byte) uint64 {
return murmur3.Sum64(b)
}
func (f *fakeBucket) Set(key, value []byte) error {
f.Lock()
defer f.Unlock()
var (
id int
ok bool
uid = keyFromBytes(key)
)
if id, ok = f.items[uid]; !ok || id >= len(f.kv) {
id = len(f.kv)
f.items[uid] = id
f.kv = append(f.kv, fakeKV{
key: key,
val: value,
})
return nil
}
f.kv[id] = fakeKV{
key: key,
val: value,
}
return nil
}
func (f *fakeBucket) Del(key []byte) error {
f.Lock()
defer f.Unlock()
delete(f.items, keyFromBytes(key))
return nil
}
func (f *fakeBucket) List() ([][]byte, error) {
f.RLock()
defer f.RUnlock()
items := make([][]byte, 0, len(f.items))
for _, id := range f.items {
// ignore unknown KV
if id >= len(f.kv) {
continue
}
items = append(items, f.kv[id].key)
}
return items, nil
}
func (f *fakeBucket) Iterate(handler bucket.FilterHandler) error {
f.Lock()
defer f.Unlock()
for _, id := range f.items {
// ignore unknown KV
if id >= len(f.kv) {
continue
}
kv := f.kv[id]
if !handler(kv.key, kv.val) {
break
}
}
return nil
}
func (f *fakeBucket) Get(_ []byte) ([]byte, error) { panic("implement me") }
func (f *fakeBucket) Has(_ []byte) bool { panic("implement me") }
func (f *fakeBucket) Size() int64 { panic("implement me") }
func (f *fakeBucket) Close() error { panic("implement me") }
func TestSyncStore(t *testing.T) {
buck := &fakeBucket{items: make(map[uint64]int)}
sizes := newSyncStore(zap.L(), buck)
for i := 0; i < 10; i++ {
cid := refs.CID{0, 0, 0, byte(i)}
require.NoError(t, buck.Set(cid.Bytes(), []byte{1, 2, 3, 4, 5, 6, 7, byte(i)}))
}
t.Run("load", func(t *testing.T) {
sizes.Load()
require.Len(t, sizes.items, len(buck.items))
})
t.Run("reset", func(t *testing.T) {
sizes.Reset(nil)
require.Len(t, sizes.items, 0)
})
t.Run("update", func(t *testing.T) {
cid := refs.CID{1, 2, 3, 4, 5}
{ // add space
sizes.Update(cid, 8, AddSpace)
val, ok := sizes.items[cid]
require.True(t, ok)
require.Equal(t, uint64(8), val)
}
{ // rem space
sizes.Update(cid, 8, RemSpace)
val, ok := sizes.items[cid]
require.True(t, ok)
require.Zero(t, val)
}
{ // rem space (zero - val)
sizes.Update(cid, 8, RemSpace)
val, ok := sizes.items[cid]
require.True(t, ok)
require.Zero(t, val)
}
})
}