From 26f03c63012469013e5c77b479b64a3137798d63 Mon Sep 17 00:00:00 2001 From: Alex Vanin Date: Fri, 4 Dec 2020 12:01:41 +0300 Subject: [PATCH] [#232] Fix SplitInfo update in existed virtual object Signed-off-by: Alex Vanin --- .../metabase/v2/exists_test.go | 55 +++++++++++++++++++ pkg/local_object_storage/metabase/v2/put.go | 7 ++- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/pkg/local_object_storage/metabase/v2/exists_test.go b/pkg/local_object_storage/metabase/v2/exists_test.go index 68220e0b..d9f97cf7 100644 --- a/pkg/local_object_storage/metabase/v2/exists_test.go +++ b/pkg/local_object_storage/metabase/v2/exists_test.go @@ -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()) + }) + }) } diff --git a/pkg/local_object_storage/metabase/v2/put.go b/pkg/local_object_storage/metabase/v2/put.go index 5a079306..f7a7979c 100644 --- a/pkg/local_object_storage/metabase/v2/put.go +++ b/pkg/local_object_storage/metabase/v2/put.go @@ -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