frostfs-node/pkg/local_object_storage/blobstor/blobovnicza_test.go
Alex Vanin e03d906cb7 [#334] engine: Make tests more predictable
There is a codecov issue because objects are not placed
in the engine the same way every unit test. Therefore
sometimes there are more coverage, sometimes there are
less. Seeded RNG should solve this issue for engine tests.

Signed-off-by: Alex Vanin <alexey@nspcc.ru>
2021-01-21 11:00:23 +03:00

162 lines
3.2 KiB
Go

package blobstor
import (
"crypto/sha256"
"errors"
"math/rand"
"os"
"testing"
"github.com/nspcc-dev/neofs-api-go/pkg/container"
objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object"
"github.com/nspcc-dev/neofs-node/pkg/core/object"
"github.com/nspcc-dev/neofs-node/pkg/util/logger/test"
"github.com/stretchr/testify/require"
)
func testSHA256() (h [sha256.Size]byte) {
rand.Read(h[:])
return h
}
func testAddress() *objectSDK.Address {
cid := container.NewID()
cid.SetSHA256(testSHA256())
oid := objectSDK.NewID()
oid.SetSHA256(testSHA256())
addr := objectSDK.NewAddress()
addr.SetObjectID(oid)
addr.SetContainerID(cid)
return addr
}
func testObject(sz uint64) *object.Object {
raw := object.NewRaw()
addr := testAddress()
raw.SetID(addr.ObjectID())
raw.SetContainerID(addr.ContainerID())
raw.SetPayload(make([]byte, sz))
// fit the binary size to the required
data, _ := raw.Marshal()
if ln := uint64(len(data)); ln > sz {
raw.SetPayload(raw.Payload()[:sz-(ln-sz)])
}
raw.SetAttributes() // for require.Equal
return raw.Object()
}
func TestBlobovniczas(t *testing.T) {
rand.Seed(1024)
l := test.NewLogger(false)
p := "./test_blz"
c := defaultCfg()
var width, depth, szLim uint64 = 2, 2, 2 << 10
for _, opt := range []Option{
WithLogger(l),
WithSmallSizeLimit(szLim),
WithBlobovniczaShallowWidth(width),
WithBlobovniczaShallowDepth(depth),
WithRootPath(p),
WithBlobovniczaSize(szLim),
} {
opt(c)
}
c.blzRootPath = p
b := newBlobovniczaTree(c)
defer os.RemoveAll(p)
require.NoError(t, b.init())
objSz := uint64(szLim / 2)
addrList := make([]*objectSDK.Address, 0)
minFitObjNum := width * depth * szLim / objSz
for i := uint64(0); i < minFitObjNum; i++ {
obj := testObject(objSz)
addrList = append(addrList, obj.Address())
d, err := obj.Marshal()
require.NoError(t, err)
// save object in blobovnicza
id, err := b.put(obj.Address(), d)
require.NoError(t, err)
// get w/ blobovnicza ID
prm := new(GetSmallPrm)
prm.SetBlobovniczaID(id)
prm.SetAddress(obj.Address())
res, err := b.get(prm)
require.NoError(t, err)
require.Equal(t, obj, res.Object())
// get w/o blobovnicza ID
prm.SetBlobovniczaID(nil)
res, err = b.get(prm)
require.NoError(t, err)
require.Equal(t, obj, res.Object())
// get range w/ blobovnicza ID
rngPrm := new(GetRangeSmallPrm)
rngPrm.SetBlobovniczaID(id)
rngPrm.SetAddress(obj.Address())
payload := obj.Payload()
pSize := uint64(len(obj.Payload()))
rng := objectSDK.NewRange()
rngPrm.SetRange(rng)
off, ln := pSize/3, 2*pSize/3
rng.SetOffset(off)
rng.SetLength(ln)
rngRes, err := b.getRange(rngPrm)
require.NoError(t, err)
require.Equal(t, payload[off:off+ln], rngRes.RangeData())
// get range w/o blobovnicza ID
rngPrm.SetBlobovniczaID(nil)
rngRes, err = b.getRange(rngPrm)
require.NoError(t, err)
require.Equal(t, payload[off:off+ln], rngRes.RangeData())
}
dPrm := new(DeleteSmallPrm)
gPrm := new(GetSmallPrm)
for i := range addrList {
dPrm.SetAddress(addrList[i])
_, err := b.delete(dPrm)
require.NoError(t, err)
gPrm.SetAddress(addrList[i])
_, err = b.get(gPrm)
require.True(t, errors.Is(err, object.ErrNotFound))
_, err = b.delete(dPrm)
require.True(t, errors.Is(err, object.ErrNotFound))
}
}