From b5e3a11347a690f5c74b2cea584a90cbbee45d79 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Sun, 29 Jan 2017 18:42:25 -0800 Subject: [PATCH] Add test for IBCRegisterChainTx --- plugins/ibc/ibc.go | 5 +++ plugins/ibc/ibc_test.go | 87 +++++++++++++++++++++++++++++++++++++++++ types/kvstore.go | 43 ++++++++++++++++---- 3 files changed, 127 insertions(+), 8 deletions(-) create mode 100644 plugins/ibc/ibc_test.go diff --git a/plugins/ibc/ibc.go b/plugins/ibc/ibc.go index 8a8d4d9fcb..a21b34d337 100644 --- a/plugins/ibc/ibc.go +++ b/plugins/ibc/ibc.go @@ -58,6 +58,9 @@ const ( IBCTxTypeRegisterChain = byte(0x01) IBCTxTypeUpdateChain = byte(0x02) IBCTxTypePacket = byte(0x03) + + IBCCodeEncodingError = abci.CodeType(1001) + IBCCodeChainAlreadyExists = abci.CodeType(1002) ) var _ = wire.RegisterInterface( @@ -182,12 +185,14 @@ func (sm *IBCStateMachine) runRegisterChainTx(tx IBCRegisterChainTx) { var err error wire.ReadJSONPtr(&chainGenDoc, []byte(chainGen.Genesis), &err) if err != nil { + sm.res.Code = IBCCodeEncodingError sm.res.AppendLog("Genesis doc couldn't be parsed: " + err.Error()) return } // Make sure chainGen doesn't already exist if exists(sm.store, chainGenKey) { + sm.res.Code = IBCCodeChainAlreadyExists sm.res.AppendLog("Already exists") return } diff --git a/plugins/ibc/ibc_test.go b/plugins/ibc/ibc_test.go new file mode 100644 index 0000000000..1de57e541d --- /dev/null +++ b/plugins/ibc/ibc_test.go @@ -0,0 +1,87 @@ +package ibc + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/tendermint/basecoin/testutils" + "github.com/tendermint/basecoin/types" + cmn "github.com/tendermint/go-common" + "github.com/tendermint/go-wire" + tm "github.com/tendermint/tendermint/types" +) + +func genGenesisDoc(chainID string, numVals int) (*tm.GenesisDoc, []*tm.Validator) { + var vals []*tm.Validator + genDoc := &tm.GenesisDoc{ + ChainID: chainID, + Validators: nil, + } + + for i := 0; i < numVals; i++ { + name := cmn.Fmt("%v_val_%v", chainID, i) + valPrivAcc := testutils.PrivAccountFromSecret(name) + val := tm.NewValidator(valPrivAcc.Account.PubKey, 1) + genDoc.Validators = append(genDoc.Validators, tm.GenesisValidator{ + PubKey: val.PubKey, + Amount: 1, + Name: name, + }) + vals = append(vals, val) + } + + return genDoc, vals +} + +func TestIBCPlugin(t *testing.T) { + + store := types.NewKVCache(nil) + store.SetLogging() // Log all activity + + ibcPlugin := New() + ctx := types.CallContext{ + CallerAddress: nil, + CallerAccount: nil, + Coins: types.Coins{}, + } + + chainID_1 := "test_chain" + genDoc_1, vals_1 := genGenesisDoc(chainID_1, 4) + genDocJSON_1 := wire.JSONBytesPretty(genDoc_1) + + // Register a malformed chain + res := ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCRegisterChainTx{ + BlockchainGenesis{ + ChainID: "test_chain", + Genesis: "", + }, + }})) + assert.Equal(t, res.Code, IBCCodeEncodingError) + t.Log(">>", strings.Join(store.GetLogLines(), "\n")) + store.ClearLogLines() + + // Successfully register a chain + res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCRegisterChainTx{ + BlockchainGenesis{ + ChainID: "test_chain", + Genesis: string(genDocJSON_1), + }, + }})) + assert.True(t, res.IsOK(), res) + t.Log(">>", strings.Join(store.GetLogLines(), "\n")) + store.ClearLogLines() + + // Duplicate request fails + res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCRegisterChainTx{ + BlockchainGenesis{ + ChainID: "test_chain", + Genesis: string(genDocJSON_1), + }, + }})) + assert.Equal(t, res.Code, IBCCodeChainAlreadyExists, res) + t.Log(">>", strings.Join(store.GetLogLines(), "\n")) + store.ClearLogLines() + + t.Log(">>", vals_1) +} diff --git a/types/kvstore.go b/types/kvstore.go index 5ba8271f03..96f8c7d0ff 100644 --- a/types/kvstore.go +++ b/types/kvstore.go @@ -36,9 +36,11 @@ func (mkv *MemKVStore) Get(key []byte) (value []byte) { // A Cache that enforces deterministic sync order. type KVCache struct { - store KVStore - cache map[string]kvCacheValue - keys *list.List + store KVStore + cache map[string]kvCacheValue + keys *list.List + logging bool + logLines []string } type kvCacheValue struct { @@ -46,12 +48,28 @@ type kvCacheValue struct { e *list.Element // The KVCache.keys element } +// NOTE: If store is nil, creates a new MemKVStore func NewKVCache(store KVStore) *KVCache { + if store == nil { + store = NewMemKVStore() + } return (&KVCache{ store: store, }).Reset() } +func (kvc *KVCache) SetLogging() { + kvc.logging = true +} + +func (kvc *KVCache) GetLogLines() []string { + return kvc.logLines +} + +func (kvc *KVCache) ClearLogLines() { + kvc.logLines = nil +} + func (kvc *KVCache) Reset() *KVCache { kvc.cache = make(map[string]kvCacheValue) kvc.keys = list.New() @@ -59,7 +77,10 @@ func (kvc *KVCache) Reset() *KVCache { } func (kvc *KVCache) Set(key []byte, value []byte) { - fmt.Println("Set [KVCache]", formatBytes(key), "=", formatBytes(value)) + if kvc.logging { + line := fmt.Sprintf("Set %v = %v", LegibleBytes(key), LegibleBytes(value)) + kvc.logLines = append(kvc.logLines, line) + } cacheValue, ok := kvc.cache[string(key)] if ok { kvc.keys.MoveToBack(cacheValue.e) @@ -73,7 +94,10 @@ func (kvc *KVCache) Set(key []byte, value []byte) { func (kvc *KVCache) Get(key []byte) (value []byte) { cacheValue, ok := kvc.cache[string(key)] if ok { - fmt.Println("GET [KVCache, hit]", formatBytes(key), "=", formatBytes(cacheValue.v)) + if kvc.logging { + line := fmt.Sprintf("Get (hit) %v = %v", LegibleBytes(key), LegibleBytes(cacheValue.v)) + kvc.logLines = append(kvc.logLines, line) + } return cacheValue.v } else { value := kvc.store.Get(key) @@ -81,7 +105,10 @@ func (kvc *KVCache) Get(key []byte) (value []byte) { v: value, e: kvc.keys.PushBack(key), } - fmt.Println("GET [KVCache, miss]", formatBytes(key), "=", formatBytes(value)) + if kvc.logging { + line := fmt.Sprintf("Get (miss) %v = %v", LegibleBytes(key), LegibleBytes(value)) + kvc.logLines = append(kvc.logLines, line) + } return value } } @@ -97,13 +124,13 @@ func (kvc *KVCache) Sync() { //---------------------------------------- -func formatBytes(data []byte) string { +func LegibleBytes(data []byte) string { s := "" for _, b := range data { if 0x21 <= b && b < 0x7F { s += Green(string(b)) } else { - s += Blue(Fmt("%X", b)) + s += Blue(Fmt("%02X", b)) } } return s