Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: run e2e/integration tests vs replica rather than ic-ref #474

Merged
merged 15 commits into from
Sep 28, 2023
30 changes: 15 additions & 15 deletions .github/workflows/ic-ref.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ jobs:
with:
path: main

- name: Install dfx
uses: dfinity/setup-dfx@main
with:
dfx-version: "0.15.0"

- name: Cargo cache
uses: actions/cache@v2
with:
Expand All @@ -48,28 +53,23 @@ jobs:
wget https://github.com/dfinity/cycles-wallet/releases/download/${{ matrix.wallet-tag }}/wallet.wasm
mv wallet.wasm $HOME/wallet.wasm

- name: Download ic-ref and universal-canister
- name: Download universal-canister
run: |
wget https://download.dfinity.systems/ic-ref/ic-ref-0.0.1-${{ matrix.ic-hs-ref }}-x86_64-linux.tar.gz
tar -xvf ic-ref-0.0.1-${{ matrix.ic-hs-ref }}-x86_64-linux.tar.gz ic-ref
mkdir -p $HOME/bin
mv ic-ref $HOME/bin/ic-ref

wget https://download.dfinity.systems/ic-ref/ic-ref-test-0.0.1-${{ matrix.ic-hs-ref }}-x86_64-linux.tar.gz
tar -xvf ic-ref-test-0.0.1-${{ matrix.ic-hs-ref }}-x86_64-linux.tar.gz test-data/universal-canister.wasm
mv test-data/universal-canister.wasm $HOME/canister.wasm

- name: Run Integration Tests
run: |
set -ex
$HOME/bin/ic-ref --pick-port --write-port-to $HOME/ic_ref_port &
dfx start --background --clean
sleep 1
export IC_REF_PORT=$(cat $HOME/ic_ref_port)
export IC_REF_PORT=$(dfx info replica-port)
export IC_UNIVERSAL_CANISTER_PATH=$HOME/canister.wasm
export IC_WALLET_CANISTER_PATH=$HOME/wallet.wasm
cd main
cargo test --all-features -- --ignored
killall ic-ref
dfx stop
env:
RUST_BACKTRACE: 1

Expand All @@ -89,14 +89,14 @@ jobs:
# create key:
pkcs11-tool -k --module $HSM_PKCS11_LIBRARY_PATH --login --slot-index $HSM_SLOT_INDEX -d $HSM_KEY_ID --key-type EC:prime256v1 --pin $HSM_PIN

$HOME/bin/ic-ref --pick-port --write-port-to $HOME/ic_ref_port &
dfx start --background --clean
sleep 1
export IC_REF_PORT=$(cat $HOME/ic_ref_port)
export IC_REF_PORT=$(dfx info replica-port)
export IC_UNIVERSAL_CANISTER_PATH=$HOME/canister.wasm
export IC_WALLET_CANISTER_PATH=$HOME/wallet.wasm
cd main/ref-tests
cargo test --all-features -- --ignored --nocapture --test-threads=1
killall ic-ref
dfx stop
env:
RUST_BACKTRACE: 1
HSM_PKCS11_LIBRARY_PATH: /usr/lib/softhsm/libsofthsm2.so
Expand All @@ -108,12 +108,12 @@ jobs:
- name: Run Doc Tests
run: |
set -ex
$HOME/bin/ic-ref --pick-port --write-port-to $HOME/ic_ref_port &
dfx start --background --clean
sleep 1
export IC_REF_PORT=$(cat $HOME/ic_ref_port)
export IC_REF_PORT=$(dfx info replica-port)
cd main
cargo test --all-features --doc -- --ignored
killall ic-ref
dfx stop
env:
RUST_BACKTRACE: 1

Expand Down
161 changes: 107 additions & 54 deletions ref-tests/tests/ic-ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,16 @@ mod management_canister {
};
use sha2::{Digest, Sha256};
use std::collections::HashSet;
use std::convert::TryInto;

