Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: add system-tests #189

Merged
merged 18 commits into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/rosetta-cli-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ jobs:
go-version: '^1.23.4'
- name: Run make test-rosetta-ci
run:
COSMOS_SDK_VERSION=v0.50.3
COSMOS_SDK_VERSION=v0.52.0-rc.1
make test-rosetta-ci
shell: bash
29 changes: 28 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,31 @@ jobs:
- name: tests
if: env.GIT_DIFF
run: |
make plugin && make test
make plugin && make test

test-system:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: "1.23"
check-latest: true
cache: true
cache-dependency-path: tests/systemtests/go.sum
- uses: technote-space/[email protected]
id: git_diff
with:
PATTERNS: |
**/*.go
go.mod
go.sum
**/go.mod
**/go.sum
**/Makefile
Makefile
- name: system tests
if: env.GIT_DIFF
run: |
make test-system
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ sim_log_file
x/genutil/config
x/genutil/data
*.fail
tests/systemtests/binaries
tests/systemtests/testnet

# Vagrant
.vagrant/
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ Ref: https://keepachangelog.com/en/1.0.0/

## [Unreleased]

### Features

* [#189](https://github.com/cosmos/rosetta/pull/189) Add system tests.

### Improvements

* [180](https://github.com/cosmos/rosetta/pull/180) Update to cosmos-sdk v0.52.0-rc.1.
Expand Down
18 changes: 16 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
all: build plugin

build:
go build -mod=readonly ./cmd/rosetta
mkdir -p ./build
go build -mod=readonly -o ./build/rosetta ./cmd/rosetta

plugin:
cd plugins/cosmos-hub && make plugin
Expand All @@ -17,10 +18,23 @@ docker:
test:
go test -mod=readonly -timeout 30m -coverprofile=coverage.out -covermode=atomic ./...

.PHONY: test-system
test-system: build
mkdir -p ./tests/systemtests/binaries/
git clone https://github.com/cosmos/cosmos-sdk.git ./build/tmp/cosmos-sdk
$(eval SDK_VERSION := $(shell grep -m 2 'github.com/cosmos/cosmos-sdk' go.mod | awk 'NR==2 {print $$4; exit} END{if(NR==1) print $$2}'))
@echo "Checking out cosmos-sdk version: $(SDK_VERSION)"
cd ./build/tmp/cosmos-sdk && git checkout $(SDK_VERSION)
$(MAKE) -C ./build/tmp/cosmos-sdk build
cp ./build/tmp/cosmos-sdk/build/simd$(if $(findstring v2,$(COSMOS_BUILD_OPTIONS)),v2) ./tests/systemtests/binaries/
cp ./build/rosetta ./tests/systemtests/binaries/
$(MAKE) -C tests/systemtests test
rm -rf ./build/tmp

test-rosetta-ci:
sh ./scripts/simapp-start-node.sh
make build && make plugin
./rosetta --blockchain "cosmos" --network "cosmos" --tendermint "tcp://localhost:26657" --addr "localhost:8080" --grpc "localhost:9090" &
./build/rosetta --blockchain "cosmos" --network "cosmos" --tendermint "tcp://localhost:26657" --addr "localhost:8080" --grpc "localhost:9090" &
sleep 30
export SIMD_BIN=./cosmos-sdk/build/simd && sh ./tests/rosetta-cli/rosetta-cli-test.sh

Expand Down
1 change: 1 addition & 0 deletions codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func MakeCodec() (*codec.ProtoCodec, codectypes.InterfaceRegistry) {
})
cdc := codec.NewProtoCodec(ir)

sdk.RegisterInterfaces(ir)
authcodec.RegisterInterfaces(ir)
bankcodec.RegisterInterfaces(ir)
cryptocodec.RegisterInterfaces(ir)
Expand Down
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -169,5 +169,4 @@ require (

replace (
github.com/cosmos/cosmos-sdk => github.com/cosmos/cosmos-sdk v0.52.0-rc.1
// Ensure we're using compatible versions
)
44 changes: 38 additions & 6 deletions scripts/go-lint-all.bash
Original file line number Diff line number Diff line change
@@ -1,18 +1,50 @@
#!/usr/bin/env bash

set -eu -o pipefail
set -e
JulianToledano marked this conversation as resolved.
Show resolved Hide resolved

REPO_ROOT="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )/.." &> /dev/null && pwd )"
export REPO_ROOT

LINT_TAGS="system_test"
lint_module() {
local root="$1"
shift
cd "$(dirname "$root")" &&
echo "linting $(grep "^module" go.mod) [$(date -Iseconds -u)]" &&
golangci-lint run ./... -c "${REPO_ROOT}/.golangci.yml" "$@"
if [ -f $root ]; then
cd "$(dirname "$root")"
else
cd "$REPO_ROOT/$root"
fi
JulianToledano marked this conversation as resolved.
Show resolved Hide resolved
echo "linting $(grep "^module" go.mod) [$(date -Iseconds -u)]"
golangci-lint run ./... -c "${REPO_ROOT}/.golangci.yml" "$@" --build-tags=${LINT_TAGS}
}
export -f lint_module

find "${REPO_ROOT}" -type f -name go.mod -print0 |
xargs -0 -I{} bash -c 'lint_module "$@"' _ {} "$@" # Prepend go.mod file before command-line args.
if [[ -z "${LINT_DIFF:-}" ]]; then
find "${REPO_ROOT}" -type f -name go.mod -print0 | xargs -0 -I{} bash -c 'lint_module "$@"' _ {} "$@" --build-tags=${LINT_TAGS}
else
if [[ -z $GIT_DIFF ]]; then
GIT_DIFF=$(git diff --name-only) || true
fi

if [[ -z "$GIT_DIFF" ]]; then
echo "no files to lint"
exit 0
fi

GIT_DIFF=$(echo $GIT_DIFF | tr -d "'" | tr ' ' '\n' | grep '\.go$' | grep -v '\.pb\.go$' | grep -Eo '^[^/]+\/[^/]+' | uniq)
JulianToledano marked this conversation as resolved.
Show resolved Hide resolved

lint_sdk=false
for dir in ${GIT_DIFF[@]}; do
if [[ ! -f "$REPO_ROOT/$dir/go.mod" ]]; then
lint_sdk=true
else
lint_module $dir "$@"
fi
done

if [[ $lint_sdk ]]; then
cd "$REPO_ROOT"
echo "linting github.com/cosmos/rosetta [$(date -Iseconds -u)]"
golangci-lint run ./... -c "${REPO_ROOT}/.golangci.yml" "$@" --build-tags=${LINT_TAGS}
fi
fi
6 changes: 6 additions & 0 deletions tests/systemtests/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/make -f

WAIT_TIME ?= 45s

test:
go test -mod=readonly -failfast -timeout=15m -tags='system_test' ./... --wait-time=$(WAIT_TIME) --verbose
45 changes: 45 additions & 0 deletions tests/systemtests/accounts_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//go:build system_test

package systemtests

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/tidwall/gjson"

"cosmossdk.io/systemtests"
)

