Skip to content

Commit

Permalink
feat(wasm): add cli_test for wasm (Finschia#24)
Browse files Browse the repository at this point in the history
  • Loading branch information
shiki-tak authored Aug 30, 2021
1 parent 1670395 commit f289ed2
Show file tree
Hide file tree
Showing 4 changed files with 198 additions and 5 deletions.
141 changes: 136 additions & 5 deletions cli_test/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,27 @@ package clitest

import (
"encoding/base64"
"encoding/hex"
"errors"
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
"strconv"
"strings"
"testing"
"time"

"github.com/stretchr/testify/require"

"github.com/line/lfb/app"

"github.com/line/lfb-sdk/client/flags"
"github.com/line/lfb-sdk/crypto/keys/ed25519"
sdk "github.com/line/lfb-sdk/types"
"github.com/line/lfb-sdk/types/tx"
gov "github.com/line/lfb-sdk/x/gov/types"
minttypes "github.com/line/lfb-sdk/x/mint/types"

"github.com/line/lfb/app"
osttypes "github.com/line/ostracon/types"
"github.com/stretchr/testify/require"
)

func TestLFBKeysAddMultisig(t *testing.T) {
Expand Down Expand Up @@ -1211,3 +1210,135 @@ func TestLFBIncrementSequenceDecorator(t *testing.T) {
require.Equal(t, height, f.QueryTx(txHash).Height)
}
}

func TestLFBWasmContract(t *testing.T) {
t.Parallel()
f := InitFixtures(t)
defer f.Cleanup()

// start lfb server with minimum fees
n := f.LFBStart("")
defer n.Cleanup()

fooAddr := f.KeyAddress(keyFoo)

flagFromFoo := fmt.Sprintf("--from=%s", fooAddr)
flagGas := "--gas=auto"
flagGasAdjustment := "--gas-adjustment=1.2"
workDir, _ := os.Getwd()
tmpDir := path.Join(workDir, "tmp-dir-for-test-queue")
dirContract := path.Join(workDir, "contracts", "queue")
hashFile := path.Join(dirContract, "hash.txt")
wasmQueue := path.Join(dirContract, "contract.wasm")
codeID := uint64(1)
amountSend := uint64(10)
denomSend := fooDenom

var contractAddress string
count := 0
initValue := 0
enqueueValue := 2

// make tmpDir
os.Mkdir(tmpDir, os.ModePerm)

// validate that there are no code in the chain
{
listCode := f.QueryListCodeWasm()
require.Len(t, listCode.CodeInfos, 0)
}

// store the contract queue
{
_, err := f.TxStoreWasm(wasmQueue, flagFromFoo, flagGasAdjustment, flagGas, "-y")
require.NoError(t, err)
// Wait for a new block
err = n.WaitForNextBlock()
require.NoError(t, err)
}

// validate the code is stored
{
queryCodesResponse := f.QueryListCodeWasm()
require.Len(t, queryCodesResponse.CodeInfos, 1)

//validate the hash is the same
expectedRow, _ := ioutil.ReadFile(hashFile)
expected, err := hex.DecodeString(string(expectedRow[:64]))
require.NoError(t, err)
actual := queryCodesResponse.CodeInfos[0].DataHash.Bytes()
require.Equal(t, expected, actual)
}

// validate getCode get the exact same wasm
{
outputPath := path.Join(tmpDir, "queue-tmp.wasm")
f.QueryCodeWasm(codeID, outputPath)
fLocal, _ := os.Open(wasmQueue)
fChain, _ := os.Open(outputPath)

// 2000000 is enough length
dataLocal := make([]byte, 2000000)
dataChain := make([]byte, 2000000)
fLocal.Read(dataLocal)
fChain.Read(dataChain)
require.Equal(t, dataLocal, dataChain)
}

// validate that there are no contract using the code (id=1)
{
listContract := f.QueryListContractByCodeWasm(codeID)
require.Len(t, listContract.Contracts, 0)
}

// instantiate a contract with the code queue
{
msgJSON := fmt.Sprintf("{}")
flagLabel := "--label=queue-test"
flagAmount := fmt.Sprintf("--amount=%d%s", amountSend, denomSend)
_, err := f.TxInstantiateWasm(codeID, msgJSON, flagFromFoo, flagGasAdjustment, flagGas, flagLabel, flagAmount, flagFromFoo, "-y")
require.NoError(t, err)
// Wait for a new block
err = n.WaitForNextBlock()
require.NoError(t, err)
}

// validate there is only one contract using codeID=1 and get contractAddress
{
listContract := f.QueryListContractByCodeWasm(codeID)
require.Len(t, listContract.Contracts, 1)
contractAddress = listContract.Contracts[0]
}

// check queue count and sum
{
res := f.QueryContractStateSmartWasm(contractAddress, "{\"count\":{}}")
require.Equal(t, fmt.Sprintf("{\"data\":{\"count\":%d}}", count), strings.TrimRight(res, "\n"))

res = f.QueryContractStateSmartWasm(contractAddress, "{\"sum\":{}}")
require.Equal(t, fmt.Sprintf("{\"data\":{\"sum\":%d}}", initValue), strings.TrimRight(res, "\n"))
}

// execute contract(enqueue function)
{
msgJSON := fmt.Sprintf("{\"enqueue\":{\"value\":%d}}", enqueueValue)
_, err := f.TxExecuteWasm(contractAddress, msgJSON, flagFromFoo, flagGasAdjustment, flagGas, "-y")
require.NoError(t, err)
// Wait for a new block
err = n.WaitForNextBlock()
require.NoError(t, err)
count++
}

// check queue count and sum
{
res := f.QueryContractStateSmartWasm(contractAddress, "{\"count\":{}}")
require.Equal(t, fmt.Sprintf("{\"data\":{\"count\":%d}}", count), strings.TrimRight(res, "\n"))

res = f.QueryContractStateSmartWasm(contractAddress, "{\"sum\":{}}")
require.Equal(t, fmt.Sprintf("{\"data\":{\"sum\":%d}}", initValue+enqueueValue), strings.TrimRight(res, "\n"))
}

// remove tmp dir
os.RemoveAll(tmpDir)
}
Binary file added cli_test/contracts/queue/contract.wasm
Binary file not shown.
1 change: 1 addition & 0 deletions cli_test/contracts/queue/hash.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
9597202eab103cbd94908759557ef50bb9d8bcd584ea0a9d88c521d9a4a20b99
61 changes: 61 additions & 0 deletions cli_test/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ import (
slashing "github.com/line/lfb-sdk/x/slashing/types"
stakingcli "github.com/line/lfb-sdk/x/staking/client/cli"
staking "github.com/line/lfb-sdk/x/staking/types"
wasmcli "github.com/line/lfb-sdk/x/wasm/client/cli"

wasmtypes "github.com/line/lfb-sdk/x/wasm/types"
ostcfg "github.com/line/ostracon/config"
ostflags "github.com/line/ostracon/libs/cli/flags"
"github.com/line/ostracon/libs/log"
Expand Down Expand Up @@ -1417,3 +1419,62 @@ func newValidator(f *Fixtures, cfg testnet.Config, appCfg *srvconfig.Config, ctx
PubKey: pubKey,
}
}

func (f *Fixtures) TxStoreWasm(wasmFilePath string, flags ...string) (testutil.BufferWriter, error) {
cmd := wasmcli.StoreCodeCmd()
return testcli.ExecTestCLICmd(getCliCtx(f), cmd, addFlags(wasmFilePath, flags...))
}

func (f *Fixtures) TxInstantiateWasm(codeID uint64, msgJSON string, flags ...string) (testutil.BufferWriter, error) {
args := fmt.Sprintf("%d %s", codeID, msgJSON)
cmd := wasmcli.InstantiateContractCmd()
return testcli.ExecTestCLICmd(getCliCtx(f), cmd, addFlags(args, flags...))
}

func (f *Fixtures) TxExecuteWasm(contractAddress string, msgJSON string, flags ...string) (testutil.BufferWriter, error) {
args := fmt.Sprintf("%s %s", contractAddress, msgJSON)
cmd := wasmcli.ExecuteContractCmd()
return testcli.ExecTestCLICmd(getCliCtx(f), cmd, addFlags(args, flags...))
}

func (f *Fixtures) QueryListCodeWasm(flags ...string) wasmtypes.QueryCodesResponse {
cmd := wasmcli.GetCmdListCode()
res, errStr := testcli.ExecTestCLICmd(getCliCtx(f), cmd, addFlags("-o=json", flags...))

require.Empty(f.T, errStr)
cdc, _ := app.MakeCodecs()
var queryCodesResponse wasmtypes.QueryCodesResponse

err := cdc.UnmarshalJSON(res.Bytes(), &queryCodesResponse)
require.NoError(f.T, err)
return queryCodesResponse
}

func (f *Fixtures) QueryCodeWasm(codeID uint64, outputPath string, flags ...string) {
args := fmt.Sprintf("%d %s -o=json", codeID, outputPath)
cmd := wasmcli.GetCmdQueryCode()
_, errStr := testcli.ExecTestCLICmd(getCliCtx(f), cmd, addFlags(args, flags...))
require.Empty(f.T, errStr)
}

func (f *Fixtures) QueryListContractByCodeWasm(codeID uint64, flags ...string) wasmtypes.QueryContractsByCodeResponse {
args := fmt.Sprintf("%d -o=json", codeID)
cmd := wasmcli.GetCmdListContractByCode()
res, errStr := testcli.ExecTestCLICmd(getCliCtx(f), cmd, addFlags(args, flags...))

require.Empty(f.T, errStr)
cdc, _ := app.MakeCodecs()
var queryContractsByCodeResponse wasmtypes.QueryContractsByCodeResponse

err := cdc.UnmarshalJSON(res.Bytes(), &queryContractsByCodeResponse)
require.NoError(f.T, err)
return queryContractsByCodeResponse
}

func (f *Fixtures) QueryContractStateSmartWasm(contractAddress string, reqJSON string, flags ...string) string {
args := fmt.Sprintf("%s %s -o=json", contractAddress, reqJSON)
cmd := wasmcli.GetCmdGetContractStateSmart()
res, errStr := testcli.ExecTestCLICmd(getCliCtx(f), cmd, addFlags(args, flags...))
require.Empty(f.T, errStr)
return res.String()
}

0 comments on commit f289ed2

Please sign in to comment.