mod create_canister {
use super::with_agent;
use ic_agent::{export::Principal, AgentError};
use ic_agent::{
agent::{RejectCode, RejectResponse},
export::Principal,
AgentError,
};

use ic_utils::interfaces::ManagementCanister;
use ref_tests::get_effective_canister_id;
use std::str::FromStr;
Expand Down Expand Up @@ -103,13 +109,14 @@ mod management_canister {
.call_and_wait()
.await;

let payload_content =
"canister does not exist: 75hes-oqbaa-aaaaa-aaaaa-aaaaa-aaaaa-aaaaa-q"
.to_string();

assert!(matches!(result,
Err(AgentError::HttpError(payload))
if String::from_utf8(payload.content.clone()).expect("Expected utf8") == payload_content));
Err(AgentError::ReplicaError(RejectResponse {
reject_code: RejectCode::DestinationInvalid,
reject_message,
error_code: Some(ref error_code)
})) if reject_message == "Canister 75hes-oqbaa-aaaaa-aaaaa-aaaaa-aaaaa-aaaaa-q not found" &&
error_code == "IC0301"));

Ok(())
})
}
Expand Down Expand Up @@ -164,7 +171,7 @@ mod management_canister {
.with_mode(InstallMode::Reinstall)
.call_and_wait()
.await;
assert!(matches!(result, Err(AgentError::HttpError(..))));
assert!(matches!(result, Err(AgentError::ReplicaError(..))));

// Upgrade should succeed.
ic00.install_code(&canister_id, &canister_wasm)
Expand All @@ -178,7 +185,7 @@ mod management_canister {
.with_mode(InstallMode::Upgrade)
.call_and_wait()
.await;
assert!(matches!(result, Err(AgentError::HttpError(..))));
assert!(matches!(result, Err(AgentError::ReplicaError(..))));

// Change controller.
ic00.update_settings(&canister_id)
Expand All @@ -192,9 +199,14 @@ mod management_canister {
.with_controller(other_agent_principal)
.call_and_wait()
.await;
assert!(matches!(result, Err(AgentError::HttpError(payload))
if String::from_utf8(payload.content.clone()).expect("Expected utf8")
== *"Wrong sender"));
assert!(
matches!(result, Err(AgentError::ReplicaError(RejectResponse{
reject_code: RejectCode::CanisterError,
reject_message,
error_code: Some(ref error_code),
})) if reject_message == format!("Only controllers of canister {} can call ic00 method update_settings", canister_id) &&
error_code == "IC0512")
);

// Reinstall as new controller
other_ic00
Expand Down Expand Up @@ -411,8 +423,8 @@ mod management_canister {
matches!(result, Err(AgentError::ReplicaError(RejectResponse{
reject_code: RejectCode::CanisterError,
reject_message,
..
})) if reject_message == "canister is not running")
error_code: None,
})) if reject_message == format!("Canister {} is stopped", canister_id))
);

// Can't call query on a stopped canister
Expand All @@ -421,8 +433,9 @@ mod management_canister {
matches!(result, Err(AgentError::ReplicaError(RejectResponse{
reject_code: RejectCode::CanisterError,
reject_message,
..
})) if reject_message == "canister is stopped")
error_code: Some(ref error_code),
})) if reject_message == format!("IC0508: Canister {} is stopped and therefore does not have a CallContextManager", canister_id) &&
error_code == "IC0508")
);

// Upgrade should succeed
Expand All @@ -444,8 +457,8 @@ mod management_canister {
matches!(result, Err(AgentError::ReplicaError(RejectResponse{
reject_code: RejectCode::DestinationInvalid,
reject_message,
..
})) if reject_message == "method does not exist: update")
error_code: None,
})) if reject_message == format!("Canister {} has no update method 'update'", canister_id))
);

