2020-11-23 13:30:56 +00:00
|
|
|
package meta_test
|
|
|
|
|
|
|
|
import (
|
2023-04-12 14:01:29 +00:00
|
|
|
"context"
|
2020-11-23 13:30:56 +00:00
|
|
|
"testing"
|
|
|
|
|
2023-03-07 13:38:26 +00:00
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
|
2023-03-20 14:10:26 +00:00
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/testutil"
|
2023-03-07 13:38:26 +00:00
|
|
|
meta "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/metabase"
|
2023-08-04 11:14:07 +00:00
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
2023-03-07 13:38:26 +00:00
|
|
|
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
2024-09-20 10:28:21 +00:00
|
|
|
cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test"
|
2023-03-07 13:38:26 +00:00
|
|
|
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
|
|
|
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
|
2020-11-23 13:30:56 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestDB_Inhume(t *testing.T) {
|
|
|
|
db := newDB(t)
|
2024-01-09 13:26:43 +00:00
|
|
|
defer func() { require.NoError(t, db.Close()) }()
|
2020-11-23 13:30:56 +00:00
|
|
|
|
2023-03-20 14:10:26 +00:00
|
|
|
raw := testutil.GenerateObject()
|
|
|
|
testutil.AddAttribute(raw, "foo", "bar")
|
2020-11-23 13:30:56 +00:00
|
|
|
|
2022-03-03 14:19:05 +00:00
|
|
|
err := putBig(db, raw)
|
2020-11-23 13:30:56 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2024-09-20 10:28:21 +00:00
|
|
|
err = metaInhume(db, object.AddressOf(raw), oidtest.ID())
|
2020-11-23 13:30:56 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2022-07-12 14:42:55 +00:00
|
|
|
_, err = metaExists(db, object.AddressOf(raw))
|
2023-08-04 11:14:07 +00:00
|
|
|
require.True(t, client.IsErrObjectAlreadyRemoved(err))
|
2020-11-23 13:30:56 +00:00
|
|
|
|
2022-07-12 14:42:55 +00:00
|
|
|
_, err = metaGet(db, object.AddressOf(raw), false)
|
2023-08-04 11:14:07 +00:00
|
|
|
require.True(t, client.IsErrObjectAlreadyRemoved(err))
|
2020-11-23 13:30:56 +00:00
|
|
|
}
|
2021-02-19 09:49:23 +00:00
|
|
|
|
|
|
|
func TestInhumeTombOnTomb(t *testing.T) {
|
|
|
|
db := newDB(t)
|
2024-01-09 13:26:43 +00:00
|
|
|
defer func() { require.NoError(t, db.Close()) }()
|
2021-02-19 09:49:23 +00:00
|
|
|
|
|
|
|
var (
|
|
|
|
err error
|
|
|
|
|
2024-09-20 10:28:21 +00:00
|
|
|
cnr = cidtest.ID()
|
2022-05-31 17:00:41 +00:00
|
|
|
addr1 = oidtest.Address()
|
|
|
|
addr2 = oidtest.Address()
|
|
|
|
addr3 = oidtest.Address()
|
2024-09-20 10:28:21 +00:00
|
|
|
addr4 = oidtest.Address()
|
2022-05-20 16:48:14 +00:00
|
|
|
inhumePrm meta.InhumePrm
|
|
|
|
existsPrm meta.ExistsPrm
|
2021-02-19 09:49:23 +00:00
|
|
|
)
|
|
|
|
|
2024-09-20 10:28:21 +00:00
|
|
|
addr1.SetContainer(cnr)
|
|
|
|
addr2.SetContainer(cnr)
|
|
|
|
addr3.SetContainer(cnr)
|
|
|
|
addr4.SetContainer(cnr)
|
|
|
|
|
2022-07-12 14:59:37 +00:00
|
|
|
inhumePrm.SetAddresses(addr1)
|
|
|
|
inhumePrm.SetTombstoneAddress(addr2)
|
2022-05-20 16:48:14 +00:00
|
|
|
|
2021-02-19 09:49:23 +00:00
|
|
|
// inhume addr1 via addr2
|
2023-04-12 14:01:29 +00:00
|
|
|
_, err = db.Inhume(context.Background(), inhumePrm)
|
2021-02-19 09:49:23 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2022-07-12 14:59:37 +00:00
|
|
|
existsPrm.SetAddress(addr1)
|
2022-05-20 16:48:14 +00:00
|
|
|
|
2021-02-19 09:49:23 +00:00
|
|
|
// addr1 should become inhumed {addr1:addr2}
|
2023-04-12 14:01:29 +00:00
|
|
|
_, err = db.Exists(context.Background(), existsPrm)
|
2023-08-04 11:14:07 +00:00
|
|
|
require.True(t, client.IsErrObjectAlreadyRemoved(err))
|
2021-02-19 09:49:23 +00:00
|
|
|
|
2022-07-12 14:59:37 +00:00
|
|
|
inhumePrm.SetAddresses(addr3)
|
|
|
|
inhumePrm.SetTombstoneAddress(addr1)
|
2022-05-20 16:48:14 +00:00
|
|
|
|
2021-02-19 09:49:23 +00:00
|
|
|
// try to inhume addr3 via addr1
|
2023-04-12 14:01:29 +00:00
|
|
|
_, err = db.Inhume(context.Background(), inhumePrm)
|
2021-02-19 09:49:23 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
// record with {addr1:addr2} should be removed from graveyard
|
2021-04-08 17:06:13 +00:00
|
|
|
// as a tomb-on-tomb; metabase should return ObjectNotFound
|
|
|
|
// NOT ObjectAlreadyRemoved since that record has been removed
|
|
|
|
// from graveyard but addr1 is still marked with GC
|
2023-04-12 14:01:29 +00:00
|
|
|
_, err = db.Exists(context.Background(), existsPrm)
|
2023-08-04 11:14:07 +00:00
|
|
|
require.True(t, client.IsErrObjectNotFound(err))
|
2021-02-19 09:49:23 +00:00
|
|
|
|
2022-07-12 14:59:37 +00:00
|
|
|
existsPrm.SetAddress(addr3)
|
2022-05-20 16:48:14 +00:00
|
|
|
|
2021-02-19 09:49:23 +00:00
|
|
|
// addr3 should be inhumed {addr3: addr1}
|
2023-04-12 14:01:29 +00:00
|
|
|
_, err = db.Exists(context.Background(), existsPrm)
|
2023-08-04 11:14:07 +00:00
|
|
|
require.True(t, client.IsErrObjectAlreadyRemoved(err))
|
2021-02-19 09:49:23 +00:00
|
|
|
|
2022-07-12 14:59:37 +00:00
|
|
|
inhumePrm.SetAddresses(addr1)
|
2024-09-20 10:28:21 +00:00
|
|
|
inhumePrm.SetTombstoneAddress(addr4)
|
2022-05-20 16:48:14 +00:00
|
|
|
|
2021-02-19 09:49:23 +00:00
|
|
|
// try to inhume addr1 (which is already a tombstone in graveyard)
|
2023-04-12 14:01:29 +00:00
|
|
|
_, err = db.Inhume(context.Background(), inhumePrm)
|
2021-02-19 09:49:23 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2022-07-12 14:59:37 +00:00
|
|
|
existsPrm.SetAddress(addr1)
|
2022-05-20 16:48:14 +00:00
|
|
|
|
2021-02-19 09:49:23 +00:00
|
|
|
// record with addr1 key should not appear in graveyard
|
2021-04-08 17:06:13 +00:00
|
|
|
// (tomb can not be inhumed) but should be kept as object
|
|
|
|
// with GC mark
|
2023-04-12 14:01:29 +00:00
|
|
|
_, err = db.Exists(context.Background(), existsPrm)
|
2023-08-04 11:14:07 +00:00
|
|
|
require.True(t, client.IsErrObjectNotFound(err))
|
2021-02-19 09:49:23 +00:00
|
|
|
}
|
2022-02-15 22:16:07 +00:00
|
|
|
|
|
|
|
func TestInhumeLocked(t *testing.T) {
|
|
|
|
db := newDB(t)
|
2024-01-09 13:26:43 +00:00
|
|
|
defer func() { require.NoError(t, db.Close()) }()
|
2022-02-15 22:16:07 +00:00
|
|
|
|
2022-05-31 17:00:41 +00:00
|
|
|
locked := oidtest.Address()
|
2022-02-15 22:16:07 +00:00
|
|
|
|
2023-04-12 14:01:29 +00:00
|
|
|
err := db.Lock(context.Background(), locked.Container(), oidtest.ID(), []oid.ID{locked.Object()})
|
2022-02-15 22:16:07 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
var prm meta.InhumePrm
|
2022-07-12 14:59:37 +00:00
|
|
|
prm.SetAddresses(locked)
|
2022-02-15 22:16:07 +00:00
|
|
|
|
2023-04-12 14:01:29 +00:00
|
|
|
_, err = db.Inhume(context.Background(), prm)
|
2022-02-15 22:16:07 +00:00
|
|
|
|
2023-08-04 11:14:07 +00:00
|
|
|
var e *apistatus.ObjectLocked
|
2022-02-15 22:16:07 +00:00
|
|
|
require.ErrorAs(t, err, &e)
|
|
|
|
}
|
2022-07-12 14:42:55 +00:00
|
|
|
|
2024-09-20 10:28:21 +00:00
|
|
|
func metaInhume(db *meta.DB, target oid.Address, tomb oid.ID) error {
|
2022-07-12 14:42:55 +00:00
|
|
|
var inhumePrm meta.InhumePrm
|
2022-07-12 14:59:37 +00:00
|
|
|
inhumePrm.SetAddresses(target)
|
2024-09-20 10:28:21 +00:00
|
|
|
var tombAddr oid.Address
|
|
|
|
tombAddr.SetContainer(target.Container())
|
|
|
|
tombAddr.SetObject(tomb)
|
|
|
|
inhumePrm.SetTombstoneAddress(tombAddr)
|
2022-07-12 14:42:55 +00:00
|
|
|
|
2023-04-12 14:01:29 +00:00
|
|
|
_, err := db.Inhume(context.Background(), inhumePrm)
|
2022-07-12 14:42:55 +00:00
|
|
|
return err
|
|
|
|
}
|