[#232] Fix SplitInfo update in existed virtual object

Signed-off-by: Alex Vanin <alexey@nspcc.ru>
remotes/KirillovDenis/release/v0.21.1
Alex Vanin 2020-12-04 12:01:41 +03:00
parent e0350efe00
commit 26f03c6301
2 changed files with 60 additions and 2 deletions

View File

@ -69,4 +69,59 @@ func TestDB_Exists(t *testing.T) {
var expectedErr *objectSDK.SplitInfoError
require.True(t, errors.As(err, &expectedErr))
})
t.Run("merge split info", func(t *testing.T) {
cid := testCID()
splitID := objectSDK.NewSplitID()
parent := generateRawObjectWithCID(t, cid)
addAttribute(parent, "foo", "bar")
child := generateRawObjectWithCID(t, cid)
child.SetParent(parent.Object().SDK())
child.SetParentID(parent.ID())
child.SetSplitID(splitID)
link := generateRawObjectWithCID(t, cid)
link.SetParent(parent.Object().SDK())
link.SetParentID(parent.ID())
link.SetChildren(child.ID())
link.SetSplitID(splitID)
t.Run("direct order", func(t *testing.T) {
err := db.Put(child.Object(), nil)
require.NoError(t, err)
err = db.Put(link.Object(), nil)
require.NoError(t, err)
_, err = db.Exists(parent.Object().Address())
require.Error(t, err)
si, ok := err.(*objectSDK.SplitInfoError)
require.True(t, ok)
require.Equal(t, splitID, si.SplitInfo().SplitID())
require.Equal(t, child.ID(), si.SplitInfo().LastPart())
require.Equal(t, link.ID(), si.SplitInfo().Link())
})
t.Run("reverse order", func(t *testing.T) {
err := db.Put(link.Object(), nil)
require.NoError(t, err)
err = db.Put(child.Object(), nil)
require.NoError(t, err)
_, err = db.Exists(parent.Object().Address())
require.Error(t, err)
si, ok := err.(*objectSDK.SplitInfoError)
require.True(t, ok)
require.Equal(t, splitID, si.SplitInfo().SplitID())
require.Equal(t, child.ID(), si.SplitInfo().LastPart())
require.Equal(t, link.ID(), si.SplitInfo().Link())
})
})
}

View File

@ -37,8 +37,11 @@ func (db *DB) put(tx *bbolt.Tx, obj *object.Object, id *blobovnicza.ID, si *obje
isParent := si != nil
exists, err := db.exists(tx, obj.Address())
if err != nil && !errors.As(err, &splitInfoError) {
return err
if errors.As(err, &splitInfoError) {
exists = true // object exists, however it is virtual
} else if err != nil {
return err // return any error besides SplitInfoError
}
// most right child and split header overlap parent so we have to