-
Notifications
You must be signed in to change notification settings - Fork 710
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
subsystem-bench: add regression tests for availability read and write #3311
Changes from all commits
c01894b
f71c502
733f0eb
fdc1392
815c023
0a65126
42963a9
98224fd
d98b899
5175897
a721bca
b27edaa
9136955
18a0c7e
d72a035
d161de1
ab2e179
1e59be1
b54b85d
0e4432a
3b6a3e9
2fec1c1
2657432
c037885
d46e9fa
708e002
d1b3631
282745a
f6df907
f0aea37
ff7dac3
e1e6f2d
68ec964
184eee1
f03f4a7
4abf5d8
9df54ec
3acfe18
3868962
e4f3c87
f55ae88
222f791
ddf4408
4f40d1f
0e1b59e
31a5090
732b4ba
c0e6f31
02d63b8
341c8b7
a03fd98
77f3da5
36b3f6c
ff91819
46ec768
07b4662
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,8 +23,10 @@ test-linux-stable: | |
- echo "Node index - ${CI_NODE_INDEX}. Total amount - ${CI_NODE_TOTAL}" | ||
# add experimental to features after https://github.com/paritytech/substrate/pull/14502 is merged | ||
# "upgrade_version_checks_should_work" is currently failing | ||
# Filtered by deps to exclude subsystem regression tests that we run in another job | ||
- | | ||
time cargo nextest run \ | ||
--filter-expr 'not deps(/polkadot-subsystem-bench/)' \ | ||
--workspace \ | ||
--locked \ | ||
--release \ | ||
|
@@ -69,7 +71,8 @@ test-linux-stable-runtime-benchmarks: | |
# but still want to have debug assertions. | ||
RUSTFLAGS: "-Cdebug-assertions=y -Dwarnings" | ||
script: | ||
- time cargo nextest run --workspace --features runtime-benchmarks benchmark --locked --cargo-profile testnet | ||
# Filtered by deps to exclude subsystem regression tests that we run in another job | ||
- time cargo nextest run --filter-expr 'not deps(/polkadot-subsystem-bench/)' --workspace --features runtime-benchmarks benchmark --locked --cargo-profile testnet | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why isn't this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a good question, and I wish I knew the answer. Somehow, it keeps running regression tests while |
||
|
||
# can be used to run all tests | ||
# test-linux-stable-all: | ||
|
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 |
---|---|---|
@@ -0,0 +1,113 @@ | ||
// Copyright (C) Parity Technologies (UK) Ltd. | ||
// This file is part of Polkadot. | ||
|
||
// Polkadot is free software: you can redistribute it and/or modify | ||
// it under the terms of the GNU General Public License as published by | ||
// the Free Software Foundation, either version 3 of the License, or | ||
// (at your option) any later version. | ||
|
||
// Polkadot is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
// GNU General Public License for more details. | ||
|
||
// You should have received a copy of the GNU General Public License | ||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
sandreim marked this conversation as resolved.
Show resolved
Hide resolved
|
||
//! availability-read regression tests | ||
//! | ||
//! TODO: Explain the test case after configuration adjusted to Kusama | ||
//! | ||
//! Subsystems involved: | ||
//! - availability-distribution | ||
//! - bitfield-distribution | ||
//! - availability-store | ||
|
||
use polkadot_subsystem_bench::{ | ||
availability::{benchmark_availability_write, prepare_test, TestDataAvailability, TestState}, | ||
configuration::{PeerLatency, TestConfiguration}, | ||
usage::BenchmarkUsage, | ||
}; | ||
|
||
const BENCH_COUNT: usize = 3; | ||
const WARM_UP_COUNT: usize = 20; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How many benches in practice are needed until There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Based on previous runs you never know, can be 3, can be 13. |
||
const WARM_UP_PRECISION: f64 = 0.01; | ||
|
||
fn main() -> Result<(), String> { | ||
let mut messages = vec![]; | ||
|
||
// TODO: Adjust the test configurations to Kusama values | ||
let mut config = TestConfiguration::default(); | ||
config.latency = Some(PeerLatency { mean_latency_ms: 30, std_dev: 2.0 }); | ||
config.n_validators = 1000; | ||
config.n_cores = 200; | ||
config.max_validators_per_core = 5; | ||
config.min_pov_size = 5120; | ||
config.max_pov_size = 5120; | ||
config.peer_bandwidth = 52428800; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is different than approval voting setup. It would be better to have the correct value set in default impl of config, and include a comment when we override it. |
||
config.bandwidth = 52428800; | ||
config.connectivity = 75; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why 75 ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Copied from |
||
config.num_blocks = 3; | ||
config.generate_pov_sizes(); | ||
|
||
warm_up(config.clone())?; | ||
let usage = benchmark(config.clone()); | ||
|
||
messages.extend(usage.check_network_usage(&[ | ||
("Received from peers", 4330.0, 0.05), | ||
("Sent to peers", 15900.0, 0.05), | ||
])); | ||
messages.extend(usage.check_cpu_usage(&[ | ||
("availability-distribution", 0.025, 0.05), | ||
("bitfield-distribution", 0.085, 0.05), | ||
("availability-store", 0.180, 0.05), | ||
])); | ||
|
||
if messages.is_empty() { | ||
Ok(()) | ||
} else { | ||
eprintln!("{}", messages.join("\n")); | ||
Err("Regressions found".to_string()) | ||
} | ||
} | ||
|
||
fn warm_up(config: TestConfiguration) -> Result<(), String> { | ||
println!("Warming up..."); | ||
let mut prev_run: Option<BenchmarkUsage> = None; | ||
for _ in 0..WARM_UP_COUNT { | ||
let curr = run(config.clone()); | ||
if let Some(ref prev) = prev_run { | ||
let av_distr_diff = | ||
curr.cpu_usage_diff(prev, "availability-distribution").expect("Must exist"); | ||
let bitf_distr_diff = | ||
curr.cpu_usage_diff(prev, "bitfield-distribution").expect("Must exist"); | ||
let av_store_diff = | ||
curr.cpu_usage_diff(prev, "availability-store").expect("Must exist"); | ||
if av_distr_diff < WARM_UP_PRECISION && | ||
bitf_distr_diff < WARM_UP_PRECISION && | ||
av_store_diff < WARM_UP_PRECISION | ||
{ | ||
return Ok(()) | ||
} | ||
} | ||
prev_run = Some(curr); | ||
} | ||
|
||
Err("Can't warm up".to_string()) | ||
} | ||
|
||
fn benchmark(config: TestConfiguration) -> BenchmarkUsage { | ||
println!("Benchmarking..."); | ||
let usages: Vec<BenchmarkUsage> = (0..BENCH_COUNT).map(|_| run(config.clone())).collect(); | ||
let usage = BenchmarkUsage::average(&usages); | ||
println!("{}", usage); | ||
usage | ||
} | ||
|
||
fn run(config: TestConfiguration) -> BenchmarkUsage { | ||
let mut state = TestState::new(&config); | ||
let (mut env, _protocol_config) = | ||
prepare_test(config.clone(), &mut state, TestDataAvailability::Write, false); | ||
env.runtime() | ||
.block_on(benchmark_availability_write("data_availability_write", &mut env, state)) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
// Copyright (C) Parity Technologies (UK) Ltd. | ||
// This file is part of Polkadot. | ||
|
||
// Polkadot is free software: you can redistribute it and/or modify | ||
// it under the terms of the GNU General Public License as published by | ||
// the Free Software Foundation, either version 3 of the License, or | ||
// (at your option) any later version. | ||
|
||
// Polkadot is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
// GNU General Public License for more details. | ||
|
||
// You should have received a copy of the GNU General Public License | ||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
//! availability-write regression tests | ||
//! | ||
//! TODO: Explain the test case after configuration adjusted to Kusama | ||
//! | ||
//! Subsystems involved: | ||
//! - availability-recovery | ||
|
||
use polkadot_subsystem_bench::{ | ||
availability::{ | ||
benchmark_availability_read, prepare_test, DataAvailabilityReadOptions, | ||
TestDataAvailability, TestState, | ||
}, | ||
configuration::{PeerLatency, TestConfiguration}, | ||
usage::BenchmarkUsage, | ||
}; | ||
|
||
const BENCH_COUNT: usize = 3; | ||
const WARM_UP_COUNT: usize = 10; | ||
const WARM_UP_PRECISION: f64 = 0.01; | ||
|
||
fn main() -> Result<(), String> { | ||
let mut messages = vec![]; | ||
|
||
// TODO: Adjust the test configurations to Kusama values | ||
let options = DataAvailabilityReadOptions { fetch_from_backers: true }; | ||
let mut config = TestConfiguration::default(); | ||
config.latency = Some(PeerLatency { mean_latency_ms: 100, std_dev: 1.0 }); | ||
config.n_validators = 300; | ||
config.n_cores = 20; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This value should be set to the number of block validators are expected to check per relay chain block. This depends on approval voting parameters. We should also factor in async backing, that is we'd expect to have 1 included candidate at every block. We can calibrate these in the followup PR. |
||
config.min_pov_size = 5120; | ||
config.max_pov_size = 5120; | ||
config.peer_bandwidth = 52428800; | ||
config.bandwidth = 52428800; | ||
config.num_blocks = 3; | ||
config.connectivity = 90; | ||
config.generate_pov_sizes(); | ||
|
||
warm_up(config.clone(), options.clone())?; | ||
let usage = benchmark(config.clone(), options.clone()); | ||
|
||
messages.extend(usage.check_network_usage(&[ | ||
("Received from peers", 102400.000, 0.05), | ||
("Sent to peers", 0.335, 0.05), | ||
])); | ||
messages.extend(usage.check_cpu_usage(&[("availability-recovery", 3.850, 0.05)])); | ||
|
||
if messages.is_empty() { | ||
Ok(()) | ||
} else { | ||
eprintln!("{}", messages.join("\n")); | ||
Err("Regressions found".to_string()) | ||
} | ||
} | ||
|
||
fn warm_up(config: TestConfiguration, options: DataAvailabilityReadOptions) -> Result<(), String> { | ||
println!("Warming up..."); | ||
let mut prev_run: Option<BenchmarkUsage> = None; | ||
for _ in 0..WARM_UP_COUNT { | ||
let curr = run(config.clone(), options.clone()); | ||
if let Some(ref prev) = prev_run { | ||
let diff = curr.cpu_usage_diff(prev, "availability-recovery").expect("Must exist"); | ||
if diff < WARM_UP_PRECISION { | ||
return Ok(()) | ||
} | ||
} | ||
prev_run = Some(curr); | ||
} | ||
|
||
Err("Can't warm up".to_string()) | ||
} | ||
|
||
fn benchmark(config: TestConfiguration, options: DataAvailabilityReadOptions) -> BenchmarkUsage { | ||
println!("Benchmarking..."); | ||
let usages: Vec<BenchmarkUsage> = | ||
(0..BENCH_COUNT).map(|_| run(config.clone(), options.clone())).collect(); | ||
let usage = BenchmarkUsage::average(&usages); | ||
println!("{}", usage); | ||
usage | ||
} | ||
|
||
fn run(config: TestConfiguration, options: DataAvailabilityReadOptions) -> BenchmarkUsage { | ||
let mut state = TestState::new(&config); | ||
let (mut env, _protocol_config) = | ||
prepare_test(config.clone(), &mut state, TestDataAvailability::Read(options), false); | ||
env.runtime() | ||
.block_on(benchmark_availability_read("data_availability_read", &mut env, state)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd move these to a separate pipeline, that allows for CI to provide the same hw specs as for validators and guarantee CPU/mem resources per POD.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @alvicsam
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, my bad, we aren't running the tests here 🙈 . let's address this properly in #3530
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@AndreiEres could you please add a comment above the command with a brief description why you added the filter or a link to your PR.