Adjustments to how find storage nodes handles limit/amout requested (#192)

* adjusted based on feedback from @jtolds and @kaloyan-raev

* generated protobuf

* fix crash

* WIP

* cleanup

* v >>found

* pointer

* test

* copyrights + cleanup

* fix tests
This commit is contained in:
Dennis Coyle 2018-08-03 09:15:52 -04:00 committed by GitHub
parent e66a0d289a
commit 7348bf1e09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 204 additions and 114 deletions

View File

@ -82,7 +82,7 @@ func (o *Cache) Put(nodeID string, value overlay.Node) error {
return err
}
return o.DB.Put([]byte(nodeID), []byte(data))
return o.DB.Put(kademlia.StringToNodeID(nodeID).Bytes(), []byte(data))
}
// Bootstrap walks the initialized network and populates the cache
@ -98,12 +98,13 @@ func (o *Cache) Bootstrap(ctx context.Context) error {
if err != nil {
zap.Error(ErrNodeNotFound)
}
addr, err := proto.Marshal(found.Address)
node, err := proto.Marshal(&found)
if err != nil {
return err
}
if err := o.DB.Put([]byte(found.Id), addr); err != nil {
if err := o.DB.Put(kademlia.StringToNodeID(found.Id).Bytes(), node); err != nil {
return err
}
}

View File

@ -35,6 +35,7 @@ func NewOverlayClient(address string) (*Overlay, error) {
if err != nil {
return nil, err
}
return &Overlay{
client: c,
}, nil
@ -44,15 +45,15 @@ func NewOverlayClient(address string) (*Overlay, error) {
var _ Client = (*Overlay)(nil)
// Choose implements the client.Choose interface
func (o *Overlay) Choose(ctx context.Context, limit int, space int64) ([]*proto.Node, error) {
func (o *Overlay) Choose(ctx context.Context, amount int, space int64) ([]*proto.Node, error) {
// TODO(coyle): We will also need to communicate with the reputation service here
resp, err := o.client.FindStorageNodes(ctx, &proto.FindStorageNodesRequest{
Opts: &proto.OverlayOptions{Limit: int64(limit), Restrictions: &proto.NodeRestrictions{
Opts: &proto.OverlayOptions{Amount: int64(amount), Restrictions: &proto.NodeRestrictions{
FreeDisk: space,
}},
})
if err != nil {
return nil, err
return nil, Error.Wrap(err)
}
return resp.GetNodes(), nil

View File

@ -1,3 +1,5 @@
// Copyright (C) 2018 Storj Labs, Inc.
// See LICENSE for copying information.
package overlay
import (

View File

@ -36,7 +36,7 @@ func TestFindStorageNodes(t *testing.T) {
c, err := NewClient(address, grpc.WithInsecure())
assert.NoError(t, err)
r, err := c.FindStorageNodes(context.Background(), &proto.FindStorageNodesRequest{Opts: &proto.OverlayOptions{Limit: 5}})
r, err := c.FindStorageNodes(context.Background(), &proto.FindStorageNodesRequest{Opts: &proto.OverlayOptions{Amount: 2}})
assert.NoError(t, err)
assert.NotNil(t, r)

View File

@ -5,9 +5,12 @@ package overlay
import (
"context"
"fmt"
protob "github.com/gogo/protobuf/proto"
"go.uber.org/zap"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"gopkg.in/spacemonkeygo/monkit.v2"
"storj.io/storj/pkg/dht"
@ -40,7 +43,7 @@ func (o *Server) Lookup(ctx context.Context, req *proto.LookupRequest) (*proto.L
// FindStorageNodes searches the overlay network for nodes that meet the provided requirements
func (o *Server) FindStorageNodes(ctx context.Context, req *proto.FindStorageNodesRequest) (resp *proto.FindStorageNodesResponse, err error) {
opts := req.GetOpts()
maxNodes := opts.GetLimit()
maxNodes := opts.GetAmount()
restrictions := opts.GetRestrictions()
restrictedBandwidth := restrictions.GetFreeBandwidth()
restrictedSpace := restrictions.GetFreeDisk()
@ -51,7 +54,7 @@ func (o *Server) FindStorageNodes(ctx context.Context, req *proto.FindStorageNod
var nodes []*proto.Node
nodes, start, err = o.populate(ctx, start, maxNodes, restrictedBandwidth, restrictedSpace)
if err != nil {
return nil, err
return nil, Error.Wrap(err)
}
if len(nodes) <= 0 {
@ -66,6 +69,10 @@ func (o *Server) FindStorageNodes(ctx context.Context, req *proto.FindStorageNod
}
if len(result) < int(maxNodes) {
return nil, status.Errorf(codes.ResourceExhausted, fmt.Sprintf("requested %d nodes, only %d nodes matched the criteria requested", maxNodes, len(result)))
}
if len(result) > int(maxNodes) {
result = result[:maxNodes]
}
@ -78,14 +85,14 @@ func (o *Server) FindStorageNodes(ctx context.Context, req *proto.FindStorageNod
func (o *Server) getNodes(ctx context.Context, keys storage.Keys) ([]*proto.Node, error) {
values, err := o.cache.DB.GetAll(keys)
if err != nil {
return nil, err
return nil, Error.Wrap(err)
}
nodes := []*proto.Node{}
for _, v := range values {
n := &proto.Node{}
if err := protob.Unmarshal(v, n); err != nil {
return nil, err
return nil, Error.Wrap(err)
}
nodes = append(nodes, n)
@ -97,10 +104,10 @@ func (o *Server) getNodes(ctx context.Context, keys storage.Keys) ([]*proto.Node
func (o *Server) populate(ctx context.Context, starting storage.Key, maxNodes, restrictedBandwidth, restrictedSpace int64) ([]*proto.Node, storage.Key, error) {
limit := storage.Limit(maxNodes) * 2
keys, err := o.cache.DB.List(nil, limit)
keys, err := o.cache.DB.List(starting, limit)
if err != nil {
o.logger.Error("Error listing nodes", zap.Error(err))
return nil, nil, err
return nil, nil, Error.Wrap(err)
}
if len(keys) <= 0 {
@ -111,7 +118,8 @@ func (o *Server) populate(ctx context.Context, starting storage.Key, maxNodes, r
result := []*proto.Node{}
nodes, err := o.getNodes(ctx, keys)
if err != nil {
return nil, nil, err
o.logger.Error("Error getting nodes", zap.Error(err))
return nil, nil, Error.Wrap(err)
}
for _, v := range nodes {

View File

@ -1,3 +1,5 @@
// Copyright (C) 2018 Storj Labs, Inc.
// See LICENSE for copying information.
// Code generated by MockGen. DO NOT EDIT.
// Source: storj.io/storj/storage (interfaces: KeyValueStore)

View File

@ -42,7 +42,7 @@ func (x NodeTransport) String() string {
return proto.EnumName(NodeTransport_name, int32(x))
}
func (NodeTransport) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_overlay_76f155a132105757, []int{0}
return fileDescriptor_overlay_c519e01640e795d6, []int{0}
}
// NodeTyp is an enum of possible node types
@ -66,7 +66,7 @@ func (x NodeType) String() string {
return proto.EnumName(NodeType_name, int32(x))
}
func (NodeType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_overlay_76f155a132105757, []int{1}
return fileDescriptor_overlay_c519e01640e795d6, []int{1}
}
type Restriction_Operator int32
@ -98,7 +98,7 @@ func (x Restriction_Operator) String() string {
return proto.EnumName(Restriction_Operator_name, int32(x))
}
func (Restriction_Operator) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_overlay_76f155a132105757, []int{11, 0}
return fileDescriptor_overlay_c519e01640e795d6, []int{11, 0}
}
type Restriction_Operand int32
@ -121,12 +121,12 @@ func (x Restriction_Operand) String() string {
return proto.EnumName(Restriction_Operand_name, int32(x))
}
func (Restriction_Operand) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_overlay_76f155a132105757, []int{11, 1}
return fileDescriptor_overlay_c519e01640e795d6, []int{11, 1}
}
// LookupRequest is is request message for the lookup rpc call
type LookupRequest struct {
NodeID string `protobuf:"bytes,1,opt,name=nodeID" json:"nodeID,omitempty"`
NodeID string `protobuf:"bytes,1,opt,name=nodeID,proto3" json:"nodeID,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -136,7 +136,7 @@ func (m *LookupRequest) Reset() { *m = LookupRequest{} }
func (m *LookupRequest) String() string { return proto.CompactTextString(m) }
func (*LookupRequest) ProtoMessage() {}
func (*LookupRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_overlay_76f155a132105757, []int{0}
return fileDescriptor_overlay_c519e01640e795d6, []int{0}
}
func (m *LookupRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_LookupRequest.Unmarshal(m, b)
@ -165,7 +165,7 @@ func (m *LookupRequest) GetNodeID() string {
// LookupResponse is is response message for the lookup rpc call
type LookupResponse struct {
Node *Node `protobuf:"bytes,1,opt,name=node" json:"node,omitempty"`
Node *Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -175,7 +175,7 @@ func (m *LookupResponse) Reset() { *m = LookupResponse{} }
func (m *LookupResponse) String() string { return proto.CompactTextString(m) }
func (*LookupResponse) ProtoMessage() {}
func (*LookupResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_overlay_76f155a132105757, []int{1}
return fileDescriptor_overlay_c519e01640e795d6, []int{1}
}
func (m *LookupResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_LookupResponse.Unmarshal(m, b)
@ -204,7 +204,7 @@ func (m *LookupResponse) GetNode() *Node {
// FindStorageNodesResponse is is response message for the FindStorageNodes rpc call
type FindStorageNodesResponse struct {
Nodes []*Node `protobuf:"bytes,1,rep,name=nodes" json:"nodes,omitempty"`
Nodes []*Node `protobuf:"bytes,1,rep,name=nodes,proto3" json:"nodes,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -214,7 +214,7 @@ func (m *FindStorageNodesResponse) Reset() { *m = FindStorageNodesRespon
func (m *FindStorageNodesResponse) String() string { return proto.CompactTextString(m) }
func (*FindStorageNodesResponse) ProtoMessage() {}
func (*FindStorageNodesResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_overlay_76f155a132105757, []int{2}
return fileDescriptor_overlay_c519e01640e795d6, []int{2}
}
func (m *FindStorageNodesResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_FindStorageNodesResponse.Unmarshal(m, b)
@ -243,9 +243,9 @@ func (m *FindStorageNodesResponse) GetNodes() []*Node {
// FindStorageNodesRequest is is request message for the FindStorageNodes rpc call
type FindStorageNodesRequest struct {
ObjectSize int64 `protobuf:"varint,1,opt,name=objectSize" json:"objectSize,omitempty"`
ContractLength *duration.Duration `protobuf:"bytes,2,opt,name=contractLength" json:"contractLength,omitempty"`
Opts *OverlayOptions `protobuf:"bytes,3,opt,name=opts" json:"opts,omitempty"`
ObjectSize int64 `protobuf:"varint,1,opt,name=objectSize,proto3" json:"objectSize,omitempty"`
ContractLength *duration.Duration `protobuf:"bytes,2,opt,name=contractLength,proto3" json:"contractLength,omitempty"`
Opts *OverlayOptions `protobuf:"bytes,3,opt,name=opts,proto3" json:"opts,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -255,7 +255,7 @@ func (m *FindStorageNodesRequest) Reset() { *m = FindStorageNodesRequest
func (m *FindStorageNodesRequest) String() string { return proto.CompactTextString(m) }
func (*FindStorageNodesRequest) ProtoMessage() {}
func (*FindStorageNodesRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_overlay_76f155a132105757, []int{3}
return fileDescriptor_overlay_c519e01640e795d6, []int{3}
}
func (m *FindStorageNodesRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_FindStorageNodesRequest.Unmarshal(m, b)
@ -298,8 +298,8 @@ func (m *FindStorageNodesRequest) GetOpts() *OverlayOptions {
// NodeAddress contains the information needed to communicate with a node on the network
type NodeAddress struct {
Transport NodeTransport `protobuf:"varint,1,opt,name=transport,enum=overlay.NodeTransport" json:"transport,omitempty"`
Address string `protobuf:"bytes,2,opt,name=address" json:"address,omitempty"`
Transport NodeTransport `protobuf:"varint,1,opt,name=transport,proto3,enum=overlay.NodeTransport" json:"transport,omitempty"`
Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -309,7 +309,7 @@ func (m *NodeAddress) Reset() { *m = NodeAddress{} }
func (m *NodeAddress) String() string { return proto.CompactTextString(m) }
func (*NodeAddress) ProtoMessage() {}
func (*NodeAddress) Descriptor() ([]byte, []int) {
return fileDescriptor_overlay_76f155a132105757, []int{4}
return fileDescriptor_overlay_c519e01640e795d6, []int{4}
}
func (m *NodeAddress) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_NodeAddress.Unmarshal(m, b)
@ -345,11 +345,11 @@ func (m *NodeAddress) GetAddress() string {
// OverlayOptions is a set of criteria that a node must meet to be considered for a storage opportunity
type OverlayOptions struct {
MaxLatency *duration.Duration `protobuf:"bytes,1,opt,name=maxLatency" json:"maxLatency,omitempty"`
MinReputation *NodeRep `protobuf:"bytes,2,opt,name=minReputation" json:"minReputation,omitempty"`
MinSpeedKbps int64 `protobuf:"varint,3,opt,name=minSpeedKbps" json:"minSpeedKbps,omitempty"`
Limit int64 `protobuf:"varint,4,opt,name=limit" json:"limit,omitempty"`
Restrictions *NodeRestrictions `protobuf:"bytes,5,opt,name=restrictions" json:"restrictions,omitempty"`
MaxLatency *duration.Duration `protobuf:"bytes,1,opt,name=maxLatency,proto3" json:"maxLatency,omitempty"`
MinReputation *NodeRep `protobuf:"bytes,2,opt,name=minReputation,proto3" json:"minReputation,omitempty"`
MinSpeedKbps int64 `protobuf:"varint,3,opt,name=minSpeedKbps,proto3" json:"minSpeedKbps,omitempty"`
Amount int64 `protobuf:"varint,4,opt,name=amount,proto3" json:"amount,omitempty"`
Restrictions *NodeRestrictions `protobuf:"bytes,5,opt,name=restrictions,proto3" json:"restrictions,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -359,7 +359,7 @@ func (m *OverlayOptions) Reset() { *m = OverlayOptions{} }
func (m *OverlayOptions) String() string { return proto.CompactTextString(m) }
func (*OverlayOptions) ProtoMessage() {}
func (*OverlayOptions) Descriptor() ([]byte, []int) {
return fileDescriptor_overlay_76f155a132105757, []int{5}
return fileDescriptor_overlay_c519e01640e795d6, []int{5}
}
func (m *OverlayOptions) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_OverlayOptions.Unmarshal(m, b)
@ -400,9 +400,9 @@ func (m *OverlayOptions) GetMinSpeedKbps() int64 {
return 0
}
func (m *OverlayOptions) GetLimit() int64 {
func (m *OverlayOptions) GetAmount() int64 {
if m != nil {
return m.Limit
return m.Amount
}
return 0
}
@ -425,7 +425,7 @@ func (m *NodeRep) Reset() { *m = NodeRep{} }
func (m *NodeRep) String() string { return proto.CompactTextString(m) }
func (*NodeRep) ProtoMessage() {}
func (*NodeRep) Descriptor() ([]byte, []int) {
return fileDescriptor_overlay_76f155a132105757, []int{6}
return fileDescriptor_overlay_c519e01640e795d6, []int{6}
}
func (m *NodeRep) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_NodeRep.Unmarshal(m, b)
@ -447,8 +447,8 @@ var xxx_messageInfo_NodeRep proto.InternalMessageInfo
// NodeRestrictions contains all relevant data about a nodes ability to store data
type NodeRestrictions struct {
FreeBandwidth int64 `protobuf:"varint,1,opt,name=freeBandwidth" json:"freeBandwidth,omitempty"`
FreeDisk int64 `protobuf:"varint,2,opt,name=freeDisk" json:"freeDisk,omitempty"`
FreeBandwidth int64 `protobuf:"varint,1,opt,name=freeBandwidth,proto3" json:"freeBandwidth,omitempty"`
FreeDisk int64 `protobuf:"varint,2,opt,name=freeDisk,proto3" json:"freeDisk,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -458,7 +458,7 @@ func (m *NodeRestrictions) Reset() { *m = NodeRestrictions{} }
func (m *NodeRestrictions) String() string { return proto.CompactTextString(m) }
func (*NodeRestrictions) ProtoMessage() {}
func (*NodeRestrictions) Descriptor() ([]byte, []int) {
return fileDescriptor_overlay_76f155a132105757, []int{7}
return fileDescriptor_overlay_c519e01640e795d6, []int{7}
}
func (m *NodeRestrictions) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_NodeRestrictions.Unmarshal(m, b)
@ -494,10 +494,10 @@ func (m *NodeRestrictions) GetFreeDisk() int64 {
// Node represents a node in the overlay network
type Node struct {
Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
Address *NodeAddress `protobuf:"bytes,2,opt,name=address" json:"address,omitempty"`
Type NodeType `protobuf:"varint,3,opt,name=type,enum=overlay.NodeType" json:"type,omitempty"`
Restrictions *NodeRestrictions `protobuf:"bytes,4,opt,name=restrictions" json:"restrictions,omitempty"`
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Address *NodeAddress `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"`
Type NodeType `protobuf:"varint,3,opt,name=type,proto3,enum=overlay.NodeType" json:"type,omitempty"`
Restrictions *NodeRestrictions `protobuf:"bytes,4,opt,name=restrictions,proto3" json:"restrictions,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -507,7 +507,7 @@ func (m *Node) Reset() { *m = Node{} }
func (m *Node) String() string { return proto.CompactTextString(m) }
func (*Node) ProtoMessage() {}
func (*Node) Descriptor() ([]byte, []int) {
return fileDescriptor_overlay_76f155a132105757, []int{8}
return fileDescriptor_overlay_c519e01640e795d6, []int{8}
}
func (m *Node) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Node.Unmarshal(m, b)
@ -556,8 +556,8 @@ func (m *Node) GetRestrictions() *NodeRestrictions {
}
type QueryRequest struct {
Sender *Node `protobuf:"bytes,1,opt,name=sender" json:"sender,omitempty"`
Receiver *Node `protobuf:"bytes,2,opt,name=receiver" json:"receiver,omitempty"`
Sender *Node `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"`
Receiver *Node `protobuf:"bytes,2,opt,name=receiver,proto3" json:"receiver,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -567,7 +567,7 @@ func (m *QueryRequest) Reset() { *m = QueryRequest{} }
func (m *QueryRequest) String() string { return proto.CompactTextString(m) }
func (*QueryRequest) ProtoMessage() {}
func (*QueryRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_overlay_76f155a132105757, []int{9}
return fileDescriptor_overlay_c519e01640e795d6, []int{9}
}
func (m *QueryRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_QueryRequest.Unmarshal(m, b)
@ -602,8 +602,8 @@ func (m *QueryRequest) GetReceiver() *Node {
}
type QueryResponse struct {
Sender *Node `protobuf:"bytes,1,opt,name=sender" json:"sender,omitempty"`
Response []*Node `protobuf:"bytes,2,rep,name=response" json:"response,omitempty"`
Sender *Node `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty"`
Response []*Node `protobuf:"bytes,2,rep,name=response,proto3" json:"response,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -613,7 +613,7 @@ func (m *QueryResponse) Reset() { *m = QueryResponse{} }
func (m *QueryResponse) String() string { return proto.CompactTextString(m) }
func (*QueryResponse) ProtoMessage() {}
func (*QueryResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_overlay_76f155a132105757, []int{10}
return fileDescriptor_overlay_c519e01640e795d6, []int{10}
}
func (m *QueryResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_QueryResponse.Unmarshal(m, b)
@ -648,9 +648,9 @@ func (m *QueryResponse) GetResponse() []*Node {
}
type Restriction struct {
Operator Restriction_Operator `protobuf:"varint,1,opt,name=operator,enum=overlay.Restriction_Operator" json:"operator,omitempty"`
Operand Restriction_Operand `protobuf:"varint,2,opt,name=operand,enum=overlay.Restriction_Operand" json:"operand,omitempty"`
Value int64 `protobuf:"varint,3,opt,name=value" json:"value,omitempty"`
Operator Restriction_Operator `protobuf:"varint,1,opt,name=operator,proto3,enum=overlay.Restriction_Operator" json:"operator,omitempty"`
Operand Restriction_Operand `protobuf:"varint,2,opt,name=operand,proto3,enum=overlay.Restriction_Operand" json:"operand,omitempty"`
Value int64 `protobuf:"varint,3,opt,name=value,proto3" json:"value,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -660,7 +660,7 @@ func (m *Restriction) Reset() { *m = Restriction{} }
func (m *Restriction) String() string { return proto.CompactTextString(m) }
func (*Restriction) ProtoMessage() {}
func (*Restriction) Descriptor() ([]byte, []int) {
return fileDescriptor_overlay_76f155a132105757, []int{11}
return fileDescriptor_overlay_c519e01640e795d6, []int{11}
}
func (m *Restriction) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Restriction.Unmarshal(m, b)
@ -893,56 +893,56 @@ var _Nodes_serviceDesc = grpc.ServiceDesc{
Metadata: "overlay.proto",
}
func init() { proto.RegisterFile("overlay.proto", fileDescriptor_overlay_76f155a132105757) }
func init() { proto.RegisterFile("overlay.proto", fileDescriptor_overlay_c519e01640e795d6) }
var fileDescriptor_overlay_76f155a132105757 = []byte{
// 759 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xdd, 0x6e, 0xda, 0x48,
0x14, 0xc6, 0xfc, 0x19, 0x0e, 0x60, 0x39, 0xa3, 0x6c, 0xe2, 0x45, 0xbb, 0xab, 0xc4, 0xbb, 0xd1,
0xee, 0x66, 0x25, 0x2e, 0x48, 0x14, 0x29, 0x17, 0xab, 0x88, 0x16, 0x1a, 0x45, 0xa5, 0xa1, 0x19,
0x2c, 0xf5, 0xaa, 0x52, 0x0d, 0x9e, 0x10, 0x37, 0xe0, 0x71, 0xc7, 0x43, 0x5a, 0xfa, 0x2e, 0x7d,
0x80, 0x4a, 0x7d, 0xc0, 0x5e, 0xf4, 0xa2, 0xf2, 0xcc, 0xd8, 0x60, 0x48, 0x22, 0xe5, 0xca, 0x3e,
0xe7, 0xfb, 0xce, 0xff, 0x99, 0x03, 0x0d, 0x7a, 0x47, 0xd8, 0xd4, 0x5d, 0xb4, 0x42, 0x46, 0x39,
0x45, 0xba, 0x12, 0x9b, 0x86, 0x37, 0x67, 0x2e, 0xf7, 0x69, 0x20, 0x01, 0xfb, 0x6f, 0x68, 0xf4,
0x29, 0xbd, 0x9d, 0x87, 0x98, 0x7c, 0x98, 0x93, 0x88, 0xa3, 0x1d, 0x28, 0x07, 0xd4, 0x23, 0x17,
0x5d, 0x4b, 0xdb, 0xd3, 0xfe, 0xa9, 0x62, 0x25, 0xd9, 0x47, 0x60, 0x24, 0xc4, 0x28, 0xa4, 0x41,
0x44, 0xd0, 0x3e, 0x14, 0x63, 0x4c, 0xf0, 0x6a, 0xed, 0x46, 0x2b, 0x89, 0x78, 0x49, 0x3d, 0x82,
0x05, 0x64, 0x9f, 0x81, 0xf5, 0xc2, 0x0f, 0xbc, 0x21, 0xa7, 0xcc, 0x9d, 0x90, 0x18, 0x88, 0x52,
0xf3, 0x3f, 0xa1, 0x14, 0x73, 0x22, 0x4b, 0xdb, 0x2b, 0x6c, 0xda, 0x4b, 0xcc, 0xfe, 0xaa, 0xc1,
0xee, 0xa6, 0x07, 0x99, 0xe9, 0x1f, 0x00, 0x74, 0xf4, 0x9e, 0x8c, 0xf9, 0xd0, 0xff, 0x2c, 0xb3,
0x28, 0xe0, 0x15, 0x0d, 0xea, 0x80, 0x31, 0xa6, 0x01, 0x67, 0xee, 0x98, 0xf7, 0x49, 0x30, 0xe1,
0x37, 0x56, 0x5e, 0x64, 0xfa, 0x6b, 0x6b, 0x42, 0xe9, 0x64, 0x4a, 0x64, 0x07, 0x46, 0xf3, 0xeb,
0x56, 0x57, 0xf5, 0x04, 0xaf, 0x19, 0xa0, 0xff, 0xa0, 0x48, 0x43, 0x1e, 0x59, 0x05, 0x61, 0xb8,
0x9b, 0xa6, 0x38, 0x90, 0xdf, 0x41, 0x18, 0x5b, 0x45, 0x58, 0x90, 0xec, 0xb7, 0x50, 0x8b, 0xf3,
0xeb, 0x78, 0x1e, 0x23, 0x51, 0x84, 0x8e, 0xa1, 0xca, 0x99, 0x1b, 0x44, 0x21, 0x65, 0x5c, 0x64,
0x67, 0xb4, 0x77, 0x32, 0x35, 0x3a, 0x09, 0x8a, 0x97, 0x44, 0x64, 0x81, 0xee, 0x4a, 0x07, 0x22,
0xdb, 0x2a, 0x4e, 0x44, 0xfb, 0x87, 0x06, 0x46, 0x36, 0x2e, 0x3a, 0x05, 0x98, 0xb9, 0x9f, 0xfa,
0x2e, 0x27, 0xc1, 0x78, 0xa1, 0xe6, 0xf0, 0x48, 0x75, 0x2b, 0x64, 0x74, 0x02, 0x8d, 0x99, 0x1f,
0x60, 0x12, 0xce, 0xb9, 0x00, 0x55, 0x6f, 0xcc, 0xec, 0x14, 0x48, 0x88, 0xb3, 0x34, 0x64, 0x43,
0x7d, 0xe6, 0x07, 0xc3, 0x90, 0x10, 0xef, 0xe5, 0x28, 0x94, 0x9d, 0x29, 0xe0, 0x8c, 0x0e, 0x6d,
0x43, 0x69, 0xea, 0xcf, 0x7c, 0x6e, 0x15, 0x05, 0x28, 0x05, 0xf4, 0x3f, 0xd4, 0x19, 0x89, 0x38,
0xf3, 0xc7, 0x22, 0x79, 0xab, 0xa4, 0xd2, 0xcd, 0x06, 0x5c, 0x12, 0x70, 0x86, 0x6e, 0x57, 0x41,
0x57, 0x29, 0xd9, 0x0e, 0x98, 0xeb, 0x64, 0xf4, 0x17, 0x34, 0xae, 0x19, 0x21, 0xcf, 0xdc, 0xc0,
0xfb, 0xe8, 0x7b, 0xfc, 0x46, 0xed, 0x43, 0x56, 0x89, 0x9a, 0x50, 0x89, 0x15, 0x5d, 0x3f, 0xba,
0x15, 0x05, 0x17, 0x70, 0x2a, 0xdb, 0xdf, 0x34, 0x28, 0xc6, 0x6e, 0x91, 0x01, 0x79, 0xdf, 0x53,
0xdb, 0x9f, 0xf7, 0x3d, 0xd4, 0xca, 0x8e, 0xa4, 0xd6, 0xde, 0xce, 0xe4, 0xac, 0xe6, 0x9d, 0x0e,
0x0a, 0x1d, 0x40, 0x91, 0x2f, 0x42, 0x22, 0x5a, 0x63, 0xb4, 0xb7, 0xb2, 0x33, 0x5f, 0x84, 0x04,
0x0b, 0x78, 0xa3, 0x1f, 0xc5, 0xa7, 0xf5, 0xe3, 0x1d, 0xd4, 0xaf, 0xe6, 0x84, 0x2d, 0x92, 0xd7,
0x70, 0x00, 0xe5, 0x88, 0x04, 0x1e, 0x61, 0xf7, 0xbf, 0x47, 0x05, 0xa2, 0x7f, 0xa1, 0xc2, 0xc8,
0x98, 0xf8, 0x77, 0x84, 0xa9, 0x6a, 0xd6, 0x88, 0x29, 0x6c, 0xbb, 0xd0, 0x50, 0x11, 0xd4, 0x8b,
0x7d, 0x4a, 0x08, 0x69, 0x62, 0xe5, 0xef, 0x7b, 0xdb, 0x29, 0x6c, 0x7f, 0xd7, 0xa0, 0xb6, 0x52,
0x23, 0x3a, 0x85, 0x0a, 0x0d, 0x09, 0x73, 0x39, 0x65, 0xea, 0xc9, 0xfc, 0x9e, 0x9a, 0xae, 0xf0,
0x5a, 0x03, 0x45, 0xc2, 0x29, 0x1d, 0x9d, 0x80, 0x2e, 0xfe, 0x03, 0x4f, 0xd4, 0x65, 0xb4, 0x7f,
0x7b, 0xd8, 0x32, 0xf0, 0x70, 0x42, 0x8e, 0x97, 0xf5, 0xce, 0x9d, 0xce, 0x89, 0xda, 0x64, 0x29,
0xd8, 0xc7, 0x50, 0x49, 0x62, 0xa0, 0x32, 0xe4, 0xfb, 0x8e, 0x99, 0x8b, 0xbf, 0xbd, 0x2b, 0x53,
0x8b, 0xbf, 0xe7, 0x8e, 0x99, 0x47, 0x3a, 0x14, 0xfa, 0x4e, 0xcf, 0x2c, 0xc4, 0x3f, 0xe7, 0x4e,
0xcf, 0x2c, 0xda, 0x87, 0xa0, 0x2b, 0xff, 0x68, 0x6b, 0x6d, 0x1f, 0xcd, 0x1c, 0xaa, 0x2f, 0x97,
0xcf, 0xd4, 0x0e, 0x2d, 0x68, 0x64, 0x8e, 0x40, 0xec, 0xc5, 0x79, 0xfe, 0xda, 0xcc, 0x1d, 0xda,
0x50, 0x49, 0x56, 0x05, 0x55, 0xa1, 0xd4, 0xe9, 0xbe, 0xba, 0xb8, 0x34, 0x73, 0xa8, 0x06, 0xfa,
0xd0, 0x19, 0xe0, 0xce, 0x79, 0xcf, 0xd4, 0xda, 0x5f, 0x34, 0xd0, 0xd5, 0x31, 0x40, 0xa7, 0x50,
0x96, 0x97, 0x19, 0x2d, 0xef, 0x4b, 0xe6, 0xa6, 0x37, 0x77, 0x37, 0xf4, 0x6a, 0xa2, 0x6f, 0xc0,
0x5c, 0xbf, 0xae, 0x68, 0x2f, 0x25, 0x3f, 0x70, 0x78, 0x9b, 0xfb, 0x8f, 0x30, 0xa4, 0xe3, 0xf6,
0x19, 0x94, 0xa4, 0xb7, 0x13, 0x28, 0x89, 0x25, 0x42, 0xbf, 0xa4, 0x46, 0xab, 0x6b, 0xdb, 0xdc,
0x59, 0x57, 0x4b, 0x07, 0xa3, 0xb2, 0x38, 0x5f, 0x47, 0x3f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x25,
0xbd, 0x2d, 0xae, 0xc8, 0x06, 0x00, 0x00,
var fileDescriptor_overlay_c519e01640e795d6 = []byte{
// 755 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0xcd, 0x6e, 0xd3, 0x40,
0x10, 0x8e, 0xf3, 0xe7, 0x64, 0x92, 0x58, 0xee, 0xaa, 0xb4, 0x26, 0x02, 0xd4, 0x1a, 0x2a, 0xa0,
0x48, 0x39, 0xa4, 0x55, 0xa5, 0x1e, 0x50, 0x15, 0x48, 0xa8, 0x2a, 0x42, 0x43, 0x37, 0x96, 0x38,
0x21, 0xe1, 0xc4, 0xdb, 0xd4, 0xb4, 0xf1, 0x9a, 0xf5, 0xba, 0x10, 0xde, 0x85, 0x07, 0x40, 0xe2,
0x01, 0x39, 0x21, 0xe4, 0xf5, 0xda, 0x89, 0x93, 0xb6, 0x52, 0x4f, 0xf6, 0xcc, 0xf7, 0xcd, 0xff,
0xec, 0x40, 0x83, 0x5e, 0x13, 0x76, 0x65, 0xcf, 0x5a, 0x3e, 0xa3, 0x9c, 0x22, 0x55, 0x8a, 0x4d,
0xcd, 0x09, 0x99, 0xcd, 0x5d, 0xea, 0xc5, 0x80, 0xf9, 0x1c, 0x1a, 0x7d, 0x4a, 0x2f, 0x43, 0x1f,
0x93, 0x6f, 0x21, 0x09, 0x38, 0xda, 0x80, 0xb2, 0x47, 0x1d, 0x72, 0xd2, 0x35, 0x94, 0x2d, 0xe5,
0x45, 0x15, 0x4b, 0xc9, 0xdc, 0x03, 0x2d, 0x21, 0x06, 0x3e, 0xf5, 0x02, 0x82, 0xb6, 0xa1, 0x18,
0x61, 0x82, 0x57, 0x6b, 0x37, 0x5a, 0x49, 0xc4, 0x53, 0xea, 0x10, 0x2c, 0x20, 0xf3, 0x08, 0x8c,
0x77, 0xae, 0xe7, 0x0c, 0x39, 0x65, 0xf6, 0x84, 0x44, 0x40, 0x90, 0x9a, 0x3f, 0x85, 0x52, 0xc4,
0x09, 0x0c, 0x65, 0xab, 0xb0, 0x6a, 0x1f, 0x63, 0xe6, 0x6f, 0x05, 0x36, 0x57, 0x3d, 0xc4, 0x99,
0x3e, 0x01, 0xa0, 0xa3, 0xaf, 0x64, 0xcc, 0x87, 0xee, 0xcf, 0x38, 0x8b, 0x02, 0x5e, 0xd0, 0xa0,
0x0e, 0x68, 0x63, 0xea, 0x71, 0x66, 0x8f, 0x79, 0x9f, 0x78, 0x13, 0x7e, 0x61, 0xe4, 0x45, 0xa6,
0x0f, 0x5b, 0x13, 0x4a, 0x27, 0x57, 0x24, 0xee, 0xc0, 0x28, 0x3c, 0x6f, 0x75, 0x65, 0x4f, 0xf0,
0x92, 0x01, 0x7a, 0x05, 0x45, 0xea, 0xf3, 0xc0, 0x28, 0x08, 0xc3, 0xcd, 0x34, 0xc5, 0x41, 0xfc,
0x1d, 0xf8, 0x91, 0x55, 0x80, 0x05, 0xc9, 0xfc, 0x0c, 0xb5, 0x28, 0xbf, 0x8e, 0xe3, 0x30, 0x12,
0x04, 0x68, 0x1f, 0xaa, 0x9c, 0xd9, 0x5e, 0xe0, 0x53, 0xc6, 0x45, 0x76, 0x5a, 0x7b, 0x23, 0x53,
0xa3, 0x95, 0xa0, 0x78, 0x4e, 0x44, 0x06, 0xa8, 0x76, 0xec, 0x40, 0x64, 0x5b, 0xc5, 0x89, 0x68,
0xfe, 0x53, 0x40, 0xcb, 0xc6, 0x45, 0x87, 0x00, 0x53, 0xfb, 0x47, 0xdf, 0xe6, 0xc4, 0x1b, 0xcf,
0xe4, 0x1c, 0xee, 0xa8, 0x6e, 0x81, 0x8c, 0x0e, 0xa0, 0x31, 0x75, 0x3d, 0x4c, 0xfc, 0x90, 0x0b,
0x50, 0xf6, 0x46, 0xcf, 0x4e, 0x81, 0xf8, 0x38, 0x4b, 0x43, 0x26, 0xd4, 0xa7, 0xae, 0x37, 0xf4,
0x09, 0x71, 0xde, 0x8f, 0xfc, 0xb8, 0x33, 0x05, 0x9c, 0xd1, 0x45, 0x2b, 0x64, 0x4f, 0x69, 0xe8,
0x71, 0xa3, 0x28, 0x50, 0x29, 0xa1, 0xd7, 0x50, 0x67, 0x24, 0xe0, 0xcc, 0x1d, 0x8b, 0xf4, 0x8d,
0x92, 0x4c, 0x38, 0x1b, 0x72, 0x4e, 0xc0, 0x19, 0xba, 0x59, 0x05, 0x55, 0x26, 0x65, 0x5a, 0xa0,
0x2f, 0x93, 0xd1, 0x33, 0x68, 0x9c, 0x33, 0x42, 0xde, 0xd8, 0x9e, 0xf3, 0xdd, 0x75, 0xf8, 0x85,
0xdc, 0x88, 0xac, 0x12, 0x35, 0xa1, 0x12, 0x29, 0xba, 0x6e, 0x70, 0x29, 0x4a, 0x2e, 0xe0, 0x54,
0x36, 0xff, 0x28, 0x50, 0x8c, 0xdc, 0x22, 0x0d, 0xf2, 0xae, 0x23, 0xf7, 0x3f, 0xef, 0x3a, 0xa8,
0x95, 0x1d, 0x4a, 0xad, 0xbd, 0x9e, 0xc9, 0x59, 0x4e, 0x3c, 0x1d, 0x15, 0xda, 0x81, 0x22, 0x9f,
0xf9, 0x44, 0x34, 0x47, 0x6b, 0xaf, 0x65, 0xa7, 0x3e, 0xf3, 0x09, 0x16, 0xf0, 0x4a, 0x3f, 0x8a,
0xf7, 0xeb, 0xc7, 0x17, 0xa8, 0x9f, 0x85, 0x84, 0xcd, 0x92, 0xf7, 0xb0, 0x03, 0xe5, 0x80, 0x78,
0x0e, 0x61, 0x37, 0xbf, 0x48, 0x09, 0xa2, 0x97, 0x50, 0x61, 0x64, 0x4c, 0xdc, 0x6b, 0xc2, 0x64,
0x35, 0x4b, 0xc4, 0x14, 0x36, 0x6d, 0x68, 0xc8, 0x08, 0xf2, 0xcd, 0xde, 0x27, 0x44, 0x6c, 0x62,
0xe4, 0x6f, 0x7a, 0xdd, 0x29, 0x6c, 0xfe, 0x55, 0xa0, 0xb6, 0x50, 0x23, 0x3a, 0x84, 0x0a, 0xf5,
0x09, 0xb3, 0x39, 0x65, 0xf2, 0xd1, 0x3c, 0x4e, 0x4d, 0x17, 0x78, 0xad, 0x81, 0x24, 0xe1, 0x94,
0x8e, 0x0e, 0x40, 0x15, 0xff, 0x9e, 0x23, 0xea, 0xd2, 0xda, 0x8f, 0x6e, 0xb7, 0xf4, 0x1c, 0x9c,
0x90, 0xd1, 0x3a, 0x94, 0xae, 0xed, 0xab, 0x90, 0xc8, 0x5d, 0x8e, 0x05, 0x73, 0x1f, 0x2a, 0x49,
0x0c, 0x54, 0x86, 0x7c, 0xdf, 0xd2, 0x73, 0xd1, 0xb7, 0x77, 0xa6, 0x2b, 0xd1, 0xf7, 0xd8, 0xd2,
0xf3, 0x48, 0x85, 0x42, 0xdf, 0xea, 0xe9, 0x85, 0xe8, 0xe7, 0xd8, 0xea, 0xe9, 0x45, 0x73, 0x17,
0x54, 0xe9, 0x1f, 0xad, 0x2d, 0xed, 0xa3, 0x9e, 0x43, 0xf5, 0xf9, 0xf2, 0xe9, 0xca, 0xae, 0x01,
0x8d, 0xcc, 0x19, 0x88, 0xbc, 0x58, 0x6f, 0x3f, 0xea, 0xb9, 0x5d, 0x13, 0x2a, 0xc9, 0xaa, 0xa0,
0x2a, 0x94, 0x3a, 0xdd, 0x0f, 0x27, 0xa7, 0x7a, 0x0e, 0xd5, 0x40, 0x1d, 0x5a, 0x03, 0xdc, 0x39,
0xee, 0xe9, 0x4a, 0xfb, 0x97, 0x02, 0xaa, 0x3c, 0x07, 0xe8, 0x10, 0xca, 0xf1, 0x6d, 0x46, 0xf3,
0x0b, 0x93, 0xb9, 0xea, 0xcd, 0xcd, 0x15, 0xbd, 0x9c, 0xe8, 0x27, 0xd0, 0x97, 0xef, 0x2b, 0xda,
0x4a, 0xc9, 0xb7, 0x9c, 0xde, 0xe6, 0xf6, 0x1d, 0x8c, 0xd8, 0x71, 0xfb, 0x08, 0x4a, 0xb1, 0xb7,
0x03, 0x28, 0x89, 0x25, 0x42, 0x0f, 0x52, 0xa3, 0xc5, 0xb5, 0x6d, 0x6e, 0x2c, 0xab, 0x63, 0x07,
0xa3, 0xb2, 0x38, 0x60, 0x7b, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0x5e, 0xbb, 0x1e, 0xde, 0xca,
0x06, 0x00, 0x00,
}

View File

@ -57,7 +57,7 @@ message OverlayOptions {
google.protobuf.Duration maxLatency = 1;
NodeRep minReputation = 2; // Not sure what NodeRep is yet.
int64 minSpeedKbps = 3;
int64 limit = 4;
int64 amount = 4;
NodeRestrictions restrictions = 5;
}

View File

@ -4,11 +4,12 @@
package boltdb
import (
"errors"
"fmt"
"time"
"github.com/boltdb/bolt"
"go.uber.org/zap"
"storj.io/storj/storage"
)
@ -30,7 +31,8 @@ const (
// KBucket is the string representing the bucket used for the kademlia routing table k-bucket ids
KBucket = "kbuckets"
// NodeBucket is the string representing the bucket used for the kademlia routing table node ids
NodeBucket = "nodes"
NodeBucket = "nodes"
maxKeyLookup = 100
)
var (
@ -147,7 +149,22 @@ func (c *Client) Close() error {
return c.db.Close()
}
// GetAll // TODO(coyle): implement
// GetAll finds all values for the provided keys up to 100 keys
// if more keys are provided than the maximum an error will be returned.
func (c *Client) GetAll(keys storage.Keys) (storage.Values, error) {
return nil, errors.New("Not Implemented")
lk := len(keys)
if lk > maxKeyLookup {
return nil, Error.New(fmt.Sprintf("requested %d keys, maximum is %d", lk, maxKeyLookup))
}
vals := make(storage.Values, lk)
for i, v := range keys {
val, err := c.Get(v)
if err != nil {
return nil, err
}
vals[i] = val
}
return vals, nil
}

View File

@ -5,10 +5,12 @@ package boltdb
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"testing"
"github.com/stretchr/testify/assert"
"go.uber.org/zap"
"storj.io/storj/storage"
)
@ -154,3 +156,60 @@ func TestListNoStartingKey(t *testing.T) {
bt.HandleErr(nil, "Expected test/path/3 to be last in list")
}
}
func TestGetAll(t *testing.T) {
bt := NewBoltClientTest(t)
defer bt.Close()
cases := []struct {
setup func(bt *BoltClientTest) storage.Keys
expected storage.Values
expectedErr error
}{
{
setup: func(bt *BoltClientTest) storage.Keys {
assert.NoError(t, bt.c.Put([]byte("hello"), []byte("world")))
return storage.Keys{storage.Key([]byte("hello"))}
},
expected: storage.Values{storage.Value([]byte("world"))},
expectedErr: nil,
},
{
setup: func(bt *BoltClientTest) storage.Keys {
keys := storage.Keys{}
for i := 0; i < 101; i++ {
key := fmt.Sprintf("hello%d", i)
assert.NoError(t, bt.c.Put([]byte(key), []byte("world")))
keys = append(keys, storage.Key([]byte(key)))
}
return keys
},
expected: nil,
expectedErr: Error.New("requested 101 keys, maximum is 100"),
},
{
setup: func(bt *BoltClientTest) storage.Keys {
assert.NoError(t, bt.c.Put([]byte("hello01"), []byte("world")))
assert.NoError(t, bt.c.Put([]byte("hello02"), []byte("world")))
assert.NoError(t, bt.c.Put([]byte("hello03"), []byte("world")))
return storage.Keys{storage.Key([]byte("hello01")), storage.Key([]byte("hello02")), storage.Key([]byte("hello03"))}
},
expected: storage.Values{storage.Value([]byte("world")), storage.Value([]byte("world")), storage.Value([]byte("world"))},
expectedErr: nil,
},
}
for _, v := range cases {
bt := NewBoltClientTest(t)
defer bt.Close()
keys := v.setup(bt)
actual, actualErr := bt.c.GetAll(keys)
if v.expectedErr != nil || actualErr != nil {
fmt.Println(actualErr)
assert.EqualError(t, v.expectedErr, actualErr.Error())
}
assert.Equal(t, v.expected, actual)
}
}