Skip to content

Commit

Permalink
test: refactor management_canister tests (#438)
Browse files Browse the repository at this point in the history
* move main/provisonal tests to e2e

* refactor management example

* use stable rust in examples

* periodically run CI to keep cache available

* fmt

* single quote in yml

* 0 for Sunday
  • Loading branch information
lwshang authored Oct 26, 2023
1 parent cda6077 commit 6bc4b33
Show file tree
Hide file tree
Showing 11 changed files with 130 additions and 96 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ on:
branches:
- main
pull_request:
schedule:
- cron: '0 4 * * 0,3' # 4 a.m. UTC every Sun and Wed, keep actions-cache available

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/conventional-commits.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ on:
- reopened
- edited
- synchronize
schedule:
- cron: '0 4 * * 0,3' # 4 a.m. UTC every Sun and Wed, keep actions-cache available

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand Down
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.

5 changes: 5 additions & 0 deletions e2e-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ ic-cdk-timers.workspace = true
lazy_static = "1.4.0"
serde_bytes.workspace = true
futures.workspace = true
sha2.workspace = true

[[bin]]
name = "simple-kv-store"
Expand All @@ -41,6 +42,10 @@ path = "canisters/timers.rs"
name = "canister_info"
path = "canisters/canister_info.rs"

[[bin]]
name = "management_caller"
path = "canisters/management_caller.rs"

[dev-dependencies]
hex.workspace = true
ic-test-state-machine-client = "3"
80 changes: 80 additions & 0 deletions e2e-tests/canisters/management_caller.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
use ic_cdk::*;

mod main {
use super::*;
use ic_cdk::api::management_canister::main::*;
#[update]
async fn execute_main_methods() {
let arg = CreateCanisterArgument {
settings: Some(CanisterSettings {
controllers: Some(vec![ic_cdk::id()]),
compute_allocation: Some(0.into()),
memory_allocation: Some(10000.into()),
freezing_threshold: Some(10000.into()),
}),
};
let canister_id = create_canister(arg, 100_000_000_000u128 / 13)
.await
.unwrap()
.0
.canister_id;

let arg = UpdateSettingsArgument {
canister_id,
settings: CanisterSettings::default(),
};
update_settings(arg).await.unwrap();

let arg = InstallCodeArgument {
mode: CanisterInstallMode::Install,
canister_id,
// A minimal valid wasm module
// wat2wasm "(module)"
wasm_module: b"\x00asm\x01\x00\x00\x00".to_vec(),
arg: vec![],
};
install_code(arg).await.unwrap();
let arg = CanisterIdRecord { canister_id };
uninstall_code(arg).await.unwrap();
start_canister(arg).await.unwrap();
stop_canister(arg).await.unwrap();
let response = canister_status(arg).await.unwrap().0;
assert_eq!(response.status, CanisterStatusType::Stopped);
deposit_cycles(arg, 1_000_000_000_000u128).await.unwrap();
delete_canister(arg).await.unwrap();
let response = raw_rand().await.unwrap().0;
assert_eq!(response.len(), 32);
}
}

mod provisional {
use super::*;
use ic_cdk::api::management_canister::provisional::*;

#[update]
async fn execute_provisional_methods() {
let settings = CanisterSettings {
controllers: Some(vec![ic_cdk::caller()]),
compute_allocation: Some(50.into()),
memory_allocation: Some(10000.into()),
freezing_threshold: Some(10000.into()),
};
let arg = ProvisionalCreateCanisterWithCyclesArgument {
amount: Some(1_000_000_000.into()),
settings: Some(settings),
};
let canister_id = provisional_create_canister_with_cycles(arg)
.await
.unwrap()
.0
.canister_id;

let arg = ProvisionalTopUpCanisterArgument {
canister_id,
amount: 1_000_000_000.into(),
};
provisional_top_up_canister(arg).await.unwrap();
}
}

fn main() {}
13 changes: 13 additions & 0 deletions e2e-tests/tests/e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -472,3 +472,16 @@ fn test_cycles_burn() {
eprintln!("Balance 3: {balance3}");
assert_eq!(balance3, 0);
}

#[test]
fn call_management() {
let env = env();
let wasm = cargo_build_canister("management_caller");
let canister_id = env.create_canister(None);
env.add_cycles(canister_id, 100_000_000_000_000);
env.install_canister(canister_id, wasm, vec![], None);
let () = call_candid(&env, canister_id, "execute_main_methods", ())
.expect("Error calling execute_main_methods");
let () = call_candid(&env, canister_id, "execute_provisional_methods", ())
.expect("Error calling execute_provisional_methods");
}
2 changes: 2 additions & 0 deletions examples/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ root="$(dirname "$0")/.."
example_root="$(dirname "$0")/$name"
did_file="/tmp/a.did"

cargo update --manifest-path="$example_root/Cargo.toml"

cargo build --manifest-path="$example_root/Cargo.toml" \
--target wasm32-unknown-unknown \
--release \
Expand Down
8 changes: 0 additions & 8 deletions examples/management_canister/dfx.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,5 @@
"wasm": "target/wasm32-unknown-unknown/release/caller-opt.wasm",
"build": "sh ../build.sh management_canister caller"
}
},
"defaults": {
"canister_http": {
"enabled": true
},
"bitcoin": {
"enabled": true
}
}
}
82 changes: 4 additions & 78 deletions examples/management_canister/src/caller/lib.rs
Original file line number Diff line number Diff line change
@@ -1,82 +1,5 @@
use ic_cdk::*;

