storj/satellite/metainfo/metabase/loop_test.go
Michał Niewrzał 8e97111513 satellite/metainfo/metabase: reduce fields number for LoopObjectEntry
We want to read from DB only those fields that are used by metainfo loop so we need to remove most of fields from LoopObjectEntry.

Change-Id: I14ecae288f631dc0ff54f4c560ce43b736eccdcf
2021-03-02 12:21:19 +00:00

260 lines
6.6 KiB
Go

// Copyright (C) 2021 Storj Labs, Inc.
// See LICENSE for copying information.
package metabase_test
import (
"strings"
"testing"
"storj.io/common/testcontext"
"storj.io/common/testrand"
"storj.io/common/uuid"
"storj.io/storj/satellite/metainfo/metabase"
)
func TestIterateLoopObjects(t *testing.T) {
All(t, func(ctx *testcontext.Context, t *testing.T, db *metabase.DB) {
t.Run("Limit is negative", func(t *testing.T) {
defer DeleteAll{}.Check(ctx, t, db)
IterateLoopObjects{
Opts: metabase.IterateLoopObjects{
BatchSize: -1,
},
ErrClass: &metabase.ErrInvalidRequest,
ErrText: "BatchSize is negative",
}.Check(ctx, t, db)
Verify{}.Check(ctx, t, db)
})
t.Run("no data", func(t *testing.T) {
defer DeleteAll{}.Check(ctx, t, db)
IterateLoopObjects{
Opts: metabase.IterateLoopObjects{
BatchSize: 0,
},
Result: nil,
}.Check(ctx, t, db)
IterateLoopObjects{
Opts: metabase.IterateLoopObjects{
BatchSize: 10,
},
Result: nil,
}.Check(ctx, t, db)
Verify{}.Check(ctx, t, db)
})
t.Run("pending and committed", func(t *testing.T) {
defer DeleteAll{}.Check(ctx, t, db)
pending := randObjectStream()
committed := randObjectStream()
committed.ProjectID = pending.ProjectID
committed.BucketName = pending.BucketName + "z"
BeginObjectExactVersion{
Opts: metabase.BeginObjectExactVersion{
ObjectStream: pending,
Encryption: defaultTestEncryption,
},
Version: 1,
}.Check(ctx, t, db)
encryptedMetadata := testrand.Bytes(1024)
encryptedMetadataNonce := testrand.Nonce()
encryptedMetadataKey := testrand.Bytes(265)
BeginObjectExactVersion{
Opts: metabase.BeginObjectExactVersion{
ObjectStream: committed,
Encryption: defaultTestEncryption,
},
Version: 1,
}.Check(ctx, t, db)
CommitObject{
Opts: metabase.CommitObject{
ObjectStream: committed,
EncryptedMetadataNonce: encryptedMetadataNonce[:],
EncryptedMetadata: encryptedMetadata,
EncryptedMetadataEncryptedKey: encryptedMetadataKey,
},
}.Check(ctx, t, db)
IterateLoopObjects{
Opts: metabase.IterateLoopObjects{
BatchSize: 1,
},
Result: []metabase.LoopObjectEntry{
{
ObjectStream: pending,
},
{
ObjectStream: committed,
EncryptedMetadataSize: len(encryptedMetadata),
},
},
}.Check(ctx, t, db)
})
t.Run("less objects than limit", func(t *testing.T) {
defer DeleteAll{}.Check(ctx, t, db)
numberOfObjects := 3
limit := 10
expected := make([]metabase.LoopObjectEntry, numberOfObjects)
objects := createObjects(ctx, t, db, numberOfObjects, uuid.UUID{1}, "mybucket")
for i, obj := range objects {
expected[i] = loopObjectEntryFromRaw(obj)
}
IterateLoopObjects{
Opts: metabase.IterateLoopObjects{
BatchSize: limit,
},
Result: expected,
}.Check(ctx, t, db)
Verify{Objects: objects}.Check(ctx, t, db)
})
t.Run("more objects than limit", func(t *testing.T) {
defer DeleteAll{}.Check(ctx, t, db)
numberOfObjects := 10
limit := 3
expected := make([]metabase.LoopObjectEntry, numberOfObjects)
objects := createObjects(ctx, t, db, numberOfObjects, uuid.UUID{1}, "mybucket")
for i, obj := range objects {
expected[i] = loopObjectEntryFromRaw(obj)
}
IterateLoopObjects{
Opts: metabase.IterateLoopObjects{
BatchSize: limit,
},
Result: expected,
}.Check(ctx, t, db)
Verify{Objects: objects}.Check(ctx, t, db)
})
t.Run("recursive", func(t *testing.T) {
defer DeleteAll{}.Check(ctx, t, db)
projectID, bucketName := uuid.UUID{1}, "bucky"
objects := createFullObjectsWithKeys(ctx, t, db, projectID, bucketName, []metabase.ObjectKey{
"a",
"b/1",
"b/2",
"b/3",
"c",
"c/",
"c//",
"c/1",
"g",
})
IterateLoopObjects{
Opts: metabase.IterateLoopObjects{
BatchSize: 3,
},
Result: []metabase.LoopObjectEntry{
objects["a"],
objects["b/1"],
objects["b/2"],
objects["b/3"],
objects["c"],
objects["c/"],
objects["c//"],
objects["c/1"],
objects["g"],
},
}.Check(ctx, t, db)
})
t.Run("multiple projects", func(t *testing.T) {
defer DeleteAll{}.Check(ctx, t, db)
projects := []uuid.UUID{}
for i := 0; i < 10; i++ {
p := testrand.UUID()
p[0] = byte(i)
projects = append(projects, p)
}
bucketNames := strings.Split("abcde", "")
expected := make([]metabase.LoopObjectEntry, 0, len(projects)*len(bucketNames))
for _, projectID := range projects {
for _, bucketName := range bucketNames {
rawObjects := createObjects(ctx, t, db, 1, projectID, bucketName)
for _, obj := range rawObjects {
expected = append(expected, loopObjectEntryFromRaw(obj))
}
}
}
IterateLoopObjects{
Opts: metabase.IterateLoopObjects{
BatchSize: 3,
},
Result: expected,
}.Check(ctx, t, db)
})
t.Run("multiple projects", func(t *testing.T) {
defer DeleteAll{}.Check(ctx, t, db)
projects := []uuid.UUID{}
for i := 0; i < 10; i++ {
p := testrand.UUID()
p[0] = byte(i)
projects = append(projects, p)
}
bucketNames := strings.Split("abcde", "")
expected := make([]metabase.LoopObjectEntry, 0, len(projects)*len(bucketNames))
for _, projectID := range projects {
for _, bucketName := range bucketNames {
obj := randObjectStream()
obj.ProjectID = projectID
obj.BucketName = bucketName
for version := 1; version < 4; version++ {
obj.Version = metabase.Version(version)
rawObject := createObject(ctx, t, db, obj, 0)
expected = append(expected, loopObjectEntryFromRaw(metabase.RawObject(rawObject)))
}
}
}
IterateLoopObjects{
Opts: metabase.IterateLoopObjects{
BatchSize: 2,
},
Result: expected,
}.Check(ctx, t, db)
})
})
}
func createFullObjectsWithKeys(ctx *testcontext.Context, t *testing.T, db *metabase.DB, projectID uuid.UUID, bucketName string, keys []metabase.ObjectKey) map[metabase.ObjectKey]metabase.LoopObjectEntry {
objects := make(map[metabase.ObjectKey]metabase.LoopObjectEntry, len(keys))
for _, key := range keys {
obj := randObjectStream()
obj.ProjectID = projectID
obj.BucketName = bucketName
obj.ObjectKey = key
createObject(ctx, t, db, obj, 0)
objects[key] = metabase.LoopObjectEntry{
ObjectStream: obj,
}
}
return objects
}
func loopObjectEntryFromRaw(m metabase.RawObject) metabase.LoopObjectEntry {
return metabase.LoopObjectEntry{
ObjectStream: m.ObjectStream,
ExpiresAt: m.ExpiresAt,
SegmentCount: m.SegmentCount,
}
}