Skip to content

Commit

Permalink
Add emulated tests for the Coretime Interface calls to ensure suffici…
Browse files Browse the repository at this point in the history
…ent weights (paritytech#2704)

Add emulated test cases for the coretime chain.

This tests the calls sent across the `CoretimeInterface` and ensures the
weights are sufficient.
  • Loading branch information
seadanda authored Sep 12, 2024
1 parent 4653c37 commit cd69f20
Show file tree
Hide file tree
Showing 11 changed files with 484 additions and 12 deletions.
14 changes: 10 additions & 4 deletions Cargo.lock

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

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "coretime-rococo-emulated-chain"
version = "0.0.0"
version = "0.1.0"
authors.workspace = true
edition.workspace = true
license = "Apache-2.0"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "coretime-westend-emulated-chain"
version = "0.0.0"
version = "0.1.0"
authors.workspace = true
edition.workspace = true
license = "Apache-2.0"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "coretime-rococo-integration-tests"
version = "0.1.0"
version = "0.0.0"
authors.workspace = true
edition.workspace = true
license = "Apache-2.0"
Expand All @@ -12,16 +12,19 @@ publish = false
# Substrate
frame-support = { workspace = true }
pallet-balances = { workspace = true }
pallet-broker = { workspace = true, default-features = true }
pallet-message-queue = { workspace = true }
pallet-identity = { workspace = true }
sp-runtime = { workspace = true }

# Polkadot
polkadot-runtime-common = { workspace = true, default-features = true }
polkadot-runtime-parachains = { workspace = true, default-features = true }
rococo-runtime-constants = { workspace = true, default-features = true }
xcm = { workspace = true }
xcm-executor = { workspace = true }

# Cumulus
cumulus-pallet-parachain-system = { workspace = true, default-features = true }
emulated-integration-tests-common = { workspace = true }
rococo-system-emulated-network = { workspace = true }
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ mod imports {

// Cumulus
pub use emulated_integration_tests_common::xcm_emulator::{
assert_expected_events, bx, TestExt,
assert_expected_events, bx, Chain, Parachain, TestExt,
};
pub use rococo_system_emulated_network::{
coretime_rococo_emulated_chain::{
coretime_rococo_runtime::ExistentialDeposit as CoretimeRococoExistentialDeposit,
CoretimeRococoParaPallet as CoretimeRococoPallet,
},
CoretimeRococoPara as CoretimeRococo, CoretimeRococoParaReceiver as CoretimeRococoReceiver,
CoretimeRococoParaSender as CoretimeRococoSender,
CoretimeRococoParaSender as CoretimeRococoSender, RococoRelay as Rococo,
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::imports::*;
use frame_support::traits::OnInitialize;
use pallet_broker::{ConfigRecord, Configuration, CoreAssignment, CoreMask, ScheduleItem};
use rococo_runtime_constants::system_parachain::coretime::TIMESLICE_PERIOD;
use sp_runtime::Perbill;

#[test]
fn transact_hardcoded_weights_are_sane() {
// There are three transacts with hardcoded weights sent from the Coretime Chain to the Relay
// Chain across the CoretimeInterface which are triggered at various points in the sales cycle.
// - Request core count - triggered directly by `start_sales` or `request_core_count`
// extrinsics.
// - Request revenue info - triggered when each timeslice is committed.
// - Assign core - triggered when an entry is encountered in the workplan for the next
// timeslice.

// RuntimeEvent aliases to avoid warning from usage of qualified paths in assertions due to
// <https://github.com/rust-lang/rust/issues/86935>
type CoretimeEvent = <CoretimeRococo as Chain>::RuntimeEvent;
type RelayEvent = <Rococo as Chain>::RuntimeEvent;

// Reserve a workload, configure broker and start sales.
CoretimeRococo::execute_with(|| {
// Hooks don't run in emulated tests - workaround as we need `on_initialize` to tick things
// along and have no concept of time passing otherwise.
<CoretimeRococo as CoretimeRococoPallet>::Broker::on_initialize(
<CoretimeRococo as Chain>::System::block_number(),
);

let coretime_root_origin = <CoretimeRococo as Chain>::RuntimeOrigin::root();

// Create and populate schedule with the worst case assignment on this core.
let mut schedule = Vec::new();
for i in 0..27 {
schedule.push(ScheduleItem {
mask: CoreMask::void().set(i),
assignment: CoreAssignment::Task(2000 + i),
})
}

assert_ok!(<CoretimeRococo as CoretimeRococoPallet>::Broker::reserve(
coretime_root_origin.clone(),
schedule.try_into().expect("Vector is within bounds."),
));

// Configure broker and start sales.
let config = ConfigRecord {
advance_notice: 1,
interlude_length: 1,
leadin_length: 2,
region_length: 1,
ideal_bulk_proportion: Perbill::from_percent(40),
limit_cores_offered: None,
renewal_bump: Perbill::from_percent(2),
contribution_timeout: 1,
};
assert_ok!(<CoretimeRococo as CoretimeRococoPallet>::Broker::configure(
coretime_root_origin.clone(),
config
));
assert_ok!(<CoretimeRococo as CoretimeRococoPallet>::Broker::start_sales(
coretime_root_origin,
100,
0
));
assert_eq!(
pallet_broker::Status::<<CoretimeRococo as Chain>::Runtime>::get()
.unwrap()
.core_count,
1
);

assert_expected_events!(
CoretimeRococo,
vec![
CoretimeEvent::Broker(
pallet_broker::Event::ReservationMade { .. }
) => {},
CoretimeEvent::Broker(
pallet_broker::Event::CoreCountRequested { core_count: 1 }
) => {},
CoretimeEvent::ParachainSystem(
cumulus_pallet_parachain_system::Event::UpwardMessageSent { .. }
) => {},
]
);
});

// Check that the request_core_count message was processed successfully. This will fail if the
// weights are misconfigured.
Rococo::execute_with(|| {
Rococo::assert_ump_queue_processed(true, Some(CoretimeRococo::para_id()), None);

assert_expected_events!(
Rococo,
vec![
RelayEvent::MessageQueue(
pallet_message_queue::Event::Processed { success: true, .. }
) => {},
]
);
});

// Keep track of the relay chain block number so we can fast forward while still checking the
// right block.
let mut block_number_cursor = Rococo::ext_wrapper(<Rococo as Chain>::System::block_number);

let config = CoretimeRococo::ext_wrapper(|| {
Configuration::<<CoretimeRococo as Chain>::Runtime>::get()
.expect("Pallet was configured earlier.")
});

// Now run up to the block before the sale is rotated.
while block_number_cursor < TIMESLICE_PERIOD - config.advance_notice - 1 {
CoretimeRococo::execute_with(|| {
// Hooks don't run in emulated tests - workaround.
<CoretimeRococo as CoretimeRococoPallet>::Broker::on_initialize(
<CoretimeRococo as Chain>::System::block_number(),
);
});

Rococo::ext_wrapper(|| {
block_number_cursor = <Rococo as Chain>::System::block_number();
});
}

// In this block we trigger assign core.
CoretimeRococo::execute_with(|| {
// Hooks don't run in emulated tests - workaround.
<CoretimeRococo as CoretimeRococoPallet>::Broker::on_initialize(
<CoretimeRococo as Chain>::System::block_number(),
);

assert_expected_events!(
CoretimeRococo,
vec![
CoretimeEvent::Broker(
pallet_broker::Event::SaleInitialized { .. }
) => {},
CoretimeEvent::Broker(
pallet_broker::Event::CoreAssigned { .. }
) => {},
CoretimeEvent::ParachainSystem(
cumulus_pallet_parachain_system::Event::UpwardMessageSent { .. }
) => {},
]
);
});

// Check that the assign_core message was processed successfully.
// This will fail if the weights are misconfigured.
Rococo::execute_with(|| {
Rococo::assert_ump_queue_processed(true, Some(CoretimeRococo::para_id()), None);

assert_expected_events!(
Rococo,
vec![
RelayEvent::MessageQueue(
pallet_message_queue::Event::Processed { success: true, .. }
) => {},
RelayEvent::Coretime(
polkadot_runtime_parachains::coretime::Event::CoreAssigned { .. }
) => {},
]
);
});

// In this block we trigger request revenue.
CoretimeRococo::execute_with(|| {
// Hooks don't run in emulated tests - workaround.
<CoretimeRococo as CoretimeRococoPallet>::Broker::on_initialize(
<CoretimeRococo as Chain>::System::block_number(),
);

assert_expected_events!(
CoretimeRococo,
vec![
CoretimeEvent::ParachainSystem(
cumulus_pallet_parachain_system::Event::UpwardMessageSent { .. }
) => {},
]
);
});

// Check that the request_revenue_info_at message was processed successfully.
// This will fail if the weights are misconfigured.
Rococo::execute_with(|| {
Rococo::assert_ump_queue_processed(true, Some(CoretimeRococo::para_id()), None);

assert_expected_events!(
Rococo,
vec![
RelayEvent::MessageQueue(
pallet_message_queue::Event::Processed { success: true, .. }
) => {},
]
);
});

// Here we receive and process the notify_revenue XCM with zero revenue.
CoretimeRococo::execute_with(|| {
// Hooks don't run in emulated tests - workaround.
<CoretimeRococo as CoretimeRococoPallet>::Broker::on_initialize(
<CoretimeRococo as Chain>::System::block_number(),
);

assert_expected_events!(
CoretimeRococo,
vec![
CoretimeEvent::MessageQueue(
pallet_message_queue::Event::Processed { success: true, .. }
) => {},
// Zero revenue in first timeslice so history is immediately dropped.
CoretimeEvent::Broker(
pallet_broker::Event::HistoryDropped { when: 0, revenue: 0 }
) => {},
]
);
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
// limitations under the License.

mod claim_assets;
mod coretime_interface;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "coretime-westend-integration-tests"
version = "0.1.0"
version = "0.0.0"
authors.workspace = true
edition.workspace = true
license = "Apache-2.0"
Expand All @@ -12,16 +12,19 @@ publish = false
# Substrate
frame-support = { workspace = true }
pallet-balances = { workspace = true }
pallet-broker = { workspace = true, default-features = true }
pallet-message-queue = { workspace = true }
pallet-identity = { workspace = true }
sp-runtime = { workspace = true }

# Polkadot
polkadot-runtime-common = { workspace = true, default-features = true }
polkadot-runtime-parachains = { workspace = true, default-features = true }
westend-runtime-constants = { workspace = true, default-features = true }
xcm = { workspace = true }
xcm-executor = { workspace = true }

# Cumulus
cumulus-pallet-parachain-system = { workspace = true, default-features = true }
emulated-integration-tests-common = { workspace = true }
westend-system-emulated-network = { workspace = true }
Loading

0 comments on commit cd69f20

Please sign in to comment.