diff --git a/Cargo.lock b/Cargo.lock index 22347a482b0..02afd2e889f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5102,6 +5102,86 @@ dependencies = [ "paste 0.1.18", ] +[[package]] +name = "local-integration-tests" +version = "0.1.0" +dependencies = [ + "common", + "composable-traits", + "cumulus-pallet-aura-ext", + "cumulus-pallet-dmp-queue", + "cumulus-pallet-parachain-system", + "cumulus-pallet-session-benchmarking", + "cumulus-pallet-xcm", + "cumulus-pallet-xcmp-queue", + "cumulus-primitives-core", + "cumulus-primitives-timestamp", + "cumulus-primitives-utility", + "dali-runtime", + "env_logger 0.9.0", + "frame-benchmarking", + "frame-executive", + "frame-support", + "frame-system", + "frame-system-benchmarking", + "frame-system-rpc-runtime-api", + "hex-literal", + "kusama-runtime", + "orml-tokens", + "orml-traits", + "pallet-assets", + "pallet-assets-registry", + "pallet-aura", + "pallet-authorship", + "pallet-balances", + "pallet-call-filter", + "pallet-collator-selection", + "pallet-collective", + "pallet-currency-factory", + "pallet-democracy 4.0.0-dev", + "pallet-governance-registry", + "pallet-indices", + "pallet-membership", + "pallet-oracle", + "pallet-randomness-collective-flip", + "pallet-scheduler", + "pallet-session", + "pallet-sudo", + "pallet-timestamp", + "pallet-transaction-payment", + "pallet-transaction-payment-rpc-runtime-api", + "pallet-treasury", + "pallet-utility", + "pallet-vault", + "pallet-xcm", + "parachain-info", + "parity-scale-codec", + "paste 1.0.6", + "polkadot-core-primitives", + "polkadot-parachain", + "polkadot-primitives", + "polkadot-runtime-parachains", + "primitives", + "scale-info", + "smallvec 1.8.0", + "sp-api", + "sp-block-builder", + "sp-consensus-aura", + "sp-core", + "sp-inherents", + "sp-io", + "sp-offchain", + "sp-runtime", + "sp-session", + "sp-std", + "sp-transaction-pool", + "sp-version", + "xcm", + "xcm-builder", + "xcm-emulator", + "xcm-executor", +] + [[package]] name = "lock_api" version = "0.3.4" @@ -14193,6 +14273,30 @@ dependencies = [ "xcm-executor", ] +[[package]] +name = "xcm-emulator" +version = "0.1.0" +source = "git+https://github.com/shaunxw/xcm-simulator?rev=a250ffc998bac4831c5692c591dee7bc13f3aead#a250ffc998bac4831c5692c591dee7bc13f3aead" +dependencies = [ + "cumulus-pallet-dmp-queue", + "cumulus-pallet-parachain-system", + "cumulus-pallet-xcmp-queue", + "cumulus-primitives-core", + "cumulus-primitives-parachain-inherent", + "cumulus-test-relay-sproof-builder", + "frame-support", + "frame-system", + "parachain-info", + "parity-scale-codec", + "paste 1.0.6", + "polkadot-primitives", + "polkadot-runtime-parachains", + "sp-io", + "sp-std", + "xcm", + "xcm-executor", +] + [[package]] name = "xcm-executor" version = "0.9.16" diff --git a/Cargo.toml b/Cargo.toml index b16dc328bce..128c3124bea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,14 +17,15 @@ composable-node = { path = "node", features = ["composable", "dali"] } color-eyre = { version = "0.5.11", default-features = false } [features] -runtime-benchmarks = ["composable-node/runtime-benchmarks"] -std = ["composable-node/std"] +runtime-benchmarks = [ "composable-node/runtime-benchmarks" ] +std = [ "composable-node/std" ] +local-integration-tests = [] [workspace] exclude = ["frame/transaction-fee"] members = [ "frame/*", - + "integration-tests/local-integration-tests", "node", "runtime/common", diff --git a/Makefile.toml b/Makefile.toml index aaa1f7870ef..2c8a8a8c969 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -28,4 +28,11 @@ script = ''' cargo run --release -- --version cd ../polkadot && cargo run --release -- --version && pwd && cd ../composable cd scripts/polkadot-launch && yarn && yarn composable +''' + +[tasks.run-local-integration-tests] +workspace=false +script=''' +# we cannot use toolchain setting as different parts of codebase require different compiler +cargo +stable-x86_64-unknown-linux-gnu test --package local-integration-tests --features local-integration-tests ''' \ No newline at end of file diff --git a/docs/rpc.md b/docs/custom-rpcs.md similarity index 87% rename from docs/rpc.md rename to docs/custom-rpcs.md index 0302d622f36..1c3432c45da 100644 --- a/docs/rpc.md +++ b/docs/custom-rpcs.md @@ -330,15 +330,15 @@ Notes: Technically, it is possible to define `at` anywhere in the RPC definition, but putting it last for all of them makes the RPCs simpler and more consistent. -* If this is a preexisting pallet, they are most likely already defined in the type definitions for `crowdloanRewards` (for reasons that don't need to be covered in this document) and can just be moved over to this file. +* If this is a preexisting pallet, the types for it are most likely already defined in the type definitions for `crowdloanRewards` (for reasons that don't need to be covered in this document) and can just be moved over to this file. Even if there are no types to declare, still define an empty object or else everything will explode. ### Tests -Create a folder here: `integration-tests/runtime-tests/src/tests/rpc/pallet-name` +Create a folder here (if it doesn't already exist): `integration-tests/runtime-tests/test/tests/pallet-name` -And then within that folder, create a file `rpcPalletName.ts` with the following structure: +And then within that folder, create a file `rpcPalletNameTests.ts` with the following structure: ```typescript /* eslint-disable no-trailing-spaces */ @@ -346,47 +346,30 @@ import { /* any custom defined types that are needed for the RPC */ } from '@com import { expect } from 'chai'; -export class RpcPalletNameTests { - /** - * - */ - public static runRpcPalletNameTests() { - describe('rpc.palletName.functionName Tests', function () { - it('STUB', async () => { - const result = await RpcPalletNameTests.rpcPalletNameTest(/* parameters */); - // see note below about bignumbers - // (this is just an example assertion) - expect(result).to.be.a["bignumber"].that.equals('0'); - }); - }); - } +describe('query.palletName.account Tests', function() { + // Set timeout to 1 minute. + this.timeout(60*1000); // <- increaase this if tests are timing out + // repeat this block as needed for every test case defined in the class below. + it('rpc.palletName.functionName Tests', async function() { + await RpcPalletNameTests.rpcPalletNameFunctionNameTest(); + }); +}); + + +export class RpcPalletNameTests { /** * */ - private static async rpcPalletNameTest(/* parameters */) { + public static async rpcPalletNameFunctionNameTest() { // api is a global variable - return await api.rpc.palletName.functionName(/* parameters */); + const result = await api.rpc.palletName.functionName(/* parameters */); + + // see note below about bignumbers + // (this is just an example assertion) + expect(result).to.be.a["bignumber"].that.equals('0'); } } - -// Uncomment to debug -// RpcPalletNameTests.runRpcPalletNameTests(); -``` - -Finally, in `integration-tests/runtime-tests/src/test.ts`, import the above class and add it's tests to the `RPC Tests` test suite: - -```typescript -// ...stub... -import { RpcPalletNameTests } from '@composable/tests/rpc/palletName/rpcPalletNameTests'; // <- add this - -describe('Picasso Runtime Tests', function () { - // ...stub... - describe('RPC Tests', function () { - // ...stub... - RpcPalletNameTests.runRpcPalletNameTests() // <- add this - }); -}); ``` Notes: diff --git a/integration-tests/Cargo.toml b/integration-tests/local-integration-tests/Cargo.toml similarity index 89% rename from integration-tests/Cargo.toml rename to integration-tests/local-integration-tests/Cargo.toml index 449918abcab..44d3f167178 100644 --- a/integration-tests/Cargo.toml +++ b/integration-tests/local-integration-tests/Cargo.toml @@ -1,5 +1,6 @@ [package] -name = "integration-tests" +name = "local-integration-tests" +description="Local in memory(no OS handles opened) integrations tests via simulator. It may take time as it builds several runtimes as has direct dependnency on runtime configuration" version = "0.1.0" edition = "2021" @@ -56,16 +57,16 @@ orml-traits = { git = "https://github.com/open-web3-stack/open-runtime-module-li smallvec = "1.6.1" # local modules -common = { path = "../runtime/common", default-features = false } -primitives = { path = "../runtime/primitives", default-features = false } -oracle = { package = "pallet-oracle", path = "../frame/oracle", default-features = false } -vault = { package = "pallet-vault", path = "../frame/vault", default-features = false } -currency-factory = { package = "pallet-currency-factory", path = "../frame/currency-factory", default-features = false } -composable-traits = { path = "../frame/composable-traits", default-features = false } -call-filter = { package = "pallet-call-filter", path = "../frame/call-filter", default-features = false } -assets-registry = { package = "pallet-assets-registry", path = "../frame/assets-registry", default-features = false, optional = true } -governance-registry = { package = "pallet-governance-registry", path = "../frame/governance-registry", default-features = false, optional = true } -assets = { package = "pallet-assets", path = "../frame/assets", default-features = false, optional = true } +common = { path = "../../runtime/common", default-features = false } +primitives = { path = "../../runtime/primitives", default-features = false } +oracle = { package = "pallet-oracle", path = "../../frame/oracle", default-features = false } +vault = { package = "pallet-vault", path = "../../frame/vault", default-features = false } +currency-factory = { package = "pallet-currency-factory", path = "../../frame/currency-factory", default-features = false } +composable-traits = { path = "../../frame/composable-traits", default-features = false } +call-filter = { package = "pallet-call-filter", path = "../../frame/call-filter", default-features = false } +assets-registry = { package = "pallet-assets-registry", path = "../../frame/assets-registry", default-features = false, optional = true } +governance-registry = { package = "pallet-governance-registry", path = "../../frame/governance-registry", default-features = false, optional = true } +assets = { package = "pallet-assets", path = "../../frame/assets", default-features = false, optional = true } # Used for the node template's RPCs system-rpc-runtime-api = { package = "frame-system-rpc-runtime-api", git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16", default-features = false } @@ -101,19 +102,20 @@ sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0 # added on top of runtime for emulation of network -paste = "1.0.5" +paste = "1.0.6" polkadot-core-primitives = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.16", default-features = false } xcm-emulator = { git = "https://github.com/shaunxw/xcm-simulator", rev = "a250ffc998bac4831c5692c591dee7bc13f3aead", default-features = false } kusama-runtime = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.16", default-features = false } polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.16", default-features = false } polkadot-runtime-parachains = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.16", default-features = false } -dali-runtime = { package = "dali-runtime", path = "../runtime/dali", default-features = false } +dali-runtime = { package = "dali-runtime", path = "../../runtime/dali", default-features = false } [dev-dependencies] env_logger = "0.9.0" [features] -default = ["std", "develop"] +local-integration-tests = [] +default = ["std", "develop", "local-integration-tests"] std = [ "codec/std", "sp-api/std", diff --git a/integration-tests/README.md b/integration-tests/local-integration-tests/README.md similarity index 100% rename from integration-tests/README.md rename to integration-tests/local-integration-tests/README.md diff --git a/integration-tests/dex-messages.plantuml b/integration-tests/local-integration-tests/dex-messages.plantuml similarity index 100% rename from integration-tests/dex-messages.plantuml rename to integration-tests/local-integration-tests/dex-messages.plantuml diff --git a/integration-tests/src/cross_chain_transfer.rs b/integration-tests/local-integration-tests/src/cross_chain_transfer.rs similarity index 96% rename from integration-tests/src/cross_chain_transfer.rs rename to integration-tests/local-integration-tests/src/cross_chain_transfer.rs index 663127c7683..baa02ff7c1b 100644 --- a/integration-tests/src/cross_chain_transfer.rs +++ b/integration-tests/local-integration-tests/src/cross_chain_transfer.rs @@ -226,7 +226,7 @@ fn transfer_insufficient_amount_should_fail() { /// Acala's tests #[test] #[ignore] -fn transfer_from_relay_chain_deposit_to_treasury_if_below_ed() { +fn transfer_from_relay_chain_deposit_to_treasury_if_below_existential_deposit() { KusamaRelay::execute_with(|| { assert_ok!(kusama_runtime::XcmPallet::reserve_transfer_assets( kusama_runtime::Origin::signed(ALICE.into()), @@ -347,27 +347,39 @@ fn xcm_transfer_execution_barrier_trader_works() { }); } +/// source: Acala #[test] -#[ignore] -fn subscribe_version_notify_works() { - // relay chain subscribe version notify of para chain - KusamaRelay::execute_with(|| { - let r = pallet_xcm::Pallet::::force_subscribe_version_notify( - kusama_runtime::Origin::root(), - Box::new(Parachain(PICASSO_PARA_ID).into().into()), +fn para_chain_subscribe_version_notify_of_sibling_chain() { + Picasso::execute_with(|| { + let r = pallet_xcm::Pallet::::force_subscribe_version_notify( + picasso_runtime::Origin::root(), + Box::new((Parent, Parachain(DALI_PARA_ID)).into()), ); assert_ok!(r); }); - KusamaRelay::execute_with(|| { - kusama_runtime::System::assert_has_event(kusama_runtime::Event::XcmPallet( - pallet_xcm::Event::SupportedVersionChanged( - MultiLocation { parents: 0, interior: X1(Parachain(PICASSO_PARA_ID)) }, - 2, - ), - )); + Picasso::execute_with(|| { + assert!(picasso_runtime::System::events().iter().any(|r| matches!( + r.event, + picasso_runtime::Event::XcmpQueue(cumulus_pallet_xcmp_queue::Event::XcmpMessageSent( + Some(_) + )) + ))); }); + Dali::execute_with(|| { + assert!(dali_runtime::System::events().iter().any(|r| matches!( + r.event, + picasso_runtime::Event::XcmpQueue(cumulus_pallet_xcmp_queue::Event::XcmpMessageSent( + Some(_) + )) | picasso_runtime::Event::XcmpQueue(cumulus_pallet_xcmp_queue::Event::Success( + Some(_) + )) + ))); + }); +} - // para chain subscribe version notify of relay chain +/// source: Acala +#[test] +fn para_chain_subscribe_version_notify_of_relay_chain() { Picasso::execute_with(|| { let r = pallet_xcm::Pallet::::force_subscribe_version_notify( picasso_runtime::Origin::root(), @@ -383,31 +395,24 @@ fn subscribe_version_notify_works() { ), )); }); +} - // para chain subscribe version notify of sibling chain - Picasso::execute_with(|| { - let r = pallet_xcm::Pallet::::force_subscribe_version_notify( - picasso_runtime::Origin::root(), - Box::new((Parent, Parachain(PICASSO_PARA_ID)).into()), +/// source: Acala +#[test] +fn relay_chain_subscribe_version_notify_of_para_chain() { + KusamaRelay::execute_with(|| { + let r = pallet_xcm::Pallet::::force_subscribe_version_notify( + kusama_runtime::Origin::root(), + Box::new(Parachain(PICASSO_PARA_ID).into().into()), ); assert_ok!(r); }); - Picasso::execute_with(|| { - assert!(picasso_runtime::System::events().iter().any(|r| matches!( - r.event, - picasso_runtime::Event::XcmpQueue(cumulus_pallet_xcmp_queue::Event::XcmpMessageSent( - Some(_) - )) - ))); - }); - Dali::execute_with(|| { - assert!(dali_runtime::System::events().iter().any(|r| matches!( - r.event, - picasso_runtime::Event::XcmpQueue(cumulus_pallet_xcmp_queue::Event::XcmpMessageSent( - Some(_) - )) | picasso_runtime::Event::XcmpQueue(cumulus_pallet_xcmp_queue::Event::Success( - Some(_) - )) - ))); + KusamaRelay::execute_with(|| { + kusama_runtime::System::assert_has_event(kusama_runtime::Event::XcmPallet( + pallet_xcm::Event::SupportedVersionChanged( + MultiLocation { parents: 0, interior: X1(Parachain(PICASSO_PARA_ID)) }, + 2, + ), + )); }); } diff --git a/integration-tests/src/kusama_test_net.rs b/integration-tests/local-integration-tests/src/kusama_test_net.rs similarity index 93% rename from integration-tests/src/kusama_test_net.rs rename to integration-tests/local-integration-tests/src/kusama_test_net.rs index 4732874547c..53e39f79bc8 100644 --- a/integration-tests/src/kusama_test_net.rs +++ b/integration-tests/local-integration-tests/src/kusama_test_net.rs @@ -18,6 +18,8 @@ decl_test_parachain! { pub struct Picasso { Runtime = picasso_runtime::Runtime, Origin = picasso_runtime::Origin, + XcmpMessageHandler = picasso_runtime::XcmpQueue, + DmpMessageHandler = picasso_runtime::DmpQueue, new_ext = picasso_ext(PICASSO_PARA_ID), } } @@ -28,6 +30,8 @@ decl_test_parachain! { pub struct Dali { Runtime = dali_runtime::Runtime, Origin = dali_runtime::Origin, + XcmpMessageHandler = dali_runtime::XcmpQueue, + DmpMessageHandler = dali_runtime::DmpQueue, new_ext = picasso_ext(DALI_PARA_ID), } } @@ -35,7 +39,7 @@ decl_test_parachain! { decl_test_relay_chain! { pub struct KusamaRelay { Runtime = kusama_runtime::Runtime, - XcmConfig = kusama_runtime::XcmConfig, + XcmConfig = kusama_runtime::xcm_config::XcmConfig, new_ext = kusama_ext(), } } @@ -56,14 +60,15 @@ decl_test_network! { fn default_parachains_host_configuration() -> HostConfiguration { HostConfiguration { - validation_upgrade_frequency: 1_u32, - validation_upgrade_delay: 1, + validation_upgrade_cooldown: 1_u32, + validation_upgrade_delay: 5, code_retention_period: 1200, max_code_size: MAX_CODE_SIZE, max_pov_size: MAX_POV_SIZE, max_head_data_size: 32 * 1024, group_rotation_frequency: 20, chain_availability_period: 4, + minimum_validation_upgrade_delay: 5, thread_availability_period: 4, max_upward_queue_count: 8, max_upward_queue_size: 1024 * 1024, diff --git a/integration-tests/local-integration-tests/src/lib.rs b/integration-tests/local-integration-tests/src/lib.rs new file mode 100644 index 00000000000..3886ee78bdd --- /dev/null +++ b/integration-tests/local-integration-tests/src/lib.rs @@ -0,0 +1,40 @@ +#![deny( + unused_imports, + clippy::useless_conversion, + bad_style, + bare_trait_objects, + const_err, + improper_ctypes, + non_shorthand_field_patterns, + no_mangle_generic_items, + overflowing_literals, + path_statements, + patterns_in_fns_without_body, + private_in_public, + unconditional_recursion, + unused_allocation, + unused_comparisons, + unused_parens, + while_true, + trivial_casts, + trivial_numeric_casts, + unused_extern_crates +)] + +/// this must be singleton +#[cfg(test)] +pub fn env_logger_init() { + let _ = env_logger::builder().is_test(true).try_init(); +} + +#[cfg(test)] +mod kusama_test_net; + +#[cfg(test)] +mod xcm_tests; + +#[cfg(test)] +mod cross_chain_transfer; + +#[cfg(test)] +mod runtime_tests; diff --git a/integration-tests/src/runtime_tests.rs b/integration-tests/local-integration-tests/src/runtime_tests.rs similarity index 100% rename from integration-tests/src/runtime_tests.rs rename to integration-tests/local-integration-tests/src/runtime_tests.rs diff --git a/integration-tests/src/xcm_tests.rs b/integration-tests/local-integration-tests/src/xcm_tests.rs similarity index 95% rename from integration-tests/src/xcm_tests.rs rename to integration-tests/local-integration-tests/src/xcm_tests.rs index 58b8fc7cfb8..01b17325397 100644 --- a/integration-tests/src/xcm_tests.rs +++ b/integration-tests/local-integration-tests/src/xcm_tests.rs @@ -11,7 +11,7 @@ use common::AccountId; use composable_traits::assets::{RemoteAssetRegistry, XcmAssetLocation}; use cumulus_primitives_core::ParaId; use dali_runtime as picasso_runtime; -use kusama_runtime::*; +use picasso_runtime::XcmConfig; use primitives::currency::CurrencyId; use sp_runtime::traits::AccountIdConversion; use support::assert_ok; @@ -106,9 +106,10 @@ fn send_remark() { Dali::execute_with(|| { use dali_runtime::{Event, System}; - assert!(System::events() - .iter() - .any(|r| matches!(r.event, Event::System(frame_system::Event::Remarked(_, _))))); + assert!(System::events().iter().any(|r| matches!( + r.event, + Event::System(frame_system::Event::Remarked { sender: _, hash: _ }) + ))); }); } diff --git a/integration-tests/src/lib.rs b/integration-tests/src/lib.rs deleted file mode 100644 index 81bc3c04696..00000000000 --- a/integration-tests/src/lib.rs +++ /dev/null @@ -1,17 +0,0 @@ -/// this must be singleton -#[cfg(test)] -pub fn env_logger_init() { - let _ = env_logger::builder().is_test(true).try_init(); -} - -#[cfg(test)] -mod kusama_test_net; - -#[cfg(test)] -mod xcm_tests; - -#[cfg(test)] -mod cross_chain_transfer; - -#[cfg(test)] -mod runtime_tests; diff --git a/runtime/dali/Cargo.toml b/runtime/dali/Cargo.toml index 1b00221005d..c45c5c8e2af 100644 --- a/runtime/dali/Cargo.toml +++ b/runtime/dali/Cargo.toml @@ -133,6 +133,7 @@ simnode-apis = { package = "simnode-runtime-apis", git = "https://github.com/pol substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.16" } [features] +local-integration-tests = [] default = ["std"] std = [ "codec/std", diff --git a/runtime/dali/build.rs b/runtime/dali/build.rs index 9b53d2457df..8a81509d8c4 100644 --- a/runtime/dali/build.rs +++ b/runtime/dali/build.rs @@ -1,9 +1,20 @@ use substrate_wasm_builder::WasmBuilder; fn main() { - WasmBuilder::new() - .with_current_project() - .export_heap_base() - .import_memory() - .build() + // NOTE: could make reproducible clean builds like next: + // - remove this file + // - put relevant rust code behind cfg target wasm into this package + // - create separate native package which will include bytes of WASM_BINARY (make it read from + // target depending on cfg of build debug/release) + // - make cargo make to build this package for wasm target with all proper env vars + // - make sure that CI/CD gets wasm only via make file to make builds more reproducible + // - document that maximal reproducability is possible if to build in layered docker + #[cfg(not(feature = "local-integration-tests"))] + { + WasmBuilder::new() + .with_current_project() + .export_heap_base() + .import_memory() + .build() + } }