Skip to content

Commit

Permalink
Get test-tube tests running
Browse files Browse the repository at this point in the history
  • Loading branch information
JakeHartnell authored and Jake Hartnell committed Mar 26, 2024
1 parent fc5d5d6 commit 2f6bba4
Show file tree
Hide file tree
Showing 7 changed files with 306 additions and 71 deletions.
12 changes: 9 additions & 3 deletions contracts/external/cw-abc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ crate-type = ["cdylib", "rlib"]
backtraces = ["cosmwasm-std/backtraces"]
# use library feature to disable all instantiate/execute/query exports
library = []
# interface = ["dep:cw-orch"] # Adds the dependency when the feature is enabled
# use test tube feature to enable test-tube integration tests, for example
# cargo test --features "test-tube"
test-tube = []
# when writing tests you may wish to enable test-tube as a default feature
default = ["test-tube"]

[dependencies]
cw-utils = { workspace = true }
Expand All @@ -39,15 +43,17 @@ token-bindings = { workspace = true }
cw-ownable = { workspace = true }
cw-paginate-storage = { workspace = true }
cw-tokenfactory-issuer = { workspace = true, features = ["library"] }
# cw-orch = { version = "0.13.3", optional = true }

[dev-dependencies]
# TODO move to workspace?
speculoos = "0.11.0"
anyhow = { workspace = true }
cw-multi-test = { workspace = true }
dao-testing = { workspace = true }
dao-testing = { workspace = true, features = ["test-tube"] }
osmosis-std = { workspace = true }
osmosis-test-tube = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }

[profile.release]
rpath = false
Expand Down
2 changes: 1 addition & 1 deletion contracts/external/cw-abc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub mod state;
// cargo test --features test-tube
#[cfg(test)]
#[cfg(feature = "test-tube")]
mod testtube;
mod test_tube;

#[cfg(test)]
mod testing;
Expand Down
3 changes: 3 additions & 0 deletions contracts/external/cw-abc/src/test_tube/integration_tests.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use super::test_env::{TestEnv, TestEnvBuilder};
use crate::{
abc::{
ClosedConfig, CommonsPhaseConfig, HatchConfig, MinMax, OpenConfig, ReserveToken,
Expand All @@ -13,5 +14,7 @@ use token_bindings::Metadata;
fn test_happy_path() {
let app = OsmosisTestApp::new();

let env = TestEnvBuilder::new();
let TestEnv { abc, accounts, .. } = env.default_setup(&app);
// TODO
}
1 change: 1 addition & 0 deletions contracts/external/cw-abc/src/test_tube/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
mod integration_tests;
mod test_env;
235 changes: 217 additions & 18 deletions contracts/external/cw-abc/src/test_tube/test_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,36 @@
#![allow(dead_code)]

use crate::{
msg::{ExecuteMsg, InitialBalance, InstantiateMsg, NewTokenInfo, QueryMsg, TokenInfo},
abc::{
ClosedConfig, CommonsPhaseConfig, CurveType, HatchConfig, MinMax, OpenConfig, ReserveToken,
SupplyToken,
},
msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg},
ContractError,
};

use cosmwasm_std::{Coin, Uint128};
use cosmwasm_std::{Coin, Decimal, Uint128};
use cw_tokenfactory_issuer::msg::{DenomResponse, DenomUnit};
use cw_utils::Duration;
use dao_interface::voting::{IsActiveResponse, VotingPowerAtHeightResponse};
use dao_testing::test_tube::{cw_abc::CwAbc, cw_tokenfactory_issuer::TokenfactoryIssuer};
use dao_voting::threshold::ActiveThreshold;
use osmosis_std::types::{
cosmos::bank::v1beta1::QueryAllBalancesRequest, cosmwasm::wasm::v1::MsgExecuteContractResponse,
};
use dao_testing::test_tube::cw_tokenfactory_issuer::TokenfactoryIssuer;
use osmosis_test_tube::{
osmosis_std::types::cosmos::bank::v1beta1::QueryAllBalancesRequest,
osmosis_std::types::cosmwasm::wasm::v1::{
MsgExecuteContractResponse, MsgMigrateContract, MsgMigrateContractResponse,
},
Account, Bank, Module, OsmosisTestApp, RunnerError, RunnerExecuteResult, RunnerResult,
SigningAccount, Wasm,
};
use serde::de::DeserializeOwned;
use std::fmt::Debug;
use std::path::PathBuf;

pub const DENOM: &str = "ucat";
pub const JUNO: &str = "ujuno";

pub struct TestEnv<'a> {
pub app: &'a OsmosisTestApp,
pub abc: TfDaoVotingContract<'a>,
pub abc: CwAbc<'a>,
pub tf_issuer: TokenfactoryIssuer<'a>,
pub accounts: Vec<SigningAccount>,
}
Expand Down Expand Up @@ -105,17 +109,46 @@ impl TestEnvBuilder {
.init_accounts(&[Coin::new(1000000000000000u128, "uosmo")], 10)
.unwrap();

let initial_balances: Vec<InitialBalance> = accounts
.iter()
.map(|acc| InitialBalance {
address: acc.address(),
amount: Uint128::new(100),
})
.collect();

let issuer_id = TokenfactoryIssuer::upload(app, &accounts[0]).unwrap();

let abc = CwAbc::deploy(app, &InstantiateMsg {}, &accounts[0]).unwrap();
let abc = CwAbc::deploy(
app,
&InstantiateMsg {
token_issuer_code_id: issuer_id,
supply: SupplyToken {
subdenom: DENOM.to_string(),
metadata: None,
decimals: 6,
},
reserve: ReserveToken {
denom: JUNO.to_string(),
decimals: 6,
},
phase_config: CommonsPhaseConfig {
hatch: HatchConfig {
initial_raise: MinMax {
min: Uint128::one(),
max: Uint128::from(1000000u128),
},
initial_price: Uint128::one(),
initial_allocation_ratio: Decimal::percent(10u64),
exit_tax: Decimal::zero(),
},
open: OpenConfig {
allocation_percentage: Decimal::percent(10u64),
exit_tax: Decimal::percent(10u64),
},
closed: ClosedConfig {},
},
hatcher_allowlist: None,
curve_type: CurveType::Constant {
value: Uint128::one(),
scale: 1,
},
},
&accounts[0],
)
.unwrap();

let issuer_addr = CwAbc::query(&abc, &QueryMsg::TokenContract {}).unwrap();

Expand Down Expand Up @@ -193,3 +226,169 @@ pub fn assert_contract_err(expected: ContractError, actual: RunnerError) {
_ => panic!("unexpected error, expect execute error but got: {}", actual),
};
}

