diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index dcafd0a1..4c647bf8 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -94,6 +94,56 @@ jobs: pkill --echo hc && pkill --echo holochain && pkill --echo lair-keystore + - name: Smoke test - app_install + run: | + # Start a sandbox conductor and run it in the background + nix develop --command bash -c "hc s clean && echo "1234" | hc s --piped create && echo "1234" | hc s --piped -f 8888 run &" + + # Run the scenario for 5 seconds + RUST_LOG=info nix run .#app_install -- --connection-string ws://localhost:8888 --agents 2 --behaviour minimal:1 --behaviour large:1 --duration 5 --no-progress + + pkill --echo hc && pkill --echo holochain && pkill --echo lair-keystore + + - name: Smoke test - first_call + run: | + # Start a sandbox conductor and run it in the background + nix develop --command bash -c "hc s clean && echo "1234" | hc s --piped create && echo "1234" | hc s --piped -f 8888 run &" + + # Run the scenario for 5 seconds + RUST_LOG=info nix run .#first_call -- --connection-string ws://localhost:8888 --agents 1 --behaviour local:1 --duration 5 --no-progress + + pkill --echo hc && pkill --echo holochain && pkill --echo lair-keystore + + - name: Smoke test - write_read + run: | + # Start a sandbox conductor and run it in the background + nix develop --command bash -c "hc s clean && echo "1234" | hc s --piped create && echo "1234" | hc s --piped -f 8888 run &" + + # Run the scenario for 5 seconds + RUST_LOG=info nix run .#write_read -- --connection-string ws://localhost:8888 --duration 5 --no-progress + + pkill --echo hc && pkill --echo holochain && pkill --echo lair-keystore + + - name: Smoke test - write_query + run: | + # Start a sandbox conductor and run it in the background + nix develop --command bash -c "hc s clean && echo "1234" | hc s --piped create && echo "1234" | hc s --piped -f 8888 run &" + + # Run the scenario for 5 seconds + RUST_LOG=info nix run .#write_query -- --connection-string ws://localhost:8888 --duration 5 --no-progress + + pkill --echo hc && pkill --echo holochain && pkill --echo lair-keystore + + - name: Smoke test - local_signals + run: | + # Start a sandbox conductor and run it in the background + nix develop --command bash -c "hc s clean && echo "1234" | hc s --piped create && echo "1234" | hc s --piped -f 8888 run &" + + # Run the scenario for 5 seconds + RUST_LOG=info nix run .#local_signals -- --connection-string ws://localhost:8888 --duration 5 --no-progress + + pkill --echo hc && pkill --echo holochain && pkill --echo lair-keystore + - name: Build scenario bundles run: | set -euxo pipefail diff --git a/CHANGELOG.md b/CHANGELOG.md index 781ff5e7..97e7d442 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added +- Exposed `on_signal` from the app websocket in the instrumented websocket. +- New handler function `handle_api_err` which can be used with `map_err` to deal with `ConductorApiError`s and convert + them into `anyhow` errors or panic when the error is fatal. +- New common helper `uninstall_app`, see its rustdoc for details. +- Each run will now generate a unique run ID which is used to keep report data separate between runs. At some point it + will be possible to specify a run ID to use but for now it is generated automatically. +- Check in the `happ_builder` whether `hc` and `cargo` are available. This is used by the scenario build script to skip + building happs if build tools are not available. This allows the project to be loaded in an environment where the + tools aren't available. + ### Changed +- Updated to new Holochain client version 0.5.0-alpha.4 which allowed `&mut self` to be replaced with `&self` in admin + and app instrumented websockets. +- `ShutdownHandle` now hides its implementation. It works the same way that it did but you can no longer access the + broadcast channel that it uses internally. Shutdown failures used to panic but it a `ShutdownHandle` happens to not + have any subscribers then that should not be considered a fatal error. It will now log a warning instead. +- Metrics now automatically include `run_id` and `scenario_name` tags. + ### Deprecated ### Removed ### Fixed diff --git a/Cargo.lock b/Cargo.lock index 9012752b..375b741e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -152,6 +152,16 @@ version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +[[package]] +name = "app_install" +version = "0.1.0" +dependencies = [ + "anyhow", + "happ_builder", + "holochain_types", + "holochain_wind_tunnel_runner", +] + [[package]] name = "approx" version = "0.5.1" @@ -387,6 +397,22 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +[[package]] +name = "callback" +version = "0.1.0" +dependencies = [ + "callback_integrity", + "hdk", +] + +[[package]] +name = "callback_integrity" +version = "0.1.0" +dependencies = [ + "hdi", + "serde", +] + [[package]] name = "camino" version = "1.1.7" @@ -1183,6 +1209,17 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "first_call" +version = "0.1.0" +dependencies = [ + "anyhow", + "happ_builder", + "holochain_types", + "holochain_wind_tunnel_runner", + "timed_integrity", +] + [[package]] name = "fixt" version = "0.3.1-rc.0" @@ -1467,6 +1504,7 @@ dependencies = [ "serde_yaml", "toml 0.8.13", "walkdir", + "which", ] [[package]] @@ -1642,9 +1680,9 @@ dependencies = [ [[package]] name = "holochain_client" -version = "0.5.0-rc.1" +version = "0.5.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "850d41651b155a465043fa17821d4552ead19188d244e5b2b6ffdd9fccc825de" +checksum = "1edd7fb6a7835e0a56c588b9b0e9ff5073a2eeff7d21a48e8efe19b25806ecad" dependencies = [ "again", "anyhow", @@ -2152,6 +2190,20 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http 0.2.12", + "hyper 0.14.28", + "rustls 0.21.12", + "tokio", + "tokio-rustls", +] + [[package]] name = "hyper-tls" version = "0.5.0" @@ -2480,7 +2532,7 @@ dependencies = [ "parking_lot 0.12.3", "paste", "rmp-serde 1.1.2", - "rustls", + "rustls 0.20.9", "serde", "serde_bytes", "serde_json", @@ -2533,6 +2585,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "large" +version = "0.1.0" +dependencies = [ + "anyhow", + "hdk", + "regex", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -2615,6 +2676,17 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "local_signals" +version = "0.1.0" +dependencies = [ + "anyhow", + "happ_builder", + "holochain_types", + "holochain_wind_tunnel_runner", + "tokio", +] + [[package]] name = "lock_api" version = "0.4.12" @@ -3573,6 +3645,7 @@ dependencies = [ "http 0.2.12", "http-body 0.4.6", "hyper 0.14.28", + "hyper-rustls", "hyper-tls 0.5.0", "ipnet", "js-sys", @@ -3582,6 +3655,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", + "rustls 0.21.12", "rustls-pemfile 1.0.4", "serde", "serde_json", @@ -3590,11 +3664,13 @@ dependencies = [ "system-configuration", "tokio", "tokio-native-tls", + "tokio-rustls", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", + "webpki-roots", "winreg 0.50.0", ] @@ -3842,6 +3918,18 @@ dependencies = [ "webpki", ] +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring 0.17.8", + "rustls-webpki", + "sct", +] + [[package]] name = "rustls-pemfile" version = "1.0.4" @@ -3867,6 +3955,16 @@ version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring 0.17.8", + "untrusted 0.9.0", +] + [[package]] name = "rustversion" version = "1.0.17" @@ -4183,6 +4281,13 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "signal" +version = "0.1.0" +dependencies = [ + "hdk", +] + [[package]] name = "signal-hook-registry" version = "1.4.2" @@ -4771,6 +4876,16 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.12", + "tokio", +] + [[package]] name = "tokio-tungstenite" version = "0.21.0" @@ -5015,6 +5130,9 @@ dependencies = [ "lazy_static", "regex", "reqwest 0.11.27", + "serde", + "serde_derive", + "serde_json", "thiserror", ] @@ -5512,6 +5630,24 @@ dependencies = [ "untrusted 0.9.0", ] +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + +[[package]] +name = "which" +version = "6.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8211e4f58a2b2805adfbefbc07bab82958fc91e3836339b1ab7ae32465dce0d7" +dependencies = [ + "either", + "home", + "rustix", + "winsafe", +] + [[package]] name = "wide" version = "0.7.21" @@ -5558,6 +5694,7 @@ name = "wind_tunnel_core" version = "0.2.0-alpha.2" dependencies = [ "derive_more", + "log", "tokio", ] @@ -5594,6 +5731,7 @@ dependencies = [ "env_logger 0.11.3", "indicatif", "log", + "nanoid", "parking_lot 0.12.3", "sysinfo 0.30.12", "tokio", @@ -5840,6 +5978,32 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "winsafe" +version = "0.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" + +[[package]] +name = "write_query" +version = "0.1.0" +dependencies = [ + "anyhow", + "happ_builder", + "holochain_types", + "holochain_wind_tunnel_runner", +] + +[[package]] +name = "write_read" +version = "0.1.0" +dependencies = [ + "anyhow", + "happ_builder", + "holochain_types", + "holochain_wind_tunnel_runner", +] + [[package]] name = "wyz" version = "0.5.1" diff --git a/Cargo.toml b/Cargo.toml index e560edd9..dac65cdc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,15 +11,24 @@ members = [ "happ_builder", - "scenarios/zome_call_single_value", - "scenarios/single_write_many_read", + "scenarios/app_install", "scenarios/dht_sync_lag", + "scenarios/single_write_many_read", + "scenarios/zome_call_single_value", + "scenarios/first_call", + "scenarios/write_read", + "scenarios/write_query", + "scenarios/local_signals", "zomes/return_single_value/coordinator", "zomes/crud/coordinator", "zomes/crud/integrity", "zomes/timed/coordinator", "zomes/timed/integrity", + "zomes/callback/coordinator", + "zomes/callback/integrity", + "zomes/large/coordinator", + "zomes/signal/coordinator", ] # By default, don't build the scenarios or zomes. @@ -55,17 +64,18 @@ url = "2.5.0" tabled = "0.15.0" indicatif = "0.17.8" # TODO waiting for 0.7.3+ relase to use the new reqwest-client-native-tls-vendored feature -# TODO waiting for Holochain 0.3 to add the feature `serde` back here, conflicts at 0.2 -influxdb = { version = "0.7.3-beta.1", package = "ts_influxdb", default-features = false, features = ["reqwest-client-native-tls-vendored"] } +influxdb = { version = "0.7.3-beta.1", package = "ts_influxdb", features = ["reqwest-client-native-tls-vendored"] } influxive-core = "0.0.2-alpha.1" +nanoid = "0.4.0" +which = "6.0.1" # Deps for Holochain -holochain_client = { version = "=0.5.0-rc.1" } +holochain_client = { version = "=0.5.0-rc.4" } holochain_zome_types = { version = "0.3.1-rc.0" } holo_hash = { version = "0.3.1-rc.0" } holochain_types = { version = "0.3.1-rc.0" } holochain_conductor_api = { version = "0.3.1-rc.0" } -hdk = { version = "0.3.1-rc.0", features = [] } +hdk = { version = "0.3.1-rc.0" } hdi = "0.4.1-rc.0" mr_bundle = "0.3.1-rc.0" @@ -85,6 +95,7 @@ happ_builder = { path = "./happ_builder", version = "0.1.0" } # Zomes for coorindator dependencies crud_integrity = { path = "./zomes/crud/integrity" } timed_integrity = { path = "./zomes/timed/integrity" } +callback_integrity = { path = "./zomes/callback/integrity" } [workspace.lints.rust] unsafe_code = "forbid" diff --git a/bindings/client/src/admin_websocket.rs b/bindings/client/src/admin_websocket.rs index b93c046f..2c1099fb 100644 --- a/bindings/client/src/admin_websocket.rs +++ b/bindings/client/src/admin_websocket.rs @@ -25,25 +25,24 @@ pub struct AdminWebsocketInstrumented { impl AdminWebsocketInstrumented { pub async fn connect(admin_url: impl ToSocketAddr, reporter: Arc) -> Result { let addr = admin_url.to_socket_addr()?; - println!("Connecting to admin websocket at {}", addr); AdminWebsocket::connect(addr) .await .map(|inner| Self { inner, reporter }) } #[wind_tunnel_instrument(prefix = "admin_")] - pub async fn generate_agent_pub_key(&mut self) -> ConductorApiResult { + pub async fn generate_agent_pub_key(&self) -> ConductorApiResult { self.inner.generate_agent_pub_key().await } #[wind_tunnel_instrument(prefix = "admin_")] - pub async fn list_app_interfaces(&mut self) -> ConductorApiResult> { + pub async fn list_app_interfaces(&self) -> ConductorApiResult> { self.inner.list_app_interfaces().await } #[wind_tunnel_instrument(prefix = "admin_")] pub async fn attach_app_interface( - &mut self, + &self, port: u16, allowed_origins: AllowedOrigins, installed_app_id: Option, @@ -55,43 +54,43 @@ impl AdminWebsocketInstrumented { #[wind_tunnel_instrument(prefix = "admin_")] pub async fn list_apps( - &mut self, + &self, status_filter: Option, ) -> ConductorApiResult> { self.inner.list_apps(status_filter).await } #[wind_tunnel_instrument(prefix = "admin_")] - pub async fn install_app(&mut self, payload: InstallAppPayload) -> ConductorApiResult { + pub async fn install_app(&self, payload: InstallAppPayload) -> ConductorApiResult { self.inner.install_app(payload).await } #[wind_tunnel_instrument(prefix = "admin_")] - pub async fn uninstall_app(&mut self, installed_app_id: String) -> ConductorApiResult<()> { + pub async fn uninstall_app(&self, installed_app_id: String) -> ConductorApiResult<()> { self.inner.uninstall_app(installed_app_id).await } #[wind_tunnel_instrument(prefix = "admin_")] pub async fn enable_app( - &mut self, + &self, installed_app_id: String, ) -> ConductorApiResult { self.inner.enable_app(installed_app_id).await } #[wind_tunnel_instrument(prefix = "admin_")] - pub async fn disable_app(&mut self, installed_app_id: String) -> ConductorApiResult<()> { + pub async fn disable_app(&self, installed_app_id: String) -> ConductorApiResult<()> { self.inner.disable_app(installed_app_id).await } #[wind_tunnel_instrument(prefix = "admin_")] // post = post_process_response - pub async fn get_dna_definition(&mut self, dna_hash: DnaHash) -> ConductorApiResult { + pub async fn get_dna_definition(&self, dna_hash: DnaHash) -> ConductorApiResult { self.inner.get_dna_definition(dna_hash).await } #[wind_tunnel_instrument(prefix = "admin_")] pub async fn grant_zome_call_capability( - &mut self, + &self, capability: GrantZomeCallCapabilityPayload, ) -> ConductorApiResult<()> { self.inner.grant_zome_call_capability(capability).await @@ -99,25 +98,25 @@ impl AdminWebsocketInstrumented { #[wind_tunnel_instrument(prefix = "admin_")] pub async fn delete_clone_cell( - &mut self, + &self, payload: DeleteCloneCellPayload, ) -> ConductorApiResult<()> { self.inner.delete_clone_cell(payload).await } #[wind_tunnel_instrument(prefix = "admin_")] - pub async fn storage_info(&mut self) -> ConductorApiResult { + pub async fn storage_info(&self) -> ConductorApiResult { self.inner.storage_info().await } #[wind_tunnel_instrument(prefix = "admin_")] - pub async fn dump_network_stats(&mut self) -> ConductorApiResult { + pub async fn dump_network_stats(&self) -> ConductorApiResult { self.inner.dump_network_stats().await } #[wind_tunnel_instrument(prefix = "admin_")] pub async fn graft_records( - &mut self, + &self, cell_id: CellId, validate: bool, records: Vec, @@ -130,7 +129,7 @@ impl AdminWebsocketInstrumented { // this and include the time taken to do the client side logic for setting up signing credentials. #[wind_tunnel_instrument(prefix = "admin_")] pub async fn authorize_signing_credentials( - &mut self, + &self, request: AuthorizeSigningCredentialsPayload, ) -> Result { self.inner.authorize_signing_credentials(request).await @@ -138,7 +137,7 @@ impl AdminWebsocketInstrumented { #[wind_tunnel_instrument(prefix = "admin_")] pub async fn issue_app_auth_token( - &mut self, + &self, payload: IssueAppAuthenticationTokenPayload, ) -> ConductorApiResult { self.inner.issue_app_auth_token(payload).await diff --git a/bindings/client/src/app_websocket.rs b/bindings/client/src/app_websocket.rs index e97b6455..5cd66355 100644 --- a/bindings/client/src/app_websocket.rs +++ b/bindings/client/src/app_websocket.rs @@ -5,7 +5,7 @@ use holochain_conductor_api::{AppAuthenticationToken, AppInfo, NetworkInfo}; use holochain_types::app::{ DisableCloneCellPayload, EnableCloneCellPayload, NetworkInfoRequestPayload, }; -use holochain_types::prelude::{CreateCloneCellPayload, ExternIO, FunctionName, ZomeName}; +use holochain_types::prelude::{CreateCloneCellPayload, ExternIO, FunctionName, Signal, ZomeName}; use holochain_zome_types::clone::ClonedCell; use std::fmt::{Debug, Formatter}; use std::sync::Arc; @@ -30,14 +30,21 @@ impl AppWebsocketInstrumented { .map(|inner| Self { inner, reporter }) } + pub async fn on_signal(&self, handler: F) -> Result + where + F: Fn(Signal) + 'static + Sync + Send, + { + self.inner.on_signal(handler).await + } + #[wind_tunnel_instrument(prefix = "app_")] - pub async fn app_info(&mut self) -> ConductorApiResult> { + pub async fn app_info(&self) -> ConductorApiResult> { self.inner.app_info().await } #[wind_tunnel_instrument(prefix = "app_", pre_hook = pre_call_zome)] pub async fn call_zome( - &mut self, + &self, target: ZomeCallTarget, zome_name: impl Into + Clone, fn_name: impl Into + Clone, @@ -50,7 +57,7 @@ impl AppWebsocketInstrumented { #[wind_tunnel_instrument(prefix = "app_")] pub async fn create_clone_cell( - &mut self, + &self, payload: CreateCloneCellPayload, ) -> ConductorApiResult { self.inner.create_clone_cell(payload).await @@ -58,7 +65,7 @@ impl AppWebsocketInstrumented { #[wind_tunnel_instrument(prefix = "app_")] pub async fn enable_clone_cell( - &mut self, + &self, payload: EnableCloneCellPayload, ) -> ConductorApiResult { self.inner.enable_clone_cell(payload).await @@ -66,7 +73,7 @@ impl AppWebsocketInstrumented { #[wind_tunnel_instrument(prefix = "app_")] pub async fn disable_clone_cell( - &mut self, + &self, payload: DisableCloneCellPayload, ) -> ConductorApiResult<()> { self.inner.disable_clone_cell(payload).await @@ -74,7 +81,7 @@ impl AppWebsocketInstrumented { #[wind_tunnel_instrument(prefix = "app_")] pub async fn network_info( - &mut self, + &self, payload: NetworkInfoRequestPayload, ) -> ConductorApiResult> { self.inner.network_info(payload).await diff --git a/bindings/client/src/error.rs b/bindings/client/src/error.rs new file mode 100644 index 00000000..7619ca2d --- /dev/null +++ b/bindings/client/src/error.rs @@ -0,0 +1,19 @@ +use holochain_client::ConductorApiError; +use std::io::ErrorKind; + +/// Handle a Conductor API error, returning an `anyhow::Error`. +/// +/// If the error is a websocket closed error, this function will panic. There is currently no way to +/// reconnect websockets so once the connection drops, the scenario won't recover. It is better to +/// treat the error as fatal amd stop than keep logging errors until the scenario finishes. +pub fn handle_api_err(err: ConductorApiError) -> anyhow::Error { + match err { + // Handle websocket closed errors by shutting down the process, as this is a fatal error + ConductorApiError::WebsocketError(e) + if e.kind() == ErrorKind::Other && e.to_string() == "ConnectionClosed" => + { + panic!("Conductor API connection closed unexpectedly: {:?}", e) + } + _ => anyhow::anyhow!("Conductor API error: {:?}", err), + } +} diff --git a/bindings/client/src/lib.rs b/bindings/client/src/lib.rs index 2303c0c6..5dd89e69 100644 --- a/bindings/client/src/lib.rs +++ b/bindings/client/src/lib.rs @@ -2,11 +2,14 @@ use std::net::{SocketAddr, ToSocketAddrs}; mod admin_websocket; mod app_websocket; +mod error; pub mod prelude { pub use crate::admin_websocket::AdminWebsocketInstrumented as AdminWebsocket; pub use crate::app_websocket::AppWebsocketInstrumented as AppWebsocket; + pub use crate::error::handle_api_err; + // Types defined in other crates should be fetched directly, but types defined in the client // need to be re-exported here to avoid confusion from depending on this client wrapper and // the original client crate diff --git a/bindings/runner/src/common.rs b/bindings/runner/src/common.rs index 9b1f8d7b..28d64d17 100644 --- a/bindings/runner/src/common.rs +++ b/bindings/runner/src/common.rs @@ -2,14 +2,17 @@ use crate::context::HolochainAgentContext; use crate::runner_context::HolochainRunnerContext; use anyhow::Context; use holochain_client_instrumented::prelude::{ - AdminWebsocket, AppWebsocket, AuthorizeSigningCredentialsPayload, ClientAgentSigner, + handle_api_err, AdminWebsocket, AppWebsocket, AuthorizeSigningCredentialsPayload, + ClientAgentSigner, }; use holochain_conductor_api::CellInfo; -use holochain_types::prelude::{AppBundleSource, ExternIO, InstallAppPayload, RoleName}; +use holochain_types::prelude::{ + AppBundleSource, ExternIO, InstallAppPayload, InstalledAppId, RoleName, +}; use holochain_types::websocket::AllowedOrigins; use std::path::PathBuf; use wind_tunnel_runner::prelude::{ - AgentContext, RunnerContext, UserValuesConstraint, WindTunnelResult, + AgentContext, HookResult, RunnerContext, UserValuesConstraint, WindTunnelResult, }; /// Sets the `app_ws_url` value in [HolochainRunnerContext] using a valid app port on the target conductor. @@ -40,14 +43,14 @@ pub fn configure_app_ws_url( .executor() .execute_in_place(async move { log::debug!("Connecting a Holochain admin client: {}", admin_ws_url); - let mut admin_client = AdminWebsocket::connect(admin_ws_url, reporter) + let admin_client = AdminWebsocket::connect(admin_ws_url, reporter) .await .context("Unable to connect admin client")?; let existing_app_interfaces = admin_client .list_app_interfaces() .await - .map_err(|e| anyhow::anyhow!("Conductor API error: {:?}", e))?; + .map_err(handle_api_err)?; let existing_app_ports = existing_app_interfaces .into_iter() @@ -69,7 +72,7 @@ pub fn configure_app_ws_url( // Don't specify the port, let the conductor pick one .attach_app_interface(0, AllowedOrigins::Any, None) .await - .map_err(|e| anyhow::anyhow!("Conductor API error: {:?}", e))?; + .map_err(handle_api_err)?; Ok(attached_app_port) } }) @@ -111,7 +114,7 @@ pub fn configure_app_ws_url( /// use holochain_wind_tunnel_runner::prelude::{HolochainAgentContext, HolochainRunnerContext, AgentContext, HookResult}; /// /// fn agent_behaviour(ctx: &mut AgentContext) -> HookResult { -/// let installed_app_id = ctx.get().installed_app_id(); +/// let installed_app_id = ctx.get().installed_app_id()?; /// let cell_id = ctx.get().cell_id(); /// let app_agent_client = ctx.get().app_client(); /// @@ -140,17 +143,17 @@ where let agent_id = ctx.agent_id().to_string(); let reporter = ctx.runner_context().reporter(); - let (installed_app_id, cell_id, app_agent_client) = ctx + let (installed_app_id, cell_id, app_client) = ctx .runner_context() .executor() .execute_in_place(async move { log::debug!("Connecting a Holochain admin client: {}", admin_ws_url); - let mut client = AdminWebsocket::connect(admin_ws_url, reporter.clone()).await?; + let client = AdminWebsocket::connect(admin_ws_url, reporter.clone()).await?; let key = client .generate_agent_pub_key() .await - .map_err(|e| anyhow::anyhow!("Conductor API error: {:?}", e))?; + .map_err(handle_api_err)?; log::debug!("Generated agent pub key: {:}", key); let installed_app_id = format!("{}-app", agent_id).to_string(); @@ -163,13 +166,13 @@ where network_seed: None, }) .await - .map_err(|e| anyhow::anyhow!("Conductor API error: {:?}", e))?; + .map_err(handle_api_err)?; log::debug!("Installed app: {:}", installed_app_id); client .enable_app(installed_app_id.clone()) .await - .map_err(|e| anyhow::anyhow!("Conductor API error: {:?}", e))?; + .map_err(handle_api_err)?; log::debug!("Enabled app: {:}", installed_app_id); let cell_id = match app_info @@ -189,8 +192,7 @@ where cell_id: cell_id.clone(), functions: None, }) - .await - .map_err(|e| anyhow::anyhow!("Conductor API error: {:?}", e))?; + .await?; log::debug!("Authorized signing credentials"); let mut signer = ClientAgentSigner::default(); @@ -212,7 +214,81 @@ where ctx.get_mut().installed_app_id = Some(installed_app_id); ctx.get_mut().cell_id = Some(cell_id); - ctx.get_mut().app_client = Some(app_agent_client); + ctx.get_mut().app_client = Some(app_client); + + Ok(()) +} + +/// Uninstall an application. Intended to be used by scenarios that clean up after themselves or +/// need to uninstall and re-install the same application. +/// +/// Requires: +/// - Either you provide the `installed_app_id` or the [HolochainAgentContext] must have an `installed_app_id`. +/// Note that this means that when passing `None`, only the last app that was installed using [install_app] will be uninstalled. +/// +/// Call this function as follows: +/// ```rust +/// use std::path::Path; +/// use holochain_wind_tunnel_runner::prelude::{HolochainAgentContext, HolochainRunnerContext, uninstall_app, AgentContext, HookResult}; +/// +/// fn agent_teardown(ctx: &mut AgentContext) -> HookResult { +/// uninstall_app(ctx, None)?; +/// Ok(()) +/// } +/// ``` +/// +/// Or if you are uninstalling in the agent behaviour and in the teardown: +/// ```rust +/// use std::path::Path; +/// use holochain_wind_tunnel_runner::prelude::{HolochainAgentContext, HolochainRunnerContext, uninstall_app, AgentContext, HookResult, install_app}; +/// +/// fn agent_behaviour(ctx: &mut AgentContext) -> HookResult { +/// install_app(ctx, Path::new("path/to/your/happ").to_path_buf(), &"your_role_name".to_string())?; +/// uninstall_app(ctx, None)?; +/// Ok(()) +/// } +/// +/// fn agent_teardown(ctx: &mut AgentContext) -> HookResult { +/// // The app may have already been uninstalled if the scenario stopped after uninstalling the app but the agent behaviour is +/// // not guaranteed to complete so we don't error when uninstalling here. +/// uninstall_app(ctx, None).ok(); +/// Ok(()) +/// } +/// ``` +/// +/// Method: +/// - Either uses the provided `installed_app_id` or gets the `installed_app_id` from the agent context. +/// - Connects to an admin port using the connection string from the runner context. +/// - Uninstalls the specified app and returns the result. +pub fn uninstall_app( + ctx: &mut AgentContext>, + installed_app_id: Option, +) -> HookResult +where + SV: UserValuesConstraint, +{ + let admin_ws_url = ctx.runner_context().get_connection_string().to_string(); + + let installed_app_id = installed_app_id.or_else(|| ctx.get().installed_app_id().ok()); + if installed_app_id.is_none() { + // If there is no installed app id, we can't uninstall anything + log::info!("No installed app id found, skipping uninstall"); + return Ok(()); + } + + let reporter = ctx.runner_context().reporter(); + + ctx.runner_context() + .executor() + .execute_in_place(async move { + let admin_client = AdminWebsocket::connect(admin_ws_url, reporter).await?; + + admin_client + .uninstall_app(installed_app_id.unwrap()) + .await + .map_err(handle_api_err)?; + Ok(()) + })?; Ok(()) } @@ -258,7 +334,7 @@ where SV: UserValuesConstraint, { let cell_id = ctx.get().cell_id(); - let mut app_agent_client = ctx.get().app_client(); + let app_agent_client = ctx.get().app_client(); ctx.runner_context().executor().execute_in_place(async { let result = app_agent_client .call_zome( @@ -268,7 +344,7 @@ where ExternIO::encode(payload).context("Encoding failure")?, ) .await - .map_err(|e| anyhow::anyhow!("Conductor API error: {:?}", e))?; + .map_err(handle_api_err)?; result .decode() diff --git a/bindings/runner/src/context.rs b/bindings/runner/src/context.rs index a810610d..1c0f1113 100644 --- a/bindings/runner/src/context.rs +++ b/bindings/runner/src/context.rs @@ -24,8 +24,8 @@ impl UserValuesConstraint for HolochainAgentContext impl HolochainAgentContext { /// Get the `installed_app_id` that was configured during agent setup. - pub fn installed_app_id(&self) -> String { - self.installed_app_id.clone().expect("installed_app_id is not set, did you forget to call `install_app` in your agent_setup?") + pub fn installed_app_id(&self) -> anyhow::Result { + self.installed_app_id.clone().ok_or_else(|| anyhow::anyhow!("installed_app_id is not set, did you forget to call `install_app` in your agent_setup?")) } /// Get the `cell_id` that was configured during agent setup. diff --git a/bindings/runner/src/lib.rs b/bindings/runner/src/lib.rs index ac87bc5a..6942c7a8 100644 --- a/bindings/runner/src/lib.rs +++ b/bindings/runner/src/lib.rs @@ -17,4 +17,7 @@ pub mod prelude { /// /// This is for convenience so that you can depend on a single crate for the runner in your scenarios. pub use wind_tunnel_runner::prelude::*; + + /// Re-export of the instrumented client for convenience. + pub use holochain_client_instrumented::prelude::*; } diff --git a/framework/core/Cargo.toml b/framework/core/Cargo.toml index d5a7aee4..4f39ca2d 100644 --- a/framework/core/Cargo.toml +++ b/framework/core/Cargo.toml @@ -12,6 +12,7 @@ repository = "https://github.com/holochain/wind-tunnel" [dependencies] tokio = { workspace = true } derive_more = { workspace = true } +log = { workspace = true } [lints] workspace = true diff --git a/framework/core/src/shutdown.rs b/framework/core/src/shutdown.rs index 4afbf550..19c046b2 100644 --- a/framework/core/src/shutdown.rs +++ b/framework/core/src/shutdown.rs @@ -8,15 +8,25 @@ pub struct ShutdownHandle { sender: Sender<()>, } +impl Default for ShutdownHandle { + fn default() -> Self { + Self::new() + } +} + impl ShutdownHandle { - pub fn new(sender: Sender<()>) -> Self { - Self { sender } + pub fn new() -> Self { + Self { + sender: tokio::sync::broadcast::channel(1).0, + } } pub fn shutdown(&self) { - self.sender - .send(()) - .expect("Failed to send shutdown signal"); + if let Err(e) = self.sender.send(()) { + // Will fail if nobody is listening for a shutdown signal, in which case the log message + // can be ignored. + log::warn!("Failed to send shutdown signal: {:?}", e); + } } pub fn new_listener(&self) -> DelegatedShutdownListener { diff --git a/framework/instruments/Cargo.toml b/framework/instruments/Cargo.toml index fce479ff..afbc33dd 100644 --- a/framework/instruments/Cargo.toml +++ b/framework/instruments/Cargo.toml @@ -14,7 +14,7 @@ anyhow = { workspace = true } opentelemetry_api = { workspace = true } parking_lot = { workspace = true } tabled = { workspace = true } -influxdb = { workspace = true, default-features = false } +influxdb = { workspace = true } tokio = { workspace = true } log = { workspace = true } influxive-core = { workspace = true } diff --git a/framework/instruments/src/lib.rs b/framework/instruments/src/lib.rs index bba98e3d..6fc24409 100644 --- a/framework/instruments/src/lib.rs +++ b/framework/instruments/src/lib.rs @@ -13,8 +13,10 @@ pub mod prelude { pub use crate::{report_operation, OperationRecord, ReportConfig, Reporter}; } +#[derive(Debug)] pub struct ReportConfig { pub dir: Option, + pub run_id: String, pub scenario_name: String, pub enable_in_memory: bool, pub enable_influx_client: bool, @@ -22,9 +24,10 @@ pub struct ReportConfig { } impl ReportConfig { - pub fn new(scenario_name: String) -> Self { + pub fn new(run_id: String, scenario_name: String) -> Self { ReportConfig { dir: None, + run_id, scenario_name, enable_in_memory: false, enable_influx_client: false, @@ -67,6 +70,8 @@ impl ReportConfig { let metrics_collector = report::InfluxClientReportCollector::new( runtime, shutdown_listener.clone(), + self.run_id.clone(), + self.scenario_name.clone(), )?; Some(RwLock::new( Box::new(metrics_collector) as Box<(dyn ReportCollector + Send + Sync)> @@ -79,6 +84,7 @@ impl ReportConfig { runtime, shutdown_listener, self.dir.unwrap(), + self.run_id, self.scenario_name, ); Some(RwLock::new( diff --git a/framework/instruments/src/report.rs b/framework/instruments/src/report.rs index 5a665eb2..56db1092 100644 --- a/framework/instruments/src/report.rs +++ b/framework/instruments/src/report.rs @@ -73,7 +73,7 @@ impl Deref for ReportMetric { pub trait ReportCollector { fn add_operation(&mut self, operation_record: &OperationRecord); - /// Record a custom metric that + /// Record a custom metric fn add_custom(&mut self, metric: ReportMetric); fn finalize(&self); diff --git a/framework/instruments/src/report/influx_client_reporter.rs b/framework/instruments/src/report/influx_client_reporter.rs index aa861367..13f78405 100644 --- a/framework/instruments/src/report/influx_client_reporter.rs +++ b/framework/instruments/src/report/influx_client_reporter.rs @@ -27,6 +27,8 @@ impl InfluxClientReportCollector { pub fn new( runtime: &Runtime, shutdown_listener: DelegatedShutdownListener, + run_id: String, + scenario_name: String, ) -> anyhow::Result { let client = Client::new( std::env::var("INFLUX_HOST").context( @@ -45,7 +47,13 @@ impl InfluxClientReportCollector { start_metrics_write_task(runtime, shutdown_listener, client, flush_complete.clone()); Ok(Self { - inner: InfluxReporterBase::new(join_handle, writer, flush_complete), + inner: InfluxReporterBase::new( + run_id, + scenario_name, + join_handle, + writer, + flush_complete, + ), }) } } diff --git a/framework/instruments/src/report/influx_file_reporter.rs b/framework/instruments/src/report/influx_file_reporter.rs index b4b5cbfc..bf6e98a1 100644 --- a/framework/instruments/src/report/influx_file_reporter.rs +++ b/framework/instruments/src/report/influx_file_reporter.rs @@ -31,6 +31,7 @@ impl InfluxFileReportCollector { runtime: &Runtime, shutdown_listener: DelegatedShutdownListener, dir: PathBuf, + run_id: String, scenario_name: String, ) -> Self { let flush_complete = Arc::new(AtomicBool::new(false)); @@ -38,12 +39,18 @@ impl InfluxFileReportCollector { runtime, shutdown_listener, dir, - scenario_name, + scenario_name.clone(), flush_complete.clone(), ); Self { - inner: InfluxReporterBase::new(join_handle, writer, flush_complete), + inner: InfluxReporterBase::new( + run_id, + scenario_name, + join_handle, + writer, + flush_complete, + ), } } } @@ -75,14 +82,19 @@ fn start_metrics_file_write_task( tokio::fs::create_dir_all(&dir).await.unwrap(); } + let out_path = dir.join(format!( + "{}-{}.influx", + scenario_name, + SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_secs() + )); + log::debug!("Influx file reporter starting, using file {:?}", out_path); let mut file = File::options() .create_new(true) .write(true) - .open(dir.join(format!( - "{}-{}.influx", - scenario_name, - SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() - ))) + .open(out_path) .await .unwrap(); diff --git a/framework/instruments/src/report/influx_reporter_base.rs b/framework/instruments/src/report/influx_reporter_base.rs index 906b606a..258967ec 100644 --- a/framework/instruments/src/report/influx_reporter_base.rs +++ b/framework/instruments/src/report/influx_reporter_base.rs @@ -11,6 +11,8 @@ use tokio::sync::mpsc::UnboundedSender; use tokio::task::JoinHandle; pub(crate) struct InfluxReporterBase { + run_id: String, + scenario_name: String, join_handle: JoinHandle<()>, writer: UnboundedSender, flush_complete: Arc, @@ -18,11 +20,15 @@ pub(crate) struct InfluxReporterBase { impl InfluxReporterBase { pub fn new( + run_id: String, + scenario_name: String, join_handle: JoinHandle<()>, writer: UnboundedSender, flush_complete: Arc, ) -> Self { Self { + run_id, + scenario_name, join_handle, writer, flush_complete, @@ -65,9 +71,11 @@ impl ReportCollector for InfluxReporterBase { operation_record .elapsed .expect("OperationRecord must have an elapsed time") - .as_micros() as f64 + .as_micros() as f64 // TODO use as_secs_f64 and let influx handle ms / 1000.0, ) + .add_tag("run_id", self.run_id.clone()) + .add_tag("scenario_name", self.scenario_name.clone()) .add_tag("operation_id", operation_record.operation_id.to_string()) .add_tag("is_error", operation_record.is_error.to_string()); @@ -100,6 +108,9 @@ impl ReportCollector for InfluxReporterBase { query = query.add_tag(k.into_string(), v.into_type()); } + query = query.add_tag("run_id", self.run_id.clone()); + query = query.add_tag("scenario_name", self.scenario_name.clone()); + self.try_send(query); } diff --git a/framework/runner/Cargo.toml b/framework/runner/Cargo.toml index c40c6a1c..b2066691 100644 --- a/framework/runner/Cargo.toml +++ b/framework/runner/Cargo.toml @@ -19,6 +19,7 @@ env_logger = { workspace = true } derive_more = { workspace = true } sysinfo = { workspace = true } indicatif = { workspace = true } +nanoid = { workspace = true } wind_tunnel_core = { workspace = true } wind_tunnel_instruments = { workspace = true } diff --git a/framework/runner/src/run.rs b/framework/runner/src/run.rs index c836169b..cb5a27c0 100644 --- a/framework/runner/src/run.rs +++ b/framework/runner/src/run.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use std::time::Duration; use anyhow::Context; -use wind_tunnel_core::prelude::ShutdownSignalError; +use wind_tunnel_core::prelude::{ShutdownHandle, ShutdownSignalError}; use wind_tunnel_instruments::ReportConfig; use crate::cli::ReporterOpt; @@ -19,6 +19,9 @@ use crate::{ pub fn run( definition: ScenarioDefinitionBuilder, ) -> anyhow::Result<()> { + let run_id = nanoid::nanoid!(); + println!("#RunId: [{}]", run_id); + let definition = definition.build()?; log::info!("Running scenario: {}", definition.name); @@ -26,10 +29,11 @@ pub fn run( let runtime = tokio::runtime::Runtime::new().context("Failed to create Tokio runtime")?; let shutdown_handle = start_shutdown_listener(&runtime)?; + let report_shutdown_handle = ShutdownHandle::default(); let reporter = { let _h = runtime.handle().enter(); - let mut report_config = ReportConfig::new(definition.name.clone()); + let mut report_config = ReportConfig::new(run_id, definition.name.clone()); match definition.reporter { ReporterOpt::InMemory => { @@ -50,7 +54,7 @@ pub fn run( } } - Arc::new(report_config.init_reporter(&runtime, shutdown_handle.new_listener())?) + Arc::new(report_config.init_reporter(&runtime, report_shutdown_handle.new_listener())?) }; let executor = Arc::new(Executor::new(runtime, shutdown_handle.clone())); let mut runner_context = RunnerContext::new( @@ -169,6 +173,10 @@ pub fn run( } } + // Manually shutdown the reporting once all the teardown steps are complete, this doesn't + // respond to Ctrl+C like the user-provided code does. + report_shutdown_handle.shutdown(); + // Then wait for the reporting to finish runner_context_for_teardown.reporter().finalize(); Ok(()) diff --git a/framework/runner/src/shutdown.rs b/framework/runner/src/shutdown.rs index ce3fccba..08983839 100644 --- a/framework/runner/src/shutdown.rs +++ b/framework/runner/src/shutdown.rs @@ -4,18 +4,16 @@ use wind_tunnel_core::prelude::ShutdownHandle; pub(crate) fn start_shutdown_listener( runtime: &tokio::runtime::Runtime, ) -> anyhow::Result { - let (tx, _) = tokio::sync::broadcast::channel(1); + let handle = ShutdownHandle::default(); - let sender = tx.clone(); + let listener_handle = handle.clone(); runtime.spawn(async move { signal::ctrl_c() .await .expect("Failed to receive Ctrl-C signal"); - sender - .send(()) - .expect("Received shutdown signal but failed to notify listeners"); + listener_handle.shutdown(); println!("Received shutdown signal, shutting down..."); }); - Ok(ShutdownHandle::new(tx)) + Ok(handle) } diff --git a/happ_builder/Cargo.toml b/happ_builder/Cargo.toml index 239dcecc..8b9a305a 100644 --- a/happ_builder/Cargo.toml +++ b/happ_builder/Cargo.toml @@ -15,6 +15,7 @@ anyhow = { workspace = true } holochain_types = { workspace = true } serde_yaml = { workspace = true } walkdir = { workspace = true } +which = { workspace = true } [lints] workspace = true diff --git a/happ_builder/src/lib.rs b/happ_builder/src/lib.rs index aeef9105..97b39c3b 100644 --- a/happ_builder/src/lib.rs +++ b/happ_builder/src/lib.rs @@ -509,3 +509,16 @@ roles: Ok(()) } + +/// Checks whether the required tools for this builder are available. +pub fn required_tools_available() -> bool { + if which::which("hc").is_err() { + return false; + } + + if which::which("cargo").is_err() { + return false; + } + + true +} diff --git a/influx/config.toml b/influx/config.toml index c366ede4..71ad9cc5 100644 --- a/influx/config.toml +++ b/influx/config.toml @@ -4,3 +4,4 @@ e2e-testing = true # Allows clearing stores between tests. http-bind-address = ":8087" reporting-disabled = true # Don't send telemetry back to Influx storage-validate-keys = true +session-length = 720 # 12 hours diff --git a/influx/templates/dashboards/app_install.json b/influx/templates/dashboards/app_install.json new file mode 100644 index 00000000..6c498886 --- /dev/null +++ b/influx/templates/dashboards/app_install.json @@ -0,0 +1 @@ +[{"apiVersion":"influxdata.com/v2alpha1","kind":"Dashboard","metadata":{"name":"eerie-dhawan-dcc001"},"spec":{"charts":[{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","label":"Time","name":"y","scale":"linear","suffix":"ms"}],"colorizeRows":true,"colors":[{"id":"uc1BLQz3iu-MrhybTFSj8","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"nZFrvZZZxpqJfCR2W6wIi","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"XB8D9DK-xaX6HDXATCElV","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"x1dOkgLLKCqPXArPwPXUQ","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"8YoQlwFuqaUf9vob0xPUy","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"saq4M-1Y0-Qqfrhhunj0a","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"aEm0B2KU5qZ7i2Vh4EejP","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"dX9F76BDifraU70HDqqRD","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"App install (admin call)","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.instruments.operation_duration\")\n |> filter(fn: (r) => r[\"operation_id\"] == \"admin_install_app\")\n |> filter(fn: (r) => r[\"scenario_name\"] == \"app_install\")\n |> filter(fn: (r) => r[\"run_id\"] == v.RunId) \n |> filter(fn: (r) => r[\"_field\"] == \"value\")\n |> filter(fn: (r) => r[\"is_error\"] == \"false\")\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":12,"widthRatio":1,"xCol":"_time","yCol":"_value"},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","label":"Time","name":"y","scale":"linear","suffix":"ms"}],"colorizeRows":true,"colors":[{"id":"CfgyeUCKp5B3m-7H2CjUP","name":"Nineteen Eighty Four","type":"scale","hex":"#31C0F6"},{"id":"lu8TvuVWdEEjeg5g7tTgV","name":"Nineteen Eighty Four","type":"scale","hex":"#A500A5"},{"id":"X0rrPOo2LTtG8tD6zRLov","name":"Nineteen Eighty Four","type":"scale","hex":"#FF7E27"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Install, enable and connect (callback, mean)","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.custom.app_install\")\n |> filter(fn: (r) => r[\"_field\"] == \"value\")\n |> filter(fn: (r) => r[\"scenario_name\"] == \"app_install\")\n |> filter(fn: (r) => r[\"happ\"] == \"callback\")\n |> filter(fn: (r) => r[\"run_id\"] == v.RunId)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> map(fn: (r) => ({ r with _value: r._value * 1000.0 })) \n |> yield(name: \"mean\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"yPos":4},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","label":"Time","name":"y","scale":"linear","suffix":"ms"}],"colorizeRows":true,"colors":[{"id":"CfgyeUCKp5B3m-7H2CjUP","name":"Nineteen Eighty Four","type":"scale","hex":"#31C0F6"},{"id":"lu8TvuVWdEEjeg5g7tTgV","name":"Nineteen Eighty Four","type":"scale","hex":"#A500A5"},{"id":"X0rrPOo2LTtG8tD6zRLov","name":"Nineteen Eighty Four","type":"scale","hex":"#FF7E27"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Install, enable and connect (callback, max)","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.custom.app_install\")\n |> filter(fn: (r) => r[\"_field\"] == \"value\")\n |> filter(fn: (r) => r[\"scenario_name\"] == \"app_install\")\n |> filter(fn: (r) => r[\"happ\"] == \"callback\")\n |> filter(fn: (r) => r[\"run_id\"] == v.RunId)\n |> aggregateWindow(every: v.windowPeriod, fn: max, createEmpty: false)\n |> map(fn: (r) => ({ r with _value: r._value * 1000.0 })) \n |> yield(name: \"mean\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"yPos":8},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","label":"Time","name":"y","scale":"linear","suffix":"s"}],"colorizeRows":true,"colors":[{"id":"CfgyeUCKp5B3m-7H2CjUP","name":"Nineteen Eighty Four","type":"scale","hex":"#31C0F6"},{"id":"lu8TvuVWdEEjeg5g7tTgV","name":"Nineteen Eighty Four","type":"scale","hex":"#A500A5"},{"id":"X0rrPOo2LTtG8tD6zRLov","name":"Nineteen Eighty Four","type":"scale","hex":"#FF7E27"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Install, enable and connect (large, mean)","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.custom.app_install\")\n |> filter(fn: (r) => r[\"_field\"] == \"value\")\n |> filter(fn: (r) => r[\"scenario_name\"] == \"app_install\")\n |> filter(fn: (r) => r[\"happ\"] == \"large\")\n |> filter(fn: (r) => r[\"run_id\"] == v.RunId)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","xPos":6,"yCol":"_value","yPos":4},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","label":"Time","name":"y","scale":"linear","suffix":"s"}],"colorizeRows":true,"colors":[{"id":"CfgyeUCKp5B3m-7H2CjUP","name":"Nineteen Eighty Four","type":"scale","hex":"#31C0F6"},{"id":"lu8TvuVWdEEjeg5g7tTgV","name":"Nineteen Eighty Four","type":"scale","hex":"#A500A5"},{"id":"X0rrPOo2LTtG8tD6zRLov","name":"Nineteen Eighty Four","type":"scale","hex":"#FF7E27"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Install, enable and connect (large, max)","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.custom.app_install\")\n |> filter(fn: (r) => r[\"_field\"] == \"value\")\n |> filter(fn: (r) => r[\"scenario_name\"] == \"app_install\")\n |> filter(fn: (r) => r[\"happ\"] == \"large\")\n |> filter(fn: (r) => r[\"run_id\"] == v.RunId)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","xPos":6,"yCol":"_value","yPos":8}],"description":"Custom charts for the app_install scenario","name":"App install"}}] \ No newline at end of file diff --git a/influx/templates/dashboards/dht_sync_lag.json b/influx/templates/dashboards/dht_sync_lag.json index acf00367..73244ee2 100644 --- a/influx/templates/dashboards/dht_sync_lag.json +++ b/influx/templates/dashboards/dht_sync_lag.json @@ -1 +1 @@ -[{"apiVersion":"influxdata.com/v2alpha1","kind":"Dashboard","metadata":{"name":"victorious-kapitsa-bf8001"},"spec":{"charts":[{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear","suffix":"s"}],"colorizeRows":true,"colors":[{"id":"EeycwCWfyw0YSbHfK-_bg","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"reCGKSBa8F4FXQG3VYe_B","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"LwHjuuBTah-Q6Kv31XbMb","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"UYJNhccStV1szRDzc5ZS8","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"ZaGqV7BaVmHtlZZ7QiBR9","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"MLJ4MzW3SBtxs8E6jW8FB","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"XQFWzHtO8a6lHXL2D1mHH","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"mwVE20owCu-EGZVTQ7aca","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Sync Lag (mean)","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.custom.dht_sync_lag\")\n |> filter(fn: (r) => r[\"_field\"] == \"value\")\n |> map(fn: (r) => ({ r with _value: r._value / 1000.0 })) \n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","yCol":"_value"},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear"}],"colorizeRows":true,"colors":[{"id":"2VIaJgN6zA7q-7pJxjW6R","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"54Pm1akf7W1i6Qu-haF2O","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"ka2GpKDmGeoX3CkjCsVB9","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"p2jDtNTUfRNUXEDkHLo3_","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"v1bMU4KDeOO9f-cKvLwcz","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"fKPuvSYrt7IdU29E-Lu4G","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"meYBhHM7mf6ZaNQiQy8vb","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"nu4Wev2n_a_Zu712_arTE","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Send count","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.custom.dht_sync_sent_count\")\n |> filter(fn: (r) => r[\"_field\"] == \"value\")\n |> increase()\n |> yield(name: \"increase\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":4},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear","suffix":"s"}],"colorizeRows":true,"colors":[{"id":"EeycwCWfyw0YSbHfK-_bg","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"reCGKSBa8F4FXQG3VYe_B","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"LwHjuuBTah-Q6Kv31XbMb","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"UYJNhccStV1szRDzc5ZS8","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"ZaGqV7BaVmHtlZZ7QiBR9","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"MLJ4MzW3SBtxs8E6jW8FB","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"XQFWzHtO8a6lHXL2D1mHH","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"mwVE20owCu-EGZVTQ7aca","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Sync Lag (max)","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.custom.dht_sync_lag\")\n |> filter(fn: (r) => r[\"_field\"] == \"value\")\n |> map(fn: (r) => ({ r with _value: r._value / 1000.0 })) \n |> aggregateWindow(every: v.windowPeriod, fn: max, createEmpty: false)\n |> yield(name: \"max\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","xPos":6,"yCol":"_value"},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear"}],"colorizeRows":true,"colors":[{"id":"2VIaJgN6zA7q-7pJxjW6R","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"54Pm1akf7W1i6Qu-haF2O","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"ka2GpKDmGeoX3CkjCsVB9","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"p2jDtNTUfRNUXEDkHLo3_","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"v1bMU4KDeOO9f-cKvLwcz","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"fKPuvSYrt7IdU29E-Lu4G","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"meYBhHM7mf6ZaNQiQy8vb","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"nu4Wev2n_a_Zu712_arTE","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Recieved count","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.custom.dht_sync_recv_count\")\n |> filter(fn: (r) => r[\"_field\"] == \"value\")\n |> increase()\n |> yield(name: \"increase\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","xPos":6,"yCol":"_value","yPos":4}],"name":"DHT Sync Lag"}}] \ No newline at end of file +[{"apiVersion":"influxdata.com/v2alpha1","kind":"Dashboard","metadata":{"name":"ecstatic-tereshkova-1cc001"},"spec":{"charts":[{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear","suffix":"s"}],"colorizeRows":true,"colors":[{"id":"EeycwCWfyw0YSbHfK-_bg","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"reCGKSBa8F4FXQG3VYe_B","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"LwHjuuBTah-Q6Kv31XbMb","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"UYJNhccStV1szRDzc5ZS8","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"ZaGqV7BaVmHtlZZ7QiBR9","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"MLJ4MzW3SBtxs8E6jW8FB","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"XQFWzHtO8a6lHXL2D1mHH","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"mwVE20owCu-EGZVTQ7aca","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Sync Lag (mean)","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.custom.dht_sync_lag\")\n |> filter(fn: (r) => r[\"scenario_name\"] == \"dht_sync_lag\")\n |> filter(fn: (r) => r[\"run_id\"] == v.RunId)\n |> filter(fn: (r) => r[\"_field\"] == \"value\")\n |> map(fn: (r) => ({ r with _value: r._value / 1000.0 })) \n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","yCol":"_value"},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear"}],"colorizeRows":true,"colors":[{"id":"2VIaJgN6zA7q-7pJxjW6R","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"54Pm1akf7W1i6Qu-haF2O","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"ka2GpKDmGeoX3CkjCsVB9","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"p2jDtNTUfRNUXEDkHLo3_","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"v1bMU4KDeOO9f-cKvLwcz","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"fKPuvSYrt7IdU29E-Lu4G","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"meYBhHM7mf6ZaNQiQy8vb","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"nu4Wev2n_a_Zu712_arTE","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Send count","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.custom.dht_sync_sent_count\")\n |> filter(fn: (r) => r[\"scenario_name\"] == \"dht_sync_lag\")\n |> filter(fn: (r) => r[\"run_id\"] == v.RunId)\n |> filter(fn: (r) => r[\"_field\"] == \"value\")\n |> increase()\n |> yield(name: \"increase\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":4},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear","suffix":"s"}],"colorizeRows":true,"colors":[{"id":"EeycwCWfyw0YSbHfK-_bg","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"reCGKSBa8F4FXQG3VYe_B","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"LwHjuuBTah-Q6Kv31XbMb","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"UYJNhccStV1szRDzc5ZS8","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"ZaGqV7BaVmHtlZZ7QiBR9","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"MLJ4MzW3SBtxs8E6jW8FB","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"XQFWzHtO8a6lHXL2D1mHH","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"mwVE20owCu-EGZVTQ7aca","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Sync Lag (max)","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.custom.dht_sync_lag\")\n |> filter(fn: (r) => r[\"scenario_name\"] == \"dht_sync_lag\")\n |> filter(fn: (r) => r[\"run_id\"] == v.RunId)\n |> filter(fn: (r) => r[\"_field\"] == \"value\")\n |> map(fn: (r) => ({ r with _value: r._value / 1000.0 })) \n |> aggregateWindow(every: v.windowPeriod, fn: max, createEmpty: false)\n |> yield(name: \"max\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","xPos":6,"yCol":"_value"},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear"}],"colorizeRows":true,"colors":[{"id":"2VIaJgN6zA7q-7pJxjW6R","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"54Pm1akf7W1i6Qu-haF2O","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"ka2GpKDmGeoX3CkjCsVB9","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"p2jDtNTUfRNUXEDkHLo3_","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"v1bMU4KDeOO9f-cKvLwcz","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"fKPuvSYrt7IdU29E-Lu4G","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"meYBhHM7mf6ZaNQiQy8vb","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"nu4Wev2n_a_Zu712_arTE","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Recieved count","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.custom.dht_sync_recv_count\")\n |> filter(fn: (r) => r[\"scenario_name\"] == \"dht_sync_lag\")\n |> filter(fn: (r) => r[\"run_id\"] == v.RunId)\n |> filter(fn: (r) => r[\"_field\"] == \"value\")\n |> increase()\n |> yield(name: \"increase\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","xPos":6,"yCol":"_value","yPos":4}],"description":"Custom charts for the dht_sync_lag scenario","name":"DHT Sync Lag"}}] \ No newline at end of file diff --git a/influx/templates/dashboards/host.json b/influx/templates/dashboards/host.json index f748d001..947e6191 100644 --- a/influx/templates/dashboards/host.json +++ b/influx/templates/dashboards/host.json @@ -1 +1 @@ -[{"apiVersion":"influxdata.com/v2alpha1","kind":"Dashboard","metadata":{"name":"dangling-ellis-d00001"},"spec":{"charts":[{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear"}],"colorizeRows":true,"colors":[{"id":"bbgfGLDcmvRyjmdEPN_br","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"4XLcdPRXBGxrCscxDmFo6","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"ebNrVA4Aaqs8oQ-gGuNx9","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"UAzJW5wnmATisyBlIYM4a","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"bKiBk-i5EVIrvDABhvW1B","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"hqlCB4If0HDV4rqhCmwRu","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"HK2fpW80wLddL7zfODftf","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"v1uO3eQ0KOkfC3nkaLEHa","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"CPU usage","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"cpu\")\n |> filter(fn: (r) => r[\"_field\"] == \"usage_idle\")\n |> filter(fn: (r) => r[\"cpu\"] == \"cpu-total\")\n |> filter(fn: (r) => r[\"host\"] == v.Host)\n |> map(fn: (r) => ({ r with _value: 100.0 - r._value }))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":12,"widthRatio":1,"xCol":"_time","yCol":"_value","yTickStep":10,"yTotalTicks":11},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear"}],"colorizeRows":true,"colors":[{"id":"T04f3vqJz3Mjqm6GY8UmD","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"zszcrhtv_2Fz7fPb6vd4g","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"5yZNdcVUb86LhFe-rm2jb","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"6SGv1m0rFrKZeGxs3lcbP","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"DNyPObWEpbOdHN8glzsz2","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"CMBvuj6rYCW1kFRVtlS7S","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"r2Sm6VWRNBr3c9uomqOUL","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"L1S6FXSzV1Z6PPkK9CWy-","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Memory usage","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"mem\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> filter(fn: (r) => r[\"host\"] == v.Host)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":12,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":4},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear"}],"colorizeRows":true,"colors":[{"id":"Wj5FBtPBcGEI2vmoUdObP","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"PSSgpSdOlzvYZ8s-c125B","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"ncp2frG8uPAhxSMi-O46h","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"__8btrVO7E6GJVcSWx8yb","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"c-1IiIpiCY0lFkIKto7Si","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"tpwua7WAQ5Q_gaLPp9jZS","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"fGmIYLRM9iI_3jvBJUMhz","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"1yGI-wkNyTXRsdUnvDzir","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Disk Read","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"diskio\")\n |> filter(fn: (r) => r[\"_field\"] == \"read_bytes\")\n |> filter(fn: (r) => r[\"host\"] == v.Host)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":8},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear"}],"colorizeRows":true,"colors":[{"id":"Wj5FBtPBcGEI2vmoUdObP","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"PSSgpSdOlzvYZ8s-c125B","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"ncp2frG8uPAhxSMi-O46h","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"__8btrVO7E6GJVcSWx8yb","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"c-1IiIpiCY0lFkIKto7Si","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"tpwua7WAQ5Q_gaLPp9jZS","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"fGmIYLRM9iI_3jvBJUMhz","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"1yGI-wkNyTXRsdUnvDzir","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Disk Write","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"diskio\")\n |> filter(fn: (r) => r[\"_field\"] == \"write_bytes\")\n |> filter(fn: (r) => r[\"host\"] == v.Host)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","xPos":6,"yCol":"_value","yPos":8}],"name":"Host"}}] \ No newline at end of file +[{"apiVersion":"influxdata.com/v2alpha1","kind":"Dashboard","metadata":{"name":"awesome-feistel-5cc001"},"spec":{"charts":[{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear"}],"colorizeRows":true,"colors":[{"id":"bbgfGLDcmvRyjmdEPN_br","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"4XLcdPRXBGxrCscxDmFo6","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"ebNrVA4Aaqs8oQ-gGuNx9","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"UAzJW5wnmATisyBlIYM4a","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"bKiBk-i5EVIrvDABhvW1B","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"hqlCB4If0HDV4rqhCmwRu","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"HK2fpW80wLddL7zfODftf","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"v1uO3eQ0KOkfC3nkaLEHa","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"CPU usage","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"cpu\")\n |> filter(fn: (r) => r[\"_field\"] == \"usage_idle\")\n |> filter(fn: (r) => r[\"cpu\"] == \"cpu-total\")\n |> filter(fn: (r) => r[\"host\"] == v.Host)\n |> map(fn: (r) => ({ r with _value: 100.0 - r._value }))\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":12,"widthRatio":1,"xCol":"_time","yCol":"_value","yTickStep":10,"yTotalTicks":11},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear"}],"colorizeRows":true,"colors":[{"id":"T04f3vqJz3Mjqm6GY8UmD","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"zszcrhtv_2Fz7fPb6vd4g","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"5yZNdcVUb86LhFe-rm2jb","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"6SGv1m0rFrKZeGxs3lcbP","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"DNyPObWEpbOdHN8glzsz2","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"CMBvuj6rYCW1kFRVtlS7S","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"r2Sm6VWRNBr3c9uomqOUL","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"L1S6FXSzV1Z6PPkK9CWy-","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Memory usage","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"mem\")\n |> filter(fn: (r) => r[\"_field\"] == \"used_percent\")\n |> filter(fn: (r) => r[\"host\"] == v.Host)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":12,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":4},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear"}],"colorizeRows":true,"colors":[{"id":"Wj5FBtPBcGEI2vmoUdObP","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"PSSgpSdOlzvYZ8s-c125B","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"ncp2frG8uPAhxSMi-O46h","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"__8btrVO7E6GJVcSWx8yb","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"c-1IiIpiCY0lFkIKto7Si","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"tpwua7WAQ5Q_gaLPp9jZS","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"fGmIYLRM9iI_3jvBJUMhz","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"1yGI-wkNyTXRsdUnvDzir","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Disk Read","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"diskio\")\n |> filter(fn: (r) => r[\"_field\"] == \"read_bytes\")\n |> filter(fn: (r) => r[\"host\"] == v.Host)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":8},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","name":"y","scale":"linear"}],"colorizeRows":true,"colors":[{"id":"Wj5FBtPBcGEI2vmoUdObP","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"PSSgpSdOlzvYZ8s-c125B","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"ncp2frG8uPAhxSMi-O46h","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"__8btrVO7E6GJVcSWx8yb","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"c-1IiIpiCY0lFkIKto7Si","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"tpwua7WAQ5Q_gaLPp9jZS","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"fGmIYLRM9iI_3jvBJUMhz","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"1yGI-wkNyTXRsdUnvDzir","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Disk Write","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"diskio\")\n |> filter(fn: (r) => r[\"_field\"] == \"write_bytes\")\n |> filter(fn: (r) => r[\"host\"] == v.Host)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","xPos":6,"yCol":"_value","yPos":8}],"description":"System metrics for the host that is running Wind Tunnel scenarios","name":"Host"}}] \ No newline at end of file diff --git a/influx/templates/dashboards/local_signals.json b/influx/templates/dashboards/local_signals.json new file mode 100644 index 00000000..f8c5310d --- /dev/null +++ b/influx/templates/dashboards/local_signals.json @@ -0,0 +1 @@ +[{"apiVersion":"influxdata.com/v2alpha1","kind":"Dashboard","metadata":{"name":"compassionate-goldwasser-a11001"},"spec":{"charts":[{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","label":"Time","name":"y","scale":"linear","suffix":"s"}],"colorizeRows":true,"colors":[{"id":"fqf-j27KQoG6ESSw1OtLY","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"5j6yXT3gcCpEC7ZTBEfej","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"mE0fU-FXA-uGil_MhKtIy","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"0UDll-4AbIIafKg57tlAw","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"P6ySVh64Vu922jjkivJT2","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"V1DvyLMb_uwT76pWL1ND6","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"rdtdOAMOO8ZHdLi7hQVKO","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"yf3nJ84cL25hiJKJ0tb5y","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Signal emit","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.custom.signal_batch_send\")\n |> filter(fn: (r) => r[\"scenario_name\"] == \"local_signals\")\n |> filter(fn: (r) => r[\"run_id\"] == v.RunId)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":12,"widthRatio":1,"xCol":"_time","yCol":"_value"},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","label":"Time","name":"y","scale":"linear","suffix":"s"}],"colorizeRows":true,"colors":[{"id":"fqf-j27KQoG6ESSw1OtLY","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"5j6yXT3gcCpEC7ZTBEfej","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"mE0fU-FXA-uGil_MhKtIy","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"0UDll-4AbIIafKg57tlAw","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"P6ySVh64Vu922jjkivJT2","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"V1DvyLMb_uwT76pWL1ND6","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"rdtdOAMOO8ZHdLi7hQVKO","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"yf3nJ84cL25hiJKJ0tb5y","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Signal receive","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.custom.signal_batch_recv\")\n |> filter(fn: (r) => r[\"scenario_name\"] == \"local_signals\")\n |> filter(fn: (r) => r[\"run_id\"] == v.RunId)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":12,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":4},{"axes":[{"base":"10","name":"x","scale":"linear"},{"label":"Success (%)","name":"y","scale":"linear","suffix":"%"}],"colorizeRows":true,"colors":[{"id":"RtzTBNRht6lZ_JsXYli_f","name":"Nineteen Eighty Four","type":"scale","hex":"#31C0F6"},{"id":"c044Oyl-DVPzc4Rr66kbD","name":"Nineteen Eighty Four","type":"scale","hex":"#A500A5"},{"id":"Ut_N7DLlE8cWE4hP7XgRX","name":"Nineteen Eighty Four","type":"scale","hex":"#FF7E27"}],"geom":"line","height":4,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Success rate","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.custom.signal_success_pct\")\n |> filter(fn: (r) => r[\"run_id\"] == v.RunId) \n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":12,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":8}],"description":"Custom chargts for the local_signals scenario","name":"Local signals"}}] \ No newline at end of file diff --git a/influx/templates/dashboards/zome_calls.json b/influx/templates/dashboards/zome_calls.json index a4317444..1c70e914 100644 --- a/influx/templates/dashboards/zome_calls.json +++ b/influx/templates/dashboards/zome_calls.json @@ -1 +1 @@ -[{"apiVersion":"influxdata.com/v2alpha1","kind":"Dashboard","metadata":{"name":"heuristic-almeida-100001"},"spec":{"charts":[{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","label":"Call Time","name":"y","scale":"linear","suffix":"ms"}],"colorizeRows":true,"colors":[{"id":"gYm7AaJv2yMV9UHhbHtmU","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"2MmbxWBAc6EkxueH74UGz","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"QqttvMw-Trmh5zJp7fLMm","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"YHgYSRxhg1HzMzp_jrrdh","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"CvTZXG2-bBCcNrDl9IcdU","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"0YMgzEo9FQM_I--ISYUwB","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"oojmDptSlY_CT_ND72vD7","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"t9AHryWl6IGKNLP62e9ek","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":6,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Call Zome (mean)","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.instruments.operation_duration\")\n |> filter(fn: (r) => r[\"_field\"] == \"value\")\n |> filter(fn: (r) => r[\"operation_id\"] == \"app_agent_call_zome\")\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","yCol":"_value"},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","label":"Call Time","name":"y","scale":"linear","suffix":"ms"}],"colorizeRows":true,"colors":[{"id":"gYm7AaJv2yMV9UHhbHtmU","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"2MmbxWBAc6EkxueH74UGz","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"QqttvMw-Trmh5zJp7fLMm","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"YHgYSRxhg1HzMzp_jrrdh","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"CvTZXG2-bBCcNrDl9IcdU","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"0YMgzEo9FQM_I--ISYUwB","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"oojmDptSlY_CT_ND72vD7","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"t9AHryWl6IGKNLP62e9ek","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":6,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Call Zome by Zome (mean)","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.instruments.operation_duration\")\n |> filter(fn: (r) => r[\"_field\"] == \"value\")\n |> filter(fn: (r) => r[\"operation_id\"] == \"app_agent_call_zome\")\n |> filter(fn: (r) => r[\"zome_name\"] == v.ZomeName)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":6},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","label":"Call Time","name":"y","scale":"linear","suffix":"ms"}],"colorizeRows":true,"colors":[{"id":"gYm7AaJv2yMV9UHhbHtmU","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"2MmbxWBAc6EkxueH74UGz","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"QqttvMw-Trmh5zJp7fLMm","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"YHgYSRxhg1HzMzp_jrrdh","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"CvTZXG2-bBCcNrDl9IcdU","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"0YMgzEo9FQM_I--ISYUwB","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"oojmDptSlY_CT_ND72vD7","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"t9AHryWl6IGKNLP62e9ek","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":6,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Call Zome by Function (mean)","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.instruments.operation_duration\")\n |> filter(fn: (r) => r[\"_field\"] == \"value\")\n |> filter(fn: (r) => r[\"operation_id\"] == \"app_agent_call_zome\")\n |> filter(fn: (r) => r[\"fn_name\"] == v.FunctionName)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":12},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","label":"Call Time","name":"y","scale":"linear","suffix":"ms"}],"colorizeRows":true,"colors":[{"id":"gYm7AaJv2yMV9UHhbHtmU","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"2MmbxWBAc6EkxueH74UGz","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"QqttvMw-Trmh5zJp7fLMm","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"YHgYSRxhg1HzMzp_jrrdh","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"CvTZXG2-bBCcNrDl9IcdU","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"0YMgzEo9FQM_I--ISYUwB","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"oojmDptSlY_CT_ND72vD7","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"t9AHryWl6IGKNLP62e9ek","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":6,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Call Zome (max)","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.instruments.operation_duration\")\n |> filter(fn: (r) => r[\"_field\"] == \"value\")\n |> filter(fn: (r) => r[\"operation_id\"] == \"app_agent_call_zome\")\n |> aggregateWindow(every: v.windowPeriod, fn: max, createEmpty: false)\n |> yield(name: \"max\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","xPos":6,"yCol":"_value"},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","label":"Call Time","name":"y","scale":"linear","suffix":"ms"}],"colorizeRows":true,"colors":[{"id":"gYm7AaJv2yMV9UHhbHtmU","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"2MmbxWBAc6EkxueH74UGz","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"QqttvMw-Trmh5zJp7fLMm","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"YHgYSRxhg1HzMzp_jrrdh","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"CvTZXG2-bBCcNrDl9IcdU","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"0YMgzEo9FQM_I--ISYUwB","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"oojmDptSlY_CT_ND72vD7","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"t9AHryWl6IGKNLP62e9ek","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":6,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Call Zome by Zome (max)","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.instruments.operation_duration\")\n |> filter(fn: (r) => r[\"_field\"] == \"value\")\n |> filter(fn: (r) => r[\"operation_id\"] == \"app_agent_call_zome\")\n |> filter(fn: (r) => r[\"zome_name\"] == v.ZomeName)\n |> aggregateWindow(every: v.windowPeriod, fn: max, createEmpty: false)\n |> yield(name: \"max\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","xPos":6,"yCol":"_value","yPos":6},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","label":"Call Time","name":"y","scale":"linear","suffix":"ms"}],"colorizeRows":true,"colors":[{"id":"gYm7AaJv2yMV9UHhbHtmU","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"2MmbxWBAc6EkxueH74UGz","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"QqttvMw-Trmh5zJp7fLMm","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"YHgYSRxhg1HzMzp_jrrdh","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"CvTZXG2-bBCcNrDl9IcdU","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"0YMgzEo9FQM_I--ISYUwB","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"oojmDptSlY_CT_ND72vD7","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"t9AHryWl6IGKNLP62e9ek","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":6,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Call Zome by Function (max)","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.instruments.operation_duration\")\n |> filter(fn: (r) => r[\"_field\"] == \"value\")\n |> filter(fn: (r) => r[\"operation_id\"] == \"app_agent_call_zome\")\n |> filter(fn: (r) => r[\"fn_name\"] == v.FunctionName)\n |> aggregateWindow(every: v.windowPeriod, fn: max, createEmpty: false)\n |> yield(name: \"max\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","xPos":6,"yCol":"_value","yPos":12}],"name":"Zome calls"}}] \ No newline at end of file +[{"apiVersion":"influxdata.com/v2alpha1","kind":"Dashboard","metadata":{"name":"funny-williamson-9cc001"},"spec":{"charts":[{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","label":"Call Time","name":"y","scale":"linear","suffix":"ms"}],"colorizeRows":true,"colors":[{"id":"gYm7AaJv2yMV9UHhbHtmU","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"2MmbxWBAc6EkxueH74UGz","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"QqttvMw-Trmh5zJp7fLMm","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"YHgYSRxhg1HzMzp_jrrdh","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"CvTZXG2-bBCcNrDl9IcdU","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"0YMgzEo9FQM_I--ISYUwB","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"oojmDptSlY_CT_ND72vD7","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"t9AHryWl6IGKNLP62e9ek","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":6,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Call Zome (mean)","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.instruments.operation_duration\")\n |> filter(fn: (r) => r[\"_field\"] == \"value\")\n |> filter(fn: (r) => r[\"scenario_name\"] == v.ScenarioName)\n |> filter(fn: (r) => r[\"run_id\"] == v.RunId)\n |> filter(fn: (r) => r[\"operation_id\"] == \"app_call_zome\")\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","yCol":"_value"},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","label":"Call Time","name":"y","scale":"linear","suffix":"ms"}],"colorizeRows":true,"colors":[{"id":"gYm7AaJv2yMV9UHhbHtmU","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"2MmbxWBAc6EkxueH74UGz","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"QqttvMw-Trmh5zJp7fLMm","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"YHgYSRxhg1HzMzp_jrrdh","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"CvTZXG2-bBCcNrDl9IcdU","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"0YMgzEo9FQM_I--ISYUwB","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"oojmDptSlY_CT_ND72vD7","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"t9AHryWl6IGKNLP62e9ek","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":6,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Call Zome by Zome (mean)","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.instruments.operation_duration\")\n |> filter(fn: (r) => r[\"_field\"] == \"value\")\n |> filter(fn: (r) => r[\"scenario_name\"] == v.ScenarioName)\n |> filter(fn: (r) => r[\"run_id\"] == v.RunId)\n |> filter(fn: (r) => r[\"operation_id\"] == \"app_call_zome\")\n |> filter(fn: (r) => r[\"zome_name\"] == v.ZomeName)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":6},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","label":"Call Time","name":"y","scale":"linear","suffix":"ms"}],"colorizeRows":true,"colors":[{"id":"gYm7AaJv2yMV9UHhbHtmU","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"2MmbxWBAc6EkxueH74UGz","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"QqttvMw-Trmh5zJp7fLMm","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"YHgYSRxhg1HzMzp_jrrdh","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"CvTZXG2-bBCcNrDl9IcdU","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"0YMgzEo9FQM_I--ISYUwB","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"oojmDptSlY_CT_ND72vD7","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"t9AHryWl6IGKNLP62e9ek","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":6,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Call Zome by Function (mean)","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.instruments.operation_duration\")\n |> filter(fn: (r) => r[\"_field\"] == \"value\")\n |> filter(fn: (r) => r[\"scenario_name\"] == v.ScenarioName)\n |> filter(fn: (r) => r[\"run_id\"] == v.RunId)\n |> filter(fn: (r) => r[\"operation_id\"] == \"app_call_zome\")\n |> filter(fn: (r) => r[\"zome_name\"] == v.ZomeName)\n |> filter(fn: (r) => r[\"fn_name\"] == v.FunctionName)\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: \"mean\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","yCol":"_value","yPos":12},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","label":"Call Time","name":"y","scale":"linear","suffix":"ms"}],"colorizeRows":true,"colors":[{"id":"gYm7AaJv2yMV9UHhbHtmU","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"2MmbxWBAc6EkxueH74UGz","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"QqttvMw-Trmh5zJp7fLMm","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"YHgYSRxhg1HzMzp_jrrdh","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"CvTZXG2-bBCcNrDl9IcdU","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"0YMgzEo9FQM_I--ISYUwB","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"oojmDptSlY_CT_ND72vD7","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"t9AHryWl6IGKNLP62e9ek","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":6,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Call Zome (max)","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.instruments.operation_duration\")\n |> filter(fn: (r) => r[\"_field\"] == \"value\")\n |> filter(fn: (r) => r[\"scenario_name\"] == v.ScenarioName)\n |> filter(fn: (r) => r[\"run_id\"] == v.RunId)\n |> filter(fn: (r) => r[\"operation_id\"] == \"app_call_zome\")\n |> aggregateWindow(every: v.windowPeriod, fn: max, createEmpty: false)\n |> yield(name: \"max\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","xPos":6,"yCol":"_value"},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","label":"Call Time","name":"y","scale":"linear","suffix":"ms"}],"colorizeRows":true,"colors":[{"id":"gYm7AaJv2yMV9UHhbHtmU","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"2MmbxWBAc6EkxueH74UGz","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"QqttvMw-Trmh5zJp7fLMm","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"YHgYSRxhg1HzMzp_jrrdh","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"CvTZXG2-bBCcNrDl9IcdU","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"0YMgzEo9FQM_I--ISYUwB","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"oojmDptSlY_CT_ND72vD7","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"t9AHryWl6IGKNLP62e9ek","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":6,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Call Zome by Zome (max)","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.instruments.operation_duration\")\n |> filter(fn: (r) => r[\"_field\"] == \"value\")\n |> filter(fn: (r) => r[\"scenario_name\"] == v.ScenarioName)\n |> filter(fn: (r) => r[\"run_id\"] == v.RunId)\n |> filter(fn: (r) => r[\"operation_id\"] == \"app_call_zome\")\n |> filter(fn: (r) => r[\"zome_name\"] == v.ZomeName)\n |> aggregateWindow(every: v.windowPeriod, fn: max, createEmpty: false)\n |> yield(name: \"max\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","xPos":6,"yCol":"_value","yPos":6},{"axes":[{"base":"10","name":"x","scale":"linear"},{"base":"10","label":"Call Time","name":"y","scale":"linear","suffix":"ms"}],"colorizeRows":true,"colors":[{"id":"gYm7AaJv2yMV9UHhbHtmU","name":"Color Blind Friendly - Light","type":"scale","hex":"#FFFFFF"},{"id":"2MmbxWBAc6EkxueH74UGz","name":"Color Blind Friendly - Light","type":"scale","hex":"#E69F00"},{"id":"QqttvMw-Trmh5zJp7fLMm","name":"Color Blind Friendly - Light","type":"scale","hex":"#56B4E9"},{"id":"YHgYSRxhg1HzMzp_jrrdh","name":"Color Blind Friendly - Light","type":"scale","hex":"#009E73"},{"id":"CvTZXG2-bBCcNrDl9IcdU","name":"Color Blind Friendly - Light","type":"scale","hex":"#F0E442"},{"id":"0YMgzEo9FQM_I--ISYUwB","name":"Color Blind Friendly - Light","type":"scale","hex":"#0072B2"},{"id":"oojmDptSlY_CT_ND72vD7","name":"Color Blind Friendly - Light","type":"scale","hex":"#D55E00"},{"id":"t9AHryWl6IGKNLP62e9ek","name":"Color Blind Friendly - Light","type":"scale","hex":"#CC79A7"}],"geom":"line","height":6,"hoverDimension":"auto","kind":"Xy","legendColorizeRows":true,"legendOpacity":1,"legendOrientationThreshold":100000000,"name":"Call Zome by Function (max)","opacity":1,"orientationThreshold":100000000,"position":"overlaid","queries":[{"query":"from(bucket: \"windtunnel\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"_measurement\"] == \"wt.instruments.operation_duration\")\n |> filter(fn: (r) => r[\"_field\"] == \"value\")\n |> filter(fn: (r) => r[\"scenario_name\"] == v.ScenarioName)\n |> filter(fn: (r) => r[\"run_id\"] == v.RunId)\n |> filter(fn: (r) => r[\"operation_id\"] == \"app_call_zome\")\n |> filter(fn: (r) => r[\"zome_name\"] == v.ZomeName)\n |> filter(fn: (r) => r[\"fn_name\"] == v.FunctionName)\n |> aggregateWindow(every: v.windowPeriod, fn: max, createEmpty: false)\n |> yield(name: \"max\")"}],"shade":true,"staticLegend":{"colorizeRows":true,"opacity":1,"orientationThreshold":100000000,"widthRatio":1},"width":6,"widthRatio":1,"xCol":"_time","xPos":6,"yCol":"_value","yPos":12}],"description":"Generic charts for exploring zome calls","name":"Zome calls"}}] \ No newline at end of file diff --git a/influx/templates/variables/runid.json b/influx/templates/variables/runid.json new file mode 100644 index 00000000..5d6c6df9 --- /dev/null +++ b/influx/templates/variables/runid.json @@ -0,0 +1 @@ +[{"apiVersion":"influxdata.com/v2alpha1","kind":"Variable","metadata":{"name":"charming-cannon-1cc001"},"spec":{"language":"flux","name":"RunId","query":"import \"influxdata/influxdb/schema\"\nschema.tagValues(bucket: \"windtunnel\", tag: \"run_id\")","type":"query"}}] \ No newline at end of file diff --git a/influx/templates/variables/scenarioname.json b/influx/templates/variables/scenarioname.json new file mode 100644 index 00000000..e48293ea --- /dev/null +++ b/influx/templates/variables/scenarioname.json @@ -0,0 +1 @@ +[{"apiVersion":"influxdata.com/v2alpha1","kind":"Variable","metadata":{"name":"affectionate-aryabhata-1cc001"},"spec":{"language":"flux","name":"ScenarioName","query":"import \"influxdata/influxdb/schema\"\nschema.tagValues(bucket: \"windtunnel\", tag: \"scenario_name\")","type":"query"}}] \ No newline at end of file diff --git a/scenarios/app_install/Cargo.toml b/scenarios/app_install/Cargo.toml new file mode 100644 index 00000000..788b528b --- /dev/null +++ b/scenarios/app_install/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "app_install" +version = "0.1.0" +edition = "2021" +build = "../scenario_build.rs" + +[dependencies] +anyhow = { workspace = true } +holochain_types = { workspace = true } +holochain_wind_tunnel_runner = { workspace = true } + +[build-dependencies] +happ_builder = { workspace = true } + +[lints] +workspace = true + +[[package.metadata.required-dna]] +name = "callback" +zomes = ["callback"] + +[[package.metadata.required-happ]] +name = "callback" +dnas = ["callback"] + +[[package.metadata.required-dna]] +name = "large" +zomes = ["large"] + +[[package.metadata.required-happ]] +name = "large" +dnas = ["large"] diff --git a/scenarios/app_install/README.md b/scenarios/app_install/README.md new file mode 100644 index 00000000..574b722e --- /dev/null +++ b/scenarios/app_install/README.md @@ -0,0 +1,24 @@ +## app_install + +### Description + +This scenario has two roles: +- **minimal**: Installs a simple app which implements initialisation callbacks but otherwise doesn't contain a lot of code. +- **large**: Installs a larger app that contains some dependencies and some generated data as padding to make the bundle larger. + These are intended to catch a compilation slowdown or issues with copying around large WASMs (e.g. accidental cloning or tracing). + +In each case, the behaviour will uninstall the app it installed so that it can re-install it on the next iteration. + +### Suggested command + +You can run the scenario locally with the following command: + +For the `minimal` case: +```bash +RUST_LOG=info cargo run --package app_install -- --connection-string ws://localhost:8888 --behaviour minimal --duration 300 +``` + +For the `large` case: +```bash +RUST_LOG=info cargo run --package app_install -- --connection-string ws://localhost:8888 --behaviour large --duration 300 +``` diff --git a/scenarios/app_install/src/main.rs b/scenarios/app_install/src/main.rs new file mode 100644 index 00000000..c3b19c01 --- /dev/null +++ b/scenarios/app_install/src/main.rs @@ -0,0 +1,88 @@ +use holochain_wind_tunnel_runner::prelude::*; +use holochain_wind_tunnel_runner::scenario_happ_path; +use std::path::{Path, PathBuf}; +use std::time::Instant; + +#[derive(Debug, Default)] +struct ScenarioValues { + admin_client: Option, +} + +impl UserValuesConstraint for ScenarioValues {} + +fn setup(ctx: &mut RunnerContext) -> HookResult { + configure_app_ws_url(ctx)?; + Ok(()) +} + +fn agent_setup( + ctx: &mut AgentContext>, +) -> HookResult { + let admin_url = ctx.runner_context().get_connection_string(); + let reporter = ctx.runner_context().reporter(); + let admin_client = ctx + .runner_context() + .executor() + .execute_in_place(async move { + let admin_client = AdminWebsocket::connect(admin_url, reporter).await?; + Ok(admin_client) + })?; + + ctx.get_mut().scenario_values.admin_client = Some(admin_client); + + Ok(()) +} + +fn agent_behaviour_minimal( + ctx: &mut AgentContext>, +) -> HookResult { + install_app_behaviour(ctx, scenario_happ_path!("callback"), "callback")?; + + Ok(()) +} + +fn agent_behaviour_large( + ctx: &mut AgentContext>, +) -> HookResult { + install_app_behaviour(ctx, scenario_happ_path!("large"), "large")?; + Ok(()) +} + +fn install_app_behaviour( + ctx: &mut AgentContext>, + happ_path: PathBuf, + happ_name: &str, +) -> HookResult { + let start = Instant::now(); + install_app(ctx, happ_path, &happ_name.to_string())?; + let install_time_s = start.elapsed().as_secs_f64(); + + uninstall_app(ctx, None)?; + + let metric = ReportMetric::new("app_install") + .with_tag("happ", happ_name.to_string()) + .with_field("value", install_time_s); + ctx.runner_context().reporter().clone().add_custom(metric); + + Ok(()) +} + +fn main() -> WindTunnelResult<()> { + let builder = ScenarioDefinitionBuilder::< + HolochainRunnerContext, + HolochainAgentContext, + >::new_with_init(env!("CARGO_PKG_NAME")) + .with_default_duration_s(60) + .use_setup(setup) + .use_agent_setup(agent_setup) + .use_named_agent_behaviour("minimal", agent_behaviour_minimal) + .use_named_agent_behaviour("large", agent_behaviour_large) + .use_agent_teardown(|ctx| { + uninstall_app(ctx, None).ok(); + Ok(()) + }); + + run(builder)?; + + Ok(()) +} diff --git a/scenarios/dht_sync_lag/src/main.rs b/scenarios/dht_sync_lag/src/main.rs index 3400e432..e99790a9 100644 --- a/scenarios/dht_sync_lag/src/main.rs +++ b/scenarios/dht_sync_lag/src/main.rs @@ -107,7 +107,11 @@ fn main() -> WindTunnelResult<()> { .use_setup(setup) .use_agent_setup(agent_setup) .use_named_agent_behaviour("write", agent_behaviour_write) - .use_named_agent_behaviour("record_lag", agent_behaviour_record_lag); + .use_named_agent_behaviour("record_lag", agent_behaviour_record_lag) + .use_agent_teardown(|ctx| { + uninstall_app(ctx, None).ok(); + Ok(()) + }); run(builder)?; diff --git a/scenarios/first_call/Cargo.toml b/scenarios/first_call/Cargo.toml new file mode 100644 index 00000000..5a2de814 --- /dev/null +++ b/scenarios/first_call/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "first_call" +version = "0.1.0" +edition = "2021" +build = "../scenario_build.rs" + +[dependencies] +anyhow = { workspace = true } +holochain_types = { workspace = true } +holochain_wind_tunnel_runner = { workspace = true } +timed_integrity = { workspace = true } + +[build-dependencies] +happ_builder = { workspace = true } + +[lints] +workspace = true + +[package.metadata.required-dna] +name = "crud" +zomes = ["crud"] + +[package.metadata.required-happ] +name = "crud" +dnas = ["crud"] diff --git a/scenarios/first_call/README.md b/scenarios/first_call/README.md new file mode 100644 index 00000000..48e117de --- /dev/null +++ b/scenarios/first_call/README.md @@ -0,0 +1,18 @@ +## first_call + +### Description + +This scenario has one: +- **local**: Installs a simple app which implements initialisation callbacks but otherwise doesn't contain a lot of code. + +The behaviour will uninstall the app it installed so that it can re-install it on the next iteration. This is required +to re-run the initialisation callback. + +### Suggested command + +You can run the scenario locally with the following command: + +For the `local` case: +```bash +RUST_LOG=info cargo run --package first_call -- --connection-string ws://localhost:8888 --behaviour local --duration 300 +``` diff --git a/scenarios/first_call/src/main.rs b/scenarios/first_call/src/main.rs new file mode 100644 index 00000000..b070b62a --- /dev/null +++ b/scenarios/first_call/src/main.rs @@ -0,0 +1,65 @@ +use holochain_types::prelude::ActionHash; +use holochain_wind_tunnel_runner::prelude::*; +use holochain_wind_tunnel_runner::scenario_happ_path; +use std::path::Path; + +#[derive(Debug, Default)] +struct ScenarioValues { + admin_client: Option, +} + +impl UserValuesConstraint for ScenarioValues {} + +fn setup(ctx: &mut RunnerContext) -> HookResult { + configure_app_ws_url(ctx)?; + Ok(()) +} + +fn agent_setup( + ctx: &mut AgentContext>, +) -> HookResult { + let admin_url = ctx.runner_context().get_connection_string(); + let reporter = ctx.runner_context().reporter(); + let admin_client = ctx + .runner_context() + .executor() + .execute_in_place(async move { + let admin_client = AdminWebsocket::connect(admin_url, reporter).await?; + Ok(admin_client) + })?; + + ctx.get_mut().scenario_values.admin_client = Some(admin_client); + + Ok(()) +} + +fn agent_behaviour_local( + ctx: &mut AgentContext>, +) -> HookResult { + install_app(ctx, scenario_happ_path!("crud"), &"crud".into())?; + + let _: ActionHash = call_zome(ctx, "crud", "create_sample_entry", "a value")?; + + uninstall_app(ctx, None)?; + + Ok(()) +} + +fn main() -> WindTunnelResult<()> { + let builder = ScenarioDefinitionBuilder::< + HolochainRunnerContext, + HolochainAgentContext, + >::new_with_init(env!("CARGO_PKG_NAME")) + .with_default_duration_s(60) + .use_setup(setup) + .use_agent_setup(agent_setup) + .use_named_agent_behaviour("local", agent_behaviour_local) + .use_agent_teardown(|ctx| { + uninstall_app(ctx, None).ok(); + Ok(()) + }); + + run(builder)?; + + Ok(()) +} diff --git a/scenarios/local_signals/Cargo.toml b/scenarios/local_signals/Cargo.toml new file mode 100644 index 00000000..bdbf88bd --- /dev/null +++ b/scenarios/local_signals/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "local_signals" +version = "0.1.0" +edition = "2021" +build = "../scenario_build.rs" + +[dependencies] +anyhow = { workspace = true } +tokio = { workspace = true } +holochain_types = { workspace = true } +holochain_wind_tunnel_runner = { workspace = true } + +[build-dependencies] +happ_builder = { workspace = true } + +[lints] +workspace = true + +[package.metadata.required-dna] +name = "signal" +zomes = ["signal"] + +[package.metadata.required-happ] +name = "signal" +dnas = ["signal"] diff --git a/scenarios/local_signals/README.md b/scenarios/local_signals/README.md new file mode 100644 index 00000000..7b37cd73 --- /dev/null +++ b/scenarios/local_signals/README.md @@ -0,0 +1,15 @@ +## app_install + +### Description + +This scenario is for testing the speed and reliability of local signals. It uses a zome with a function that will emit +10,000 signals. The scenario measures how long it takes to send the signals and how many have been received by the time +the zome call ends. + +### Suggested command + +You can run the scenario locally with the following command: + +```bash +RUST_LOG=info cargo run --package local_signals -- --connection-string ws://localhost:8888 --duration 300 +``` diff --git a/scenarios/local_signals/src/main.rs b/scenarios/local_signals/src/main.rs new file mode 100644 index 00000000..b795efbf --- /dev/null +++ b/scenarios/local_signals/src/main.rs @@ -0,0 +1,98 @@ +use holochain_wind_tunnel_runner::prelude::*; +use holochain_wind_tunnel_runner::scenario_happ_path; +use std::path::Path; +use std::sync::atomic::AtomicU32; +use std::sync::Arc; +use std::time::Instant; + +fn setup(ctx: &mut RunnerContext) -> HookResult { + configure_app_ws_url(ctx)?; + Ok(()) +} + +fn agent_setup( + ctx: &mut AgentContext, +) -> HookResult { + install_app(ctx, scenario_happ_path!("signal"), &"signal".into())?; + + Ok(()) +} + +fn agent_behaviour( + ctx: &mut AgentContext, +) -> HookResult { + let received_count = Arc::new(AtomicU32::new(0)); + + let app_client = ctx.get().app_client(); + ctx.runner_context().executor().execute_in_place({ + let received_count = received_count.clone(); + async move { + app_client + .on_signal(move |_signal| { + received_count.fetch_add(1, std::sync::atomic::Ordering::Acquire); + }) + .await?; + + Ok(()) + } + })?; + + let start = Instant::now(); + call_zome(ctx, "signal", "emit_10k_signals", ())?; + let send_elapsed_s = start.elapsed().as_secs_f64(); + + ctx.runner_context().executor().execute_in_place({ + let received_count = received_count.clone(); + async move { + tokio::time::timeout(std::time::Duration::from_secs(30), async move { + loop { + let received_count = received_count.load(std::sync::atomic::Ordering::Acquire); + if received_count >= 10_000 { + break; + } else { + // Lower values make the metrics more accurate, but a higher value lets the scenario use less CPU. + tokio::time::sleep(std::time::Duration::from_millis(250)).await; + } + } + }) + .await + .ok(); + + Ok(()) + } + })?; + + let recv_elapsed_s = start.elapsed().as_secs_f64(); + + let metric = ReportMetric::new("signal_batch_send").with_field("value", send_elapsed_s); + ctx.runner_context().reporter().clone().add_custom(metric); + + let metric = ReportMetric::new("signal_batch_recv").with_field("value", recv_elapsed_s); + ctx.runner_context().reporter().clone().add_custom(metric); + + let received_count = received_count.load(std::sync::atomic::Ordering::Acquire); + let metric = + ReportMetric::new("signal_success_pct").with_field("value", received_count as f32 / 100.0); + ctx.runner_context().reporter().clone().add_custom(metric); + + Ok(()) +} + +fn main() -> WindTunnelResult<()> { + let builder = + ScenarioDefinitionBuilder::::new_with_init( + env!("CARGO_PKG_NAME"), + ) + .with_default_duration_s(60) + .use_setup(setup) + .use_agent_setup(agent_setup) + .use_agent_behaviour(agent_behaviour) + .use_agent_teardown(|ctx| { + uninstall_app(ctx, None).ok(); + Ok(()) + }); + + run(builder)?; + + Ok(()) +} diff --git a/scenarios/scenario_build.rs b/scenarios/scenario_build.rs index bd1c4254..60822427 100644 --- a/scenarios/scenario_build.rs +++ b/scenarios/scenario_build.rs @@ -1,4 +1,4 @@ -use happ_builder::{build_happs, BuildOptions, HappBuilderResult}; +use happ_builder::{build_happs, required_tools_available, BuildOptions, HappBuilderResult}; /// Build the required DNA(s) and hApps for the scenario. /// The built DNA(s) will appear as `/dnas//.dna` from the project root. @@ -9,5 +9,10 @@ fn main() -> HappBuilderResult { return Ok(()); } + if !required_tools_available() { + println!("cargo:warning=Missing required tools for building hApps. Skipping hApp build."); + return Ok(()); + } + build_happs(BuildOptions::default()) } diff --git a/scenarios/single_write_many_read/src/main.rs b/scenarios/single_write_many_read/src/main.rs index 82d96759..b4641ce8 100644 --- a/scenarios/single_write_many_read/src/main.rs +++ b/scenarios/single_write_many_read/src/main.rs @@ -57,7 +57,11 @@ fn main() -> WindTunnelResult<()> { .with_default_duration_s(60) .use_setup(setup) .use_agent_setup(agent_setup) - .use_agent_behaviour(agent_behaviour); + .use_agent_behaviour(agent_behaviour) + .use_agent_teardown(|ctx| { + uninstall_app(ctx, None).ok(); + Ok(()) + }); run(builder)?; diff --git a/scenarios/write_query/Cargo.toml b/scenarios/write_query/Cargo.toml new file mode 100644 index 00000000..85485abb --- /dev/null +++ b/scenarios/write_query/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "write_query" +version = "0.1.0" +edition = "2021" +build = "../scenario_build.rs" + +[dependencies] +anyhow = { workspace = true } +holochain_types = { workspace = true } +holochain_wind_tunnel_runner = { workspace = true } + +[build-dependencies] +happ_builder = { workspace = true } + +[lints] +workspace = true + +[package.metadata.required-dna] +name = "crud" +zomes = ["crud"] + +[package.metadata.required-happ] +name = "crud" +dnas = ["crud"] diff --git a/scenarios/write_query/README.md b/scenarios/write_query/README.md new file mode 100644 index 00000000..dcd26878 --- /dev/null +++ b/scenarios/write_query/README.md @@ -0,0 +1,11 @@ +## write_query + +### Description + +Creates an entry, then queries the source chain and performs a simple operation on the entries, then repeat. + +### Suggested command + +```bash +RUST_LOG=info cargo run --package write_query -- --connection-string ws://localhost:8888 --duration 300 +``` diff --git a/scenarios/write_query/src/main.rs b/scenarios/write_query/src/main.rs new file mode 100644 index 00000000..d67c95d4 --- /dev/null +++ b/scenarios/write_query/src/main.rs @@ -0,0 +1,69 @@ +use holochain_types::prelude::ActionHash; +use holochain_wind_tunnel_runner::prelude::*; +use holochain_wind_tunnel_runner::scenario_happ_path; +use std::path::Path; + +#[derive(Debug, Default)] +struct ScenarioValues { + call_count: u32, +} + +impl UserValuesConstraint for ScenarioValues {} + +fn setup(ctx: &mut RunnerContext) -> HookResult { + configure_app_ws_url(ctx)?; + Ok(()) +} + +fn agent_setup( + ctx: &mut AgentContext>, +) -> HookResult { + install_app(ctx, scenario_happ_path!("crud"), &"crud".to_string())?; + + Ok(()) +} + +fn agent_behaviour( + ctx: &mut AgentContext>, +) -> HookResult { + let _: ActionHash = call_zome( + ctx, + "crud", + "create_sample_entry", + "this is a test entry value", + )?; + + let response: u32 = call_zome(ctx, "crud", "chain_query_count_len", ())?; + + let values = &mut ctx.get_mut().scenario_values; + values.call_count += 1; + + // Minimal check that we're querying the right content and getting the expected result from the + // calculation in this zome function. + assert_eq!( + values.call_count * 26, + response, + "Expected call count to match response" + ); + + Ok(()) +} + +fn main() -> WindTunnelResult<()> { + let builder = ScenarioDefinitionBuilder::< + HolochainRunnerContext, + HolochainAgentContext, + >::new_with_init(env!("CARGO_PKG_NAME")) + .with_default_duration_s(60) + .use_setup(setup) + .use_agent_setup(agent_setup) + .use_agent_behaviour(agent_behaviour) + .use_agent_teardown(|ctx| { + uninstall_app(ctx, None).ok(); + Ok(()) + }); + + run(builder)?; + + Ok(()) +} diff --git a/scenarios/write_read/Cargo.toml b/scenarios/write_read/Cargo.toml new file mode 100644 index 00000000..e56438f2 --- /dev/null +++ b/scenarios/write_read/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "write_read" +version = "0.1.0" +edition = "2021" +build = "../scenario_build.rs" + +[dependencies] +anyhow = { workspace = true } +holochain_types = { workspace = true } +holochain_wind_tunnel_runner = { workspace = true } + +[build-dependencies] +happ_builder = { workspace = true } + +[lints] +workspace = true + +[package.metadata.required-dna] +name = "crud" +zomes = ["crud"] + +[package.metadata.required-happ] +name = "crud" +dnas = ["crud"] diff --git a/scenarios/write_read/README.md b/scenarios/write_read/README.md new file mode 100644 index 00000000..be55a365 --- /dev/null +++ b/scenarios/write_read/README.md @@ -0,0 +1,11 @@ +## write_read + +### Description + +Creates an entry and read it back, then repeat. + +### Suggested command + +```bash +RUST_LOG=info cargo run --package write_read -- --connection-string ws://localhost:8888 --duration 300 +``` diff --git a/scenarios/write_read/src/main.rs b/scenarios/write_read/src/main.rs new file mode 100644 index 00000000..b1a2558c --- /dev/null +++ b/scenarios/write_read/src/main.rs @@ -0,0 +1,53 @@ +use holochain_types::prelude::{ActionHash, Record}; +use holochain_wind_tunnel_runner::prelude::*; +use holochain_wind_tunnel_runner::scenario_happ_path; +use std::path::Path; + +fn setup(ctx: &mut RunnerContext) -> HookResult { + configure_app_ws_url(ctx)?; + Ok(()) +} + +fn agent_setup( + ctx: &mut AgentContext, +) -> HookResult { + install_app(ctx, scenario_happ_path!("crud"), &"crud".to_string())?; + + Ok(()) +} + +fn agent_behaviour( + ctx: &mut AgentContext, +) -> HookResult { + let action_hash: ActionHash = call_zome( + ctx, + "crud", + "create_sample_entry", + "this is a test entry value", + )?; + + let response: Option = call_zome(ctx, "crud", "get_sample_entry", action_hash)?; + + assert!(response.is_some(), "Expected record to be found"); + + Ok(()) +} + +fn main() -> WindTunnelResult<()> { + let builder = + ScenarioDefinitionBuilder::::new_with_init( + env!("CARGO_PKG_NAME"), + ) + .with_default_duration_s(60) + .use_setup(setup) + .use_agent_setup(agent_setup) + .use_agent_behaviour(agent_behaviour) + .use_agent_teardown(|ctx| { + uninstall_app(ctx, None).ok(); + Ok(()) + }); + + run(builder)?; + + Ok(()) +} diff --git a/scenarios/zome_call_single_value/src/main.rs b/scenarios/zome_call_single_value/src/main.rs index 2a365d74..b62d379a 100644 --- a/scenarios/zome_call_single_value/src/main.rs +++ b/scenarios/zome_call_single_value/src/main.rs @@ -35,7 +35,11 @@ fn main() -> WindTunnelResult<()> { .with_default_duration_s(60) .use_setup(setup) .use_agent_setup(agent_setup) - .use_agent_behaviour(agent_behaviour); + .use_agent_behaviour(agent_behaviour) + .use_agent_teardown(|ctx| { + uninstall_app(ctx, None).ok(); + Ok(()) + }); run(builder)?; diff --git a/zomes/callback/coordinator/Cargo.toml b/zomes/callback/coordinator/Cargo.toml new file mode 100644 index 00000000..be4ee909 --- /dev/null +++ b/zomes/callback/coordinator/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "callback" +version = "0.1.0" +edition = "2021" +description = "A Holochain coordinator zome with callbacks implemented" + +[lib] +name = "callback_coordinator" +path = "src/lib.rs" +crate-type = ["cdylib", "rlib"] + +[dependencies] +hdk = { workspace = true } +callback_integrity = { workspace = true } + +[lints] +workspace = true diff --git a/zomes/callback/coordinator/src/lib.rs b/zomes/callback/coordinator/src/lib.rs new file mode 100644 index 00000000..1906ae1f --- /dev/null +++ b/zomes/callback/coordinator/src/lib.rs @@ -0,0 +1,6 @@ +use hdk::prelude::*; + +#[hdk_extern] +fn init() -> ExternResult { + Ok(InitCallbackResult::Pass) +} diff --git a/zomes/callback/integrity/Cargo.toml b/zomes/callback/integrity/Cargo.toml new file mode 100644 index 00000000..ac5af338 --- /dev/null +++ b/zomes/callback/integrity/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "callback_integrity" +version = "0.1.0" +edition = "2021" +description = "A Holochain integrity zome with callbacks implemented" + +[lib] +name = "callback_integrity" +path = "src/lib.rs" +crate-type = ["cdylib", "rlib"] + +[dependencies] +hdi = { workspace = true } +serde = { workspace = true } + +## TODO watiing for a fix in 0.2.7-rc.1+ +#[target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies] +#getrandom = { version = "0.2", features = ["custom"] } + +[lints] +workspace = true diff --git a/zomes/callback/integrity/src/lib.rs b/zomes/callback/integrity/src/lib.rs new file mode 100644 index 00000000..4f106f39 --- /dev/null +++ b/zomes/callback/integrity/src/lib.rs @@ -0,0 +1,6 @@ +use hdi::prelude::*; + +#[hdk_extern] +pub fn genesis_self_check(_data: GenesisSelfCheckData) -> ExternResult { + Ok(ValidateCallbackResult::Valid) +} diff --git a/zomes/crud/coordinator/src/lib.rs b/zomes/crud/coordinator/src/lib.rs index 8e525243..3622c9b3 100644 --- a/zomes/crud/coordinator/src/lib.rs +++ b/zomes/crud/coordinator/src/lib.rs @@ -1,6 +1,20 @@ -use crud_integrity::{EntryTypes, SampleEntry}; +use crud_integrity::{EntryTypes, SampleEntry, UnitEntryTypes}; use hdk::prelude::*; +#[hdk_extern] +fn init() -> ExternResult { + create_cap_grant(CapGrantEntry { + tag: "access".into(), + access: CapAccess::Unrestricted, + functions: GrantedFunctions::Listed(BTreeSet::from([( + "crud".into(), + "create_sample_entry".into(), + )])), + })?; + + Ok(InitCallbackResult::Pass) +} + #[hdk_extern] fn create_sample_entry(value: String) -> ExternResult { create_entry(EntryTypes::SampleEntry(SampleEntry { value })) @@ -10,3 +24,22 @@ fn create_sample_entry(value: String) -> ExternResult { fn get_sample_entry(hash: ActionHash) -> ExternResult> { get(hash, GetOptions::local()) } + +#[hdk_extern] +fn chain_query_count_len() -> ExternResult { + let q = ChainQueryFilter::new() + .include_entries(true) + .entry_type(UnitEntryTypes::SampleEntry.try_into()?); + let results = query(q)?; + + let sum = results + .into_iter() + .filter_map(|r| { + let se: SampleEntry = r.entry.into_option().unwrap().try_into().ok()?; + Some(se) + }) + .map(|se| se.value.len()) + .sum::(); + + Ok(sum as u32) +} diff --git a/zomes/large/coordinator/Cargo.toml b/zomes/large/coordinator/Cargo.toml new file mode 100644 index 00000000..87a87d84 --- /dev/null +++ b/zomes/large/coordinator/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "large" +version = "0.1.0" +edition = "2021" +description = "A Holochain coordinator zome which produces a large app bundle" + +[lib] +name = "large_coordinator" +path = "src/lib.rs" +crate-type = ["cdylib", "rlib"] + +[dependencies] +hdk = { workspace = true } +anyhow = { workspace = true } +regex = "1.10.4" # Known to be large, contains data tables + +[lints] +workspace = true diff --git a/zomes/large/coordinator/src/lib.rs b/zomes/large/coordinator/src/lib.rs new file mode 100644 index 00000000..a9561186 --- /dev/null +++ b/zomes/large/coordinator/src/lib.rs @@ -0,0 +1,18 @@ +use hdk::prelude::*; + +#[hdk_extern] +fn init() -> ExternResult { + some_regex_fn().ok(); + + Ok(InitCallbackResult::Pass) +} + +fn some_regex_fn() -> anyhow::Result<()> { + let re = regex::Regex::new(r"^\d{4}-\d{2}-\d{2}$")?; + let date = "2021-01-01"; + if re.is_match(date) { + Ok(()) + } else { + anyhow::bail!("Invalid date") + } +} diff --git a/zomes/signal/coordinator/Cargo.toml b/zomes/signal/coordinator/Cargo.toml new file mode 100644 index 00000000..37afc1b0 --- /dev/null +++ b/zomes/signal/coordinator/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "signal" +version = "0.1.0" +edition = "2021" +description = "A Holochain coordinator zome for emiting signals" + +[lib] +name = "signal_coordinator" +path = "src/lib.rs" +crate-type = ["cdylib", "rlib"] + +[dependencies] +hdk = { workspace = true } + +[lints] +workspace = true diff --git a/zomes/signal/coordinator/src/lib.rs b/zomes/signal/coordinator/src/lib.rs new file mode 100644 index 00000000..ae27e751 --- /dev/null +++ b/zomes/signal/coordinator/src/lib.rs @@ -0,0 +1,10 @@ +use hdk::prelude::*; + +#[hdk_extern] +fn emit_10k_signals() -> ExternResult<()> { + for i in 0..10_000 { + emit_signal(format!("test payload {i}"))?; + } + + Ok(()) +}