package main import ( "context" "crypto/ecdsa" "errors" "testing" "github.com/nspcc-dev/neofs-api-go/v2/refs" "github.com/nspcc-dev/neofs-api-go/v2/session" sessionGRPC "github.com/nspcc-dev/neofs-api-go/v2/session/grpc" "github.com/nspcc-dev/neofs-api-go/v2/signature" "github.com/nspcc-dev/neofs-crypto/test" "github.com/stretchr/testify/require" "google.golang.org/grpc" ) type testGRPCClient struct { server *testGRPCServer } type testGRPCServer struct { key *ecdsa.PrivateKey resp *session.CreateResponse err error } func (s *testGRPCClient) Create(ctx context.Context, in *sessionGRPC.CreateRequest, opts ...grpc.CallOption) (*sessionGRPC.CreateResponse, error) { return s.server.Create(ctx, in) } func (s *testGRPCServer) Create(_ context.Context, req *sessionGRPC.CreateRequest) (*sessionGRPC.CreateResponse, error) { if s.err != nil { return nil, s.err } // verify request structure if err := signature.VerifyServiceMessage( session.CreateRequestFromGRPCMessage(req), ); err != nil { return nil, err } // sign response structure if err := signature.SignServiceMessage(s.key, s.resp); err != nil { return nil, err } return session.CreateResponseToGRPCMessage(s.resp), nil } func testRequest() *session.CreateRequest { ownerID := new(refs.OwnerID) ownerID.SetValue([]byte{1, 2, 3}) body := new(session.CreateRequestBody) body.SetOwnerID(ownerID) meta := new(session.RequestMetaHeader) meta.SetTTL(1) req := new(session.CreateRequest) req.SetBody(body) req.SetMetaHeader(meta) return req } func testResponse() *session.CreateResponse { body := new(session.CreateResponseBody) body.SetID([]byte{1, 2, 3}) meta := new(session.ResponseMetaHeader) meta.SetTTL(1) resp := new(session.CreateResponse) resp.SetBody(body) resp.SetMetaHeader(meta) return resp } func TestGRPCClient(t *testing.T) { ctx := context.TODO() cliKey := test.DecodeKey(0) srvKey := test.DecodeKey(1) t.Run("gRPC server error", func(t *testing.T) { srvErr := errors.New("test server error") srv := &testGRPCServer{ err: srvErr, } cli := &testGRPCClient{ server: srv, } c, err := session.New(session.WithGRPCServiceClient(cli)) require.NoError(t, err) resp, err := c.Create(ctx, new(session.CreateRequest)) require.True(t, errors.Is(err, srvErr)) require.Nil(t, resp) }) t.Run("invalid request structure", func(t *testing.T) { req := testRequest() require.Error(t, signature.VerifyServiceMessage(req)) c, err := session.New( session.WithGRPCServiceClient( &testGRPCClient{ server: new(testGRPCServer), }, ), ) require.NoError(t, err) resp, err := c.Create(ctx, req) require.Error(t, err) require.Nil(t, resp) }) t.Run("correct response", func(t *testing.T) { req := testRequest() require.NoError(t, signature.SignServiceMessage(cliKey, req)) resp := testResponse() { // w/o this require.Equal fails due to nil and []T{} difference meta := new(session.ResponseMetaHeader) meta.SetXHeaders([]*session.XHeader{}) resp.SetMetaHeader(meta) } c, err := session.New( session.WithGRPCServiceClient( &testGRPCClient{ server: &testGRPCServer{ key: srvKey, resp: resp, }, }, ), ) require.NoError(t, err) r, err := c.Create(ctx, req) require.NoError(t, err) require.NoError(t, signature.VerifyServiceMessage(r)) require.Equal(t, resp.GetBody(), r.GetBody()) require.Equal(t, resp.GetMetaHeader(), r.GetMetaHeader()) }) }