Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions rs/migration_canister/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,14 @@ rust_canister(
rust_test(
name = "mc_tests",
srcs = glob(["src/**/*.rs"]),
compile_data = [":migration_canister.did"],
proc_macro_deps = [
"@crate_index//:strum_macros",
],
deps = [
# Keep sorted.
"@crate_index//:candid",
"@crate_index//:candid_parser",
"@crate_index//:futures",
"@crate_index//:ic-cdk",
"@crate_index//:ic-cdk-timers",
Expand Down
1 change: 1 addition & 0 deletions rs/migration_canister/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ strum = { workspace = true }
strum_macros = { workspace = true }

[dev-dependencies]
candid_parser = { workspace = true }
pocket-ic = { path = "../../packages/pocket-ic" }
tempfile = { workspace = true }
tokio = { workspace = true }
Expand Down
39 changes: 37 additions & 2 deletions rs/migration_canister/migration_canister.did
Original file line number Diff line number Diff line change
@@ -1,5 +1,40 @@
type MigrationCanisterInitPayload = record {};
type ListEventsArgs = record { page_size : nat64; page_index : nat64 };
type MigrationStatus = variant {
Failed : record { time : nat64; reason : text };
Succeeded : record { time : nat64 };
InProgress : record { status : text };
};

type MigrateCanisterArgs = record { source : principal; target : principal };

service : (opt MigrationCanisterInitPayload) -> {
type MigrationCanisterResult = variant { Ok; Err : MigrationCanisterError };
type MigrationCanisterError = variant { CallerNotAuthorized };

type ValidationResult = variant { Ok; Err : ValidationError };
type ValidationError = variant {
CanisterNotFound : record { canister : principal };
CallFailed : record { reason : text };
NotController : record { canister : principal };
CallerNotController : record { canister : principal };
TargetHasSnapshots;
MigrationInProgress : record { canister : principal };
SourceNotStopped;
RateLimited;
MigrationsDisabled;
SourceNotReady;
SourceInsufficientCycles;
SameSubnet;
TargetNotStopped;
};

type MigrationCanisterInitArgs = record { allowlist : opt vec principal };

service : (MigrationCanisterInitArgs) -> {
disable_api : () -> (MigrationCanisterResult);
enable_api : () -> (MigrationCanisterResult);
list_events : (ListEventsArgs) -> (vec MigrationStatus) query;
migrate_canister : (MigrateCanisterArgs) -> (ValidationResult);
// The same `(source, target)` pair might be processed again after a failure
// and thus we return a vector.
migration_status : (MigrateCanisterArgs) -> (vec MigrationStatus) query;
}
4 changes: 2 additions & 2 deletions rs/migration_canister/src/migration_canister.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use crate::{
};

#[derive(CandidType, Deserialize)]
struct MigrationCanisterInitArgs {
pub(crate) struct MigrationCanisterInitArgs {
allowlist: Option<Vec<Principal>>,
}

Expand Down Expand Up @@ -124,7 +124,7 @@ fn migration_status(args: MigrateCanisterArgs) -> Vec<MigrationStatus> {
}

#[derive(Clone, CandidType, Deserialize)]
struct ListEventsArgs {
pub(crate) struct ListEventsArgs {
page_index: u64,
page_size: u64,
}
Expand Down
2 changes: 1 addition & 1 deletion rs/migration_canister/src/privileged.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ fn check_caller() -> Result<(), MigrationCanisterError> {
}

#[derive(Clone, Debug, CandidType, Deserialize)]
enum MigrationCanisterError {
pub(crate) enum MigrationCanisterError {
CallerNotAuthorized,
}

Expand Down
18 changes: 18 additions & 0 deletions rs/migration_canister/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
//! Unit tests
use crate::migration_canister::{ListEventsArgs, MigrationCanisterInitArgs};
use crate::privileged::MigrationCanisterError;
use crate::{MigrateCanisterArgs, MigrationStatus, ValidationError};
use candid::Principal;
use candid_parser::utils::{CandidSource, service_equal};

use crate::{
Request, RequestState,
Expand All @@ -26,3 +30,17 @@ fn test() {
insert_request(RequestState::Accepted { request });
assert!(find_request(source, target).len() == 1);
}

#[test]
fn test_implemented_interface_matches_declared_interface_exactly() {
let declared_interface = CandidSource::Text(include_str!("../migration_canister.did"));

// The line below generates did types and service definition.
// The service definition is then obtained with `__export_service()`.
candid::export_service!();
let implemented_interface_str = __export_service();
let implemented_interface = CandidSource::Text(&implemented_interface_str);

let result = service_equal(declared_interface, implemented_interface);
assert!(result.is_ok(), "{:?}\n\n", result.unwrap_err());
}
Loading