func TestAccounts(t *testing.T) {
sut.ResetChain(t)
cli := systemtests.NewCLIWrapper(t, sut, verbose)
// add genesis account with some tokens
fromAddr := cli.AddKey("account1")
sut.ModifyGenesisCLI(t,
[]string{"genesis", "add-genesis-account", fromAddr, "10000000stake"},
)
toAddr := cli.AddKey("account2")
sut.StartChain(t)

rsp := cli.RunAndWait("tx", "bank", "send", fromAddr, toAddr, "1000000stake")
systemtests.RequireTxSuccess(t, rsp)

rosetta.restart(t)
rosettaRest := newRestClient(rosetta)

// check balance after spent
res, err := rosettaRest.accountBalance(fromAddr)
assert.NoError(t, err)
assert.Equal(t, int64(8999999), gjson.GetBytes(res, "balances.0.value").Int())

// check recipient's balance after receiving tokens
res, err = rosettaRest.accountBalance(toAddr)
assert.NoError(t, err)
assert.Equal(t, int64(1000000), gjson.GetBytes(res, "balances.0.value").Int())

// check balance at genesis, before spent
res, err = rosettaRest.accountBalance(fromAddr, withBlockIdentifier("1"))
assert.NoError(t, err)
assert.Equal(t, int64(10000000), gjson.GetBytes(res, "balances.0.value").Int())
}
45 changes: 45 additions & 0 deletions tests/systemtests/block_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//go:build system_test

package systemtests

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/tidwall/gjson"

"cosmossdk.io/systemtests"
)