#[derive(Debug)]
pub struct CwAbc<'a> {
pub app: &'a OsmosisTestApp,
pub code_id: u64,
pub contract_addr: String,
}

impl<'a> CwAbc<'a> {
pub fn deploy(
app: &'a OsmosisTestApp,
instantiate_msg: &InstantiateMsg,
signer: &SigningAccount,
) -> Result<Self, RunnerError> {
let wasm = Wasm::new(app);
let token_creation_fee = Coin::new(10000000, "uosmo");

let code_id = wasm
.store_code(&Self::get_wasm_byte_code(), None, signer)?
.data
.code_id;

let contract_addr = wasm
.instantiate(
code_id,
&instantiate_msg,
Some(&signer.address()),
None,
&[token_creation_fee],
signer,
)?
.data
.address;

Ok(Self {
app,
code_id,
contract_addr,
})
}

pub fn new_with_values(
app: &'a OsmosisTestApp,
code_id: u64,
contract_addr: String,
) -> Result<Self, RunnerError> {
Ok(Self {
app,
code_id,
contract_addr,
})
}

/// uploads contract and returns a code ID
pub fn upload(app: &OsmosisTestApp, signer: &SigningAccount) -> Result<u64, RunnerError> {
let wasm = Wasm::new(app);

let code_id = wasm
.store_code(&Self::get_wasm_byte_code(), None, signer)?
.data
.code_id;

Ok(code_id)
}

pub fn instantiate(
app: &'a OsmosisTestApp,
code_id: u64,
instantiate_msg: &InstantiateMsg,
signer: &SigningAccount,
) -> Result<Self, RunnerError> {
let wasm = Wasm::new(app);
let contract_addr = wasm
.instantiate(
code_id,
&instantiate_msg,
Some(&signer.address()),
None,
&[],
signer,
)?
.data
.address;

Ok(Self {
app,
code_id,
contract_addr,
})
}

// executes
pub fn execute(
&self,
execute_msg: &ExecuteMsg,
funds: &[Coin],
signer: &SigningAccount,
) -> RunnerExecuteResult<MsgExecuteContractResponse> {
let wasm = Wasm::new(self.app);
wasm.execute(&self.contract_addr, execute_msg, funds, signer)
}

// queries
pub fn query<T>(&self, query_msg: &QueryMsg) -> Result<T, RunnerError>
where
T: DeserializeOwned,
{
let wasm = Wasm::new(self.app);
wasm.query(&self.contract_addr, query_msg)
}

// pub fn migrate(
// &self,
// testdata: &str,
// signer: &SigningAccount,
// ) -> RunnerExecuteResult<MsgMigrateContractResponse> {
// let wasm = Wasm::new(self.app);
// let manifest_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
// let wasm_byte_code =
// std::fs::read(manifest_path.join("tests").join("testdata").join(testdata)).unwrap();

// let code_id = wasm.store_code(&wasm_byte_code, None, signer)?.data.code_id;
// self.app.execute(
// MsgMigrateContract {
// sender: signer.address(),
// contract: self.contract_addr.clone(),
// code_id,
// msg: serde_json::to_vec(&MigrateMsg {}).unwrap(),
// },
// "/cosmwasm.wasm.v1.MsgMigrateContract",
// signer,
// )
// }

fn get_wasm_byte_code() -> Vec<u8> {
let manifest_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let byte_code = std::fs::read(
manifest_path
.join("..")
.join("..")
.join("artifacts")
.join("cw_tokenfactory_issuer.wasm"),
);
match byte_code {
Ok(byte_code) => byte_code,
// On arm processors, the above path is not found, so we try the following path
Err(_) => std::fs::read(
manifest_path
.join("..")
.join("..")
.join("artifacts")
.join("cw_tokenfactory_issuer-aarch64.wasm"),
)
.unwrap(),
}
}

pub fn execute_error(err: ContractError) -> RunnerError {
RunnerError::ExecuteError {
msg: format!(
"failed to execute message; message index: 0: {}: execute wasm contract failed",
err
),
}
}
}
Loading

0 comments on commit 2f6bba4

Please sign in to comment.