Skip to content

Commit

Permalink
[ioctl] Refactor bcblock command in new ioctl (#3360)
Browse files Browse the repository at this point in the history
* [ioctl] refactor bcblock command in new ioctl
LuckyPigeon authored May 12, 2022

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 76e02c7 commit 9844fac
Showing 2 changed files with 238 additions and 222 deletions.
212 changes: 105 additions & 107 deletions ioctl/newcmd/bc/bcblock.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2019 IoTeX
// Copyright (c) 2022 IoTeX
// This is an alpha (internal) release and is not suitable for production. This source code is provided 'as is' and no
// warranties are given as to title or non-infringement, merchantability or fitness for purpose and, to the extent
// permitted by law, all liability for your use of the code is disclaimed. This source code is governed by Apache
@@ -11,19 +11,19 @@ import (
"fmt"
"strconv"

"github.com/iotexproject/iotex-core/ioctl"
"google.golang.org/grpc/status"

"github.com/grpc-ecosystem/go-grpc-middleware/util/metautils"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"google.golang.org/grpc/status"

"github.com/iotexproject/iotex-proto/golang/iotexapi"
"github.com/iotexproject/iotex-proto/golang/iotextypes"

"github.com/iotexproject/go-pkgs/hash"
"github.com/iotexproject/iotex-core/ioctl"
"github.com/iotexproject/iotex-core/ioctl/config"
"github.com/iotexproject/iotex-core/ioctl/output"
"github.com/iotexproject/iotex-core/ioctl/util"
"github.com/iotexproject/iotex-core/ioctl/validator"
"github.com/iotexproject/iotex-proto/golang/iotexapi"
"github.com/iotexproject/iotex-proto/golang/iotextypes"
)

// Multi-language support
@@ -43,88 +43,82 @@ var (
)

// NewBCBlockCmd represents the bc block command
func NewBCBlockCmd(client ioctl.Client) *cobra.Command {
bcBlockCmdUse, _ := client.SelectTranslation(_bcBlockCmdUses)
bcBlockCmdShort, _ := client.SelectTranslation(_bcBlockCmdShorts)
func NewBCBlockCmd(c ioctl.Client) *cobra.Command {
bcBlockCmdUse, _ := c.SelectTranslation(_bcBlockCmdUses)
bcBlockCmdShort, _ := c.SelectTranslation(_bcBlockCmdShorts)
flagVerboseUsage, _ := c.SelectTranslation(_flagVerboseUsages)

var verbose bool
var endpoint string
var insecure bool
var (
verbose bool
endpoint string
insecure bool
)

cmd := &cobra.Command{
Use: bcBlockCmdUse,
Short: bcBlockCmdShort,
Args: cobra.MaximumNArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
cmd.SilenceUsage = true
var height uint64
var err error
isHeight := true

apiServiceClient, err := client.APIServiceClient(ioctl.APIServiceConfig{
var (
err error
request *iotexapi.GetBlockMetasRequest
blockMeta *iotextypes.BlockMeta
blocksInfo []*iotexapi.BlockInfo
)

apiServiceClient, err := c.APIServiceClient(ioctl.APIServiceConfig{
Endpoint: endpoint,
Insecure: insecure,
})
if err != nil {
return err
}

if len(args) != 0 {
height, err = strconv.ParseUint(args[0], 10, 64)
if err != nil {
isHeight = false
} else if err = validator.ValidatePositiveNumber(int64(height)); err != nil {
return output.NewError(output.ValidationError, "invalid height", err)
}
request, err = parseArg(c, args[0])
} else {
chainMetaResponse, err := apiServiceClient.GetChainMeta(context.Background(), &iotexapi.GetChainMetaRequest{})
if err != nil {
return err
}
height = chainMetaResponse.ChainMeta.Height
request, err = parseArg(c, "")
}
var blockMeta *iotextypes.BlockMeta
var blocksInfo []*iotexapi.BlockInfo
if isHeight {
blockMeta, err = getBlockMetaByHeight(&apiServiceClient, height)
} else {
blockMeta, err = getBlockMetaByHash(&apiServiceClient, args[0])
if err != nil {
return err
}

blockMeta, err = getBlockMeta(&apiServiceClient, request)
if err != nil {
return output.NewError(0, "failed to get block meta", err)
return errors.Wrap(err, "failed to get block meta")
}
blockInfoMessage := blockMessage{Node: config.ReadConfig.Endpoint, Block: blockMeta, Actions: nil}
message := blockMessage{Node: c.Config().Endpoint, Block: blockMeta, Actions: nil}
if verbose {
blocksInfo, err = getActionInfoWithinBlock(&apiServiceClient, blockMeta.Height, uint64(blockMeta.NumActions))
if err != nil {
return output.NewError(0, "failed to get actions info", err)
return errors.Wrap(err, "failed to get actions info")
}
for _, ele := range blocksInfo {
for _, item := range ele.Block.Body.Actions {
for i, item := range ele.Block.Body.Actions {
actionInfo := actionInfo{
Version: item.Core.Version,
Nonce: item.Core.Nonce,
GasLimit: item.Core.GasLimit,
GasPrice: item.Core.GasPrice,
SenderPubKey: item.SenderPubKey,
Signature: item.Signature,
Version: item.Core.Version,
Nonce: item.Core.Nonce,
GasLimit: item.Core.GasLimit,
GasPrice: item.Core.GasPrice,
SenderPubKey: item.SenderPubKey,
Signature: item.Signature,
Status: ele.Receipts[i].Status,
BlkHeight: ele.Receipts[i].BlkHeight,
ActHash: hash.Hash256b(ele.Receipts[i].ActHash),
GasConsumed: ele.Receipts[i].GasConsumed,
ContractAddress: ele.Receipts[i].ContractAddress,
Logs: ele.Receipts[i].Logs,
}
blockInfoMessage.Actions = append(blockInfoMessage.Actions, actionInfo)
message.Actions = append(message.Actions, actionInfo)
}
}
}
fmt.Println(blockInfoMessage.String())
cmd.Println(fmt.Sprintf("Blockchain Node: %s\n%s\n%s", message.Node, JSONString(message.Block), JSONString(message.Actions)))
return nil
},
}

flagVerboseUsage, _ := client.SelectTranslation(_flagVerboseUsages)
flagEndpointUsage, _ := client.SelectTranslation(_flagEndpointUsages)
flagInsecureUsage, _ := client.SelectTranslation(_flagInsecureUsages)

cmd.PersistentFlags().BoolVar(&verbose, "verbose", false, flagVerboseUsage)
cmd.PersistentFlags().StringVar(&endpoint, "endpoint", client.Config().Endpoint, flagEndpointUsage)
cmd.PersistentFlags().BoolVar(&insecure, "insecure", !client.Config().SecureConnect, flagInsecureUsage)

return cmd
}
@@ -136,20 +130,18 @@ type blockMessage struct {
}

type actionInfo struct {
Version uint32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"`
Nonce uint64 `protobuf:"varint,2,opt,name=nonce,proto3" json:"nonce,omitempty"`
GasLimit uint64 `protobuf:"varint,3,opt,name=gasLimit,proto3" json:"gasLimit,omitempty"`
GasPrice string `protobuf:"bytes,4,opt,name=gasPrice,proto3" json:"gasPrice,omitempty"`
SenderPubKey []byte `protobuf:"bytes,2,opt,name=senderPubKey,proto3" json:"senderPubKey,omitempty"`
Signature []byte `protobuf:"bytes,3,opt,name=signature,proto3" json:"signature,omitempty"`
}

func (m *blockMessage) String() string {
if output.Format == "" {
message := fmt.Sprintf("Blockchain Node: %s\n%s\n%s", m.Node, output.JSONString(m.Block), output.JSONString(m.Actions))
return message
}
return output.FormatString(output.Result, m)
Version uint32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"`
Nonce uint64 `protobuf:"varint,2,opt,name=nonce,proto3" json:"nonce,omitempty"`
GasLimit uint64 `protobuf:"varint,3,opt,name=gasLimit,proto3" json:"gasLimit,omitempty"`
GasPrice string `protobuf:"bytes,4,opt,name=gasPrice,proto3" json:"gasPrice,omitempty"`
SenderPubKey []byte `protobuf:"bytes,2,opt,name=senderPubKey,proto3" json:"senderPubKey,omitempty"`
Signature []byte `protobuf:"bytes,3,opt,name=signature,proto3" json:"signature,omitempty"`
Status uint64 `protobuf:"varint,4,opt,name=status,proto3" json:"status,omitempty"`
BlkHeight uint64 `protobuf:"varint,5,opt,name=blkheight,proto3" json:"blkheight,omitempty"`
ActHash hash.Hash256 `protobuf:"bytes,4,opt,name=acthash,proto3" json:"acthash,omitempty"`
GasConsumed uint64 `protobuf:"varint,6,opt,name=gasconsumed,proto3" json:"gasconsumed,omitempty"`
ContractAddress string `protobuf:"bytes,5,opt,name=contractaddress,proto3" json:"contractaddress,omitempty"`
Logs []*iotextypes.Log `protobuf:"bytes,6,opt,name=logs,proto3" json:"logs,omitempty"`
}

// getActionInfoByBlock gets action info by block hash with start index and action count
@@ -166,27 +158,19 @@ func getActionInfoWithinBlock(cli *iotexapi.APIServiceClient, height uint64, cou
if err != nil {
sta, ok := status.FromError(err)
if ok {
return nil, output.NewError(output.APIError, sta.Message(), nil)
return nil, errors.New(sta.Message())
}
return nil, output.NewError(output.NetworkError, "failed to invoke GetRawBlocks api", err)
return nil, errors.Wrap(err, "failed to invoke GetRawBlocks api")
}
if len(response.Blocks) == 0 {
return nil, output.NewError(output.APIError, "no actions returned", err)
return nil, errors.New("no actions returned")
}
return response.Blocks, nil

}

// getBlockMetaByHeight gets block metadata by height
func getBlockMetaByHeight(cli *iotexapi.APIServiceClient, height uint64) (*iotextypes.BlockMeta, error) {
request := &iotexapi.GetBlockMetasRequest{
Lookup: &iotexapi.GetBlockMetasRequest_ByIndex{
ByIndex: &iotexapi.GetBlockMetasByIndexRequest{
Start: height,
Count: 1,
},
},
}
// getBlockMeta gets block metadata
func getBlockMeta(cli *iotexapi.APIServiceClient, request *iotexapi.GetBlockMetasRequest) (*iotextypes.BlockMeta, error) {
ctx := context.Background()

jwtMD, err := util.JwtAuth()
@@ -198,40 +182,54 @@ func getBlockMetaByHeight(cli *iotexapi.APIServiceClient, height uint64) (*iotex
if err != nil {
sta, ok := status.FromError(err)
if ok {
return nil, output.NewError(output.APIError, sta.Message(), nil)
return nil, errors.New(sta.Message())
}
return nil, output.NewError(output.NetworkError, "failed to invoke GetBlockMetas api", err)
return nil, errors.Wrap(err, "failed to invoke GetBlockMetas api")
}
if len(response.BlkMetas) == 0 {
return nil, output.NewError(output.APIError, "no block returned", err)
return nil, errors.New("no block returned")
}
return response.BlkMetas[0], nil
}

// getBlockMetaByHash gets block metadata by hash
func getBlockMetaByHash(cli *iotexapi.APIServiceClient, hash string) (*iotextypes.BlockMeta, error) {
request := &iotexapi.GetBlockMetasRequest{
Lookup: &iotexapi.GetBlockMetasRequest_ByHash{
ByHash: &iotexapi.GetBlockMetaByHashRequest{BlkHash: hash},
},
}
ctx := context.Background()

jwtMD, err := util.JwtAuth()
if err == nil {
ctx = metautils.NiceMD(jwtMD).ToOutgoing(ctx)
}

response, err := (*cli).GetBlockMetas(ctx, request)
if err != nil {
sta, ok := status.FromError(err)
if ok {
return nil, output.NewError(output.APIError, sta.Message(), nil)
// parseArg parse argument and returns GetBlockMetasRequest
func parseArg(c ioctl.Client, arg string) (*iotexapi.GetBlockMetasRequest, error) {
var (
height uint64
err error
)
if arg != "" {
height, err = strconv.ParseUint(arg, 10, 64)
if err != nil {
return &iotexapi.GetBlockMetasRequest{
Lookup: &iotexapi.GetBlockMetasRequest_ByHash{
ByHash: &iotexapi.GetBlockMetaByHashRequest{BlkHash: arg},
},
}, nil
}
return nil, output.NewError(output.NetworkError, "failed to invoke GetBlockMetas api", err)
if err = validator.ValidatePositiveNumber(int64(height)); err != nil {
return nil, errors.Wrap(err, "invalid height")
}
return &iotexapi.GetBlockMetasRequest{
Lookup: &iotexapi.GetBlockMetasRequest_ByIndex{
ByIndex: &iotexapi.GetBlockMetasByIndexRequest{
Start: height,
Count: 1,
},
},
}, nil
}
if len(response.BlkMetas) == 0 {
return nil, output.NewError(output.APIError, "no block returned", err)
chainMeta, err := GetChainMeta(c)
if err != nil {
return nil, err
}
return response.BlkMetas[0], nil
height = chainMeta.Height
return &iotexapi.GetBlockMetasRequest{
Lookup: &iotexapi.GetBlockMetasRequest_ByIndex{
ByIndex: &iotexapi.GetBlockMetasByIndexRequest{
Start: height,
Count: 1,
},
},
}, nil
}
248 changes: 133 additions & 115 deletions ioctl/newcmd/bc/bcblock_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2019 IoTeX
// Copyright (c) 2022 IoTeX
// This is an alpha (internal) release and is not suitable for production. This source code is provided 'as is' and no
// warranties are given as to title or non-infringement, merchantability or fitness for purpose and, to the extent
// permitted by law, all liability for your use of the code is disclaimed. This source code is governed by Apache
@@ -10,22 +10,21 @@ import (
"testing"

"github.com/golang/mock/gomock"
"github.com/iotexproject/iotex-proto/golang/iotexapi"
"github.com/iotexproject/iotex-proto/golang/iotexapi/mock_iotexapi"
"github.com/iotexproject/iotex-proto/golang/iotextypes"
"github.com/pkg/errors"
"github.com/stretchr/testify/require"

"github.com/iotexproject/iotex-core/ioctl/config"
"github.com/iotexproject/iotex-core/ioctl/output"
"github.com/iotexproject/iotex-core/ioctl/util"
"github.com/iotexproject/iotex-core/test/mock/mock_ioctlclient"
"github.com/iotexproject/iotex-proto/golang/iotexapi"
"github.com/iotexproject/iotex-proto/golang/iotexapi/mock_iotexapi"
"github.com/iotexproject/iotex-proto/golang/iotextypes"
)

// test for bc info command
func TestNewBCBlockCmd(t *testing.T) {
require := require.New(t)
ctrl := gomock.NewController(t)

client := mock_ioctlclient.NewMockClient(ctrl)
cfg := config.Config{}
apiServiceClient := mock_iotexapi.NewMockAPIServiceClient(ctrl)
@@ -38,130 +37,149 @@ func TestNewBCBlockCmd(t *testing.T) {
}
blockMetaResponse := &iotexapi.GetBlockMetasResponse{BlkMetas: blockMeta}

client.EXPECT().SelectTranslation(gomock.Any()).Return("", config.English).Times(5)
client.EXPECT().Config().Return(cfg).Times(2)
client.EXPECT().APIServiceClient(gomock.Any()).Return(apiServiceClient, nil).Times(3)
apiServiceClient.EXPECT().GetChainMeta(gomock.Any(), gomock.Any()).Return(chainMetaResponse, nil).Times(1)
apiServiceClient.EXPECT().GetBlockMetas(gomock.Any(), gomock.Any()).Return(blockMetaResponse, nil).Times(3)

cmd := NewBCBlockCmd(client)
_, err := util.ExecuteCmd(cmd)
require.NoError(t, err)

_, err = util.ExecuteCmd(cmd, "1")
require.NoError(t, err)

_, err = util.ExecuteCmd(cmd, "abcd")
require.NoError(t, err)
client.EXPECT().SelectTranslation(gomock.Any()).Return("", config.English).Times(35)
client.EXPECT().Config().Return(cfg).Times(20)

client.EXPECT().SelectTranslation(gomock.Any()).Return("", config.English).Times(5)
client.EXPECT().Config().Return(cfg).Times(2)
t.Run("failed to dial grpc connection", func(t *testing.T) {
expectedErr := errors.New("failed to dial grpc connection")
client.EXPECT().APIServiceClient(gomock.Any()).Return(nil, expectedErr).Times(1)

expectedError := errors.New("failed to dial grpc connection")
client.EXPECT().APIServiceClient(gomock.Any()).Return(nil, expectedError).Times(1)
cmd := NewBCBlockCmd(client)
_, err := util.ExecuteCmd(cmd)
require.Error(err)
require.Equal(expectedErr, err)
})

cmd = NewBCBlockCmd(client)
_, err = util.ExecuteCmd(cmd)
require.Error(t, err)
require.Equal(t, expectedError, err)
client.EXPECT().APIServiceClient(gomock.Any()).Return(apiServiceClient, nil).Times(16)

client.EXPECT().SelectTranslation(gomock.Any()).Return("", config.English).Times(5)
client.EXPECT().Config().Return(cfg).Times(2)
client.EXPECT().APIServiceClient(gomock.Any()).Return(apiServiceClient, nil).Times(1)
t.Run("failed to get chain meta", func(t *testing.T) {
expectedErr := errors.New("failed to get chain meta")
apiServiceClient.EXPECT().GetChainMeta(gomock.Any(), gomock.Any()).Return(nil, expectedErr).Times(1)

expectedErr := output.ErrorMessage{
Code: 5,
Info: "invalid height: invalid number that is not positive",
}
err = output.ErrorMessage{}

cmd = NewBCBlockCmd(client)
_, err = util.ExecuteCmd(cmd, "0")
require.Error(t, err)
require.Equal(t, expectedErr, err)
cmd := NewBCBlockCmd(client)
_, err := util.ExecuteCmd(cmd)
require.Error(err)
require.Contains(err.Error(), expectedErr.Error())
})

client.EXPECT().SelectTranslation(gomock.Any()).Return("", config.English).Times(5)
client.EXPECT().Config().Return(cfg).Times(2)
client.EXPECT().APIServiceClient(gomock.Any()).Return(apiServiceClient, nil).Times(1)
expectedError = errors.New("failed to get chain meta")
apiServiceClient.EXPECT().GetChainMeta(gomock.Any(), gomock.Any()).Return(nil, expectedError).Times(1)
t.Run("failed to invoke GetBlockMetas api", func(t *testing.T) {
expectedErr := errors.New("failed to invoke GetBlockMetas api")
apiServiceClient.EXPECT().GetChainMeta(gomock.Any(), gomock.Any()).Return(chainMetaResponse, nil).Times(1)
apiServiceClient.EXPECT().GetBlockMetas(gomock.Any(), gomock.Any()).Return(nil, expectedErr).Times(1)

cmd = NewBCBlockCmd(client)
_, err = util.ExecuteCmd(cmd)
require.Error(t, err)
require.Equal(t, expectedError, err)
cmd := NewBCBlockCmd(client)
_, err := util.ExecuteCmd(cmd)
require.Error(err)
require.Contains(err.Error(), expectedErr.Error())

client.EXPECT().SelectTranslation(gomock.Any()).Return("", config.English).Times(5)
client.EXPECT().Config().Return(cfg).Times(2)
client.EXPECT().APIServiceClient(gomock.Any()).Return(apiServiceClient, nil).Times(1)
})

apiServiceClient.EXPECT().GetChainMeta(gomock.Any(), gomock.Any()).Return(chainMetaResponse, nil).Times(1)
apiServiceClient.EXPECT().GetBlockMetas(gomock.Any(), gomock.Any()).Return(blockMetaResponse, nil).Times(1)
expectedError = errors.New("failed to get raw block")
apiServiceClient.EXPECT().GetRawBlocks(gomock.Any(), gomock.Any()).Return(nil, expectedError).Times(1)
expectedErr = output.ErrorMessage{
Code: 3,
Info: "failed to get actions info: failed to invoke GetRawBlocks api: failed to get raw block",
}

cmd = NewBCBlockCmd(client)
_, err = util.ExecuteCmd(cmd, "--verbose")
require.Error(t, err)
require.Equal(t, expectedErr, err)

client.EXPECT().SelectTranslation(gomock.Any()).Return("", config.English).Times(5)
client.EXPECT().Config().Return(cfg).Times(2)
client.EXPECT().APIServiceClient(gomock.Any()).Return(apiServiceClient, nil).Times(1)
apiServiceClient.EXPECT().GetBlockMetas(gomock.Any(), gomock.Any()).Return(blockMetaResponse, nil).Times(3)

apiServiceClient.EXPECT().GetChainMeta(gomock.Any(), gomock.Any()).Return(chainMetaResponse, nil).Times(1)
apiServiceClient.EXPECT().GetBlockMetas(gomock.Any(), gomock.Any()).Return(blockMetaResponse, nil).Times(1)
blockInfo := []*iotexapi.BlockInfo{
{
Block: &iotextypes.Block{
Body: &iotextypes.BlockBody{
Actions: []*iotextypes.Action{
&iotextypes.Action{
Core: &iotextypes.ActionCore{
Version: 1,
Nonce: 2,
GasLimit: 3,
GasPrice: "4",
t.Run("get blockchain block", func(t *testing.T) {
expectedValue := "Blockchain Node: \n{\n \"hash\": \"abcd\",\n \"height\": 1\n}\nnull\n"

cmd := NewBCBlockCmd(client)
result, err := util.ExecuteCmd(cmd)
require.NoError(err)
require.Equal(expectedValue, result)
})

t.Run("get block meta by height", func(t *testing.T) {
expectedValue := "\"height\": 1"

cmd := NewBCBlockCmd(client)
result, err := util.ExecuteCmd(cmd, "1")
require.NoError(err)
require.Contains(result, expectedValue)
})

t.Run("get block meta by hash", func(t *testing.T) {
expectedValue := "\"hash\": \"abcd\""

cmd := NewBCBlockCmd(client)
result, err := util.ExecuteCmd(cmd, "abcd")
require.NoError(err)
require.Contains(result, expectedValue)
})

t.Run("invalid height", func(t *testing.T) {
expectedErr := errors.New("invalid height")

cmd := NewBCBlockCmd(client)
_, err := util.ExecuteCmd(cmd, "0")
require.Error(err)
require.Contains(err.Error(), expectedErr.Error())
})

apiServiceClient.EXPECT().GetChainMeta(gomock.Any(), gomock.Any()).Return(chainMetaResponse, nil).Times(2)
apiServiceClient.EXPECT().GetBlockMetas(gomock.Any(), gomock.Any()).Return(blockMetaResponse, nil).Times(2)

t.Run("failed to get actions info", func(t *testing.T) {
expectedErr := errors.New("failed to get actions info")
apiServiceClient.EXPECT().GetRawBlocks(gomock.Any(), gomock.Any()).Return(nil, expectedErr).Times(1)

cmd := NewBCBlockCmd(client)
_, err := util.ExecuteCmd(cmd, "--verbose")
require.Error(err)
require.Contains(err.Error(), expectedErr.Error())
})

t.Run("verbose", func(t *testing.T) {
blockInfo := []*iotexapi.BlockInfo{
{
Block: &iotextypes.Block{
Body: &iotextypes.BlockBody{
Actions: []*iotextypes.Action{
&iotextypes.Action{
Core: &iotextypes.ActionCore{
Version: 1,
Nonce: 2,
GasLimit: 3,
GasPrice: "4",
},
},
},
&iotextypes.Action{
Core: &iotextypes.ActionCore{
Version: 5,
Nonce: 6,
GasLimit: 7,
GasPrice: "8",
&iotextypes.Action{
Core: &iotextypes.ActionCore{
Version: 5,
Nonce: 6,
GasLimit: 7,
GasPrice: "8",
},
},
},
},
},
Receipts: []*iotextypes.Receipt{
{
Status: 1,
BlkHeight: 1,
ActHash: []byte("02ae2a956d21e8d481c3a69e146633470cf625ec"),
GasConsumed: 1,
ContractAddress: "test",
Logs: []*iotextypes.Log{},
},
{
Status: 1,
BlkHeight: 1,
ActHash: []byte("02ae2a956d21e8d481c3a69e146633470cf625ec"),
GasConsumed: 1,
ContractAddress: "test",
Logs: []*iotextypes.Log{},
},
},
},
},
}
rawBlocksResponse := &iotexapi.GetRawBlocksResponse{Blocks: blockInfo}
apiServiceClient.EXPECT().GetRawBlocks(gomock.Any(), gomock.Any()).Return(rawBlocksResponse, nil).Times(1)

cmd = NewBCBlockCmd(client)
_, err = util.ExecuteCmd(cmd, "--verbose")
require.NoError(t, err)

client.EXPECT().SelectTranslation(gomock.Any()).Return("", config.English).Times(5)
client.EXPECT().Config().Return(cfg).Times(2)
client.EXPECT().APIServiceClient(gomock.Any()).Return(apiServiceClient, nil).Times(1)
apiServiceClient.EXPECT().GetChainMeta(gomock.Any(), gomock.Any()).Return(chainMetaResponse, nil).Times(1)

expectedErr = output.ErrorMessage{
Code: 3,
Info: "failed to get block meta: failed to invoke GetBlockMetas api: ",
}
err = output.ErrorMessage{}
apiServiceClient.EXPECT().GetBlockMetas(gomock.Any(), gomock.Any()).Return(nil, err).Times(1)

cmd = NewBCBlockCmd(client)
_, err = util.ExecuteCmd(cmd)
require.Error(t, err)
require.Equal(t, expectedErr, err)
}
rawBlocksResponse := &iotexapi.GetRawBlocksResponse{Blocks: blockInfo}
expectedValue1 := "\"version\": 1,\n \"nonce\": 2,\n \"gasLimit\": 3,\n \"gasPrice\": \"4\""
expectedValue2 := "\"version\": 5,\n \"nonce\": 6,\n \"gasLimit\": 7,\n \"gasPrice\": \"8\""
apiServiceClient.EXPECT().GetRawBlocks(gomock.Any(), gomock.Any()).Return(rawBlocksResponse, nil).Times(1)

cmd := NewBCBlockCmd(client)
result, err := util.ExecuteCmd(cmd, "--verbose")
require.NoError(err)
require.Contains(result, expectedValue1)
require.Contains(result, expectedValue2)
})
}

0 comments on commit 9844fac

Please sign in to comment.