diff --git a/cmd/crates/soroban-test/src/lib.rs b/cmd/crates/soroban-test/src/lib.rs index 8116e191be..7cf95c5b64 100644 --- a/cmd/crates/soroban-test/src/lib.rs +++ b/cmd/crates/soroban-test/src/lib.rs @@ -124,7 +124,11 @@ impl TestEnv { /// A convenience method for using the invoke command. pub fn invoke>(&self, command_str: &[I]) -> Result { let cmd = contract::invoke::Cmd::parse_arg_vec( - &command_str.iter().map(AsRef::as_ref).collect::>(), + &command_str + .iter() + .map(AsRef::as_ref) + .filter(|s| !s.is_empty()) + .collect::>(), ) .unwrap(); self.invoke_cmd(cmd) diff --git a/cmd/crates/soroban-test/tests/it/contract_sandbox.rs b/cmd/crates/soroban-test/tests/it/contract_sandbox.rs index a5c5ede96a..ea2af861ca 100644 --- a/cmd/crates/soroban-test/tests/it/contract_sandbox.rs +++ b/cmd/crates/soroban-test/tests/it/contract_sandbox.rs @@ -6,8 +6,9 @@ use soroban_test::TestEnv; use std::path::PathBuf; use crate::util::{ - add_test_seed, DEFAULT_PUB_KEY, DEFAULT_PUB_KEY_1, DEFAULT_SECRET_KEY, DEFAULT_SEED_PHRASE, - HELLO_WORLD, TEST_SALT, + add_test_seed, is_rpc, network_passphrase, network_passphrase_arg, rpc_url, rpc_url_arg, + DEFAULT_PUB_KEY, DEFAULT_PUB_KEY_1, DEFAULT_SECRET_KEY, DEFAULT_SEED_PHRASE, HELLO_WORLD, + TEST_SALT, }; #[test] @@ -32,10 +33,10 @@ fn deploy_hello(sandbox: &TestEnv) -> String { let mut cmd: &mut assert_cmd::Command = &mut sandbox.new_assert_cmd("contract"); cmd = cmd.arg("deploy").arg("--wasm-hash").arg(&format!("{hash}")); - if std::env::var("SOROBAN_RPC_URL").is_err() { - cmd = cmd.arg("--id").arg(TEST_CONTRACT_ID); - } else { + if is_rpc() { cmd = cmd.arg("--salt").arg(TEST_SALT); + } else { + cmd = cmd.arg("--id").arg(TEST_CONTRACT_ID); } cmd.assert() .success() @@ -45,6 +46,9 @@ fn deploy_hello(sandbox: &TestEnv) -> String { #[test] fn deploy_contract_with_wasm_file() { + if is_rpc() { + return; + } TestEnv::default() .new_assert_cmd("contract") .arg("deploy") @@ -59,17 +63,7 @@ fn deploy_contract_with_wasm_file() { #[test] fn invoke_hello_world_with_deploy_first() { let sandbox = TestEnv::default(); - let res = sandbox - .new_assert_cmd("contract") - .arg("deploy") - .arg("--salt") - .arg(TEST_SALT) - .arg("--wasm") - .arg(HELLO_WORLD.path()) - .assert() - .success(); - let stdout = String::from_utf8(res.get_output().stdout.clone()).unwrap(); - let id = stdout.trim_end(); + let id = deploy_hello(&sandbox); println!("{id}"); sandbox .new_assert_cmd("contract") @@ -87,10 +81,12 @@ fn invoke_hello_world_with_deploy_first() { #[test] fn invoke_hello_world() { let sandbox = TestEnv::default(); + let id = deploy_hello(&sandbox); sandbox .new_assert_cmd("contract") .arg("invoke") - .arg("--id=1") + .arg("--id") + .arg(id) .arg("--wasm") .arg(HELLO_WORLD.path()) .arg("--") @@ -106,10 +102,12 @@ fn invoke_hello_world_from_file() { let sandbox = TestEnv::default(); let tmp_file = sandbox.temp_dir.join("world.txt"); std::fs::write(&tmp_file, "world").unwrap(); + let id = deploy_hello(&sandbox); sandbox .new_assert_cmd("contract") .arg("invoke") - .arg("--id=1") + .arg("--id") + .arg(id) .arg("--wasm") .arg(HELLO_WORLD.path()) .arg("--") @@ -126,10 +124,12 @@ fn invoke_hello_world_from_file_fail() { let sandbox = TestEnv::default(); let tmp_file = sandbox.temp_dir.join("world.txt"); std::fs::write(&tmp_file, "world").unwrap(); + let id = deploy_hello(&sandbox); sandbox .new_assert_cmd("contract") .arg("invoke") - .arg("--id=1") + .arg("--id") + .arg(id) .arg("--wasm") .arg(HELLO_WORLD.path()) .arg("--") @@ -145,12 +145,16 @@ fn invoke_hello_world_from_file_fail() { #[test] fn invoke_hello_world_with_lib() { TestEnv::with_default(|e| { - let cmd = contract::invoke::Cmd { - contract_id: "1".to_string(), - wasm: Some(HELLO_WORLD.path()), + let id = deploy_hello(e); + let mut cmd = contract::invoke::Cmd { + contract_id: id, slop: vec!["hello".into(), "--world=world".into()], ..Default::default() }; + + cmd.config.network.rpc_url = rpc_url(); + cmd.config.network.network_passphrase = network_passphrase(); + let res = e.invoke_cmd(cmd).unwrap(); assert_eq!(res, r#"["Hello","world"]"#); }); @@ -159,16 +163,19 @@ fn invoke_hello_world_with_lib() { #[test] fn invoke_hello_world_with_lib_two() { TestEnv::with_default(|e| { - let res = e - .invoke(&[ - "--id=1", - "--wasm", - &HELLO_WORLD.to_string(), - "--", - "hello", - "--world=world", - ]) - .unwrap(); + let id = deploy_hello(e); + let hello_world = HELLO_WORLD.to_string(); + let mut invoke_args = vec!["--id", &id, "--wasm", hello_world.as_str()]; + let args = vec!["--", "hello", "--world=world"]; + let res = if let (Some(rpc), Some(network_passphrase)) = + (rpc_url_arg(), network_passphrase_arg()) + { + invoke_args.push(&rpc); + invoke_args.push(&network_passphrase); + e.invoke(&[invoke_args, args].concat()).unwrap() + } else { + e.invoke(&[invoke_args, args].concat()).unwrap() + }; assert_eq!(res, r#"["Hello","world"]"#); }); } @@ -183,10 +190,12 @@ fn invoke_hello_world_with_lib_two() { #[test] fn invoke_auth() { let sandbox = TestEnv::default(); + let id = &deploy_hello(&sandbox); sandbox .new_assert_cmd("contract") .arg("invoke") - .arg("--id=1") + .arg("--id") + .arg(id) .arg("--wasm") .arg(HELLO_WORLD.path()) .arg("--") @@ -201,7 +210,8 @@ fn invoke_auth() { sandbox .new_assert_cmd("contract") .arg("invoke") - .arg("--id=1") + .arg("--id") + .arg(id) .arg("--") .arg("auth") .arg(&format!("--addr={DEFAULT_PUB_KEY}")) @@ -214,16 +224,17 @@ fn invoke_auth() { #[tokio::test] async fn invoke_auth_with_identity() { let sandbox = TestEnv::default(); - sandbox .cmd::("test -d ") .run() .await .unwrap(); + let id = deploy_hello(&sandbox); sandbox .new_assert_cmd("contract") .arg("invoke") - .arg("--id=1") + .arg("--id") + .arg(id) .arg("--wasm") .arg(HELLO_WORLD.path()) .arg("--") @@ -238,11 +249,13 @@ async fn invoke_auth_with_identity() { #[test] fn invoke_auth_with_different_test_account() { let sandbox = TestEnv::default(); + let id = deploy_hello(&sandbox); sandbox .new_assert_cmd("contract") .arg("invoke") .arg("--hd-path=1") - .arg("--id=1") + .arg("--id") + .arg(id) .arg("--wasm") .arg(HELLO_WORLD.path()) .arg("--") @@ -256,31 +269,14 @@ fn invoke_auth_with_different_test_account() { #[test] fn contract_data_read_failure() { - let hash = HELLO_WORLD.hash().unwrap(); let sandbox = TestEnv::default(); - sandbox - .new_assert_cmd("contract") - .arg("install") - .arg("--wasm") - .arg(HELLO_WORLD.path()) - .assert() - .success() - .stdout(format!("{hash}\n")); - - sandbox - .new_assert_cmd("contract") - .arg("deploy") - .arg("--wasm-hash") - .arg(&format!("{hash}")) - .arg("--id=1") - .assert() - .success() - .stdout("CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM\n"); + let id = deploy_hello(&sandbox); sandbox .new_assert_cmd("contract") .arg("read") - .arg("--id=1") + .arg("--id") + .arg(id) .arg("--key=COUNTER") .assert() .failure() @@ -291,31 +287,14 @@ fn contract_data_read_failure() { #[test] fn contract_data_read() { - let hash = HELLO_WORLD.hash().unwrap(); let sandbox = TestEnv::default(); - sandbox - .new_assert_cmd("contract") - .arg("install") - .arg("--wasm") - .arg(HELLO_WORLD.path()) - .assert() - .success() - .stdout(format!("{hash}\n")); - - sandbox - .new_assert_cmd("contract") - .arg("deploy") - .arg("--wasm-hash") - .arg(&format!("{hash}")) - .arg("--id=1") - .assert() - .success() - .stdout("CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM\n"); + let id = &deploy_hello(&sandbox); sandbox .new_assert_cmd("contract") .arg("invoke") - .arg("--id=1") + .arg("--id") + .arg(id) .arg("--") .arg("inc") .assert() @@ -324,7 +303,8 @@ fn contract_data_read() { sandbox .new_assert_cmd("contract") .arg("read") - .arg("--id=1") + .arg("--id") + .arg(id) .arg("--key=COUNTER") .assert() .success() @@ -333,7 +313,8 @@ fn contract_data_read() { sandbox .new_assert_cmd("contract") .arg("invoke") - .arg("--id=1") + .arg("--id") + .arg(id) .arg("--") .arg("inc") .assert() @@ -342,7 +323,8 @@ fn contract_data_read() { sandbox .new_assert_cmd("contract") .arg("read") - .arg("--id=1") + .arg("--id") + .arg(id) .arg("--key=COUNTER") .assert() .success() @@ -352,12 +334,15 @@ fn contract_data_read() { #[test] fn invoke_auth_with_different_test_account_fail() { let sandbox = TestEnv::default(); - + let id = &deploy_hello(&sandbox); let res = sandbox.invoke(&[ "--hd-path=1", - "--id=1", + "--id", + id, "--wasm", HELLO_WORLD.path().to_str().unwrap(), + &rpc_url_arg().unwrap_or_default(), + &network_passphrase_arg().unwrap_or_default(), "--", "auth", &format!("--addr={DEFAULT_PUB_KEY}"), @@ -399,12 +384,16 @@ fn invoke_with_sk() { } fn invoke_with_source(sandbox: &TestEnv, source: &str) { + let id = &deploy_hello(sandbox); let cmd = sandbox.invoke(&[ "--source-account", source, - "--id=1", + "--id", + id, "--wasm", HELLO_WORLD.path().to_str().unwrap(), + &rpc_url_arg().unwrap_or_default(), + &network_passphrase_arg().unwrap_or_default(), "--", "hello", "--world=world", @@ -415,7 +404,8 @@ fn invoke_with_source(sandbox: &TestEnv, source: &str) { let cmd = sandbox.invoke(&[ "--source-account", source, - "--id=1", + "--id", + id, "--", "hello", "--world=world", @@ -425,9 +415,12 @@ fn invoke_with_source(sandbox: &TestEnv, source: &str) { #[test] fn handles_kebab_case() { - assert!(TestEnv::default() + let e = TestEnv::default(); + let id = deploy_hello(&e); + assert!(e .invoke(&[ - "--id=1", + "--id", + &id, "--wasm", HELLO_WORLD.path().to_str().unwrap(), "--", @@ -437,22 +430,15 @@ fn handles_kebab_case() { .is_ok()); } -#[ignore] #[tokio::test] async fn fetch() { - // TODO: Currently this test fetches a live contract from futurenet. This obviously depends on - // futurenet for the test to work, which is not great. But also means that if we are upgrading - // the XDR ahead of a futurenet upgrade, this test will pass. Oof. :( + if !is_rpc() { + return; + } let e = TestEnv::default(); let f = e.dir().join("contract.wasm"); - let cmd = e.cmd_arr::(&[ - "--id", - "bc074f0f03934d0189653bc15af9a83170411e103b4c48a63888306cfba41ac8", - "--network", - "futurenet", - "--out-file", - f.to_str().unwrap(), - ]); + let id = deploy_hello(&e); + let cmd = e.cmd_arr::(&["--id", &id, "--out-file", f.to_str().unwrap()]); cmd.run().await.unwrap(); assert!(f.exists()); } diff --git a/cmd/crates/soroban-test/tests/it/util.rs b/cmd/crates/soroban-test/tests/it/util.rs index 17df21e70b..56990ec54b 100644 --- a/cmd/crates/soroban-test/tests/it/util.rs +++ b/cmd/crates/soroban-test/tests/it/util.rs @@ -84,6 +84,10 @@ where }); } +pub fn is_rpc() -> bool { + std::env::var("SOROBAN_RPC_URL").is_ok() +} + pub const DEFAULT_SEED_PHRASE: &str = "coral light army gather adapt blossom school alcohol coral light army giggle"; @@ -92,3 +96,19 @@ pub const DEFAULT_SECRET_KEY: &str = "SC36BWNUOCZAO7DMEJNNKFV6BOTPJP7IG5PSHLUOLT pub const DEFAULT_PUB_KEY_1: &str = "GCKZUJVUNEFGD4HLFBUNVYM2QY2P5WQQZMGRA3DDL4HYVT5MW5KG3ODV"; pub const TEST_SALT: &str = "f55ff16f66f43360266b95db6f8fec01d76031054306ae4a4b380598f6cfd114"; + +pub fn rpc_url() -> Option { + std::env::var("SOROBAN_RPC_URL").ok() +} + +pub fn rpc_url_arg() -> Option { + rpc_url().map(|url| format!("--rpc-url={url}")) +} + +pub fn network_passphrase() -> Option { + std::env::var("SOROBAN_NETWORK_PASSPHRASE").ok() +} + +pub fn network_passphrase_arg() -> Option { + network_passphrase().map(|p| format!("--network-passphrase={p}")) +} diff --git a/cmd/soroban-rpc/internal/test/cli_test.go b/cmd/soroban-rpc/internal/test/cli_test.go index 19a321726b..ca77cc0223 100644 --- a/cmd/soroban-rpc/internal/test/cli_test.go +++ b/cmd/soroban-rpc/internal/test/cli_test.go @@ -20,20 +20,75 @@ import ( "gotest.tools/v3/icmd" ) -func cargoTest(name string) *icmd.Result { +func cargoTest(t *testing.T, name string) { + NewCLITest(t) c := icmd.Command("cargo", "test", "--package", "soroban-test", "--test", "it", "--", name, "--exact", "--nocapture") c.Env = append(os.Environ(), fmt.Sprintf("SOROBAN_RPC_URL=http://localhost:%d/", sorobanRPCPort), fmt.Sprintf("SOROBAN_NETWORK_PASSPHRASE=%s", StandaloneNetworkPassphrase), ) - return icmd.RunCmd(c) + res := icmd.RunCmd(c) + require.NoError(t, res.Error, res.Stdout(), res.Stderr()) } -func TestCLIWithCargo(t *testing.T) { - NewCLITest(t) - res := cargoTest("contract_sandbox::invoke_hello_world_with_deploy_first") - stdout, stderr := res.Stdout(), res.Stderr() - println(stdout, stderr) +func TestCLIfetch(t *testing.T) { + cargoTest(t, "contract_sandbox::fetch") +} + +func TestCLIinstall_wasm_then_deploy_contract(t *testing.T) { + cargoTest(t, "contract_sandbox::install_wasm_then_deploy_contract") +} +func TestCLIcontract_data_read_failure(t *testing.T) { + cargoTest(t, "contract_sandbox::contract_data_read_failure") +} +func TestCLIinvoke_auth_with_different_test_account(t *testing.T) { + cargoTest(t, "contract_sandbox::invoke_auth_with_different_test_account") +} +func TestCLIinvoke_auth_with_different_test_account_fail(t *testing.T) { + cargoTest(t, "contract_sandbox::invoke_auth_with_different_test_account_fail") +} +func TestCLIhandles_kebab_case(t *testing.T) { + cargoTest(t, "contract_sandbox::handles_kebab_case") +} +func TestCLIinvoke_auth(t *testing.T) { + cargoTest(t, "contract_sandbox::invoke_auth") +} +func TestCLIinvoke_hello_world(t *testing.T) { + cargoTest(t, "contract_sandbox::invoke_hello_world") +} + +func TestCLIcontract_data_read(t *testing.T) { + cargoTest(t, "contract_sandbox::contract_data_read") +} +func TestCLIinvoke_hello_world_from_file(t *testing.T) { + cargoTest(t, "contract_sandbox::invoke_hello_world_from_file") +} +func TestCLIinvoke_hello_world_from_file_fail(t *testing.T) { + cargoTest(t, "contract_sandbox::invoke_hello_world_from_file_fail") +} +func TestCLIinvoke_hello_world_with_deploy_first(t *testing.T) { + cargoTest(t, "contract_sandbox::invoke_hello_world_with_deploy_first") +} +func TestCLIinvoke_hello_world_with_lib_two(t *testing.T) { + cargoTest(t, "contract_sandbox::invoke_hello_world_with_lib_two") +} +func TestCLIinvoke_hello_world_with_lib(t *testing.T) { + cargoTest(t, "contract_sandbox::invoke_hello_world_with_lib") +} +func TestCLIinvoke_hello_world_with_seed(t *testing.T) { + cargoTest(t, "contract_sandbox::invoke_hello_world_with_seed") +} +func TestCLIinvoke_with_sk(t *testing.T) { + cargoTest(t, "contract_sandbox::invoke_with_sk") +} +func TestCLIinvoke_auth_with_identity(t *testing.T) { + cargoTest(t, "contract_sandbox::invoke_auth_with_identity") +} +func TestCLIinvoke_with_id(t *testing.T) { + cargoTest(t, "contract_sandbox::invoke_with_id") +} +func TestCLIinvoke_with_seed(t *testing.T) { + cargoTest(t, "contract_sandbox::invoke_with_seed") } func TestCLIContractInstall(t *testing.T) {