storj/pkg/ranger/grpc_test.go
Kaloyan Raev 916e0b0ee0 gRPC Ranger (#44)
* Added piecestore

* gofmt

* Added requested changes

* Added cli

* Removed ranger because I wanted something that can stand alone

* Add example of http server using piece store

* Changed piecestore code to make it more optial for error handelling

* Merged with piecestore

* Added missing package

* Forgot io import

* gofmt

* gofmt

* Forgot io

* Make path by hash exported

* updated to simplify again whoops

* Updated server to work real good

* Forgot ampersand

* Updated to match FilePiece

* Merged in cam's delete code

* Remove unused io

* Added RPC code

* Give the download request a reader

* Removed http server stuff; changed receive stream to say io.reader

* Added expiration date to shardInfo

* gRPC Ranger

* Change all instances of Shard to Piece; change protobuf name; moved client insance to outside functions

* Adapt to latest changes in piece store rpc api

* added ttl info request

* Initialize grpcRanger type with named fields

* Move scripts to http server pr; added close method for Retrieve api

* added rpc server tests for getting piece meta data and retrieval routes

* Adapt to PieceStreamReader now being a ReadCloser

* Resolved linter errors, moved to prc server to pkg, updated go.mod to use latest protobuf

* Imported cams test

* Bump gometalinter deadline

* Adapt to package name changes

* Remove Garbage

* Adapt to latest changes in piece store rpc api

* NewCustomRoute constructor to allow mocking the gRPC client

* Name struct values in constructor.
2018-06-02 22:20:17 -06:00

137 lines
3.9 KiB
Go

// Copyright (C) 2018 Storj Labs, Inc.
// See LICENSE for copying information.
package ranger
import (
"context"
"fmt"
"io"
"io/ioutil"
"testing"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"storj.io/storj/pkg/piecestore/rpc/client"
pb "storj.io/storj/protos/piecestore"
)
func TestGRPCRanger(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
for i, tt := range []struct {
data string
size, offset, length int64
substr string
errString string
}{
{"", 0, 0, 0, "", ""},
{"abcdef", 6, 0, 0, "", ""},
{"abcdef", 6, 3, 0, "", ""},
{"abcdef", 6, 0, 6, "abcdef", ""},
{"abcdef", 6, 0, 5, "abcde", ""},
{"abcdef", 6, 0, 4, "abcd", ""},
{"abcdef", 6, 1, 4, "bcde", ""},
{"abcdef", 6, 2, 4, "cdef", ""},
{"abcdefg", 7, 1, 4, "bcde", ""},
{"abcdef", 6, 0, 7, "abcdef", "ranger error: range beyond end"},
{"abcdef", 6, -1, 7, "abcde", "ranger error: negative offset"},
{"abcdef", 6, 0, -1, "abcde", "ranger error: negative length"},
} {
errTag := fmt.Sprintf("Test case #%d", i)
route := pb.NewMockPieceStoreRoutesClient(ctrl)
calls := []*gomock.Call{
route.EXPECT().Piece(
gomock.Any(), gomock.Any(), gomock.Any(),
).Return(&pb.PieceSummary{Size: int64(len(tt.data))}, nil),
}
if tt.offset >= 0 && tt.length > 0 && tt.offset+tt.length <= tt.size {
stream := pb.NewMockPieceStoreRoutes_RetrieveClient(ctrl)
calls = append(calls,
route.EXPECT().Retrieve(
gomock.Any(), gomock.Any(), gomock.Any(),
).Return(stream, nil),
stream.EXPECT().Recv().Return(
&pb.PieceRetrievalStream{
Size: tt.length,
Content: []byte(tt.data)[tt.offset : tt.offset+tt.length],
}, nil),
stream.EXPECT().Recv().Return(&pb.PieceRetrievalStream{}, io.EOF),
)
}
gomock.InOrder(calls...)
c := client.NewCustomRoute(context.Background(), route)
r, err := GRPCRanger(c, "")
if assert.NoError(t, err, errTag) {
assert.Equal(t, tt.size, r.Size(), errTag)
}
data, err := ioutil.ReadAll(r.Range(tt.offset, tt.length))
if tt.errString != "" {
assert.EqualError(t, err, tt.errString, errTag)
return
}
if assert.NoError(t, err, errTag) {
assert.Equal(t, []byte(tt.substr), data, errTag)
}
}
}
func TestGRPCRangerSize(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
for i, tt := range []struct {
data string
size, offset, length int64
substr string
errString string
}{
{"", 0, 0, 0, "", ""},
{"abcdef", 6, 0, 0, "", ""},
{"abcdef", 6, 3, 0, "", ""},
{"abcdef", 6, 0, 6, "abcdef", ""},
{"abcdef", 6, 0, 5, "abcde", ""},
{"abcdef", 6, 0, 4, "abcd", ""},
{"abcdef", 6, 1, 4, "bcde", ""},
{"abcdef", 6, 2, 4, "cdef", ""},
{"abcdefg", 7, 1, 4, "bcde", ""},
{"abcdef", 6, 0, 7, "abcdef", "ranger error: range beyond end"},
{"abcdef", 6, -1, 7, "abcde", "ranger error: negative offset"},
{"abcdef", 6, 0, -1, "abcde", "ranger error: negative length"},
} {
errTag := fmt.Sprintf("Test case #%d", i)
route := pb.NewMockPieceStoreRoutesClient(ctrl)
if tt.offset >= 0 && tt.length > 0 && tt.offset+tt.length <= tt.size {
stream := pb.NewMockPieceStoreRoutes_RetrieveClient(ctrl)
gomock.InOrder(
route.EXPECT().Retrieve(
gomock.Any(), gomock.Any(), gomock.Any(),
).Return(stream, nil),
stream.EXPECT().Recv().Return(
&pb.PieceRetrievalStream{
Size: tt.size,
Content: []byte(tt.data)[tt.offset : tt.offset+tt.length],
}, nil),
stream.EXPECT().Recv().Return(&pb.PieceRetrievalStream{}, io.EOF),
)
}
c := client.NewCustomRoute(context.Background(), route)
r := GRPCRangerSize(c, "", tt.size)
assert.Equal(t, tt.size, r.Size(), errTag)
data, err := ioutil.ReadAll(r.Range(tt.offset, tt.length))
if tt.errString != "" {
assert.EqualError(t, err, tt.errString, errTag)
return
}
if assert.NoError(t, err, errTag) {
assert.Equal(t, []byte(tt.substr), data, errTag)
}
}
}