Remove sleep from tests (#4639)

* Remove sleep and use polkadot test service

Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>

* updates

Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>

* Fix other tests

Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>

* Run metrics tests separately

Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>

* copy some substrate utilities

Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>

* update runtime metric test

Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>

* Remove sleep from cli tests

Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>

* cargo

Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>

* Polkadot companion for Substrate#10463 (#4519)

* Grandpa and Beefy protocol names include chain id

Signed-off-by: acatangiu <adrian@parity.io>

* chain_spec: include fork id

* use simplified protocol name

* fix after merge

* avoid using hash default, even for protocol names

* update lockfile for substrate

Co-authored-by: parity-processbot <>

* configuration: Update upgrade validation delay doc (#4662)

* typo

Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>

* review feedback

Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>

* cargo lock

Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>

* use testnet profile

Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>

* Don't run with runtime-benchmark feature

Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>

* conditional compile up one level

Signed-off-by: Andrei Sandu <andrei-mihail@parity.io>

Co-authored-by: Sergei Shulepov <sergei@parity.io>
This commit is contained in:
sandreim
2022-01-10 13:00:46 +02:00
committed by GitHub
parent c342e99261
commit 0da05cac26
16 changed files with 234 additions and 105 deletions
+86 -49
View File
@@ -13,58 +13,95 @@
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
#![cfg(feature = "runtime-metrics")]
use assert_cmd::cargo::cargo_bin;
use std::{convert::TryInto, process::Command, thread, time::Duration};
use tempfile::tempdir;
#[test]
#[cfg(unix)]
fn runtime_can_publish_metrics() {
use hyper::{Client, Uri};
use nix::{
sys::signal::{kill, Signal::SIGINT},
unistd::Pid,
//! Polkadot runtime metrics integration test.
use hyper::{Client, Uri};
use polkadot_test_service::{node_config, run_validator_node, test_prometheus_config};
use primitives::v1::metric_definitions::PARACHAIN_INHERENT_DATA_BITFIELDS_PROCESSED;
use sc_client_api::{execution_extensions::ExecutionStrategies, ExecutionStrategy};
use sp_keyring::AccountKeyring::*;
use std::{collections::HashMap, convert::TryFrom};
const DEFAULT_PROMETHEUS_PORT: u16 = 9616;
#[substrate_test_utils::test]
async fn runtime_can_publish_metrics() {
let mut alice_config =
node_config(|| {}, tokio::runtime::Handle::current(), Alice, Vec::new(), true);
// Enable Prometheus metrics for Alice.
alice_config.prometheus_config = Some(test_prometheus_config(DEFAULT_PROMETHEUS_PORT));
let mut builder = sc_cli::LoggerBuilder::new("");
// Enable profiling with `wasm_tracing` target.
builder.with_profiling(Default::default(), String::from("wasm_tracing=trace"));
// Setup the runtime metrics provider.
crate::logger_hook()(&mut builder, &alice_config);
// Override default native strategy, runtime metrics are available only in the wasm runtime.
alice_config.execution_strategies = ExecutionStrategies {
syncing: ExecutionStrategy::AlwaysWasm,
importing: ExecutionStrategy::AlwaysWasm,
block_construction: ExecutionStrategy::AlwaysWasm,
offchain_worker: ExecutionStrategy::AlwaysWasm,
other: ExecutionStrategy::AlwaysWasm,
};
use std::convert::TryFrom;
const RUNTIME_METRIC_NAME: &str = "polkadot_parachain_inherent_data_bitfields_processed";
const DEFAULT_PROMETHEUS_PORT: u16 = 9615;
builder.init().expect("Failed to set up the logger");
// Start validator Alice.
let alice = run_validator_node(alice_config, None);
let bob_config =
node_config(|| {}, tokio::runtime::Handle::current(), Bob, vec![alice.addr.clone()], true);
// Start validator Bob.
let _bob = run_validator_node(bob_config, None);
// Wait for Alice to author two blocks.
alice.wait_for_blocks(2).await;
let metrics_uri = format!("http://localhost:{}/metrics", DEFAULT_PROMETHEUS_PORT);
let metrics = scrape_prometheus_metrics(&metrics_uri).await;
// Start the node with tracing enabled and forced wasm runtime execution.
let cmd = Command::new(cargo_bin("polkadot"))
// Runtime metrics require this trace target.
.args(&["--tracing-targets", "wasm_tracing=trace"])
.args(&["--execution", "wasm"])
.args(&["--dev", "-d"])
.arg(tempdir().expect("failed to create temp dir.").path())
.spawn()
.expect("failed to start the node process");
// Enough time to author one block.
thread::sleep(Duration::from_secs(30));
let runtime = tokio::runtime::Runtime::new().expect("failed to create tokio runtime");
runtime.block_on(async {
let client = Client::new();
let res = client
.get(Uri::try_from(&metrics_uri).expect("bad URI"))
.await
.expect("get request failed");
let body = String::from_utf8(
hyper::body::to_bytes(res).await.expect("can't get body as bytes").to_vec(),
)
.expect("body is not an UTF8 string");
// Time to die.
kill(Pid::from_raw(cmd.id().try_into().unwrap()), SIGINT)
.expect("failed to kill the node process");
// If the node has authored at least 1 block this should pass.
assert!(body.contains(&RUNTIME_METRIC_NAME));
});
// There should be at least 1 bitfield processed by now.
assert!(
*metrics
.get(&PARACHAIN_INHERENT_DATA_BITFIELDS_PROCESSED.name.to_owned())
.unwrap() > 1
);
}
async fn scrape_prometheus_metrics(metrics_uri: &str) -> HashMap<String, u64> {
let res = Client::new()
.get(Uri::try_from(metrics_uri).expect("bad URI"))
.await
.expect("GET request failed");
// Retrieve the `HTTP` response body.
let body = String::from_utf8(
hyper::body::to_bytes(res).await.expect("can't get body as bytes").to_vec(),
)
.expect("body is not an UTF8 string");
let lines: Vec<_> = body.lines().map(|s| Ok(s.to_owned())).collect();
prometheus_parse::Scrape::parse(lines.into_iter())
.expect("Scraper failed to parse Prometheus metrics")
.samples
.into_iter()
.map(|sample| {
(
sample.metric.to_owned(),
match sample.value {
prometheus_parse::Value::Counter(value) => value as u64,
prometheus_parse::Value::Gauge(value) => value as u64,
prometheus_parse::Value::Untyped(value) => value as u64,
_ => unreachable!("unexpected metric type"),
},
)
})
.collect()
}