forked from TrueCloudLab/frostfs-node
[#1163] metabase: Handle multiple splitInfos for EC
For REP updating split info is handled explicitly by a high-level PUT logic. For EC it is trickier, because the address of an object we put is only distantly related to a split info. Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
This commit is contained in:
parent
2e074d3846
commit
3f1961157e
2 changed files with 168 additions and 71 deletions
|
@ -642,7 +642,7 @@ func (tt *testTarget) WriteObject(_ context.Context, obj *objectSDK.Object) erro
|
|||
return nil
|
||||
}
|
||||
|
||||
func cutObject(t *testing.T, p transformer.ChunkedObjectWriter, hdr *objectSDK.Object, size int) {
|
||||
func cutObject(t *testing.T, p transformer.ChunkedObjectWriter, hdr *objectSDK.Object, size int) *transformer.AccessIdentifiers {
|
||||
ctx := context.Background()
|
||||
require.NoError(t, p.WriteHeader(ctx, hdr))
|
||||
|
||||
|
@ -652,8 +652,128 @@ func cutObject(t *testing.T, p transformer.ChunkedObjectWriter, hdr *objectSDK.O
|
|||
_, err := p.Write(ctx, payload)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = p.Close(ctx)
|
||||
ids, err := p.Close(ctx)
|
||||
require.NoError(t, err)
|
||||
return ids
|
||||
}
|
||||
|
||||
func TestDB_RawHead_SplitInfo(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const (
|
||||
partSize = 10
|
||||
partCount = 2
|
||||
dataCount = 2
|
||||
parityCount = 1
|
||||
)
|
||||
|
||||
db := newDB(t)
|
||||
defer func() { require.NoError(t, db.Close()) }()
|
||||
|
||||
cnr := cidtest.ID()
|
||||
|
||||
pk, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
|
||||
tt := new(testTarget)
|
||||
p := transformer.NewPayloadSizeLimiter(transformer.Params{
|
||||
Key: &pk.PrivateKey,
|
||||
NextTargetInit: func() transformer.ObjectWriter { return tt },
|
||||
NetworkState: epochState{e: 1},
|
||||
MaxSize: partSize,
|
||||
})
|
||||
|
||||
hdr := objectSDK.New()
|
||||
hdr.SetContainerID(cnr)
|
||||
hdr.SetOwnerID(usertest.ID())
|
||||
ids := cutObject(t, p, hdr, partSize*partCount)
|
||||
require.Equal(t, len(tt.objects), partCount+1)
|
||||
|
||||
t.Run("rep", func(t *testing.T) {
|
||||
testGetRawSplitInfo(t, cnr, ids, tt.objects[partCount], tt.objects[partCount-1])
|
||||
})
|
||||
t.Run("with ec", func(t *testing.T) {
|
||||
ec, err := erasurecode.NewConstructor(dataCount, parityCount)
|
||||
require.NoError(t, err)
|
||||
|
||||
cs, err := ec.Split(tt.objects[partCount-1], &pk.PrivateKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
testGetRawSplitInfo(t, cnr, ids, tt.objects[partCount], cs[0])
|
||||
})
|
||||
}
|
||||
|
||||
func testGetRawSplitInfo(t *testing.T, cnr cidSDK.ID, ids *transformer.AccessIdentifiers, linking, lastPart *objectSDK.Object) {
|
||||
expectedLinkID, ok := linking.ID()
|
||||
require.True(t, ok)
|
||||
|
||||
t.Run("first last, then linking", func(t *testing.T) {
|
||||
db := newDB(t)
|
||||
defer func() { require.NoError(t, db.Close()) }()
|
||||
|
||||
require.NoError(t, metaPut(db, lastPart, nil))
|
||||
require.NoError(t, metaPut(db, linking, nil))
|
||||
|
||||
var addr oid.Address
|
||||
addr.SetContainer(cnr)
|
||||
addr.SetObject(*ids.ParentID)
|
||||
|
||||
_, err := metaGet(db, addr, true)
|
||||
|
||||
var siErr *objectSDK.SplitInfoError
|
||||
require.ErrorAs(t, err, &siErr)
|
||||
|
||||
lastID, ok := siErr.SplitInfo().LastPart()
|
||||
require.True(t, ok)
|
||||
require.Equal(t, ids.SelfID, lastID)
|
||||
|
||||
linkID, ok := siErr.SplitInfo().Link()
|
||||
require.True(t, ok)
|
||||
require.Equal(t, expectedLinkID, linkID)
|
||||
})
|
||||
t.Run("first linking, then last", func(t *testing.T) {
|
||||
db := newDB(t)
|
||||
defer func() { require.NoError(t, db.Close()) }()
|
||||
|
||||
require.NoError(t, metaPut(db, linking, nil))
|
||||
require.NoError(t, metaPut(db, lastPart, nil))
|
||||
|
||||
var addr oid.Address
|
||||
addr.SetContainer(cnr)
|
||||
addr.SetObject(*ids.ParentID)
|
||||
|
||||
_, err := metaGet(db, addr, true)
|
||||
|
||||
var siErr *objectSDK.SplitInfoError
|
||||
require.ErrorAs(t, err, &siErr)
|
||||
|
||||
lastID, ok := siErr.SplitInfo().LastPart()
|
||||
require.True(t, ok)
|
||||
require.Equal(t, ids.SelfID, lastID)
|
||||
|
||||
linkID, ok := siErr.SplitInfo().Link()
|
||||
require.True(t, ok)
|
||||
require.Equal(t, expectedLinkID, linkID)
|
||||
})
|
||||
t.Run("only last part", func(t *testing.T) {
|
||||
db := newDB(t)
|
||||
defer func() { require.NoError(t, db.Close()) }()
|
||||
|
||||
require.NoError(t, metaPut(db, lastPart, nil))
|
||||
|
||||
var addr oid.Address
|
||||
addr.SetContainer(cnr)
|
||||
addr.SetObject(*ids.ParentID)
|
||||
|
||||
_, err := metaGet(db, addr, true)
|
||||
|
||||
var siErr *objectSDK.SplitInfoError
|
||||
require.ErrorAs(t, err, &siErr)
|
||||
|
||||
lastPart, ok := siErr.SplitInfo().LastPart()
|
||||
require.True(t, ok)
|
||||
require.Equal(t, ids.SelfID, lastPart)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDB_SelectSplitID_EC(t *testing.T) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue