satellite/metabase: add version tests for GetLatestObjectLastSegment
Change-Id: Ia7ed1f6b23bcdc9e83fec288cbf3571b382d5e13
This commit is contained in:
parent
a7e1378f89
commit
504d5c5651
@ -272,12 +272,16 @@ func (db *DB) deleteObjectUnversionedCommitted(ctx context.Context, loc ObjectLo
|
||||
|
||||
var deleted Object
|
||||
|
||||
// TODO(ver): this scanning can probably simplified somehow.
|
||||
|
||||
var version sql.NullInt64
|
||||
var streamID uuid.NullUUID
|
||||
var createdAt sql.NullTime
|
||||
var segmentCount, fixedSegmentSize sql.NullInt32
|
||||
var totalPlainSize, totalEncryptedSize sql.NullInt64
|
||||
var status sql.NullByte
|
||||
var params nullableValue[encryptionParameters]
|
||||
params.value.EncryptionParameters = &deleted.Encryption
|
||||
var encryptionParams nullableValue[encryptionParameters]
|
||||
encryptionParams.value.EncryptionParameters = &deleted.Encryption
|
||||
|
||||
err = stmt.QueryRowContext(ctx, `
|
||||
WITH highest_object AS (
|
||||
@ -290,8 +294,11 @@ func (db *DB) deleteObjectUnversionedCommitted(ctx context.Context, loc ObjectLo
|
||||
(project_id, bucket_name, object_key) = ($1, $2, $3)
|
||||
AND status IN `+statusesUnversioned+`
|
||||
RETURNING
|
||||
version, stream_id, status, created_at, expires_at,
|
||||
version, stream_id,
|
||||
created_at, expires_at,
|
||||
status, segment_count,
|
||||
encrypted_metadata_nonce, encrypted_metadata, encrypted_metadata_encrypted_key,
|
||||
total_plain_size, total_encrypted_size, fixed_segment_size,
|
||||
encryption
|
||||
), deleted_segments AS (
|
||||
DELETE FROM segments
|
||||
@ -301,12 +308,16 @@ func (db *DB) deleteObjectUnversionedCommitted(ctx context.Context, loc ObjectLo
|
||||
SELECT
|
||||
(SELECT version FROM deleted_objects),
|
||||
(SELECT stream_id FROM deleted_objects),
|
||||
(SELECT status FROM deleted_objects),
|
||||
(SELECT created_at FROM deleted_objects),
|
||||
(SELECT expires_at FROM deleted_objects),
|
||||
(SELECT status FROM deleted_objects),
|
||||
(SELECT segment_count FROM deleted_objects),
|
||||
(SELECT encrypted_metadata_nonce FROM deleted_objects),
|
||||
(SELECT encrypted_metadata FROM deleted_objects),
|
||||
(SELECT encrypted_metadata_encrypted_key FROM deleted_objects),
|
||||
(SELECT total_plain_size FROM deleted_objects),
|
||||
(SELECT total_encrypted_size FROM deleted_objects),
|
||||
(SELECT fixed_segment_size FROM deleted_objects),
|
||||
(SELECT encryption FROM deleted_objects),
|
||||
(SELECT count(*) FROM deleted_objects),
|
||||
(SELECT count(*) FROM deleted_segments),
|
||||
@ -315,19 +326,26 @@ func (db *DB) deleteObjectUnversionedCommitted(ctx context.Context, loc ObjectLo
|
||||
Scan(
|
||||
&version,
|
||||
&streamID,
|
||||
&status,
|
||||
&createdAt,
|
||||
&deleted.ExpiresAt,
|
||||
&status,
|
||||
&segmentCount,
|
||||
&deleted.EncryptedMetadataNonce,
|
||||
&deleted.EncryptedMetadata,
|
||||
&deleted.EncryptedMetadataEncryptedKey,
|
||||
¶ms,
|
||||
|
||||
&totalPlainSize,
|
||||
&totalEncryptedSize,
|
||||
&fixedSegmentSize,
|
||||
&encryptionParams,
|
||||
&result.DeletedObjectCount,
|
||||
&result.DeletedSegmentCount,
|
||||
&result.MaxVersion,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return deleteObjectUnversionedCommittedResult{}, Error.Wrap(err)
|
||||
}
|
||||
|
||||
deleted.ProjectID = loc.ProjectID
|
||||
deleted.BucketName = loc.BucketName
|
||||
deleted.ObjectKey = loc.ObjectKey
|
||||
@ -336,10 +354,11 @@ func (db *DB) deleteObjectUnversionedCommitted(ctx context.Context, loc ObjectLo
|
||||
deleted.Status = ObjectStatus(status.Byte)
|
||||
deleted.StreamID = streamID.UUID
|
||||
deleted.CreatedAt = createdAt.Time
|
||||
deleted.SegmentCount = segmentCount.Int32
|
||||
|
||||
if err != nil {
|
||||
return deleteObjectUnversionedCommittedResult{}, Error.Wrap(err)
|
||||
}
|
||||
deleted.TotalPlainSize = totalPlainSize.Int64
|
||||
deleted.TotalEncryptedSize = totalEncryptedSize.Int64
|
||||
deleted.FixedSegmentSize = fixedSegmentSize.Int32
|
||||
|
||||
// TODO: this should happen outside of this func
|
||||
mon.Meter("object_delete").Mark(result.DeletedObjectCount)
|
||||
|
@ -4,6 +4,7 @@
|
||||
package metabase_test
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -1607,9 +1608,138 @@ func TestGetLatestObjectLastSegment(t *testing.T) {
|
||||
}.Check(ctx, t, db)
|
||||
})
|
||||
|
||||
// TODO(ver): add test for committed versioned
|
||||
// TODO(ver): add test for delete marker versioned
|
||||
// TODO(ver): add test for delete marker unversioned
|
||||
t.Run("versioned", func(t *testing.T) {
|
||||
defer metabasetest.DeleteAll{}.Check(ctx, t, db)
|
||||
|
||||
object := metabasetest.CreateObjectVersioned(ctx, t, db, obj, 2)
|
||||
|
||||
segments, err := db.TestingAllSegments(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, segments, 2)
|
||||
|
||||
metabasetest.GetLatestObjectLastSegment{
|
||||
Opts: metabase.GetLatestObjectLastSegment{
|
||||
ObjectLocation: location,
|
||||
},
|
||||
Result: segments[1],
|
||||
}.Check(ctx, t, db)
|
||||
|
||||
metabasetest.Verify{
|
||||
Objects: []metabase.RawObject{
|
||||
metabase.RawObject(object),
|
||||
},
|
||||
Segments: metabasetest.SegmentsToRaw(segments),
|
||||
}.Check(ctx, t, db)
|
||||
})
|
||||
|
||||
t.Run("versioned delete marker", func(t *testing.T) {
|
||||
defer metabasetest.DeleteAll{}.Check(ctx, t, db)
|
||||
|
||||
object := metabasetest.CreateObjectVersioned(ctx, t, db, obj, 2)
|
||||
|
||||
segments, err := db.TestingAllSegments(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, segments, 2)
|
||||
|
||||
markerLocation := obj
|
||||
markerLocation.StreamID = uuid.UUID{}
|
||||
markerLocation.Version = object.Version + 1
|
||||
marker := metabase.Object{
|
||||
ObjectStream: markerLocation,
|
||||
CreatedAt: time.Now(),
|
||||
Status: metabase.DeleteMarkerVersioned,
|
||||
}
|
||||
|
||||
// this creates a versioned delete marker
|
||||
metabasetest.DeleteObjectLastCommitted{
|
||||
Opts: metabase.DeleteObjectLastCommitted{
|
||||
ObjectLocation: location,
|
||||
Versioned: true,
|
||||
},
|
||||
Result: metabase.DeleteObjectResult{
|
||||
Markers: []metabase.Object{marker},
|
||||
},
|
||||
}.Check(ctx, t, db)
|
||||
|
||||
metabasetest.GetLatestObjectLastSegment{
|
||||
Opts: metabase.GetLatestObjectLastSegment{
|
||||
ObjectLocation: location,
|
||||
},
|
||||
ErrClass: &metabase.ErrObjectNotFound,
|
||||
ErrText: "metabase: object or segment missing",
|
||||
}.Check(ctx, t, db)
|
||||
|
||||
metabasetest.Verify{
|
||||
Objects: []metabase.RawObject{
|
||||
metabase.RawObject(object),
|
||||
metabase.RawObject(marker),
|
||||
},
|
||||
Segments: metabasetest.SegmentsToRaw(segments),
|
||||
}.Check(ctx, t, db)
|
||||
})
|
||||
t.Run("unversioned delete marker", func(t *testing.T) {
|
||||
defer metabasetest.DeleteAll{}.Check(ctx, t, db)
|
||||
|
||||
unversioned := metabasetest.CreateObject(ctx, t, db, obj, 2)
|
||||
versionedobj := obj
|
||||
versionedobj.Version++
|
||||
versionedobj.StreamID = testrand.UUID()
|
||||
versioned := metabasetest.CreateObjectVersioned(ctx, t, db, versionedobj, 2)
|
||||
|
||||
segments, err := db.TestingAllSegments(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, segments, 4)
|
||||
|
||||
metabasetest.Verify{
|
||||
Objects: []metabase.RawObject{
|
||||
metabase.RawObject(unversioned),
|
||||
metabase.RawObject(versioned),
|
||||
},
|
||||
Segments: metabasetest.SegmentsToRaw(segments),
|
||||
}.Check(ctx, t, db)
|
||||
|
||||
markerLocation := obj
|
||||
markerLocation.StreamID = uuid.UUID{}
|
||||
markerLocation.Version = unversioned.Version + 2
|
||||
marker := metabase.Object{
|
||||
ObjectStream: markerLocation,
|
||||
CreatedAt: time.Now(),
|
||||
Status: metabase.DeleteMarkerUnversioned,
|
||||
}
|
||||
|
||||
// this creates a versioned delete marker
|
||||
metabasetest.DeleteObjectLastCommitted{
|
||||
Opts: metabase.DeleteObjectLastCommitted{
|
||||
ObjectLocation: location,
|
||||
Versioned: false,
|
||||
Suspended: true,
|
||||
},
|
||||
Result: metabase.DeleteObjectResult{
|
||||
Markers: []metabase.Object{marker},
|
||||
Removed: []metabase.Object{unversioned},
|
||||
},
|
||||
}.Check(ctx, t, db)
|
||||
|
||||
metabasetest.GetLatestObjectLastSegment{
|
||||
Opts: metabase.GetLatestObjectLastSegment{
|
||||
ObjectLocation: location,
|
||||
},
|
||||
ErrClass: &metabase.ErrObjectNotFound,
|
||||
ErrText: "metabase: object or segment missing",
|
||||
}.Check(ctx, t, db)
|
||||
|
||||
segments = slices.DeleteFunc(segments, func(seg metabase.Segment) bool {
|
||||
return seg.StreamID == unversioned.StreamID
|
||||
})
|
||||
|
||||
metabasetest.Verify{
|
||||
Objects: []metabase.RawObject{
|
||||
metabase.RawObject(versioned),
|
||||
metabase.RawObject(marker),
|
||||
},
|
||||
Segments: metabasetest.SegmentsToRaw(segments),
|
||||
}.Check(ctx, t, db)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user