diff --git a/.circleci/config.yml b/.circleci/config.yml index 90a8393c1a..269d4ca94b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -63,7 +63,7 @@ jobs: export PATH="$GOBIN:$PATH" make test_lint - test_cli: + integration_tests: <<: *defaults parallelism: 1 steps: @@ -80,6 +80,7 @@ jobs: command: | export PATH="$GOBIN:$PATH" make test_cli + make test_examples test_sim_modules: <<: *defaults @@ -220,7 +221,7 @@ workflows: - lint: requires: - setup_dependencies - - test_cli: + - integration_tests: requires: - setup_dependencies - test_sim_modules: diff --git a/Makefile b/Makefile index b35e3f5c9a..de5f6956f2 100644 --- a/Makefile +++ b/Makefile @@ -132,6 +132,10 @@ test: test_unit test_cli: @go test -count 1 -p 1 `go list github.com/cosmos/cosmos-sdk/cmd/gaia/cli_test` -tags=cli_test +test_examples: + @go test -count 1 -p 1 `go list github.com/cosmos/cosmos-sdk/examples/basecoin/cli_test` -tags=cli_test + @go test -count 1 -p 1 `go list github.com/cosmos/cosmos-sdk/examples/democoin/cli_test` -tags=cli_test + test_unit: @go test $(PACKAGES_NOSIMULATION) diff --git a/PENDING.md b/PENDING.md index dca1e8fe93..213453e4af 100644 --- a/PENDING.md +++ b/PENDING.md @@ -21,6 +21,7 @@ BREAKING CHANGES * SDK * [core] \#1807 Switch from use of rational to decimal * [types] \#1901 Validator interface's GetOwner() renamed to GetOperator() + * [types] \#2119 Parsed error messages and ABCI log errors to make them more human readable. * Tendermint @@ -51,12 +52,13 @@ IMPROVEMENTS * [cli] #2060 removed `--select` from `block` command * Gaia - * [x/stake] [#2023](https://github.com/cosmos/cosmos-sdk/pull/2023) Terminate iteration loop in `UpdateBondedValidators` and `UpdateBondedValidatorsFull` when the first revoked validator is encountered and perform a sanity check. + * [x/stake] [#2023](https://github.com/cosmos/cosmos-sdk/pull/2023) Terminate iteration loop in `UpdateBondedValidators` and `UpdateBondedValidatorsFull` when the first revoked validator is encountered and perform a sanity check. * [x/auth] Signature verification's gas cost now accounts for pubkey type. [#2046](https://github.com/tendermint/tendermint/pull/2046) * SDK * [tools] Make get_vendor_deps deletes `.vendor-new` directories, in case scratch files are present. * [spec] Added simple piggy bank distribution spec + * [cli] \#1632 Add integration tests to ensure `basecoind init && basecoind` start sequences run successfully for both `democoin` and `basecoin` examples. * Tendermint diff --git a/docs/DOCS_README.md b/docs/DOCS_README.md index 564a7e9558..da11b2c01e 100644 --- a/docs/DOCS_README.md +++ b/docs/DOCS_README.md @@ -8,10 +8,9 @@ and built using [VuePress](https://vuepress.vuejs.org/) from the Cosmos website - https://github.com/cosmos/cosmos.network -which has a [configuration file](https://github.com/cosmos/cosmos.network/blob/develop/docs/.vuepress/config.js) for displaying -the Table of Contents that lists all the documentation. +Under the hood, Jenkins listens for changes (on develop or master) in ./docs then rebuilds +either the staging or production site depending on which branch the changes were made. -Under the hood, Jenkins listens for changes in ./docs then pushes a `docs-staging` branch to the cosmos.network repo with the latest documentation. That branch must be manually PR'd to `develop` then `master` for staging then production. This process should happen in synchrony with a release. - -The `README.md` in this directory is the landing page for +To update the Table of Contents (layout of the documentation sidebar), edit the +`config.js` in this directory, while the `README.md` is the landing page for the website documentation. diff --git a/docs/config.js b/docs/config.js new file mode 100644 index 0000000000..61607b1b08 --- /dev/null +++ b/docs/config.js @@ -0,0 +1,86 @@ +module.exports = { + title: "Cosmos Network", + description: "Documentation for the Cosmos Network.", + dest: "./site-docs", + base: "/", + markdown: { + lineNumbers: true + }, + themeConfig: { + lastUpdated: "Last Updated", + nav: [{ text: "Back to Cosmos", link: "https://cosmos.network" }], + sidebar: [ + { + title: "Introduction", + collapsable: false, + children: [ + "/introduction/cosmos-hub", + "/introduction/tendermint", + ] + }, + { + title: "Getting Started", + collapsable: false, + children: [ + "/getting-started/voyager", + "/getting-started/installation", + "/getting-started/full-node", + "/getting-started/create-testnet" + ] + }, + { + title: "Cosmos SDK", + collapsable: false, + children: [ + ["/sdk/overview", "Overview"], + ["/sdk/core/intro", "Core"], + "/sdk/core/app1", + "/sdk/core/app2", + "/sdk/core/app3", + "/sdk/core/app4", + "/sdk/core/app5", + // "/sdk/modules", + "/sdk/clients" + ] + }, + // { + // title: "Specifications", + // collapsable: false, + // children: [ + // ["/specs/overview", "Overview"], + // "/specs/governance", + // "/specs/ibc", + // "/specs/staking", + // "/specs/icts", + // ] + // }, + { + title: "Lotion JS", + collapsable: false, + children: [["/lotion/overview", "Overview"], "/lotion/building-an-app"] + }, + { + title: "Validators", + collapsable: false, + children: [ + ["/validators/overview", "Overview"], + ["/validators/security", "Security"], + ["/validators/validator-setup", "Validator Setup"], + "/validators/validator-faq" + ] + }, + { + title: "Resources", + collapsable: false, + children: [ + // ["/resources/faq" "General"], + "/resources/delegator-faq", + ["/resources/whitepaper", "Whitepaper - English"], + ["/resources/whitepaper-ko", "Whitepaper - 한국어"], + ["/resources/whitepaper-zh-CN", "Whitepaper - 中文"], + ["/resources/whitepaper-pt", "Whitepaper - Português"] + ] + } + ] + } +} diff --git a/examples/basecoin/cli_test/cli_test.go b/examples/basecoin/cli_test/cli_test.go new file mode 100644 index 0000000000..3a33135e39 --- /dev/null +++ b/examples/basecoin/cli_test/cli_test.go @@ -0,0 +1,52 @@ +package clitest + +import ( + "encoding/json" + "fmt" + "os" + "testing" + + "github.com/cosmos/cosmos-sdk/server" + "github.com/cosmos/cosmos-sdk/tests" + "github.com/stretchr/testify/require" +) + +var ( + basecoindHome = "" +) + +func init() { + basecoindHome = getTestingHomeDir() +} + +func TestInitStartSequence(t *testing.T) { + os.RemoveAll(basecoindHome) + servAddr, port, err := server.FreeTCPAddr() + require.NoError(t, err) + executeInit(t) + executeStart(t, servAddr, port) +} + +func executeInit(t *testing.T) { + var ( + chainID string + initRes map[string]json.RawMessage + ) + out := tests.ExecuteT(t, fmt.Sprintf("basecoind --home=%s init", basecoindHome), "") + err := json.Unmarshal([]byte(out), &initRes) + require.NoError(t, err) + err = json.Unmarshal(initRes["chain_id"], &chainID) + require.NoError(t, err) +} + +func executeStart(t *testing.T, servAddr, port string) { + proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("basecoind start --home=%s --rpc.laddr=%v", basecoindHome, servAddr)) + defer proc.Stop(false) + tests.WaitForTMStart(port) +} + +func getTestingHomeDir() string { + tmpDir := os.TempDir() + basecoindHome := fmt.Sprintf("%s%s.test_basecoind", tmpDir, string(os.PathSeparator)) + return basecoindHome +} diff --git a/examples/democoin/cli_test/cli_test.go b/examples/democoin/cli_test/cli_test.go new file mode 100644 index 0000000000..2db2fff096 --- /dev/null +++ b/examples/democoin/cli_test/cli_test.go @@ -0,0 +1,52 @@ +package clitest + +import ( + "encoding/json" + "fmt" + "os" + "testing" + + "github.com/cosmos/cosmos-sdk/server" + "github.com/cosmos/cosmos-sdk/tests" + "github.com/stretchr/testify/require" +) + +var ( + democoindHome = "" +) + +func init() { + democoindHome = getTestingHomeDir() +} + +func TestInitStartSequence(t *testing.T) { + os.RemoveAll(democoindHome) + servAddr, port, err := server.FreeTCPAddr() + require.NoError(t, err) + executeInit(t) + executeStart(t, servAddr, port) +} + +func executeInit(t *testing.T) { + var ( + chainID string + initRes map[string]json.RawMessage + ) + out := tests.ExecuteT(t, fmt.Sprintf("democoind --home=%s init", democoindHome), "") + err := json.Unmarshal([]byte(out), &initRes) + require.NoError(t, err) + err = json.Unmarshal(initRes["chain_id"], &chainID) + require.NoError(t, err) +} + +func executeStart(t *testing.T, servAddr, port string) { + proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("democoind start --home=%s --rpc.laddr=%v", democoindHome, servAddr)) + defer proc.Stop(false) + tests.WaitForTMStart(port) +} + +func getTestingHomeDir() string { + tmpDir := os.TempDir() + democoindHome := fmt.Sprintf("%s%s.test_democoind", tmpDir, string(os.PathSeparator)) + return democoindHome +} diff --git a/types/errors.go b/types/errors.go index 58541dfea9..45ef79f56a 100644 --- a/types/errors.go +++ b/types/errors.go @@ -2,9 +2,11 @@ package types import ( "fmt" + "strings" cmn "github.com/tendermint/tendermint/libs/common" + "github.com/cosmos/cosmos-sdk/wire" abci "github.com/tendermint/tendermint/abci/types" ) @@ -225,7 +227,11 @@ func (err *sdkError) TraceSDK(format string, args ...interface{}) Error { // Implements ABCIError. // Overrides err.Error.Error(). func (err *sdkError) Error() string { - return fmt.Sprintf("Error{%d:%d,%#v}", err.codespace, err.code, err.cmnError) + return fmt.Sprintf(`ERROR: +Codespace: %d +Code: %d +Message: %#v +`, err.codespace, err.code, parseCmnError(err.cmnError.Error())) } // Implements ABCIError. @@ -245,13 +251,20 @@ func (err *sdkError) Code() CodeType { // Implements ABCIError. func (err *sdkError) ABCILog() string { - return fmt.Sprintf(`=== ABCI Log === -Codespace: %v -Code: %v -ABCICode: %v -Error: %#v -=== /ABCI Log === -`, err.codespace, err.code, err.ABCICode(), err.cmnError) + cdc := wire.NewCodec() + parsedErrMsg := parseCmnError(err.cmnError.Error()) + jsonErr := humanReadableError{ + Codespace: err.codespace, + Code: err.code, + ABCICode: err.ABCICode(), + Message: parsedErrMsg, + } + bz, er := cdc.MarshalJSON(jsonErr) + if er != nil { + panic(er) + } + stringifiedJSON := string(bz) + return stringifiedJSON } func (err *sdkError) Result() Result { @@ -268,3 +281,18 @@ func (err *sdkError) QueryResult() abci.ResponseQuery { Log: err.ABCILog(), } } + +func parseCmnError(err string) string { + if idx := strings.Index(err, "{"); idx != -1 { + err = err[idx+1 : len(err)-1] + } + return err +} + +// nolint +type humanReadableError struct { + Codespace CodespaceType `json:"codespace"` + Code CodeType `json:"code"` + ABCICode ABCICodeType `json:"abci_code"` + Message string `json:"message"` +} diff --git a/types/errors_test.go b/types/errors_test.go index e7625e96f8..f00b2600ca 100644 --- a/types/errors_test.go +++ b/types/errors_test.go @@ -57,7 +57,10 @@ func TestErrFn(t *testing.T) { err := errFn("") codeType := codeTypes[i] require.Equal(t, err.Code(), codeType, "Err function expected to return proper code. tc #%d", i) + require.Equal(t, err.Codespace(), CodespaceRoot, "Err function expected to return proper codespace. tc #%d", i) require.Equal(t, err.Result().Code, ToABCICode(CodespaceRoot, codeType), "Err function expected to return proper ABCICode. tc #%d") + require.Equal(t, err.QueryResult().Code, uint32(err.ABCICode()), "Err function expected to return proper ABCICode from QueryResult. tc #%d") + require.Equal(t, err.QueryResult().Log, err.ABCILog(), "Err function expected to return proper ABCILog from QueryResult. tc #%d") } require.Equal(t, ABCICodeOK, ToABCICode(CodespaceRoot, CodeOK))