mod main {
use super::*;
use ic_cdk::api::management_canister::main::*;
#[update]
async fn execute_main_methods() {
let arg = CreateCanisterArgument {
settings: Some(CanisterSettings {
controllers: Some(vec![ic_cdk::id()]),
compute_allocation: Some(0.into()),
memory_allocation: Some(10000.into()),
freezing_threshold: Some(10000.into()),
}),
};
let canister_id = create_canister(arg, 100_000_000_000u128 / 13)
.await
.unwrap()
.0
.canister_id;

let arg = UpdateSettingsArgument {
canister_id,
settings: CanisterSettings::default(),
};
update_settings(arg).await.unwrap();

let arg = InstallCodeArgument {
mode: CanisterInstallMode::Install,
canister_id,
// A minimal valid wasm module
// wat2wasm "(module)"
wasm_module: b"\x00asm\x01\x00\x00\x00".to_vec(),
arg: vec![],
};
install_code(arg).await.unwrap();
let arg = CanisterIdRecord { canister_id };
uninstall_code(arg).await.unwrap();
start_canister(arg).await.unwrap();
stop_canister(arg).await.unwrap();
let response = canister_status(arg).await.unwrap().0;
assert_eq!(response.status, CanisterStatusType::Stopped);
deposit_cycles(arg, 1_000_000_000_000u128).await.unwrap();
delete_canister(arg).await.unwrap();
let response = raw_rand().await.unwrap().0;
assert_eq!(response.len(), 32);
}
}

mod provisional {
use super::*;
use ic_cdk::api::management_canister::provisional::*;

#[update]
async fn execute_provisional_methods() {
let settings = CanisterSettings {
controllers: Some(vec![ic_cdk::caller()]),
compute_allocation: Some(50.into()),
memory_allocation: Some(10000.into()),
freezing_threshold: Some(10000.into()),
};
let arg = ProvisionalCreateCanisterWithCyclesArgument {
amount: Some(1_000_000_000.into()),
settings: Some(settings),
};
let canister_id = provisional_create_canister_with_cycles(arg)
.await
.unwrap()
.0
.canister_id;

let arg = ProvisionalTopUpCanisterArgument {
canister_id,
amount: 1_000_000_000.into(),
};
provisional_top_up_canister(arg).await.unwrap();
}
}

mod http_request {
use super::*;
use ic_cdk::api::management_canister::http_request::*;
Expand Down Expand Up @@ -206,7 +129,10 @@ mod bitcoin {
assert!(response.is_err());
if let Err((rejection_code, rejection_reason)) = response {
assert_eq!(rejection_code, RejectionCode::CanisterReject);
assert_eq!(&rejection_reason, "bitcoin_send_transaction failed: Can't deserialize transaction because it's malformed.");
assert_eq!(
&rejection_reason,
"send_transaction failed: MalformedTransaction"
);
};
}
}
Expand Down
27 changes: 17 additions & 10 deletions examples/management_canister/tests/basic.bats
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
# Executed before each test.
setup() {
cd examples/management_canister
bitcoind -regtest -daemonwait
# Make sure the directory is clean.
dfx start --clean --background
}

# executed after each test
teardown() {
dfx stop
bitcoin-cli -regtest stop
}

@test "All management canister methods succeed" {
@test "http_request example succeed" {
dfx start --clean --background --enable-canister-http
dfx deploy
dfx canister call caller http_request_example
}

@test "ecdsa methods succeed" {
dfx start --clean --background
dfx deploy
dfx canister call caller execute_ecdsa_methods
}

@test "bitcoin methods succeed" {
bitcoind -regtest -daemonwait
dfx start --clean --background --enable-bitcoin
dfx deploy
run dfx canister call caller execute_main_methods
run dfx canister call caller execute_provisional_methods
run dfx canister call caller http_request_example
run dfx canister call caller execute_ecdsa_methods
run dfx canister call caller execute_bitcoin_methods
dfx canister call caller execute_bitcoin_methods
bitcoin-cli -regtest stop
}
4 changes: 4 additions & 0 deletions examples/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[toolchain]
channel = "stable" # sync with rust-version in root Cargo.toml
targets = ["wasm32-unknown-unknown"]
components = ["rustfmt", "clippy"]

0 comments on commit 6bc4b33

Please sign in to comment.