func TestBlockAndBlockTransaction(t *testing.T) {
sut.ResetChain(t)
cli := systemtests.NewCLIWrapper(t, sut, verbose)
// add genesis account with some tokens
fromAddr := cli.AddKey("account1")
sut.ModifyGenesisCLI(t,
[]string{"genesis", "add-genesis-account", fromAddr, "10000000stake"},
)
toAddr := cli.AddKey("account2")
sut.StartChain(t)

rosetta.restart(t)

// stake tokens
rsp := cli.RunAndWait("tx", "bank", "send", fromAddr, toAddr, "10stake")
systemtests.RequireTxSuccess(t, rsp)

rosettaRest := newRestClient(rosetta)

// test /block endpoint
height := gjson.Get(rsp, "height").String()
res, err := rosettaRest.block(height)
assert.NoError(t, err)
assert.Equal(t, gjson.GetBytes(res, "block.block_identifier.index").String(), height)

// test block/transaction endpoint
blockHash := gjson.GetBytes(res, "block.block_identifier.hash").String()
hash := gjson.GetBytes(res, "block.transactions.0.transaction_identifier.hash").String()
res, err = rosettaRest.blockTransaction(height, blockHash, hash)
assert.NoError(t, err)
assert.Equal(t, gjson.GetBytes(res, "transaction.operations.0.metadata.from_address").String(), fromAddr)
}
JulianToledano marked this conversation as resolved.
Show resolved Hide resolved
84 changes: 84 additions & 0 deletions tests/systemtests/construction_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
//go:build system_test

package systemtests

import (
"encoding/base64"
"encoding/hex"
"strings"
"testing"

"github.com/stretchr/testify/assert"
"github.com/tidwall/gjson"

"cosmossdk.io/systemtests"

"github.com/cosmos/cosmos-sdk/codec/address"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
)

func TestDerive(t *testing.T) {
sut.ResetChain(t)
sut.StartChain(t)

rosetta.restart(t)
rosettaRest := newRestClient(rosetta)

pubKey := secp256k1.GenPrivKey().PubKey()
addr, err := address.NewBech32Codec("cosmos").BytesToString(pubKey.Address().Bytes())
assert.NoError(t, err)

hexPk := strings.Split(pubKey.String(), "{")[1]
res, err := rosettaRest.constructionDerive(hexPk[:len(hexPk)-1])
JulianToledano marked this conversation as resolved.
Show resolved Hide resolved
assert.NoError(t, err)
assert.Equal(t, addr, gjson.GetBytes(res, "address").String())
}

func TestHash(t *testing.T) {
sut.ResetChain(t)
sut.StartChain(t)

cli := systemtests.NewCLIWrapper(t, sut, verbose)
fromAddr := cli.AddKey("account1")
sut.ModifyGenesisCLI(t,
[]string{"genesis", "add-genesis-account", fromAddr, "10000000stake"},
)
toAddr := cli.AddKey("account2")

rosetta.restart(t)
rosettaRest := newRestClient(rosetta)

rsp := cli.RunCommandWithArgs(cli.WithTXFlags("tx", "bank", "send", fromAddr, toAddr, "10stake", "--generate-only")...)
tempFile := systemtests.StoreTempFile(t, []byte(rsp))
rsp = cli.RunCommandWithArgs(cli.WithTXFlags("tx", "sign", tempFile.Name(), "--from", fromAddr)...)
tempFile = systemtests.StoreTempFile(t, []byte(rsp))
rsp = cli.RunCommandWithArgs("tx", "encode", tempFile.Name())
JulianToledano marked this conversation as resolved.
Show resolved Hide resolved

txBytes, err := base64.StdEncoding.DecodeString(rsp)
assert.NoError(t, err)
hexTx := hex.EncodeToString(txBytes)

res, err := rosettaRest.constructionHash(hexTx)
assert.NoError(t, err)
assert.NotEmpty(t, gjson.GetBytes(res, "transaction_identifier.hash"))
}

func TestMetadata(t *testing.T) {
sut.ResetChain(t)
sut.StartChain(t)

rosetta.restart(t)
rosettaRest := newRestClient(rosetta)

pubKey := secp256k1.GenPrivKey().PubKey()
hexPk := strings.Split(pubKey.String(), "{")[1]

metadata := make(map[string]interface{})
metadata["gas_price"] = `"123uatom"`
metadata["gas_limit"] = 423

res, err := rosettaRest.constructionMetadata(hexPk, metadata)
assert.NoError(t, err)
assert.Equal(t, gjson.GetBytes(res, "metadata.gas_price").String(), "123uatom")
assert.Greater(t, gjson.GetBytes(res, "suggested_fee.0.value").Int(), int64(0))
}
Loading
Loading