// Can call query
Expand All @@ -454,17 +467,14 @@ mod management_canister {
matches!(result, Err(AgentError::ReplicaError(RejectResponse{
reject_code: RejectCode::DestinationInvalid,
reject_message,
..
})) if reject_message == "query method does not exist")
error_code: Some(ref error_code),
})) if reject_message == format!("IC0302: Canister {} has no query method 'query'", canister_id) &&
error_code == "IC0302")
);

// Another start is a noop
ic00.start_canister(&canister_id).call_and_wait().await?;

// Delete a running canister should fail.
let result = ic00.delete_canister(&canister_id).call_and_wait().await;
assert!(matches!(result, Err(AgentError::ReplicaError { .. })));

// Stop should succeed.
ic00.stop_canister(&canister_id).call_and_wait().await?;

Expand All @@ -473,37 +483,51 @@ mod management_canister {

// Cannot call update
let result = agent.update(&canister_id, "update").call_and_wait().await;
assert!(matches!(result, Err(AgentError::HttpError(payload))
if String::from_utf8(payload.content.clone()).expect("Expected utf8")
== format!("canister no longer exists: {}", canister_id.to_text())));
assert!(
matches!(result, Err(AgentError::ReplicaError(RejectResponse{
reject_code: RejectCode::DestinationInvalid,
reject_message,
error_code: Some(ref error_code),
})) if reject_message == format!("Canister {} not found", canister_id) &&
error_code == "IC0301")
);

// Cannot call query
let result = agent.query(&canister_id, "query").with_arg([]).call().await;
assert!(
matches!(result, Err(AgentError::ReplicaError(RejectResponse{
reject_code: RejectCode::DestinationInvalid,
reject_message,
..
})) if reject_message
== format!("canister no longer exists: {}", canister_id.to_text()))
error_code: Some(ref error_code)
})) if reject_message == format!("IC0301: Canister {} not found", canister_id) &&
error_code == "IC0301")
);

// Cannot query canister status
let result = ic00.canister_status(&canister_id).call_and_wait().await;
assert!(match result {
Err(AgentError::HttpError(payload))
if String::from_utf8(payload.content.clone()).expect("Expected utf8")
== format!("canister no longer exists: {}", canister_id.to_text()) =>
Err(AgentError::ReplicaError(RejectResponse{
reject_code: RejectCode::DestinationInvalid,
reject_message,
error_code: Some(ref error_code)
}))
if reject_message == format!("Canister {} not found", canister_id) &&
error_code == "IC0301" =>
true,
Ok((_status_call_result,)) => false,
_ => false,
});

