Skip to content
This repository has been archived by the owner on Nov 16, 2022. It is now read-only.

Commit

Permalink
Merge pull request #1891 from bandprotocol/app-test
Browse files Browse the repository at this point in the history
App test to check request flow request + report + endblock
  • Loading branch information
taobun authored Jun 11, 2020
2 parents f46dc28 + 6582b41 commit 14f5320
Show file tree
Hide file tree
Showing 6 changed files with 209 additions and 153 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG_UNRELEASED.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

### Chain

- (impv) [\#1891](https://github.com/bandprotocol/bandchain/pull/1891) Add end-to-end request flow test.

### Scan

- (impv) [\#1928](https://github.com/bandprotocol/bandchain/pull/1928) Add chainID for guanyu-devnet
Expand Down
178 changes: 177 additions & 1 deletion chain/x/oracle/app_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,179 @@
package oracle_test

// TODO: This file aim to test endblock logic.
import (
"fmt"
"testing"
"time"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/kv"

"github.com/bandprotocol/bandchain/chain/x/oracle"
"github.com/bandprotocol/bandchain/chain/x/oracle/types"
)

func parseEventAttribute(attr interface{}) []byte {
return []byte(fmt.Sprint(attr))
}

func TestSuccessRequestOracleData(t *testing.T) {
app, ctx, k := createTestInput()

for i := 1; i <= 3; i++ {
dataSource, clear := getTestDataSource(fmt.Sprintf("Code %d", i))
defer clear()
k.SetDataSource(ctx, types.DataSourceID(i), dataSource)
}
oracleScript, clear := getTestOracleScript()
defer clear()
k.SetOracleScript(ctx, types.OracleScriptID(1), oracleScript)

ctx = ctx.WithBlockHeight(4).WithBlockTime(time.Unix(int64(1581589790), 0))
handler := oracle.NewHandler(k)
requestMsg := types.NewMsgRequestData(types.OracleScriptID(1), []byte("calldata"), 3, 2, "app_test", Alice.Address)
res, err := handler(ctx, requestMsg)
require.NotNil(t, res)
require.NoError(t, err)

expectRequest := types.NewRequest(
types.OracleScriptID(1), []byte("calldata"),
[]sdk.ValAddress{Validator1.ValAddress, Validator3.ValAddress, Validator2.ValAddress},
2, 4, 1581589790, "app_test", nil, []types.ExternalID{1, 2, 3},
)
app.EndBlocker(ctx, abci.RequestEndBlock{Height: 4})
request, err := k.GetRequest(ctx, types.RequestID(1))
require.Equal(t, expectRequest, request)

reportMsg1 := types.NewMsgReportData(
types.RequestID(1), []types.RawReport{
types.NewRawReport(1, 0, []byte("answer1")),
types.NewRawReport(2, 0, []byte("answer2")),
types.NewRawReport(3, 0, []byte("answer3")),
},
Validator1.ValAddress, Validator1.Address,
)
res, err = handler(ctx, reportMsg1)
require.NotNil(t, res)
require.NoError(t, err)

ids := k.GetPendingResolveList(ctx)
require.Equal(t, []types.RequestID{}, ids)
_, err = k.GetResult(ctx, types.RequestID(1))
require.Error(t, err)

result := app.EndBlocker(ctx, abci.RequestEndBlock{Height: 6})
expectEvents := []abci.Event{}

require.Equal(t, expectEvents, result.GetEvents())

ctx = ctx.WithBlockTime(time.Unix(int64(1581589795), 0))
reportMsg2 := types.NewMsgReportData(
types.RequestID(1), []types.RawReport{
types.NewRawReport(1, 0, []byte("answer1")),
types.NewRawReport(2, 0, []byte("answer2")),
types.NewRawReport(3, 0, []byte("answer3")),
},
Validator2.ValAddress, Validator2.Address,
)
res, err = handler(ctx, reportMsg2)
require.NotNil(t, res)
require.NoError(t, err)

ids = k.GetPendingResolveList(ctx)
require.Equal(t, []types.RequestID{1}, ids)
_, err = k.GetResult(ctx, types.RequestID(1))
require.Error(t, err)

result = app.EndBlocker(ctx, abci.RequestEndBlock{Height: 8})
reqPacket := types.NewOracleRequestPacketData(
expectRequest.ClientID, types.OracleScriptID(1), expectRequest.Calldata,
uint64(len(expectRequest.RequestedValidators)), expectRequest.MinCount,
)
resPacket := types.NewOracleResponsePacketData(
expectRequest.ClientID, types.RequestID(1), 2, expectRequest.RequestTime, 1581589795,
types.ResolveStatus_Success, []byte("beeb"),
)
expectEvents = []abci.Event{{Type: types.EventTypeRequestExecute, Attributes: []kv.Pair{
{Key: []byte(types.AttributeKeyClientID), Value: parseEventAttribute(reqPacket.ClientID)},
{Key: []byte(types.AttributeKeyOracleScriptID), Value: parseEventAttribute(reqPacket.OracleScriptID)},
{Key: []byte(types.AttributeKeyCalldata), Value: expectRequest.Calldata},
{Key: []byte(types.AttributeKeyAskCount), Value: parseEventAttribute(reqPacket.AskCount)},
{Key: []byte(types.AttributeKeyMinCount), Value: parseEventAttribute(reqPacket.MinCount)},
{Key: []byte(types.AttributeKeyRequestID), Value: parseEventAttribute(resPacket.RequestID)},
{Key: []byte(types.AttributeKeyResolveStatus), Value: parseEventAttribute(uint32(resPacket.ResolveStatus))},
{Key: []byte(types.AttributeKeyAnsCount), Value: parseEventAttribute(resPacket.AnsCount)},
{Key: []byte(types.AttributeKeyRequestTime), Value: parseEventAttribute(resPacket.RequestTime)},
{Key: []byte(types.AttributeKeyResolveTime), Value: parseEventAttribute(resPacket.ResolveTime)},
{Key: []byte(types.AttributeKeyResult), Value: resPacket.Result},
}}}

require.Equal(t, expectEvents, result.GetEvents())

ids = k.GetPendingResolveList(ctx)
require.Equal(t, []types.RequestID{}, ids)

req, err := k.GetRequest(ctx, types.RequestID(1))
require.NotEqual(t, types.Request{}, req)
require.NoError(t, err)

ctx = ctx.WithBlockHeight(32).WithBlockTime(ctx.BlockTime().Add(time.Minute))
app.EndBlocker(ctx, abci.RequestEndBlock{Height: 32})
}

func TestExpiredRequestOracleData(t *testing.T) {
app, ctx, k := createTestInput()

for i := 1; i <= 3; i++ {
dataSource, clear := getTestDataSource(fmt.Sprintf("Code %d", i))
defer clear()
k.SetDataSource(ctx, types.DataSourceID(i), dataSource)
}
oracleScript, clear := getTestOracleScript()
defer clear()
k.SetOracleScript(ctx, types.OracleScriptID(1), oracleScript)

ctx = ctx.WithBlockHeight(4).WithBlockTime(time.Unix(int64(1581589790), 0))
handler := oracle.NewHandler(k)
requestMsg := types.NewMsgRequestData(types.OracleScriptID(1), []byte("calldata"), 3, 2, "app_test", Alice.Address)
res, err := handler(ctx, requestMsg)
require.NotNil(t, res)
require.NoError(t, err)

expectRequest := types.NewRequest(
types.OracleScriptID(1), []byte("calldata"),
[]sdk.ValAddress{Validator1.ValAddress, Validator3.ValAddress, Validator2.ValAddress},
2, 4, 1581589790, "app_test", nil, []types.ExternalID{1, 2, 3},
)
app.EndBlocker(ctx, abci.RequestEndBlock{Height: 4})
request, err := k.GetRequest(ctx, types.RequestID(1))
require.Equal(t, expectRequest, request)

ctx = ctx.WithBlockHeight(32).WithBlockTime(ctx.BlockTime().Add(time.Minute))
result := app.EndBlocker(ctx, abci.RequestEndBlock{Height: 32})

reqPacket := types.NewOracleRequestPacketData(
expectRequest.ClientID, types.OracleScriptID(1), expectRequest.Calldata,
uint64(len(expectRequest.RequestedValidators)), expectRequest.MinCount,
)
resPacket := types.NewOracleResponsePacketData(
expectRequest.ClientID, types.RequestID(1), 0, expectRequest.RequestTime, ctx.BlockTime().Unix(),
types.ResolveStatus_Expired, []byte{},
)
expectEvents := []abci.Event{{Type: types.EventTypeRequestExecute, Attributes: []kv.Pair{
{Key: []byte(types.AttributeKeyClientID), Value: parseEventAttribute(reqPacket.ClientID)},
{Key: []byte(types.AttributeKeyOracleScriptID), Value: parseEventAttribute(reqPacket.OracleScriptID)},
{Key: []byte(types.AttributeKeyCalldata), Value: expectRequest.Calldata},
{Key: []byte(types.AttributeKeyAskCount), Value: parseEventAttribute(reqPacket.AskCount)},
{Key: []byte(types.AttributeKeyMinCount), Value: parseEventAttribute(reqPacket.MinCount)},
{Key: []byte(types.AttributeKeyRequestID), Value: parseEventAttribute(resPacket.RequestID)},
{Key: []byte(types.AttributeKeyResolveStatus), Value: parseEventAttribute(uint32(resPacket.ResolveStatus))},
{Key: []byte(types.AttributeKeyAnsCount), Value: parseEventAttribute(resPacket.AnsCount)},
{Key: []byte(types.AttributeKeyRequestTime), Value: parseEventAttribute(resPacket.RequestTime)},
{Key: []byte(types.AttributeKeyResolveTime), Value: parseEventAttribute(resPacket.ResolveTime)},
{Key: []byte(types.AttributeKeyResult), Value: resPacket.Result},
}}}

require.Equal(t, expectEvents, result.GetEvents())
}
3 changes: 2 additions & 1 deletion chain/x/oracle/endblock.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package oracle

import (
"github.com/bandprotocol/bandchain/chain/x/oracle/types"
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/bandprotocol/bandchain/chain/x/oracle/types"
)

// handleEndBlock cleans up the state during end block. See comment in the implementation!
Expand Down
124 changes: 0 additions & 124 deletions chain/x/oracle/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -568,130 +568,6 @@ func TestReportFailed(t *testing.T) {
require.Error(t, err)
}

// // func TestEndBlock(t *testing.T) {
// // ctx, keeper := keep.CreateTestInput(t, false)

// // ctx = ctx.WithBlockHeight(2)
// // ctx = ctx.WithBlockTime(time.Unix(int64(1581589790), 0))
// // calldata := []byte("calldata")
// // sender := sdk.AccAddress([]byte("sender"))

// // script := keep.GetTestOracleScript("../../pkg/owasm/res/silly.wasm")
// // keeper.SetOracleScript(ctx, 1, script)

// // pubStr := []string{
// // "03d03708f161d1583f49e4260a42b2b08d3ba186d7803a23cc3acd12f074d9d76f",
// // "03f57f3997a4e81d8f321e9710927e22c2e6d30fb6d8f749a9e4a07afb3b3b7909",
// // }

// // validatorAddress1 := keep.SetupTestValidator(ctx, keeper, pubStr[0], 10)
// // validatorAddress2 := keep.SetupTestValidator(ctx, keeper, pubStr[1], 100)

// // dataSource := keep.GetTestDataSource()
// // keeper.SetDataSource(ctx, 1, dataSource)

// // msg := types.NewMsgRequestData(1, calldata, 2, 2, "clientID", sender)

// // handleMsgRequestData(ctx, keeper, msg)

// // keeper.SetReport(ctx, 1, 1, validatorAddress1, types.NewReport(0, []byte("answer1")))
// // keeper.SetReport(ctx, 1, 1, validatorAddress2, types.NewReport(0, []byte("answer2")))

// // keeper.SetPendingResolveList(ctx, []types.RequestID{1})

// // ctx = ctx.WithBlockTime(time.Unix(int64(1581589999), 0))
// // handleEndBlock(ctx, keeper)

// // require.Equal(t, []types.RequestID{}, keeper.GetPendingResolveList(ctx))

// // result, err := keeper.GetResult(ctx, 1, 1, calldata)
// // require.Nil(t, err)
// // require.Equal(t,
// // types.Result{
// // RequestTime: 1581589790,
// // AggregationTime: 1581589999,
// // RequestedValidatorsCount: 2,
// // MinCount: 2,
// // ReportedValidatorsCount: 0,
// // Data: []byte("answer2"),
// // },
// // result,
// // )

// // actualRequest, err := keeper.GetRequest(ctx, 1)
// // require.Nil(t, err)
// // require.Equal(t, types.ResolveStatus_Success, actualRequest.ResolveStatus)
// // }

// func TestEndBlockExecuteFailedIfExecuteGasLessThanGasUsed(t *testing.T) {
// // TODO: Write this test properly. Pending on having owasm that can easily control gas usage.
// }

// func TestAddAndRemoveOracleAddress(t *testing.T) {
// // Setup test environment
// ctx, keeper := keep.CreateTestInput(t, false)

// ctx = ctx.WithBlockHeight(2)
// ctx = ctx.WithBlockTime(time.Unix(int64(1581589790), 0))
// calldata := []byte("calldata")

// script := keep.GetTestOracleScript("../../pkg/owasm/res/silly.wasm")
// keeper.SetOracleScript(ctx, 1, script)

// pubStr := []string{
// "03d03708f161d1583f49e4260a42b2b08d3ba186d7803a23cc3acd12f074d9d76f",
// "03f57f3997a4e81d8f321e9710927e22c2e6d30fb6d8f749a9e4a07afb3b3b7909",
// }

// validatorAddress1 := keep.SetupTestValidator(ctx, keeper, pubStr[0], 10)

// address1 := keep.GetAddressFromPub(pubStr[0])

// validatorAddress2 := keep.SetupTestValidator(ctx, keeper, pubStr[1], 100)
// reporterAddress2 := sdk.AccAddress(validatorAddress2)

// dataSource := keep.GetTestDataSource()
// keeper.SetDataSource(ctx, 1, dataSource)

// _, err := keeper.CoinKeeper.AddCoins(ctx, address1, keep.NewUBandCoins(1000000))
// require.Nil(t, err)

// request := types.NewRequest(1, calldata,
// []sdk.ValAddress{validatorAddress2, validatorAddress1}, 2,
// 2, 1581589790, "clientID", nil, nil,
// )
// keeper.SetRequest(ctx, 1, request)
// keeper.SetRawRequest(ctx, 1, types.NewRawRequest(42, 1, []byte("calldata1")))

// ctx = ctx.WithBlockHeight(5)
// ctx = ctx.WithBlockTime(time.Unix(int64(1581589800), 0))

// keeper.AddReporter(ctx, validatorAddress1, reporterAddress2)
// err = keeper.AddReporter(ctx, validatorAddress1, reporterAddress2)

// require.NotNil(t, err)

// msg := types.NewMsgReportData(1, []types.RawReport{
// types.NewRawReport(42, 0, []byte("data1")),
// }, validatorAddress1, reporterAddress2)

// _, err = handleMsgReportData(ctx, keeper, msg)
// require.Nil(t, err)
// list := keeper.GetPendingResolveList(ctx)
// require.Equal(t, []types.RequestID{}, list)

// keeper.RemoveReporter(ctx, validatorAddress1, reporterAddress2)
// err = keeper.RemoveReporter(ctx, validatorAddress1, reporterAddress2)
// require.NotNil(t, err)

// msg = types.NewMsgReportData(1, []types.RawReport{
// types.NewRawReport(42, 0, []byte("data2")),
// }, validatorAddress1, reporterAddress2)

// _, err = handleMsgReportData(ctx, keeper, msg)
// require.NotNil(t, err)
// }

func TestAddReporterSuccess(t *testing.T) {
_, ctx, k := createTestInput()

Expand Down
Loading

0 comments on commit 14f5320

Please sign in to comment.