forked from TrueCloudLab/frostfs-node
133 lines
3.1 KiB
Go
133 lines
3.1 KiB
Go
|
package container
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"errors"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/nspcc-dev/neofs-api-go/container"
|
||
|
libcnr "github.com/nspcc-dev/neofs-node/lib/container"
|
||
|
"github.com/nspcc-dev/neofs-node/lib/netmap"
|
||
|
"github.com/nspcc-dev/neofs-node/lib/test"
|
||
|
"github.com/stretchr/testify/require"
|
||
|
"google.golang.org/grpc/codes"
|
||
|
"google.golang.org/grpc/status"
|
||
|
)
|
||
|
|
||
|
// Entity for mocking interfaces.
|
||
|
// Implementation of any interface intercepts arguments via f (if not nil).
|
||
|
// If err is not nil, it returns as it is. Otherwise, casted to needed type res returns w/o error.
|
||
|
type testPutEntity struct {
|
||
|
// Set of interfaces which entity must implement, but some methods from those does not call.
|
||
|
libcnr.Storage
|
||
|
|
||
|
// Argument interceptor. Used for ascertain of correct parameter passage between components.
|
||
|
f func(...interface{})
|
||
|
// Mocked result of any interface.
|
||
|
res interface{}
|
||
|
// Mocked error of any interface.
|
||
|
err error
|
||
|
}
|
||
|
|
||
|
func (s testPutEntity) PutContainer(p libcnr.PutParams) (*libcnr.PutResult, error) {
|
||
|
if s.f != nil {
|
||
|
s.f(p)
|
||
|
}
|
||
|
|
||
|
if s.err != nil {
|
||
|
return nil, s.err
|
||
|
}
|
||
|
|
||
|
return s.res.(*libcnr.PutResult), nil
|
||
|
}
|
||
|
|
||
|
func TestCnrService_Put(t *testing.T) {
|
||
|
ctx := context.TODO()
|
||
|
|
||
|
t.Run("unhealthy", func(t *testing.T) {
|
||
|
s := cnrService{
|
||
|
healthy: &testCommonEntity{
|
||
|
err: errors.New("some error"),
|
||
|
},
|
||
|
}
|
||
|
|
||
|
_, err := s.Put(ctx, new(container.PutRequest))
|
||
|
require.Error(t, err)
|
||
|
})
|
||
|
|
||
|
t.Run("invalid request structure", func(t *testing.T) {
|
||
|
s := cnrService{
|
||
|
healthy: new(testCommonEntity),
|
||
|
}
|
||
|
|
||
|
// create unsigned request
|
||
|
req := new(container.PutRequest)
|
||
|
require.Error(t, requestVerifyFunc(req))
|
||
|
|
||
|
_, err := s.Put(ctx, req)
|
||
|
require.Error(t, err)
|
||
|
|
||
|
st, ok := status.FromError(err)
|
||
|
require.True(t, ok)
|
||
|
require.Equal(t, codes.InvalidArgument, st.Code())
|
||
|
})
|
||
|
|
||
|
t.Run("container storage failure", func(t *testing.T) {
|
||
|
req := new(container.PutRequest)
|
||
|
req.SetCapacity(1)
|
||
|
req.SetBasicACL(2)
|
||
|
req.SetOwnerID(OwnerID{1, 2, 3})
|
||
|
req.SetRules(netmap.PlacementRule{
|
||
|
ReplFactor: 3,
|
||
|
})
|
||
|
|
||
|
require.NoError(t, requestSignFunc(test.DecodeKey(0), req))
|
||
|
|
||
|
s := cnrService{
|
||
|
healthy: new(testCommonEntity),
|
||
|
cnrStore: &testPutEntity{
|
||
|
f: func(items ...interface{}) {
|
||
|
p := items[0].(libcnr.PutParams)
|
||
|
require.Equal(t, ctx, p.Context())
|
||
|
|
||
|
cnr := p.Container()
|
||
|
require.Equal(t, req.GetCapacity(), cnr.GetCapacity())
|
||
|
require.Equal(t, req.GetBasicACL(), cnr.GetBasicACL())
|
||
|
require.Equal(t, req.GetRules(), cnr.GetRules())
|
||
|
require.Equal(t, req.GetOwnerID(), cnr.OwnerID)
|
||
|
},
|
||
|
err: errors.New("storage error"),
|
||
|
},
|
||
|
}
|
||
|
|
||
|
_, err := s.Put(ctx, req)
|
||
|
require.Error(t, err)
|
||
|
|
||
|
st, ok := status.FromError(err)
|
||
|
require.True(t, ok)
|
||
|
require.Equal(t, codes.Aborted, st.Code())
|
||
|
})
|
||
|
|
||
|
t.Run("correct result", func(t *testing.T) {
|
||
|
req := new(container.PutRequest)
|
||
|
|
||
|
require.NoError(t, requestSignFunc(test.DecodeKey(0), req))
|
||
|
|
||
|
cid := CID{1, 2, 3}
|
||
|
|
||
|
putRes := new(libcnr.PutResult)
|
||
|
putRes.SetCID(cid)
|
||
|
|
||
|
s := cnrService{
|
||
|
healthy: new(testCommonEntity),
|
||
|
cnrStore: &testPutEntity{
|
||
|
res: putRes,
|
||
|
},
|
||
|
}
|
||
|
|
||
|
res, err := s.Put(ctx, req)
|
||
|
require.NoError(t, err)
|
||
|
require.Equal(t, cid, res.CID)
|
||
|
})
|
||
|
}
|