Pocket IC 7.0 Issue with HTTP outcalls in live mode

Description of the issue

So basically we need to make an integration tests and our canister is using HTTP outcalls to some docker service running on localhost.

I’ve got an issue which can be easily reproduced in this repo I’ve made for this reason: GitHub - veeso/pocket-ic-live-issue: A demonstrative repo with the Pocket IC HTTP outcall issue

So basically I have a simple test canister which has an endpoint which makes an HTTP request to a express server running on the localhost. The server just responds with the same body as the same sent to it.

When I run the integration test with Pocket IC 7, I see the express server receives the request and returns the response, but pocket-ic crashes like this:

thread 'test_should_get_posts_1' panicked at $HOME/cargo/registry/src/index.crates.io-6f17d22bba15001f/pocket-ic-6.0.0/src/nonblocking.rs:1304:51:
BadIngressMessage("Failed to answer to ingress 0x35a3b8c5fde5ef5305fa502edf15d9bd5cafc84f9c6a5148a28d6a00c51aed5a after 100 rounds.")

Pocket IC initialization

Pocket IC is initialized with our sdk like this:

PocketIcBuilder::new()
        .with_nns_subnet()
        .with_ii_subnet()
        .with_application_subnet()
        .build_async()
        .await;

Then we install the canister and set it live with make_live(None).await

The code of the SDK with the pocket-ic module is located here canister-sdk/ic-exports/src/pocket_ic.rs at main · bitfinity-network/canister-sdk · GitHub.

Does anybody know how to fix this?

Im having a similar issue with update calls not being processed, but unsure why

In my case, making an update call to the http gateway works a small fraction of the time even if i wait indefinitely for the response
Do your other tests work for incrementing the counter?

Flagging @mraszyk since he has helped me look into my issue which we are still trying to figure out

The issue comes from the fact that the PocketIc::update_call function doesn’t combine with the “live” mode. In more detail, the PocketIc::update_call function doesn’t wait until the update call is processed via the “live” mode, but instead executes up to 100 rounds on its own (independently of the “live” mode) without making canister http outcalls (they are only automatically processed by the “live” mode). The justification for this behavior is that the PocketIc::update_call function is supposed to be deterministic (to have reproducible tests) and relying on the “live” mode would make the tests not deterministic. Now there are two options:

  • follow the tutorial section on testing canister http outcalls using the PocketIC library by mocking their responses deterministically (then you don’t even need to spin up a testing webserver): this is recommended as tests are reproducible;
  • instead of PocketIc::update_call, use PocketIc::submit_call followed by PocketIc::await_call_no_ticks (unreleased) to await update call execution in the “live” mode.

Oh I didn’t know that! That’s good to know. Maybe it would be better to outline that in the HOWTO.

Thank you very much!