Skip to content

Commit

Permalink
test: Add test for taking a snapshot that triggers storage reservation (
Browse files Browse the repository at this point in the history
#3395)

This is a redo of #3360. Matching on the exact number of bytes requested
can be flaky apparently so instead focus on matching only on the
required amount of cycles in the error message which is the focus of the
test anyway.
  • Loading branch information
dsarlis authored Jan 13, 2025
1 parent 7fb826a commit a23113f
Showing 1 changed file with 41 additions and 0 deletions.
41 changes: 41 additions & 0 deletions rs/execution_environment/tests/storage_reservation.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use ic_config::execution_environment::Config as ExecutionConfig;
use ic_config::subnet_config::SubnetConfig;
use ic_error_types::ErrorCode;
use ic_management_canister_types::TakeCanisterSnapshotArgs;
use ic_management_canister_types::{self as ic00, CanisterInstallMode, EmptyBlob, Payload};
use ic_registry_subnet_type::SubnetType;
Expand Down Expand Up @@ -168,3 +169,43 @@ fn test_storage_reservation_triggered_in_canister_snapshot_with_enough_cycles_av
reserved_balance_before_snapshot
);
}

#[test]
fn test_storage_reservation_triggered_in_canister_snapshot_without_enough_cycles_available() {
// This test verifies that a canister cannot take a snapshot if it does not have enough
// cycles to cover the storage reservation triggered by the snapshot operation. The main
// point of the test is to verify that the error message is informative and includes the
// amount of cycles required to cover the storage reservation.
//
// The error message is produced by running the test once and checking the output. Calculating
// the exact amounts is hard to do in advance. Note that any changes to cycles cost or how
// the reservation mechanism works may require updating the error message in the test.

let (env, canister_id) = setup(
SUBNET_MEMORY_THRESHOLD,
SUBNET_MEMORY_CAPACITY,
Some(300_400_000_000),
);
assert_eq!(reserved_balance(&env, canister_id), 0);

// Grow memory in update call, should trigger storage reservation.
let _ = env.execute_ingress(canister_id, "update", wasm().stable_grow(3000).build());
let reserved_balance_before_snapshot = reserved_balance(&env, canister_id);
assert_gt!(reserved_balance_before_snapshot, 0); // Storage reservation is triggered.

// Take a snapshot to trigger more storage reservation. The canister does not have
// enough cycles in its balance, so this should fail.
let res = env.take_canister_snapshot(TakeCanisterSnapshotArgs::new(canister_id, None));
match res {
Ok(_) => panic!("Expected an error but got Ok(_)"),
Err(err) => {
assert_eq!(err.code(), ErrorCode::InsufficientCyclesInMemoryGrow);
// Match on a substring of the error message. Due to a difference in instructions consumed on
// Mac vs Linux, we cannot match on the exact number of cycles but we only need to verify it's
// a non-zero amount.
assert!(err
.description()
.contains("due to insufficient cycles. At least 339_603_"));
}
}
}

0 comments on commit a23113f

Please sign in to comment.