refactor(systemtests): Extract system test framework (#22578)

Co-authored-by: marbar3778 <marbar3778@yahoo.com>
This commit is contained in:
Alexander Peters
2024-11-26 14:46:54 +00:00
committed by GitHub
co-authored by marbar3778
parent f153426ab2
commit 14d98d2771
38 changed files with 2266 additions and 676 deletions
+1
View File
@@ -22,6 +22,7 @@ use (
./server/v2/appmanager
./store
./store/v2
./systemtests
./runtime/v2
./tools/cosmovisor
./tools/confix
+41
View File
@@ -0,0 +1,41 @@
<!--
Guiding Principles:
Changelogs are for humans, not machines.
There should be an entry for every single version.
The same types of changes should be grouped.
Versions and sections should be linkable.
The latest version comes first.
The release date of each version is displayed.
Mention whether you follow Semantic Versioning.
Usage:
Changelog entries are generated by git cliff ref: https://github.com/orhun/git-cliff
Each commit should be conventional, the following message groups are supported.
* feat: A new feature
* fix: A bug fix
* docs: Documentation only changes
* style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
* refactor: A code change that neither fixes a bug nor adds a feature
* perf: A code change that improves performance
* test: Adding missing tests or correcting existing tests
* build: Changes that affect the build system or external dependencies (example scopes: go, npm)
* ci: Changes to our CI configuration files and scripts (example scopes: GH Actions)
* chore: Other changes that don't modify src or test files
* revert: Reverts a previous commit
When a change is made that affects the API or state machine, the commit message prefix should be suffixed with `!`.
Ref: https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json
-->
# Changelog
## [Unreleased]
### Features
* [#22578](https://github.com/cosmos/cosmos-sdk/pull/22578) Extract system test framework
+63
View File
@@ -0,0 +1,63 @@
# System Tests
This package contains the testing framework for black-box system tests. It includes a test runner that sets up a
multi-node blockchain locally for use in tests. The framework provides utilities and helpers for easy access and
setup in tests.
## Components
- **CLI**: Command-line interface wrapper for interacting with the chain or keyring
- **Servers**: Server instances to run the blockchain environment.
- **Events**: Event listeners
- **RPC**: Remote Procedure Call setup for communication.
## Dependencies
- **testify**: Testing toolkit.
- **gjson**: JSON parser.
- **sjson**: JSON modifier.
Server and client-side operations are executed on the host machine.
## Developer
### Test strategy
System tests cover the full stack via cli and a running (multi node) network. They are more expensive (in terms of time/ cpu)
to run compared to unit or integration tests.
Therefore, we focus on the **critical path** and do not cover every condition.
## How to use
Read the [getting_started.md](../tests/systemtests/getting_started.md) guide to get started.
### Execute a single test
```sh
go test -tags system_test -count=1 -v . --run TestStakeUnstake -verbose
```
Test cli parameters
* `-verbose` verbose output
* `-wait-time` duration - time to wait for chain events (default 30s)
* `-nodes-count` int - number of nodes in the cluster (default 4)
# Port ranges
With *n* nodes:
* `26657` - `26657+n` - RPC
* `1317` - `1317+n` - API
* `9090` - `9090+n` - GRPC
* `16656` - `16656+n` - P2P
For example Node *3* listens on `26660` for RPC calls
## Resources
* [gjson query syntax](https://github.com/tidwall/gjson#path-syntax)
## Disclaimer
This is based on the system test framework in [wasmd](https://github.com/CosmWasm/wasmd) built by Confio.
+52 -42
View File
@@ -100,39 +100,31 @@ func (c CLIWrapper) WithRunErrorsIgnored() CLIWrapper {
// WithRunErrorMatcher assert function to ensure run command error value
func (c CLIWrapper) WithRunErrorMatcher(f RunErrorAssert) CLIWrapper {
return *NewCLIWrapperX(
c.t,
c.execBinary,
c.nodeAddress,
c.chainID,
c.awaitNextBlock,
c.nodesCount,
c.homeDir,
c.fees,
c.Debug,
f,
c.expTXCommitted,
)
return c.clone(func(r *CLIWrapper) {
r.assertErrorFn = f
})
}
func (c CLIWrapper) WithNodeAddress(nodeAddr string) CLIWrapper {
return *NewCLIWrapperX(
c.t,
c.execBinary,
nodeAddr,
c.chainID,
c.awaitNextBlock,
c.nodesCount,
c.homeDir,
c.fees,
c.Debug,
c.assertErrorFn,
c.expTXCommitted,
)
return c.clone(func(r *CLIWrapper) {
r.nodeAddress = nodeAddr
})
}
func (c CLIWrapper) WithAssertTXUncommitted() CLIWrapper {
return *NewCLIWrapperX(
return c.clone(func(r *CLIWrapper) {
r.expTXCommitted = false
})
}
func (c CLIWrapper) WithChainID(newChainID string) CLIWrapper {
return c.clone(func(r *CLIWrapper) {
r.chainID = newChainID
})
}
func (c CLIWrapper) clone(mutator ...func(r *CLIWrapper)) CLIWrapper {
r := NewCLIWrapperX(
c.t,
c.execBinary,
c.nodeAddress,
@@ -143,8 +135,12 @@ func (c CLIWrapper) WithAssertTXUncommitted() CLIWrapper {
c.fees,
c.Debug,
c.assertErrorFn,
false,
c.expTXCommitted,
)
for _, m := range mutator {
m(r)
}
return *r
}
// Run main entry for executing cli commands.
@@ -156,7 +152,7 @@ func (c CLIWrapper) Run(args ...string) string {
}) {
args = append(args, "--fees="+c.fees) // add default fee
}
args = c.withTXFlags(args...)
args = c.WithTXFlags(args...)
execOutput, ok := c.run(args)
if !ok {
return execOutput
@@ -207,14 +203,14 @@ func (c CLIWrapper) AwaitTxCommitted(submitResp string, timeout ...time.Duration
// Keys wasmd keys CLI command
func (c CLIWrapper) Keys(args ...string) string {
args = c.withKeyringFlags(args...)
args = c.WithKeyringFlags(args...)
out, _ := c.run(args)
return out
}
// CustomQuery main entrypoint for wasmd CLI queries
func (c CLIWrapper) CustomQuery(args ...string) string {
args = c.withQueryFlags(args...)
args = c.WithQueryFlags(args...)
out, _ := c.run(args)
return out
}
@@ -254,23 +250,32 @@ func (c CLIWrapper) runWithInput(args []string, input io.Reader) (output string,
return strings.TrimSpace(string(gotOut)), ok
}
func (c CLIWrapper) withQueryFlags(args ...string) []string {
// WithQueryFlags append the test default query flags to the given args
func (c CLIWrapper) WithQueryFlags(args ...string) []string {
args = append(args, "--output", "json")
return c.withChainFlags(args...)
return c.WithTargetNodeFlags(args...)
}
func (c CLIWrapper) withTXFlags(args ...string) []string {
// WithTXFlags append the test default TX flags to the given args.
// This includes
// - broadcast-mode: sync
// - output: json
// - chain-id
// - keyring flags
// - target-node
func (c CLIWrapper) WithTXFlags(args ...string) []string {
args = append(args,
"--broadcast-mode", "sync",
"--output", "json",
"--yes",
"--chain-id", c.chainID,
)
args = c.withKeyringFlags(args...)
return c.withChainFlags(args...)
args = c.WithKeyringFlags(args...)
return c.WithTargetNodeFlags(args...)
}
func (c CLIWrapper) withKeyringFlags(args ...string) []string {
// WithKeyringFlags append the test default keyring flags to the given args
func (c CLIWrapper) WithKeyringFlags(args ...string) []string {
r := append(args,
"--home", c.homeDir,
"--keyring-backend", "test",
@@ -283,7 +288,8 @@ func (c CLIWrapper) withKeyringFlags(args ...string) []string {
return append(r, "--output", "json")
}
func (c CLIWrapper) withChainFlags(args ...string) []string {
// WithTargetNodeFlags append the test default target node address flags to the given args
func (c CLIWrapper) WithTargetNodeFlags(args ...string) []string {
return append(args,
"--node", c.nodeAddress,
)
@@ -297,7 +303,7 @@ func (c CLIWrapper) WasmExecute(contractAddr, msg, from string, args ...string)
// AddKey add key to default keyring. Returns address
func (c CLIWrapper) AddKey(name string) string {
cmd := c.withKeyringFlags("keys", "add", name, "--no-backup")
cmd := c.WithKeyringFlags("keys", "add", name, "--no-backup")
out, _ := c.run(cmd)
addr := gjson.Get(out, "address").String()
require.NotEmpty(c.t, addr, "got %q", out)
@@ -306,7 +312,7 @@ func (c CLIWrapper) AddKey(name string) string {
// AddKeyFromSeed recovers the key from given seed and add it to default keyring. Returns address
func (c CLIWrapper) AddKeyFromSeed(name, mnemoic string) string {
cmd := c.withKeyringFlags("keys", "add", name, "--recover")
cmd := c.WithKeyringFlags("keys", "add", name, "--recover")
out, _ := c.runWithInput(cmd, strings.NewReader(mnemoic))
addr := gjson.Get(out, "address").String()
require.NotEmpty(c.t, addr, "got %q", out)
@@ -315,7 +321,7 @@ func (c CLIWrapper) AddKeyFromSeed(name, mnemoic string) string {
// GetKeyAddr returns Acc address
func (c CLIWrapper) GetKeyAddr(name string) string {
cmd := c.withKeyringFlags("keys", "show", name, "-a")
cmd := c.WithKeyringFlags("keys", "show", name, "-a")
out, _ := c.run(cmd)
addr := strings.Trim(out, "\n")
require.NotEmpty(c.t, addr, "got %q", out)
@@ -324,7 +330,7 @@ func (c CLIWrapper) GetKeyAddr(name string) string {
// GetKeyAddrPrefix returns key address with Beach32 prefix encoding for a key (acc|val|cons)
func (c CLIWrapper) GetKeyAddrPrefix(name, prefix string) string {
cmd := c.withKeyringFlags("keys", "show", name, "-a", "--bech="+prefix)
cmd := c.WithKeyringFlags("keys", "show", name, "-a", "--bech="+prefix)
out, _ := c.run(cmd)
addr := strings.Trim(out, "\n")
require.NotEmpty(c.t, addr, "got %q", out)
@@ -413,6 +419,10 @@ func (c CLIWrapper) SubmitAndVoteGovProposal(proposalJson string, args ...string
return ourProposalID
}
func (c CLIWrapper) ChainID() string {
return c.chainID
}
// Version returns the current version of the client binary
func (c CLIWrapper) Version() string {
v, ok := c.run([]string{"version"})
+215
View File
@@ -0,0 +1,215 @@
# Getting started with a new system test
## Preparation
Build a new binary from current branch and copy it to the `tests/systemtests/binaries` folder by running system tests.
In project root:
```shell
make test-system
```
Or via manual steps
```shell
make build
mkdir -p ./tests/systemtests/binaries
cp ./build/simd ./tests/systemtests/binaries/
```
## Part 1: Writing the first system test
Switch to the `tests/systemtests` folder to work from here.
If there is no test file matching your use case, start a new test file here.
for example `bank_test.go` to begin with:
```go
//go:build system_test
package systemtests
import (
"testing"
)
func TestQueryTotalSupply(t *testing.T) {
sut.ResetChain(t)
sut.StartChain(t)
cli := NewCLIWrapper(t, sut, verbose)
raw := cli.CustomQuery("q", "bank", "total-supply")
t.Log("### got: " + raw)
}
```
The file begins with a Go build tag to exclude it from regular go test runs.
All tests in the `systemtests` folder build upon the *test runner* initialized in `main_test.go`.
This gives you a multi node chain started on your box.
It is a good practice to reset state in the beginning so that you have a stable base.
The system tests framework comes with a CLI wrapper that makes it easier to interact or parse results.
In this example we want to execute `simd q bank total-supply --output json --node tcp://localhost:26657` which queries
the bank module.
Then print the result to for the next steps
### Run the test
```shell
go test -mod=readonly -tags='system_test' -v ./... --run TestQueryTotalSupply --verbose
```
This give very verbose output. You would see all simd CLI commands used for starting the server or by the client to interact.
In the example code, we just log the output. Watch out for
```shell
bank_test.go:15: ### got: {
"supply": [
{
"denom": "stake",
"amount": "2000000190"
},
{
"denom": "testtoken",
"amount": "4000000000"
}
],
"pagination": {
"total": "2"
}
}
```
At the end is a tail from the server log printed. This can sometimes be handy when debugging issues.
### Tips
* Passing `--nodes-count=1` overwrites the default node count and can speed up your test for local runs
## Part 2: Working with json
When we have a json response, the [gjson](https://github.com/tidwall/gjson) lib can shine. It comes with jquery like
syntax that makes it easy to navigation within the document.
For example `gjson.Get(raw, "supply").Array()` gives us all the childs to `supply` as an array.
Or `gjson.Get("supply.#(denom==stake).amount").Int()` for the amount of the stake token as int64 type.
In order to test our assumptions in the system test, we modify the code to use `gjson` to fetch the data:
```go
raw := cli.CustomQuery("q", "bank", "total-supply")
exp := map[string]int64{
"stake": int64(500000000 * sut.nodesCount),
"testtoken": int64(1000000000 * sut.nodesCount),
}
require.Len(t, gjson.Get(raw, "supply").Array(), len(exp), raw)
for k, v := range exp {
got := gjson.Get(raw, fmt.Sprintf("supply.#(denom==%q).amount", k)).Int()
assert.Equal(t, v, got, raw)
}
```
The assumption on the staking token usually fails due to inflation minted on the staking token. Let's fix this in the next step
### Run the test
```shell
go test -mod=readonly -tags='system_test' -v ./... --run TestQueryTotalSupply --verbose
```
### Tips
* Putting the `raw` json response to the assert/require statements helps with debugging on failures. You are usually lacking
context when you look at the values only.
## Part 3: Setting state via genesis
First step is to disable inflation. This can be done via the `ModifyGenesisJSON` helper. But to add some complexity,
we also introduce a new token and update the balance of the account for key `node0`.
The setup code looks quite big and unreadable now. Usually a good time to think about extracting helper functions for
common operations. The `genesis_io.go` file contains some examples already. I would skip this and take this to showcase the mix
of `gjson`, `sjson` and stdlib json operations.
```go
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
sut.ModifyGenesisJSON(t, func(genesis []byte) []byte {
// disable inflation
genesis, err := sjson.SetRawBytes(genesis, "app_state.mint.minter.inflation", []byte(`"0.000000000000000000"`))
require.NoError(t, err)
// add new token to supply
var supply []json.RawMessage
rawSupply := gjson.Get(string(genesis), "app_state.bank.supply").String()
require.NoError(t, json.Unmarshal([]byte(rawSupply), &supply))
supply = append(supply, json.RawMessage(`{"denom": "mytoken","amount": "1000000"}`))
newSupply, err := json.Marshal(supply)
require.NoError(t, err)
genesis, err = sjson.SetRawBytes(genesis, "app_state.bank.supply", newSupply)
require.NoError(t, err)
// add amount to any balance
anyAddr := cli.GetKeyAddr("node0")
newBalances := GetGenesisBalance(genesis, anyAddr).Add(sdk.NewInt64Coin("mytoken", 1000000))
newBalancesBz, err := newBalances.MarshalJSON()
require.NoError(t, err)
newState, err := sjson.SetRawBytes(genesis, fmt.Sprintf("app_state.bank.balances.#[address==%q]#.coins", anyAddr), newBalancesBz)
require.NoError(t, err)
return newState
})
sut.StartChain(t)
```
Next step is to add the new token to the assert map. But we can also make it more resilient to different node counts.
```go
exp := map[string]int64{
"stake": int64(500000000 * sut.nodesCount),
"testtoken": int64(1000000000 * sut.nodesCount),
"mytoken": 1000000,
}
```
```shell
go test -mod=readonly -tags='system_test' -v ./... --run TestQueryTotalSupply --verbose --nodes-count=1
```
## Part 4: Set state via TX
Complexer workflows and tests require modifying state on a running chain. This works only with builtin logic and operations.
If we want to burn some of our new tokens, we need to submit a bank burn message to do this.
The CLI wrapper works similar to the query. Just pass the parameters. It uses the `node0` key as *default*:
```go
// and when
txHash := cli.Run("tx", "bank", "burn", "node0", "400000mytoken")
RequireTxSuccess(t, txHash)
```
`RequireTxSuccess` or `RequireTxFailure` can be used to ensure the expected result of the operation.
Next, check that the changes are applied.
```go
exp["mytoken"] = 600_000 // update expected state
raw = cli.CustomQuery("q", "bank", "total-supply")
for k, v := range exp {
got := gjson.Get(raw, fmt.Sprintf("supply.#(denom==%q).amount", k)).Int()
assert.Equal(t, v, got, raw)
}
assert.Equal(t, int64(600_000), cli.QueryBalance(cli.GetKeyAddr("node0"), "mytoken"))
```
While tests are still more or less readable, it can gets harder the longer they are. I found it helpful to add
some comments at the beginning to describe what the intention is. For example:
```go
// scenario:
// given a chain with a custom token on genesis
// when an amount is burned
// then this is reflected in the total supply
```
+171
View File
@@ -0,0 +1,171 @@
module cosmossdk.io/systemtests
go 1.23
require (
github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect
github.com/cosmos/cosmos-sdk v0.50.6
github.com/cosmos/gogogateway v1.2.0 // indirect
github.com/cosmos/gogoproto v1.7.0 // indirect
github.com/cosmos/iavl v1.1.4 // indirect
github.com/dvsekhvalnov/jose2go v1.6.0 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.20.5 // indirect
github.com/spf13/cast v1.7.0 // indirect
github.com/spf13/cobra v1.8.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/testify v1.9.0
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
google.golang.org/grpc v1.68.0
)
require (
cosmossdk.io/math v1.4.0
github.com/cometbft/cometbft v0.38.15
github.com/cometbft/cometbft/api v1.0.0-rc.1
github.com/creachadair/tomledit v0.0.26
github.com/tidwall/gjson v1.14.2
github.com/tidwall/sjson v1.2.5
)
require (
cosmossdk.io/api v0.7.6 // indirect
cosmossdk.io/collections v0.4.0 // indirect
cosmossdk.io/core v0.11.0 // indirect
cosmossdk.io/depinject v1.1.0 // indirect
cosmossdk.io/errors v1.0.1 // indirect
cosmossdk.io/log v1.5.0 // indirect
cosmossdk.io/store v1.1.0 // indirect
cosmossdk.io/x/tx v0.13.3-0.20240419091757-db5906b1e894 // indirect
filippo.io/edwards25519 v1.0.0 // indirect
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
github.com/99designs/keyring v1.2.1 // indirect
github.com/DataDog/datadog-go v3.2.0+incompatible // indirect
github.com/DataDog/zstd v1.5.5 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bgentry/speakeasy v0.2.0 // indirect
github.com/bytedance/sonic v1.12.4 // indirect
github.com/bytedance/sonic/loader v0.2.1 // indirect
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
github.com/cockroachdb/errors v1.11.3 // indirect
github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
github.com/cockroachdb/pebble v1.1.1 // indirect
github.com/cockroachdb/redact v1.1.5 // indirect
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
github.com/cometbft/cometbft-db v0.14.1 // indirect
github.com/cosmos/btcutil v1.0.5 // indirect
github.com/cosmos/cosmos-db v1.0.3-0.20240829004618-717cba019b33 // indirect
github.com/cosmos/go-bip39 v1.0.0 // indirect
github.com/cosmos/ics23/go v0.11.0 // indirect
github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect
github.com/danieljoos/wincred v1.1.2 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect
github.com/dgraph-io/badger/v4 v4.2.0 // indirect
github.com/dgraph-io/ristretto v0.1.1 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/emicklei/dot v1.6.2 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.8.0 // indirect
github.com/getsentry/sentry-go v0.27.0 // indirect
github.com/go-kit/kit v0.13.0 // indirect
github.com/go-kit/log v0.2.1 // indirect
github.com/go-logfmt/logfmt v0.6.0 // indirect
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
github.com/gogo/googleapis v1.4.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/glog v1.2.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/flatbuffers v1.12.1 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/orderedcode v0.0.1 // indirect
github.com/gorilla/handlers v1.5.1 // indirect
github.com/gorilla/websocket v1.5.3 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
github.com/hashicorp/go-hclog v1.6.3 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-metrics v0.5.3 // indirect
github.com/hashicorp/go-plugin v1.6.2 // indirect
github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/yamux v0.1.2 // indirect
github.com/hdevalence/ed25519consensus v0.1.0 // indirect
github.com/huandu/skiplist v1.2.1 // indirect
github.com/iancoleman/strcase v0.3.0 // indirect
github.com/improbable-eng/grpc-web v0.15.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jmhodges/levigo v1.0.0 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/linxGnu/grocksdb v1.9.3 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/minio/highwayhash v1.0.3 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mtibben/percent v0.2.1 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a // indirect
github.com/oklog/run v1.1.0 // indirect
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.60.1 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/rs/cors v1.11.1 // indirect
github.com/rs/zerolog v1.33.0 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sasha-s/go-deadlock v0.3.5 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/viper v1.19.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/tendermint/go-amino v0.16.0 // indirect
github.com/tidwall/btree v1.7.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/zondax/hid v0.9.2 // indirect
github.com/zondax/ledger-go v0.14.3 // indirect
go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5 // indirect
go.opencensus.io v0.24.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/arch v0.12.0 // indirect
golang.org/x/crypto v0.29.0 // indirect
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect
golang.org/x/net v0.30.0 // indirect
golang.org/x/sync v0.9.0 // indirect
golang.org/x/sys v0.27.0 // indirect
golang.org/x/term v0.26.0 // indirect
golang.org/x/text v0.20.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 // indirect
google.golang.org/protobuf v1.35.2 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gotest.tools/v3 v3.5.1 // indirect
nhooyr.io/websocket v1.8.6 // indirect
pgregory.net/rapid v1.1.0 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)
+1032
View File
File diff suppressed because it is too large Load Diff
@@ -12,21 +12,21 @@ import (
)
type RestTestCase struct {
name string
url string
expCode int
expOut string
Name string
Url string
ExpCode int
ExpOut string
}
// RunRestQueries runs given Rest testcases by making requests and
// checking response with expected output
func RunRestQueries(t *testing.T, testCases []RestTestCase) {
func RunRestQueries(t *testing.T, testCases ...RestTestCase) {
t.Helper()
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
resp := GetRequestWithHeaders(t, tc.url, nil, tc.expCode)
require.JSONEq(t, tc.expOut, string(resp))
t.Run(tc.Name, func(t *testing.T) {
resp := GetRequestWithHeaders(t, tc.Url, nil, tc.ExpCode)
require.JSONEq(t, tc.ExpOut, string(resp))
})
}
}
@@ -34,12 +34,12 @@ func RunRestQueries(t *testing.T, testCases []RestTestCase) {
// TestRestQueryIgnoreNumbers runs given rest testcases by making requests and
// checking response with expected output ignoring number values
// This method is used when number values in response are non-deterministic
func TestRestQueryIgnoreNumbers(t *testing.T, testCases []RestTestCase) {
func TestRestQueryIgnoreNumbers(t *testing.T, testCases ...RestTestCase) {
t.Helper()
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
resp, err := testutil.GetRequest(tc.url)
t.Run(tc.Name, func(t *testing.T) {
resp, err := testutil.GetRequest(tc.Url)
require.NoError(t, err)
// regular expression pattern to match any numeric value in the JSON
@@ -50,7 +50,7 @@ func TestRestQueryIgnoreNumbers(t *testing.T, testCases []RestTestCase) {
require.NoError(t, err)
// replace all numeric values in the above JSONs with `NUMBER` text
expectedJSON := r.ReplaceAllString(tc.expOut, `"NUMBER"`)
expectedJSON := r.ReplaceAllString(tc.ExpOut, `"NUMBER"`)
actualJSON := r.ReplaceAllString(string(resp), `"NUMBER"`)
// compare two jsons
@@ -37,6 +37,8 @@ var (
ExecBinaryUnversionedRegExp = regexp.MustCompile(`^(\w+)-?.*$`)
MaxGas = 10_000_000
// DefaultApiPort is the port for the node to interact with
DefaultApiPort = 1317
)
type TestnetInitializer interface {
@@ -89,7 +91,7 @@ func NewSystemUnderTest(execBinary string, verbose bool, nodesCount int, blockTi
outputDir: "./testnet",
blockTime: blockTime,
rpcAddr: "tcp://localhost:26657",
apiAddr: fmt.Sprintf("http://localhost:%d", apiPortStart),
apiAddr: fmt.Sprintf("http://localhost:%d", DefaultApiPort),
initialNodesCount: nodesCount,
outBuff: ring.New(100),
errBuff: ring.New(100),
@@ -99,18 +101,34 @@ func NewSystemUnderTest(execBinary string, verbose bool, nodesCount int, blockTi
projectName: nameTokens[0],
pids: make(map[int]struct{}, nodesCount),
}
s.testnetInitializer = NewSingleHostTestnetCmdInitializer(execBinary, WorkDir, s.chainID, s.outputDir, s.initialNodesCount, s.minGasPrice, s.CommitTimeout(), s.Log)
if len(initer) > 0 {
s.testnetInitializer = initer[0]
} else {
s.testnetInitializer = NewSingleHostTestnetCmdInitializer(execBinary, WorkDir, s.chainID, s.outputDir, s.initialNodesCount, s.minGasPrice, s.CommitTimeout(), s.Log)
}
return s
}
// SetExecBinary sets the executable binary for the system under test.
func (s *SystemUnderTest) SetExecBinary(binary string) {
s.execBinary = binary
}
// ExecBinary returns the path of the binary executable associated with the SystemUnderTest instance.
func (s *SystemUnderTest) ExecBinary() string {
return s.execBinary
}
// SetTestnetInitializer sets the initializer for the testnet configuration.
func (s *SystemUnderTest) SetTestnetInitializer(testnetInitializer TestnetInitializer) {
s.testnetInitializer = testnetInitializer
}
// TestnetInitializer returns the testnet initializer associated with the SystemUnderTest.
func (s *SystemUnderTest) TestnetInitializer() TestnetInitializer {
return s.testnetInitializer
}
// CommitTimeout returns the max time to wait for a commit. Default to 90% of block time
func (s *SystemUnderTest) CommitTimeout() time.Duration {
// The commit timeout is a lower bound for the block time. We try to set it to a level that allows us to reach the expected block time.
@@ -763,6 +781,10 @@ func (s *SystemUnderTest) NodesCount() int {
return s.nodesCount
}
func (s *SystemUnderTest) BlockTime() time.Duration {
return s.blockTime
}
type Node struct {
ID string
IP string
@@ -14,8 +14,8 @@ import (
)
var (
sut *SystemUnderTest
verbose bool
Sut *SystemUnderTest
Verbose bool
execBinaryName string
)
@@ -25,7 +25,7 @@ func RunTests(m *testing.M) {
blockTime := flag.Duration("block-time", 1000*time.Millisecond, "block creation time")
execBinary := flag.String("binary", "simd", "executable binary for server/ client side")
bech32Prefix := flag.String("bech32", "cosmos", "bech32 prefix to be used with addresses")
flag.BoolVar(&verbose, "verbose", false, "verbose output")
flag.BoolVar(&Verbose, "verbose", false, "verbose output")
flag.Parse()
// fail fast on most common setup issue
@@ -36,7 +36,7 @@ func RunTests(m *testing.M) {
panic(err)
}
WorkDir = dir
if verbose {
if Verbose {
println("Work dir: ", WorkDir)
}
initSDKConfig(*bech32Prefix)
@@ -47,16 +47,16 @@ func RunTests(m *testing.M) {
}
execBinaryName = *execBinary
sut = NewSystemUnderTest(*execBinary, verbose, *nodesCount, *blockTime)
sut.SetupChain() // setup chain and keyring
Sut = NewSystemUnderTest(*execBinary, Verbose, *nodesCount, *blockTime)
Sut.SetupChain() // setup chain and keyring
// run tests
exitCode := m.Run()
// postprocess
sut.StopChain()
if verbose || exitCode != 0 {
sut.PrintBuffer()
Sut.StopChain()
if Verbose || exitCode != 0 {
Sut.PrintBuffer()
printResultFlag(exitCode == 0)
}
@@ -64,11 +64,11 @@ func RunTests(m *testing.M) {
}
func GetSystemUnderTest() *SystemUnderTest {
return sut
return Sut
}
func IsVerbose() bool {
return verbose
return Verbose
}
func GetExecutableName() string {
@@ -13,8 +13,8 @@ import (
"github.com/creachadair/tomledit/parser"
)
// isV2 checks if the tests run with simapp v2
func isV2() bool {
// IsV2 checks if the tests run with simapp v2
func IsV2() bool {
buildOptions := os.Getenv("COSMOS_BUILD_OPTIONS")
return strings.Contains(buildOptions, "v2")
}
@@ -77,7 +77,7 @@ func (s SingleHostTestnetCmdInitializer) Initialize() {
"--single-host",
}
if isV2() {
if IsV2() {
args = append(args, "--server.minimum-gas-prices="+s.minGasPrice)
} else {
args = append(args, "--minimum-gas-prices="+s.minGasPrice)
@@ -136,7 +136,7 @@ func (s ModifyConfigYamlInitializer) Initialize() {
"--keyring-backend=test",
}
if isV2() {
if IsV2() {
args = append(args, "--server.minimum-gas-prices="+s.minGasPrice)
} else {
args = append(args, "--minimum-gas-prices="+s.minGasPrice)
+1
View File
@@ -1,2 +1,3 @@
/testnet
/binaries
foo/
+31 -44
View File
@@ -1,61 +1,48 @@
# Testing
# System tests
Test framework for system tests.
Starts and interacts with a (multi node) blockchain in Go.
Supports
Go black box tests that setup and interact with a local blockchain. The system test [framework](../../systemtests)
works with the compiled binary of the chain artifact only.
To get up to speed, checkout the [getting started guide](../../systemtests/getting_started.md).
* CLI
* Servers
* Events
* RPC
Beside the Go tests and testdata files, this directory can contain the following directories:
Uses:
* `binaries` - cache for binary
* `testnet` - node files
* testify
* gjson
* sjson
Please make sure to not add or push them to git.
Server and client side are executed on the host machine.
## Execution
## Developer
Build a new binary from current branch and copy it to the `tests/systemtests/binaries` folder by running system tests.
In project root:
### Test strategy
System tests cover the full stack via cli and a running (multi node) network. They are more expensive (in terms of time/ cpu)
to run compared to unit or integration tests.
Therefore, we focus on the **critical path** and do not cover every condition.
## How to use
Read the [getting_started.md](getting_started.md) guide to get started.
### Execute a single test
```sh
go test -tags system_test -count=1 -v . --run TestStakeUnstake -verbose
```shell
make test-system
```
Test cli parameters
Or via manual steps
* `-verbose` verbose output
* `-wait-time` duration - time to wait for chain events (default 30s)
* `-nodes-count` int - number of nodes in the cluster (default 4)
```shell
make build
mkdir -p ./tests/systemtests/binaries
cp ./build/simd ./tests/systemtests/binaries/
```
# Port ranges
### Manual test run
With *n* nodes:
```shell
go test -v -mod=readonly -failfast -tags='system_test' --run TestStakeUnstake ./... --verbose
```
* `26657` - `26657+n` - RPC
* `1317` - `1317+n` - API
* `9090` - `9090+n` - GRPC
* `16656` - `16656+n` - P2P
### Working with macOS
For example Node *3* listens on `26660` for RPC calls
Most tests should function seamlessly. However, the file [upgrade_test.go](upgrade_test.go) includes a **build annotation** for Linux only.
## Resources
For the system upgrade test, an older version of the binary is utilized to perform a chain upgrade. This artifact is retrieved from a Docker container built for Linux.
* [gjson query syntax](https://github.com/tidwall/gjson#path-syntax)
To circumvent this limitation locally:
1. Checkout and build the older version of the artifact from a specific tag for your OS.
2. Place the built artifact into the `binaries` folder.
3. Ensure that the filename, including the version, is correct.
## Disclaimer
This is based on the system test framework in [wasmd](https://github.com/CosmWasm/wasmd) built by Confio.
With the cached artifact in place, the test will use this file instead of attempting to pull it from Docker.
+16 -14
View File
@@ -8,6 +8,8 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tidwall/gjson"
systest "cosmossdk.io/systemtests"
)
func TestAccountCreation(t *testing.T) {
@@ -18,24 +20,24 @@ func TestAccountCreation(t *testing.T) {
// when accountB is sending funds to accountA,
// AccountB should be created
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
systest.Sut.ResetChain(t)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// add genesis account with some tokens
account1Addr := cli.AddKey("account1")
account2Addr := cli.AddKey("account2")
require.NotEqual(t, account1Addr, account2Addr)
sut.ModifyGenesisCLI(t,
systest.Sut.ModifyGenesisCLI(t,
[]string{"genesis", "add-genesis-account", account1Addr, "10000000stake"},
)
sut.StartChain(t)
systest.Sut.StartChain(t)
// query account1
rsp := cli.CustomQuery("q", "auth", "account", account1Addr)
assert.Equal(t, account1Addr, gjson.Get(rsp, "account.value.address").String(), rsp)
rsp1 := cli.RunAndWait("tx", "bank", "send", account1Addr, account2Addr, "5000stake", "--from="+account1Addr, "--fees=1stake")
RequireTxSuccess(t, rsp1)
systest.RequireTxSuccess(t, rsp1)
// query account2
assertNotFound := func(t assert.TestingT, err error, msgAndArgs ...interface{}) (ok bool) {
@@ -44,7 +46,7 @@ func TestAccountCreation(t *testing.T) {
_ = cli.WithRunErrorMatcher(assertNotFound).CustomQuery("q", "auth", "account", account2Addr)
rsp3 := cli.RunAndWait("tx", "bank", "send", account2Addr, account1Addr, "1000stake", "--from="+account2Addr, "--fees=1stake")
RequireTxSuccess(t, rsp3)
systest.RequireTxSuccess(t, rsp3)
// query account2 to make sure its created
rsp4 := cli.CustomQuery("q", "auth", "account", account2Addr)
@@ -54,19 +56,19 @@ func TestAccountCreation(t *testing.T) {
}
func TestAccountsMigration(t *testing.T) {
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
systest.Sut.ResetChain(t)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
legacyAddress := cli.GetKeyAddr(defaultSrcAddr)
legacyAddress := cli.GetKeyAddr("node0")
// Create a receiver account
receiverName := "receiver-account"
receiverAddress := cli.AddKey(receiverName)
require.NotEmpty(t, receiverAddress)
sut.ModifyGenesisCLI(t,
systest.Sut.ModifyGenesisCLI(t,
[]string{"genesis", "add-genesis-account", receiverAddress, "1000000stake"},
)
sut.StartChain(t)
systest.Sut.StartChain(t)
// Get pubkey
pubKeyValue := cli.GetPubKeyByCustomField(legacyAddress, "address")
@@ -99,7 +101,7 @@ func TestAccountsMigration(t *testing.T) {
fmt.Sprintf("--account-init-msg=%s", accountInitMsg),
fmt.Sprintf("--from=%s", legacyAddress),
"--fees=1stake")
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// 3. Now the account should be existed, query the account Sequence
rsp = cli.CustomQuery("q", "accounts", "query", legacyAddress, "cosmos.accounts.defaults.base.v1.QuerySequence", "{}")
@@ -121,7 +123,7 @@ func TestAccountsMigration(t *testing.T) {
transferAmount+"stake",
fmt.Sprintf("--from=%s", legacyAddress),
"--fees=1stake")
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// Verify the balances after the transaction
newLegacyBalance := cli.QueryBalance(legacyAddress, "stake")
@@ -151,5 +153,5 @@ func TestAccountsMigration(t *testing.T) {
rsp = cli.RunAndWait("tx", "accounts", "execute", legacyAddress, "cosmos.accounts.defaults.base.v1.MsgSwapPubKey", swapKeyMsg,
fmt.Sprintf("--from=%s", legacyAddress),
"--fees=1stake")
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
}
+63 -61
View File
@@ -10,6 +10,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
systest "cosmossdk.io/systemtests"
)
const (
@@ -20,10 +22,10 @@ func TestAuthSignAndBroadcastTxCmd(t *testing.T) {
// scenario: test auth sign and broadcast commands
// given a running chain
sut.ResetChain(t)
require.GreaterOrEqual(t, sut.NodesCount(), 2)
systest.Sut.ResetChain(t)
require.GreaterOrEqual(t, systest.Sut.NodesCount(), 2)
cli := NewCLIWrapper(t, sut, verbose)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator addresses
val1Addr := cli.GetKeyAddr("node0")
@@ -32,7 +34,7 @@ func TestAuthSignAndBroadcastTxCmd(t *testing.T) {
val2Addr := cli.GetKeyAddr("node1")
require.NotEmpty(t, val2Addr)
sut.StartChain(t)
systest.Sut.StartChain(t)
var transferAmount, feeAmount int64 = 1000, 1
@@ -40,37 +42,37 @@ func TestAuthSignAndBroadcastTxCmd(t *testing.T) {
// run bank tx send with --generate-only flag
sendTx := generateBankSendTx(t, cli, val1Addr, val2Addr, transferAmount, feeAmount, "")
txFile := StoreTempFile(t, []byte(fmt.Sprintf("%s\n", sendTx)))
txFile := systest.StoreTempFile(t, []byte(fmt.Sprintf("%s\n", sendTx)))
// query node0 account details
signTxCmd := []string{"tx", "sign", txFile.Name(), "--from=" + val1Addr, "--chain-id=" + cli.chainID}
signTxCmd := []string{"tx", "sign", txFile.Name(), "--from=" + val1Addr, "--chain-id=" + cli.ChainID()}
testSignTxBroadcast(t, cli, signTxCmd, "sign tx", val1Addr, val2Addr, transferAmount, feeAmount)
// test broadcast with empty public key in signed tx
rsp := cli.RunCommandWithArgs(cli.withTXFlags("tx", "sign", txFile.Name(), "--from="+val1Addr)...)
rsp := cli.RunCommandWithArgs(cli.WithTXFlags("tx", "sign", txFile.Name(), "--from="+val1Addr)...)
updated, err := sjson.Set(rsp, "auth_info.signer_infos.0.public_key", nil)
require.NoError(t, err)
newSignFile := StoreTempFile(t, []byte(updated))
newSignFile := systest.StoreTempFile(t, []byte(updated))
broadcastCmd := []string{"tx", "broadcast", newSignFile.Name()}
rsp = cli.RunCommandWithArgs(cli.withTXFlags(broadcastCmd...)...)
RequireTxFailure(t, rsp)
rsp = cli.RunCommandWithArgs(cli.WithTXFlags(broadcastCmd...)...)
systest.RequireTxFailure(t, rsp)
// test sign-batch tx command
// generate another bank send tx with less amount
newAmount := int64(100)
sendTx2 := generateBankSendTx(t, cli, val1Addr, val2Addr, newAmount, feeAmount, "")
tx2File := StoreTempFile(t, []byte(fmt.Sprintf("%s\n", sendTx2)))
tx2File := systest.StoreTempFile(t, []byte(fmt.Sprintf("%s\n", sendTx2)))
signBatchCmd := []string{"tx", "sign-batch", txFile.Name(), tx2File.Name(), "--from=" + val1Addr, "--chain-id=" + cli.chainID}
signBatchCmd := []string{"tx", "sign-batch", txFile.Name(), tx2File.Name(), "--from=" + val1Addr, "--chain-id=" + cli.ChainID()}
sendAmount := transferAmount + newAmount
fees := feeAmount * 2
testSignTxBroadcast(t, cli, signBatchCmd, "sign-batch tx", val1Addr, val2Addr, sendAmount, fees)
}
func testSignTxBroadcast(t *testing.T, cli *CLIWrapper, txCmd []string, prefix, fromAddr, toAddr string, amount, fees int64) {
func testSignTxBroadcast(t *testing.T, cli *systest.CLIWrapper, txCmd []string, prefix, fromAddr, toAddr string, amount, fees int64) {
t.Helper()
fromAddrBal := cli.QueryBalance(fromAddr, authTestDenom)
@@ -109,21 +111,21 @@ func testSignTxBroadcast(t *testing.T, cli *CLIWrapper, txCmd []string, prefix,
cmd := append(txCmd, tc.extraArgs...)
// run tx sign command and verify signatures count
rsp = cli.RunCommandWithArgs(cli.withKeyringFlags(cmd...)...)
rsp = cli.RunCommandWithArgs(cli.WithKeyringFlags(cmd...)...)
signatures := gjson.Get(rsp, "signatures").Array()
require.Len(t, signatures, 1)
signFile := StoreTempFile(t, []byte(rsp))
signFile := systest.StoreTempFile(t, []byte(rsp))
// validate signature
rsp = cli.RunCommandWithArgs(cli.withKeyringFlags("tx", "validate-signatures", signFile.Name(), "--from="+fromAddr, "--chain-id="+cli.chainID)...)
rsp = cli.RunCommandWithArgs(cli.WithKeyringFlags("tx", "validate-signatures", signFile.Name(), "--from="+fromAddr, "--chain-id="+cli.ChainID())...)
require.Contains(t, rsp, "[OK]")
// run broadcast tx command
broadcastCmd := []string{"tx", "broadcast", signFile.Name()}
rsp = cli.RunAndWait(broadcastCmd...)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// query balance and confirm transaction
expVal1Bal := fromAddrBal - amount - fees
@@ -141,10 +143,10 @@ func TestAuthQueryTxCmds(t *testing.T) {
// scenario: test query tx and txs commands
// given a running chain
sut.ResetChain(t)
require.GreaterOrEqual(t, sut.NodesCount(), 2)
systest.Sut.ResetChain(t)
require.GreaterOrEqual(t, systest.Sut.NodesCount(), 2)
cli := NewCLIWrapper(t, sut, verbose)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator addresses
val1Addr := cli.GetKeyAddr("node0")
@@ -153,12 +155,12 @@ func TestAuthQueryTxCmds(t *testing.T) {
val2Addr := cli.GetKeyAddr("node1")
require.NotEmpty(t, val2Addr)
sut.StartChain(t)
systest.Sut.StartChain(t)
// do a bank transfer and use it for query txs
feeAmount := "2stake"
rsp := cli.RunAndWait("tx", "bank", "send", val1Addr, val2Addr, "10000stake", "--fees="+feeAmount)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// parse values from above tx
height := gjson.Get(rsp, "height").String()
@@ -231,8 +233,8 @@ func TestAuthMultisigTxCmds(t *testing.T) {
// scenario: test auth multisig related tx commands
// given a running chain
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
systest.Sut.ResetChain(t)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
@@ -248,11 +250,11 @@ func TestAuthMultisigTxCmds(t *testing.T) {
acc3Addr := cli.AddKey("acc3")
require.NotEqual(t, acc1Addr, acc3Addr)
out := cli.RunCommandWithArgs(cli.withKeyringFlags("keys", "add", "multi", "--multisig=acc1,acc2,acc3", "--multisig-threshold=2")...)
out := cli.RunCommandWithArgs(cli.WithKeyringFlags("keys", "add", "multi", "--multisig=acc1,acc2,acc3", "--multisig-threshold=2")...)
multiAddr := gjson.Get(out, "address").String()
require.NotEmpty(t, multiAddr)
sut.StartChain(t)
systest.Sut.StartChain(t)
// fund multisig address some amount
var initialAmount, transferAmount, feeAmount int64 = 10000, 100, 1
@@ -265,10 +267,10 @@ func TestAuthMultisigTxCmds(t *testing.T) {
// run bank tx send with --generate-only flag
sendTx := generateBankSendTx(t, cli, multiAddr, valAddr, transferAmount, feeAmount, "")
txFile := StoreTempFile(t, []byte(sendTx))
txFile := systest.StoreTempFile(t, []byte(sendTx))
signTxCmd := cli.withKeyringFlags("tx", "sign", txFile.Name(), "--multisig="+multiAddr, "--chain-id="+cli.chainID)
multiSignTxCmd := cli.withKeyringFlags("tx", "multisign", txFile.Name(), "multi", "--chain-id="+cli.chainID)
signTxCmd := cli.WithKeyringFlags("tx", "sign", txFile.Name(), "--multisig="+multiAddr, "--chain-id="+cli.ChainID())
multiSignTxCmd := cli.WithKeyringFlags("tx", "multisign", txFile.Name(), "multi", "--chain-id="+cli.ChainID())
testMultisigTxBroadcast(t, cli, multiSigTxInput{
"multisign",
@@ -287,10 +289,10 @@ func TestAuthMultisigTxCmds(t *testing.T) {
// generate two send transactions in single file
multiSendTx := fmt.Sprintf("%s\n%s", sendTx, sendTx)
multiTxFile := StoreTempFile(t, []byte(multiSendTx))
multiTxFile := systest.StoreTempFile(t, []byte(multiSendTx))
signBatchTxCmd := cli.withKeyringFlags("tx", "sign-batch", multiTxFile.Name(), "--multisig="+multiAddr, "--signature-only", "--chain-id="+cli.chainID)
multiSignBatchTxCmd := cli.withKeyringFlags("tx", "multisign-batch", multiTxFile.Name(), "multi", "--chain-id="+cli.chainID)
signBatchTxCmd := cli.WithKeyringFlags("tx", "sign-batch", multiTxFile.Name(), "--multisig="+multiAddr, "--signature-only", "--chain-id="+cli.ChainID())
multiSignBatchTxCmd := cli.WithKeyringFlags("tx", "multisign-batch", multiTxFile.Name(), "multi", "--chain-id="+cli.ChainID())
// as we done couple of bank transactions as batch,
// transferred amount will be twice
@@ -311,7 +313,7 @@ func TestAuthMultisigTxCmds(t *testing.T) {
})
}
func generateBankSendTx(t *testing.T, cli *CLIWrapper, fromAddr, toAddr string, amount, fees int64, memo string) string {
func generateBankSendTx(t *testing.T, cli *systest.CLIWrapper, fromAddr, toAddr string, amount, fees int64, memo string) string {
t.Helper()
bankSendGenCmd := []string{
@@ -322,7 +324,7 @@ func generateBankSendTx(t *testing.T, cli *CLIWrapper, fromAddr, toAddr string,
"--note=" + memo,
}
return cli.RunCommandWithArgs(cli.withTXFlags(bankSendGenCmd...)...)
return cli.RunCommandWithArgs(cli.WithTXFlags(bankSendGenCmd...)...)
}
type multiSigTxInput struct {
@@ -338,7 +340,7 @@ type multiSigTxInput struct {
feeAmount int64
}
func testMultisigTxBroadcast(t *testing.T, cli *CLIWrapper, i multiSigTxInput) {
func testMultisigTxBroadcast(t *testing.T, cli *systest.CLIWrapper, i multiSigTxInput) {
t.Helper()
multiAddrBal := cli.QueryBalance(i.multiAddr, authTestDenom)
@@ -372,23 +374,23 @@ func testMultisigTxBroadcast(t *testing.T, cli *CLIWrapper, i multiSigTxInput) {
cmd := i.multiSignCmd
for _, acc := range tc.signingAccs {
rsp := cli.RunCommandWithArgs(append(i.signCmd, "--from="+acc)...)
signFile := StoreTempFile(t, []byte(rsp))
signFile := systest.StoreTempFile(t, []byte(rsp))
cmd = append(cmd, signFile.Name())
}
rsp := cli.RunCommandWithArgs(cmd...)
multiSignFile := StoreTempFile(t, []byte(rsp))
multiSignFile := systest.StoreTempFile(t, []byte(rsp))
// run broadcast tx command
broadcastCmd := []string{"tx", "broadcast", multiSignFile.Name()}
if tc.expErrMsg != "" {
rsp = cli.RunCommandWithArgs(cli.withTXFlags(broadcastCmd...)...)
RequireTxFailure(t, rsp)
rsp = cli.RunCommandWithArgs(cli.WithTXFlags(broadcastCmd...)...)
systest.RequireTxFailure(t, rsp)
require.Contains(t, rsp, tc.expErrMsg)
return
}
rsp = cli.RunAndWait(broadcastCmd...)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// query balance and confirm transaction
expMultiBal := multiAddrBal - i.transferAmount - i.feeAmount
@@ -406,10 +408,10 @@ func TestAuxSigner(t *testing.T) {
// scenario: test tx with direct aux sign mode
// given a running chain
sut.ResetChain(t)
require.GreaterOrEqual(t, sut.NodesCount(), 2)
systest.Sut.ResetChain(t)
require.GreaterOrEqual(t, systest.Sut.NodesCount(), 2)
cli := NewCLIWrapper(t, sut, verbose)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator addresses
val1Addr := cli.GetKeyAddr("node0")
@@ -418,7 +420,7 @@ func TestAuxSigner(t *testing.T) {
val2Addr := cli.GetKeyAddr("node1")
require.NotEmpty(t, val2Addr)
sut.StartChain(t)
systest.Sut.StartChain(t)
bankSendCmd := []string{"tx", "bank", "send", val1Addr, val2Addr, "10000stake", "--from=" + val1Addr}
@@ -467,7 +469,7 @@ func TestAuxSigner(t *testing.T) {
return false
}
_ = cli.WithRunErrorMatcher(assertTxOutput).Run(cli.withTXFlags(cmd...)...)
_ = cli.WithRunErrorMatcher(assertTxOutput).Run(cli.WithTXFlags(cmd...)...)
})
}
}
@@ -475,7 +477,7 @@ func TestAuxSigner(t *testing.T) {
func TestTxEncodeandDecode(t *testing.T) {
// scenario: test tx encode and decode commands
cli := NewCLIWrapper(t, sut, verbose)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator address
val1Addr := cli.GetKeyAddr("node0")
@@ -483,7 +485,7 @@ func TestTxEncodeandDecode(t *testing.T) {
memoText := "testmemo"
sendTx := generateBankSendTx(t, cli, val1Addr, val1Addr, 100, 1, memoText)
txFile := StoreTempFile(t, []byte(sendTx))
txFile := systest.StoreTempFile(t, []byte(sendTx))
// run encode command
encodedText := cli.RunCommandWithArgs("tx", "encode", txFile.Name())
@@ -501,45 +503,45 @@ func TestTxWithFeePayer(t *testing.T) {
// check tx executed ok
// check fees had been deducted from feePayers balance
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose).WithRunErrorsIgnored()
systest.Sut.ResetChain(t)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose).WithRunErrorsIgnored()
// add sender and feePayer accounts
senderAddr := cli.AddKey("sender")
sut.ModifyGenesisCLI(t,
systest.Sut.ModifyGenesisCLI(t,
[]string{"genesis", "add-genesis-account", senderAddr, "10000000stake"},
)
feePayerAddr := cli.AddKey("feePayer")
sut.ModifyGenesisCLI(t,
systest.Sut.ModifyGenesisCLI(t,
[]string{"genesis", "add-genesis-account", feePayerAddr, "10000000stake"},
)
sut.StartChain(t)
systest.Sut.StartChain(t)
// send a tx with FeePayer without his signature
rsp := cli.RunCommandWithArgs(cli.withTXFlags(
rsp := cli.RunCommandWithArgs(cli.WithTXFlags(
"tx", "bank", "send", senderAddr, "cosmos108jsm625z3ejy63uef2ke7t67h6nukt4ty93nr", "1000stake", "--fees", "1000000stake", "--fee-payer", feePayerAddr,
)...)
RequireTxFailure(t, rsp, "invalid number of signatures")
systest.RequireTxFailure(t, rsp, "invalid number of signatures")
// send tx with feePayers signature
rsp = cli.RunCommandWithArgs(cli.withTXFlags(
rsp = cli.RunCommandWithArgs(cli.WithTXFlags(
"tx", "bank", "send", senderAddr, "cosmos108jsm625z3ejy63uef2ke7t67h6nukt4ty93nr", "1000stake", "--fees", "1000000stake", "--fee-payer", feePayerAddr, "--generate-only",
)...)
tempFile := StoreTempFile(t, []byte(rsp))
tempFile := systest.StoreTempFile(t, []byte(rsp))
rsp = cli.RunCommandWithArgs(cli.withTXFlags(
rsp = cli.RunCommandWithArgs(cli.WithTXFlags(
"tx", "sign", tempFile.Name(), "--from", senderAddr, "--sign-mode", "amino-json",
)...)
tempFile = StoreTempFile(t, []byte(rsp))
tempFile = systest.StoreTempFile(t, []byte(rsp))
rsp = cli.RunCommandWithArgs(cli.withTXFlags(
rsp = cli.RunCommandWithArgs(cli.WithTXFlags(
"tx", "sign", tempFile.Name(), "--from", feePayerAddr, "--sign-mode", "amino-json",
)...)
tempFile = StoreTempFile(t, []byte(rsp))
tempFile = systest.StoreTempFile(t, []byte(rsp))
rsp = cli.RunAndWait([]string{"tx", "broadcast", tempFile.Name()}...)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// Query to check fee has been deducted from feePayer
balance := cli.QueryBalance(feePayerAddr, authTestDenom)
+68 -59
View File
@@ -12,6 +12,8 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tidwall/gjson"
systest "cosmossdk.io/systemtests"
)
const (
@@ -29,8 +31,8 @@ func TestAuthzGrantTxCmd(t *testing.T) {
// scenario: test authz grant command
// given a running chain
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
systest.Sut.ResetChain(t)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator address which will be used as granter
granterAddr := cli.GetKeyAddr("node0")
@@ -49,7 +51,7 @@ func TestAuthzGrantTxCmd(t *testing.T) {
grantee6Addr := cli.AddKey("grantee6")
require.NotEqual(t, granterAddr, grantee6Addr)
sut.StartChain(t)
systest.Sut.StartChain(t)
// query validator operator address
rsp := cli.CustomQuery("q", "staking", "validators")
@@ -202,7 +204,7 @@ func TestAuthzGrantTxCmd(t *testing.T) {
if tc.expErrMsg != "" {
if tc.queryTx {
rsp := cli.Run(cmd...)
RequireTxFailure(t, rsp)
systest.RequireTxFailure(t, rsp)
require.Contains(t, rsp, tc.expErrMsg)
} else {
assertErr := func(_ assert.TestingT, gotErr error, gotOutputs ...interface{}) bool {
@@ -216,7 +218,7 @@ func TestAuthzGrantTxCmd(t *testing.T) {
return
}
rsp := cli.RunAndWait(cmd...)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// query granter-grantee grants
resp := cli.CustomQuery("q", "authz", "grants", granterAddr, tc.grantee)
@@ -237,8 +239,8 @@ func TestAuthzExecSendAuthorization(t *testing.T) {
// scenario: test authz exec send authorization
// given a running chain
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
systest.Sut.ResetChain(t)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator address which will be used as granter
granterAddr := cli.GetKeyAddr("node0")
@@ -256,12 +258,12 @@ func TestAuthzExecSendAuthorization(t *testing.T) {
var initialAmount int64 = 10000000
initialBalance := fmt.Sprintf("%d%s", initialAmount, testDenom)
sut.ModifyGenesisCLI(t,
systest.Sut.ModifyGenesisCLI(t,
[]string{"genesis", "add-genesis-account", granteeAddr, initialBalance},
[]string{"genesis", "add-genesis-account", allowedAddr, initialBalance},
[]string{"genesis", "add-genesis-account", newAccount, initialBalance},
)
sut.StartChain(t)
systest.Sut.StartChain(t)
// query balances
granterBal := cli.QueryBalance(granterAddr, testDenom)
@@ -271,7 +273,7 @@ func TestAuthzExecSendAuthorization(t *testing.T) {
require.Equal(t, initialAmount, allowedAddrBal)
var spendLimitAmount int64 = 1000
expirationTime := time.Now().Add(time.Second * 10).Unix()
expirationTime := time.Now().Add(systest.Sut.BlockTime() * 10)
// test exec send authorization
@@ -279,10 +281,10 @@ func TestAuthzExecSendAuthorization(t *testing.T) {
rsp := cli.RunAndWait("tx", "authz", "grant", granteeAddr, "send",
"--spend-limit="+fmt.Sprintf("%d%s", spendLimitAmount, testDenom),
"--allow-list="+allowedAddr,
"--expiration="+fmt.Sprintf("%d", expirationTime),
"--expiration="+fmt.Sprintf("%d", expirationTime.Unix()),
"--fees=1"+testDenom,
"--from", granterAddr)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// reduce fees of above tx from granter balance
granterBal--
@@ -329,12 +331,12 @@ func TestAuthzExecSendAuthorization(t *testing.T) {
cmd := msgSendExec(t, granterAddr, tc.grantee, tc.toAddr, testDenom, tc.amount)
if tc.expErrMsg != "" {
rsp := cli.Run(cmd...)
RequireTxFailure(t, rsp)
systest.RequireTxFailure(t, rsp)
require.Contains(t, rsp, tc.expErrMsg)
return
}
rsp := cli.RunAndWait(cmd...)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// check granter balance equals to granterBal - transferredAmount
expGranterBal := granterBal - tc.amount
@@ -349,11 +351,15 @@ func TestAuthzExecSendAuthorization(t *testing.T) {
}
// test grant expiry
time.Sleep(time.Second * 10)
require.Eventually(t, func() bool {
resp := cli.CustomQuery("q", "authz", "grants", granterAddr, granteeAddr)
grants := gjson.Get(resp, "grants").Array()
return len(grants) == 0
}, 10*systest.Sut.BlockTime(), 200*time.Millisecond)
execSendCmd := msgSendExec(t, granterAddr, granteeAddr, allowedAddr, testDenom, 10)
rsp = cli.Run(execSendCmd...)
RequireTxFailure(t, rsp)
systest.RequireTxFailure(t, rsp)
require.Contains(t, rsp, "authorization not found")
}
@@ -369,30 +375,33 @@ func TestAuthzExecGenericAuthorization(t *testing.T) {
// query balances
granterBal := cli.QueryBalance(granterAddr, testDenom)
expirationTime := time.Now().Add(time.Second * 5).Unix()
execSendCmd := msgSendExec(t, granterAddr, granteeAddr, allowedAddr, testDenom, 10)
expirationTime := time.Now().Add(systest.Sut.BlockTime() * 5)
// create generic authorization grant
rsp := cli.RunAndWait("tx", "authz", "grant", granteeAddr, "generic",
_ = cli.RunAndWait("tx", "authz", "grant", granteeAddr, "generic",
"--msg-type="+msgSendTypeURL,
"--expiration="+fmt.Sprintf("%d", expirationTime),
"--expiration="+fmt.Sprintf("%d", expirationTime.Unix()),
"--fees=1"+testDenom,
"--from", granterAddr)
RequireTxSuccess(t, rsp)
granterBal--
rsp = cli.RunAndWait(execSendCmd...)
RequireTxSuccess(t, rsp)
execSendCmd := msgSendExec(t, granterAddr, granteeAddr, allowedAddr, testDenom, 10)
_ = cli.RunAndWait(execSendCmd...)
// check granter balance equals to granterBal - transferredAmount
expGranterBal := granterBal - 10
require.Equal(t, expGranterBal, cli.QueryBalance(granterAddr, testDenom))
time.Sleep(time.Second * 5)
// check grants after expiration
resp := cli.CustomQuery("q", "authz", "grants", granterAddr, granteeAddr)
grants := gjson.Get(resp, "grants").Array()
require.Len(t, grants, 0)
// wait until block after expired has passed
maxWait := max(expirationTime.Sub(time.Now()), time.Nanosecond) + 5*systest.Sut.BlockTime()
require.Eventually(t, func() bool {
resp := cli.CustomQuery("q", "authz", "grants", granterAddr, granteeAddr)
grants := gjson.Get(resp, "grants").Array()
if len(grants) != 0 {
t.Log(time.Now().Format(time.RFC3339))
t.Log(resp)
}
return len(grants) == 0
}, maxWait, 200*time.Millisecond)
}
func TestAuthzExecDelegateAuthorization(t *testing.T) {
@@ -419,7 +428,7 @@ func TestAuthzExecDelegateAuthorization(t *testing.T) {
"--allowed-validators="+val1Addr,
"--fees=1"+testDenom,
"--from", granterAddr)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// reduce fees of above tx from granter balance
granterBal--
@@ -478,12 +487,12 @@ func TestAuthzExecDelegateAuthorization(t *testing.T) {
cmd := append(append(execCmdArgs, execMsg.Name()), "--from="+tc.grantee)
if tc.expErrMsg != "" {
rsp := cli.Run(cmd...)
RequireTxFailure(t, rsp)
systest.RequireTxFailure(t, rsp)
require.Contains(t, rsp, tc.expErrMsg)
return
}
rsp := cli.RunAndWait(cmd...)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// check granter balance equals to granterBal - transferredAmount
expGranterBal := granterBal - tc.amount
@@ -508,7 +517,7 @@ func TestAuthzExecUndelegateAuthorization(t *testing.T) {
// delegate some tokens
rsp = cli.RunAndWait("tx", "staking", "delegate", val1Addr, "10000"+testDenom, "--from="+granterAddr)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// query delegated tokens count
resp := cli.CustomQuery("q", "staking", "delegation", granterAddr, val1Addr)
@@ -518,7 +527,7 @@ func TestAuthzExecUndelegateAuthorization(t *testing.T) {
"--allowed-validators="+val1Addr,
"--fees=1"+testDenom,
"--from", granterAddr)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
undelegateTestCases := []struct {
name string
@@ -552,12 +561,12 @@ func TestAuthzExecUndelegateAuthorization(t *testing.T) {
cmd := []string{"tx", "authz", "exec", execMsg.Name(), "--from=" + tc.grantee}
if tc.expErrMsg != "" {
rsp := cli.Run(cmd...)
RequireTxFailure(t, rsp)
systest.RequireTxFailure(t, rsp)
require.Contains(t, rsp, tc.expErrMsg)
return
}
rsp := cli.RunAndWait(cmd...)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// query delegation and check balance reduced
expectedAmount := delegatedAmount - tc.amount
@@ -569,7 +578,7 @@ func TestAuthzExecUndelegateAuthorization(t *testing.T) {
// revoke existing grant
rsp = cli.RunAndWait("tx", "authz", "revoke", granteeAddr, msgUndelegateTypeURL, "--from", granterAddr)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// check grants between granter and grantee after revoking
resp = cli.CustomQuery("q", "authz", "grants", granterAddr, granteeAddr)
@@ -592,14 +601,14 @@ func TestAuthzExecRedelegateAuthorization(t *testing.T) {
// delegate some tokens
rsp = cli.RunAndWait("tx", "staking", "delegate", val1Addr, "10000"+testDenom, "--from="+granterAddr)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// test exec redelegate authorization
rsp = cli.RunAndWait("tx", "authz", "grant", granteeAddr, "redelegate",
fmt.Sprintf("--allowed-validators=%s,%s", val1Addr, val2Addr),
"--fees=1"+testDenom,
"--from", granterAddr)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
var redelegationAmount int64 = 10
@@ -609,7 +618,7 @@ func TestAuthzExecRedelegateAuthorization(t *testing.T) {
redelegateCmd := []string{"tx", "authz", "exec", execMsg.Name(), "--from=" + granteeAddr, "--gas=500000", "--fees=10stake"}
rsp = cli.RunAndWait(redelegateCmd...)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// query new delegation and check balance increased
resp := cli.CustomQuery("q", "staking", "delegation", granterAddr, val2Addr)
@@ -618,7 +627,7 @@ func TestAuthzExecRedelegateAuthorization(t *testing.T) {
// revoke all existing grants
rsp = cli.RunAndWait("tx", "authz", "revoke-all", "--from", granterAddr)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// check grants after revoking
resp = cli.CustomQuery("q", "authz", "grants-by-granter", granterAddr)
@@ -640,28 +649,28 @@ func TestAuthzGRPCQueries(t *testing.T) {
rsp := cli.RunAndWait("tx", "authz", "grant", grantee1Addr, "send",
"--spend-limit=10000"+testDenom,
"--from", granterAddr)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
grant1 := fmt.Sprintf(`"authorization":{"@type":"%s","spend_limit":[{"denom":"%s","amount":"10000"}],"allow_list":[]},"expiration":null`, sendAuthzTypeURL, testDenom)
rsp = cli.RunAndWait("tx", "authz", "grant", grantee2Addr, "send",
"--spend-limit=1000"+testDenom,
"--from", granterAddr)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
grant2 := fmt.Sprintf(`"authorization":{"@type":"%s","spend_limit":[{"denom":"%s","amount":"1000"}],"allow_list":[]},"expiration":null`, sendAuthzTypeURL, testDenom)
rsp = cli.RunAndWait("tx", "authz", "grant", grantee2Addr, "generic",
"--msg-type="+msgVoteTypeURL,
"--from", granterAddr)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
grant3 := fmt.Sprintf(`"authorization":{"@type":"%s","msg":"%s"},"expiration":null`, genericAuthzTypeURL, msgVoteTypeURL)
rsp = cli.RunAndWait("tx", "authz", "grant", grantee2Addr, "generic",
"--msg-type="+msgDelegateTypeURL,
"--from", grantee1Addr)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
grant4 := fmt.Sprintf(`"authorization":{"@type":"%s","msg":"%s"},"expiration":null`, genericAuthzTypeURL, msgDelegateTypeURL)
baseurl := sut.APIAddress()
baseurl := systest.Sut.APIAddress()
// test query grant grpc endpoint
grantURL := baseurl + "/cosmos/authz/v1beta1/grants?granter=%s&grantee=%s&msg_type_url=%s"
@@ -671,7 +680,7 @@ func TestAuthzGRPCQueries(t *testing.T) {
invalidMsgTypeOutput := `{"code":2, "message":"codespace authz code 2: authorization not found: authorization not found for invalidMsg type", "details":[]}`
expGrantOutput := fmt.Sprintf(`{"grants":[{%s}],"pagination":null}`, grant1)
grantTestCases := []RestTestCase{
grantTestCases := []systest.RestTestCase{
{
"invalid granter address",
fmt.Sprintf(grantURL, "invalid_granter", grantee1Addr, msgSendTypeURL),
@@ -710,12 +719,12 @@ func TestAuthzGRPCQueries(t *testing.T) {
},
}
RunRestQueries(t, grantTestCases)
systest.RunRestQueries(t, grantTestCases...)
// test query grants grpc endpoint
grantsURL := baseurl + "/cosmos/authz/v1beta1/grants?granter=%s&grantee=%s"
grantsTestCases := []RestTestCase{
grantsTestCases := []systest.RestTestCase{
{
"expect single grant",
fmt.Sprintf(grantsURL, granterAddr, grantee1Addr),
@@ -748,7 +757,7 @@ func TestAuthzGRPCQueries(t *testing.T) {
},
}
RunRestQueries(t, grantsTestCases)
systest.RunRestQueries(t, grantsTestCases...)
// test query grants by granter grpc endpoint
grantsByGranterURL := baseurl + "/cosmos/authz/v1beta1/grants/granter/%s"
@@ -757,7 +766,7 @@ func TestAuthzGRPCQueries(t *testing.T) {
granterQueryOutput := fmt.Sprintf(`{"grants":[{"granter":"%s","grantee":"%s",%s}],"pagination":{"next_key":null,"total":"1"}}`,
grantee1Addr, grantee2Addr, grant4)
granterTestCases := []RestTestCase{
granterTestCases := []systest.RestTestCase{
{
"invalid granter account address",
fmt.Sprintf(grantsByGranterURL, "invalid address"),
@@ -778,13 +787,13 @@ func TestAuthzGRPCQueries(t *testing.T) {
},
}
RunRestQueries(t, granterTestCases)
systest.RunRestQueries(t, granterTestCases...)
// test query grants by grantee grpc endpoint
grantsByGranteeURL := baseurl + "/cosmos/authz/v1beta1/grants/grantee/%s"
grantee1GrantsOutput := fmt.Sprintf(`{"grants":[{"granter":"%s","grantee":"%s",%s}],"pagination":{"next_key":null,"total":"1"}}`, granterAddr, grantee1Addr, grant1)
granteeTestCases := []RestTestCase{
granteeTestCases := []systest.RestTestCase{
{
"invalid grantee account address",
fmt.Sprintf(grantsByGranteeURL, "invalid address"),
@@ -805,16 +814,16 @@ func TestAuthzGRPCQueries(t *testing.T) {
},
}
RunRestQueries(t, granteeTestCases)
systest.RunRestQueries(t, granteeTestCases...)
}
func setupChain(t *testing.T) (*CLIWrapper, string, string) {
func setupChain(t *testing.T) (*systest.CLIWrapper, string, string) {
t.Helper()
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
systest.Sut.ResetChain(t)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
require.GreaterOrEqual(t, cli.nodesCount, 2)
require.GreaterOrEqual(t, systest.Sut.NodesCount(), 2)
// get validators' address which will be used as granter and grantee
granterAddr := cli.GetKeyAddr("node0")
@@ -822,7 +831,7 @@ func setupChain(t *testing.T) (*CLIWrapper, string, string) {
granteeAddr := cli.GetKeyAddr("node1")
require.NotEmpty(t, granteeAddr)
sut.StartChain(t)
systest.Sut.StartChain(t)
return cli, granterAddr, granteeAddr
}
+27 -27
View File
@@ -11,23 +11,24 @@ import (
"github.com/stretchr/testify/require"
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
systest "cosmossdk.io/systemtests"
)
func TestBankSendTxCmd(t *testing.T) {
// scenario: test bank send command
// given a running chain
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
systest.Sut.ResetChain(t)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)
// add new key
receiverAddr := cli.AddKey("account1")
denom := "stake"
sut.StartChain(t)
systest.Sut.StartChain(t)
// query validator balance and make sure it has enough balance
var transferAmount int64 = 1000
@@ -40,7 +41,7 @@ func TestBankSendTxCmd(t *testing.T) {
rsp := cli.Run(append(bankSendCmdArgs, "--fees=1stake")...)
txResult, found := cli.AwaitTxCommitted(rsp)
require.True(t, found)
RequireTxSuccess(t, txResult)
systest.RequireTxSuccess(t, txResult)
// check valaddr balance equals to valBalance-(transferedAmount+feeAmount)
require.Equal(t, valBalance-(transferAmount+1), cli.QueryBalance(valAddr, denom))
// check receiver balance equals to transferAmount
@@ -50,7 +51,7 @@ func TestBankSendTxCmd(t *testing.T) {
insufficientCmdArgs := bankSendCmdArgs[0 : len(bankSendCmdArgs)-1]
insufficientCmdArgs = append(insufficientCmdArgs, fmt.Sprintf("%d%s", valBalance, denom), "--fees=10stake")
rsp = cli.Run(insufficientCmdArgs...)
RequireTxFailure(t, rsp)
systest.RequireTxFailure(t, rsp)
require.Contains(t, rsp, "insufficient funds")
// test tx bank send with unauthorized signature
@@ -58,13 +59,12 @@ func TestBankSendTxCmd(t *testing.T) {
require.Len(t, gotOutputs, 1)
code := gjson.Get(gotOutputs[0].(string), "code")
require.True(t, code.Exists())
require.Greater(t, code.Int(), int64(0))
require.Greater(t, code.Int(), int64(0), gotOutputs[0])
return false
}
invalidCli := cli
invalidCli.chainID = cli.chainID + "a" // set invalid chain-id
invalidCli := cli.WithChainID(cli.ChainID() + "a") // set invalid chain-id
rsp = invalidCli.WithRunErrorMatcher(assertUnauthorizedErr).Run(bankSendCmdArgs...)
RequireTxFailure(t, rsp)
systest.RequireTxFailure(t, rsp)
// test tx bank send generate only
assertGenOnlyOutput := func(_ assert.TestingT, gotErr error, gotOutputs ...interface{}) bool {
@@ -100,8 +100,8 @@ func TestBankMultiSendTxCmd(t *testing.T) {
// scenario: test bank multi-send command
// given a running chain
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
systest.Sut.ResetChain(t)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// add genesis account with some tokens
account1Addr := cli.AddKey("account1")
account2Addr := cli.AddKey("account2")
@@ -111,11 +111,11 @@ func TestBankMultiSendTxCmd(t *testing.T) {
denom := "stake"
var initialAmount int64 = 10000000
initialBalance := fmt.Sprintf("%d%s", initialAmount, denom)
sut.ModifyGenesisCLI(t,
systest.Sut.ModifyGenesisCLI(t,
[]string{"genesis", "add-genesis-account", account1Addr, initialBalance},
[]string{"genesis", "add-genesis-account", account2Addr, initialBalance},
)
sut.StartChain(t)
systest.Sut.StartChain(t)
// query accounts balances
account1Bal := cli.QueryBalance(account1Addr, denom)
@@ -172,7 +172,7 @@ func TestBankMultiSendTxCmd(t *testing.T) {
rsp := cli.Run(tc.cmdArgs...)
txResult, found := cli.AwaitTxCommitted(rsp)
require.True(t, found)
RequireTxSuccess(t, txResult)
systest.RequireTxSuccess(t, txResult)
// check account1 balance equals to account1Bal - transferredAmount*no_of_accounts - fees
expAcc1Balance := account1Bal - (1000 * 2) - 1
require.Equal(t, expAcc1Balance, cli.QueryBalance(account1Addr, denom))
@@ -193,8 +193,8 @@ func TestBankGRPCQueries(t *testing.T) {
// scenario: test bank grpc gateway queries
// given a running chain
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
systest.Sut.ResetChain(t)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// update bank denom metadata in genesis
atomDenomMetadata := `{"description":"The native staking token of the Cosmos Hub.","denom_units":[{"denom":"uatom","exponent":0,"aliases":["microatom"]},{"denom":"atom","exponent":6,"aliases":["ATOM"]}],"base":"uatom","display":"atom","name":"Cosmos Hub Atom","symbol":"ATOM","uri":"","uri_hash":""}`
@@ -202,7 +202,7 @@ func TestBankGRPCQueries(t *testing.T) {
bankDenomMetadata := fmt.Sprintf("[%s,%s]", atomDenomMetadata, ethDenomMetadata)
sut.ModifyGenesisJSON(t, func(genesis []byte) []byte {
systest.Sut.ModifyGenesisJSON(t, func(genesis []byte) []byte {
state, err := sjson.SetRawBytes(genesis, "app_state.bank.denom_metadata", []byte(bankDenomMetadata))
require.NoError(t, err)
return state
@@ -212,13 +212,13 @@ func TestBankGRPCQueries(t *testing.T) {
account1Addr := cli.AddKey("account1")
newDenom := "newdenom"
initialAmount := "10000000"
sut.ModifyGenesisCLI(t,
systest.Sut.ModifyGenesisCLI(t,
[]string{"genesis", "add-genesis-account", account1Addr, "10000000stake," + initialAmount + newDenom},
)
// start chain
sut.StartChain(t)
baseurl := sut.APIAddress()
systest.Sut.StartChain(t)
baseurl := systest.Sut.APIAddress()
// test supply grpc endpoint
supplyUrl := baseurl + "/cosmos/bank/v1beta1/supply"
@@ -229,7 +229,7 @@ func TestBankGRPCQueries(t *testing.T) {
bogusDenomOutput := `{"denom":"foobar","amount":"0"}`
blockHeightHeader := "x-cosmos-block-height"
blockHeight := sut.CurrentHeight()
blockHeight := systest.Sut.CurrentHeight()
supplyTestCases := []struct {
name string
@@ -275,14 +275,14 @@ func TestBankGRPCQueries(t *testing.T) {
for _, tc := range supplyTestCases {
t.Run(tc.name, func(t *testing.T) {
resp := GetRequestWithHeaders(t, tc.url, tc.headers, tc.expHttpCode)
resp := systest.GetRequestWithHeaders(t, tc.url, tc.headers, tc.expHttpCode)
require.Contains(t, string(resp), tc.expOut)
})
}
// test denom metadata endpoint
denomMetadataUrl := baseurl + "/cosmos/bank/v1beta1/denoms_metadata"
dmTestCases := []RestTestCase{
dmTestCases := []systest.RestTestCase{
{
"test GRPC client metadata",
denomMetadataUrl,
@@ -303,13 +303,13 @@ func TestBankGRPCQueries(t *testing.T) {
},
}
RunRestQueries(t, dmTestCases)
systest.RunRestQueries(t, dmTestCases...)
// test bank balances endpoint
balanceUrl := baseurl + "/cosmos/bank/v1beta1/balances/"
allBalancesOutput := `{"balances":[` + specificDenomOutput + `,{"denom":"stake","amount":"10000000"}],"pagination":{"next_key":null,"total":"2"}}`
balanceTestCases := []RestTestCase{
balanceTestCases := []systest.RestTestCase{
{
"test GRPC total account balance",
balanceUrl + account1Addr,
@@ -330,5 +330,5 @@ func TestBankGRPCQueries(t *testing.T) {
},
}
RunRestQueries(t, balanceTestCases)
systest.RunRestQueries(t, balanceTestCases...)
}
+7 -5
View File
@@ -8,18 +8,20 @@ import (
"github.com/stretchr/testify/require"
"github.com/tidwall/gjson"
systest "cosmossdk.io/systemtests"
)
func TestBankV2SendTxCmd(t *testing.T) {
// Currently only run with app v2
if !isV2() {
if !systest.IsV2() {
t.Skip()
}
// scenario: test bank send command
// given a running chain
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
systest.Sut.ResetChain(t)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator address
valAddr := gjson.Get(cli.Keys("keys", "list"), "1.address").String()
@@ -28,7 +30,7 @@ func TestBankV2SendTxCmd(t *testing.T) {
// add new key
receiverAddr := cli.AddKey("account1")
denom := "stake"
sut.StartChain(t)
systest.Sut.StartChain(t)
// query validator balance and make sure it has enough balance
var transferAmount int64 = 1000
@@ -43,7 +45,7 @@ func TestBankV2SendTxCmd(t *testing.T) {
rsp := cli.Run(append(bankSendCmdArgs, "--fees=1stake")...)
txResult, found := cli.AwaitTxCommitted(rsp)
require.True(t, found)
RequireTxSuccess(t, txResult)
systest.RequireTxSuccess(t, txResult)
// Check balance after send
valRaw := cli.CustomQuery("q", "bankv2", "balance", valAddr, denom)
+30 -27
View File
@@ -11,6 +11,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/tidwall/gjson"
systest "cosmossdk.io/systemtests"
)
var someMsgs = []string{"/cosmos.bank.v1beta1.MsgSend", "/cosmos.bank.v1beta1.MsgMultiSend"}
@@ -19,10 +21,10 @@ func TestCircuitCommands(t *testing.T) {
// scenario: test circuit commands
// given a running chain
sut.ResetChain(t)
require.GreaterOrEqual(t, sut.NodesCount(), 2)
systest.Sut.ResetChain(t)
require.GreaterOrEqual(t, systest.Sut.NodesCount(), 2)
cli := NewCLIWrapper(t, sut, verbose)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator addresses
superAdmin := cli.GetKeyAddr("node0")
@@ -33,13 +35,14 @@ func TestCircuitCommands(t *testing.T) {
// short voting period
// update expedited voting period to avoid validation error
sut.ModifyGenesisJSON(
votingPeriod := 5 * time.Second
systest.Sut.ModifyGenesisJSON(
t,
SetGovVotingPeriod(t, time.Second*8),
SetGovExpeditedVotingPeriod(t, time.Second*7),
systest.SetGovVotingPeriod(t, votingPeriod),
systest.SetGovExpeditedVotingPeriod(t, votingPeriod-time.Second),
)
sut.StartChain(t)
systest.Sut.StartChain(t)
allMsgsAcc := cli.AddKey("allMsgsAcc")
require.NotEmpty(t, allMsgsAcc)
@@ -51,11 +54,11 @@ func TestCircuitCommands(t *testing.T) {
var amount int64 = 100000
denom := "stake"
rsp := cli.FundAddress(allMsgsAcc, fmt.Sprintf("%d%s", amount, denom))
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
require.Equal(t, amount, cli.QueryBalance(allMsgsAcc, denom))
rsp = cli.FundAddress(someMsgsAcc, fmt.Sprintf("%d%s", amount, denom))
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
require.Equal(t, amount, cli.QueryBalance(someMsgsAcc, denom))
// query gov module account address
@@ -77,24 +80,23 @@ func TestCircuitCommands(t *testing.T) {
"deposit": "10000000stake",
"summary": "A short summary of my proposal"
}`, govModAddr, superAdmin)
proposalFile := StoreTempFile(t, []byte(validProposal))
proposalFile := systest.StoreTempFile(t, []byte(validProposal))
rsp = cli.RunAndWait("tx", "gov", "submit-proposal", proposalFile.Name(), "--from="+superAdmin)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// vote to proposal from two validators
rsp = cli.RunAndWait("tx", "gov", "vote", "1", "yes", "--from="+superAdmin)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
rsp = cli.RunAndWait("tx", "gov", "vote", "1", "yes", "--from="+superAdmin2)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// wait for proposal to pass
time.Sleep(time.Second * 8)
rsp = cli.CustomQuery("q", "circuit", "accounts")
level := gjson.Get(rsp, fmt.Sprintf("accounts.#(address==%s).permissions.level", superAdmin)).String()
require.Equal(t, "LEVEL_SUPER_ADMIN", level)
require.Eventually(t, func() bool {
rsp = cli.CustomQuery("q", "circuit", "accounts")
level := gjson.Get(rsp, fmt.Sprintf("accounts.#(address==%s).permissions.level", superAdmin)).String()
return "LEVEL_SUPER_ADMIN" == level
}, votingPeriod+systest.Sut.BlockTime(), 200*time.Millisecond)
authorizeTestCases := []struct {
name string
@@ -133,7 +135,7 @@ func TestCircuitCommands(t *testing.T) {
permissionJSON = fmt.Sprintf(`{"level":%d,"limit_type_urls":["%s"]}`, tc.level, strings.Join(tc.limtTypeURLs[:], `","`))
}
rsp = cli.RunAndWait("tx", "circuit", "authorize", tc.address, permissionJSON, "--from="+superAdmin)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// query account permissions
rsp = cli.CustomQuery("q", "circuit", "account", tc.address)
@@ -157,7 +159,7 @@ func TestCircuitCommands(t *testing.T) {
testCircuitTxCommand(t, cli, "reset", superAdmin, superAdmin2, allMsgsAcc, someMsgsAcc)
}
func testCircuitTxCommand(t *testing.T, cli *CLIWrapper, txType, superAdmin, superAdmin2, allMsgsAcc, someMsgsAcc string) {
func testCircuitTxCommand(t *testing.T, cli *systest.CLIWrapper, txType, superAdmin, superAdmin2, allMsgsAcc, someMsgsAcc string) {
t.Helper()
disableTestCases := []struct {
@@ -206,7 +208,7 @@ func testCircuitTxCommand(t *testing.T, cli *CLIWrapper, txType, superAdmin, sup
cmd := []string{"tx", "circuit", txType, "--from=" + tc.fromAddr}
cmd = append(cmd, tc.disableMsgs...)
rsp := cli.RunAndWait(cmd...)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// execute given type transaction
rsp = cli.CustomQuery("q", "circuit", "disabled-list")
@@ -228,15 +230,16 @@ func testCircuitTxCommand(t *testing.T, cli *CLIWrapper, txType, superAdmin, sup
// test given msg transaction to confirm
for _, tx := range tc.executeTxs {
tx = append(tx, "--fees=2stake")
rsp = cli.RunCommandWithArgs(cli.withTXFlags(tx...)...)
rsp = cli.RunCommandWithArgs(cli.WithTXFlags(tx...)...)
if txType == "disable" {
RequireTxFailure(t, rsp)
systest.RequireTxFailure(t, rsp)
require.Contains(t, gjson.Get(rsp, "raw_log").String(), "tx type not allowed")
} else {
RequireTxSuccess(t, rsp)
continue
}
systest.RequireTxSuccess(t, rsp)
// wait for sometime to avoid sequence error
time.Sleep(time.Second * 2)
_, found := cli.AwaitTxCommitted(rsp)
require.True(t, found)
}
})
}
+60 -51
View File
@@ -13,6 +13,8 @@ import (
"github.com/stretchr/testify/assert"
"github.com/tidwall/gjson"
systest "cosmossdk.io/systemtests"
"github.com/cosmos/cosmos-sdk/client/grpc/cmtservice"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
@@ -21,79 +23,78 @@ import (
)
func TestQueryNodeInfo(t *testing.T) {
baseurl := fmt.Sprintf("http://localhost:%d", apiPortStart)
sut.ResetChain(t)
sut.StartChain(t)
systest.Sut.ResetChain(t)
systest.Sut.StartChain(t)
qc := cmtservice.NewServiceClient(sut.RPCClient(t))
qc := cmtservice.NewServiceClient(systest.Sut.RPCClient(t))
res, err := qc.GetNodeInfo(context.Background(), &cmtservice.GetNodeInfoRequest{})
assert.NoError(t, err)
v := NewCLIWrapper(t, sut, true).Version()
v := systest.NewCLIWrapper(t, systest.Sut, true).Version()
assert.Equal(t, res.ApplicationVersion.Version, v)
baseurl := systest.Sut.APIAddress()
// TODO: we should be adding a way to distinguish a v2. Eventually we should skip some v2 system depending on the consensus engine we want to test
restRes := GetRequest(t, mustV(url.JoinPath(baseurl, "/cosmos/base/tendermint/v1beta1/node_info")))
restRes := systest.GetRequest(t, must(url.JoinPath(baseurl, "/cosmos/base/tendermint/v1beta1/node_info")))
assert.NoError(t, err)
assert.Equal(t, gjson.GetBytes(restRes, "application_version.version").String(), res.ApplicationVersion.Version)
}
func TestQuerySyncing(t *testing.T) {
baseurl := fmt.Sprintf("http://localhost:%d", apiPortStart)
sut.ResetChain(t)
sut.StartChain(t)
systest.Sut.ResetChain(t)
systest.Sut.StartChain(t)
qc := cmtservice.NewServiceClient(sut.RPCClient(t))
qc := cmtservice.NewServiceClient(systest.Sut.RPCClient(t))
res, err := qc.GetSyncing(context.Background(), &cmtservice.GetSyncingRequest{})
assert.NoError(t, err)
restRes := GetRequest(t, mustV(url.JoinPath(baseurl, "/cosmos/base/tendermint/v1beta1/syncing")))
baseurl := systest.Sut.APIAddress()
restRes := systest.GetRequest(t, must(url.JoinPath(baseurl, "/cosmos/base/tendermint/v1beta1/syncing")))
assert.Equal(t, gjson.GetBytes(restRes, "syncing").Bool(), res.Syncing)
}
func TestQueryLatestBlock(t *testing.T) {
baseurl := fmt.Sprintf("http://localhost:%d", apiPortStart)
sut.ResetChain(t)
sut.StartChain(t)
systest.Sut.ResetChain(t)
systest.Sut.StartChain(t)
qc := cmtservice.NewServiceClient(sut.RPCClient(t))
qc := cmtservice.NewServiceClient(systest.Sut.RPCClient(t))
res, err := qc.GetLatestBlock(context.Background(), &cmtservice.GetLatestBlockRequest{})
assert.NoError(t, err)
assert.Contains(t, res.SdkBlock.Header.ProposerAddress, "cosmosvalcons")
_ = GetRequest(t, mustV(url.JoinPath(baseurl, "/cosmos/base/tendermint/v1beta1/blocks/latest")))
baseurl := systest.Sut.APIAddress()
_ = systest.GetRequest(t, must(url.JoinPath(baseurl, "/cosmos/base/tendermint/v1beta1/blocks/latest")))
}
func TestQueryBlockByHeight(t *testing.T) {
baseurl := fmt.Sprintf("http://localhost:%d", apiPortStart)
sut.ResetChain(t)
sut.StartChain(t)
systest.Sut.ResetChain(t)
systest.Sut.StartChain(t)
sut.AwaitNBlocks(t, 2, time.Second*25)
systest.Sut.AwaitNBlocks(t, 2, time.Second*25)
qc := cmtservice.NewServiceClient(sut.RPCClient(t))
qc := cmtservice.NewServiceClient(systest.Sut.RPCClient(t))
res, err := qc.GetBlockByHeight(context.Background(), &cmtservice.GetBlockByHeightRequest{Height: 2})
assert.NoError(t, err)
assert.Equal(t, res.SdkBlock.Header.Height, int64(2))
assert.Contains(t, res.SdkBlock.Header.ProposerAddress, "cosmosvalcons")
restRes := GetRequest(t, mustV(url.JoinPath(baseurl, "/cosmos/base/tendermint/v1beta1/blocks/2")))
baseurl := systest.Sut.APIAddress()
restRes := systest.GetRequest(t, must(url.JoinPath(baseurl, "/cosmos/base/tendermint/v1beta1/blocks/2")))
assert.Equal(t, gjson.GetBytes(restRes, "sdk_block.header.height").Int(), int64(2))
assert.Contains(t, gjson.GetBytes(restRes, "sdk_block.header.proposer_address").String(), "cosmosvalcons")
}
func TestQueryLatestValidatorSet(t *testing.T) {
if sut.NodesCount() < 2 {
if systest.Sut.NodesCount() < 2 {
t.Skip("not enough nodes")
return
}
baseurl := fmt.Sprintf("http://localhost:%d", apiPortStart)
sut.ResetChain(t)
sut.StartChain(t)
systest.Sut.ResetChain(t)
systest.Sut.StartChain(t)
vals := sut.RPCClient(t).Validators()
vals := systest.Sut.RPCClient(t).Validators()
qc := cmtservice.NewServiceClient(sut.RPCClient(t))
qc := cmtservice.NewServiceClient(systest.Sut.RPCClient(t))
res, err := qc.GetLatestValidatorSet(context.Background(), &cmtservice.GetLatestValidatorSetRequest{
Pagination: nil,
})
@@ -108,17 +109,18 @@ func TestQueryLatestValidatorSet(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, len(res.Validators), 2)
restRes := GetRequest(t, fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/latest?pagination.offset=%d&pagination.limit=%d", baseurl, 0, 2))
baseurl := systest.Sut.APIAddress()
restRes := systest.GetRequest(t, fmt.Sprintf("%s/cosmos/base/tendermint/v1beta1/validatorsets/latest?pagination.offset=%d&pagination.limit=%d", baseurl, 0, 2))
assert.Equal(t, len(gjson.GetBytes(restRes, "validators").Array()), 2)
}
func TestLatestValidatorSet(t *testing.T) {
sut.ResetChain(t)
sut.StartChain(t)
systest.Sut.ResetChain(t)
systest.Sut.StartChain(t)
vals := sut.RPCClient(t).Validators()
vals := systest.Sut.RPCClient(t).Validators()
qc := cmtservice.NewServiceClient(sut.RPCClient(t))
qc := cmtservice.NewServiceClient(systest.Sut.RPCClient(t))
testCases := []struct {
name string
req *cmtservice.GetLatestValidatorSetRequest
@@ -147,12 +149,12 @@ func TestLatestValidatorSet(t *testing.T) {
}
func TestLatestValidatorSet_GRPCGateway(t *testing.T) {
sut.ResetChain(t)
sut.StartChain(t)
systest.Sut.ResetChain(t)
systest.Sut.StartChain(t)
baseurl := fmt.Sprintf("http://localhost:%d", apiPortStart)
baseurl := systest.Sut.APIAddress()
vals := sut.RPCClient(t).Validators()
vals := systest.Sut.RPCClient(t).Validators()
testCases := []struct {
name string
@@ -167,23 +169,23 @@ func TestLatestValidatorSet_GRPCGateway(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
if tc.expErr {
rsp := GetRequestWithHeaders(t, baseurl+tc.url, nil, http.StatusBadRequest)
rsp := systest.GetRequestWithHeaders(t, baseurl+tc.url, nil, http.StatusBadRequest)
errMsg := gjson.GetBytes(rsp, "message").String()
assert.Contains(t, errMsg, tc.expErrMsg)
return
}
rsp := GetRequest(t, baseurl+tc.url)
rsp := systest.GetRequest(t, baseurl+tc.url)
assert.Equal(t, len(vals), int(gjson.GetBytes(rsp, "pagination.total").Int()))
})
}
}
func TestValidatorSetByHeight(t *testing.T) {
sut.ResetChain(t)
sut.StartChain(t)
systest.Sut.ResetChain(t)
systest.Sut.StartChain(t)
qc := cmtservice.NewServiceClient(sut.RPCClient(t))
vals := sut.RPCClient(t).Validators()
qc := cmtservice.NewServiceClient(systest.Sut.RPCClient(t))
vals := systest.Sut.RPCClient(t).Validators()
testCases := []struct {
name string
@@ -211,13 +213,13 @@ func TestValidatorSetByHeight(t *testing.T) {
}
func TestValidatorSetByHeight_GRPCRestGateway(t *testing.T) {
sut.ResetChain(t)
sut.StartChain(t)
systest.Sut.ResetChain(t)
systest.Sut.StartChain(t)
vals := sut.RPCClient(t).Validators()
vals := systest.Sut.RPCClient(t).Validators()
baseurl := sut.APIAddress()
block := sut.AwaitNextBlock(t, time.Second*3)
baseurl := systest.Sut.APIAddress()
block := systest.Sut.AwaitNextBlock(t, time.Second*3)
testCases := []struct {
name string
url string
@@ -232,7 +234,7 @@ func TestValidatorSetByHeight_GRPCRestGateway(t *testing.T) {
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
rsp := GetRequestWithHeaders(t, tc.url, nil, tc.expHttpCode)
rsp := systest.GetRequestWithHeaders(t, tc.url, nil, tc.expHttpCode)
if tc.expErr {
errMsg := gjson.GetBytes(rsp, "message").String()
assert.Contains(t, errMsg, tc.expErrMsg)
@@ -244,9 +246,9 @@ func TestValidatorSetByHeight_GRPCRestGateway(t *testing.T) {
}
func TestABCIQuery(t *testing.T) {
sut.StartChain(t)
systest.Sut.StartChain(t)
qc := cmtservice.NewServiceClient(sut.RPCClient(t))
qc := cmtservice.NewServiceClient(systest.Sut.RPCClient(t))
cdc := codec.NewProtoCodec(codectypes.NewInterfaceRegistry())
testCases := []struct {
name string
@@ -328,3 +330,10 @@ func TestABCIQuery(t *testing.T) {
})
}
}
func must[T any](r T, err error) T {
if err != nil {
panic(err)
}
return r
}
+41 -45
View File
@@ -7,7 +7,6 @@ import (
"net/http"
"os"
"path/filepath"
"regexp"
"strings"
"testing"
@@ -15,6 +14,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/tidwall/gjson"
"github.com/tidwall/sjson"
systest "cosmossdk.io/systemtests"
)
const (
@@ -25,18 +26,18 @@ func TestWithdrawAllRewardsCmd(t *testing.T) {
// scenario: test distribution withdraw all rewards command
// given a running chain
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
systest.Sut.ResetChain(t)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
newAddr := cli.AddKey("newAddr")
require.NotEmpty(t, newAddr)
var initialAmount int64 = 10000000
initialBalance := fmt.Sprintf("%d%s", initialAmount, distrTestDenom)
sut.ModifyGenesisCLI(t,
systest.Sut.ModifyGenesisCLI(t,
[]string{"genesis", "add-genesis-account", newAddr, initialBalance},
)
sut.StartChain(t)
systest.Sut.StartChain(t)
// query balance
newAddrBal := cli.QueryBalance(newAddr, distrTestDenom)
@@ -54,11 +55,11 @@ func TestWithdrawAllRewardsCmd(t *testing.T) {
// delegate tokens to validator1
rsp = cli.RunAndWait("tx", "staking", "delegate", val1Addr, delegation, "--from="+newAddr, "--fees=1"+distrTestDenom)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// delegate tokens to validator2
rsp = cli.RunAndWait("tx", "staking", "delegate", val2Addr, delegation, "--from="+newAddr, "--fees=1"+distrTestDenom)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// check updated balance: newAddrBal - delegatedBal - fees
expBal := newAddrBal - (delegationAmount * 2) - 2
@@ -101,32 +102,32 @@ func TestWithdrawAllRewardsCmd(t *testing.T) {
// test withdraw-all-rewards transaction
rsp = cli.RunAndWait(withdrawCmdArgs...)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
}
func TestDistrValidatorGRPCQueries(t *testing.T) {
// scenario: test distribution validator grpc gateway queries
// given a running chain
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
systest.Sut.ResetChain(t)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)
valOperAddr := cli.GetKeyAddrPrefix("node0", "val")
require.NotEmpty(t, valOperAddr)
sut.StartChain(t)
systest.Sut.StartChain(t)
sut.AwaitNBlocks(t, 3)
systest.Sut.AwaitNBlocks(t, 3)
baseurl := sut.APIAddress()
baseurl := systest.Sut.APIAddress()
expectedAmountOutput := fmt.Sprintf(`{"denom":"%s","amount":"203.105000000000000000"}`, distrTestDenom)
// test params grpc endpoint
paramsURL := baseurl + "/cosmos/distribution/v1beta1/params"
paramsTestCases := []RestTestCase{
paramsTestCases := []systest.RestTestCase{
{
"gRPC request params",
paramsURL,
@@ -134,13 +135,13 @@ func TestDistrValidatorGRPCQueries(t *testing.T) {
`{"params":{"community_tax":"0.020000000000000000","base_proposer_reward":"0.000000000000000000","bonus_proposer_reward":"0.000000000000000000","withdraw_addr_enabled":true}}`,
},
}
RunRestQueries(t, paramsTestCases)
systest.RunRestQueries(t, paramsTestCases...)
// test validator distribution info grpc endpoint
validatorsURL := baseurl + `/cosmos/distribution/v1beta1/validators/%s`
validatorsOutput := fmt.Sprintf(`{"operator_address":"%s","self_bond_rewards":[],"commission":[%s]}`, valAddr, expectedAmountOutput)
validatorsTestCases := []RestTestCase{
validatorsTestCases := []systest.RestTestCase{
{
"gRPC request validator with valid validator address",
fmt.Sprintf(validatorsURL, valOperAddr),
@@ -148,12 +149,12 @@ func TestDistrValidatorGRPCQueries(t *testing.T) {
validatorsOutput,
},
}
TestRestQueryIgnoreNumbers(t, validatorsTestCases)
systest.TestRestQueryIgnoreNumbers(t, validatorsTestCases...)
// test outstanding rewards grpc endpoint
outstandingRewardsURL := baseurl + `/cosmos/distribution/v1beta1/validators/%s/outstanding_rewards`
rewardsTestCases := []RestTestCase{
rewardsTestCases := []systest.RestTestCase{
{
"gRPC request outstanding rewards with valid validator address",
fmt.Sprintf(outstandingRewardsURL, valOperAddr),
@@ -161,12 +162,12 @@ func TestDistrValidatorGRPCQueries(t *testing.T) {
fmt.Sprintf(`{"rewards":{"rewards":[%s]}}`, expectedAmountOutput),
},
}
TestRestQueryIgnoreNumbers(t, rewardsTestCases)
systest.TestRestQueryIgnoreNumbers(t, rewardsTestCases...)
// test validator commission grpc endpoint
commissionURL := baseurl + `/cosmos/distribution/v1beta1/validators/%s/commission`
commissionTestCases := []RestTestCase{
commissionTestCases := []systest.RestTestCase{
{
"gRPC request commission with valid validator address",
fmt.Sprintf(commissionURL, valOperAddr),
@@ -174,13 +175,13 @@ func TestDistrValidatorGRPCQueries(t *testing.T) {
fmt.Sprintf(`{"commission":{"commission":[%s]}}`, expectedAmountOutput),
},
}
TestRestQueryIgnoreNumbers(t, commissionTestCases)
systest.TestRestQueryIgnoreNumbers(t, commissionTestCases...)
// test validator slashes grpc endpoint
slashURL := baseurl + `/cosmos/distribution/v1beta1/validators/%s/slashes`
invalidHeightOutput := `{"code":3, "message":"strconv.ParseUint: parsing \"-3\": invalid syntax", "details":[]}`
slashTestCases := []RestTestCase{
slashTestCases := []systest.RestTestCase{
{
"invalid start height",
fmt.Sprintf(slashURL+`?starting_height=%s&ending_height=%s`, valOperAddr, "-3", "3"),
@@ -200,15 +201,15 @@ func TestDistrValidatorGRPCQueries(t *testing.T) {
`{"slashes":[],"pagination":{"next_key":null,"total":"0"}}`,
},
}
RunRestQueries(t, slashTestCases)
systest.RunRestQueries(t, slashTestCases...)
}
func TestDistrDelegatorGRPCQueries(t *testing.T) {
// scenario: test distribution validator gsrpc gateway queries
// given a running chain
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
systest.Sut.ResetChain(t)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
@@ -218,17 +219,12 @@ func TestDistrDelegatorGRPCQueries(t *testing.T) {
// update commission rate of node0 validator
// generate new gentx and copy it to genesis.json before starting network
rsp := cli.RunCommandWithArgs("genesis", "gentx", "node0", "100000000"+distrTestDenom, "--chain-id="+cli.chainID, "--commission-rate=0.01", "--home", sut.nodePath(0), "--keyring-backend=test")
// extract gentx path from above command output
re := regexp.MustCompile(`"(.*?\.json)"`)
match := re.FindStringSubmatch(rsp)
require.GreaterOrEqual(t, len(match), 1)
updatedGentx := filepath.Join(WorkDir, match[1])
updatedGentxBz, err := os.ReadFile(updatedGentx) // #nosec G304
outFile := filepath.Join(t.TempDir(), "gentx.json")
rsp := cli.RunCommandWithArgs("genesis", "gentx", "node0", "100000000"+distrTestDenom, "--chain-id="+cli.ChainID(), "--commission-rate=0.01", "--home", systest.Sut.NodeDir(0), "--keyring-backend=test", "--output-document="+outFile)
updatedGentxBz, err := os.ReadFile(outFile) // #nosec G304
require.NoError(t, err)
sut.ModifyGenesisJSON(t, func(genesis []byte) []byte {
systest.Sut.ModifyGenesisJSON(t, func(genesis []byte) []byte {
state, err := sjson.SetRawBytes(genesis, "app_state.genutil.gen_txs.0", updatedGentxBz)
require.NoError(t, err)
return state
@@ -240,26 +236,26 @@ func TestDistrDelegatorGRPCQueries(t *testing.T) {
var initialAmount int64 = 1000000000
initialBalance := fmt.Sprintf("%d%s", initialAmount, distrTestDenom)
sut.ModifyGenesisCLI(t,
systest.Sut.ModifyGenesisCLI(t,
[]string{"genesis", "add-genesis-account", delAddr, initialBalance},
)
sut.StartChain(t)
systest.Sut.StartChain(t)
// delegate some tokens to valOperAddr
rsp = cli.RunAndWait("tx", "staking", "delegate", valOperAddr, "100000000"+distrTestDenom, "--from="+delAddr)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
sut.AwaitNBlocks(t, 5)
systest.Sut.AwaitNBlocks(t, 5)
baseurl := sut.APIAddress()
baseurl := systest.Sut.APIAddress()
// test delegator rewards grpc endpoint
delegatorRewardsURL := baseurl + `/cosmos/distribution/v1beta1/delegators/%s/rewards`
expectedAmountOutput := `{"denom":"stake","amount":"0.121275000000000000"}`
rewardsOutput := fmt.Sprintf(`{"rewards":[{"validator_address":"%s","reward":[%s]}],"total":[%s]}`, valOperAddr, expectedAmountOutput, expectedAmountOutput)
delegatorRewardsTestCases := []RestTestCase{
delegatorRewardsTestCases := []systest.RestTestCase{
{
"valid rewards request with valid delegator address",
fmt.Sprintf(delegatorRewardsURL, delAddr),
@@ -273,11 +269,11 @@ func TestDistrDelegatorGRPCQueries(t *testing.T) {
fmt.Sprintf(`{"rewards":[%s]}`, expectedAmountOutput),
},
}
TestRestQueryIgnoreNumbers(t, delegatorRewardsTestCases)
systest.TestRestQueryIgnoreNumbers(t, delegatorRewardsTestCases...)
// test delegator validators grpc endpoint
delegatorValsURL := baseurl + `/cosmos/distribution/v1beta1/delegators/%s/validators`
valsTestCases := []RestTestCase{
valsTestCases := []systest.RestTestCase{
{
"gRPC request delegator validators with valid delegator address",
fmt.Sprintf(delegatorValsURL, delAddr),
@@ -285,11 +281,11 @@ func TestDistrDelegatorGRPCQueries(t *testing.T) {
fmt.Sprintf(`{"validators":["%s"]}`, valOperAddr),
},
}
RunRestQueries(t, valsTestCases)
systest.RunRestQueries(t, valsTestCases...)
// test withdraw address grpc endpoint
withdrawAddrURL := baseurl + `/cosmos/distribution/v1beta1/delegators/%s/withdraw_address`
withdrawAddrTestCases := []RestTestCase{
withdrawAddrTestCases := []systest.RestTestCase{
{
"gRPC request withdraw address with valid delegator address",
fmt.Sprintf(withdrawAddrURL, delAddr),
@@ -297,5 +293,5 @@ func TestDistrDelegatorGRPCQueries(t *testing.T) {
fmt.Sprintf(`{"withdraw_address":"%s"}`, delAddr),
},
}
RunRestQueries(t, withdrawAddrTestCases)
systest.RunRestQueries(t, withdrawAddrTestCases...)
}
+17 -16
View File
@@ -6,32 +6,33 @@ import (
"fmt"
"os"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tidwall/gjson"
systest "cosmossdk.io/systemtests"
)
func TestExportCmd_WithHeight(t *testing.T) {
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
systest.Sut.ResetChain(t)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
sut.StartChain(t)
systest.Sut.StartChain(t)
// Wait 10s for producing blocks
time.Sleep(10 * time.Second)
systest.Sut.AwaitNBlocks(t, 10)
sut.StopChain()
systest.Sut.StopChain()
testCases := []struct {
name string
args []string
expZeroHeight bool
}{
{"should export correct height", []string{"genesis", "export", "--home", sut.nodePath(0)}, false},
{"should export correct height with --height", []string{"genesis", "export", "--height=5", "--home", sut.nodePath(0), "--log_level=disabled"}, false},
{"should export height 0 with --for-zero-height", []string{"genesis", "export", "--for-zero-height=true", "--home", sut.nodePath(0)}, true},
{"should export correct height", []string{"genesis", "export", "--home", systest.Sut.NodeDir(0)}, false},
{"should export correct height with --height", []string{"genesis", "export", "--height=5", "--home", systest.Sut.NodeDir(0), "--log_level=disabled"}, false},
{"should export height 0 with --for-zero-height", []string{"genesis", "export", "--for-zero-height=true", "--home", systest.Sut.NodeDir(0)}, true},
}
for _, tc := range testCases {
@@ -45,21 +46,21 @@ func TestExportCmd_WithHeight(t *testing.T) {
// Check consensus params of exported state
maxGas := gjson.Get(res, "consensus.params.block.max_gas").Int()
require.Equal(t, maxGas, int64(MaxGas))
require.Equal(t, maxGas, int64(systest.MaxGas))
}
}
func TestExportCmd_WithFileFlag(t *testing.T) {
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
systest.Sut.ResetChain(t)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
exportFile := "foobar.json"
sut.StartChain(t)
systest.Sut.StartChain(t)
// Wait 10s for producing blocks
time.Sleep(10 * time.Second)
systest.Sut.AwaitNBlocks(t, 10)
sut.StopChain()
systest.Sut.StopChain()
testCases := []struct {
name string
@@ -68,7 +69,7 @@ func TestExportCmd_WithFileFlag(t *testing.T) {
errMsg string
}{
{"invalid home dir", []string{"genesis", "export", "--home=foo"}, true, "no such file or directory"},
{"should export state to the specified file", []string{"genesis", "export", fmt.Sprintf("--output-document=%s", exportFile), "--home", sut.nodePath(0)}, false, ""},
{"should export state to the specified file", []string{"genesis", "export", fmt.Sprintf("--output-document=%s", exportFile), "--home", systest.Sut.NodeDir(0)}, false, ""},
}
for _, tc := range testCases {
+16 -14
View File
@@ -11,6 +11,8 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tidwall/gjson"
systest "cosmossdk.io/systemtests"
)
func TestValidatorDoubleSign(t *testing.T) {
@@ -18,35 +20,35 @@ func TestValidatorDoubleSign(t *testing.T) {
// given: a running chain
// when: a second instance with the same val key signs a block
// then: the validator is removed from the active set and jailed forever
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
sut.StartChain(t)
systest.Sut.ResetChain(t)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
systest.Sut.StartChain(t)
// Check the validator is in the active set
rsp := cli.CustomQuery("q", "staking", "validators")
t.Log(rsp)
validatorPubKey := LoadValidatorPubKeyForNode(t, sut, 0)
rpc, pkBz := sut.RPCClient(t), validatorPubKey.Bytes()
validatorPubKey := systest.LoadValidatorPubKeyForNode(t, systest.Sut, 0)
rpc, pkBz := systest.Sut.RPCClient(t), validatorPubKey.Bytes()
nodePowerBefore := QueryCometValidatorPower(rpc, pkBz)
nodePowerBefore := systest.QueryCometValidatorPower(rpc, pkBz)
require.NotEmpty(t, nodePowerBefore)
t.Logf("nodePowerBefore: %v", nodePowerBefore)
newNode := sut.AddFullnode(t, func(nodeNumber int, nodePath string) {
valKeyFile := filepath.Join(WorkDir, nodePath, "config", "priv_validator_key.json")
newNode := systest.Sut.AddFullnode(t, func(nodeNumber int, nodePath string) {
valKeyFile := filepath.Join(systest.WorkDir, nodePath, "config", "priv_validator_key.json")
_ = os.Remove(valKeyFile)
_ = MustCopyFile(filepath.Join(WorkDir, sut.nodePath(0), "config", "priv_validator_key.json"), valKeyFile)
_ = systest.MustCopyFile(filepath.Join(systest.Sut.NodeDir(0), "config", "priv_validator_key.json"), valKeyFile)
})
sut.AwaitNodeUp(t, fmt.Sprintf("http://%s:%d", newNode.IP, newNode.RPCPort))
systest.Sut.AwaitNodeUp(t, fmt.Sprintf("http://%s:%d", newNode.IP, newNode.RPCPort))
// let's wait some blocks to have evidence and update persisted
var nodePowerAfter int64 = -1
for i := 0; i < 30; i++ {
sut.AwaitNextBlock(t)
if nodePowerAfter = QueryCometValidatorPower(rpc, pkBz); nodePowerAfter == 0 {
systest.Sut.AwaitNextBlock(t)
if nodePowerAfter = systest.QueryCometValidatorPower(rpc, pkBz); nodePowerAfter == 0 {
break
}
t.Logf("wait %d", sut.CurrentHeight())
t.Logf("wait %d", systest.Sut.CurrentHeight())
}
// then comet status updated
require.Empty(t, nodePowerAfter)
@@ -57,5 +59,5 @@ func TestValidatorDoubleSign(t *testing.T) {
assert.True(t, gjson.Get(rsp, "validator.jailed").Bool(), rsp)
// let's run for some blocks to confirm all good
sut.AwaitNBlocks(t, 5)
systest.Sut.AwaitNBlocks(t, 5)
}
+8 -5
View File
@@ -20,14 +20,12 @@ require (
github.com/stretchr/testify v1.10.0
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
google.golang.org/grpc v1.68.0
google.golang.org/grpc v1.68.0 // indirect
)
require (
cosmossdk.io/math v1.4.0
github.com/cometbft/cometbft v0.38.15
github.com/cometbft/cometbft/api v1.0.0-rc.1
github.com/creachadair/tomledit v0.0.26
cosmossdk.io/systemtests v0.0.0-00010101000000-000000000000
github.com/tidwall/gjson v1.14.2
github.com/tidwall/sjson v1.2.5
)
@@ -60,12 +58,15 @@ require (
github.com/cockroachdb/pebble v1.1.1 // indirect
github.com/cockroachdb/redact v1.1.5 // indirect
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
github.com/cometbft/cometbft v0.38.15 // indirect
github.com/cometbft/cometbft-db v0.14.1 // indirect
github.com/cometbft/cometbft/api v1.0.0-rc.1 // indirect
github.com/cosmos/btcutil v1.0.5 // indirect
github.com/cosmos/cosmos-db v1.0.3-0.20240829004618-717cba019b33 // indirect
github.com/cosmos/go-bip39 v1.0.0 // indirect
github.com/cosmos/ics23/go v0.11.0 // indirect
github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect
github.com/creachadair/tomledit v0.0.26 // indirect
github.com/danieljoos/wincred v1.1.2 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
@@ -153,7 +154,7 @@ require (
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/arch v0.12.0 // indirect
golang.org/x/crypto v0.29.0 // indirect
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect
golang.org/x/net v0.30.0 // indirect
golang.org/x/sync v0.9.0 // indirect
golang.org/x/sys v0.27.0 // indirect
@@ -169,3 +170,5 @@ require (
pgregory.net/rapid v1.1.0 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)
replace cosmossdk.io/systemtests => ../../systemtests
+6 -6
View File
@@ -772,8 +772,8 @@ golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgR
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f h1:XdNn9LlyWAhLVp6P/i8QYBW+hlyhrhei9uErw2B5GJo=
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f/go.mod h1:D5SMRVC3C2/4+F/DB1wZsLRnSNimn2Sp/NPsCrsv8ak=
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc h1:O9NuF4s+E/PvMIy+9IUZB9znFwUIXEWSstNjek6VpVg=
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -787,8 +787,8 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -920,8 +920,8 @@ golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapK
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o=
golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+32 -32
View File
@@ -13,6 +13,7 @@ import (
"github.com/tidwall/gjson"
"cosmossdk.io/math"
systest "cosmossdk.io/systemtests"
"github.com/cosmos/cosmos-sdk/client/flags"
sdk "github.com/cosmos/cosmos-sdk/types"
@@ -21,14 +22,14 @@ import (
func TestSubmitProposal(t *testing.T) {
// given a running chain
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
systest.Sut.ResetChain(t)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator address
valAddr := gjson.Get(cli.Keys("keys", "list"), "0.address").String()
require.NotEmpty(t, valAddr)
sut.StartChain(t)
systest.Sut.StartChain(t)
// get gov module address
resp := cli.CustomQuery("q", "auth", "module-account", "gov")
@@ -41,7 +42,7 @@ func TestSubmitProposal(t *testing.T) {
"deposit": "-324foocoin"
}`
invalidPropFile := StoreTempFile(t, []byte(invalidProp))
invalidPropFile := systest.StoreTempFile(t, []byte(invalidProp))
defer invalidPropFile.Close()
// Create a valid new proposal JSON.
@@ -64,7 +65,7 @@ func TestSubmitProposal(t *testing.T) {
"metadata": "%s",
"deposit": "%s"
}`, govAddress, base64.StdEncoding.EncodeToString(propMetadata), sdk.NewCoin("stake", math.NewInt(100000)))
validPropFile := StoreTempFile(t, []byte(validProp))
validPropFile := systest.StoreTempFile(t, []byte(validProp))
defer validPropFile.Close()
testCases := []struct {
@@ -114,7 +115,7 @@ func TestSubmitProposal(t *testing.T) {
rsp := cli.Run(tc.args...)
txResult, found := cli.AwaitTxCommitted(rsp)
require.True(t, found)
RequireTxSuccess(t, txResult)
systest.RequireTxSuccess(t, txResult)
}
})
}
@@ -123,14 +124,14 @@ func TestSubmitProposal(t *testing.T) {
func TestSubmitLegacyProposal(t *testing.T) {
// given a running chain
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
systest.Sut.ResetChain(t)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator address
valAddr := gjson.Get(cli.Keys("keys", "list"), "0.address").String()
require.NotEmpty(t, valAddr)
sut.StartChain(t)
systest.Sut.StartChain(t)
invalidProp := `{
"title": "",
@@ -138,7 +139,7 @@ func TestSubmitLegacyProposal(t *testing.T) {
"type": "Text",
"deposit": "-324foocoin"
}`
invalidPropFile := StoreTempFile(t, []byte(invalidProp))
invalidPropFile := systest.StoreTempFile(t, []byte(invalidProp))
defer invalidPropFile.Close()
validProp := fmt.Sprintf(`{
@@ -147,7 +148,7 @@ func TestSubmitLegacyProposal(t *testing.T) {
"type": "Text",
"deposit": "%s"
}`, sdk.NewCoin("stake", math.NewInt(154310)))
validPropFile := StoreTempFile(t, []byte(validProp))
validPropFile := systest.StoreTempFile(t, []byte(validProp))
defer validPropFile.Close()
testCases := []struct {
@@ -227,7 +228,7 @@ func TestSubmitLegacyProposal(t *testing.T) {
rsp := cli.Run(tc.args...)
txResult, found := cli.AwaitTxCommitted(rsp)
require.True(t, found)
RequireTxSuccess(t, txResult)
systest.RequireTxSuccess(t, txResult)
}
})
}
@@ -236,14 +237,14 @@ func TestSubmitLegacyProposal(t *testing.T) {
func TestNewCmdWeightedVote(t *testing.T) {
// given a running chain
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
systest.Sut.ResetChain(t)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator address
valAddr := gjson.Get(cli.Keys("keys", "list"), "0.address").String()
require.NotEmpty(t, valAddr)
sut.StartChain(t)
systest.Sut.StartChain(t)
// Submit a new proposal for voting
proposalArgs := []string{
@@ -260,7 +261,7 @@ func TestNewCmdWeightedVote(t *testing.T) {
rsp := cli.Run(proposalArgs...)
txResult, found := cli.AwaitTxCommitted(rsp)
require.True(t, found)
RequireTxSuccess(t, txResult)
systest.RequireTxSuccess(t, txResult)
proposalsResp := cli.CustomQuery("q", "gov", "proposals")
proposals := gjson.Get(proposalsResp, "proposals.#.id").Array()
@@ -361,7 +362,7 @@ func TestNewCmdWeightedVote(t *testing.T) {
} else {
rsp := cli.Run(tc.args...)
if tc.expectErr {
RequireTxFailure(t, rsp)
systest.RequireTxFailure(t, rsp)
} else {
cli.AwaitTxCommitted(rsp)
}
@@ -372,22 +373,20 @@ func TestNewCmdWeightedVote(t *testing.T) {
func TestQueryDeposit(t *testing.T) {
// given a running chain
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
systest.Sut.ResetChain(t)
// short voting period
// update expedited voting period to avoid validation error
sut.ModifyGenesisJSON(
votingPeriod := 3 * time.Second
systest.Sut.ModifyGenesisJSON(
t,
SetGovVotingPeriod(t, time.Second*8),
SetGovExpeditedVotingPeriod(t, time.Second*7),
systest.SetGovVotingPeriod(t, votingPeriod),
systest.SetGovExpeditedVotingPeriod(t, votingPeriod-time.Second),
)
systest.Sut.StartChain(t)
// get validator address
valAddr := gjson.Get(cli.Keys("keys", "list"), "0.address").String()
require.NotEmpty(t, valAddr)
sut.StartChain(t)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
valAddr := cli.GetKeyAddr("node0")
// Submit a new proposal for voting
proposalArgs := []string{
@@ -404,7 +403,7 @@ func TestQueryDeposit(t *testing.T) {
rsp := cli.Run(proposalArgs...)
txResult, found := cli.AwaitTxCommitted(rsp)
require.True(t, found)
RequireTxSuccess(t, txResult)
systest.RequireTxSuccess(t, txResult)
// Query initial deposit
resp := cli.CustomQuery("q", "gov", "deposit", "1", valAddr)
@@ -415,8 +414,9 @@ func TestQueryDeposit(t *testing.T) {
deposits := gjson.Get(resp, "deposits").Array()
require.Equal(t, len(deposits), 1)
time.Sleep(time.Second * 8)
resp = cli.CustomQuery("q", "gov", "deposits", "1")
deposits = gjson.Get(resp, "deposits").Array()
require.Equal(t, len(deposits), 0)
assert.Eventually(t, func() bool {
resp = cli.CustomQuery("q", "gov", "deposits", "1")
deposits = gjson.Get(resp, "deposits").Array()
return len(deposits) == 0
}, votingPeriod, 100*time.Millisecond)
}
+21 -19
View File
@@ -8,6 +8,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/tidwall/gjson"
systest "cosmossdk.io/systemtests"
)
const (
@@ -18,18 +20,18 @@ func TestGroupCommands(t *testing.T) {
// scenario: test group commands
// given a running chain
sut.ResetChain(t)
require.GreaterOrEqual(t, sut.NodesCount(), 2)
systest.Sut.ResetChain(t)
require.GreaterOrEqual(t, systest.Sut.NodesCount(), 2)
cli := NewCLIWrapper(t, sut, verbose)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)
sut.StartChain(t)
systest.Sut.StartChain(t)
baseurl := sut.APIAddress()
baseurl := systest.Sut.APIAddress()
// test create group
memberWeight := "5"
@@ -43,10 +45,10 @@ func TestGroupCommands(t *testing.T) {
}
]
}`, valAddr, memberWeight, validMetadata)
validMembersFile := StoreTempFile(t, []byte(validMembers))
validMembersFile := systest.StoreTempFile(t, []byte(validMembers))
createGroupCmd := []string{"tx", "group", "create-group", valAddr, validMetadata, validMembersFile.Name(), "--from=" + valAddr}
rsp := cli.RunAndWait(createGroupCmd...)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// query groups by admin to confirm group creation
rsp = cli.CustomQuery("q", "group", "groups-by-admin", valAddr)
@@ -56,34 +58,34 @@ func TestGroupCommands(t *testing.T) {
// test create group policies
for i := 0; i < 5; i++ {
threshold := i + 1
policyFile := StoreTempFile(t, []byte(fmt.Sprintf(`{"@type":"/cosmos.group.v1.ThresholdDecisionPolicy", "threshold":"%d", "windows":{"voting_period":"30000s"}}`, threshold)))
policyFile := systest.StoreTempFile(t, []byte(fmt.Sprintf(`{"@type":"/cosmos.group.v1.ThresholdDecisionPolicy", "threshold":"%d", "windows":{"voting_period":"30000s"}}`, threshold)))
policyCmd := []string{"tx", "group", "create-group-policy", valAddr, groupId, validMetadata, policyFile.Name(), "--from=" + valAddr}
rsp = cli.RunAndWait(policyCmd...)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// TODO: remove isV2() check once v2 is integrated with grpc gateway
var groupPoliciesResp, policyAddrQuery string
if isV2() {
if systest.IsV2() {
groupPoliciesResp = cli.CustomQuery("q", "group", "group-policies-by-group", groupId)
policyAddrQuery = fmt.Sprintf("group_policies.#(decision_policy.value.threshold==%d).address", threshold)
} else {
groupPoliciesResp = string(GetRequest(t, fmt.Sprintf("%s/cosmos/group/v1/group_policies_by_group/%s", baseurl, groupId)))
groupPoliciesResp = string(systest.GetRequest(t, fmt.Sprintf("%s/cosmos/group/v1/group_policies_by_group/%s", baseurl, groupId)))
policyAddrQuery = fmt.Sprintf("group_policies.#(decision_policy.threshold==%d).address", threshold)
}
require.Equal(t, gjson.Get(groupPoliciesResp, "pagination.total").Int(), int64(threshold))
policyAddr := gjson.Get(groupPoliciesResp, policyAddrQuery).String()
require.NotEmpty(t, policyAddr)
rsp = cli.RunCommandWithArgs(cli.withTXFlags("tx", "bank", "send", valAddr, policyAddr, "1000stake", "--generate-only")...)
rsp = cli.RunCommandWithArgs(cli.WithTXFlags("tx", "bank", "send", valAddr, policyAddr, "1000stake", "--generate-only")...)
require.Equal(t, policyAddr, gjson.Get(rsp, "body.messages.0.to_address").String())
}
// test create group policy with percentage decision policy
percentagePolicyType := "/cosmos.group.v1.PercentageDecisionPolicy"
policyFile := StoreTempFile(t, []byte(fmt.Sprintf(`{"@type":"%s", "percentage":"%f", "windows":{"voting_period":"30000s"}}`, percentagePolicyType, 0.5)))
policyFile := systest.StoreTempFile(t, []byte(fmt.Sprintf(`{"@type":"%s", "percentage":"%f", "windows":{"voting_period":"30000s"}}`, percentagePolicyType, 0.5)))
policyCmd := []string{"tx", "group", "create-group-policy", valAddr, groupId, validMetadata, policyFile.Name(), "--from=" + valAddr}
rsp = cli.RunAndWait(policyCmd...)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
groupPoliciesResp := cli.CustomQuery("q", "group", "group-policies-by-admin", valAddr)
require.Equal(t, gjson.Get(groupPoliciesResp, "pagination.total").Int(), int64(6))
@@ -106,9 +108,9 @@ func TestGroupCommands(t *testing.T) {
"summary": "Summary",
"proposers": ["%s"]
}`, policyAddr, policyAddr, valAddr, validMetadata, valAddr)
proposalFile := StoreTempFile(t, []byte(proposalJSON))
proposalFile := systest.StoreTempFile(t, []byte(proposalJSON))
rsp = cli.RunAndWait("tx", "group", "submit-proposal", proposalFile.Name())
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// query proposals
rsp = cli.CustomQuery("q", "group", "proposals-by-group-policy", policyAddr)
@@ -117,15 +119,15 @@ func TestGroupCommands(t *testing.T) {
// test vote proposal
rsp = cli.RunAndWait("tx", "group", "vote", proposalId, valAddr, "yes", validMetadata)
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
// query votes
// TODO: remove isV2() check once v2 is integrated with grpc gateway
var voteResp string
if isV2() {
if systest.IsV2() {
voteResp = cli.CustomQuery("q", "group", "vote", proposalId, valAddr)
} else {
voteResp = string(GetRequest(t, fmt.Sprintf("%s/cosmos/group/v1/vote_by_proposal_voter/%s/%s", baseurl, proposalId, valAddr)))
voteResp = string(systest.GetRequest(t, fmt.Sprintf("%s/cosmos/group/v1/vote_by_proposal_voter/%s/%s", baseurl, proposalId, valAddr)))
}
require.Equal(t, "VOTE_OPTION_YES", gjson.Get(voteResp, "vote.option").String())
}
+6 -2
View File
@@ -2,8 +2,12 @@
package systemtests
import "testing"
import (
"testing"
systest "cosmossdk.io/systemtests"
)
func TestMain(m *testing.M) {
RunTests(m)
systest.RunTests(m)
}
+11 -9
View File
@@ -7,16 +7,18 @@ import (
"github.com/stretchr/testify/require"
"github.com/tidwall/sjson"
systest "cosmossdk.io/systemtests"
)
func TestMintQueries(t *testing.T) {
// scenario: test mint grpc queries
// given a running chain
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
systest.Sut.ResetChain(t)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
sut.ModifyGenesisJSON(t,
systest.Sut.ModifyGenesisJSON(t,
func(genesis []byte) []byte {
state, err := sjson.Set(string(genesis), "app_state.mint.minter.inflation", "1.00")
require.NoError(t, err)
@@ -29,17 +31,17 @@ func TestMintQueries(t *testing.T) {
},
)
sut.StartChain(t)
systest.Sut.StartChain(t)
sut.AwaitNextBlock(t)
systest.Sut.AwaitNextBlock(t)
baseurl := sut.APIAddress()
baseurl := systest.Sut.APIAddress()
blockHeightHeader := "x-cosmos-block-height"
queryAtHeight := "1"
// TODO: check why difference in values when querying with height between v1 and v2
// ref: https://github.com/cosmos/cosmos-sdk/issues/22302
if isV2() {
if systest.IsV2() {
queryAtHeight = "2"
}
@@ -78,10 +80,10 @@ func TestMintQueries(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// TODO: remove below check once grpc gateway is implemented in v2
if isV2() {
if systest.IsV2() {
return
}
resp := GetRequestWithHeaders(t, tc.url, tc.headers, http.StatusOK)
resp := systest.GetRequestWithHeaders(t, tc.url, tc.headers, http.StatusOK)
require.JSONEq(t, tc.expOut, string(resp))
})
}
+17 -15
View File
@@ -8,24 +8,26 @@ import (
"testing"
"github.com/stretchr/testify/require"
systest "cosmossdk.io/systemtests"
)
func TestSnapshots(t *testing.T) {
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
sut.StartChain(t)
systest.Sut.ResetChain(t)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
systest.Sut.StartChain(t)
// Wait for chain produce some blocks
sut.AwaitNBlocks(t, 6)
systest.Sut.AwaitNBlocks(t, 6)
// Stop all nodes
sut.StopChain()
systest.Sut.StopChain()
var (
command string
restoreableDirs []string
)
node0Dir := sut.NodeDir(0)
if isV2() {
node0Dir := systest.Sut.NodeDir(0)
if systest.IsV2() {
command = "store"
restoreableDirs = []string{fmt.Sprintf("%s/data/application.db", node0Dir), fmt.Sprintf("%s/data/ss", node0Dir)}
} else {
@@ -62,7 +64,7 @@ func TestSnapshots(t *testing.T) {
// Remove database
err := os.RemoveAll(fmt.Sprintf("%s/data/application.db", node0Dir))
require.NoError(t, err)
if isV2() {
if systest.IsV2() {
require.NoError(t, os.RemoveAll(fmt.Sprintf("%s/data/ss", node0Dir)))
}
@@ -73,22 +75,22 @@ func TestSnapshots(t *testing.T) {
}
func TestPrune(t *testing.T) {
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
systest.Sut.ResetChain(t)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
sut.StartChain(t)
systest.Sut.StartChain(t)
// Wait for chain produce some blocks
sut.AwaitNBlocks(t, 6)
systest.Sut.AwaitNBlocks(t, 6)
// Stop all nodes
sut.StopChain()
systest.Sut.StopChain()
node0Dir := sut.NodeDir(0)
node0Dir := systest.Sut.NodeDir(0)
// prune
var command []string
if isV2() {
if systest.IsV2() {
command = []string{"store", "prune", "--store.keep-recent=1"}
} else {
command = []string{"prune", "everything"}
+8 -6
View File
@@ -7,6 +7,8 @@ import (
"github.com/stretchr/testify/assert"
"github.com/tidwall/gjson"
systest "cosmossdk.io/systemtests"
)
func TestStakeUnstake(t *testing.T) {
@@ -15,17 +17,17 @@ func TestStakeUnstake(t *testing.T) {
// check validator has been updated
// undelegate some tokens
sut.ResetChain(t)
systest.Sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// add genesis account with some tokens
account1Addr := cli.AddKey("account1")
sut.ModifyGenesisCLI(t,
systest.Sut.ModifyGenesisCLI(t,
[]string{"genesis", "add-genesis-account", account1Addr, "10000000stake"},
)
sut.StartChain(t)
systest.Sut.StartChain(t)
// query validator address to delegate tokens
rsp := cli.CustomQuery("q", "staking", "validators")
@@ -34,7 +36,7 @@ func TestStakeUnstake(t *testing.T) {
// stake tokens
rsp = cli.RunAndWait("tx", "staking", "delegate", valAddr, "1000000stake", "--from="+account1Addr, "--fees=1stake")
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
t.Log(cli.QueryBalance(account1Addr, "stake"))
assert.Equal(t, int64(8999999), cli.QueryBalance(account1Addr, "stake"))
@@ -52,7 +54,7 @@ func TestStakeUnstake(t *testing.T) {
// unstake tokens
rsp = cli.RunAndWait("tx", "staking", "unbond", valAddr, "5000stake", "--from="+account1Addr, "--fees=1stake")
RequireTxSuccess(t, rsp)
systest.RequireTxSuccess(t, rsp)
rsp = cli.CustomQuery("q", "staking", "delegation", account1Addr, valAddr)
assert.Equal(t, "995000", gjson.Get(rsp, "delegation_response.balance.amount").String(), rsp)
+111 -111
View File
@@ -6,23 +6,23 @@ import (
"context"
"encoding/base64"
"encoding/json"
"os"
"fmt"
"os"
"testing"
"github.com/cosmos/cosmos-sdk/testutil"
"github.com/cosmos/cosmos-sdk/types/tx"
"github.com/stretchr/testify/require"
"github.com/tidwall/gjson"
systest "cosmossdk.io/systemtests"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/legacy"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/std"
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/query"
"github.com/cosmos/cosmos-sdk/types/tx"
"github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
)
@@ -34,9 +34,9 @@ var (
)
func TestQueryBySig(t *testing.T) {
sut.ResetChain(t)
systest.Sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)
@@ -44,21 +44,21 @@ func TestQueryBySig(t *testing.T) {
// add new key
receiverAddr := cli.AddKey("account1")
sut.StartChain(t)
systest.Sut.StartChain(t)
qc := tx.NewServiceClient(sut.RPCClient(t))
qc := tx.NewServiceClient(systest.Sut.RPCClient(t))
// create unsign tx
bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=10stake", fmt.Sprintf("--chain-id=%s", sut.chainID), "--sign-mode=direct", "--generate-only"}
bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=10stake", "--chain-id=" + cli.ChainID(), "--sign-mode=direct", "--generate-only"}
unsignedTx := cli.RunCommandWithArgs(bankSendCmdArgs...)
txFile := StoreTempFile(t, []byte(unsignedTx))
txFile := systest.StoreTempFile(t, []byte(unsignedTx))
signedTx := cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", valAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet/node0/simd")
signedTx := cli.RunCommandWithArgs("tx", "sign", txFile.Name(), "--from="+valAddr, "--chain-id="+cli.ChainID(), "--keyring-backend=test", "--home="+systest.Sut.NodeDir(0))
sig := gjson.Get(signedTx, "signatures.0").String()
signedTxFile := StoreTempFile(t, []byte(signedTx))
signedTxFile := systest.StoreTempFile(t, []byte(signedTx))
res := cli.Run("tx", "broadcast", signedTxFile.Name())
RequireTxSuccess(t, res)
systest.RequireTxSuccess(t, res)
sigFormatted := fmt.Sprintf("%s.%s='%s'", sdk.EventTypeTx, sdk.AttributeKeySignature, sig)
resp, err := qc.GetTxsEvent(context.Background(), &tx.GetTxsEventRequest{
@@ -73,9 +73,9 @@ func TestQueryBySig(t *testing.T) {
}
func TestSimulateTx_GRPC(t *testing.T) {
sut.ResetChain(t)
systest.Sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)
@@ -83,17 +83,17 @@ func TestSimulateTx_GRPC(t *testing.T) {
// add new key
receiverAddr := cli.AddKey("account1")
sut.StartChain(t)
systest.Sut.StartChain(t)
qc := tx.NewServiceClient(sut.RPCClient(t))
qc := tx.NewServiceClient(systest.Sut.RPCClient(t))
// create unsign tx
bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), fmt.Sprintf("--chain-id=%s", sut.chainID), "--fees=10stake", "--sign-mode=direct", "--generate-only"}
bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--chain-id=" + cli.ChainID(), "--fees=10stake", "--sign-mode=direct", "--generate-only"}
res := cli.RunCommandWithArgs(bankSendCmdArgs...)
txFile := StoreTempFile(t, []byte(res))
txFile := systest.StoreTempFile(t, []byte(res))
res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", valAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet/node0/simd")
signedTxFile := StoreTempFile(t, []byte(res))
res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), "--from="+valAddr, "--chain-id="+cli.ChainID(), "--keyring-backend=test", "--home="+systest.Sut.NodeDir(0))
signedTxFile := systest.StoreTempFile(t, []byte(res))
res = cli.RunCommandWithArgs("tx", "encode", signedTxFile.Name())
txBz, err := base64.StdEncoding.DecodeString(res)
@@ -135,9 +135,9 @@ func TestSimulateTx_GRPC(t *testing.T) {
}
func TestSimulateTx_GRPCGateway(t *testing.T) {
sut.ResetChain(t)
systest.Sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)
@@ -145,18 +145,18 @@ func TestSimulateTx_GRPCGateway(t *testing.T) {
// add new key
receiverAddr := cli.AddKey("account1")
sut.StartChain(t)
systest.Sut.StartChain(t)
// qc := tx.NewServiceClient(sut.RPCClient(t))
baseURL := sut.APIAddress()
baseURL := systest.Sut.APIAddress()
// create unsign tx
bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), fmt.Sprintf("--chain-id=%s", sut.chainID), "--fees=10stake", "--sign-mode=direct", "--generate-only"}
bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--chain-id=" + cli.ChainID(), "--fees=10stake", "--sign-mode=direct", "--generate-only"}
res := cli.RunCommandWithArgs(bankSendCmdArgs...)
txFile := StoreTempFile(t, []byte(res))
txFile := systest.StoreTempFile(t, []byte(res))
res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", valAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet/node0/simd")
signedTxFile := StoreTempFile(t, []byte(res))
res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), "--from="+valAddr, "--chain-id="+cli.ChainID(), "--keyring-backend=test", "--home="+systest.Sut.NodeDir(0))
signedTxFile := systest.StoreTempFile(t, []byte(res))
res = cli.RunCommandWithArgs("tx", "encode", signedTxFile.Name())
txBz, err := base64.StdEncoding.DecodeString(res)
@@ -197,9 +197,9 @@ func TestSimulateTx_GRPCGateway(t *testing.T) {
}
func TestGetTxEvents_GRPC(t *testing.T) {
sut.ResetChain(t)
systest.Sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)
@@ -207,18 +207,18 @@ func TestGetTxEvents_GRPC(t *testing.T) {
// add new key
receiverAddr := cli.AddKey("account1")
sut.StartChain(t)
systest.Sut.StartChain(t)
qc := tx.NewServiceClient(sut.RPCClient(t))
qc := tx.NewServiceClient(systest.Sut.RPCClient(t))
rsp := cli.Run("tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--note=foobar", "--fees=1stake")
txResult, found := cli.AwaitTxCommitted(rsp)
require.True(t, found)
RequireTxSuccess(t, txResult)
systest.RequireTxSuccess(t, txResult)
rsp = cli.Run("tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=1stake")
txResult, found = cli.AwaitTxCommitted(rsp)
require.True(t, found)
RequireTxSuccess(t, txResult)
systest.RequireTxSuccess(t, txResult)
testCases := []struct {
name string
@@ -311,9 +311,9 @@ func TestGetTxEvents_GRPC(t *testing.T) {
}
func TestGetTxEvents_GRPCGateway(t *testing.T) {
sut.ResetChain(t)
systest.Sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)
@@ -321,19 +321,19 @@ func TestGetTxEvents_GRPCGateway(t *testing.T) {
// add new key
receiverAddr := cli.AddKey("account1")
sut.StartChain(t)
systest.Sut.StartChain(t)
// qc := tx.NewServiceClient(sut.RPCClient(t))
baseURL := sut.APIAddress()
baseURL := systest.Sut.APIAddress()
rsp := cli.Run("tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--note=foobar", "--fees=1stake")
txResult, found := cli.AwaitTxCommitted(rsp)
require.True(t, found)
RequireTxSuccess(t, txResult)
systest.RequireTxSuccess(t, txResult)
rsp = cli.Run("tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=1stake")
txResult, found = cli.AwaitTxCommitted(rsp)
require.True(t, found)
RequireTxSuccess(t, txResult)
systest.RequireTxSuccess(t, txResult)
testCases := []struct {
name string
@@ -407,9 +407,9 @@ func TestGetTxEvents_GRPCGateway(t *testing.T) {
}
func TestGetTx_GRPC(t *testing.T) {
sut.ResetChain(t)
systest.Sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)
@@ -417,14 +417,14 @@ func TestGetTx_GRPC(t *testing.T) {
// add new key
receiverAddr := cli.AddKey("account1")
sut.StartChain(t)
systest.Sut.StartChain(t)
qc := tx.NewServiceClient(sut.RPCClient(t))
qc := tx.NewServiceClient(systest.Sut.RPCClient(t))
rsp := cli.Run("tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=1stake", "--note=foobar")
txResult, found := cli.AwaitTxCommitted(rsp)
require.True(t, found)
RequireTxSuccess(t, txResult)
systest.RequireTxSuccess(t, txResult)
txHash := gjson.Get(txResult, "txhash").String()
testCases := []struct {
@@ -454,9 +454,9 @@ func TestGetTx_GRPC(t *testing.T) {
}
func TestGetTx_GRPCGateway(t *testing.T) {
sut.ResetChain(t)
systest.Sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)
@@ -464,14 +464,14 @@ func TestGetTx_GRPCGateway(t *testing.T) {
// add new key
receiverAddr := cli.AddKey("account1")
sut.StartChain(t)
systest.Sut.StartChain(t)
baseURL := sut.APIAddress()
baseURL := systest.Sut.APIAddress()
rsp := cli.Run("tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=1stake", "--note=foobar")
txResult, found := cli.AwaitTxCommitted(rsp)
require.True(t, found)
RequireTxSuccess(t, txResult)
systest.RequireTxSuccess(t, txResult)
txHash := gjson.Get(txResult, "txhash").String()
testCases := []struct {
@@ -517,9 +517,9 @@ func TestGetTx_GRPCGateway(t *testing.T) {
}
func TestGetBlockWithTxs_GRPC(t *testing.T) {
sut.ResetChain(t)
systest.Sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)
@@ -527,14 +527,14 @@ func TestGetBlockWithTxs_GRPC(t *testing.T) {
// add new key
receiverAddr := cli.AddKey("account1")
sut.StartChain(t)
systest.Sut.StartChain(t)
qc := tx.NewServiceClient(sut.RPCClient(t))
qc := tx.NewServiceClient(systest.Sut.RPCClient(t))
rsp := cli.Run("tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=1stake", "--note=foobar")
txResult, found := cli.AwaitTxCommitted(rsp)
require.True(t, found)
RequireTxSuccess(t, txResult)
systest.RequireTxSuccess(t, txResult)
height := gjson.Get(txResult, "height").Int()
testCases := []struct {
@@ -575,9 +575,9 @@ func TestGetBlockWithTxs_GRPC(t *testing.T) {
}
func TestGetBlockWithTxs_GRPCGateway(t *testing.T) {
sut.ResetChain(t)
systest.Sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)
@@ -585,14 +585,14 @@ func TestGetBlockWithTxs_GRPCGateway(t *testing.T) {
// add new key
receiverAddr := cli.AddKey("account1")
sut.StartChain(t)
systest.Sut.StartChain(t)
baseUrl := sut.APIAddress()
baseUrl := systest.Sut.APIAddress()
rsp := cli.Run("tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=1stake", "--note=foobar")
txResult, found := cli.AwaitTxCommitted(rsp)
require.True(t, found)
RequireTxSuccess(t, txResult)
systest.RequireTxSuccess(t, txResult)
height := gjson.Get(txResult, "height").Int()
testCases := []struct {
@@ -635,16 +635,16 @@ func TestGetBlockWithTxs_GRPCGateway(t *testing.T) {
}
func TestTxEncode_GRPC(t *testing.T) {
sut.ResetChain(t)
systest.Sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)
sut.StartChain(t)
systest.Sut.StartChain(t)
qc := tx.NewServiceClient(sut.RPCClient(t))
qc := tx.NewServiceClient(systest.Sut.RPCClient(t))
protoTx := &tx.Tx{
Body: &tx.TxBody{
@@ -680,16 +680,16 @@ func TestTxEncode_GRPC(t *testing.T) {
}
func TestTxEncode_GRPCGateway(t *testing.T) {
sut.ResetChain(t)
systest.Sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)
sut.StartChain(t)
systest.Sut.StartChain(t)
baseUrl := sut.APIAddress()
baseUrl := systest.Sut.APIAddress()
protoTx := &tx.Tx{
Body: &tx.TxBody{
@@ -724,9 +724,9 @@ func TestTxEncode_GRPCGateway(t *testing.T) {
}
func TestTxDecode_GRPC(t *testing.T) {
sut.ResetChain(t)
systest.Sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)
@@ -734,17 +734,17 @@ func TestTxDecode_GRPC(t *testing.T) {
// add new key
receiverAddr := cli.AddKey("account1")
sut.StartChain(t)
systest.Sut.StartChain(t)
qc := tx.NewServiceClient(sut.RPCClient(t))
qc := tx.NewServiceClient(systest.Sut.RPCClient(t))
// create unsign tx
bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), fmt.Sprintf("--chain-id=%s", sut.chainID), "--fees=10stake", "--sign-mode=direct", "--generate-only"}
bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--chain-id=" + cli.ChainID(), "--fees=10stake", "--sign-mode=direct", "--generate-only"}
res := cli.RunCommandWithArgs(bankSendCmdArgs...)
txFile := StoreTempFile(t, []byte(res))
txFile := systest.StoreTempFile(t, []byte(res))
res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", valAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet/node0/simd")
signedTxFile := StoreTempFile(t, []byte(res))
res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), "--from="+valAddr, "--chain-id="+cli.ChainID(), "--keyring-backend=test", "--home="+systest.Sut.NodeDir(0))
signedTxFile := systest.StoreTempFile(t, []byte(res))
res = cli.RunCommandWithArgs("tx", "encode", signedTxFile.Name())
txBz, err := base64.StdEncoding.DecodeString(res)
@@ -779,9 +779,9 @@ func TestTxDecode_GRPC(t *testing.T) {
}
func TestTxDecode_GRPCGateway(t *testing.T) {
sut.ResetChain(t)
systest.Sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)
@@ -789,17 +789,17 @@ func TestTxDecode_GRPCGateway(t *testing.T) {
// add new key
receiverAddr := cli.AddKey("account1")
sut.StartChain(t)
systest.Sut.StartChain(t)
basrUrl := sut.APIAddress()
basrUrl := systest.Sut.APIAddress()
// create unsign tx
bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), fmt.Sprintf("--chain-id=%s", sut.chainID), "--fees=10stake", "--sign-mode=direct", "--generate-only"}
bankSendCmdArgs := []string{"tx", "bank", "send", valAddr, receiverAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--chain-id=" + cli.ChainID(), "--fees=10stake", "--sign-mode=direct", "--generate-only"}
res := cli.RunCommandWithArgs(bankSendCmdArgs...)
txFile := StoreTempFile(t, []byte(res))
txFile := systest.StoreTempFile(t, []byte(res))
res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", valAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet/node0/simd")
signedTxFile := StoreTempFile(t, []byte(res))
res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), "--from="+valAddr, "--chain-id="+cli.ChainID(), "--keyring-backend=test", "--home="+systest.Sut.NodeDir(0))
signedTxFile := systest.StoreTempFile(t, []byte(res))
res = cli.RunCommandWithArgs("tx", "encode", signedTxFile.Name())
txBz, err := base64.StdEncoding.DecodeString(res)
@@ -835,15 +835,15 @@ func TestTxDecode_GRPCGateway(t *testing.T) {
}
func TestTxEncodeAmino_GRPC(t *testing.T) {
sut.ResetChain(t)
sut.StartChain(t)
systest.Sut.ResetChain(t)
systest.Sut.StartChain(t)
legacyAmino := codec.NewLegacyAmino()
std.RegisterLegacyAminoCodec(legacyAmino)
legacytx.RegisterLegacyAminoCodec(legacyAmino)
legacy.RegisterAminoMsg(legacyAmino, &banktypes.MsgSend{}, "cosmos-sdk/MsgSend")
qc := tx.NewServiceClient(sut.RPCClient(t))
qc := tx.NewServiceClient(systest.Sut.RPCClient(t))
txJSONBytes, stdTx := readTestAminoTxJSON(t, legacyAmino)
testCases := []struct {
@@ -879,15 +879,15 @@ func TestTxEncodeAmino_GRPC(t *testing.T) {
}
func TestTxEncodeAmino_GRPCGateway(t *testing.T) {
sut.ResetChain(t)
sut.StartChain(t)
systest.Sut.ResetChain(t)
systest.Sut.StartChain(t)
legacyAmino := codec.NewLegacyAmino()
std.RegisterLegacyAminoCodec(legacyAmino)
legacytx.RegisterLegacyAminoCodec(legacyAmino)
legacy.RegisterAminoMsg(legacyAmino, &banktypes.MsgSend{}, "cosmos-sdk/MsgSend")
baseUrl := sut.APIAddress()
baseUrl := systest.Sut.APIAddress()
txJSONBytes, stdTx := readTestAminoTxJSON(t, legacyAmino)
testCases := []struct {
@@ -925,15 +925,15 @@ func TestTxEncodeAmino_GRPCGateway(t *testing.T) {
}
func TestTxDecodeAmino_GRPC(t *testing.T) {
sut.ResetChain(t)
sut.StartChain(t)
systest.Sut.ResetChain(t)
systest.Sut.StartChain(t)
legacyAmino := codec.NewLegacyAmino()
std.RegisterLegacyAminoCodec(legacyAmino)
legacytx.RegisterLegacyAminoCodec(legacyAmino)
legacy.RegisterAminoMsg(legacyAmino, &banktypes.MsgSend{}, "cosmos-sdk/MsgSend")
qc := tx.NewServiceClient(sut.RPCClient(t))
qc := tx.NewServiceClient(systest.Sut.RPCClient(t))
encodedTx, stdTx := readTestAminoTxBinary(t, legacyAmino)
invalidTxBytes := append(encodedTx, byte(0o00))
@@ -971,15 +971,15 @@ func TestTxDecodeAmino_GRPC(t *testing.T) {
}
func TestTxDecodeAmino_GRPCGateway(t *testing.T) {
sut.ResetChain(t)
sut.StartChain(t)
systest.Sut.ResetChain(t)
systest.Sut.StartChain(t)
legacyAmino := codec.NewLegacyAmino()
std.RegisterLegacyAminoCodec(legacyAmino)
legacytx.RegisterLegacyAminoCodec(legacyAmino)
legacy.RegisterAminoMsg(legacyAmino, &banktypes.MsgSend{}, "cosmos-sdk/MsgSend")
baseUrl := sut.APIAddress()
baseUrl := systest.Sut.APIAddress()
encodedTx, stdTx := readTestAminoTxBinary(t, legacyAmino)
invalidTxBytes := append(encodedTx, byte(0o00))
@@ -1021,9 +1021,9 @@ func TestTxDecodeAmino_GRPCGateway(t *testing.T) {
func TestSimMultiSigTx(t *testing.T) {
t.Skip() // waiting for @hieuvubk fix
sut.ResetChain(t)
systest.Sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator address
valAddr := cli.GetKeyAddr("node0")
require.NotEmpty(t, valAddr)
@@ -1032,7 +1032,7 @@ func TestSimMultiSigTx(t *testing.T) {
_ = cli.AddKey("account1")
_ = cli.AddKey("account2")
sut.StartChain(t)
systest.Sut.StartChain(t)
multiSigName := "multisig"
cli.RunCommandWithArgs("keys", "add", multiSigName, "--multisig=account1,account2", "--multisig-threshold=2", "--keyring-backend=test", "--home=./testnet")
@@ -1042,7 +1042,7 @@ func TestSimMultiSigTx(t *testing.T) {
rsp := cli.Run("tx", "bank", "send", valAddr, multiSigAddr, fmt.Sprintf("%d%s", transferAmount, denom), "--fees=1stake")
txResult, found := cli.AwaitTxCommitted(rsp)
require.True(t, found)
RequireTxSuccess(t, txResult)
systest.RequireTxSuccess(t, txResult)
multiSigBalance := cli.QueryBalance(multiSigAddr, denom)
require.Equal(t, multiSigBalance, transferAmount)
@@ -1050,20 +1050,20 @@ func TestSimMultiSigTx(t *testing.T) {
// Send from multisig to validator
// create unsign tx
var newTransferAmount int64 = 100
bankSendCmdArgs := []string{"tx", "bank", "send", multiSigAddr, valAddr, fmt.Sprintf("%d%s", newTransferAmount, denom), fmt.Sprintf("--chain-id=%s", sut.chainID), "--fees=10stake", "--sign-mode=direct", "--generate-only"}
bankSendCmdArgs := []string{"tx", "bank", "send", multiSigAddr, valAddr, fmt.Sprintf("%d%s", newTransferAmount, denom), "--chain-id=" + cli.ChainID(), "--fees=10stake", "--sign-mode=direct", "--generate-only"}
res := cli.RunCommandWithArgs(bankSendCmdArgs...)
txFile := StoreTempFile(t, []byte(res))
txFile := systest.StoreTempFile(t, []byte(res))
res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", "account1"), fmt.Sprintf("--multisig=%s", multiSigAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet")
account1Signed := StoreTempFile(t, []byte(res))
res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", "account2"), fmt.Sprintf("--multisig=%s", multiSigAddr), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet")
account2Signed := StoreTempFile(t, []byte(res))
res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", "account1"), fmt.Sprintf("--multisig=%s", multiSigAddr), "--chain-id="+cli.ChainID(), "--keyring-backend=test", "--home=./testnet")
account1Signed := systest.StoreTempFile(t, []byte(res))
res = cli.RunCommandWithArgs("tx", "sign", txFile.Name(), fmt.Sprintf("--from=%s", "account2"), fmt.Sprintf("--multisig=%s", multiSigAddr), "--chain-id="+cli.ChainID(), "--keyring-backend=test", "--home=./testnet")
account2Signed := systest.StoreTempFile(t, []byte(res))
res = cli.RunCommandWithArgs("tx", "multisign-batch", txFile.Name(), multiSigName, account1Signed.Name(), account2Signed.Name(), fmt.Sprintf("--chain-id=%s", sut.chainID), "--keyring-backend=test", "--home=./testnet")
txSignedFile := StoreTempFile(t, []byte(res))
res = cli.RunCommandWithArgs("tx", "multisign-batch", txFile.Name(), multiSigName, account1Signed.Name(), account2Signed.Name(), "--chain-id="+cli.ChainID(), "--keyring-backend=test", "--home=./testnet")
txSignedFile := systest.StoreTempFile(t, []byte(res))
res = cli.Run("tx", "broadcast", txSignedFile.Name())
RequireTxSuccess(t, res)
systest.RequireTxSuccess(t, res)
multiSigBalance = cli.QueryBalance(multiSigAddr, denom)
require.Equal(t, multiSigBalance, transferAmount-newTransferAmount-10)
+13 -9
View File
@@ -9,31 +9,35 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
systest "cosmossdk.io/systemtests"
)
func TestUnorderedTXDuplicate(t *testing.T) {
t.Skip("The unordered tx handling is not wired in v2")
if systest.IsV2() {
t.Skip("The unordered tx handling is not wired in v2")
return
}
// scenario: test unordered tx duplicate
// given a running chain with a tx in the unordered tx pool
// when a new tx with the same hash is broadcasted
// then the new tx should be rejected
sut.ResetChain(t)
cli := NewCLIWrapper(t, sut, verbose)
systest.Sut.ResetChain(t)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// add genesis account with some tokens
account1Addr := cli.AddKey("account1")
account2Addr := cli.AddKey("account2")
sut.ModifyGenesisCLI(t,
systest.Sut.ModifyGenesisCLI(t,
[]string{"genesis", "add-genesis-account", account1Addr, "10000000stake"},
)
sut.StartChain(t)
systest.Sut.StartChain(t)
timeoutTimestamp := time.Now().Add(time.Minute)
// send tokens
rsp1 := cli.Run("tx", "bank", "send", account1Addr, account2Addr, "5000stake", "--from="+account1Addr, "--fees=1stake", fmt.Sprintf("--timeout-timestamp=%v", timeoutTimestamp.Unix()), "--unordered", "--sequence=1", "--note=1")
RequireTxSuccess(t, rsp1)
systest.RequireTxSuccess(t, rsp1)
assertDuplicateErr := func(xt assert.TestingT, gotErr error, gotOutputs ...interface{}) bool {
require.Len(t, gotOutputs, 1)
@@ -41,9 +45,9 @@ func TestUnorderedTXDuplicate(t *testing.T) {
return false // always abort
}
rsp2 := cli.WithRunErrorMatcher(assertDuplicateErr).Run("tx", "bank", "send", account1Addr, account2Addr, "5000stake", "--from="+account1Addr, "--fees=1stake", fmt.Sprintf("--timeout-timestamp=%v", timeoutTimestamp.Unix()), "--unordered", "--sequence=1")
RequireTxFailure(t, rsp2)
systest.RequireTxFailure(t, rsp2)
require.Eventually(t, func() bool {
return cli.QueryBalance(account2Addr, "stake") == 5000
}, time.Minute, time.Microsecond*500, "TX was not executed before timeout")
}, 10*systest.Sut.BlockTime(), 200*time.Millisecond, "TX was not executed before timeout")
}
+30 -28
View File
@@ -12,6 +12,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/tidwall/gjson"
systest "cosmossdk.io/systemtests"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/address"
)
@@ -24,26 +26,26 @@ func TestChainUpgrade(t *testing.T) {
// start a legacy chain with some state
// when a chain upgrade proposal is executed
// then the chain upgrades successfully
sut.StopChain()
systest.Sut.StopChain()
legacyBinary := FetchExecutable(t, "v0.52")
t.Logf("+++ legacy binary: %s\n", legacyBinary)
currentBranchBinary := sut.execBinary
currentInitializer := sut.testnetInitializer
sut.SetExecBinary(legacyBinary)
sut.SetTestnetInitializer(InitializerWithBinary(legacyBinary, sut))
sut.SetupChain()
currentBranchBinary := systest.Sut.ExecBinary()
currentInitializer := systest.Sut.TestnetInitializer()
systest.Sut.SetExecBinary(legacyBinary)
systest.Sut.SetTestnetInitializer(systest.InitializerWithBinary(legacyBinary, systest.Sut))
systest.Sut.SetupChain()
votingPeriod := 5 * time.Second // enough time to vote
sut.ModifyGenesisJSON(t, SetGovVotingPeriod(t, votingPeriod))
systest.Sut.ModifyGenesisJSON(t, systest.SetGovVotingPeriod(t, votingPeriod))
const (
upgradeHeight int64 = 22
upgradeName = "v052-to-v054" // must match UpgradeName in simapp/upgrades.go
)
sut.StartChain(t, fmt.Sprintf("--halt-height=%d", upgradeHeight+1))
systest.Sut.StartChain(t, fmt.Sprintf("--halt-height=%d", upgradeHeight+1))
cli := NewCLIWrapper(t, sut, verbose)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
govAddr := sdk.AccAddress(address.Module("gov")).String()
// submit upgrade proposal
proposal := fmt.Sprintf(`
@@ -64,32 +66,32 @@ func TestChainUpgrade(t *testing.T) {
"summary": "testing"
}`, govAddr, upgradeName, upgradeHeight)
proposalID := cli.SubmitAndVoteGovProposal(proposal)
t.Logf("current_height: %d\n", sut.currentHeight)
t.Logf("current_height: %d\n", systest.Sut.CurrentHeight())
raw := cli.CustomQuery("q", "gov", "proposal", proposalID)
t.Log(raw)
sut.AwaitBlockHeight(t, upgradeHeight-1, 60*time.Second)
t.Logf("current_height: %d\n", sut.currentHeight)
systest.Sut.AwaitBlockHeight(t, upgradeHeight-1, 60*time.Second)
t.Logf("current_height: %d\n", systest.Sut.CurrentHeight())
raw = cli.CustomQuery("q", "gov", "proposal", proposalID)
proposalStatus := gjson.Get(raw, "proposal.status").String()
require.Equal(t, "PROPOSAL_STATUS_PASSED", proposalStatus, raw) // PROPOSAL_STATUS_PASSED
t.Log("waiting for upgrade info")
sut.AwaitUpgradeInfo(t)
sut.StopChain()
systest.Sut.AwaitUpgradeInfo(t)
systest.Sut.StopChain()
t.Log("Upgrade height was reached. Upgrading chain")
sut.SetExecBinary(currentBranchBinary)
sut.SetTestnetInitializer(currentInitializer)
sut.StartChain(t)
cli = NewCLIWrapper(t, sut, verbose)
systest.Sut.SetExecBinary(currentBranchBinary)
systest.Sut.SetTestnetInitializer(currentInitializer)
systest.Sut.StartChain(t)
cli = systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// smoke test that new version runs
ownerAddr := cli.GetKeyAddr(defaultSrcAddr)
got := cli.Run("tx", "accounts", "init", "continuous-locking-account", `{"end_time":"2034-01-22T11:38:15.116127Z", "owner":"`+ownerAddr+`"}`, "--from="+defaultSrcAddr)
RequireTxSuccess(t, got)
got = cli.Run("tx", "protocolpool", "fund-community-pool", "100stake", "--from="+defaultSrcAddr)
RequireTxSuccess(t, got)
ownerAddr := cli.GetKeyAddr("node0")
got := cli.Run("tx", "accounts", "init", "continuous-locking-account", `{"end_time":"2034-01-22T11:38:15.116127Z", "owner":"`+ownerAddr+`"}`, "--from=node0")
systest.RequireTxSuccess(t, got)
got = cli.Run("tx", "protocolpool", "fund-community-pool", "100stake", "--from=node0")
systest.RequireTxSuccess(t, got)
}
const cacheDir = "binaries"
@@ -97,20 +99,20 @@ const cacheDir = "binaries"
// FetchExecutable to download and extract tar.gz for linux
func FetchExecutable(t *testing.T, version string) string {
// use local cache
cacheFolder := filepath.Join(WorkDir, cacheDir)
cacheFolder := filepath.Join(systest.WorkDir, cacheDir)
err := os.MkdirAll(cacheFolder, 0o777)
if err != nil && !os.IsExist(err) {
panic(err)
}
cacheFile := filepath.Join(cacheFolder, fmt.Sprintf("%s_%s", execBinaryName, version))
cacheFile := filepath.Join(cacheFolder, fmt.Sprintf("%s_%s", systest.GetExecutableName(), version))
if _, err := os.Stat(cacheFile); err == nil {
return cacheFile
}
destFile := cacheFile
t.Log("+++ version not in cache, downloading from docker image")
MustRunShellCmd(t, "docker", "pull", "ghcr.io/cosmos/simapp:"+version)
MustRunShellCmd(t, "docker", "create", "--name=ci_temp", "ghcr.io/cosmos/simapp:"+version)
MustRunShellCmd(t, "docker", "cp", "ci_temp:/usr/bin/simd", destFile)
systest.MustRunShellCmd(t, "docker", "pull", "ghcr.io/cosmos/simapp:"+version)
systest.MustRunShellCmd(t, "docker", "create", "--name=ci_temp", "ghcr.io/cosmos/simapp:"+version)
systest.MustRunShellCmd(t, "docker", "cp", "ci_temp:/usr/bin/simd", destFile)
return destFile
}