Giter VIP home page Giter VIP logo

test-tube's Introduction

test-tube

test

test-tube is a generic library for building testing environments for CosmWasm smart contracts. It allows you to test your smart contract logic against the actual Cosmos SDK chain's logic, which is written in Go, using Rust. This eliminates the need to write Go code or learn Go in order to test your smart contracts against the Cosmos SDK.

test-tube is currently used to build osmosis-test-tube, but it can be used to build testing environments for any Cosmos SDK-based chain. To do this, you will need to build a shared library that exports the functions described here. You can use the Go code and build script from osmosis-test-tube as a reference.

Features

  • Test your CosmWasm smart contracts using Rust without the need to write Go code or learn Go
  • Test against the actual Cosmos SDK chain's logic
  • Build testing environments for any Cosmos SDK-based chain

Why don't just use cw-multi-test?

You might want to just use cw-multi-test if your contract does not interact with chain's custom module. cw-multi-test is faster since it does not need to run the chain code or build and upload .wasm file, but it does not test your contract against the actual chain's logic and rely on simulation which only some basic modules are implemented.

So if your contract just interact with common modules like Bank, Staking, and Distribution, cw-multi-test is enough. But if it's interacting with custom modules, you should use test-tube.

Known Issues

linking with cc failed on Mac M1/M2 (arm64) #28

Check your go version if it's darwin/arm64, it might be darwin/amd64 and your local build has been working but it confuses the linker.

If you don't want to reinstall, go you opt for cross-compile.

cargo clean
export GOOS="darwin"
export GOARCH="arm64"
export CGO_ENABLED=1

But we would installing go version that match your architecture makes more sense.

Contributing

We welcome contributions to test-tube! If you find a bug or have an idea for a new feature, please open an issue or submit a pull request.

License

The crates in this repository are licensed under either of the following licenses, at your discretion.

Apache License Version 2.0 (LICENSE-APACHE or apache.org license link)
MIT license (LICENSE-MIT or opensource.org license link)

Unless you explicitly state otherwise, any contribution submitted for inclusion in this library by you shall be dual licensed as above (as defined in the Apache v2 License), without any additional terms or conditions.

test-tube's People

Contributors

apollo-sturdy avatar github-actions[bot] avatar grod220 avatar iboss-ptk avatar magiodev avatar maxrobot avatar omahs avatar pacmanifold avatar whalelephant avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

test-tube's Issues

Basic Documentation

  • review usage for osmosis-test-tube
  • high level description of test-tube and what it aims to be
  • how to use test-tube to create your own chain's test-tube

Error: Debug Messages are Printed Twice

Description: when trying to debug my contracts I noticed that some debug messages would be printed twice.

I have even created an integration test here

Which simply instantiates a contract with a debug message:

#[cfg(not(tarpaulin_include))]
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn instantiate(
    deps: DepsMut,
    _env: Env,
    _info: MessageInfo,
    _msg: InstantiateMsg,
) -> StdResult<Response> {
    deps.api.debug(&format!("\nInstantiate Mock Query"));
    Ok(Response::default())
}

When I execute the linked test in the test-tube repo as follows:

user@machine:test-tube$ cargo test wasm_integration
    Finished test [unoptimized + debuginfo] target(s) in 0.12s
     Running unittests src/lib.rs (target/debug/deps/osmosis_test_tube-cb3dd881bea82e8e)

running 1 test

Instantiate Mock Query

Instantiate Mock Query
test module::wasm::tests::wasm_integration ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 17 filtered out; finished in 0.12s

     Running unittests src/lib.rs (target/debug/deps/test_tube-4170a80f535dabc4)

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 3 filtered out; finished in 0.00s

As shown above Instantiate Mock Query is printed twice, further investigation printing the block info shows also that these transaction are executed at different block heights.

I am very confused why this would be happening and would be grateful for any pointers how to stop/solve this from happening.

Non UTF-8 Go code

I just got this panic:

thread 'deposit_lands' panicked at .../.cargo/registry/src/index.crates.io-6f17d22bba15001f/test-tube-0.3.0/src/runner/result.rs:222:18:
Go code must encode valid UTF-8 string: Utf8Error { valid_up_to: 127, error_len: Some(1)

You can see it here:

let content_string = CString::new(content)
.unwrap()
.to_str()
.expect("Go code must encode valid UTF-8 string")
.to_string();

Converting error to the lossy string helped me figure out the issue:

[.../.cargo/registry/src/index.crates.io-6f17d22bba15001f/test-tube-0.3.0/src/runner/result.rs:221] lossy = "failed to execute message; message index: 0: dispatch: submessages: dispatch: submessages: failed to update grant with key \u{1}\u{14}\u{f6ec} ��Gl�O�=\u{1e}�\u{18}N�L�* �=\u{10}�\u{11}�V\t�\u{10}\u{1b}��mr>����G��tn�R\u{b}j��W/osmosis.concentratedliquidity.v1beta1.MsgCreatePosition: authorization not found"

I would like to at least get the lossy error in case of the Non UTF-8 strings

Feature: Add pool incentivisation setup functionallity

As pools and their incentives are core part of the Dex, it would be a valuable addition to the testsuite to provide a convenience method for setting up pool incentives. Ideally, this would provide the complete logic for both setting up the gauges, the incentive params for that gauge and the token distribution setup.

Conflicting `osmosis-std` versions causing build failure.

The current version of test-tube and osmosis-test-tube have conflicting versions for osmosis-std, causing our builds to fail as shown here.

This problem is persistent for most versions we tried.

Can osmosis-std be omitted from test-tube itself?

> cargo tree -i [email protected]
osmosis-std v0.16.2
└── osmosis-test-tube v16.1.2
    └── cw-orch v0.13.3 (/Users/robin/Programming/Abstract/cw-orch/cw-orch)
        
> cargo tree -i [email protected]
osmosis-std v0.17.0-rc0
└── test-tube v0.1.6
    └── osmosis-test-tube v16.1.2
        └── cw-orch v0.13.3 (/Users/robin/Programming/Abstract/cw-orch/cw-orch)

Remove cosmrs from osmosis-test-tube and only relying osmosis-std types

Reason being, cosmrs types don't derive serde and osmosis-std now have ability to generate types from cosmos module.

potential blocker: osmosis-labs/osmosis-rust#52

Problem

  • osmosis-std struct requires implementing Serialize & Deserialize but tendermint_proto's structs do not implement them, so whenever there is a struct that depends on tendermint_proto, it will cause compile errors
  • it maps tendermint related struct to tendermint_proto by this line
  • This hack is used to skip struct that depends on tendermint_proto to suppress compiles error.

So that maybe not all of them can be replaced at the moment, only case by case, unless the blocker is resolved.

ForceExecuteGovProposal

The idea here is to allow governance gated execution without voting in test.

Here is some implementation idea on go side:

// libosmosistesttube/main.go

//export ForceExecuteGovProposal
func ForceExecuteGovProposal(envId uint64, path, proposalTypeUrl, base64ProposalBytes string) *C.char {
	env := loadEnv(envId)

	// get router 
	govRouter := govkeeper.Keeper.Router(*env.App.GovKeeper)

	// unmarshal content from base64ProposalBytes and proposalTypeUrl
        // every proposal type implement `Content` interface
	// we might need to create a proposal type registry to fetch the correct type to unmarshal
	// but if you find a way to unmarshal without registry, that would be better
	content = ...
	err := govRouter.GetRoute(path)(env.Ctx, content)

	if err {
		return encodeErrToResultBytes(result.ExecuteError, err)
	}

	return encodeBytesResultBytes([]byte{})
}

Error on run custom build

Adding osmosis-test-tube = "16.1.2" to Cargo.toml involve into this error:

   Compiling osmosis-test-tube v16.1.2
error: failed to run custom build command for `osmosis-test-tube v16.1.2`

Caused by:
  process didn't exit successfully: `/root/simmetry/target/debug/build/osmosis-test-tube-42e715c7e7e407f6/build-script-build` (exit status: 101)
  --- stdout
  cargo:rerun-if-changed=./libosmosistesttube
  cargo:rustc-link-search=native=/root/simmetry/target/debug/build/osmosis-test-tube-e15027d09411ff04/out
  cargo:rustc-link-lib=dylib=osmosistesttube

  --- stderr
  thread 'main' panicked at 'Unable to find libclang: "couldn't find any valid shared libraries matching: ['libclang.so', 'libclang-*.so', 'libclang.so.*', 'libclang-*.so.*'], set the `LIBCLANG_PATH` environment variable to a path where one of these files can be found (invalid: [])"', /root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bindgen-0.60.1/src/lib.rs:2172:31
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Any workaround?

Run msgs in the same block

Why do we need this

Allowing test to be able to test scenario that requires multiple txs in the same block.

What should it look like

Implement Runner trait for Block which all it's functionality are scoped to specific block of a specific app.

pub struct Block(BaseApp);

impl<'a> Runner<'a> for Block { ... }

BaseApp should implement the following function.

pub fn run_block(impl Fn(Block));

Now that we can move BaseApp Runner logic to Block and new BaseApp implementation can call them through run_block.

Implement this function in OsmosisTestApp

poolmanager::EstimateSwapExactAmountOut failed with no `sender` field

I was using autobuild-15.0.0 to test an IBCX contract. but after bump to v15.1.0, this situation happened.

before bump

expected(raw)         : 7b22746f6b656e5f696e5f616d6f756e74223a2231303030303030227d
expected(hex_decoded) : {"token_in_amount":"1000000"}

actual(raw)           : 7b227374617267617465223a7b2270617468223a222f6f736d6f7369732e706f6f6c6d616e616765722e763162657461312e51756572792f457374696d617465537761704578616374416d6f756e744f7574222c2264617461223a22436763784d4441774d444177227d7d
actual(hex_decoded)   : {"stargate":{"path":"/osmosis.poolmanager.v1beta1.Query/EstimateSwapExactAmountOut","data":"CgcxMDAwMDAw"}}

There's also a bug that simulation result is returned as Request type - osmosis-labs/osmosis#5048 - so i solved with decoding both type of response EstimateSwapExactAmountOutRequest and EstimateSwapExactAmountOutResponse and cherrypick the successful one.

But after bump it returns without totally different format like this.

expected(raw)         : 7b22746f6b656e5f696e5f616d6f756e74223a2231303030303030227d
expected(hex_decoded) : {"token_in_amount":"1000000"}

actual(raw)           : 7b22706f6f6c5f6964223a2230222c22726f75746573223a5b5d2c22746f6b656e5f6f7574223a22227d
actual(hex_decoded)   : {"pool_id":"0","routes":[],"token_out":""}

It is confused to reflect the returned payload after bump - it does not stores the result of simulation... So it'll be great to know what is actually happened in the core side!

Error: linking with cc failed

When using test-tube as an execution environment I run into the following error:

error: linking with `cc` failed: exit status: 1
|
  = note: LC_ALL="C" PATH="/Users/robin/.rustup/toolchains/stable-aarch
  // a dump....
  ct/abstract/framework/target/debug/deps/authz-2cb5cbbc2d1e019a" "-Wl,-dead_strip" "-nodefaultlibs"
  = note: ld: warning: ignoring file /Users/robin/Programming/Abstract/abstract/framework/target/debug/deps/libosmosistesttube.dylib, building for macOS-arm64 but attempting to link with file built for macOS-x86_64
          Undefined symbols for architecture arm64:
            "_AccountNumber", referenced from:
                test_tube::runner::app::BaseApp::create_signed_tx::heeb23fb2f1dc67e9 in authz-2cb5cbbc2d1e019a.pofc1mhaai8ywix.rcgu.o
            "_AccountSequence", referenced from:
                test_tube::runner::app::BaseApp::create_signed_tx::heeb23fb2f1dc67e9 in authz-2cb5cbbc2d1e019a.pofc1mhaai8ywix.rcgu.o
            "_BeginBlock", referenced from:
                test_tube::runner::app::BaseApp::run_block::h35beeb6f6973b738 in authz-2cb5cbbc2d1e019a.pofc1mhaai8ywix.rcgu.o
                test_tube::runner::app::BaseApp::run_block::h4f5cf920549feaf9 in authz-2cb5cbbc2d1e019a.pofc1mhaai8ywix.rcgu.o
                test_tube::runner::app::BaseApp::run_block::h9d5e1886d063572f in authz-2cb5cbbc2d1e019a.pofc1mhaai8ywix.rcgu.o
                test_tube::runner::app::BaseApp::init_account::hb6c1758ff816e7c9 in libtest_tube-32dac9dd450a6ea7.rlib(test_tube-32dac9dd450a6ea7.test_tube.585259ba-cgu.7.rcgu.o)
            "_EndBlock", referenced from:
                test_tube::runner::app::BaseApp::run_block::h35beeb6f6973b738 in authz-2cb5cbbc2d1e019a.pofc1mhaai8ywix.rcgu.o
                test_tube::runner::app::BaseApp::run_block::h4f5cf920549feaf9 in authz-2cb5cbbc2d1e019a.pofc1mhaai8ywix.rcgu.o
                test_tube::runner::app::BaseApp::run_block::h9d5e1886d063572f in authz-2cb5cbbc2d1e019a.pofc1mhaai8ywix.rcgu.o
                test_tube::runner::app::BaseApp::init_account::hb6c1758ff816e7c9 in libtest_tube-32dac9dd450a6ea7.rlib(test_tube-32dac9dd450a6ea7.test_tube.585259ba-cgu.7.rcgu.o)
            "_Execute", referenced from:
                _$LT$test_tube..runner..app..BaseApp$u20$as$u20$test_tube..runner..Runner$GT$::execute_multiple_raw::_$u7b$$u7b$closure$u7d$$u7d$::h2352f24e142551de in authz-2cb5cbbc2d1e019a.pofc1mhaai8ywix.rcgu.o
                _$LT$test_tube..runner..app..BaseApp$u20$as$u20$test_tube..runner..Runner$GT$::execute_multiple_raw::_$u7b$$u7b$closure$u7d$$u7d$::h514c07ab6259dcc1 in authz-2cb5cbbc2d1e019a.pofc1mhaai8ywix.rcgu.o
                _$LT$test_tube..runner..app..BaseApp$u20$as$u20$test_tube..runner..Runner$GT$::execute_multiple_raw::_$u7b$$u7b$closure$u7d$$u7d$::h6fe04a9bd8ec67c7 in authz-2cb5cbbc2d1e019a.pofc1mhaai8ywix.rcgu.o
            "_InitAccount", referenced from:
                test_tube::runner::app::BaseApp::init_account::hb6c1758ff816e7c9 in libtest_tube-32dac9dd450a6ea7.rlib(test_tube-32dac9dd450a6ea7.test_tube.585259ba-cgu.7.rcgu.o)
            "_InitTestEnv", referenced from:
                test_tube::runner::app::BaseApp::new::h1f50c7e5febe166b in libtest_tube-32dac9dd450a6ea7.rlib(test_tube-32dac9dd450a6ea7.test_tube.585259ba-cgu.7.rcgu.o)
            "_Query", referenced from:
                _$LT$test_tube..runner..app..BaseApp$u20$as$u20$test_tube..runner..Runner$GT$::query::h6e7977d2643c0655 in authz-2cb5cbbc2d1e019a.pofc1mhaai8ywix.rcgu.o
            "_Simulate", referenced from:
                test_tube::runner::app::BaseApp::simulate_tx::h69440b7504931d3f in authz-2cb5cbbc2d1e019a.pofc1mhaai8ywix.rcgu.o
          ld: symbol(s) not found for architecture arm64
          clang: error: linker command failed with exit code 1 (use -v to see invocation)

Are there any pre-requisites that I might not have installed? I didn't see any in the readme.
Running on an M1 max.

IBC testing

To be able to test cross-chain CosmWasm contract, test-tube needs to be able to relay IBC packet across.

As suggested by @ethanfrey & @alpe, since the idea of test-tube is similar to how ibctesting is constructed, which we can take inspiration from for enabling IBC testing for test-tube.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.