frostfs-node/pkg/local_object_storage/blobovnicza/blobovnicza_test.go

165 lines
3.3 KiB
Go

package blobovnicza
import (
"encoding/binary"
"errors"
"math/rand"
"os"
"testing"
"github.com/nspcc-dev/neofs-node/pkg/util/logger/test"
addressSDK "github.com/nspcc-dev/neofs-sdk-go/object/address"
objecttest "github.com/nspcc-dev/neofs-sdk-go/object/address/test"
"github.com/stretchr/testify/require"
)
func testPutGet(t *testing.T, blz *Blobovnicza, addr *addressSDK.Address, sz uint64, assertErrPut, assertErrGet func(error) bool) *addressSDK.Address {
// create binary object
data := make([]byte, sz)
rand.Read(data)
pPut := new(PutPrm)
pPut.SetAddress(addr)
pPut.SetMarshaledObject(data)
_, err := blz.Put(pPut)
if assertErrPut != nil {
require.True(t, assertErrPut(err))
} else {
require.NoError(t, err)
}
if assertErrPut != nil {
return nil
}
testGet(t, blz, addr, data, assertErrGet)
return addr
}
func testGet(t *testing.T, blz *Blobovnicza, addr *addressSDK.Address, expObj []byte, assertErr func(error) bool) {
pGet := new(GetPrm)
pGet.SetAddress(addr)
// try to read object from Blobovnicza
res, err := blz.Get(pGet)
if assertErr != nil {
require.True(t, assertErr(err))
} else {
require.NoError(t, err)
}
if assertErr == nil {
require.Equal(t, expObj, res.Object())
}
}
func TestBlobovnicza(t *testing.T) {
rand.Seed(1024)
p := "./test_blz"
sizeLim := uint64(256 * 1 << 10) // 256KB
objSizeLim := sizeLim / 2
// create Blobovnicza instance
blz := New(
WithPath(p),
WithObjectSizeLimit(objSizeLim),
WithFullSizeLimit(sizeLim),
WithLogger(test.NewLogger(false)),
)
defer os.Remove(p)
// open Blobovnicza
require.NoError(t, blz.Open())
// initialize Blobovnicza
require.NoError(t, blz.Init())
// try to read non-existent address
testGet(t, blz, objecttest.Address(), nil, IsErrNotFound)
filled := uint64(15 * 1 << 10)
// test object 15KB
addr := testPutGet(t, blz, objecttest.Address(), filled, nil, nil)
// remove the object
dPrm := new(DeletePrm)
dPrm.SetAddress(addr)
_, err := blz.Delete(dPrm)
require.NoError(t, err)
// should return 404
testGet(t, blz, addr, nil, IsErrNotFound)
// fill Blobovnicza fully
for ; filled < sizeLim; filled += objSizeLim {
testPutGet(t, blz, objecttest.Address(), objSizeLim, nil, nil)
}
// from now objects should not be saved
testPutGet(t, blz, objecttest.Address(), 1024, func(err error) bool {
return errors.Is(err, ErrFull)
}, nil)
require.NoError(t, blz.Close())
}
func TestIterateObjects(t *testing.T) {
p := t.Name()
// create Blobovnicza instance
blz := New(
WithPath(p),
WithObjectSizeLimit(1<<10),
WithFullSizeLimit(100<<10),
)
defer os.Remove(p)
// open Blobovnicza
require.NoError(t, blz.Open())
// initialize Blobovnicza
require.NoError(t, blz.Init())
const objNum = 5
mObjs := make(map[string][]byte)
for i := uint64(0); i < objNum; i++ {
data := make([]byte, 8) // actual data doesn't really matter for test
binary.BigEndian.PutUint64(data, i)
mObjs[string(data)] = data
}
var putPrm PutPrm
for _, v := range mObjs {
putPrm.SetAddress(objecttest.Address())
putPrm.SetMarshaledObject(v)
_, err := blz.Put(&putPrm)
require.NoError(t, err)
}
err := IterateObjects(blz, func(data []byte) error {
v, ok := mObjs[string(data)]
require.True(t, ok)
require.Equal(t, v, data)
delete(mObjs, string(data))
return nil
})
require.NoError(t, err)
require.Empty(t, mObjs)
}