Skip to content

Commit 342c6cb

Browse files
committed
fstree: refactor tests
Make cleaner tests code, remove duplication. Signed-off-by: Andrey Butusov <andrey@nspcc.io>
1 parent d745fca commit 342c6cb

5 files changed

Lines changed: 139 additions & 184 deletions

File tree

pkg/local_object_storage/blobstor/fstree/bench_test.go

Lines changed: 25 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ import (
44
"io"
55
"testing"
66

7-
"github.com/nspcc-dev/neofs-node/pkg/core/object"
8-
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/compression"
97
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/fstree"
108
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
119
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
@@ -15,109 +13,76 @@ import (
1513
func BenchmarkFSTree_Head(b *testing.B) {
1614
for _, size := range payloadSizes {
1715
b.Run(generateSizeLabel(size), func(b *testing.B) {
18-
fsTree := fstree.New(fstree.WithPath(b.TempDir()))
19-
20-
require.NoError(b, fsTree.Open(false))
21-
require.NoError(b, fsTree.Init())
22-
23-
testReadOp(b, fsTree, fsTree.Head, "Head", size)
16+
fsTree := setupFSTree(b)
17+
runReadBenchmark(b, fsTree, fsTree.Head, "Head", size)
2418
})
2519
}
2620
}
2721

2822
func BenchmarkFSTree_Get(b *testing.B) {
2923
for _, size := range payloadSizes {
3024
b.Run(generateSizeLabel(size), func(b *testing.B) {
31-
fsTree := fstree.New(fstree.WithPath(b.TempDir()))
32-
33-
require.NoError(b, fsTree.Open(false))
34-
require.NoError(b, fsTree.Init())
35-
36-
testReadOp(b, fsTree, fsTree.Get, "Get", size)
25+
fsTree := setupFSTree(b)
26+
runReadBenchmark(b, fsTree, fsTree.Get, "Get", size)
3727
})
3828
}
3929
}
4030

4131
func BenchmarkFSTree_GetStream(b *testing.B) {
4232
for _, size := range payloadSizes {
4333
b.Run(generateSizeLabel(size), func(b *testing.B) {
44-
fsTree := fstree.New(fstree.WithPath(b.TempDir()))
45-
46-
require.NoError(b, fsTree.Open(false))
47-
require.NoError(b, fsTree.Init())
48-
49-
testGetStreamOp(b, fsTree, size)
34+
fsTree := setupFSTree(b)
35+
runGetStreamBenchmark(b, fsTree, size)
5036
})
5137
}
5238
}
5339

54-
func testReadOp(b *testing.B, fsTree *fstree.FSTree, read func(address oid.Address) (*objectSDK.Object, error),
55-
name string, payloadSize int) {
40+
func runReadBenchmark(b *testing.B, fsTree *fstree.FSTree, readFunc func(oid.Address) (*objectSDK.Object, error), name string, payloadSize int) {
5641
b.Run(name+"_regular", func(b *testing.B) {
57-
obj := generateTestObject(payloadSize)
58-
addr := object.AddressOf(obj)
42+
addr := prepareSingleObject(b, fsTree, payloadSize)
5943

60-
require.NoError(b, fsTree.Put(addr, obj.Marshal()))
6144
b.ReportAllocs()
6245
b.ResetTimer()
6346
for range b.N {
64-
_, err := read(addr)
47+
_, err := readFunc(addr)
6548
if err != nil {
6649
b.Fatal(err)
6750
}
6851
}
6952
})
7053

7154
b.Run(name+"_combined", func(b *testing.B) {
72-
const numObjects = 10
73-
74-
objMap := make(map[oid.Address][]byte, numObjects)
75-
addrs := make([]oid.Address, numObjects)
76-
for i := range numObjects {
77-
o := generateTestObject(payloadSize)
78-
objMap[object.AddressOf(o)] = o.Marshal()
79-
addrs[i] = object.AddressOf(o)
80-
}
81-
require.NoError(b, fsTree.PutBatch(objMap))
55+
addrs := prepareMultipleObjects(b, fsTree, payloadSize)
8256

8357
b.ReportAllocs()
8458
b.ResetTimer()
8559
for k := range b.N {
86-
_, err := read(addrs[k%numObjects])
60+
_, err := readFunc(addrs[k%len(addrs)])
8761
if err != nil {
8862
b.Fatal(err)
8963
}
9064
}
9165
})
9266

9367
b.Run(name+"_compressed", func(b *testing.B) {
94-
obj := generateTestObject(payloadSize)
95-
addr := object.AddressOf(obj)
96-
97-
compressConfig := &compression.Config{
98-
Enabled: true,
99-
}
100-
require.NoError(b, compressConfig.Init())
101-
fsTree.SetCompressor(compressConfig)
102-
require.NoError(b, fsTree.Put(addr, obj.Marshal()))
68+
setupCompressor(b, fsTree)
69+
addr := prepareSingleObject(b, fsTree, payloadSize)
10370

10471
b.ReportAllocs()
10572
b.ResetTimer()
10673
for range b.N {
107-
_, err := read(addr)
74+
_, err := readFunc(addr)
10875
if err != nil {
10976
b.Fatal(err)
11077
}
11178
}
11279
})
11380
}
11481

115-
func testGetStreamOp(b *testing.B, fsTree *fstree.FSTree, payloadSize int) {
82+
func runGetStreamBenchmark(b *testing.B, fsTree *fstree.FSTree, payloadSize int) {
11683
b.Run("GetStream_regular", func(b *testing.B) {
117-
obj := generateTestObject(payloadSize)
118-
addr := object.AddressOf(obj)
84+
addr := prepareSingleObject(b, fsTree, payloadSize)
11985

120-
require.NoError(b, fsTree.Put(addr, obj.Marshal()))
12186
b.ReportAllocs()
12287
b.ResetTimer()
12388
for range b.N {
@@ -129,49 +94,33 @@ func testGetStreamOp(b *testing.B, fsTree *fstree.FSTree, payloadSize int) {
12994
b.Fatal("header is nil")
13095
}
13196
if reader != nil {
132-
reader.Close()
97+
require.NoError(b, reader.Close())
13398
}
13499
}
135100
})
136101

137102
b.Run("GetStream_combined", func(b *testing.B) {
138-
const numObjects = 10
139-
140-
objMap := make(map[oid.Address][]byte, numObjects)
141-
addrs := make([]oid.Address, numObjects)
142-
for i := range numObjects {
143-
o := generateTestObject(payloadSize)
144-
objMap[object.AddressOf(o)] = o.Marshal()
145-
addrs[i] = object.AddressOf(o)
146-
}
147-
require.NoError(b, fsTree.PutBatch(objMap))
103+
addrs := prepareMultipleObjects(b, fsTree, payloadSize)
148104

149105
b.ReportAllocs()
150106
b.ResetTimer()
151107
for k := range b.N {
152-
header, reader, err := fsTree.GetStream(addrs[k%numObjects])
108+
header, reader, err := fsTree.GetStream(addrs[k%len(addrs)])
153109
if err != nil {
154110
b.Fatal(err)
155111
}
156112
if header == nil {
157113
b.Fatal("header is nil")
158114
}
159115
if reader != nil {
160-
reader.Close()
116+
require.NoError(b, reader.Close())
161117
}
162118
}
163119
})
164120

165121
b.Run("GetStream_compressed", func(b *testing.B) {
166-
obj := generateTestObject(payloadSize)
167-
addr := object.AddressOf(obj)
168-
169-
compressConfig := &compression.Config{
170-
Enabled: true,
171-
}
172-
require.NoError(b, compressConfig.Init())
173-
fsTree.SetCompressor(compressConfig)
174-
require.NoError(b, fsTree.Put(addr, obj.Marshal()))
122+
setupCompressor(b, fsTree)
123+
addr := prepareSingleObject(b, fsTree, payloadSize)
175124

176125
b.ReportAllocs()
177126
b.ResetTimer()
@@ -184,16 +133,14 @@ func testGetStreamOp(b *testing.B, fsTree *fstree.FSTree, payloadSize int) {
184133
b.Fatal("header is nil")
185134
}
186135
if reader != nil {
187-
reader.Close()
136+
require.NoError(b, reader.Close())
188137
}
189138
}
190139
})
191140

192141
b.Run("GetStream_with_payload_read", func(b *testing.B) {
193-
obj := generateTestObject(payloadSize)
194-
addr := object.AddressOf(obj)
142+
addr := prepareSingleObject(b, fsTree, payloadSize)
195143

196-
require.NoError(b, fsTree.Put(addr, obj.Marshal()))
197144
b.ReportAllocs()
198145
b.ResetTimer()
199146
for range b.N {
@@ -210,7 +157,7 @@ func testGetStreamOp(b *testing.B, fsTree *fstree.FSTree, payloadSize int) {
210157
if err != nil {
211158
b.Fatal(err)
212159
}
213-
reader.Close()
160+
require.NoError(b, reader.Close())
214161
}
215162
}
216163
})
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package fstree_test
2+
3+
import (
4+
"crypto/rand"
5+
"fmt"
6+
"testing"
7+
8+
"github.com/nspcc-dev/neofs-node/pkg/core/object"
9+
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/compression"
10+
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/fstree"
11+
objectSDK "github.com/nspcc-dev/neofs-sdk-go/object"
12+
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
13+
objecttest "github.com/nspcc-dev/neofs-sdk-go/object/test"
14+
"github.com/stretchr/testify/require"
15+
)
16+
17+
var payloadSizes = []int{
18+
0, // Empty payload
19+
100, // 100 bytes
20+
4 * 1024, // 4 KB
21+
16 * 1024, // 16 KB
22+
32 * 1024, // 32 KB
23+
100 * 1024, // 100 KB
24+
1024 * 1024, // 1 MB
25+
}
26+
27+
func setupFSTree(tb testing.TB) *fstree.FSTree {
28+
fsTree := fstree.New(fstree.WithPath(tb.TempDir()))
29+
require.NoError(tb, fsTree.Open(false))
30+
require.NoError(tb, fsTree.Init())
31+
return fsTree
32+
}
33+
34+
func setupCompressor(tb testing.TB, fsTree *fstree.FSTree) {
35+
compressConfig := &compression.Config{
36+
Enabled: true,
37+
}
38+
require.NoError(tb, compressConfig.Init())
39+
fsTree.SetCompressor(compressConfig)
40+
}
41+
42+
func prepareSingleObject(tb testing.TB, fsTree *fstree.FSTree, payloadSize int) oid.Address {
43+
obj := generateTestObject(payloadSize)
44+
addr := object.AddressOf(obj)
45+
require.NoError(tb, fsTree.Put(addr, obj.Marshal()))
46+
return addr
47+
}
48+
49+
func addAttribute(obj *objectSDK.Object, key, value string) {
50+
var attr objectSDK.Attribute
51+
attr.SetKey(key)
52+
attr.SetValue(value)
53+
54+
attrs := obj.Attributes()
55+
attrs = append(attrs, attr)
56+
obj.SetAttributes(attrs...)
57+
}
58+
59+
func generateTestObject(payloadSize int) *objectSDK.Object {
60+
obj := objecttest.Object()
61+
if payloadSize > 0 {
62+
payload := make([]byte, payloadSize)
63+
_, _ = rand.Read(payload)
64+
obj.SetPayload(payload)
65+
} else {
66+
obj.SetPayload(nil)
67+
}
68+
obj.SetPayloadSize(uint64(payloadSize))
69+
70+
return &obj
71+
}
72+
73+
func generateSizeLabel(size int) string {
74+
switch {
75+
case size == 0:
76+
return "Empty"
77+
case size < 1024:
78+
return fmt.Sprintf("%dB", size)
79+
case size < 1024*1024:
80+
return fmt.Sprintf("%dKB", size/1024)
81+
default:
82+
return fmt.Sprintf("%dMB", size/(1024*1024))
83+
}
84+
}
85+
86+
func prepareMultipleObjects(tb testing.TB, fsTree *fstree.FSTree, payloadSize int) []oid.Address {
87+
const numObjects = 10
88+
objMap := make(map[oid.Address][]byte, numObjects)
89+
addrs := make([]oid.Address, numObjects)
90+
91+
for i := range numObjects {
92+
obj := generateTestObject(payloadSize)
93+
addr := object.AddressOf(obj)
94+
objMap[addr] = obj.Marshal()
95+
addrs[i] = addr
96+
}
97+
98+
require.NoError(tb, fsTree.PutBatch(objMap))
99+
return addrs
100+
}

0 commit comments

Comments
 (0)