Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(PocketIC): simplify PocketIc::try_get_controllers #4026

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/pocket-ic/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased

### Added
- The function `PocketIc::try_get_controllers` which gets the controllers of a canister but doesn't panic if the target canister
doesn't exist.
- The function `PocketIcBuilder::with_bitcoind_addrs` to specify multiple addresses and ports at which `bitcoind` processes are listening.
- The function `PocketIc::query_call_with_effective_principal` for making generic query calls (including management canister query calls).
- The function `PocketIc::ingress_status` to fetch the status of an update call submitted through an ingress message.
Expand All @@ -19,7 +17,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
(round execution must be triggered separarely, e.g., on a "live" instance or by separate PocketIC library calls).
- The function `PocketIc::set_certified_time` to set the current certified time on all subnets of the PocketIC instance.
- The function `PocketIc::update_call_with_effective_principal` is made public. It is helpful, e.g., for
modeling management canister calls that need to be routed to the right subnet using effective principals.
modeling management canister calls that need to be routed to the right subnet using effective principals.
- The function `PocketIc::try_get_controllers` which gets the controllers of a canister but doesn't panic if the target canister
doesn't exist.

### Changed
- The response types `pocket_ic::WasmResult`, `pocket_ic::UserError`, and `pocket_ic::CallError` are replaced by a single reject response type `pocket_ic::RejectResponse`.
Expand Down
8 changes: 3 additions & 5 deletions packages/pocket-ic/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ use candid::{
Principal,
};
use ic_transport_types::SubnetMetrics;
use reqwest::{StatusCode, Url};
use reqwest::Url;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use slog::Level;
Expand Down Expand Up @@ -650,11 +650,9 @@ impl PocketIc {
}

/// Get the controllers of a canister.
/// Returns `None` if the canister does not exist.
#[instrument(ret, skip(self), fields(instance_id=self.pocket_ic.instance_id, canister_id = %canister_id.to_string()))]
pub fn try_get_controllers(
&self,
canister_id: CanisterId,
) -> Result<Vec<Principal>, (StatusCode, String)> {
pub fn try_get_controllers(&self, canister_id: CanisterId) -> Option<Vec<Principal>> {
let runtime = self.runtime.clone();
runtime.block_on(async { self.pocket_ic.try_get_controllers(canister_id).await })
}
Expand Down
26 changes: 14 additions & 12 deletions packages/pocket-ic/src/nonblocking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,25 +519,27 @@ impl PocketIc {
/// Panics if the canister does not exist.
#[instrument(ret, skip(self), fields(instance_id=self.instance_id, canister_id = %canister_id.to_string()))]
pub async fn get_controllers(&self, canister_id: CanisterId) -> Vec<Principal> {
self.try_get_controllers(canister_id).await.unwrap()
}

/// Get the controllers of a canister.
#[instrument(ret, skip(self), fields(instance_id=self.instance_id, canister_id = %canister_id.to_string()))]
pub async fn try_get_controllers(
&self,
canister_id: CanisterId,
) -> Result<Vec<Principal>, (StatusCode, String)> {
let endpoint = "read/get_controllers";
let result: Result<Vec<RawPrincipalId>, (StatusCode, String)> = self
.try_post(
let result: Vec<RawPrincipalId> = self
.post(
endpoint,
RawCanisterId {
canister_id: canister_id.as_slice().to_vec(),
},
)
.await;
result.map(|v| v.into_iter().map(|p| p.into()).collect())
result.into_iter().map(|p| p.into()).collect()
}

/// Get the controllers of a canister.
/// Returns `None` if the canister does not exist.
#[instrument(ret, skip(self), fields(instance_id=self.instance_id, canister_id = %canister_id.to_string()))]
pub async fn try_get_controllers(&self, canister_id: CanisterId) -> Option<Vec<Principal>> {
if self.canister_exists(canister_id).await {
Some(self.get_controllers(canister_id).await)
} else {
None
}
}

/// Get the current cycles balance of a canister.
Expand Down
4 changes: 3 additions & 1 deletion packages/pocket-ic/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1744,12 +1744,14 @@ fn try_get_controllers_of_nonexisting_canister() {
let pic = PocketIc::new();

let canister_id = pic.create_canister();
pic.try_get_controllers(canister_id).unwrap();

pic.add_cycles(canister_id, 100_000_000_000_000);
pic.stop_canister(canister_id, None).unwrap();
pic.delete_canister(canister_id, None).unwrap();

let res = pic.try_get_controllers(canister_id);
assert!(res.is_err())
assert!(res.is_none());
}

#[test]
Expand Down