2a0c4e60d2
* preparing for use of `customtype` gogo extension with `NodeID` type * review changes * preparing for use of `customtype` gogo extension with `NodeID` type * review changes * wip * tests passing * wip fixing tests * more wip test fixing * remove NodeIDList from proto files * linter fixes * linter fixes * linter/review fixes * more freaking linter fixes * omg just kill me - linterrrrrrrr * travis linter, i will muder you and your family in your sleep * goimports everything - burn in hell travis * goimports update * go mod tidy
297 lines
7.6 KiB
Go
297 lines
7.6 KiB
Go
// Copyright (C) 2018 Storj Labs, Inc.
|
|
// See LICENSE for copying information.
|
|
|
|
package pdbclient
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/gogo/protobuf/proto"
|
|
"github.com/golang/mock/gomock"
|
|
"github.com/golang/protobuf/ptypes"
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"storj.io/storj/internal/teststorj"
|
|
|
|
"storj.io/storj/pkg/auth"
|
|
"storj.io/storj/pkg/pb"
|
|
"storj.io/storj/pkg/storage/meta"
|
|
"storj.io/storj/pkg/storj"
|
|
)
|
|
|
|
const (
|
|
unauthenticated = "failed API creds"
|
|
noPathGiven = "file path not given"
|
|
)
|
|
|
|
var (
|
|
ErrUnauthenticated = errors.New(unauthenticated)
|
|
ErrNoFileGiven = errors.New(noPathGiven)
|
|
)
|
|
|
|
func TestNewPointerDBClient(t *testing.T) {
|
|
// mocked grpcClient so we don't have
|
|
// to call the network to test the code
|
|
ctrl := gomock.NewController(t)
|
|
defer ctrl.Finish()
|
|
|
|
gc := NewMockPointerDBClient(ctrl)
|
|
pdb := PointerDB{client: gc}
|
|
|
|
assert.NotNil(t, pdb)
|
|
assert.NotNil(t, pdb.client)
|
|
}
|
|
|
|
func makePointer(path storj.Path) pb.PutRequest {
|
|
// rps is an example slice of RemotePieces to add to this
|
|
// REMOTE pointer type.
|
|
var rps []*pb.RemotePiece
|
|
rps = append(rps, &pb.RemotePiece{
|
|
PieceNum: 1,
|
|
NodeId: teststorj.NodeIDFromString("testId"),
|
|
})
|
|
pr := pb.PutRequest{
|
|
Path: path,
|
|
Pointer: &pb.Pointer{
|
|
Type: pb.Pointer_REMOTE,
|
|
Remote: &pb.RemoteSegment{
|
|
Redundancy: &pb.RedundancyScheme{
|
|
Type: pb.RedundancyScheme_RS,
|
|
MinReq: 1,
|
|
Total: 3,
|
|
RepairThreshold: 2,
|
|
SuccessThreshold: 3,
|
|
},
|
|
PieceId: "testId",
|
|
RemotePieces: rps,
|
|
},
|
|
SegmentSize: int64(1),
|
|
},
|
|
}
|
|
return pr
|
|
}
|
|
|
|
func TestPut(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
defer ctrl.Finish()
|
|
|
|
for i, tt := range []struct {
|
|
APIKey []byte
|
|
path storj.Path
|
|
err error
|
|
errString string
|
|
}{
|
|
{[]byte("abc123"), "file1/file2", nil, ""},
|
|
{[]byte("wrong key"), "file1/file2", ErrUnauthenticated, unauthenticated},
|
|
{[]byte("abc123"), "", ErrNoFileGiven, noPathGiven},
|
|
{[]byte("wrong key"), "", ErrUnauthenticated, unauthenticated},
|
|
{[]byte(""), "", ErrUnauthenticated, unauthenticated},
|
|
} {
|
|
ctx := context.Background()
|
|
ctx = auth.WithAPIKey(ctx, tt.APIKey)
|
|
|
|
putRequest := makePointer(tt.path)
|
|
|
|
errTag := fmt.Sprintf("Test case #%d", i)
|
|
gc := NewMockPointerDBClient(ctrl)
|
|
pdb := PointerDB{client: gc}
|
|
|
|
// here we don't care what type of context we pass
|
|
gc.EXPECT().Put(gomock.Any(), &putRequest).Return(nil, tt.err)
|
|
|
|
err := pdb.Put(ctx, tt.path, putRequest.Pointer)
|
|
|
|
if err != nil {
|
|
assert.EqualError(t, err, tt.errString, errTag)
|
|
} else {
|
|
assert.NoError(t, err, errTag)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGet(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
defer ctrl.Finish()
|
|
|
|
for i, tt := range []struct {
|
|
APIKey []byte
|
|
path storj.Path
|
|
err error
|
|
errString string
|
|
}{
|
|
{[]byte("wrong key"), "file1/file2", ErrUnauthenticated, unauthenticated},
|
|
{[]byte("abc123"), "", ErrNoFileGiven, noPathGiven},
|
|
{[]byte("wrong key"), "", ErrUnauthenticated, unauthenticated},
|
|
{[]byte(""), "", ErrUnauthenticated, unauthenticated},
|
|
{[]byte("abc123"), "file1/file2", nil, ""},
|
|
} {
|
|
ctx := context.Background()
|
|
ctx = auth.WithAPIKey(ctx, tt.APIKey)
|
|
|
|
getPointer := makePointer(tt.path)
|
|
getRequest := pb.GetRequest{Path: tt.path}
|
|
|
|
data, err := proto.Marshal(getPointer.Pointer)
|
|
if err != nil {
|
|
log.Fatal("marshaling error: ", err)
|
|
}
|
|
|
|
byteData := data
|
|
ptr := &pb.Pointer{}
|
|
err = proto.Unmarshal(byteData, ptr)
|
|
assert.NoError(t, err)
|
|
|
|
getResponse := pb.GetResponse{Pointer: ptr, Nodes: []*pb.Node{}, Pba: &pb.PayerBandwidthAllocation{}}
|
|
|
|
errTag := fmt.Sprintf("Test case #%d", i)
|
|
|
|
gc := NewMockPointerDBClient(ctrl)
|
|
pdb := PointerDB{client: gc}
|
|
|
|
gc.EXPECT().Get(gomock.Any(), &getRequest).Return(&getResponse, tt.err)
|
|
|
|
pointer, nodes, pba, err := pdb.Get(ctx, tt.path)
|
|
|
|
if err != nil {
|
|
assert.True(t, strings.Contains(err.Error(), tt.errString), errTag)
|
|
assert.Nil(t, pointer)
|
|
assert.Nil(t, nodes)
|
|
assert.Nil(t, pba)
|
|
} else {
|
|
assert.NotNil(t, pointer)
|
|
assert.NotNil(t, nodes)
|
|
assert.NotNil(t, pba)
|
|
assert.NoError(t, err, errTag)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestList(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
defer ctrl.Finish()
|
|
|
|
for i, tt := range []struct {
|
|
prefix string
|
|
startAfter string
|
|
endBefore string
|
|
recursive bool
|
|
limit int
|
|
metaFlags uint32
|
|
APIKey string
|
|
items []*pb.ListResponse_Item
|
|
more bool
|
|
err error
|
|
errString string
|
|
}{
|
|
{"", "", "", false, 0, meta.None, "",
|
|
[]*pb.ListResponse_Item{}, false, nil, ""},
|
|
{"", "", "", false, 0, meta.None, "",
|
|
[]*pb.ListResponse_Item{{}}, false, nil, ""},
|
|
{"", "", "", false, -1, meta.None, "",
|
|
[]*pb.ListResponse_Item{}, false, ErrUnauthenticated, unauthenticated},
|
|
{"prefix", "after", "before", false, 1, meta.None, "some key",
|
|
[]*pb.ListResponse_Item{
|
|
{Path: "a/b/c"},
|
|
},
|
|
true, nil, ""},
|
|
{"prefix", "after", "before", false, 1, meta.All, "some key",
|
|
[]*pb.ListResponse_Item{
|
|
{Path: "a/b/c", Pointer: &pb.Pointer{
|
|
SegmentSize: 1234,
|
|
CreationDate: ptypes.TimestampNow(),
|
|
ExpirationDate: ptypes.TimestampNow(),
|
|
}},
|
|
},
|
|
true, nil, ""},
|
|
{"some/prefix", "start/after", "end/before", true, 123, meta.Size, "some key",
|
|
[]*pb.ListResponse_Item{
|
|
{Path: "a/b/c", Pointer: &pb.Pointer{SegmentSize: 1234}},
|
|
{Path: "x/y", Pointer: &pb.Pointer{SegmentSize: 789}},
|
|
},
|
|
true, nil, ""},
|
|
} {
|
|
ctx := context.Background()
|
|
ctx = auth.WithAPIKey(ctx, []byte(tt.APIKey))
|
|
|
|
errTag := fmt.Sprintf("Test case #%d", i)
|
|
|
|
listRequest := pb.ListRequest{
|
|
Prefix: tt.prefix,
|
|
StartAfter: tt.startAfter,
|
|
EndBefore: tt.endBefore,
|
|
Recursive: tt.recursive,
|
|
Limit: int32(tt.limit),
|
|
MetaFlags: tt.metaFlags,
|
|
}
|
|
|
|
listResponse := pb.ListResponse{Items: tt.items, More: tt.more}
|
|
|
|
gc := NewMockPointerDBClient(ctrl)
|
|
pdb := PointerDB{client: gc}
|
|
|
|
gc.EXPECT().List(gomock.Any(), &listRequest).Return(&listResponse, tt.err)
|
|
|
|
items, more, err := pdb.List(ctx, tt.prefix, tt.startAfter, tt.endBefore, tt.recursive, tt.limit, tt.metaFlags)
|
|
|
|
if err != nil {
|
|
assert.EqualError(t, err, tt.errString, errTag)
|
|
assert.False(t, more)
|
|
assert.Nil(t, items)
|
|
} else {
|
|
assert.NoError(t, err, errTag)
|
|
assert.Equal(t, tt.more, more)
|
|
assert.NotNil(t, items)
|
|
assert.Equal(t, len(tt.items), len(items))
|
|
|
|
for i := 0; i < len(items); i++ {
|
|
assert.Equal(t, tt.items[i].GetPath(), items[i].Path)
|
|
assert.Equal(t, tt.items[i].GetPointer().GetSegmentSize(), items[i].Pointer.GetSegmentSize())
|
|
assert.Equal(t, tt.items[i].GetPointer().GetCreationDate(), items[i].Pointer.GetCreationDate())
|
|
assert.Equal(t, tt.items[i].GetPointer().GetExpirationDate(), items[i].Pointer.GetExpirationDate())
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDelete(t *testing.T) {
|
|
ctrl := gomock.NewController(t)
|
|
defer ctrl.Finish()
|
|
|
|
for i, tt := range []struct {
|
|
APIKey []byte
|
|
path storj.Path
|
|
err error
|
|
errString string
|
|
}{
|
|
{[]byte("wrong key"), "file1/file2", ErrUnauthenticated, unauthenticated},
|
|
{[]byte("abc123"), "", ErrNoFileGiven, noPathGiven},
|
|
{[]byte("wrong key"), "", ErrUnauthenticated, unauthenticated},
|
|
{[]byte(""), "", ErrUnauthenticated, unauthenticated},
|
|
{[]byte("abc123"), "file1/file2", nil, ""},
|
|
} {
|
|
ctx := context.Background()
|
|
ctx = auth.WithAPIKey(ctx, tt.APIKey)
|
|
|
|
deleteRequest := pb.DeleteRequest{Path: tt.path}
|
|
|
|
errTag := fmt.Sprintf("Test case #%d", i)
|
|
gc := NewMockPointerDBClient(ctrl)
|
|
pdb := PointerDB{client: gc}
|
|
|
|
gc.EXPECT().Delete(gomock.Any(), &deleteRequest).Return(nil, tt.err)
|
|
|
|
err := pdb.Delete(ctx, tt.path)
|
|
|
|
if err != nil {
|
|
assert.EqualError(t, err, tt.errString, errTag)
|
|
} else {
|
|
assert.NoError(t, err, errTag)
|
|
}
|
|
}
|
|
}
|