2020-07-10 14:17:51 +00:00
|
|
|
package state
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"crypto/ecdsa"
|
|
|
|
"encoding/hex"
|
|
|
|
"encoding/json"
|
|
|
|
"expvar"
|
|
|
|
"os"
|
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/nspcc-dev/neofs-api-go/refs"
|
|
|
|
"github.com/nspcc-dev/neofs-api-go/service"
|
|
|
|
"github.com/nspcc-dev/neofs-api-go/state"
|
|
|
|
crypto "github.com/nspcc-dev/neofs-crypto"
|
2020-07-24 13:54:03 +00:00
|
|
|
testlogger "github.com/nspcc-dev/neofs-node/pkg/util/logger/test"
|
|
|
|
"github.com/nspcc-dev/neofs-node/pkg/util/test"
|
2020-07-10 14:17:51 +00:00
|
|
|
"github.com/spf13/viper"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"google.golang.org/grpc/codes"
|
|
|
|
"google.golang.org/grpc/status"
|
|
|
|
)
|
|
|
|
|
|
|
|
var requestSignFunc = service.SignRequestData
|
|
|
|
|
|
|
|
func Test_nonForwarding(t *testing.T) {
|
|
|
|
cases := []struct {
|
|
|
|
err error
|
|
|
|
ttl uint32
|
|
|
|
name string
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "ZeroTTL",
|
|
|
|
ttl: service.ZeroTTL,
|
|
|
|
err: status.Error(codes.InvalidArgument, service.ErrInvalidTTL.Error()),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "SingleForwardingTTL",
|
|
|
|
ttl: service.SingleForwardingTTL,
|
|
|
|
err: status.Error(codes.InvalidArgument, service.ErrInvalidTTL.Error()),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "NonForwardingTTL",
|
|
|
|
ttl: service.NonForwardingTTL,
|
|
|
|
err: nil,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for i := range cases {
|
|
|
|
tt := cases[i]
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
err := nonForwarding(tt.ttl)
|
|
|
|
switch tt.err {
|
|
|
|
case nil:
|
|
|
|
require.NoError(t, err, tt.name)
|
|
|
|
default:
|
|
|
|
require.EqualError(t, err, tt.err.Error())
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func Test_fetchOwners(t *testing.T) {
|
2020-07-24 13:54:03 +00:00
|
|
|
l := testlogger.NewLogger(false)
|
2020-07-10 14:17:51 +00:00
|
|
|
|
|
|
|
t.Run("from config options", func(t *testing.T) {
|
|
|
|
key0 := test.DecodeKey(0)
|
|
|
|
require.NotEmpty(t, key0)
|
|
|
|
|
|
|
|
data0 := crypto.MarshalPublicKey(&key0.PublicKey)
|
|
|
|
hKey0 := hex.EncodeToString(data0)
|
|
|
|
|
|
|
|
owner0, err := refs.NewOwnerID(&key0.PublicKey)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
v := viper.New()
|
|
|
|
v.SetDefault("node.rpc.owners", []string{hKey0})
|
|
|
|
|
|
|
|
owners := fetchOwners(l, v)
|
|
|
|
require.Len(t, owners, 1)
|
|
|
|
require.Contains(t, owners, owner0)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("from environment and config options", func(t *testing.T) {
|
|
|
|
key0 := test.DecodeKey(0)
|
|
|
|
require.NotEmpty(t, key0)
|
|
|
|
|
|
|
|
data0 := crypto.MarshalPublicKey(&key0.PublicKey)
|
|
|
|
hKey0 := hex.EncodeToString(data0)
|
|
|
|
|
|
|
|
owner0, err := refs.NewOwnerID(&key0.PublicKey)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
key1 := test.DecodeKey(1)
|
|
|
|
require.NotEmpty(t, key1)
|
|
|
|
|
|
|
|
owner1, err := refs.NewOwnerID(&key1.PublicKey)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
data1 := crypto.MarshalPublicKey(&key1.PublicKey)
|
|
|
|
hKey1 := hex.EncodeToString(data1)
|
|
|
|
|
|
|
|
require.NoError(t, os.Setenv("NEOFS_NODE_RPC_OWNERS_0", hKey1))
|
|
|
|
|
|
|
|
v := viper.New()
|
|
|
|
v.AutomaticEnv()
|
|
|
|
v.SetEnvPrefix("NeoFS")
|
|
|
|
v.SetConfigType("yaml")
|
|
|
|
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
|
|
|
v.SetDefault("node.rpc.owners", []string{hKey0})
|
|
|
|
|
|
|
|
require.NoError(t, v.ReadConfig(strings.NewReader("")))
|
|
|
|
|
|
|
|
owners := fetchOwners(l, v)
|
|
|
|
|
|
|
|
require.Len(t, owners, 2)
|
|
|
|
require.Contains(t, owners, owner0)
|
|
|
|
require.Contains(t, owners, owner1)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestStateService_DumpConfig(t *testing.T) {
|
|
|
|
cases := []struct {
|
|
|
|
err error
|
|
|
|
ttl uint32
|
|
|
|
name string
|
|
|
|
key *ecdsa.PrivateKey
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
err: nil,
|
|
|
|
name: "allow",
|
|
|
|
key: test.DecodeKey(0),
|
|
|
|
ttl: service.NonForwardingTTL,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "wrong ttl",
|
|
|
|
key: test.DecodeKey(0),
|
|
|
|
ttl: service.SingleForwardingTTL,
|
|
|
|
err: status.Error(codes.InvalidArgument, service.ErrInvalidTTL.Error()),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
key := test.DecodeKey(0)
|
|
|
|
require.NotEmpty(t, key)
|
|
|
|
|
|
|
|
owner, err := refs.NewOwnerID(&key.PublicKey)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
owners := map[refs.OwnerID]struct{}{
|
|
|
|
owner: {},
|
|
|
|
}
|
|
|
|
|
|
|
|
viper.SetDefault("test", true)
|
|
|
|
|
|
|
|
svc := stateService{
|
|
|
|
owners: owners,
|
|
|
|
config: viper.GetViper(),
|
|
|
|
}
|
|
|
|
|
|
|
|
for i := range cases {
|
|
|
|
tt := cases[i]
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
req := new(state.DumpRequest)
|
|
|
|
|
|
|
|
req.SetTTL(tt.ttl)
|
|
|
|
if tt.key != nil {
|
|
|
|
require.NoError(t, requestSignFunc(tt.key, req))
|
|
|
|
}
|
|
|
|
|
|
|
|
res, err := svc.DumpConfig(context.Background(), req)
|
|
|
|
switch tt.err {
|
|
|
|
case nil:
|
|
|
|
require.NoError(t, err, tt.name)
|
|
|
|
require.NotEmpty(t, res)
|
|
|
|
require.NotEmpty(t, res.Config)
|
|
|
|
default:
|
|
|
|
require.EqualError(t, err, tt.err.Error())
|
|
|
|
require.Empty(t, res)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestStateService_DumpVars(t *testing.T) {
|
|
|
|
cases := []struct {
|
|
|
|
err error
|
|
|
|
ttl uint32
|
|
|
|
name string
|
|
|
|
key *ecdsa.PrivateKey
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
err: nil,
|
|
|
|
name: "allow",
|
|
|
|
key: test.DecodeKey(0),
|
|
|
|
ttl: service.NonForwardingTTL,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "wrong ttl",
|
|
|
|
key: test.DecodeKey(0),
|
|
|
|
ttl: service.SingleForwardingTTL,
|
|
|
|
err: status.Error(codes.InvalidArgument, service.ErrInvalidTTL.Error()),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
key := test.DecodeKey(0)
|
|
|
|
require.NotEmpty(t, key)
|
|
|
|
|
|
|
|
owner, err := refs.NewOwnerID(&key.PublicKey)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
owners := map[refs.OwnerID]struct{}{
|
|
|
|
owner: {},
|
|
|
|
}
|
|
|
|
|
|
|
|
svc := stateService{owners: owners}
|
|
|
|
|
|
|
|
expvar.NewString("test1").Set("test1")
|
2020-07-24 13:54:03 +00:00
|
|
|
expvar.NewString("test").Set("test")
|
2020-07-10 14:17:51 +00:00
|
|
|
|
|
|
|
for i := range cases {
|
|
|
|
tt := cases[i]
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
req := new(state.DumpVarsRequest)
|
|
|
|
|
|
|
|
req.SetTTL(tt.ttl)
|
|
|
|
if tt.key != nil {
|
|
|
|
require.NoError(t, requestSignFunc(tt.key, req))
|
|
|
|
}
|
|
|
|
|
|
|
|
res, err := svc.DumpVars(nil, req)
|
|
|
|
switch tt.err {
|
|
|
|
case nil:
|
|
|
|
require.NoError(t, err, tt.name)
|
|
|
|
require.NotEmpty(t, res)
|
|
|
|
require.NotEmpty(t, res.Variables)
|
|
|
|
|
|
|
|
dump := make(map[string]interface{})
|
|
|
|
require.NoError(t, json.Unmarshal(res.Variables, &dump))
|
|
|
|
|
|
|
|
require.Contains(t, dump, "test1")
|
|
|
|
require.Equal(t, dump["test1"], "test1")
|
|
|
|
|
2020-07-24 13:54:03 +00:00
|
|
|
require.Contains(t, dump, "test")
|
|
|
|
require.Equal(t, dump["test"], "test")
|
2020-07-10 14:17:51 +00:00
|
|
|
default:
|
|
|
|
require.EqualError(t, err, tt.err.Error())
|
|
|
|
require.Empty(t, res)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|