frostfs-node/pkg/local_object_storage/blobovnicza/blobovnicza_test.go
Leonard Lyubich eaae5a5dd7 [#229] blobovnicza: Store objects in a binary format
In previous implementation Blobovnicza's stored objects in protocol format
which did not allow working with externally compressed objects. To achieve
this goal, operations Get and Put no longer work with the structure of the
object, but only with abstract binary data. Operation GetRange has become
incorrect in its original purpose to receive the payload range. In this
regard, BlobStor receives the payload range of the object through Get
operation. In the future either Blobovnicza will learn to compress objects
by itself, or the GetRange operation will be eliminated.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2020-12-11 17:19:37 +03:00

141 lines
2.9 KiB
Go

package blobovnicza
import (
"crypto/rand"
"crypto/sha256"
"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/pkg/errors"
"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 testPutGet(t *testing.T, blz *Blobovnicza, sz uint64, expPut, expGet error) *objectSDK.Address {
// create binary object
data := make([]byte, sz)
addr := testAddress()
// try to save object in Blobovnicza
pPut := new(PutPrm)
pPut.SetAddress(addr)
pPut.SetMarshaledObject(data)
_, err := blz.Put(pPut)
require.True(t, errors.Is(err, expPut))
if expPut != nil {
return nil
}
testGet(t, blz, addr, data, expGet)
return addr
}
func testGet(t *testing.T, blz *Blobovnicza, addr *objectSDK.Address, expObj []byte, expErr error) {
pGet := new(GetPrm)
pGet.SetAddress(addr)
// try to read object from Blobovnicza
res, err := blz.Get(pGet)
require.True(t, errors.Is(err, expErr))
if expErr == nil {
require.Equal(t, expObj, res.Object())
}
}
func TestBlobovnicza(t *testing.T) {
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, testAddress(), nil, object.ErrNotFound)
filled := uint64(15 * 1 << 10)
// test object 15KB
addr := testPutGet(t, blz, 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, object.ErrNotFound)
// fill Blobovnicza fully
for ; filled < sizeLim; filled += objSizeLim {
testPutGet(t, blz, objSizeLim, nil, nil)
}
// from now objects should not be saved
testPutGet(t, blz, 1024, ErrFull, nil)
require.NoError(t, blz.Close())
}