storj/pkg/pointerdb/pdbclient/client_test.go
Bryan White ee62e2a9d8
Use transport client and cleanup all the clients (#574)
* wip

* linter fixes

* linter fixes

* test fixes

* linter fixes

* fix merge + restructure piecestore packages

* review feedback

* linter fixes

* linter fixes

* remove unnecessary aliases to piecestore

* more merge fixing
2018-11-06 18:49:17 +01:00

293 lines
7.5 KiB
Go

// Copyright (C) 2018 Storj Labs, Inc.
// See LICENSE for copying information.
package pdbclient
import (
"context"
"errors"
"fmt"
"log"
"strings"
"testing"
"github.com/golang/mock/gomock"
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/ptypes"
"github.com/stretchr/testify/assert"
"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: "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,
},
Size: 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{}}
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, 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)
} else {
assert.NotNil(t, pointer)
assert.NotNil(t, nodes)
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{
Size: 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{Size: 1234}},
{Path: "x/y", Pointer: &pb.Pointer{Size: 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().GetSize(), items[i].Pointer.GetSize())
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)
}
}
}