Skip to content

Commit

Permalink
Start and Stop smeshing via GRPC uses supervisor
Browse files Browse the repository at this point in the history
  • Loading branch information
fasmat committed Oct 10, 2023
1 parent 080c08b commit fb39c0b
Show file tree
Hide file tree
Showing 6 changed files with 216 additions and 87 deletions.
141 changes: 82 additions & 59 deletions api/grpcserver/grpcserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -432,38 +432,6 @@ func newChallenge(sequence uint64, prevAtxID, posAtxID types.ATXID, epoch types.
}
}

// SmeshingAPIMock is a mock for Smeshing API.
type SmeshingAPIMock struct {
UpdatePoETErr error
}

func (s *SmeshingAPIMock) UpdatePoETServers(context.Context, []string) error {
return s.UpdatePoETErr
}

func (*SmeshingAPIMock) Smeshing() bool {
return false
}

func (*SmeshingAPIMock) StartSmeshing(types.Address, activation.PostSetupOpts) error {
return nil
}

func (*SmeshingAPIMock) StopSmeshing(bool) error {
return nil
}

func (*SmeshingAPIMock) SmesherID() types.NodeID {
return signer.NodeID()
}

func (*SmeshingAPIMock) Coinbase() types.Address {
return addr1
}

func (*SmeshingAPIMock) SetCoinbase(coinbase types.Address) {
}

func marshalProto(t *testing.T, msg proto.Message) []byte {
buf, err := protojson.Marshal(msg)
require.NoError(t, err)
Expand Down Expand Up @@ -904,42 +872,67 @@ func TestGlobalStateService(t *testing.T) {
}
}

