Skip to content

Commit

Permalink
Fix codecov: `statesync: improve e2e test outcomes (backport #6378) (…
Browse files Browse the repository at this point in the history
…#6380)`
  • Loading branch information
tnasu committed Jan 12, 2022
1 parent dd96011 commit d13c936
Show file tree
Hide file tree
Showing 2 changed files with 188 additions and 0 deletions.
29 changes: 29 additions & 0 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,35 @@ func TestMempoolConfigValidateBasic(t *testing.T) {
func TestStateSyncConfigValidateBasic(t *testing.T) {
cfg := TestStateSyncConfig()
require.NoError(t, cfg.ValidateBasic())

testVerify := func(expectedError string) {
actual := cfg.ValidateBasic()
require.Error(t, actual)
require.Equal(t, expectedError, actual.Error())
}

// Enabled
cfg.Enable = true
testVerify("rpc_servers is required")
cfg.RPCServers = []string{""}
testVerify("at least two rpc_servers entries is required")
cfg.RPCServers = []string{"", ""}
testVerify("found empty rpc_servers entry")
cfg.RPCServers = []string{"a", "b"}
cfg.DiscoveryTime = 1 * time.Second
testVerify("discovery time must be 0s or greater than five seconds")
cfg.DiscoveryTime = 0
cfg.TrustPeriod = 0
testVerify("trusted_period is required")
cfg.TrustPeriod = 1
testVerify("trusted_height is required")
cfg.TrustHeight = 1
testVerify("trusted_hash is required")
cfg.TrustHash = "0"
testVerify("invalid trusted_hash: encoding/hex: odd length hex string")
cfg.TrustHash = "00"
// Success with Enabled
require.NoError(t, cfg.ValidateBasic())
}

func TestFastSyncConfigValidateBasic(t *testing.T) {
Expand Down
159 changes: 159 additions & 0 deletions statesync/reactor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ import (
"testing"
"time"

"github.com/line/ostracon/config"
"github.com/line/ostracon/libs/log"
tmstate "github.com/line/ostracon/proto/ostracon/state"
tmversion "github.com/line/ostracon/proto/ostracon/version"
"github.com/line/ostracon/proxy"
sm "github.com/line/ostracon/state"
"github.com/line/ostracon/statesync/mocks"
"github.com/line/ostracon/types"
"github.com/line/ostracon/version"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -155,3 +165,152 @@ func TestReactor_Receive_SnapshotsRequest(t *testing.T) {
})
}
}

func makeTestStateSyncReactor(
t *testing.T, appHash string, height int64, snapshot *snapshot, chunks []*chunk) *Reactor {
connSnapshot := makeMockAppConnSnapshot(appHash, snapshot, chunks)
connQuery := makeMockAppConnQuery(appHash, height)

p2pConfig := config.DefaultP2PConfig()
p2pConfig.PexReactor = true
p2pConfig.AllowDuplicateIP = true

name := "STATE_SYNC_REACTOR_FOR_TEST"
size := 2
reactors := make([]*Reactor, size)
initSwitch := func(i int, s *p2p.Switch, config *config.P2PConfig) *p2p.Switch {
logger := log.TestingLogger()
reactors[i] = NewReactor(connSnapshot, connQuery, true, 1000)
reactors[i].SetLogger(logger)
reactors[i].SetSwitch(s)

s.AddReactor(name, reactors[i])
s.SetLogger(logger)
return s
}
switches := p2p.MakeConnectedSwitches(p2pConfig, size, initSwitch, p2p.Connect2Switches)

t.Cleanup(func() {
for i := 0; i < size; i++ {
if err := switches[i].Stop(); err != nil {
t.Error(err)
}
}
})

return reactors[0]
}

func makeMockAppConnSnapshot(appHash string, snapshot *snapshot, chunks []*chunk) *proxymocks.AppConnSnapshot {
connSnapshot := &proxymocks.AppConnSnapshot{}

connSnapshot.On("OfferSnapshotSync", abci.RequestOfferSnapshot{
Snapshot: &abci.Snapshot{
Height: snapshot.Height,
Format: snapshot.Format,
Chunks: snapshot.Chunks,
Hash: snapshot.Hash,
},
AppHash: []byte(appHash),
}).Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ACCEPT}, nil)

