storj/satellite/metabase/common_test.go
Egon Elbre 267506bb20 satellite/metabase: move package one level higher
metabase has become a central concept and it's more suitable for it to
be directly nested under satellite rather than being part of metainfo.

metainfo is going to be the "endpoint" logic for handling requests.

Change-Id: I53770d6761ac1e9a1283b5aa68f471b21e784198
2021-04-21 15:54:22 +03:00

277 lines
7.1 KiB
Go

// Copyright (C) 2020 Storj Labs, Inc.
// See LICENSE for copying information.
package metabase_test
import (
"strconv"
"testing"
"github.com/stretchr/testify/require"
"storj.io/common/testrand"
"storj.io/common/uuid"
"storj.io/storj/satellite/metabase"
)
func TestParseBucketPrefixInvalid(t *testing.T) {
var testCases = []struct {
name string
prefix metabase.BucketPrefix
}{
{"invalid, not valid UUID", "not UUID string/bucket1"},
{"invalid, not valid UUID, no bucket", "not UUID string"},
{"invalid, no project, no bucket", ""},
}
for _, tt := range testCases {
tt := tt
t.Run(tt.name, func(t *testing.T) {
_, err := metabase.ParseBucketPrefix(tt.prefix)
require.NotNil(t, err)
require.Error(t, err)
})
}
}
func TestParseBucketPrefixValid(t *testing.T) {
var testCases = []struct {
name string
project string
bucketName string
expectedBucketName string
}{
{"valid, no bucket, no objects", "bb6218e3-4b4a-4819-abbb-fa68538e33c0", "", ""},
{"valid, with bucket", "bb6218e3-4b4a-4819-abbb-fa68538e33c0", "testbucket", "testbucket"},
}
for _, tt := range testCases {
tt := tt
t.Run(tt.name, func(t *testing.T) {
expectedProjectID, err := uuid.FromString(tt.project)
require.NoError(t, err)
bucketID := expectedProjectID.String() + "/" + tt.bucketName
bucketLocation, err := metabase.ParseBucketPrefix(metabase.BucketPrefix(bucketID))
require.NoError(t, err)
require.Equal(t, expectedProjectID, bucketLocation.ProjectID)
require.Equal(t, tt.expectedBucketName, bucketLocation.BucketName)
})
}
}
func TestParseSegmentKeyInvalid(t *testing.T) {
var testCases = []struct {
name string
segmentKey string
}{
{
name: "invalid, project ID only",
segmentKey: "bb6218e3-4b4a-4819-abbb-fa68538e33c0",
},
{
name: "invalid, project ID and segment index only",
segmentKey: "bb6218e3-4b4a-4819-abbb-fa68538e33c0/s0",
},
{
name: "invalid, project ID, bucket, and segment index only",
segmentKey: "bb6218e3-4b4a-4819-abbb-fa68538e33c0/s0/testbucket",
},
{
name: "invalid, project ID is not UUID",
segmentKey: "not UUID string/s0/testbucket/test/object",
},
{
name: "invalid, last segment with segment number",
segmentKey: "bb6218e3-4b4a-4819-abbb-fa68538e33c0/l0/testbucket/test/object",
},
{
name: "invalid, missing segment number",
segmentKey: "bb6218e3-4b4a-4819-abbb-fa68538e33c0/s/testbucket/test/object",
},
{
name: "invalid, missing segment prefix",
segmentKey: "bb6218e3-4b4a-4819-abbb-fa68538e33c0/1/testbucket/test/object",
},
{
name: "invalid, segment index overflows int64",
segmentKey: "bb6218e3-4b4a-4819-abbb-fa68538e33c0/s18446744073709551616/testbucket/test/object",
},
}
for _, tt := range testCases {
tt := tt
t.Run(tt.name, func(t *testing.T) {
_, err := metabase.ParseSegmentKey(metabase.SegmentKey(tt.segmentKey))
require.NotNil(t, err, tt.name)
require.Error(t, err, tt.name)
})
}
}
func TestParseSegmentKeyValid(t *testing.T) {
projectID := testrand.UUID()
var testCases = []struct {
name string
segmentKey string
expectedLocation metabase.SegmentLocation
}{
{
name: "valid, part 0, last segment",
segmentKey: projectID.String() + "/l/testbucket/test/object",
expectedLocation: metabase.SegmentLocation{
ProjectID: projectID,
BucketName: "testbucket",
ObjectKey: "test/object",
Position: metabase.SegmentPosition{Part: 0, Index: metabase.LastSegmentIndex},
},
},
{
name: "valid, part 0, last segment, trailing slash",
segmentKey: projectID.String() + "/l/testbucket/test/object/",
expectedLocation: metabase.SegmentLocation{
ProjectID: projectID,
BucketName: "testbucket",
ObjectKey: "test/object/",
Position: metabase.SegmentPosition{Part: 0, Index: metabase.LastSegmentIndex},
},
},
{
name: "valid, part 0, index 0",
segmentKey: projectID.String() + "/s0/testbucket/test/object",
expectedLocation: metabase.SegmentLocation{
ProjectID: projectID,
BucketName: "testbucket",
ObjectKey: "test/object",
Position: metabase.SegmentPosition{Part: 0, Index: 0},
},
},
{
name: "valid, part 0, index 1",
segmentKey: projectID.String() + "/s1/testbucket/test/object",
expectedLocation: metabase.SegmentLocation{
ProjectID: projectID,
BucketName: "testbucket",
ObjectKey: "test/object",
Position: metabase.SegmentPosition{Part: 0, Index: 1},
},
},
{
name: "valid, part 0, index 315",
segmentKey: projectID.String() + "/s315/testbucket/test/object",
expectedLocation: metabase.SegmentLocation{
ProjectID: projectID,
BucketName: "testbucket",
ObjectKey: "test/object",
Position: metabase.SegmentPosition{Part: 0, Index: 315},
},
},
{
name: "valid, part 1, index 0",
segmentKey: projectID.String() + "/s" + strconv.FormatInt(1<<32, 10) + "/testbucket/test/object",
expectedLocation: metabase.SegmentLocation{
ProjectID: projectID,
BucketName: "testbucket",
ObjectKey: "test/object",
Position: metabase.SegmentPosition{Part: 1, Index: 0},
},
},
{
name: "valid, part 1, index 1",
segmentKey: projectID.String() + "/s" + strconv.FormatInt(1<<32+1, 10) + "/testbucket/test/object",
expectedLocation: metabase.SegmentLocation{
ProjectID: projectID,
BucketName: "testbucket",
ObjectKey: "test/object",
Position: metabase.SegmentPosition{Part: 1, Index: 1},
},
},
{
name: "valid, part 18, index 315",
segmentKey: projectID.String() + "/s" + strconv.FormatInt(18<<32+315, 10) + "/testbucket/test/object",
expectedLocation: metabase.SegmentLocation{
ProjectID: projectID,
BucketName: "testbucket",
ObjectKey: "test/object",
Position: metabase.SegmentPosition{Part: 18, Index: 315},
},
},
}
for _, tt := range testCases {
tt := tt
t.Run(tt.name, func(t *testing.T) {
segmentLocation, err := metabase.ParseSegmentKey(metabase.SegmentKey(tt.segmentKey))
require.NoError(t, err, tt.name)
require.Equal(t, tt.expectedLocation, segmentLocation)
})
}
}
func TestPiecesEqual(t *testing.T) {
sn1 := testrand.NodeID()
sn2 := testrand.NodeID()
var testCases = []struct {
source metabase.Pieces
target metabase.Pieces
equal bool
}{
{metabase.Pieces{}, metabase.Pieces{}, true},
{
metabase.Pieces{
{1, sn1},
},
metabase.Pieces{}, false,
},
{
metabase.Pieces{},
metabase.Pieces{
{1, sn1},
}, false,
},
{
metabase.Pieces{
{1, sn1},
{2, sn2},
},
metabase.Pieces{
{1, sn1},
{2, sn2},
}, true,
},
{
metabase.Pieces{
{2, sn2},
{1, sn1},
},
metabase.Pieces{
{1, sn1},
{2, sn2},
}, true,
},
{
metabase.Pieces{
{1, sn1},
{2, sn2},
},
metabase.Pieces{
{1, sn2},
{2, sn1},
}, false,
},
{
metabase.Pieces{
{1, sn1},
{3, sn2},
{2, sn2},
},
metabase.Pieces{
{3, sn2},
{1, sn1},
{2, sn2},
}, true,
},
}
for _, tt := range testCases {
require.Equal(t, tt.equal, tt.source.Equal(tt.target))
}
}