func TestSmesherService(t *testing.T) {
ctrl := gomock.NewController(t)
type smesherServiceConn struct {
pb.SmesherServiceClient

postProvider *MockpostSetupProvider
smeshingProvider *activation.MockSmeshingProvider
postSupervisor *MockpostSupervisor
}

func setupSmesherService(t *testing.T) (*smesherServiceConn, context.Context) {
ctrl, mockCtx := gomock.WithContext(context.Background(), t)
postProvider := NewMockpostSetupProvider(ctrl)
postProvider.EXPECT().Config().Return(activation.DefaultPostConfig()).AnyTimes()
postProvider.EXPECT().Status().Return(&activation.PostSetupStatus{}).AnyTimes()
postProvider.EXPECT().Providers().Return(nil, nil).AnyTimes()
smeshingAPI := &SmeshingAPIMock{}
svc := NewSmesherService(postProvider, smeshingAPI, 10*time.Millisecond, activation.DefaultPostSetupOpts())
smeshingProvider := activation.NewMockSmeshingProvider(ctrl)
postSupervisor := NewMockpostSupervisor(ctrl)
svc := NewSmesherService(postProvider, smeshingProvider, postSupervisor, 10*time.Millisecond, activation.DefaultPostSetupOpts())
cfg, cleanup := launchServer(t, svc)
t.Cleanup(cleanup)

ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
conn := dialGrpc(ctx, t, cfg.PublicListener)
c := pb.NewSmesherServiceClient(conn)
client := pb.NewSmesherServiceClient(conn)

return &smesherServiceConn{
SmesherServiceClient: client,

postProvider: postProvider,
smeshingProvider: smeshingProvider,
postSupervisor: postSupervisor,
}, mockCtx
}

func TestSmesherService(t *testing.T) {
t.Run("IsSmeshing", func(t *testing.T) {
res, err := c.IsSmeshing(context.Background(), &emptypb.Empty{})
t.Parallel()
c, ctx := setupSmesherService(t)
c.smeshingProvider.EXPECT().Smeshing().Return(false)
res, err := c.IsSmeshing(ctx, &emptypb.Empty{})
require.NoError(t, err)
require.False(t, res.IsSmeshing, "expected IsSmeshing to be false")
})

t.Run("StartSmeshingMissingArgs", func(t *testing.T) {
_, err := c.StartSmeshing(context.Background(), &pb.StartSmeshingRequest{})
t.Parallel()
c, ctx := setupSmesherService(t)
_, err := c.StartSmeshing(ctx, &pb.StartSmeshingRequest{})
require.Equal(t, codes.InvalidArgument, status.Code(err))
})

t.Run("StartSmeshing", func(t *testing.T) {
t.Parallel()
opts := &pb.PostSetupOpts{}
opts.DataDir = t.TempDir()
opts.NumUnits = 1
opts.MaxFileSize = 1024

coinbase := &pb.AccountId{Address: addr1.String()}

res, err := c.StartSmeshing(context.Background(), &pb.StartSmeshingRequest{
c, ctx := setupSmesherService(t)
c.smeshingProvider.EXPECT().StartSmeshing(gomock.Any(), gomock.Any()).Return(nil)
c.postSupervisor.EXPECT().Start().Return(nil)
res, err := c.StartSmeshing(ctx, &pb.StartSmeshingRequest{
Opts: opts,
Coinbase: coinbase,
})
Expand All @@ -948,62 +941,87 @@ func TestSmesherService(t *testing.T) {
})

t.Run("StopSmeshing", func(t *testing.T) {
res, err := c.StopSmeshing(context.Background(), &pb.StopSmeshingRequest{})
t.Parallel()
c, ctx := setupSmesherService(t)
c.smeshingProvider.EXPECT().StopSmeshing(gomock.Any()).Return(nil)
c.postSupervisor.EXPECT().Stop().Return(nil)
res, err := c.StopSmeshing(ctx, &pb.StopSmeshingRequest{})
require.NoError(t, err)
require.Equal(t, int32(code.Code_OK), res.Status.Code)
})

t.Run("SmesherID", func(t *testing.T) {
res, err := c.SmesherID(context.Background(), &emptypb.Empty{})
require.NoError(t, err)
t.Parallel()
c, ctx := setupSmesherService(t)
c.smeshingProvider.EXPECT().SmesherID().Return(signer.NodeID())
res, err := c.SmesherID(ctx, &emptypb.Empty{})
require.NoError(t, err)
require.Equal(t, signer.NodeID().Bytes(), res.PublicKey)
})

t.Run("SetCoinbaseMissingArgs", func(t *testing.T) {
_, err := c.SetCoinbase(context.Background(), &pb.SetCoinbaseRequest{})
t.Parallel()
c, ctx := setupSmesherService(t)
_, err := c.SetCoinbase(ctx, &pb.SetCoinbaseRequest{})
require.Error(t, err)
statusCode := status.Code(err)
require.Equal(t, codes.InvalidArgument, statusCode)
})

t.Run("SetCoinbase", func(t *testing.T) {
res, err := c.SetCoinbase(context.Background(), &pb.SetCoinbaseRequest{
t.Parallel()
c, ctx := setupSmesherService(t)
c.smeshingProvider.EXPECT().SetCoinbase(addr1)
res, err := c.SetCoinbase(ctx, &pb.SetCoinbaseRequest{
Id: &pb.AccountId{Address: addr1.String()},
})
require.NoError(t, err)
require.Equal(t, int32(code.Code_OK), res.Status.Code)
})

t.Run("Coinbase", func(t *testing.T) {
res, err := c.Coinbase(context.Background(), &emptypb.Empty{})
t.Parallel()
c, ctx := setupSmesherService(t)
c.smeshingProvider.EXPECT().Coinbase().Return(addr1)
res, err := c.Coinbase(ctx, &emptypb.Empty{})
require.NoError(t, err)
addr, err := types.StringToAddress(res.AccountId.Address)
require.NoError(t, err)
require.Equal(t, addr1.Bytes(), addr.Bytes())
require.Equal(t, addr1, addr)
})

t.Run("MinGas", func(t *testing.T) {
_, err := c.MinGas(context.Background(), &emptypb.Empty{})
t.Parallel()
c, ctx := setupSmesherService(t)
_, err := c.MinGas(ctx, &emptypb.Empty{})
require.Error(t, err)
statusCode := status.Code(err)
require.Equal(t, codes.Unimplemented, statusCode)
})

t.Run("SetMinGas", func(t *testing.T) {
_, err := c.SetMinGas(context.Background(), &pb.SetMinGasRequest{})
t.Parallel()
c, ctx := setupSmesherService(t)
_, err := c.SetMinGas(ctx, &pb.SetMinGasRequest{})
require.Error(t, err)
statusCode := status.Code(err)
require.Equal(t, codes.Unimplemented, statusCode)
})

t.Run("PostSetupComputeProviders", func(t *testing.T) {
_, err := c.PostSetupProviders(context.Background(), &pb.PostSetupProvidersRequest{Benchmark: false})
t.Parallel()
c, ctx := setupSmesherService(t)
c.postProvider.EXPECT().Providers().Return(nil, nil)
_, err := c.PostSetupProviders(ctx, &pb.PostSetupProvidersRequest{Benchmark: false})
require.NoError(t, err)
})

t.Run("PostSetupStatusStream", func(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
t.Parallel()
c, ctx := setupSmesherService(t)
c.postProvider.EXPECT().Status().Return(&activation.PostSetupStatus{}).AnyTimes()

ctx, cancel := context.WithCancel(ctx)
defer cancel()
stream, err := c.PostSetupStatusStream(ctx, &emptypb.Empty{})
require.NoError(t, err)
Expand All @@ -1018,18 +1036,23 @@ func TestSmesherService(t *testing.T) {
_, err = stream.Recv()
require.ErrorContains(t, err, context.Canceled.Error())
})

t.Run("UpdatePoetServer", func(t *testing.T) {
smeshingAPI.UpdatePoETErr = nil
res, err := c.UpdatePoetServers(context.Background(), &pb.UpdatePoetServersRequest{Urls: []string{"test"}})
t.Parallel()
c, ctx := setupSmesherService(t)
c.smeshingProvider.EXPECT().UpdatePoETServers(gomock.Any(), gomock.Any()).Return(nil)
res, err := c.UpdatePoetServers(ctx, &pb.UpdatePoetServersRequest{Urls: []string{"test"}})
require.NoError(t, err)
require.EqualValues(t, res.Status.Code, code.Code_OK)
})
t.Run("UpdatePoetServerUnavailable", func(t *testing.T) {
smeshingAPI.UpdatePoETErr = activation.ErrPoetServiceUnstable
t.Parallel()
c, ctx := setupSmesherService(t)
c.smeshingProvider.EXPECT().UpdatePoETServers(gomock.Any(), gomock.Any()).Return(activation.ErrPoetServiceUnstable)
urls := []string{"test"}
res, err := c.UpdatePoetServers(context.Background(), &pb.UpdatePoetServersRequest{Urls: urls})
res, err := c.UpdatePoetServers(ctx, &pb.UpdatePoetServersRequest{Urls: urls})
require.Nil(t, res)
require.ErrorIs(t, err, status.Errorf(codes.Unavailable, "can't reach poet service (%v). retry later", smeshingAPI.UpdatePoETErr))
require.ErrorIs(t, err, status.Errorf(codes.Unavailable, "can't reach poet service (%v). retry later", activation.ErrPoetServiceUnstable))
})
}

Expand Down
5 changes: 5 additions & 0 deletions api/grpcserver/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ type postSetupProvider interface {
Config() activation.PostConfig
}

type postSupervisor interface {
Start() error
Stop() error
}

// peerCounter is an api to get amount of connected peers.
type peerCounter interface {
PeerCount() uint64
Expand Down
99 changes: 99 additions & 0 deletions api/grpcserver/mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit fb39c0b

Please sign in to comment.