Skip to content

Commit cd36aaf

Browse files
authored
feat!: management canister types refresh 2025-10-21 (#677)
* refresh mgmt types to 2025-10-21 * update pocket-ic to 2025-10-17 * merge management_canister tests into one * ic_cdk::management_canister add canister_metadata and snapshot APIs * e2e test new management canister APIs * breaking changes proposed in forum post * merge api e2e tests, no more nonmainnet
1 parent b7ef253 commit cd36aaf

File tree

14 files changed

+402
-205
lines changed

14 files changed

+402
-205
lines changed

e2e-tests/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ cargo_metadata = "0.21"
2828
futures = "0.3"
2929
hex.workspace = true
3030
ic-vetkd-utils = { git = "https://github.com/dfinity/ic", rev = "95231520" }
31-
pocket-ic = { git = "https://github.com/dfinity/ic", tag = "release-2025-08-21_03-19-base" }
31+
pocket-ic = { git = "https://github.com/dfinity/ic", tag = "release-2025-10-17_03-17-base" }
3232
reqwest = "0.12"
3333

3434
[build-dependencies]

e2e-tests/src/bin/api.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,36 @@ fn call_cost_sign_with_schnorr() {
258258
msg_reply(vec![]);
259259
}
260260

261+
#[export_name = "canister_query call_env_var_count"]
262+
fn call_env_var_count() {
263+
let count = env_var_count();
264+
assert_eq!(count, 2);
265+
msg_reply(vec![]);
266+
}
267+
268+
#[export_name = "canister_query call_env_var_name"]
269+
fn call_env_var_name() {
270+
// This is expected to panic as no environment variables are set.
271+
assert_eq!(env_var_name(0), "key1");
272+
assert_eq!(env_var_name(1), "key2");
273+
msg_reply(vec![]);
274+
}
275+
276+
#[export_name = "canister_query call_env_var_name_exists"]
277+
fn call_env_var_name_exists() {
278+
assert!(env_var_name_exists("key1"));
279+
assert!(env_var_name_exists("key2"));
280+
assert!(!env_var_name_exists("non_existent_var"));
281+
msg_reply(vec![]);
282+
}
283+
284+
#[export_name = "canister_query call_env_var_value"]
285+
fn call_env_var_value() {
286+
assert_eq!(env_var_value("key1"), "value1");
287+
assert_eq!(env_var_value("key2"), "value2");
288+
msg_reply(vec![]);
289+
}
290+
261291
#[export_name = "canister_update call_debug_print"]
262292
fn call_debug_print() {
263293
debug_print("Hello, world!");

e2e-tests/src/bin/api_nonmainnet.rs

Lines changed: 0 additions & 33 deletions
This file was deleted.

e2e-tests/src/bin/management_canister.rs

Lines changed: 67 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,30 @@ async fn basic() {
5959
};
6060
update_settings(&arg).await.unwrap();
6161

62+
// wat2wasm "(module (@custom "icp:public X" "content of X"))"
63+
let wasm_module = b"\x00asm\x01\x00\x00\x00\x00\x19\x0c\
64+
icp:public\x20Xcontent\x20of\x20X"
65+
.to_vec();
66+
6267
// install_code
6368
let arg = InstallCodeArgs {
6469
mode: CanisterInstallMode::Install,
6570
canister_id,
6671
// A minimal valid wasm module
6772
// wat2wasm "(module)"
68-
wasm_module: b"\x00asm\x01\x00\x00\x00".to_vec(),
73+
wasm_module,
6974
arg: vec![],
7075
};
7176
install_code(&arg).await.unwrap();
7277

78+
// canister_metadata
79+
let arg = CanisterMetadataArgs {
80+
canister_id,
81+
name: "X".to_string(),
82+
};
83+
let result = canister_metadata(&arg).await.unwrap();
84+
assert_eq!(result.value, b"content of X".to_vec());
85+
7386
// uninstall_code
7487
let arg = UninstallCodeArgs { canister_id };
7588
uninstall_code(&arg).await.unwrap();
@@ -307,12 +320,13 @@ async fn snapshots() {
307320

308321
// Cannot take a snapshot of a canister that is empty.
309322
// So we install a minimal wasm module.
323+
// A minimal valid wasm module
324+
// wat2wasm "(module)"
325+
let wasm_module = b"\x00asm\x01\x00\x00\x00".to_vec();
310326
let arg = InstallCodeArgs {
311327
mode: CanisterInstallMode::Install,
312328
canister_id,
313-
// A minimal valid wasm module
314-
// wat2wasm "(module)"
315-
wasm_module: b"\x00asm\x01\x00\x00\x00".to_vec(),
329+
wasm_module: wasm_module.clone(),
316330
arg: vec![],
317331
};
318332
install_code(&arg).await.unwrap();
@@ -322,25 +336,67 @@ async fn snapshots() {
322336
canister_id,
323337
replace_snapshot: None,
324338
};
325-
let snapshot = take_canister_snapshot(&arg).await.unwrap();
339+
let snapshot1 = take_canister_snapshot(&arg).await.unwrap();
326340

327341
// load_canister_snapshot
328342
let arg = LoadCanisterSnapshotArgs {
329343
canister_id,
330-
snapshot_id: snapshot.id.clone(),
344+
snapshot_id: snapshot1.id.clone(),
331345
};
332346
assert!(load_canister_snapshot(&arg).await.is_ok());
333347

348+
// read_canister_snapshot_metadata
349+
let arg = ReadCanisterSnapshotMetadataArgs {
350+
canister_id,
351+
snapshot_id: snapshot1.id.clone(),
352+
};
353+
let snapshot_metadata = read_canister_snapshot_metadata(&arg).await.unwrap();
354+
355+
// read_canister_snapshot_data
356+
let arg = ReadCanisterSnapshotDataArgs {
357+
canister_id,
358+
snapshot_id: snapshot1.id.clone(),
359+
kind: SnapshotDataKind::WasmModule { offset: 0, size: 8 },
360+
};
361+
let result = read_canister_snapshot_data(&arg).await.unwrap();
362+
assert_eq!(result.chunk, wasm_module);
363+
364+
// upload_canister_snapshot_metadata
365+
let globals = snapshot_metadata.globals.into_iter().flatten().collect();
366+
let arg = UploadCanisterSnapshotMetadataArgs {
367+
canister_id,
368+
replace_snapshot: None,
369+
wasm_module_size: snapshot_metadata.wasm_module_size,
370+
globals,
371+
wasm_memory_size: snapshot_metadata.wasm_memory_size,
372+
stable_memory_size: snapshot_metadata.stable_memory_size,
373+
certified_data: snapshot_metadata.certified_data,
374+
global_timer: snapshot_metadata.global_timer,
375+
on_low_wasm_memory_hook_status: snapshot_metadata.on_low_wasm_memory_hook_status,
376+
};
377+
let snapshot2 = upload_canister_snapshot_metadata(&arg).await.unwrap();
378+
assert!(!snapshot2.snapshot_id.is_empty());
379+
380+
// upload_canister_snapshot_data
381+
let arg = UploadCanisterSnapshotDataArgs {
382+
canister_id,
383+
snapshot_id: snapshot2.snapshot_id.clone(),
384+
kind: SnapshotDataOffset::WasmModule { offset: 0 },
385+
chunk: wasm_module.clone(),
386+
};
387+
assert!(upload_canister_snapshot_data(&arg).await.is_ok());
388+
334389
// list_canister_snapshots
335390
let args = ListCanisterSnapshotsArgs { canister_id };
336391
let snapshots = list_canister_snapshots(&args).await.unwrap();
337-
assert_eq!(snapshots.len(), 1);
338-
assert_eq!(snapshots[0].id, snapshot.id);
392+
assert_eq!(snapshots.len(), 2);
393+
assert_eq!(snapshots[0].id, snapshot1.id);
394+
assert_eq!(snapshots[1].id, snapshot2.snapshot_id);
339395

340396
// delete_canister_snapshot
341397
let arg = DeleteCanisterSnapshotArgs {
342398
canister_id,
343-
snapshot_id: snapshot.id.clone(),
399+
snapshot_id: snapshot1.id.clone(),
344400
};
345401
assert!(delete_canister_snapshot(&arg).await.is_ok());
346402

@@ -353,11 +409,11 @@ async fn snapshots() {
353409
assert_eq!(canister_info_result.total_num_changes, 3);
354410
assert_eq!(canister_info_result.recent_changes.len(), 1);
355411
if let Change {
356-
details: ChangeDetails::LoadSnapshot(load_snapshot_record),
412+
details: Some(ChangeDetails::LoadSnapshot(load_snapshot_record)),
357413
..
358414
} = &canister_info_result.recent_changes[0]
359415
{
360-
assert_eq!(load_snapshot_record.snapshot_id, snapshot.id);
416+
assert_eq!(load_snapshot_record.snapshot_id, snapshot1.id);
361417
} else {
362418
panic!("Expected the most recent change to be LoadSnapshot");
363419
}

e2e-tests/tests/api.rs

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -146,27 +146,7 @@ fn call_api() {
146146
.unwrap();
147147
assert!(res.is_empty());
148148

149-
let res = pic
150-
.update_call(canister_id, sender, "call_debug_print", vec![])
151-
.unwrap();
152-
assert!(res.is_empty());
153-
let rej = pic
154-
.update_call(canister_id, sender, "call_trap", vec![])
155-
.unwrap_err();
156-
assert_eq!(rej.error_code, ErrorCode::CanisterCalledTrap);
157-
assert!(rej.reject_message.contains("It's a trap!"));
158-
}
159-
160-
// Test for the system API that are not enabled on the mainnet yet.
161-
// A canister Wasm module that imports the non-mainnet APIs would result in canister installation failure.
162-
#[test]
163-
fn call_api_nonmainnet() {
164-
let wasm = cargo_build_canister("api_nonmainnet");
165-
let pic = pic_base().with_nonmainnet_features(true).build();
166-
let canister_id = pic.create_canister();
167-
pic.add_cycles(canister_id, 100_000_000_000_000);
168-
pic.install_canister(canister_id, wasm, vec![], None);
169-
let sender = Principal::anonymous();
149+
// env var
170150
let update_settings_arg = UpdateSettingsArgs {
171151
canister_id,
172152
settings: CanisterSettings {
@@ -190,8 +170,6 @@ fn call_api_nonmainnet() {
190170
(update_settings_arg,),
191171
)
192172
.unwrap();
193-
194-
// As of 2025-08, the env_var APIs are not available on mainnet yet.
195173
let res = pic
196174
.update_call(canister_id, sender, "call_env_var_count", vec![])
197175
.unwrap();
@@ -208,4 +186,14 @@ fn call_api_nonmainnet() {
208186
.update_call(canister_id, sender, "call_env_var_value", vec![])
209187
.unwrap();
210188
assert!(res.is_empty());
189+
190+
let res = pic
191+
.update_call(canister_id, sender, "call_debug_print", vec![])
192+
.unwrap();
193+
assert!(res.is_empty());
194+
let rej = pic
195+
.update_call(canister_id, sender, "call_trap", vec![])
196+
.unwrap_err();
197+
assert_eq!(rej.error_code, ErrorCode::CanisterCalledTrap);
198+
assert!(rej.reject_message.contains("It's a trap!"));
211199
}

e2e-tests/tests/bindgen.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ fn bindgen() {
88
let wasm = cargo_build_canister("bindgen");
99
let callee_wasm = cargo_build_canister("bindgen_callee");
1010

11-
let pic = pic_base().with_nonmainnet_features(true).build();
11+
let pic = pic_base().build();
1212

1313
let callee_canister_id = pic.create_canister();
1414
pic.add_cycles(callee_canister_id, 100_000_000_000_000);

0 commit comments

Comments
 (0)