storj/satellite/metainfo/db_test.go
Michał Niewrzał 4a146000cc satellite/metainfo: read from DB only needed columns fro bucket
Uplink needs only part of columns we are reading from DB.
To improve performance we should read only those that are
realy needed.

Change-Id: Ib39259318169c46afe5fa4c6ce2184da82e960c8
2021-10-19 11:53:42 +00:00

220 lines
7.1 KiB
Go

// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
package metainfo_test
import (
"testing"
"github.com/stretchr/testify/require"
"storj.io/common/macaroon"
"storj.io/common/storj"
"storj.io/common/testcontext"
"storj.io/common/testrand"
"storj.io/common/uuid"
"storj.io/storj/satellite"
"storj.io/storj/satellite/console"
"storj.io/storj/satellite/satellitedb/satellitedbtest"
)
func newTestBucket(name string, projectID uuid.UUID) storj.Bucket {
return storj.Bucket{
ID: testrand.UUID(),
Name: name,
ProjectID: projectID,
PathCipher: storj.EncAESGCM,
DefaultSegmentsSize: 65536,
DefaultRedundancyScheme: storj.RedundancyScheme{
Algorithm: storj.ReedSolomon,
ShareSize: 9,
RequiredShares: 10,
RepairShares: 11,
OptimalShares: 12,
TotalShares: 13,
},
DefaultEncryptionParameters: storj.EncryptionParameters{
CipherSuite: storj.EncAESGCM,
BlockSize: 9 * 10,
},
}
}
func TestBasicBucketOperations(t *testing.T) {
satellitedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db satellite.DB) {
consoleDB := db.Console()
project, err := consoleDB.Projects().Insert(ctx, &console.Project{Name: "testproject1"})
require.NoError(t, err)
bucketsDB := db.Buckets()
expectedBucket := newTestBucket("testbucket", project.ID)
count, err := bucketsDB.CountBuckets(ctx, project.ID)
require.NoError(t, err)
require.Equal(t, 0, count)
// CreateBucket
_, err = bucketsDB.CreateBucket(ctx, expectedBucket)
require.NoError(t, err)
// GetBucket
bucket, err := bucketsDB.GetBucket(ctx, []byte("testbucket"), project.ID)
require.NoError(t, err)
require.Equal(t, expectedBucket.ID, bucket.ID)
require.Equal(t, expectedBucket.Name, bucket.Name)
require.Equal(t, expectedBucket.ProjectID, bucket.ProjectID)
require.Equal(t, expectedBucket.PathCipher, bucket.PathCipher)
require.Equal(t, expectedBucket.DefaultSegmentsSize, bucket.DefaultSegmentsSize)
require.Equal(t, expectedBucket.DefaultRedundancyScheme, bucket.DefaultRedundancyScheme)
require.Equal(t, expectedBucket.DefaultEncryptionParameters, bucket.DefaultEncryptionParameters)
// GetMinimalBucket
minimalBucket, err := bucketsDB.GetMinimalBucket(ctx, []byte("testbucket"), project.ID)
require.NoError(t, err)
require.Equal(t, []byte("testbucket"), minimalBucket.Name)
require.False(t, minimalBucket.CreatedAt.IsZero())
_, err = bucketsDB.GetMinimalBucket(ctx, []byte("not-existing-bucket"), project.ID)
require.True(t, storj.ErrBucketNotFound.Has(err))
// CountBuckets
count, err = bucketsDB.CountBuckets(ctx, project.ID)
require.NoError(t, err)
require.Equal(t, 1, count)
_, err = bucketsDB.CreateBucket(ctx, newTestBucket("testbucket2", project.ID))
require.NoError(t, err)
count, err = bucketsDB.CountBuckets(ctx, project.ID)
require.NoError(t, err)
require.Equal(t, 2, count)
// DeleteBucket
err = bucketsDB.DeleteBucket(ctx, []byte("testbucket"), project.ID)
require.NoError(t, err)
})
}
func TestListBucketsAllAllowed(t *testing.T) {
testCases := []struct {
name string
cursor string
limit int
expectedItems int
expectedMore bool
}{
{"empty string cursor", "", 10, 10, false},
{"last bucket cursor", "zzz", 2, 1, false},
{"non matching cursor", "ccc", 10, 5, false},
{"first bucket cursor", "0test", 10, 10, false},
{"empty string cursor, more", "", 5, 5, true},
{"non matching cursor, more", "ccc", 3, 3, true},
{"first bucket cursor, more", "0test", 5, 5, true},
}
satellitedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db satellite.DB) {
consoleDB := db.Console()
project, err := consoleDB.Projects().Insert(ctx, &console.Project{Name: "testproject1"})
require.NoError(t, err)
bucketsDB := db.Buckets()
allowedBuckets := macaroon.AllowedBuckets{
Buckets: map[string]struct{}{},
}
{ // setup some test buckets
var testBucketNames = []string{"aaa", "bbb", "mmm", "qqq", "zzz",
"test.bucket", "123", "0test", "999", "test-bucket.thing",
}
for _, bucket := range testBucketNames {
testBucket := newTestBucket(bucket, project.ID)
_, err := bucketsDB.CreateBucket(ctx, testBucket)
allowedBuckets.Buckets[bucket] = struct{}{}
if err != nil {
require.NoError(t, err)
}
}
}
for _, tt := range testCases {
tt := tt // avoid scopelint error
t.Run(tt.name, func(t *testing.T) {
listOpts := storj.BucketListOptions{
Cursor: tt.cursor,
Direction: storj.Forward,
Limit: tt.limit,
}
bucketList, err := bucketsDB.ListBuckets(ctx, project.ID, listOpts, allowedBuckets)
require.NoError(t, err)
require.Equal(t, tt.expectedItems, len(bucketList.Items))
require.Equal(t, tt.expectedMore, bucketList.More)
})
}
})
}
func TestListBucketsNotAllowed(t *testing.T) {
testCases := []struct {
name string
cursor string
limit int
expectedItems int
expectedMore bool
allowAll bool
allowedBuckets map[string]struct{}
expectedNames []string
}{
{"empty string cursor, 2 allowed", "", 10, 1, false, false, map[string]struct{}{"aaa": {}, "ddd": {}}, []string{"aaa"}},
{"empty string cursor, more", "", 2, 2, true, false, map[string]struct{}{"aaa": {}, "bbb": {}, "zzz": {}}, []string{"aaa", "bbb"}},
{"empty string cursor, 3 allowed", "", 4, 3, false, false, map[string]struct{}{"aaa": {}, "bbb": {}, "zzz": {}}, []string{"aaa", "bbb", "zzz"}},
{"last bucket cursor", "zzz", 2, 1, false, false, map[string]struct{}{"zzz": {}}, []string{"zzz"}},
{"last bucket cursor, allow all", "zzz", 2, 1, false, true, map[string]struct{}{"zzz": {}}, []string{"zzz"}},
{"empty string cursor, allow all, more", "", 5, 5, true, true, map[string]struct{}{"": {}}, []string{"123", "0test", "999", "aaa", "bbb"}},
}
satellitedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db satellite.DB) {
consoleDB := db.Console()
project, err := consoleDB.Projects().Insert(ctx, &console.Project{Name: "testproject1"})
require.NoError(t, err)
bucketsDB := db.Buckets()
{ // setup some test buckets
var testBucketNames = []string{"aaa", "bbb", "mmm", "qqq", "zzz",
"test.bucket", "123", "0test", "999", "test-bucket.thing",
}
for _, bucket := range testBucketNames {
testBucket := newTestBucket(bucket, project.ID)
_, err := bucketsDB.CreateBucket(ctx, testBucket)
if err != nil {
require.NoError(t, err)
}
}
}
for _, tt := range testCases {
tt := tt // avoid scopelint error
listOpts := storj.BucketListOptions{
Cursor: tt.cursor,
Direction: storj.Forward,
Limit: tt.limit,
}
t.Run(tt.name, func(t *testing.T) {
allowed := macaroon.AllowedBuckets{
Buckets: tt.allowedBuckets,
All: tt.allowAll,
}
bucketList, err := bucketsDB.ListBuckets(ctx,
project.ID,
listOpts,
allowed,
)
require.NoError(t, err)
require.Equal(t, tt.expectedItems, len(bucketList.Items))
require.Equal(t, tt.expectedMore, bucketList.More)
for _, actualItem := range bucketList.Items {
require.Contains(t, tt.expectedNames, actualItem.Name)
}
})
}
})
}