Skip to content

Commit

Permalink
Merge branch 'elias/pic-tests' into 'master'
Browse files Browse the repository at this point in the history
fix(PocketIC): Fix line numbers in README.md, copy change log for server

- fix line numbers in README.md and move the referenced tests to the top such that this happens less often in the future
- extended `get_subnet()` test case
- copy the server change log to this repo as well s.t. we can keep track of changes more easily 

See merge request dfinity-lab/public/ic!16313
  • Loading branch information
fxgst committed Nov 24, 2023
2 parents 74b90dd + 0eabe84 commit 4ac5712
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 43 deletions.
4 changes: 2 additions & 2 deletions packages/pocket-ic/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ fn call_counter_canister(pic: &PocketIc, canister_id: CanisterId, method: &str)
* Import PocketIC with `use pocket_ic::PocketIc`, and create a new PocketIC instance with `let pic = PocketIc::new()` in your Rust code and start testing!

### Examples
For a simple but complete example with the counter canister, see [here](tests/tests.rs#L491).
For an example with cross canister calls on two different subnets with the ledger canister, see [here](tests/tests.rs#L19).
For a simple but complete example with the counter canister, see [here](tests/tests.rs#L19).
For an example with cross canister calls on two different subnets with the ledger canister, see [here](tests/tests.rs#L57).

For larger test suites with more complex test setups, consider the [OpenChat](https://github.com/open-chat-labs/open-chat/tree/master/backend/integration_tests/src) integration test suite.
Note that instances are shared among test cases there, which is not recommended in general.
Expand Down
86 changes: 50 additions & 36 deletions packages/pocket-ic/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,44 @@ use std::{collections::HashMap, io::Read, time::SystemTime};
// 2T cycles
const INIT_CYCLES: u128 = 2_000_000_000_000;

#[test]
fn test_counter_canister() {
let pic = PocketIc::new();

// Create a canister and charge it with 2T cycles.
let can_id = pic.create_canister();
pic.add_cycles(can_id, INIT_CYCLES);

// Install the counter canister wasm file on the canister.
let counter_wasm = counter_wasm();
pic.install_canister(can_id, counter_wasm, vec![], None);

// Make some calls to the canister.
let reply = call_counter_can(&pic, can_id, "read");
assert_eq!(reply, WasmResult::Reply(vec![0, 0, 0, 0]));
let reply = call_counter_can(&pic, can_id, "write");
assert_eq!(reply, WasmResult::Reply(vec![1, 0, 0, 0]));
let reply = call_counter_can(&pic, can_id, "write");
assert_eq!(reply, WasmResult::Reply(vec![2, 0, 0, 0]));
let reply = call_counter_can(&pic, can_id, "read");
assert_eq!(reply, WasmResult::Reply(vec![2, 0, 0, 0]));
}

fn counter_wasm() -> Vec<u8> {
let wasm_path = std::env::var_os("COUNTER_WASM").expect("Missing counter wasm file");
std::fs::read(wasm_path).unwrap()
}

fn call_counter_can(ic: &PocketIc, can_id: CanisterId, method: &str) -> WasmResult {
ic.update_call(
can_id,
Principal::anonymous(),
method,
encode_one(()).unwrap(),
)
.expect("Failed to call counter canister")
}

#[test]
fn test_xnet_ledger_canister() {
// Set up PocketIC with two subnets: the NNS and an application subnet.
Expand Down Expand Up @@ -510,27 +548,6 @@ fn test_create_and_drop_instances() {
assert_eq!(PocketIc::list_instances()[id], "Deleted".to_string());
}

#[test]
fn test_counter_canister() {
let pic = PocketIc::new();

let can_id = pic.create_canister();
pic.add_cycles(can_id, INIT_CYCLES);

// Open a wasm file and install it on the canister
let counter_wasm = counter_wasm();
pic.install_canister(can_id, counter_wasm, vec![], None);

let reply = call_counter_can(&pic, can_id, "read");
assert_eq!(reply, WasmResult::Reply(vec![0, 0, 0, 0]));
let reply = call_counter_can(&pic, can_id, "write");
assert_eq!(reply, WasmResult::Reply(vec![1, 0, 0, 0]));
let reply = call_counter_can(&pic, can_id, "write");
assert_eq!(reply, WasmResult::Reply(vec![2, 0, 0, 0]));
let reply = call_counter_can(&pic, can_id, "read");
assert_eq!(reply, WasmResult::Reply(vec![2, 0, 0, 0]));
}

#[test]
fn test_tick() {
let pic = PocketIc::new();
Expand Down Expand Up @@ -582,6 +599,18 @@ fn test_get_subnet_of_canister() {
let canister_id = pic.create_canister_on_subnet(None, None, app_subnet);
let subnet_id = pic.get_subnet(canister_id);
assert_eq!(subnet_id.unwrap(), app_subnet);

let pic = PocketIc::new();
let canister_id = pic.create_canister();
let app_subnet = pic.topology().get_app_subnets()[0];
let subnet_id = pic.get_subnet(canister_id).unwrap();
assert_eq!(subnet_id, app_subnet);

pic.add_cycles(canister_id, INIT_CYCLES);
pic.stop_canister(canister_id, None).unwrap();
pic.delete_canister(canister_id, None).unwrap();
let subnet_id = pic.get_subnet(canister_id);
assert!(subnet_id.is_none());
}

#[test]
Expand Down Expand Up @@ -618,18 +647,3 @@ fn test_set_and_get_stable_memory_compressed() {
let read_data = pic.get_stable_memory(canister_id);
assert_eq!(data, read_data[..8]);
}

fn counter_wasm() -> Vec<u8> {
let wasm_path = std::env::var_os("COUNTER_WASM").expect("Missing counter wasm file");
std::fs::read(wasm_path).unwrap()
}

fn call_counter_can(ic: &PocketIc, can_id: CanisterId, method: &str) -> WasmResult {
ic.update_call(
can_id,
Principal::anonymous(),
method,
encode_one(()).unwrap(),
)
.expect("Failed to call counter canister")
}
59 changes: 59 additions & 0 deletions rs/pocket_ic_server/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
Before a release of the PocketIC server, copy the contents below into the CHANGELOG.md in the [PocketIC server repo](https://github.com/dfinity/pocketic/blob/main/CHANGELOG.md)!
=================================================================================================================================================================================
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).


## 2.0.1 - 2023-11-23

### Fixed
- Fixed a bug where `get_subnet()` would return results for non-existent canisters, causing `canister_exists()` to return `true` for non-existent canisters in client libraries
- Fixed a bug related to `PocketIc`s internal time being set to the current time, which lead to non-deterministic behavior


### Changed
- Cycles consumption is now more appropriately scaled according to the size of the subnet



## 2.0.0 - 2023-11-21

### Added
- Support for multiple subnets
- Support for cross-subnet canister calls
- Improved support to start the PocketIC server from the command line:
- Ability to start the server without any flags
- Use `-p or --port` to specify a port where the server should listen
- Use `--ttl` to specify for how long the server should be running before it shuts down
- `--pid` flag is no longer required and discouraged to use from the command line
- Improved logging support:
- Use the `POCKET_IC_LOG_DIR` environment varible to specify where to store logs
- Use the environment variable `POCKET_IC_LOG_DIR_LEVELS=trace` to specify the log level of the logs that are written to the log file
- `read/pub_key` endpoint to retrieve the public key of a subnet
- `read/get_subnet` endpoint to retrieve the subnet id of a canister

### Changed
- POST `instances/` endpoint requires a subnet config
- POST `instances/` endpoint returns a toplogy of the instance
- `/read/query` and `/update/execute_ingress_message` require an `effective_principal` field

### Removed
- Checkpointing
- `read/canister_exists` endpoint (superseded by `read/get_subnet`)
- `read/root_key` endpoint (superseded by `read/pub_key`)


## 1.0.0 - 2023-10-12

### Added
- Blocking REST-API: Encode IC-call in endpoint, not in body.


## 0.1.0 - 2023-08-31

### Added
- Blocking API to make IC-calls to a PocketIC server.
8 changes: 3 additions & 5 deletions rs/pocket_ic_server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,17 @@ use tracing_subscriber::filter::EnvFilter;
const TTL_SEC: u64 = 60;
// axum logs rejections from built-in extractors with the `axum::rejection`
// target, at `TRACE` level. `axum::rejection=trace` enables showing those events
// XXX: UPDATE CLI-ARGS IF YOU CHANGE THIS!
const DEFAULT_LOG_LEVELS: &str = "pocket_ic_server=info,tower_http=info,axum::rejection=trace";
const LOG_DIR_PATH_ENV_NAME: &str = "POCKET_IC_LOG_DIR";
const LOG_DIR_LEVELS_ENV_NAME: &str = "POCKET_IC_LOG_DIR_LEVELS";

/// The PocketIC server hosts and manages IC instances.
#[derive(Parser)]
#[clap(version = "2.0.1")]
struct Args {
/// If you use PocketIC from the command line, you should not use this flag.
/// Client libraries use this flag to provide a common identifier (the process ID of the test
/// process) such that the server is only started once and the individual tests in a test
/// run can (re-)use the same server.
/// process) such that the server is only started once and the individual tests can (re-)use
/// the same server.
#[clap(long)]
pid: Option<u32>,
/// The port under which the PocketIC server should be started
Expand Down Expand Up @@ -74,7 +72,7 @@ async fn start(runtime: Arc<Runtime>) {

// If PocketIC was started with the `--pid` flag, create a port file to communicate the port back to
// the parent process (e.g., the `cargo test` invocation). Other tests can then see this port file
// as well and reuse the same PocketIC server.
// and reuse the same PocketIC server.
let use_port_file = args.pid.is_some();
let mut port_file_path = None;
let mut ready_file_path = None;
Expand Down

0 comments on commit 4ac5712

Please sign in to comment.