move tests around and add (non working) benchmark

This commit is contained in:
James Wilson
2021-07-14 15:05:09 +01:00
parent c1208b9e81
commit e34da5761f
12 changed files with 490 additions and 53 deletions
+309
View File
@@ -86,6 +86,18 @@ dependencies = [
"generic-array",
]
[[package]]
name = "bstr"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279"
dependencies = [
"lazy_static",
"memchr",
"regex-automata",
"serde",
]
[[package]]
name = "buf_redux"
version = "0.8.4"
@@ -120,6 +132,15 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
[[package]]
name = "cast"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a"
dependencies = [
"rustc_version",
]
[[package]]
name = "cc"
version = "1.0.68"
@@ -214,12 +235,116 @@ dependencies = [
"libc",
]
[[package]]
name = "criterion"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab327ed7354547cc2ef43cbe20ef68b988e70b4b593cbd66a2a61733123a3d23"
dependencies = [
"atty",
"cast",
"clap",
"criterion-plot",
"csv",
"futures",
"itertools 0.10.1",
"lazy_static",
"num-traits",
"oorandom",
"plotters",
"rayon",
"regex",
"serde",
"serde_cbor",
"serde_derive",
"serde_json",
"tinytemplate",
"tokio",
"walkdir",
]
[[package]]
name = "criterion-plot"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e022feadec601fba1649cfa83586381a4ad31c6bf3a9ab7d408118b05dd9889d"
dependencies = [
"cast",
"itertools 0.9.0",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
dependencies = [
"cfg-if",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd"
dependencies = [
"cfg-if",
"crossbeam-utils",
"lazy_static",
"memoffset",
"scopeguard",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
dependencies = [
"cfg-if",
"lazy_static",
]
[[package]]
name = "crunchy"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]]
name = "csv"
version = "1.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1"
dependencies = [
"bstr",
"csv-core",
"itoa",
"ryu",
"serde",
]
[[package]]
name = "csv-core"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
dependencies = [
"memchr",
]
[[package]]
name = "digest"
version = "0.9.0"
@@ -229,6 +354,12 @@ dependencies = [
"generic-array",
]
[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "encoding_rs"
version = "0.8.28"
@@ -432,6 +563,12 @@ dependencies = [
"tracing",
]
[[package]]
name = "half"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3"
[[package]]
name = "hashbrown"
version = "0.9.1"
@@ -621,6 +758,24 @@ version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9"
[[package]]
name = "itertools"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
dependencies = [
"either",
]
[[package]]
name = "itertools"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "0.4.7"
@@ -678,6 +833,15 @@ version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
[[package]]
name = "memoffset"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
dependencies = [
"autocfg",
]
[[package]]
name = "mime"
version = "0.3.16"
@@ -796,6 +960,12 @@ version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
[[package]]
name = "oorandom"
version = "11.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
[[package]]
name = "opaque-debug"
version = "0.3.0"
@@ -916,6 +1086,34 @@ version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
[[package]]
name = "plotters"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a"
dependencies = [
"num-traits",
"plotters-backend",
"plotters-svg",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "plotters-backend"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c"
[[package]]
name = "plotters-svg"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9"
dependencies = [
"plotters-backend",
]
[[package]]
name = "ppv-lite86"
version = "0.2.10"
@@ -1081,6 +1279,31 @@ dependencies = [
"rand_core 0.6.3",
]
[[package]]
name = "rayon"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
dependencies = [
"autocfg",
"crossbeam-deque",
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-utils",
"lazy_static",
"num_cpus",
]
[[package]]
name = "redox_syscall"
version = "0.2.9"
@@ -1090,6 +1313,27 @@ dependencies = [
"bitflags",
]
[[package]]
name = "regex"
version = "1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
dependencies = [
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
[[package]]
name = "regex-syntax"
version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "remove_dir_all"
version = "0.5.3"
@@ -1146,6 +1390,15 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6"
[[package]]
name = "rustc_version"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [
"semver",
]
[[package]]
name = "ryu"
version = "1.0.5"
@@ -1158,6 +1411,15 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]]
name = "schannel"
version = "0.1.19"
@@ -1203,6 +1465,12 @@ dependencies = [
"libc",
]
[[package]]
name = "semver"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f3aac57ee7f3272d8395c6e4f502f434f0e289fcd62876f70daa008c20dcabe"
[[package]]
name = "serde"
version = "1.0.126"
@@ -1212,6 +1480,16 @@ dependencies = [
"serde_derive",
]
[[package]]
name = "serde_cbor"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622"
dependencies = [
"half",
"serde",
]
[[package]]
name = "serde_derive"
version = "1.0.126"
@@ -1379,6 +1657,7 @@ dependencies = [
"bimap",
"bincode",
"common",
"criterion",
"futures",
"hex",
"http",
@@ -1493,6 +1772,16 @@ dependencies = [
"winapi",
]
[[package]]
name = "tinytemplate"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
dependencies = [
"serde",
"serde_json",
]
[[package]]
name = "tinyvec"
version = "1.2.0"
@@ -1749,6 +2038,17 @@ version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
[[package]]
name = "walkdir"
version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
dependencies = [
"same-file",
"winapi",
"winapi-util",
]
[[package]]
name = "want"
version = "0.3.0"
@@ -1894,6 +2194,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
+6 -1
View File
@@ -31,4 +31,9 @@ tokio-util = { version = "0.6", features = ["compat"] }
warp = "0.3.1"
[dev-dependencies]
test_utils = { path = "../test_utils" }
criterion = { version = "0.3.4", features = ["async", "async_tokio"] }
test_utils = { path = "../test_utils" }
[[bench]]
name = "throughput"
harness = false
@@ -0,0 +1,79 @@
use test_utils::workspace::start_server_release;
use criterion::{criterion_group, criterion_main, Criterion};
use tokio::runtime::Runtime;
use serde_json::json;
use common::node_types::BlockHash;
pub fn benchmark_throughput_single_shard(c: &mut Criterion) {
let rt = Runtime::new().expect("tokio runtime should start");
// Setup our server and node/feed connections first:
let (nodes, feeds) = rt.block_on(async {
let mut server = start_server_release().await;
let shard_id = server.add_shard().await.unwrap();
// Connect 1000 nodes to the shard:
let mut nodes = server
.get_shard(shard_id)
.unwrap()
.connect_multiple(1000)
.await
.expect("nodes can connect");
// Every node announces itself on the same chain:
for (idx, (node_tx, _)) in nodes.iter_mut().enumerate() {
node_tx.send_json_text(json!({
"id":1, // message ID, not node ID. Can be the same for all.
"ts":"2021-07-12T10:37:47.714666+01:00",
"payload": {
"authority":true,
"chain":"Local Testnet",
"config":"",
"genesis_hash": BlockHash::from_low_u64_ne(1),
"implementation":"Substrate Node",
"msg":"system.connected",
"name": format!("Alice {}", idx),
"network_id":"12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp",
"startup_time":"1625565542717",
"version":"2.0.0-07a1af348-aarch64-macos"
}
})).await.unwrap();
}
// Start 1000 feeds:
let mut feeds = server
.get_core()
.connect_multiple(1000)
.await
.expect("feeds can connect");
// Subscribe all feeds to the chain:
for (feed_tx, _) in feeds.iter_mut() {
feed_tx.send_command("subscribe", "Local Testnet").await.unwrap();
}
// Consume any messages feeds have received so far:
let feed_consumers = feeds
.iter_mut()
.map(|(_,rx)| rx.recv_feed_messages());
futures::future::join_all(feed_consumers).await;
tokio::time::sleep(std::time::Duration::from_secs(100)).await;
(nodes, feeds)
});
// Next, run criterion using the same tokio runtime to benchmark time taken to send
// messages to nodes and receive them from feeds.
c.bench_function(
"throughput time",
|b| b.to_async(&rt).iter(|| async {
// TODO: Actually implement the benchmark.
})
);
}
criterion_group!(benches, benchmark_throughput_single_shard);
criterion_main!(benches);
@@ -4,21 +4,12 @@ use std::time::Duration;
use test_utils::{
assert_contains_matches,
feed_message_de::{FeedMessage, NodeDetails},
server::{self, Server},
workspace::start_server_debug
};
async fn cargo_run_server() -> Server {
Server::start(server::StartOpts {
shard_command: server::cargo_run_commands::telemetry_shard().expect("valid shard command"),
core_command: server::cargo_run_commands::telemetry_core().expect("valid core command"),
})
.await
.unwrap()
}
#[tokio::test]
async fn feed_sent_version_on_connect() {
let server = cargo_run_server().await;
let server = start_server_debug().await;
// Connect a feed:
let (_feed_tx, mut feed_rx) = server.get_core().connect().await.unwrap();
@@ -37,7 +28,7 @@ async fn feed_sent_version_on_connect() {
#[tokio::test]
async fn feed_ping_responded_to_with_pong() {
let server = cargo_run_server().await;
let server = start_server_debug().await;
// Connect a feed:
let (mut feed_tx, mut feed_rx) = server.get_core().connect().await.unwrap();
@@ -61,7 +52,7 @@ async fn feed_ping_responded_to_with_pong() {
#[tokio::test]
async fn feed_add_and_remove_node() {
// Connect server and add shard
let mut server = cargo_run_server().await;
let mut server = start_server_debug().await;
let shard_id = server.add_shard().await.unwrap();
// Connect a node to the shard:
@@ -122,7 +113,7 @@ async fn feed_add_and_remove_node() {
#[tokio::test]
async fn feed_add_and_remove_shard() {
let mut server = cargo_run_server().await;
let mut server = start_server_debug().await;
let mut shards = vec![];
for id in 1..=2 {
@@ -202,7 +193,7 @@ async fn feed_can_subscribe_and_unsubscribe_from_chain() {
use FeedMessage::*;
// Start server, add shard, connect node:
let mut server = cargo_run_server().await;
let mut server = start_server_debug().await;
let shard_id = server.add_shard().await.unwrap();
let (mut node_tx, _node_rx) = server.get_shard(shard_id).unwrap().connect().await.unwrap();
+2
View File
@@ -1,3 +1,5 @@
#[warn(missing_docs)]
mod aggregator;
mod connection;
mod json_message;
+3
View File
@@ -13,3 +13,6 @@ pub mod ws_client;
/// in an iterable container.
#[macro_use]
pub mod contains_matches;
/// Utilities to help with running tests from within this current workspace.
pub mod workspace;
@@ -1,36 +0,0 @@
//! A pair of commands we can use when running `cargo test` style tests in this workspace
//! that want to test the current code. For more external tests, we may want to ask for the
//! commands, or connect to a running instance instead.
use super::Command;
use std::path::PathBuf;
/// Runs `cargo run` in the current workspace to start up a telemetry shard process
pub fn telemetry_shard() -> Result<Command, std::io::Error> {
telemetry_command("telemetry_shard")
}
/// Runs `cargo run` in the current workspace to start up a telemetry core process
pub fn telemetry_core() -> Result<Command, std::io::Error> {
telemetry_command("telemetry_core")
}
fn telemetry_command(bin: &'static str) -> Result<Command, std::io::Error> {
let mut workspace_dir = try_find_workspace_dir()?;
workspace_dir.push("Cargo.toml");
Ok(Command::new("cargo")
.arg("run")
.arg("--bin")
.arg(bin)
.arg("--manifest-path")
.arg(workspace_dir)
.arg("--"))
}
/// A _very_ naive way to find the workspace ("backend") directory
/// from the current path (which is assumed to be inside it).
fn try_find_workspace_dir() -> Result<PathBuf, std::io::Error> {
let mut dir = std::env::current_dir()?;
while !dir.ends_with("backend") && dir.pop() {}
Ok(dir)
}
-1
View File
@@ -1,6 +1,5 @@
mod server;
mod utils;
pub mod cargo_run_commands;
pub mod channels;
pub use server::*;
@@ -0,0 +1,46 @@
//! Commands that we can use when running `cargo test` style tests in this workspace
//! that want to test the current code.
use crate::server::Command;
use std::path::PathBuf;
/// Runs `cargo run` in the current workspace to start up a telemetry shard process.
///
/// Note: The CWD must be somewhere within this backend workspace for the command to work.
pub fn cargo_run_telemetry_shard(release_mode: bool) -> Result<Command, std::io::Error> {
telemetry_command("telemetry_shard", release_mode)
}
/// Runs `cargo run` in the current workspace to start up a telemetry core process.
///
/// Note: The CWD must be somewhere within this backend workspace for the command to work.
pub fn cargo_run_telemetry_core(release_mode: bool) -> Result<Command, std::io::Error> {
telemetry_command("telemetry_core", release_mode)
}
fn telemetry_command(bin: &'static str, release_mode: bool) -> Result<Command, std::io::Error> {
let mut workspace_dir = try_find_workspace_dir()?;
workspace_dir.push("Cargo.toml");
let mut cmd = Command::new("cargo").arg("run");
// Release mode?
if release_mode {
cmd = cmd.arg("--release");
}
cmd = cmd.arg("--bin")
.arg(bin)
.arg("--manifest-path")
.arg(workspace_dir)
.arg("--");
Ok(cmd)
}
/// A _very_ naive way to find the workspace ("backend") directory
/// from the current path (which is assumed to be inside it).
fn try_find_workspace_dir() -> Result<PathBuf, std::io::Error> {
let mut dir = std::env::current_dir()?;
while !dir.ends_with("backend") && dir.pop() {}
Ok(dir)
}
+4
View File
@@ -0,0 +1,4 @@
mod commands;
mod start_server;
pub use start_server::{ start_server_debug, start_server_release };
@@ -0,0 +1,30 @@
use super::commands;
use crate::server::{self, Server, Command};
/// Start a telemetry core server. We'll use `cargo run` by default, to ensure that
/// the code we run is uptodate, but you can also provide env vars to configure the binary
/// that runs for the shard and core process:
///
/// TELEMETRY_SHARD_BIN - path to telemetry_shard binary
/// TELEMETRY_CORE_BIN - path to telemetry_core binary
async fn start_server(release_mode: bool) -> Server {
let shard_command = std::env::var("TELEMETRY_SHARD_BIN")
.map(|val| Command::new(val))
.unwrap_or_else(|_| commands::cargo_run_telemetry_shard(release_mode).expect("valid shard command"));
let core_command = std::env::var("TELEMETRY_CORE_BIN")
.map(|val| Command::new(val))
.unwrap_or_else(|_| commands::cargo_run_telemetry_core(release_mode).expect("valid core command"));
Server::start(server::StartOpts { shard_command, core_command }).await.unwrap()
}
/// Start a telemetry server using debug builds for compile speed
pub async fn start_server_debug() -> Server {
start_server(false).await
}
/// Start a telemetry server using release builds for performance accuracy
pub async fn start_server_release() -> Server {
start_server(true).await
}
+5
View File
@@ -11,10 +11,15 @@ pub struct Sender {
}
impl Sender {
/// Ask the underlying Websocket connection to close.
pub async fn close(&mut self) -> Result<(), SendError> {
self.inner.send(SentMessage::Close).await?;
Ok(())
}
/// Returns whether this channel is closed.
pub fn is_closed(&mut self) -> bool {
self.inner.is_closed()
}
}
#[derive(thiserror::Error, Debug, Clone)]