🤗 *PocketIC*: Fast and versatile Canister Testing in Rust and Python

Hi infu, good to hear.

We think that is possible, and we are exploring adding the IC’s HTTP layer to PocketIc, which would make the agent libraries compatible and enable frontends. But this is currently in an early exploration stage and we cannot promise anything at this time.

If you have any other feedback or feature requests, we are happy to learn them.

3 Likes

Hi all, we have released a new version of PocketIC which supports multi-subnet testing. Have a look:

4 Likes

@michael-weigelt
I would like to report a couple of issues we are encountering with PocketIC. Firstly, in version 2.1.0 of PocketIC, the default features of reqwest are not properly set to false. Consequently, both native-tls and rustls are enabled by default. This issue is causing complications in our CI build, where the use of OpenSSL is restricted, leading to failures in the build process.
Additionally, if a call is blocked by the inspect_message check, PocketIC currently panics instead of returning an error as expected. This behavior poses a challenge in testing the inspect_message functionality, as it prevents us from properly assessing its behavior.

Hi ufoscout

Thank you for the feedback, we will look into it.
Is your first point a regression with regards to a previous version?

Yes, it is a regression

Hi @ufoscout, we’ve updated the PocketIC Rust crate to not use default features again, it will be released with the next release. Regarding the inspect_message check, could you please provide some more details where the panic is happening and where you’d expect an error? Maybe with a short code snippet, if that’s possible! Thank you. Update: see @mraszyk’s comment

This shouldn’t be the case if you use PocketIC server v3.0.0 and PocketIC library v2.1.

Thanks, I tested it and I confirm that it works as expected now

Do you plan to publish a 2.1.1 patch on crates.io anytime soon?

Yes, I expect within 24h.

1 Like

Just out of curiosity, is there any plan to create a non-blocking/async version of pocket-ic?

If there is demand, perhaps. If you would find this useful, it would be helpful to know a specific test scenario that you’d like to make possible.

We are currently working on a feature that will make PocketIC compatible with the IC’s HTTP Interface. That is, it will be compatible with agent-based tools like DFX and other software that uses agent.rs / agent.js. This also sets the stage for frontend-dapp testing. So if these are your use cases, they are very likely coming soon, with certain caveats.

1 Like

@michael-weigelt
For each of our canisters, we provide a fully-typed client. For instance, if the canister canister_one has a query endpoint get_name() -> String, invoking it through the client appears as follows:

// There are 4 supported backend types:
// 1. ic_backend: for canister-to-canister calls
// 2. ic-agent: for agent-to-canister calls
// 3. ic-state-machine-tests: for integration testing with state-machine-tests
// 4. pocket-ic: for integration testing with pocket-ic
let backend_type = ...;

// This is a fully-typed client for the CanisterOne canister
let canister_one_client = CanisterOneClient::new(backend_type);

// Performs a remote call to canister_one.
let endpoint_response = canister_one_client.get_name().await.unwrap(); 

The client has a single consistent API that can be used for testing and real scenarios.
The issue lies in the backend_type, as all types are asynchronous except for pocket-ic, which utilizes a blocking API. This necessitates wrapping each pocket-ic function call inside tokio::spawn_blocking, as shown below:

pub async fn canister_exists(&self, canister_id: CanisterId) -> bool {
    let pocket_ic = ...;
    tokio::task::spawn_blocking(move || pocket_ic.canister_exists(canister_id))
        .await
        .unwrap()
}

However, this approach fails to function as expected in multithreaded code.

Thanks for the details!

Here is server version 3.0.1 with the old default features (disabled):

And the rust library is now on version 2.2.0:
https://crates.io/crates/pocket-ic

1 Like

Can I use the performance counters with PocketIC?

And can I upgrade canisters on PocketIC?

Hi @timo,
Both of these things can be done with PocketIC.

Any update on when http outcalls will be available on pocket-ic?
We are currently forced to use dfx for some integration tests due to this limitation.

Hi @ufoscout, we have HTTP outcalls on the radar, but haven’t specified a timeline yet, as we prioritize other features for now. It’s definitely on the roadmap though!

2 Likes

Is it supported in PocketIC to add cycles to inter-canister calls?
And, in particular, is it possible to use a cycle wallet and make wallet calls?

Is it supported in PocketIC to add cycles to inter-canister calls?

Sure, if a canister has sufficient cycles balance, it can attach cycles to its outgoing calls.

And, in particular, is it possible to use a cycle wallet and make wallet calls?

Yes, indeed.