forked from TrueCloudLab/frostfs-node
[#135] metabase: Implement benchmarking tests
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
1db01725c9
commit
a61f8d44d1
4 changed files with 377 additions and 0 deletions
66
pkg/local_object_storage/metabase/delete_test.go
Normal file
66
pkg/local_object_storage/metabase/delete_test.go
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
package meta
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/pkg/object"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"go.etcd.io/bbolt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BenchmarkDB_Delete(b *testing.B) {
|
||||||
|
path := "delete_test.db"
|
||||||
|
|
||||||
|
bdb, err := bbolt.Open(path, 0600, nil)
|
||||||
|
require.NoError(b, err)
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
bdb.Close()
|
||||||
|
os.Remove(path)
|
||||||
|
}()
|
||||||
|
|
||||||
|
db := NewDB(bdb)
|
||||||
|
|
||||||
|
var existingAddr *object.Address
|
||||||
|
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
obj := generateObject(b, testPrm{})
|
||||||
|
|
||||||
|
existingAddr = obj.Address()
|
||||||
|
|
||||||
|
require.NoError(b, db.Put(obj))
|
||||||
|
}
|
||||||
|
|
||||||
|
b.Run("existing address", func(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
b.ResetTimer()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
err := db.Delete(existingAddr)
|
||||||
|
|
||||||
|
b.StopTimer()
|
||||||
|
require.NoError(b, err)
|
||||||
|
b.StartTimer()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
b.Run("non-existing address", func(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
b.ResetTimer()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
b.StopTimer()
|
||||||
|
addr := object.NewAddress()
|
||||||
|
addr.SetContainerID(testCID())
|
||||||
|
addr.SetObjectID(testOID())
|
||||||
|
b.StartTimer()
|
||||||
|
|
||||||
|
err := db.Delete(addr)
|
||||||
|
|
||||||
|
b.StopTimer()
|
||||||
|
require.NoError(b, err)
|
||||||
|
b.StartTimer()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
66
pkg/local_object_storage/metabase/get_test.go
Normal file
66
pkg/local_object_storage/metabase/get_test.go
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
package meta
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/pkg/object"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"go.etcd.io/bbolt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BenchmarkDB_Get(b *testing.B) {
|
||||||
|
path := "get_test.db"
|
||||||
|
|
||||||
|
bdb, err := bbolt.Open(path, 0600, nil)
|
||||||
|
require.NoError(b, err)
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
bdb.Close()
|
||||||
|
os.Remove(path)
|
||||||
|
}()
|
||||||
|
|
||||||
|
db := NewDB(bdb)
|
||||||
|
|
||||||
|
var existingAddr *object.Address
|
||||||
|
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
obj := generateObject(b, testPrm{})
|
||||||
|
|
||||||
|
existingAddr = obj.Address()
|
||||||
|
|
||||||
|
require.NoError(b, db.Put(obj))
|
||||||
|
}
|
||||||
|
|
||||||
|
b.Run("existing address", func(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
b.ResetTimer()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_, err := db.Get(existingAddr)
|
||||||
|
|
||||||
|
b.StopTimer()
|
||||||
|
require.NoError(b, err)
|
||||||
|
b.StartTimer()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
b.Run("non-existing address", func(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
b.ResetTimer()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
b.StopTimer()
|
||||||
|
addr := object.NewAddress()
|
||||||
|
addr.SetContainerID(testCID())
|
||||||
|
addr.SetObjectID(testOID())
|
||||||
|
b.StartTimer()
|
||||||
|
|
||||||
|
_, err := db.Get(addr)
|
||||||
|
|
||||||
|
b.StopTimer()
|
||||||
|
require.Error(b, err)
|
||||||
|
b.StartTimer()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
145
pkg/local_object_storage/metabase/put_test.go
Normal file
145
pkg/local_object_storage/metabase/put_test.go
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
package meta
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/sha256"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/pkg"
|
||||||
|
objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
|
||||||
|
"github.com/nspcc-dev/neofs-node/pkg/core/object"
|
||||||
|
"github.com/nspcc-dev/neofs-node/pkg/util/test"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"go.etcd.io/bbolt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type testPrm struct {
|
||||||
|
withParent bool
|
||||||
|
|
||||||
|
attrNum int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p testPrm) String() string {
|
||||||
|
return fmt.Sprintf("[with_parent:%t, attributes:%d]",
|
||||||
|
p.withParent,
|
||||||
|
p.attrNum,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateChecksum() *pkg.Checksum {
|
||||||
|
cs := pkg.NewChecksum()
|
||||||
|
|
||||||
|
sh := [sha256.Size]byte{}
|
||||||
|
rand.Read(sh[:])
|
||||||
|
|
||||||
|
cs.SetSHA256(sh)
|
||||||
|
|
||||||
|
return cs
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateObject(t require.TestingT, prm testPrm) *object.Object {
|
||||||
|
obj := object.NewRaw()
|
||||||
|
obj.SetID(testOID())
|
||||||
|
obj.SetVersion(pkg.SDKVersion())
|
||||||
|
obj.SetContainerID(testCID())
|
||||||
|
obj.SetChildren(testOID())
|
||||||
|
obj.SetPreviousID(testOID())
|
||||||
|
obj.SetParentID(testOID())
|
||||||
|
obj.SetPayloadChecksum(generateChecksum())
|
||||||
|
obj.SetPayloadHomomorphicHash(generateChecksum())
|
||||||
|
obj.SetType(objectSDK.TypeRegular)
|
||||||
|
|
||||||
|
as := make([]*objectSDK.Attribute, 0, prm.attrNum)
|
||||||
|
|
||||||
|
for i := 0; i < prm.attrNum; i++ {
|
||||||
|
a := objectSDK.NewAttribute()
|
||||||
|
|
||||||
|
k := make([]byte, 32)
|
||||||
|
rand.Read(k)
|
||||||
|
a.SetKey(string(k))
|
||||||
|
|
||||||
|
v := make([]byte, 32)
|
||||||
|
rand.Read(v)
|
||||||
|
a.SetValue(string(v))
|
||||||
|
|
||||||
|
as = append(as, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
obj.SetAttributes(as...)
|
||||||
|
|
||||||
|
wallet, err := owner.NEO3WalletFromPublicKey(&test.DecodeKey(-1).PublicKey)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
ownerID := owner.NewID()
|
||||||
|
ownerID.SetNeo3Wallet(wallet)
|
||||||
|
|
||||||
|
obj.SetOwnerID(ownerID)
|
||||||
|
|
||||||
|
if prm.withParent {
|
||||||
|
prm.withParent = false
|
||||||
|
obj.SetParent(generateObject(t, prm).SDK())
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj.Object()
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkDB_Put(b *testing.B) {
|
||||||
|
path := "put_test.db"
|
||||||
|
|
||||||
|
bdb, err := bbolt.Open(path, 0600, nil)
|
||||||
|
require.NoError(b, err)
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
bdb.Close()
|
||||||
|
os.Remove(path)
|
||||||
|
}()
|
||||||
|
|
||||||
|
db := NewDB(bdb)
|
||||||
|
|
||||||
|
for _, prm := range []testPrm{
|
||||||
|
{
|
||||||
|
withParent: false,
|
||||||
|
attrNum: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
withParent: true,
|
||||||
|
attrNum: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
withParent: false,
|
||||||
|
attrNum: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
withParent: true,
|
||||||
|
attrNum: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
withParent: false,
|
||||||
|
attrNum: 1000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
withParent: true,
|
||||||
|
attrNum: 1000,
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
b.Run(prm.String(), func(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
b.ResetTimer()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
b.StopTimer()
|
||||||
|
obj := generateObject(b, prm)
|
||||||
|
b.StartTimer()
|
||||||
|
|
||||||
|
err := db.Put(obj)
|
||||||
|
|
||||||
|
b.StopTimer()
|
||||||
|
require.NoError(b, err)
|
||||||
|
b.StartTimer()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
100
pkg/local_object_storage/metabase/select_test.go
Normal file
100
pkg/local_object_storage/metabase/select_test.go
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
package meta
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"go.etcd.io/bbolt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func addNFilters(fs *objectSDK.SearchFilters, n int) {
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
key := make([]byte, 32)
|
||||||
|
rand.Read(key)
|
||||||
|
|
||||||
|
val := make([]byte, 32)
|
||||||
|
rand.Read(val)
|
||||||
|
|
||||||
|
fs.AddFilter(string(key), string(val), objectSDK.MatchStringEqual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkDB_Select(b *testing.B) {
|
||||||
|
path := "select_test.db"
|
||||||
|
|
||||||
|
bdb, err := bbolt.Open(path, 0600, nil)
|
||||||
|
require.NoError(b, err)
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
bdb.Close()
|
||||||
|
os.Remove(path)
|
||||||
|
}()
|
||||||
|
|
||||||
|
db := NewDB(bdb)
|
||||||
|
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
obj := generateObject(b, testPrm{
|
||||||
|
withParent: true,
|
||||||
|
attrNum: 100,
|
||||||
|
})
|
||||||
|
|
||||||
|
require.NoError(b, db.Put(obj))
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range []struct {
|
||||||
|
name string
|
||||||
|
filters func(*objectSDK.SearchFilters)
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "empty",
|
||||||
|
filters: func(*objectSDK.SearchFilters) {
|
||||||
|
return
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "1 filter",
|
||||||
|
filters: func(fs *objectSDK.SearchFilters) {
|
||||||
|
addNFilters(fs, 1)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "10 filters",
|
||||||
|
filters: func(fs *objectSDK.SearchFilters) {
|
||||||
|
addNFilters(fs, 10)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "100 filters",
|
||||||
|
filters: func(fs *objectSDK.SearchFilters) {
|
||||||
|
addNFilters(fs, 100)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "1000 filters",
|
||||||
|
filters: func(fs *objectSDK.SearchFilters) {
|
||||||
|
addNFilters(fs, 1000)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
b.Run(item.name, func(b *testing.B) {
|
||||||
|
b.ReportAllocs()
|
||||||
|
b.ResetTimer()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
b.StopTimer()
|
||||||
|
fs := new(objectSDK.SearchFilters)
|
||||||
|
item.filters(fs)
|
||||||
|
b.StartTimer()
|
||||||
|
|
||||||
|
_, err := db.Select(*fs)
|
||||||
|
|
||||||
|
b.StopTimer()
|
||||||
|
require.NoError(b, err)
|
||||||
|
b.StartTimer()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue