-
Notifications
You must be signed in to change notification settings - Fork 69
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add tests for all CLI commands shown in docs
This makes use of the newly-published [soroban-test](https://docs.rs/soroban-test/latest/soroban_test/) crate and the newly-reorganized [soroban-cli](https://docs.rs/soroban-cli) library to test all commands shown in the docs. This gives us confidence that all of these commands work, though it does come with some downsides: - these tests live far from the thing they are meant to test - could we generate the docs from this repository, rather than keeping them in sync with each other? - maybe, but it's a little unclear how that would work - this is a good starting point Another shortcoming of the approach here: it still makes use of `assert_cmd` in some tests, which runs the version of `soroban-cli` installed on the host system, making it quite brittle. This is necessary because some commands (`Cmd`s) from `soroban-cli` do not currently operate in a test-friendly way. This can be seen in a secondary way, too: not all `Cmd`s can be run the same way. Some use `run`, some use `run_in_sandbox`, some take arguments, some do not. These concerns can all be addressed together by refactoring `soroban-cli` to make all `Cmd`s implement an asynchronous `run` method with the same signature, and which will return a struct containing both `stdout` and `stderr`. However, even with these shortcomings and downsides, it is still worth merging these tests as-is, since it will give us higher confidence that everything works as expected with the current code. We can refactor these tests later, and potentially move them to a different repo. Co-authored-by: Chad Ostrowski <221614+chadoh@users.noreply.github.com>
- Loading branch information
1 parent
9613590
commit 2de3f37
Showing
13 changed files
with
2,385 additions
and
236 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
[package] | ||
name = "cli-tests" | ||
version = "0.0.0" | ||
authors = ["Stellar Development Foundation <info@stellar.org>"] | ||
license = "Apache-2.0" | ||
edition = "2021" | ||
publish = false | ||
|
||
|
||
[lib] | ||
crate-type = ["cdylib"] | ||
doctest = false | ||
|
||
[dev-dependencies] | ||
predicates = "2.1.5" | ||
soroban-test = "0.7.1" | ||
soroban-cli = "0.7.1" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
Test CLI commands shown in the docs | ||
=================================== | ||
|
||
This directory contains tests for all CLI commands currently shown in | ||
https://soroban.stellar.org/docs/category/how-to-guides. | ||
|
||
Ideally, the docs themselves would have executable tests on all of their CLI | ||
examples. Perhaps in the future this can be facilitated by co-locating docs and | ||
examples in the same repo with git submodules. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
// empty crate to collect all workspace tests into one binary |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
//! Tests CLI commands from https://soroban.stellar.org/docs/how-to-guides/auth | ||
|
||
use soroban_cli::commands::config::identity::address; | ||
use soroban_test::{TestEnv, Wasm}; | ||
|
||
const WASM: &Wasm = &Wasm::Release("soroban_auth_contract"); | ||
|
||
const INCREMENT_1: &str = "2"; | ||
const INCREMENT_2: &str = "5"; | ||
|
||
fn account_pk(workspace: &TestEnv, hd_path: u8) -> String { | ||
workspace | ||
.cmd_arr::<address::Cmd>(&["--hd-path", &hd_path.to_string()]) | ||
.public_key() | ||
.unwrap() | ||
.to_string() | ||
} | ||
|
||
#[test] | ||
fn invoke_and_read() { | ||
TestEnv::with_default(|workspace| { | ||
let account_0_pk = account_pk(workspace, 0); | ||
let account_1_pk = account_pk(workspace, 1); | ||
|
||
assert_eq!( | ||
format!("{INCREMENT_1}"), | ||
workspace | ||
.invoke(&[ | ||
"--wasm", | ||
&WASM.path().to_string_lossy(), | ||
"--id", | ||
"1", | ||
"--", | ||
"increment", | ||
"--user", | ||
&account_0_pk, | ||
"--value", | ||
&INCREMENT_1, | ||
]) | ||
.unwrap(), | ||
); | ||
assert_eq!( | ||
format!("{INCREMENT_2}"), | ||
workspace | ||
.invoke(&[ | ||
"--hd-path", | ||
"1", | ||
"--wasm", | ||
&WASM.path().to_string_lossy(), | ||
"--id", | ||
"1", | ||
"--", | ||
"increment", | ||
"--user", | ||
&account_1_pk, | ||
"--value", | ||
&INCREMENT_2, | ||
]) | ||
.unwrap(), | ||
); | ||
|
||
// `read::Cmd`'s `run` returns `()` & dumps right to STDOUT; need to use assert_cmd | ||
workspace | ||
.new_assert_cmd("contract") | ||
.arg("read") | ||
.args(["--id", "1"]) | ||
.assert() | ||
.stderr("") | ||
.stdout(format!( | ||
r#""[""Counter"",""{account_0_pk}""]",{INCREMENT_1} | ||
"[""Counter"",""{account_1_pk}""]",{INCREMENT_2} | ||
"# | ||
)); | ||
}); | ||
} | ||
|
||
#[test] | ||
fn invoke_auth_preview() { | ||
TestEnv::with_default(|workspace| { | ||
let account_0_pk = account_pk(workspace, 0); | ||
|
||
// `invoke::Cmd`'s `auth` option prints directly to STDERR; need to test with assert_cmd | ||
workspace.new_assert_cmd("contract") | ||
.arg("invoke") | ||
.arg("--auth") | ||
.arg("--wasm") | ||
.arg(&WASM.path()) | ||
.args(["--id", "1"]) | ||
.args(["--"]) | ||
.arg("increment") | ||
.args(["--user", &account_0_pk]) | ||
.args(["--value", &INCREMENT_1]) | ||
.assert() | ||
.stdout(format!("{INCREMENT_1}\n")) | ||
.stderr( | ||
r#"Contract auth: [{"address_with_nonce":null,"root_invocation":{"contract_id":"0000000000000000000000000000000000000000000000000000000000000001","function_name":"increment","args":[{"address":{"account":{"public_key_type_ed25519":"d18f0210ff6cc1f2dcf1301fbbd4c30ee11a075820684d471df89d0f1011ea28"}}},{"u32":"#.to_string() + &format!("{INCREMENT_1}") + r#"}],"sub_invocations":[]},"signature_args":[]}] | ||
"# | ||
); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
//! Tests CLI commands from https://soroban.stellar.org/docs/how-to-guides/cross-contract-call | ||
|
||
use soroban_cli::commands::contract::{deploy, install}; | ||
use soroban_test::{TestEnv, Wasm}; | ||
|
||
const WASM_A: &Wasm = &Wasm::Release("soroban_cross_contract_a_contract"); | ||
const WASM_B: &Wasm = &Wasm::Release("soroban_cross_contract_b_contract"); | ||
|
||
#[test] | ||
fn invoke() { | ||
TestEnv::with_default(|workspace| { | ||
let hash_a = WASM_A.hash().unwrap(); | ||
workspace | ||
.cmd_arr::<install::Cmd>(&["--wasm", &WASM_A.path().to_string_lossy()]) | ||
.run_in_sandbox(WASM_A.bytes()) | ||
.unwrap(); | ||
workspace | ||
.cmd_arr::<deploy::Cmd>(&["--id", "a", "--wasm-hash", &format!("{hash_a}")]) | ||
.run_in_sandbox(hash_a) | ||
.unwrap(); | ||
|
||
let hash_b = WASM_B.hash().unwrap(); | ||
workspace | ||
.cmd_arr::<install::Cmd>(&["--wasm", &WASM_B.path().to_string_lossy()]) | ||
.run_in_sandbox(WASM_B.bytes()) | ||
.unwrap(); | ||
workspace | ||
.cmd_arr::<deploy::Cmd>(&["--id", "b", "--wasm-hash", &format!("{hash_b}")]) | ||
.run_in_sandbox(hash_b) | ||
.unwrap(); | ||
|
||
let res = workspace | ||
.invoke(&[ | ||
"--id", | ||
"b", | ||
"--", | ||
"add_with", | ||
"--contract_id", | ||
"a", | ||
"--x", | ||
"5", | ||
"--y", | ||
"7", | ||
]) | ||
.unwrap(); | ||
|
||
assert_eq!(res, "12"); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
//! Tests CLI commands from https://soroban.stellar.org/docs/how-to-guides/custom-types | ||
|
||
use soroban_test::{TestEnv, Wasm}; | ||
|
||
const WASM: &Wasm = &Wasm::Release("soroban_custom_types_contract"); | ||
|
||
fn increment_by_5(workspace: &TestEnv) -> String { | ||
workspace | ||
.invoke(&[ | ||
"--wasm", | ||
&WASM.path().to_string_lossy(), | ||
"--id", | ||
"1", | ||
"--", | ||
"increment", | ||
"--incr", | ||
"5", | ||
]) | ||
.unwrap() | ||
} | ||
|
||
#[test] | ||
fn invoke() { | ||
TestEnv::with_default(|workspace| { | ||
assert_eq!("5", increment_by_5(workspace)); | ||
}); | ||
} | ||
|
||
const EXPECTED_READ: &str = r#"STATE,"{""count"":5,""last_incr"":5}" | ||
"#; | ||
|
||
#[test] | ||
fn read() { | ||
TestEnv::with_default(|workspace| { | ||
increment_by_5(workspace); | ||
|
||
// `read::Cmd`'s `run` returns `()` & dumps right to STDOUT; need to use assert_cmd | ||
workspace | ||
.new_assert_cmd("contract") | ||
.arg("read") | ||
.args(["--id", "1"]) | ||
.args(["--key", "STATE"]) | ||
.assert() | ||
.stderr("") | ||
.stdout(EXPECTED_READ); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
//! Tests CLI commands from https://soroban.stellar.org/docs/how-to-guides/deployer | ||
|
||
use soroban_cli::commands::contract::install; | ||
use soroban_test::{TestEnv, Wasm}; | ||
|
||
const WASM_DEPLOYER_TEST: &Wasm = &Wasm::Release("soroban_deployer_test_contract"); | ||
const WASM_DEPLOYER: &Wasm = &Wasm::Release("soroban_deployer_contract"); | ||
|
||
const INIT_VALUE: &str = "5"; | ||
|
||
#[test] | ||
fn invoke() { | ||
TestEnv::with_default(|workspace| { | ||
let hash = WASM_DEPLOYER_TEST.hash().unwrap(); | ||
|
||
// install (aka upload) the bytes | ||
let install_ret = workspace | ||
.cmd_arr::<install::Cmd>(&["--wasm", &WASM_DEPLOYER_TEST.path().to_string_lossy()]) | ||
.run_in_sandbox(WASM_DEPLOYER_TEST.bytes()) | ||
.unwrap(); | ||
assert_eq!(hash, install_ret); | ||
|
||
// now invoke a 2nd contract, which deploys an instance of the previously-uploaded bytes | ||
let new_contract_info_array = workspace | ||
.invoke(&[ | ||
"--wasm", | ||
&WASM_DEPLOYER.path().to_string_lossy(), | ||
"--id", | ||
"0", | ||
"--", | ||
"deploy", | ||
"--salt", | ||
"0000000000000000000000000000000000000000000000000000000000000000", | ||
"--wasm_hash", | ||
&hash.to_string(), | ||
"--init_fn", | ||
"init", | ||
"--init_args", | ||
&format!("[{{\"u32\":{INIT_VALUE}}}]"), | ||
]) | ||
.unwrap(); | ||
|
||
let contract_id = new_contract_info_array.split('"').nth(1).unwrap(); | ||
|
||
assert_eq!( | ||
format!("{INIT_VALUE}"), | ||
workspace | ||
.invoke(&["--id", contract_id, "--", "value",]) | ||
.unwrap() | ||
); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
//! Tests CLI commands from https://soroban.stellar.org/docs/how-to-guides/errors | ||
|
||
use soroban_cli::commands::contract::invoke; | ||
use soroban_test::{TestEnv, Wasm}; | ||
|
||
const WASM: &Wasm = &Wasm::Release("soroban_errors_contract"); | ||
|
||
const EXPECTED_ERROR_START: &str = r#"HostError | ||
Value: Status(ContractError(1)) | ||
"#; | ||
|
||
#[test] | ||
fn invoke() { | ||
TestEnv::with_default(|sandbox| { | ||
let increment = || { | ||
sandbox.invoke(&[ | ||
"--wasm", | ||
&WASM.path().to_string_lossy(), | ||
"--id", | ||
"1", | ||
"--", | ||
"increment", | ||
]) | ||
}; | ||
|
||
// works the first five times | ||
assert_eq!(increment().unwrap(), "1"); | ||
assert_eq!(increment().unwrap(), "2"); | ||
assert_eq!(increment().unwrap(), "3"); | ||
assert_eq!(increment().unwrap(), "4"); | ||
assert_eq!(increment().unwrap(), "5"); | ||
|
||
// then errors | ||
let res = increment(); | ||
|
||
assert!(matches!(res, Err(invoke::Error::Host(_)))); | ||
assert!(format!("{res:?}").contains(EXPECTED_ERROR_START)); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
//! Tests CLI commands from https://soroban.stellar.org/docs/how-to-guides/events | ||
|
||
use soroban_test::{TestEnv, Wasm}; | ||
|
||
const WASM: &Wasm = &Wasm::Release("soroban_events_contract"); | ||
|
||
const EXPECTED_EVENT: &str = r#"#0: event: {"ext":"v0","contract_id":"0000000000000000000000000000000000000000000000000000000000000001","type_":"contract","body":{"v0":{"topics":[{"symbol":"COUNTER"},{"symbol":"increment"}],"data":{"u32":1}}}} | ||
"#; | ||
|
||
#[test] | ||
fn invoke() { | ||
TestEnv::with_default(|workspace| { | ||
// events get dumped right to STDERR using eprintln; need to test with assert_cmd | ||
workspace | ||
.new_assert_cmd("contract") | ||
.arg("invoke") | ||
.arg("--wasm") | ||
.arg(&WASM.path()) | ||
.args(["--id", "1"]) | ||
.args(["--", "increment"]) | ||
.assert() | ||
.stdout("1\n") | ||
.stderr(EXPECTED_EVENT); | ||
}); | ||
} |
Oops, something went wrong.