connSnapshot.On("ListSnapshotsSync", abci.RequestListSnapshots{}).Return(&abci.ResponseListSnapshots{
Snapshots: []*abci.Snapshot{{
Height: snapshot.Height,
Format: snapshot.Format,
Chunks: snapshot.Chunks,
Hash: snapshot.Hash,
Metadata: snapshot.Metadata,
}},
}, nil)

index := len(chunks)
for i := 0; i < index; i++ {
connSnapshot.On("ApplySnapshotChunkSync",
mock.Anything).Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil)
connSnapshot.On("LoadSnapshotChunkSync", abci.RequestLoadSnapshotChunk{
Height: chunks[i].Height, Format: chunks[i].Format, Chunk: chunks[i].Index,
}).Return(&abci.ResponseLoadSnapshotChunk{Chunk: chunks[i].Chunk}, nil)
}

return connSnapshot
}

func makeMockAppConnQuery(appHash string, height int64) *proxymocks.AppConnQuery {
connQuery := &proxymocks.AppConnQuery{}
connQuery.On("InfoSync", proxy.RequestInfo).Return(&abci.ResponseInfo{
AppVersion: 9,
LastBlockHeight: height,
LastBlockAppHash: []byte(appHash),
}, nil)
return connQuery
}

func makeTestStateAndCommit(appHash string, height int64) (sm.State, *types.Commit) {
blockHash := "block_hash"

state := sm.State{
ChainID: "chain",
Version: tmstate.Version{
Consensus: tmversion.Consensus{
Block: version.BlockProtocol,
App: 0,
},

Software: version.OCCoreSemVer,
},

LastBlockHeight: height,
LastBlockID: types.BlockID{Hash: []byte(blockHash)},
LastBlockTime: time.Now(),
LastResultsHash: []byte("last_results_hash"),
AppHash: []byte(appHash),

LastVoters: &types.VoterSet{},
Validators: &types.ValidatorSet{},
Voters: &types.VoterSet{},
NextValidators: &types.ValidatorSet{},
VoterParams: types.DefaultVoterParams(),

ConsensusParams: *types.DefaultConsensusParams(),
LastHeightConsensusParamsChanged: 1,
}

commit := &types.Commit{BlockID: types.BlockID{Hash: []byte(blockHash)}}

return state, commit
}

func makeMockStateProvider(appHash string, height uint64) *mocks.StateProvider {
state, commit := makeTestStateAndCommit(appHash, int64(height))

stateProvider := &mocks.StateProvider{}
stateProvider.On("AppHash", mock.Anything, mock.Anything).Return([]byte(appHash), nil)
stateProvider.On("State", mock.Anything, height).Return(state, nil)
stateProvider.On("Commit", mock.Anything, height).Return(commit, nil)
return stateProvider
}

func TestSync(t *testing.T) {
// prepare
height, format := uint64(1), uint32(1)
appHash := "app_hash"

chunks := []*chunk{
{Height: height, Format: format, Index: 0, Chunk: []byte{1, 1, 0}},
{Height: height, Format: format, Index: 1, Chunk: []byte{1, 1, 1}},
{Height: height, Format: format, Index: 2, Chunk: []byte{1, 1, 2}},
}
snapshot := &snapshot{Height: height, Format: format, Chunks: uint32(len(chunks)), Hash: []byte{1, 2, 3}}
reactor := makeTestStateSyncReactor(t, appHash, int64(height), snapshot, chunks)
stateProvider := makeMockStateProvider(appHash, height)

// test
state, previousState, commit, err := reactor.Sync(stateProvider, 5*time.Second)

// verify
require.NoError(t, err)
require.NotNil(t, state)
require.NotNil(t, previousState)
require.NotNil(t, commit)
}

0 comments on commit d13c936

Please sign in to comment.