Skip to content

Commit

Permalink
test: call and up contracts unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexD10S committed Apr 11, 2024
1 parent 9f1fb32 commit 9c6aac1
Show file tree
Hide file tree
Showing 4 changed files with 190 additions and 18 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion crates/pop-contracts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ contract-build = { version = "4.0.2" }
contract-extrinsics = { version = "4.0.0-rc.3"}

[dev-dependencies]
tempfile.workspace = true
tempfile.workspace = true
tokio.workspace = true
97 changes: 96 additions & 1 deletion crates/pop-contracts/src/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ pub async fn set_up_call(
) -> anyhow::Result<CallExec<DefaultConfig, DefaultEnvironment, Keypair>> {
let token_metadata = TokenMetadata::query::<DefaultConfig>(&call_opts.url).await?;
let manifest_path = get_manifest_path(&call_opts.path)?;

let signer = create_signer(&call_opts.suri)?;

let extrinsic_opts = ExtrinsicOptsBuilder::new(signer)
.manifest_path(Some(manifest_path))
.url(call_opts.url.clone())
Expand Down Expand Up @@ -130,3 +130,98 @@ pub async fn call_smart_contract(
display_events.display_events::<DefaultEnvironment>(Verbosity::Default, &token_metadata)?;
Ok(output)
}

#[cfg(feature = "unit_contract")]
#[cfg(test)]
mod tests {
use super::*;
use crate::{build_smart_contract, create_smart_contract};
use anyhow::{Error, Result};
use std::fs;
use tempfile::TempDir;

const CONTRACTS_NETWORK_URL: &str = "wss://rococo-contracts-rpc.polkadot.io";

fn generate_smart_contract_test_environment() -> Result<tempfile::TempDir, Error> {
let temp_dir = tempfile::tempdir().expect("Could not create temp dir");
let temp_contract_dir = temp_dir.path().join("test_contract");
fs::create_dir(&temp_contract_dir)?;
let result =
create_smart_contract("test_contract".to_string(), temp_contract_dir.as_path());
assert!(result.is_ok(), "Contract test environment setup failed");

Ok(temp_dir)
}
fn build_smart_contract_test_environment(temp_dir: &TempDir) -> Result<(), Error> {
build_smart_contract(&Some(temp_dir.path().join("test_contract")))?;
Ok(())
}

#[tokio::test]
async fn test_set_up_call() -> Result<(), Error> {
let temp_dir = generate_smart_contract_test_environment()?;
build_smart_contract_test_environment(&temp_dir)?;

let call_opts = CallOpts {
path: Some(temp_dir.path().join("test_contract")),
contract: "5CLPm1CeUvJhZ8GCDZCR7nWZ2m3XXe4X5MtAQK69zEjut36A".to_string(),
message: "get".to_string(),
args: [].to_vec(),
value: "1000".to_string(),
gas_limit: None,
proof_size: None,
url: Url::parse(CONTRACTS_NETWORK_URL)?,
suri: "//Alice".to_string(),
execute: false,
};
let call = set_up_call(call_opts).await;
assert!(call.is_ok());
assert_eq!(call.unwrap().message(), "get");

Ok(())
}

#[tokio::test]
async fn test_set_up_call_error_contract_not_build() -> Result<(), Error> {
let temp_dir = generate_smart_contract_test_environment()?;
let call_opts = CallOpts {
path: Some(temp_dir.path().join("test_contract")),
contract: "5CLPm1CeUvJhZ8GCDZCR7nWZ2m3XXe4X5MtAQK69zEjut36A".to_string(),
message: "get".to_string(),
args: [].to_vec(),
value: "1000".to_string(),
gas_limit: None,
proof_size: None,
url: Url::parse(CONTRACTS_NETWORK_URL)?,
suri: "//Alice".to_string(),
execute: false,
};
let call = set_up_call(call_opts).await;
assert!(call.is_err());
let error = call.err().unwrap();
assert_eq!(error.root_cause().to_string(), "Failed to find any contract artifacts in target directory. \nRun `cargo contract build --release` to generate the artifacts.");

Ok(())
}
#[tokio::test]
async fn test_set_up_call_fails_no_smart_contract_folder() -> Result<(), Error> {
let call_opts = CallOpts {
path: None,
contract: "5CLPm1CeUvJhZ8GCDZCR7nWZ2m3XXe4X5MtAQK69zEjut36A".to_string(),
message: "get".to_string(),
args: [].to_vec(),
value: "1000".to_string(),
gas_limit: None,
proof_size: None,
url: Url::parse(CONTRACTS_NETWORK_URL)?,
suri: "//Alice".to_string(),
execute: false,
};
let call = set_up_call(call_opts).await;
assert!(call.is_err());
let error = call.err().unwrap();
assert_eq!(error.root_cause().to_string(), "No 'ink' dependency found");

Ok(())
}
}
107 changes: 91 additions & 16 deletions crates/pop-contracts/src/up.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,24 +68,24 @@ pub async fn dry_run_gas_estimate_instantiate(
) -> anyhow::Result<Weight> {
let instantiate_result = instantiate_exec.instantiate_dry_run().await?;
match instantiate_result.result {
Ok(_) => {
// use user specified values where provided, otherwise use the estimates
let ref_time = instantiate_exec
.args()
.gas_limit()
.unwrap_or_else(|| instantiate_result.gas_required.ref_time());
let proof_size = instantiate_exec
.args()
.proof_size()
.unwrap_or_else(|| instantiate_result.gas_required.proof_size());
Ok(Weight::from_parts(ref_time, proof_size))
}
Err(ref _err) => {
Err(anyhow::anyhow!(
Ok(_) => {
// use user specified values where provided, otherwise use the estimates
let ref_time = instantiate_exec
.args()
.gas_limit()
.unwrap_or_else(|| instantiate_result.gas_required.ref_time());
let proof_size = instantiate_exec
.args()
.proof_size()
.unwrap_or_else(|| instantiate_result.gas_required.proof_size());
Ok(Weight::from_parts(ref_time, proof_size))
},
Err(ref _err) => {
Err(anyhow::anyhow!(
"Pre-submission dry-run failed. Add gas_limit and proof_size manually to skip this step."
))
}
}
},
}
}

pub async fn instantiate_smart_contract(
Expand All @@ -95,3 +95,78 @@ pub async fn instantiate_smart_contract(
let instantiate_result = instantiate_exec.instantiate(Some(gas_limit)).await?;
Ok(instantiate_result.contract_address.to_string())
}

#[cfg(feature = "unit_contract")]
#[cfg(test)]
mod tests {
use super::*;
use crate::{build_smart_contract, create_smart_contract};
use anyhow::{Error, Result};
use std::fs;
use tempfile::TempDir;
use url::Url;

const CONTRACTS_NETWORK_URL: &str = "wss://rococo-contracts-rpc.polkadot.io";

fn generate_smart_contract_test_environment() -> Result<tempfile::TempDir, Error> {
let temp_dir = tempfile::tempdir().expect("Could not create temp dir");
let temp_contract_dir = temp_dir.path().join("test_contract");
fs::create_dir(&temp_contract_dir)?;
let result =
create_smart_contract("test_contract".to_string(), temp_contract_dir.as_path());
assert!(result.is_ok(), "Contract test environment setup failed");

Ok(temp_dir)
}
fn build_smart_contract_test_environment(temp_dir: &TempDir) -> Result<(), Error> {
build_smart_contract(&Some(temp_dir.path().join("test_contract")))?;
Ok(())
}

#[tokio::test]
async fn test_set_up_deployment() -> Result<(), Error> {
let temp_dir = generate_smart_contract_test_environment()?;
build_smart_contract_test_environment(&temp_dir)?;

let call_opts = UpOpts {
path: Some(temp_dir.path().join("test_contract")),
constructor: "new".to_string(),
args: ["false".to_string()].to_vec(),
value: "1000".to_string(),
gas_limit: None,
proof_size: None,
url: Url::parse(CONTRACTS_NETWORK_URL)?,
suri: "//Alice".to_string(),
salt: None,
};
let result = set_up_deployment(call_opts).await;
assert!(result.is_ok());
assert_eq!(result.unwrap().url(), "wss://rococo-contracts-rpc.polkadot.io:443/");
Ok(())
}

#[tokio::test]
async fn test_dry_run_gas_estimate_instantiate() -> Result<(), Error> {
let temp_dir = generate_smart_contract_test_environment()?;
build_smart_contract_test_environment(&temp_dir)?;

let call_opts = UpOpts {
path: Some(temp_dir.path().join("test_contract")),
constructor: "new".to_string(),
args: ["false".to_string()].to_vec(),
value: "0".to_string(),
gas_limit: None,
proof_size: None,
url: Url::parse(CONTRACTS_NETWORK_URL)?,
suri: "//Alice".to_string(),
salt: None,
};
let instantiate_exec = set_up_deployment(call_opts).await;

let result = dry_run_gas_estimate_instantiate(&instantiate_exec.unwrap()).await;
assert!(result.is_ok());
assert_eq!(result.unwrap(), Weight::from_parts(140492887, 16689));

Ok(())
}
}

0 comments on commit 9c6aac1

Please sign in to comment.