[#1445] metabase/test: Add tests for locks of the new format

Test decoding and encoding functions for locks and lists of locks of
the new format. Also, test that when the object is being locked with
the same lock, its expiration epoch is set if it wasn't set before.

Signed-off-by: Aleksey Savchuk <a.savchuk@yadro.com>
This commit is contained in:
Aleksey Savchuk 2024-12-12 15:41:38 +03:00
parent 428cfed8af
commit 4d8550945c
Signed by: a-savchuk
GPG key ID: 70C0A7FF6F9C4639
2 changed files with 177 additions and 0 deletions

View file

@ -326,3 +326,46 @@ func TestGetLocks(t *testing.T) {
require.ElementsMatch(t, locks, gotLocks)
})
}
func TestAddMissingExpirationEpochOnLock(t *testing.T) {
t.Parallel()
db := newDB(t)
defer func() { require.NoError(t, db.Close(context.Background())) }()
locked := oidtest.Address()
locks := []meta.Lock{
{oidtest.ID(), rand.Uint64()},
{oidtest.ID(), meta.NoExpirationEpoch},
}
for _, lock := range locks {
require.NoError(t, db.Lock(
context.Background(),
locked.Container(),
lock.ID,
[]oid.ID{locked.Object()},
lock.ExpEpoch,
))
}
gotLocks, err := db.GetLocks(context.Background(), locked)
require.NoError(t, err)
require.ElementsMatch(t, locks, gotLocks)
for i := range locks {
require.NoError(t, db.Lock(
context.Background(),
locked.Container(),
locks[i].ID, []oid.ID{locked.Object()},
locks[i].ExpEpoch+100,
))
if locks[i].ExpEpoch == meta.NoExpirationEpoch {
locks[i].ExpEpoch += 100
}
}
gotLocks, err = db.GetLocks(context.Background(), locked)
require.NoError(t, err)
require.ElementsMatch(t, locks, gotLocks)
}

View file

@ -0,0 +1,134 @@
package meta
import (
"crypto/rand"
"testing"
"github.com/stretchr/testify/require"
)
func Test_lockWithExpEpoch(t *testing.T) {
t.Parallel()
id1 := make([]byte, objectKeySize)
id2 := make([]byte, objectKeySize)
epoch1 := make([]byte, epochSize)
epoch2 := make([]byte, epochSize)
noEpoch := make([]byte, epochSize)
_, _ = rand.Read(id1)
_, _ = rand.Read(id2)
_, _ = rand.Read(epoch1)
_, _ = rand.Read(epoch2)
for _, testCase := range []struct {
name string
rawLockList [][]byte
ids [][]byte
expEpochs [][]byte
shouldFail bool
}{
{
name: "nil lock",
},
{
name: "empty lock",
rawLockList: [][]byte{},
},
{
name: "all locks have epochs",
rawLockList: [][]byte{
id1, epoch1,
id2, epoch2,
id1, epoch2,
},
ids: [][]byte{id1, id2, id1},
expEpochs: [][]byte{epoch1, epoch2, epoch2},
},
{
name: "some locks have epochs",
rawLockList: [][]byte{
id1,
id2, epoch1,
id1, epoch2,
id2,
id2, epoch2,
},
ids: [][]byte{id1, id2, id1, id2, id2},
expEpochs: [][]byte{noEpoch, epoch1, epoch2, noEpoch, epoch2},
},
{
name: "locks have no epochs",
rawLockList: [][]byte{
id1,
id2,
id1,
id2,
},
ids: [][]byte{id1, id2, id1, id2},
expEpochs: [][]byte{noEpoch, noEpoch, noEpoch, noEpoch},
},
{
name: "got an epoch when want an id (in the beginning)",
rawLockList: [][]byte{
epoch1,
id1,
id2, epoch2,
},
shouldFail: true,
},
{
name: "got an epoch when want an id (in the middle)",
rawLockList: [][]byte{
id1,
id2, epoch2,
epoch1,
id1, epoch1,
id2, epoch2,
},
shouldFail: true,
},
{
name: "got an epoch when want an id (in the end)",
rawLockList: [][]byte{
id1, epoch1,
id2,
id1,
id2, epoch2,
epoch1,
},
shouldFail: true,
},
} {
t.Run(testCase.name, func(t *testing.T) {
require.Equal(t, len(testCase.ids), len(testCase.expEpochs), "not a valid test case")
rawLocks, err := encodeList(testCase.rawLockList)
require.NoError(t, err)
locks, err := decodeLockWithExpEpochList(rawLocks)
if testCase.shouldFail {
require.Error(t, err)
return
}
require.NoError(t, err)
require.Equal(t, len(testCase.ids), len(locks))
for i := range testCase.ids {
require.Equal(t, testCase.ids[i], locks[i].id[:])
require.Equal(t, testCase.expEpochs[i], locks[i].expEpoch[:])
}
data, err := encodeLockWithExpEpochList(locks)
require.NoError(t, err)
require.Equal(t, rawLocks, data)
data, err = encodeLockWithExpEpochList(locks)
require.NoError(t, err)
require.Equal(t, rawLocks, data)
})
}
}