satellite/metabase: use commit order for objects

This changes metabase behavior such that the latest object
will be the committed object which may result in a new version
assigned to the objects.

Change-Id: I7a731d7db4696caba75fff65107a248569b6111f
This commit is contained in:
Egon Elbre 2023-10-25 19:14:24 +03:00
parent eff1719977
commit a4edbdd005
8 changed files with 212 additions and 123 deletions

View File

@ -692,11 +692,11 @@ func (db *DB) CommitObject(ctx context.Context, opts CommitObject) (object Objec
var highestVersion Version
if opts.Versioned {
// TODO(ver): fold this into the queries below using a subquery.
v, err := db.queryHighestVersion(ctx, opts.Location(), tx)
maxVersion, err := db.queryHighestVersion(ctx, opts.Location(), tx)
if err != nil {
return Error.Wrap(err)
}
highestVersion = v
highestVersion = maxVersion
} else {
// TODO(ver): fold this into the query below using a subquery using `ON CONFLICT` on the unique index.
// Note, we are prematurely deleting the object without permissions
@ -708,7 +708,6 @@ func (db *DB) CommitObject(ctx context.Context, opts CommitObject) (object Objec
if deleteResult.DeletedObjectCount > 0 && opts.DisallowDelete {
return ErrPermissionDenied.New("no permissions to delete existing object")
}
highestVersion = deleteResult.MaxVersion
}
@ -784,6 +783,13 @@ func (db *DB) CommitObject(ctx context.Context, opts CommitObject) (object Objec
return Error.New("failed to update object: %w", err)
}
} else {
nextVersion := opts.Version
if nextVersion < highestVersion {
nextVersion = highestVersion + 1
}
args = append(args, nextVersion)
opts.Version = nextVersion
metadataColumns := ""
if opts.OverrideEncryptedMetadata {
args = append(args,
@ -792,13 +798,14 @@ func (db *DB) CommitObject(ctx context.Context, opts CommitObject) (object Objec
opts.EncryptedMetadataEncryptedKey,
)
metadataColumns = `,
encrypted_metadata_nonce = $12,
encrypted_metadata = $13,
encrypted_metadata_encrypted_key = $14
encrypted_metadata_nonce = $13,
encrypted_metadata = $14,
encrypted_metadata_encrypted_key = $15
`
}
err = tx.QueryRowContext(ctx, `
UPDATE objects SET
version = $12,
status = $6,
segment_count = $7,

View File

@ -51,23 +51,31 @@ func (db *DB) CommitObjectWithSegments(ctx context.Context, opts CommitObjectWit
return Object{}, nil, err
}
var previousObject deleteObjectUnversionedCommittedResult
var deleted deleteObjectUnversionedCommittedResult
err = txutil.WithTx(ctx, db.db, nil, func(ctx context.Context, tx tagsql.Tx) error {
// TODO: should we prevent this from executing when the object has been committed
// currently this requires quite a lot of database communication, so invalid handling can be expensive.
var highestVersion Version
if !opts.Versioned {
var err error
// Note, we are prematurely deleting the object without permissions
// and then rolling the action back, if we were not allowed to.
previousObject, err = db.deleteObjectUnversionedCommitted(ctx, opts.Location(), tx)
deleted, err = db.deleteObjectUnversionedCommitted(ctx, opts.Location(), tx)
if err != nil {
return err
}
if previousObject.DeletedObjectCount > 0 && opts.DisallowDelete {
if deleted.DeletedObjectCount > 0 && opts.DisallowDelete {
return ErrPermissionDenied.New("no permissions to delete existing object")
}
highestVersion = deleted.MaxVersion
} else {
v, err := db.queryHighestVersion(ctx, opts.Location(), tx)
if err != nil {
return err
}
highestVersion = v
}
segmentsInDatabase, err := fetchSegmentsForCommit(ctx, tx, opts.StreamID)
@ -113,9 +121,14 @@ func (db *DB) CommitObjectWithSegments(ctx context.Context, opts CommitObjectWit
}
nextStatus := committedWhereVersioned(opts.Versioned)
nextVersion := opts.Version
if nextVersion < highestVersion {
nextVersion = highestVersion + 1
}
err = tx.QueryRowContext(ctx, `
UPDATE objects SET
version = $14,
status = $6,
segment_count = $7,
@ -138,6 +151,7 @@ func (db *DB) CommitObjectWithSegments(ctx context.Context, opts CommitObjectWit
totalPlainSize,
totalEncryptedSize,
fixedSegmentSize,
nextVersion,
).
Scan(
&object.CreatedAt, &object.ExpiresAt,
@ -154,7 +168,7 @@ func (db *DB) CommitObjectWithSegments(ctx context.Context, opts CommitObjectWit
object.ProjectID = opts.ProjectID
object.BucketName = opts.BucketName
object.ObjectKey = opts.ObjectKey
object.Version = opts.Version
object.Version = nextVersion
object.Status = nextStatus
object.SegmentCount = int32(len(finalSegments))
object.EncryptedMetadataNonce = opts.EncryptedMetadataNonce

View File

@ -332,6 +332,7 @@ func TestCommitObjectWithSegments(t *testing.T) {
EncryptedMetadata: encryptedMetadata,
EncryptedMetadataEncryptedKey: encryptedMetadataKey,
},
ExpectVersion: obj.Version + 1,
}.Check(ctx, t, db)
metabasetest.Verify{
@ -341,7 +342,7 @@ func TestCommitObjectWithSegments(t *testing.T) {
ProjectID: obj.ProjectID,
BucketName: obj.BucketName,
ObjectKey: obj.ObjectKey,
Version: 5,
Version: obj.Version + 1,
StreamID: obj.StreamID,
},
CreatedAt: now,

View File

@ -264,6 +264,7 @@ func TestBeginObjectNextVersion(t *testing.T) {
StreamID: obj.StreamID,
},
},
ExpectVersion: 3,
}.Check(ctx, t, db)
// currently CommitObject always deletes previous versions so only version 1 left
@ -274,7 +275,7 @@ func TestBeginObjectNextVersion(t *testing.T) {
ProjectID: obj.ProjectID,
BucketName: obj.BucketName,
ObjectKey: obj.ObjectKey,
Version: 1,
Version: 3,
StreamID: obj.StreamID,
},
CreatedAt: now1,
@ -799,6 +800,7 @@ func TestBeginObjectExactVersion(t *testing.T) {
Opts: metabase.CommitObject{
ObjectStream: objectStream,
},
ExpectVersion: 301,
}.Check(ctx, t, db)
// currently CommitObject always deletes previous versions so only version 1 left
@ -809,7 +811,7 @@ func TestBeginObjectExactVersion(t *testing.T) {
ProjectID: obj.ProjectID,
BucketName: obj.BucketName,
ObjectKey: obj.ObjectKey,
Version: 100,
Version: 301,
StreamID: obj.StreamID,
},
CreatedAt: now1,
@ -4432,21 +4434,27 @@ func TestCommitObjectVersioned(t *testing.T) {
ObjectStream: v1,
Versioned: true,
},
ExpectVersion: v3.Version + 1,
}.Check(ctx, t, db)
v1.Version = v3.Version + 1
metabasetest.CommitObject{
Opts: metabase.CommitObject{
ObjectStream: v2,
Versioned: true,
},
ExpectVersion: v3.Version + 2,
}.Check(ctx, t, db)
v2.Version = v1.Version + 1
metabasetest.CommitObject{
Opts: metabase.CommitObject{
ObjectStream: v3,
Versioned: true,
},
ExpectVersion: v3.Version + 3,
}.Check(ctx, t, db)
v3.Version = v2.Version + 1
metabasetest.Verify{
Objects: []metabase.RawObject{
@ -4558,13 +4566,17 @@ func TestCommitObjectVersioned(t *testing.T) {
Opts: metabase.CommitObject{
ObjectStream: v3,
},
ExpectVersion: 5,
}.Check(ctx, t, db)
v3.Version = 5
metabasetest.CommitObject{
Opts: metabase.CommitObject{
ObjectStream: v1,
},
ExpectVersion: 6,
}.Check(ctx, t, db)
v1.Version = 6
// The latter commit should overwrite the v3.
// When pending objects table is enabled, then objects
@ -4601,14 +4613,18 @@ func TestCommitObjectVersioned(t *testing.T) {
ObjectStream: v2,
Versioned: true,
},
ExpectVersion: 7,
}.Check(ctx, t, db)
v2.Version = 7
metabasetest.CommitObject{
Opts: metabase.CommitObject{
ObjectStream: v4,
Versioned: true,
},
ExpectVersion: 8,
}.Check(ctx, t, db)
v4.Version = 8
metabasetest.Verify{
Objects: []metabase.RawObject{
@ -4719,14 +4735,18 @@ func TestCommitObjectVersioned(t *testing.T) {
ObjectStream: v1,
Versioned: true,
},
ExpectVersion: 5,
}.Check(ctx, t, db)
v1.Version = 5
metabasetest.CommitObject{
Opts: metabase.CommitObject{
ObjectStream: v3,
Versioned: true,
},
ExpectVersion: 6,
}.Check(ctx, t, db)
v3.Version = 6
metabasetest.Verify{
Objects: []metabase.RawObject{
@ -4763,13 +4783,17 @@ func TestCommitObjectVersioned(t *testing.T) {
Opts: metabase.CommitObject{
ObjectStream: v2,
},
ExpectVersion: 7,
}.Check(ctx, t, db)
v2.Version = 7
metabasetest.CommitObject{
Opts: metabase.CommitObject{
ObjectStream: v4,
},
ExpectVersion: 8,
}.Check(ctx, t, db)
v4.Version = 8
// committing v4 should overwrite the previous unversioned commit (v2),
// so v2 is not in the result check
@ -4882,7 +4906,9 @@ func TestCommitObjectVersioned(t *testing.T) {
ObjectStream: v1,
Versioned: true,
},
ExpectVersion: 5,
}.Check(ctx, t, db)
v1.Version = 5
metabasetest.Verify{
Objects: []metabase.RawObject{
@ -4920,7 +4946,9 @@ func TestCommitObjectVersioned(t *testing.T) {
Opts: metabase.CommitObject{
ObjectStream: v2,
},
ExpectVersion: 6,
}.Check(ctx, t, db)
v2.Version = 6
metabasetest.Verify{
Objects: []metabase.RawObject{
@ -4958,7 +4986,9 @@ func TestCommitObjectVersioned(t *testing.T) {
ObjectStream: v3,
Versioned: true,
},
ExpectVersion: 7,
}.Check(ctx, t, db)
v3.Version = 7
metabasetest.Verify{
Objects: []metabase.RawObject{
@ -4994,7 +5024,9 @@ func TestCommitObjectVersioned(t *testing.T) {
Opts: metabase.CommitObject{
ObjectStream: v4,
},
ExpectVersion: 8,
}.Check(ctx, t, db)
v4.Version = 8
// committing v4 should overwrite the previous unversioned commit (v2),
// so v2 is not in the result check
@ -5043,6 +5075,7 @@ func TestCommitObjectVersioned(t *testing.T) {
}
rawObjects := make([]metabase.RawObject, 0, len(objs))
expectVersion := metabase.Version(numCommits + 1)
for i := 0; i < len(objs); i++ {
versioned := i%2 == 0
@ -5051,7 +5084,10 @@ func TestCommitObjectVersioned(t *testing.T) {
ObjectStream: *objs[i],
Versioned: versioned,
},
ExpectVersion: expectVersion,
}.Check(ctx, t, db)
objs[i].Version = expectVersion
expectVersion++
if versioned {
rawObjects = append(rawObjects, metabase.RawObject{

View File

@ -4,6 +4,7 @@
package metabase_test
import (
"strconv"
"testing"
"time"
@ -1028,125 +1029,131 @@ func TestFinishCopyObject(t *testing.T) {
// - expected copy version
testCases := []struct {
Bucket string
Key metabase.ObjectKey
NewBucket string
NewKey metabase.ObjectKey
sourcePendingVersions []metabase.Version
sourceCommittedVersion metabase.Version
destinationPendingVersions []metabase.Version
destinationCommittedVersion metabase.Version
expectedCopyVersion metabase.Version
Bucket string
Key metabase.ObjectKey
NewBucket string
NewKey metabase.ObjectKey
sourcePendingVersions []metabase.Version
sourceCommitVersion metabase.Version
sourceCommittedVersion metabase.Version
destinationPendingVersions []metabase.Version
destinationCommitVersion metabase.Version
destionationCommittedVersion metabase.Version
expectedCopyVersion metabase.Version
}{
// the same bucket
{"testbucket", "object", "testbucket", "new-object",
[]metabase.Version{}, 2,
[]metabase.Version{}, 1,
0: {"testbucket", "object", "testbucket", "new-object",
[]metabase.Version{}, 2, 2,
[]metabase.Version{}, 1, 1,
2},
{"testbucket", "object", "testbucket", "new-object",
[]metabase.Version{}, 1,
[]metabase.Version{1}, 2,
1: {"testbucket", "object", "testbucket", "new-object",
[]metabase.Version{}, 1, 1,
[]metabase.Version{1}, 2, 2,
3},
{"testbucket", "object", "testbucket", "new-object",
[]metabase.Version{}, 1,
[]metabase.Version{1, 3}, 2,
4},
{"testbucket", "object", "testbucket", "new-object",
[]metabase.Version{1, 5}, 2,
[]metabase.Version{1, 3}, 2,
4},
{"testbucket", "object", "newbucket", "object",
[]metabase.Version{2, 3}, 1,
[]metabase.Version{1, 5}, 2,
6},
2: {"testbucket", "object", "testbucket", "new-object",
[]metabase.Version{}, 1, 1,
[]metabase.Version{1, 3}, 2, 4,
5},
3: {"testbucket", "object", "testbucket", "new-object",
[]metabase.Version{1, 5}, 2, 6,
[]metabase.Version{1, 3}, 2, 4,
5},
4: {"testbucket", "object", "newbucket", "object",
[]metabase.Version{2, 3}, 1, 4,
[]metabase.Version{1, 5}, 2, 6,
7},
}
for _, tc := range testCases {
metabasetest.DeleteAll{}.Check(ctx, t, db)
sourceObjStream.BucketName = tc.Bucket
sourceObjStream.ObjectKey = tc.Key
destinationObjStream.BucketName = tc.NewBucket
destinationObjStream.ObjectKey = tc.NewKey
for i, tc := range testCases {
t.Run(strconv.Itoa(i), func(t *testing.T) {
defer metabasetest.DeleteAll{}.Check(ctx, t, db)
sourceObjStream.BucketName = tc.Bucket
sourceObjStream.ObjectKey = tc.Key
destinationObjStream.BucketName = tc.NewBucket
destinationObjStream.ObjectKey = tc.NewKey
var rawObjects []metabase.RawObject
for _, version := range tc.sourcePendingVersions {
sourceObjStream.Version = version
var rawObjects []metabase.RawObject
for _, version := range tc.sourcePendingVersions {
sourceObjStream.Version = version
sourceObjStream.StreamID = testrand.UUID()
metabasetest.CreatePendingObject(ctx, t, db, sourceObjStream, 0)
rawObjects = append(rawObjects, metabase.RawObject{
ObjectStream: sourceObjStream,
CreatedAt: now,
Status: metabase.Pending,
Encryption: metabasetest.DefaultEncryption,
ZombieDeletionDeadline: &zombieDeadline,
})
}
sourceObjStream.Version = tc.sourceCommitVersion
sourceObjStream.StreamID = testrand.UUID()
metabasetest.CreatePendingObject(ctx, t, db, sourceObjStream, 0)
rawObjects = append(rawObjects, metabase.RawObject{
ObjectStream: sourceObjStream,
CreatedAt: now,
Status: metabase.Pending,
Encryption: metabasetest.DefaultEncryption,
ZombieDeletionDeadline: &zombieDeadline,
})
}
sourceObjStream.Version = tc.sourceCommittedVersion
sourceObjStream.StreamID = testrand.UUID()
sourceObj, _ := metabasetest.CreateTestObject{
BeginObjectExactVersion: &metabase.BeginObjectExactVersion{
ObjectStream: sourceObjStream,
Encryption: metabasetest.DefaultEncryption,
},
CommitObject: &metabase.CommitObject{
ObjectStream: sourceObjStream,
OverrideEncryptedMetadata: true,
EncryptedMetadata: testrand.Bytes(64),
EncryptedMetadataNonce: testrand.Nonce().Bytes(),
EncryptedMetadataEncryptedKey: testrand.Bytes(265),
},
}.Run(ctx, t, db, sourceObjStream, 0)
rawObjects = append(rawObjects, metabase.RawObject(sourceObj))
for _, version := range tc.destinationPendingVersions {
destinationObjStream.Version = version
destinationObjStream.StreamID = testrand.UUID()
metabasetest.CreatePendingObject(ctx, t, db, destinationObjStream, 0)
rawObjects = append(rawObjects, metabase.RawObject{
ObjectStream: destinationObjStream,
CreatedAt: now,
Status: metabase.Pending,
Encryption: metabasetest.DefaultEncryption,
ZombieDeletionDeadline: &zombieDeadline,
})
}
if tc.destinationCommittedVersion != 0 {
destinationObjStream.StreamID = testrand.UUID()
destinationObjStream.Version = tc.destinationCommittedVersion
_, _ = metabasetest.CreateTestObject{
sourceObj, _ := metabasetest.CreateTestObject{
BeginObjectExactVersion: &metabase.BeginObjectExactVersion{
ObjectStream: destinationObjStream,
ObjectStream: sourceObjStream,
Encryption: metabasetest.DefaultEncryption,
},
CommitObject: &metabase.CommitObject{
ObjectStream: destinationObjStream,
ObjectStream: sourceObjStream,
OverrideEncryptedMetadata: true,
EncryptedMetadata: testrand.Bytes(64),
EncryptedMetadataNonce: testrand.Nonce().Bytes(),
EncryptedMetadataEncryptedKey: testrand.Bytes(265),
},
}.Run(ctx, t, db, destinationObjStream, 0)
}
ExpectVersion: tc.sourceCommittedVersion,
}.Run(ctx, t, db, sourceObjStream, 0)
copyObj, expectedOriginalSegments, _ := metabasetest.CreateObjectCopy{
OriginalObject: sourceObj,
CopyObjectStream: &destinationObjStream,
}.Run(ctx, t, db)
rawObjects = append(rawObjects, metabase.RawObject(sourceObj))
require.Equal(t, tc.expectedCopyVersion, copyObj.Version)
for _, version := range tc.destinationPendingVersions {
destinationObjStream.Version = version
destinationObjStream.StreamID = testrand.UUID()
metabasetest.CreatePendingObject(ctx, t, db, destinationObjStream, 0)
rawObjects = append(rawObjects, metabase.RawObject(copyObj))
rawObjects = append(rawObjects, metabase.RawObject{
ObjectStream: destinationObjStream,
CreatedAt: now,
Status: metabase.Pending,
metabasetest.Verify{
Objects: rawObjects,
Segments: expectedOriginalSegments,
}.Check(ctx, t, db)
Encryption: metabasetest.DefaultEncryption,
ZombieDeletionDeadline: &zombieDeadline,
})
}
if tc.destinationCommitVersion != 0 {
destinationObjStream.StreamID = testrand.UUID()
destinationObjStream.Version = tc.destinationCommitVersion
_, _ = metabasetest.CreateTestObject{
BeginObjectExactVersion: &metabase.BeginObjectExactVersion{
ObjectStream: destinationObjStream,
Encryption: metabasetest.DefaultEncryption,
},
CommitObject: &metabase.CommitObject{
ObjectStream: destinationObjStream,
OverrideEncryptedMetadata: true,
EncryptedMetadata: testrand.Bytes(64),
EncryptedMetadataNonce: testrand.Nonce().Bytes(),
EncryptedMetadataEncryptedKey: testrand.Bytes(265),
},
ExpectVersion: tc.destionationCommittedVersion,
}.Run(ctx, t, db, destinationObjStream, 0)
}
copyObj, expectedOriginalSegments, _ := metabasetest.CreateObjectCopy{
OriginalObject: sourceObj,
CopyObjectStream: &destinationObjStream,
}.Run(ctx, t, db)
require.Equal(t, tc.expectedCopyVersion, copyObj.Version)
rawObjects = append(rawObjects, metabase.RawObject(copyObj))
metabasetest.Verify{
Objects: rawObjects,
Segments: expectedOriginalSegments,
}.Check(ctx, t, db)
})
}
})

View File

@ -902,13 +902,13 @@ func TestListObjectsVersioned(t *testing.T) {
a1 := a0
a1.Version = 1001
b1 := a0
b1 := b0
b1.Version = 500
objA0 := metabasetest.CreateObjectVersioned(ctx, t, db, a0, 0)
objA1 := metabasetest.CreateObjectVersioned(ctx, t, db, a1, 0)
objB0 := metabasetest.CreateObjectVersioned(ctx, t, db, b0, 0)
objB1 := metabasetest.CreateObjectVersioned(ctx, t, db, b1, 0)
objB1 := metabasetest.CreateObjectVersionedOutOfOrder(ctx, t, db, b1, 0, 1001)
metabasetest.ListObjects{
Opts: metabase.ListObjects{
@ -922,7 +922,7 @@ func TestListObjectsVersioned(t *testing.T) {
Result: metabase.ListObjectsResult{
Objects: []metabase.ObjectEntry{
objectEntryFromRaw(metabase.RawObject(objA1)),
objectEntryFromRaw(metabase.RawObject(objB0)),
objectEntryFromRaw(metabase.RawObject(objB1)),
},
}}.Check(ctx, t, db)
@ -952,13 +952,13 @@ func TestListObjectsVersioned(t *testing.T) {
a1 := a0
a1.Version = 1001
b1 := a0
b1 := b0
b1.Version = 500
objA0 := metabasetest.CreateObjectVersioned(ctx, t, db, a0, 0)
objA1 := metabasetest.CreateObjectVersioned(ctx, t, db, a1, 0)
objB0 := metabasetest.CreateObjectVersioned(ctx, t, db, b0, 0)
objB1 := metabasetest.CreateObjectVersioned(ctx, t, db, b1, 0)
objB1 := metabasetest.CreateObjectVersionedOutOfOrder(ctx, t, db, b1, 0, 1001)
deletionResult := metabasetest.DeleteObjectLastCommitted{
Opts: metabase.DeleteObjectLastCommitted{
@ -992,7 +992,7 @@ func TestListObjectsVersioned(t *testing.T) {
},
Result: metabase.ListObjectsResult{
Objects: []metabase.ObjectEntry{
objectEntryFromRaw(metabase.RawObject(objB0)),
objectEntryFromRaw(metabase.RawObject(objB1)),
},
}}.Check(ctx, t, db)

View File

@ -124,6 +124,19 @@ func CreateObjectVersioned(ctx *testcontext.Context, t testing.TB, db *metabase.
}.Check(ctx, t, db)
}
// CreateObjectVersionedOutOfOrder creates a new committed object with the specified number of segments.
func CreateObjectVersionedOutOfOrder(ctx *testcontext.Context, t testing.TB, db *metabase.DB, obj metabase.ObjectStream, numberOfSegments byte, expectVersion metabase.Version) metabase.Object {
CreatePendingObject(ctx, t, db, obj, numberOfSegments)
return CommitObject{
Opts: metabase.CommitObject{
ObjectStream: obj,
Versioned: true,
},
ExpectVersion: expectVersion,
}.Check(ctx, t, db)
}
// CreateExpiredObject creates a new committed expired object with the specified number of segments.
func CreateExpiredObject(ctx *testcontext.Context, t testing.TB, db *metabase.DB, obj metabase.ObjectStream, numberOfSegments byte, expiresAt time.Time) metabase.Object {
BeginObjectExactVersion{
@ -206,6 +219,7 @@ func CreateSegments(ctx *testcontext.Context, t testing.TB, db *metabase.DB, obj
type CreateTestObject struct {
BeginObjectExactVersion *metabase.BeginObjectExactVersion
CommitObject *metabase.CommitObject
ExpectVersion metabase.Version
CreateSegment func(object metabase.Object, index int) metabase.Segment
}
@ -302,7 +316,8 @@ func (co CreateTestObject) Run(ctx *testcontext.Context, t testing.TB, db *metab
}
createdObject := CommitObject{
Opts: coOpts,
Opts: coOpts,
ExpectVersion: co.ExpectVersion,
}.Check(ctx, t, db)
return createdObject, createdSegments

View File

@ -87,9 +87,10 @@ func (step BeginObjectExactVersion) Check(ctx *testcontext.Context, t require.Te
// CommitObject is for testing metabase.CommitObject.
type CommitObject struct {
Opts metabase.CommitObject
ErrClass *errs.Class
ErrText string
Opts metabase.CommitObject
ExpectVersion metabase.Version
ErrClass *errs.Class
ErrText string
}
// Check runs the test.
@ -97,6 +98,9 @@ func (step CommitObject) Check(ctx *testcontext.Context, t require.TestingT, db
object, err := db.CommitObject(ctx, step.Opts)
checkError(t, err, step.ErrClass, step.ErrText)
if err == nil {
if step.ExpectVersion != 0 {
step.Opts.ObjectStream.Version = step.ExpectVersion
}
require.Equal(t, step.Opts.ObjectStream, object.ObjectStream)
}
return object
@ -104,8 +108,10 @@ func (step CommitObject) Check(ctx *testcontext.Context, t require.TestingT, db
// CommitObjectWithSegments is for testing metabase.CommitObjectWithSegments.
type CommitObjectWithSegments struct {
Opts metabase.CommitObjectWithSegments
Deleted []metabase.DeletedSegmentInfo
Opts metabase.CommitObjectWithSegments
Deleted []metabase.DeletedSegmentInfo
ExpectVersion metabase.Version
ErrClass *errs.Class
ErrText string
}
@ -115,6 +121,9 @@ func (step CommitObjectWithSegments) Check(ctx *testcontext.Context, t testing.T
object, deleted, err := db.CommitObjectWithSegments(ctx, step.Opts)
checkError(t, err, step.ErrClass, step.ErrText)
if err == nil {
if step.ExpectVersion != 0 {
step.Opts.ObjectStream.Version = step.ExpectVersion
}
require.Equal(t, step.Opts.ObjectStream, object.ObjectStream)
}
require.Equal(t, step.Deleted, deleted)