diff --git a/v2/session/test/client_test.go b/v2/session/test/client_test.go new file mode 100644 index 00000000..156bc8e8 --- /dev/null +++ b/v2/session/test/client_test.go @@ -0,0 +1,160 @@ +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/service" + "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(service.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(service.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(service.ResponseMetaHeader) + meta.SetXHeaders([]*service.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()) + }) +}