// Delete a deleted canister should fail.
let result = ic00.delete_canister(&canister_id).call_and_wait().await;
assert!(matches!(result, Err(AgentError::HttpError(payload))
if String::from_utf8(payload.content.clone()).expect("Expected utf8")
== format!("canister no longer exists: {}", canister_id.to_text())));
assert!(
matches!(result, Err(AgentError::ReplicaError(RejectResponse{
reject_code: RejectCode::DestinationInvalid,
reject_message,
error_code: Some(ref error_code)
})) if reject_message == format!("Canister {} not found", canister_id) &&
error_code == "IC0301")
);
Ok(())
})
}
Expand Down Expand Up @@ -538,33 +562,51 @@ mod management_canister {
.start_canister(&canister_id)
.call_and_wait()
.await;
assert!(matches!(result, Err(AgentError::HttpError(payload))
if String::from_utf8(payload.content.clone()).expect("Expected utf8")
== *"Wrong sender"));
assert!(matches!(result,
Err(AgentError::ReplicaError(RejectResponse {
reject_code: RejectCode::CanisterError,
reject_message,
error_code: Some(ref error_code)
})) if reject_message == format!("Only controllers of canister {} can call ic00 method start_canister", canister_id) &&
error_code == "IC0512"));

// Stop as a wrong controller should fail.
let result = other_ic00.stop_canister(&canister_id).call_and_wait().await;
assert!(matches!(result, Err(AgentError::HttpError(payload))
if String::from_utf8(payload.content.clone()).expect("Expected utf8")
== *"Wrong sender"));
assert!(
matches!(result,
Err(AgentError::ReplicaError(RejectResponse {
reject_code: RejectCode::CanisterError,
reject_message,
error_code: Some(ref error_code)
})) if reject_message == format!("Only controllers of canister {} can call ic00 method stop_canister", canister_id) &&
error_code == "IC0512")
);

// Get canister status as a wrong controller should fail.
let result = other_ic00
.canister_status(&canister_id)
.call_and_wait()
.await;
assert!(matches!(result, Err(AgentError::HttpError(payload))
if String::from_utf8(payload.content.clone()).expect("Expected utf8")
== *"Wrong sender"));
assert!(matches!(result,
Err(AgentError::ReplicaError(RejectResponse {
reject_code: RejectCode::CanisterError,
reject_message,
error_code: Some(ref error_code)
})) if reject_message == format!("Only controllers of canister {} can call ic00 method canister_status", canister_id) &&
error_code == "IC0512"));

// Delete as a wrong controller should fail.
let result = other_ic00
.delete_canister(&canister_id)
.call_and_wait()
.await;
assert!(matches!(result, Err(AgentError::HttpError(payload))
if String::from_utf8(payload.content.clone()).expect("Expected utf8")
== *"Wrong sender"));
assert!(matches!(result,
Err(AgentError::ReplicaError(RejectResponse {
reject_code: RejectCode::CanisterError,
reject_message,
error_code: Some(ref error_code)
})) if reject_message == format!("Only controllers of canister {} can call ic00 method delete_canister", canister_id) &&
error_code == "IC0512"));

Ok(())
})
Expand Down Expand Up @@ -596,8 +638,14 @@ mod management_canister {

let args = Argument::from_candid((create_args,));

let creation_fee = 8000000000;
let (create_result,): (CreateResult,) = wallet
.call(Principal::management_canister(), "create_canister", args, 0)
.call(
Principal::management_canister(),
"create_canister",
args,
creation_fee,
)
.call_and_wait()
.await?;
let canister_id = create_result.canister_id;
Expand All @@ -614,7 +662,7 @@ mod management_canister {
.call_and_wait()
.await?;

assert_eq!(result.cycles, 0_u64);
assert!(result.cycles > 0_u64 && result.cycles < creation_fee);

let ic00 = ManagementCanister::create(&agent);
// cycle balance is default_canister_balance when creating with
Expand All @@ -626,7 +674,10 @@ mod management_canister {
.call_and_wait()
.await?;
let result = ic00.canister_status(&canister_id_1).call_and_wait().await?;
assert_eq!(result.0.cycles, default_canister_balance);
// assume some cycles are already burned
let cycles: i128 = result.0.cycles.0.try_into().unwrap();
let burned = default_canister_balance as i128 - cycles;
assert!(burned > 0 && burned < 100_000_000);

// cycle balance should be amount specified to
// provisional_create_canister_with_cycles call
Expand All @@ -638,7 +689,9 @@ mod management_canister {
.call_and_wait()
.await?;
let result = ic00.canister_status(&canister_id_2).call_and_wait().await?;
assert_eq!(result.0.cycles, amount);
let cycles: i128 = result.0.cycles.0.try_into().unwrap();
let burned = amount as i128 - cycles;
assert!(burned > 0 && burned < 100_000_000);

Ok(())
})
Expand Down Expand Up @@ -928,8 +981,8 @@ mod extras {
Err(AgentError::ReplicaError(RejectResponse {
reject_code: RejectCode::DestinationInvalid,
reject_message,
..
})) if reject_message == "The specified_id of the created canister is already in use."));
error_code: None,
})) if reject_message == "Canister iimsn-6yaaa-aaaaa-afiaa-cai is already installed"));

Ok(())
})
Expand Down
Loading
Loading