From 42a0ac55b1eb3eef8c686ea6f859e210309b3561 Mon Sep 17 00:00:00 2001 From: Pietro Date: Sun, 14 Jan 2024 21:28:12 +0100 Subject: [PATCH 01/27] Add integration test for mainnet targets --- Cargo.lock | 95 +++++++++++++++++++ .../builders/prometheus_config_structure.rs | 4 +- .../multiservice-discovery/BUILD.bazel | 8 +- .../multiservice-discovery/Cargo.toml | 6 +- .../multiservice-discovery/tests/tests.rs | 55 +++++++++++ 5 files changed, 164 insertions(+), 4 deletions(-) create mode 100644 rs/ic-observability/multiservice-discovery/tests/tests.rs diff --git a/Cargo.lock b/Cargo.lock index 3da9cc24b..71d0453fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -450,6 +450,20 @@ dependencies = [ "serde_json", ] +[[package]] +name = "assert_cmd" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c98233c6673d8601ab23e77eb38f999c51100d46c5703b17288c57fddf3a1ffe" +dependencies = [ + "bstr", + "doc-comment", + "predicates", + "predicates-core", + "predicates-tree", + "wait-timeout", +] + [[package]] name = "assert_matches" version = "1.5.0" @@ -2261,6 +2275,12 @@ dependencies = [ "syn 2.0.48", ] +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + [[package]] name = "dotenv" version = "0.15.0" @@ -2691,6 +2711,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + [[package]] name = "funty" version = "2.0.0" @@ -5969,6 +5995,8 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" name = "multiservice-discovery" version = "0.1.0" dependencies = [ + "anyhow", + "assert_cmd", "base64 0.13.1", "clap 4.4.13", "crossbeam", @@ -5983,12 +6011,14 @@ dependencies = [ "ic-utils 0.9.0", "multiservice-discovery-shared", "regex", + "reqwest", "serde", "serde_json", "service-discovery", "slog", "slog-async", "slog-term", + "tempdir", "tokio", "url", "warp", @@ -7109,6 +7139,19 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +[[package]] +name = "rand" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +dependencies = [ + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "rdrand", + "winapi", +] + [[package]] name = "rand" version = "0.7.3" @@ -7153,6 +7196,21 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + [[package]] name = "rand_core" version = "0.5.1" @@ -7215,6 +7273,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + [[package]] name = "redox_syscall" version = "0.4.1" @@ -7328,6 +7395,15 @@ dependencies = [ "url", ] +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + [[package]] name = "rend" version = "0.4.1" @@ -8404,6 +8480,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "tempdir" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" +dependencies = [ + "rand 0.4.6", + "remove_dir_all", +] + [[package]] name = "tempfile" version = "3.9.0" @@ -9061,6 +9147,15 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + [[package]] name = "waker-fn" version = "1.1.1" diff --git a/rs/ic-observability/multiservice-discovery-shared/src/builders/prometheus_config_structure.rs b/rs/ic-observability/multiservice-discovery-shared/src/builders/prometheus_config_structure.rs index ada6dadf1..1afea3194 100644 --- a/rs/ic-observability/multiservice-discovery-shared/src/builders/prometheus_config_structure.rs +++ b/rs/ic-observability/multiservice-discovery-shared/src/builders/prometheus_config_structure.rs @@ -1,13 +1,13 @@ use std::collections::{BTreeMap, BTreeSet}; use ic_types::PrincipalId; -use serde::{Serialize, Serializer}; +use serde::{Deserialize, Serialize, Serializer}; use service_discovery::job_types::JobType; use service_discovery::jobs::Job; use crate::{builders::ConfigBuilder, contracts::target::TargetDto}; -#[derive(Serialize, Debug, Clone, PartialEq, PartialOrd, Ord, Eq)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, PartialOrd, Ord, Eq)] pub struct PrometheusStaticConfig { pub targets: BTreeSet, pub labels: BTreeMap, diff --git a/rs/ic-observability/multiservice-discovery/BUILD.bazel b/rs/ic-observability/multiservice-discovery/BUILD.bazel index dce7ba004..2be7b73eb 100644 --- a/rs/ic-observability/multiservice-discovery/BUILD.bazel +++ b/rs/ic-observability/multiservice-discovery/BUILD.bazel @@ -1,5 +1,5 @@ load("@crate_index_dre//:defs.bzl", "aliases", "all_crate_deps") -load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_test") +load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_test", rust_test_suite) load("@//rs:oci_images.bzl", "rust_binary_oci_image_rules") DEPS = [ @@ -40,3 +40,9 @@ rust_test( normal_dev = True, ) + DEPS, ) + +rust_test_suite( + name = "mainnet_targets_tests", + srcs = glob(["tests/**/*.rs"]), + deps = [":multiservice-discovery"] + DEPS, +) diff --git a/rs/ic-observability/multiservice-discovery/Cargo.toml b/rs/ic-observability/multiservice-discovery/Cargo.toml index 56743274c..598322898 100644 --- a/rs/ic-observability/multiservice-discovery/Cargo.toml +++ b/rs/ic-observability/multiservice-discovery/Cargo.toml @@ -33,4 +33,8 @@ regex = "1.7.0" ic-types ={ git = "https://github.com/dfinity/ic.git", rev = "4b3b2ce76c4bde0c1c60fb80b0915931003b7eca" } multiservice-discovery-shared = {path = "../multiservice-discovery-shared"} ic-crypto-utils-threshold-sig-der = { git = "https://github.com/dfinity/ic.git", rev = "4b3b2ce76c4bde0c1c60fb80b0915931003b7eca" } -base64 = "0.13.1" \ No newline at end of file +base64 = "0.13.1" +tempdir = "0.3.7" +reqwest = "0.11.23" +assert_cmd = "1.0" +anyhow = "1.0.79" diff --git a/rs/ic-observability/multiservice-discovery/tests/tests.rs b/rs/ic-observability/multiservice-discovery/tests/tests.rs new file mode 100644 index 000000000..999941e49 --- /dev/null +++ b/rs/ic-observability/multiservice-discovery/tests/tests.rs @@ -0,0 +1,55 @@ +use std::collections::BTreeSet; +use std::process::{Command, Child}; +use tempdir::TempDir; +use std::time::Duration; +use assert_cmd::cargo::CommandCargoExt; +use tokio::runtime::Runtime; +use tokio::task::JoinHandle; +use tokio::time::sleep; +use multiservice_discovery_shared::builders::prometheus_config_structure::PrometheusStaticConfig; + +#[test] +fn mainnet_targets_tests() { + + let rt = Runtime::new().unwrap(); + let temp_dir = TempDir::new("target").expect("Failed to create temporary directory"); + let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")).expect("Failed to find binary"); + + // Add the necessary arguments + cmd.arg("--targets-dir").arg(temp_dir.path().to_path_buf().to_str().unwrap()); + + let mut child_process: Child = cmd.spawn().expect("Failed to run command"); + + let handle: JoinHandle>> = rt.spawn(async { + let timeout_duration = Duration::from_secs(300); + let start_time = std::time::Instant::now(); + + loop { + if start_time.elapsed() > timeout_duration { + return Err(anyhow::anyhow!("Timeout reached")); + } + sleep(Duration::from_secs(5)).await; + + let response = reqwest::get("http://localhost:8000/prom/targets").await?.text().await?; + let deserialized: Result, serde_json::Error> = serde_json::from_str(&response); + + match deserialized { + Ok(mainnet_targets) => { + if !mainnet_targets.is_empty() { + return Ok(mainnet_targets); + } + } + Err(err) => { + return Err(anyhow::anyhow!("Failed to deserialize: {}", err)); + } + } + } + }); + + let mainnet_targets = rt.block_on(handle).unwrap().unwrap(); + + assert!(mainnet_targets.iter().count() >= 5895); + + child_process.kill().unwrap(); + child_process.wait_with_output().unwrap(); +} \ No newline at end of file From 9731e613deb020a3653f5a225dc11a030b45802a Mon Sep 17 00:00:00 2001 From: Pietro Date: Mon, 15 Jan 2024 10:48:34 +0100 Subject: [PATCH 02/27] Fix test suite --- .bazelversion | 2 +- Cargo.Bazel.lock | 495 +++++++++++++++++- .../multiservice-discovery/BUILD.bazel | 2 +- 3 files changed, 493 insertions(+), 6 deletions(-) diff --git a/.bazelversion b/.bazelversion index 8cf77b432..9ff157766 100644 --- a/.bazelversion +++ b/.bazelversion @@ -1,2 +1,2 @@ -buildbuddy-io/5.0.9 +buildbuddy-io/5.0.28 6.3.0 diff --git a/Cargo.Bazel.lock b/Cargo.Bazel.lock index 06aca940d..0bc7cf437 100644 --- a/Cargo.Bazel.lock +++ b/Cargo.Bazel.lock @@ -1,5 +1,5 @@ { - "checksum": "c02ec9d24a31d5f25804ffe28f52fb2be2483fc64b5a77f32d69a29f5b7eac01", + "checksum": "99a52a6139478bbcddd825128a32c05c2d247f784f3280154350c303794175b0", "crates": { "actix 0.13.1": { "name": "actix", @@ -2202,6 +2202,65 @@ }, "license": "MIT" }, + "assert_cmd 1.0.8": { + "name": "assert_cmd", + "version": "1.0.8", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/assert_cmd/1.0.8/download", + "sha256": "c98233c6673d8601ab23e77eb38f999c51100d46c5703b17288c57fddf3a1ffe" + } + }, + "targets": [ + { + "Library": { + "crate_name": "assert_cmd", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "assert_cmd", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "bstr 0.2.17", + "target": "bstr" + }, + { + "id": "doc-comment 0.3.3", + "target": "doc_comment" + }, + { + "id": "predicates 2.1.5", + "target": "predicates" + }, + { + "id": "predicates-core 1.0.6", + "target": "predicates_core" + }, + { + "id": "predicates-tree 1.0.9", + "target": "predicates_tree" + }, + { + "id": "wait-timeout 0.2.0", + "target": "wait_timeout" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "1.0.8" + }, + "license": "MIT OR Apache-2.0" + }, "assert_matches 1.5.0": { "name": "assert_matches", "version": "1.5.0", @@ -11337,6 +11396,59 @@ }, "license": "MIT OR Apache-2.0" }, + "doc-comment 0.3.3": { + "name": "doc-comment", + "version": "0.3.3", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/doc-comment/0.3.3/download", + "sha256": "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + } + }, + "targets": [ + { + "Library": { + "crate_name": "doc_comment", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "doc_comment", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "doc-comment 0.3.3", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2015", + "version": "0.3.3" + }, + "build_script_attrs": { + "data_glob": [ + "**" + ] + }, + "license": "MIT" + }, "dotenv 0.15.0": { "name": "dotenv", "version": "0.15.0", @@ -13476,6 +13588,36 @@ }, "license": "MIT/Apache-2.0" }, + "fuchsia-cprng 0.1.1": { + "name": "fuchsia-cprng", + "version": "0.1.1", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/fuchsia-cprng/0.1.1/download", + "sha256": "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + } + }, + "targets": [ + { + "Library": { + "crate_name": "fuchsia_cprng", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "fuchsia_cprng", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2018", + "version": "0.1.1" + }, + "license": null + }, "funty 2.0.0": { "name": "funty", "version": "2.0.0", @@ -28392,13 +28534,32 @@ ], "crate_features": { "common": [ - "elf", - "errno", "general", "ioctl", "no_std" ], - "selects": {} + "selects": { + "aarch64-unknown-linux-gnu": [ + "elf", + "errno" + ], + "arm-unknown-linux-gnueabi": [ + "elf", + "errno" + ], + "armv7-unknown-linux-gnueabi": [ + "elf", + "errno" + ], + "i686-unknown-linux-gnu": [ + "elf", + "errno" + ], + "x86_64-unknown-linux-gnu": [ + "elf", + "errno" + ] + } }, "edition": "2021", "version": "0.4.12" @@ -29777,6 +29938,14 @@ ], "deps": { "common": [ + { + "id": "anyhow 1.0.79", + "target": "anyhow" + }, + { + "id": "assert_cmd 1.0.8", + "target": "assert_cmd" + }, { "id": "base64 0.13.1", "target": "base64" @@ -29829,6 +29998,10 @@ "id": "regex 1.10.2", "target": "regex" }, + { + "id": "reqwest 0.11.23", + "target": "reqwest" + }, { "id": "serde 1.0.194", "target": "serde" @@ -29849,6 +30022,10 @@ "id": "slog-term 2.9.0", "target": "slog_term" }, + { + "id": "tempdir 0.3.7", + "target": "tempdir" + }, { "id": "tokio 1.35.1", "target": "tokio" @@ -35740,6 +35917,77 @@ }, "license": "MIT" }, + "rand 0.4.6": { + "name": "rand", + "version": "0.4.6", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/rand/0.4.6/download", + "sha256": "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" + } + }, + "targets": [ + { + "Library": { + "crate_name": "rand", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "rand", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "libc", + "std" + ], + "selects": {} + }, + "deps": { + "common": [], + "selects": { + "cfg(target_env = \"sgx\")": [ + { + "id": "rand_core 0.3.1", + "target": "rand_core" + }, + { + "id": "rdrand 0.4.0", + "target": "rdrand" + } + ], + "cfg(target_os = \"fuchsia\")": [ + { + "id": "fuchsia-cprng 0.1.1", + "target": "fuchsia_cprng" + } + ], + "cfg(unix)": [ + { + "id": "libc 0.2.151", + "target": "libc" + } + ], + "cfg(windows)": [ + { + "id": "winapi 0.3.9", + "target": "winapi" + } + ] + } + }, + "edition": "2015", + "version": "0.4.6" + }, + "license": "MIT/Apache-2.0" + }, "rand 0.7.3": { "name": "rand", "version": "0.7.3", @@ -35976,6 +36224,75 @@ }, "license": "MIT OR Apache-2.0" }, + "rand_core 0.3.1": { + "name": "rand_core", + "version": "0.3.1", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/rand_core/0.3.1/download", + "sha256": "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" + } + }, + "targets": [ + { + "Library": { + "crate_name": "rand_core", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "rand_core", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "rand_core 0.4.2", + "target": "rand_core" + } + ], + "selects": {} + }, + "edition": "2015", + "version": "0.3.1" + }, + "license": "MIT/Apache-2.0" + }, + "rand_core 0.4.2": { + "name": "rand_core", + "version": "0.4.2", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/rand_core/0.4.2/download", + "sha256": "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + } + }, + "targets": [ + { + "Library": { + "crate_name": "rand_core", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "rand_core", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2015", + "version": "0.4.2" + }, + "license": "MIT/Apache-2.0" + }, "rand_core 0.5.1": { "name": "rand_core", "version": "0.5.1", @@ -36283,6 +36600,45 @@ }, "license": "MIT OR Apache-2.0" }, + "rdrand 0.4.0": { + "name": "rdrand", + "version": "0.4.0", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/rdrand/0.4.0/download", + "sha256": "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" + } + }, + "targets": [ + { + "Library": { + "crate_name": "rdrand", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "rdrand", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "rand_core 0.3.1", + "target": "rand_core" + } + ], + "selects": {} + }, + "edition": "2015", + "version": "0.4.0" + }, + "license": "ISC" + }, "redox_syscall 0.4.1": { "name": "redox_syscall", "version": "0.4.1", @@ -36905,6 +37261,47 @@ }, "license": null }, + "remove_dir_all 0.5.3": { + "name": "remove_dir_all", + "version": "0.5.3", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/remove_dir_all/0.5.3/download", + "sha256": "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" + } + }, + "targets": [ + { + "Library": { + "crate_name": "remove_dir_all", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "remove_dir_all", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [], + "selects": { + "cfg(windows)": [ + { + "id": "winapi 0.3.9", + "target": "winapi" + } + ] + } + }, + "edition": "2015", + "version": "0.5.3" + }, + "license": "MIT/Apache-2.0" + }, "rend 0.4.1": { "name": "rend", "version": "0.4.1", @@ -42559,6 +42956,49 @@ }, "license": "MIT" }, + "tempdir 0.3.7": { + "name": "tempdir", + "version": "0.3.7", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/tempdir/0.3.7/download", + "sha256": "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" + } + }, + "targets": [ + { + "Library": { + "crate_name": "tempdir", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "tempdir", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "rand 0.4.6", + "target": "rand" + }, + { + "id": "remove_dir_all 0.5.3", + "target": "remove_dir_all" + } + ], + "selects": {} + }, + "edition": "2015", + "version": "0.3.7" + }, + "license": "MIT/Apache-2.0" + }, "tempfile 3.9.0": { "name": "tempfile", "version": "3.9.0", @@ -45998,6 +46438,47 @@ }, "license": "MIT" }, + "wait-timeout 0.2.0": { + "name": "wait-timeout", + "version": "0.2.0", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/wait-timeout/0.2.0/download", + "sha256": "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" + } + }, + "targets": [ + { + "Library": { + "crate_name": "wait_timeout", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "wait_timeout", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [], + "selects": { + "cfg(unix)": [ + { + "id": "libc 0.2.151", + "target": "libc" + } + ] + } + }, + "edition": "2015", + "version": "0.2.0" + }, + "license": "MIT/Apache-2.0" + }, "waker-fn 1.1.1": { "name": "waker-fn", "version": "1.1.1", @@ -46899,6 +47380,7 @@ "objbase", "processenv", "processthreadsapi", + "profileapi", "shlobj", "std", "sysinfoapi", @@ -51017,6 +51499,7 @@ "wasm32-unknown-unknown", "wasm32-wasi" ], + "cfg(target_env = \"sgx\")": [], "cfg(target_family = \"unix\")": [ "aarch64-apple-darwin", "aarch64-apple-ios", @@ -51052,6 +51535,10 @@ "i686-unknown-freebsd", "x86_64-unknown-freebsd" ], + "cfg(target_os = \"fuchsia\")": [ + "aarch64-fuchsia", + "x86_64-fuchsia" + ], "cfg(target_os = \"haiku\")": [], "cfg(target_os = \"hermit\")": [], "cfg(target_os = \"ios\")": [ diff --git a/rs/ic-observability/multiservice-discovery/BUILD.bazel b/rs/ic-observability/multiservice-discovery/BUILD.bazel index 2be7b73eb..a1aca8d1b 100644 --- a/rs/ic-observability/multiservice-discovery/BUILD.bazel +++ b/rs/ic-observability/multiservice-discovery/BUILD.bazel @@ -1,5 +1,5 @@ load("@crate_index_dre//:defs.bzl", "aliases", "all_crate_deps") -load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_test", rust_test_suite) +load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_test", "rust_test_suite") load("@//rs:oci_images.bzl", "rust_binary_oci_image_rules") DEPS = [ From cb87493d126ac259432832722ec92b7d902c80ea Mon Sep 17 00:00:00 2001 From: Pietro Date: Mon, 15 Jan 2024 11:04:49 +0100 Subject: [PATCH 03/27] Add Bazel dependencies --- rs/ic-observability/multiservice-discovery/BUILD.bazel | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/rs/ic-observability/multiservice-discovery/BUILD.bazel b/rs/ic-observability/multiservice-discovery/BUILD.bazel index a1aca8d1b..2010fcca5 100644 --- a/rs/ic-observability/multiservice-discovery/BUILD.bazel +++ b/rs/ic-observability/multiservice-discovery/BUILD.bazel @@ -44,5 +44,12 @@ rust_test( rust_test_suite( name = "mainnet_targets_tests", srcs = glob(["tests/**/*.rs"]), - deps = [":multiservice-discovery"] + DEPS, + aliases = aliases(), + proc_macro_deps = all_crate_deps( + proc_macro = True, + ), + stamp = 1, + deps = all_crate_deps( + normal = True, + ) + DEPS, ) From f9be393b22ad8320479f78acd14300e84c519746 Mon Sep 17 00:00:00 2001 From: Pietro Date: Mon, 15 Jan 2024 11:31:19 +0100 Subject: [PATCH 04/27] Make explicit path to bin --- rs/ic-observability/multiservice-discovery/tests/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rs/ic-observability/multiservice-discovery/tests/tests.rs b/rs/ic-observability/multiservice-discovery/tests/tests.rs index 999941e49..2e96987c1 100644 --- a/rs/ic-observability/multiservice-discovery/tests/tests.rs +++ b/rs/ic-observability/multiservice-discovery/tests/tests.rs @@ -13,7 +13,7 @@ fn mainnet_targets_tests() { let rt = Runtime::new().unwrap(); let temp_dir = TempDir::new("target").expect("Failed to create temporary directory"); - let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")).expect("Failed to find binary"); + let mut cmd = Command::cargo_bin("multiservice-discovery").expect("Failed to find binary"); // Add the necessary arguments cmd.arg("--targets-dir").arg(temp_dir.path().to_path_buf().to_str().unwrap()); From 84acd53b93b55c83847eca69c7d0c05bf6a93e25 Mon Sep 17 00:00:00 2001 From: Pietro Date: Wed, 17 Jan 2024 15:14:29 +0100 Subject: [PATCH 05/27] Add tests --- .../multiservice-discovery/tests/tests.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/rs/ic-observability/multiservice-discovery/tests/tests.rs b/rs/ic-observability/multiservice-discovery/tests/tests.rs index 2e96987c1..3c1ea48c4 100644 --- a/rs/ic-observability/multiservice-discovery/tests/tests.rs +++ b/rs/ic-observability/multiservice-discovery/tests/tests.rs @@ -13,12 +13,12 @@ fn mainnet_targets_tests() { let rt = Runtime::new().unwrap(); let temp_dir = TempDir::new("target").expect("Failed to create temporary directory"); - let mut cmd = Command::cargo_bin("multiservice-discovery").expect("Failed to find binary"); - - // Add the necessary arguments - cmd.arg("--targets-dir").arg(temp_dir.path().to_path_buf().to_str().unwrap()); - - let mut child_process: Child = cmd.spawn().expect("Failed to run command"); + let path_buf = temp_dir.path().to_path_buf(); + let args = vec!["--targets-dir", path_buf.to_str().unwrap()]; + let mut child_process = Command::new("rs/ic-observability/multiservice-discovery") + .args(&args) + .spawn() + .expect("Failed to run command"); let handle: JoinHandle>> = rt.spawn(async { let timeout_duration = Duration::from_secs(300); From 8afac61f87865aa30945a43672b803d0d702586a Mon Sep 17 00:00:00 2001 From: Pietro Date: Wed, 17 Jan 2024 16:02:06 +0100 Subject: [PATCH 06/27] Add tests --- rs/ic-observability/multiservice-discovery/tests/tests.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rs/ic-observability/multiservice-discovery/tests/tests.rs b/rs/ic-observability/multiservice-discovery/tests/tests.rs index 3c1ea48c4..4a3c962f1 100644 --- a/rs/ic-observability/multiservice-discovery/tests/tests.rs +++ b/rs/ic-observability/multiservice-discovery/tests/tests.rs @@ -1,8 +1,7 @@ use std::collections::BTreeSet; -use std::process::{Command, Child}; +use std::process::Command; use tempdir::TempDir; use std::time::Duration; -use assert_cmd::cargo::CommandCargoExt; use tokio::runtime::Runtime; use tokio::task::JoinHandle; use tokio::time::sleep; @@ -12,10 +11,11 @@ use multiservice_discovery_shared::builders::prometheus_config_structure::Promet fn mainnet_targets_tests() { let rt = Runtime::new().unwrap(); + let binary_path = concat!(env!("CARGO_MANIFEST_DIR"), "/target/debug/multiservice-discovery"); let temp_dir = TempDir::new("target").expect("Failed to create temporary directory"); let path_buf = temp_dir.path().to_path_buf(); let args = vec!["--targets-dir", path_buf.to_str().unwrap()]; - let mut child_process = Command::new("rs/ic-observability/multiservice-discovery") + let mut child_process = Command::new(binary_path) .args(&args) .spawn() .expect("Failed to run command"); From dde9850a629fd1c11633420e8005913629fb58eb Mon Sep 17 00:00:00 2001 From: Pietro Date: Wed, 17 Jan 2024 18:11:46 +0100 Subject: [PATCH 07/27] Add tests --- rs/ic-observability/multiservice-discovery/BUILD.bazel | 3 +++ rs/ic-observability/multiservice-discovery/tests/tests.rs | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/rs/ic-observability/multiservice-discovery/BUILD.bazel b/rs/ic-observability/multiservice-discovery/BUILD.bazel index 2010fcca5..344b03396 100644 --- a/rs/ic-observability/multiservice-discovery/BUILD.bazel +++ b/rs/ic-observability/multiservice-discovery/BUILD.bazel @@ -49,6 +49,9 @@ rust_test_suite( proc_macro = True, ), stamp = 1, + env = { + "MULTISERVICE_DISCOVERY_BIN": "$(rootpath //rs/ic-observability/multiservice-discovery)", + }, deps = all_crate_deps( normal = True, ) + DEPS, diff --git a/rs/ic-observability/multiservice-discovery/tests/tests.rs b/rs/ic-observability/multiservice-discovery/tests/tests.rs index 4a3c962f1..a3a860ffd 100644 --- a/rs/ic-observability/multiservice-discovery/tests/tests.rs +++ b/rs/ic-observability/multiservice-discovery/tests/tests.rs @@ -11,7 +11,8 @@ use multiservice_discovery_shared::builders::prometheus_config_structure::Promet fn mainnet_targets_tests() { let rt = Runtime::new().unwrap(); - let binary_path = concat!(env!("CARGO_MANIFEST_DIR"), "/target/debug/multiservice-discovery"); + let binary_path = env!("MULTISERVICE_DISCOVERY_BIN")); + println!("binary path: {:?}", binary_path); let temp_dir = TempDir::new("target").expect("Failed to create temporary directory"); let path_buf = temp_dir.path().to_path_buf(); let args = vec!["--targets-dir", path_buf.to_str().unwrap()]; From 7299461466a2b95fa0a63920e640bda3704ef169 Mon Sep 17 00:00:00 2001 From: Pietro Date: Wed, 17 Jan 2024 18:29:09 +0100 Subject: [PATCH 08/27] Add tests --- .../multiservice-discovery/BUILD.bazel | 16 +++++----------- .../multiservice-discovery/tests/tests.rs | 2 +- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/rs/ic-observability/multiservice-discovery/BUILD.bazel b/rs/ic-observability/multiservice-discovery/BUILD.bazel index 344b03396..3f320426d 100644 --- a/rs/ic-observability/multiservice-discovery/BUILD.bazel +++ b/rs/ic-observability/multiservice-discovery/BUILD.bazel @@ -1,5 +1,5 @@ load("@crate_index_dre//:defs.bzl", "aliases", "all_crate_deps") -load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_test", "rust_test_suite") +load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_test") load("@//rs:oci_images.bzl", "rust_binary_oci_image_rules") DEPS = [ @@ -41,18 +41,12 @@ rust_test( ) + DEPS, ) -rust_test_suite( +rust_test( name = "mainnet_targets_tests", - srcs = glob(["tests/**/*.rs"]), - aliases = aliases(), - proc_macro_deps = all_crate_deps( - proc_macro = True, - ), - stamp = 1, + srcs = ["tests/tests.rs"], env = { "MULTISERVICE_DISCOVERY_BIN": "$(rootpath //rs/ic-observability/multiservice-discovery)", }, deps = all_crate_deps( - normal = True, - ) + DEPS, -) + normal_dev = True, + ) + DEPS,) diff --git a/rs/ic-observability/multiservice-discovery/tests/tests.rs b/rs/ic-observability/multiservice-discovery/tests/tests.rs index a3a860ffd..515944fee 100644 --- a/rs/ic-observability/multiservice-discovery/tests/tests.rs +++ b/rs/ic-observability/multiservice-discovery/tests/tests.rs @@ -11,7 +11,7 @@ use multiservice_discovery_shared::builders::prometheus_config_structure::Promet fn mainnet_targets_tests() { let rt = Runtime::new().unwrap(); - let binary_path = env!("MULTISERVICE_DISCOVERY_BIN")); + let binary_path = env!("MULTISERVICE_DISCOVERY_BIN"); println!("binary path: {:?}", binary_path); let temp_dir = TempDir::new("target").expect("Failed to create temporary directory"); let path_buf = temp_dir.path().to_path_buf(); From 9f1525dd273f651a40833182c272be9991ec09ca Mon Sep 17 00:00:00 2001 From: Pietro Date: Wed, 17 Jan 2024 19:46:37 +0100 Subject: [PATCH 09/27] Add tests --- rs/ic-observability/multiservice-discovery/BUILD.bazel | 7 +++---- rs/ic-observability/multiservice-discovery/tests/tests.rs | 4 +--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/rs/ic-observability/multiservice-discovery/BUILD.bazel b/rs/ic-observability/multiservice-discovery/BUILD.bazel index 3f320426d..f71856240 100644 --- a/rs/ic-observability/multiservice-discovery/BUILD.bazel +++ b/rs/ic-observability/multiservice-discovery/BUILD.bazel @@ -44,9 +44,8 @@ rust_test( rust_test( name = "mainnet_targets_tests", srcs = ["tests/tests.rs"], - env = { - "MULTISERVICE_DISCOVERY_BIN": "$(rootpath //rs/ic-observability/multiservice-discovery)", - }, + data = [":multiservice-discovery"], deps = all_crate_deps( normal_dev = True, - ) + DEPS,) + ) + DEPS, + ) diff --git a/rs/ic-observability/multiservice-discovery/tests/tests.rs b/rs/ic-observability/multiservice-discovery/tests/tests.rs index 515944fee..90663e989 100644 --- a/rs/ic-observability/multiservice-discovery/tests/tests.rs +++ b/rs/ic-observability/multiservice-discovery/tests/tests.rs @@ -11,12 +11,10 @@ use multiservice_discovery_shared::builders::prometheus_config_structure::Promet fn mainnet_targets_tests() { let rt = Runtime::new().unwrap(); - let binary_path = env!("MULTISERVICE_DISCOVERY_BIN"); - println!("binary path: {:?}", binary_path); let temp_dir = TempDir::new("target").expect("Failed to create temporary directory"); let path_buf = temp_dir.path().to_path_buf(); let args = vec!["--targets-dir", path_buf.to_str().unwrap()]; - let mut child_process = Command::new(binary_path) + let mut child_process = Command::new("rs/ic-observability/multiservice-discovery/multiservice-discovery") .args(&args) .spawn() .expect("Failed to run command"); From 6c8cc7717a138925a76247aa10b475323ffba907 Mon Sep 17 00:00:00 2001 From: Pietro Date: Wed, 17 Jan 2024 20:00:39 +0100 Subject: [PATCH 10/27] Add tests --- rs/ic-observability/multiservice-discovery/BUILD.bazel | 3 +++ rs/ic-observability/multiservice-discovery/tests/tests.rs | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/rs/ic-observability/multiservice-discovery/BUILD.bazel b/rs/ic-observability/multiservice-discovery/BUILD.bazel index f71856240..6d5bf0a39 100644 --- a/rs/ic-observability/multiservice-discovery/BUILD.bazel +++ b/rs/ic-observability/multiservice-discovery/BUILD.bazel @@ -45,6 +45,9 @@ rust_test( name = "mainnet_targets_tests", srcs = ["tests/tests.rs"], data = [":multiservice-discovery"], + proc_macro_deps = all_crate_deps( + proc_macro_dev = True, + ), deps = all_crate_deps( normal_dev = True, ) + DEPS, diff --git a/rs/ic-observability/multiservice-discovery/tests/tests.rs b/rs/ic-observability/multiservice-discovery/tests/tests.rs index 90663e989..ff15f5394 100644 --- a/rs/ic-observability/multiservice-discovery/tests/tests.rs +++ b/rs/ic-observability/multiservice-discovery/tests/tests.rs @@ -2,6 +2,7 @@ use std::collections::BTreeSet; use std::process::Command; use tempdir::TempDir; use std::time::Duration; +use assert_cmd::cargo::CommandCargoExt; use tokio::runtime::Runtime; use tokio::task::JoinHandle; use tokio::time::sleep; @@ -14,7 +15,12 @@ fn mainnet_targets_tests() { let temp_dir = TempDir::new("target").expect("Failed to create temporary directory"); let path_buf = temp_dir.path().to_path_buf(); let args = vec!["--targets-dir", path_buf.to_str().unwrap()]; - let mut child_process = Command::new("rs/ic-observability/multiservice-discovery/multiservice-discovery") + let bazel_path = "rs/ic-observability/multiservice-discovery/multiservice-discovery"; + let mut cmd = match Command::cargo_bin("multiservice-discovery") { + Ok(v) => v, + Err(_) => Command::new(bazel_path), + }; + let mut child_process = cmd .args(&args) .spawn() .expect("Failed to run command"); From 44a994f5414a54969627bb31371b6eadb33d03ff Mon Sep 17 00:00:00 2001 From: Pietro Date: Wed, 17 Jan 2024 20:08:55 +0100 Subject: [PATCH 11/27] Add tests --- rs/ic-observability/multiservice-discovery/BUILD.bazel | 9 +++++++++ .../multiservice-discovery/tests/tests.rs | 5 +---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/rs/ic-observability/multiservice-discovery/BUILD.bazel b/rs/ic-observability/multiservice-discovery/BUILD.bazel index 6d5bf0a39..e0aad362c 100644 --- a/rs/ic-observability/multiservice-discovery/BUILD.bazel +++ b/rs/ic-observability/multiservice-discovery/BUILD.bazel @@ -7,6 +7,15 @@ DEPS = [ "//rs/ic-observability/multiservice-discovery-shared" ] +DEV_DEPENDENCIES = [ + "@crate_index//:assert_cmd", + "@crate_index//:tokio", + "@crate_index//:tempdir", + "@crate_index//:anyhow", + "@crate_index//:reqwest", + "@crate_index//:serde_json", +] + rust_binary( name = "multiservice-discovery", srcs = glob(["src/**/*.rs"]), diff --git a/rs/ic-observability/multiservice-discovery/tests/tests.rs b/rs/ic-observability/multiservice-discovery/tests/tests.rs index ff15f5394..eadaf97b1 100644 --- a/rs/ic-observability/multiservice-discovery/tests/tests.rs +++ b/rs/ic-observability/multiservice-discovery/tests/tests.rs @@ -16,10 +16,7 @@ fn mainnet_targets_tests() { let path_buf = temp_dir.path().to_path_buf(); let args = vec!["--targets-dir", path_buf.to_str().unwrap()]; let bazel_path = "rs/ic-observability/multiservice-discovery/multiservice-discovery"; - let mut cmd = match Command::cargo_bin("multiservice-discovery") { - Ok(v) => v, - Err(_) => Command::new(bazel_path), - }; + let mut cmd = Command::cargo_bin("multiservice-discovery").unwrap_or_else(|_| Command::new(bazel_path)); let mut child_process = cmd .args(&args) .spawn() From 96d81e13204861990021eb638cdd6d1696c09726 Mon Sep 17 00:00:00 2001 From: Pietro Date: Wed, 17 Jan 2024 20:21:30 +0100 Subject: [PATCH 12/27] test new git index --- .../multiservice-discovery/BUILD.bazel | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rs/ic-observability/multiservice-discovery/BUILD.bazel b/rs/ic-observability/multiservice-discovery/BUILD.bazel index e0aad362c..05bfe0e51 100644 --- a/rs/ic-observability/multiservice-discovery/BUILD.bazel +++ b/rs/ic-observability/multiservice-discovery/BUILD.bazel @@ -8,12 +8,12 @@ DEPS = [ ] DEV_DEPENDENCIES = [ - "@crate_index//:assert_cmd", - "@crate_index//:tokio", - "@crate_index//:tempdir", - "@crate_index//:anyhow", - "@crate_index//:reqwest", - "@crate_index//:serde_json", + "@crate_index_dre//:assert_cmd", + "@crate_index_dre//:tokio", + "@crate_index_dre//:tempdir", + "@crate_index_dre//:anyhow", + "@crate_index_dre//:reqwest", + "@crate_index_dre//:serde_json", ] rust_binary( @@ -59,5 +59,5 @@ rust_test( ), deps = all_crate_deps( normal_dev = True, - ) + DEPS, + ) + DEPS + DEV_DEPENDENCIES, ) From 6a58c920c2acb11a632aae2a7507bc515a5aca42 Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 23 Jan 2024 11:10:16 +0100 Subject: [PATCH 13/27] Add test data --- .../builders/prometheus_config_structure.rs | 8 +- .../multiservice-discovery/BUILD.bazel | 4 +- .../mercury/targets/0000000000/00/00/01.pb | Bin 0 -> 21977 bytes .../time.local_store.v1.CertificationTime.pb | 1 + .../multiservice-discovery/tests/tests.rs | 131 +++++++++++------- 5 files changed, 89 insertions(+), 55 deletions(-) create mode 100644 rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/0000000000/00/00/01.pb create mode 100644 rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb diff --git a/rs/ic-observability/multiservice-discovery-shared/src/builders/prometheus_config_structure.rs b/rs/ic-observability/multiservice-discovery-shared/src/builders/prometheus_config_structure.rs index 1afea3194..c32974916 100644 --- a/rs/ic-observability/multiservice-discovery-shared/src/builders/prometheus_config_structure.rs +++ b/rs/ic-observability/multiservice-discovery-shared/src/builders/prometheus_config_structure.rs @@ -51,10 +51,10 @@ fn get_endpoints(target_group: TargetDto, job: JobType) -> BTreeSet { .collect() } -const IC_NAME: &str = "ic"; -const IC_NODE: &str = "ic_node"; -const IC_SUBNET: &str = "ic_subnet"; -const JOB: &str = "job"; +pub const IC_NAME: &str = "ic"; +pub const IC_NODE: &str = "ic_node"; +pub const IC_SUBNET: &str = "ic_subnet"; +pub const JOB: &str = "job"; // TODO: Re-add the labels below once we resolve the issues with the public dashboard queries // https://dfinity.atlassian.net/browse/OB-442 // const DC: &str = "dc"; diff --git a/rs/ic-observability/multiservice-discovery/BUILD.bazel b/rs/ic-observability/multiservice-discovery/BUILD.bazel index 05bfe0e51..404d87d93 100644 --- a/rs/ic-observability/multiservice-discovery/BUILD.bazel +++ b/rs/ic-observability/multiservice-discovery/BUILD.bazel @@ -51,9 +51,9 @@ rust_test( ) rust_test( - name = "mainnet_targets_tests", + name = "prom_targets_tests", srcs = ["tests/tests.rs"], - data = [":multiservice-discovery"], + data = [":multiservice-discovery", "test_data/mercury"], proc_macro_deps = all_crate_deps( proc_macro_dev = True, ), diff --git a/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/0000000000/00/00/01.pb b/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/0000000000/00/00/01.pb new file mode 100644 index 0000000000000000000000000000000000000000..a212f9c07f5f0b5b14c4bef655fdb63ebfd04661 GIT binary patch literal 21977 zcmd43RaBf&w5^E+g1fsr6z)!NCqQALaCZpq?(S~E-7OH@-GWfj6UP` zLqBx$#zXPfmbLd>-<&@PG6;A^Hm1(brX~hXrVcii#)bwzO`V)A?d_Z~7!c^#InB7) z*$nx(IE;-sjk!&EIgNQZ_}JKt+08h(*mybE**Lj4I043ZkO)H(2-?PmF2)uHt_}tc zhQ`*0=B5V5_I56&b}r5aR<=$K?#%WaRvdQB=3G2(cFb;`j_mf##_k@b=FHYy>}Fid z&W_eUZJC|yEKSUqt$rFg8#3FQa(c2ea~qms9Ec;-kt48UAV5O=$Ilxi86*P*0$C^B z`?+N}u~-%~knB}FT)TD7>|r8{ez#GCh<-c5hY$^tfY?aNFsJ`UYc7%A`Rd8^+w#*^ zb_^9Z?Ar2J13eV@&n%G@I7&O&yI8OT48(1m+1L#@c-ab_9bApT69OKCshOFjvE~09 zM}f_M{Vf0pYB5KRq=3>l?1Xd=uoCbP7;GpBhkvArWqbi(YvyZh0B7WP0o_;T*I7$Q z8M`>tu)~#BvOIHS>*CL_my_m4NC7u$$=yCr6a1^RD?z2?Ek7#2Vjn>iWUf!8V?2q`-du`4zW3zxOdI@(@x;oLW9U!hB{9N@L<6XX3ASbL!Y>^s$R82# zlr^#|I?q1^s3SXC7jo-;cvv5RfL45>daZ-J?$*p-M~hRonPqQF4qsi1r-kmP6<9*U zg1SX#DX#zNnU*=0*h{)XM*smOk7itbo}4CcC|Cl)A%N$h$IGT>b>eH^zs#mqB^0!u zYW15&Otl4v4{Gel4;FYpKq#&4p{wG{Vy?3fl~kRrsfLT%Sp^sH`uUe(o8NNp@91Xq z6RfNJ*Y5zv{o(n9M<5{F&HhK2VQWTN9C~Z=N?_m1(4afQoJ0JXHvfz9D0%m@0_p&DuF9Zy!)@Hx_6CfZxt}u0J;fwPh$QD9$PZKf;s$~9^oD;)a+&RZ9s;gUljGO+m!{F?M z&A0n&Mq@M}An44>geL4@I1YRLinN~{uj_Ai#)~Q^wf0*s3eJ~#Eud4GhTxT5jeYHf>CXT@49Y@2b4Xv= zWtM#)pgrlS|DHfZkLX$R=qqu%5LvimhwWlZ;7k)eWcMjc>}t>3?(xA0%jc`(3~Wa& z2M`b&qF)F!@UU)i z!}qM2eYWH-|L9{_w+E~4_FgL#nVo-eEKL*mq4HuwDDE^Tkm^QyxE>P!0Rl4Q7$~?v z0%JZiAUn}}&7Qj*P!}iLdcX!7Pq0ME7(T<0V=4O!7(;?5sgA;8o;H#+TGlhRd8@r)V@AiKCnbxUk}R-}(AbhnOwM}+Ms;YfZn@LoxRNv3h$ zMn5`~B1rsHy}Mq6}0X}q6A_P`NmK> z=-8`X%RgU`NYN!bD#k;d`X+70R;~Nia?s(T{w#fV2Lh6KFlqYzijOF2M20dxY=c~m zsdn*Yw=7CaOWo$?ygQ(&_~=+pQN*Y{?`XNv9$~?|ewR=^-&Mnp_ea;zp&YW>vCLor zEmYeVi5s^N?p>y_{c>Zs&wefvK_!p!lw1}T@czP*egWDq8wqBLPMf~iC}(uy{qy1# zYWa;rW_NBqo@eUQ&h==?^l5XbaNpFQ0L>1-RPj{L17k{jU|NglSyf#V27GKW>#i_(Q+T6dWIp_3P&U#{h3ffCv_$Lh#_jSj@V?|gQE3I~)W0P< z|F(avpm)_=FQ^wU2cPj%1j@I($jo?O@py2j%60l<1vHhZNch4$_L3-1VBtlR|0ppF zmn^uimGm6|g`_~JO?xB_z zNCnsKz`@^oz6%7kO9ngk9N$UZqE&%;)Gox#Mc_XYRPAjTw z_4`3*+wrv~Jf#e6(y*C*U-IeFM5pXN*REgWwK_j`Y;<6PWfymrvk(RCehNIblc_RS zaT@R^5R_V`MZwbbU35&c*)39z-^Q5>6I9HDri5EpJNuo?Uz)1pmU1b4`3QE^ra=)B z)*9(PPR@E&`3ET~UW`M9oH)S#^qK~ulzgOakF>`O(w;Ya^LJvI%dGl(a84oI%{ma2 zgyJ~WTna3-Q_r2U*@M75~2?A-QVoY(yT*Uk-#aSxu*5$q_2Kg=rlRe*i4rDm$(TljD(j9SqxVW? zaLZNL_Fg;QxCgkOI8ur~JJ&@}RI?iTIfTR}PA~O=Ab+Z8yJ$8cxac@kr-+r;GV;}5&-jf)) zp-xg-O*1eUEnA9XW(R_zC;89#tSk|6v0h~zduLHlNcd=ZHfVN|ICUMRH^(Qd2? zMvgK<^i-we0GwN`b$T!E*Cpsz*vCjz(^XkH#fLu{)zmIy> z0?*pfzTQrtI6ywEkZ>}>r1A#oTJO{luF$_6PNu*?=rtDzijuBDk#;%2wskMeTI zOzADNqNXa3Se8fmKIXL>Or1&aDtWY`#9QDgyd9l{f&LZ)i&B!R>-`~h{V70BmME;? zR{KN`OeGlK>JFA@g6!qz=uMbBS3=*!r(B~W2Z9P2TbeV`pXc$OlS$_&m>%ab&p<&P zelW@A8e9RoO2V-N4mRvC7Gb3J&^gO>BxEpIr(Zr@rY^28C(og#>J}Q|W^5ijaM#D( zLM!Q`vfvT}LR(fZsF?A0KQq~lm0TQ+EgdXOom@=aT?~vZTd13I*FOjh)gY_mc;6~5*fJtfARvJgY8fu)BFUAX z9-R%i#)&>{+~HDNPwr_euL7gm`4)S;F~HVKE9;$;;TuBEs}8==8fp^B@y~4f1?Oe0 zztte(y&a7$tK3(HdSj|s^!4JZ;$s>4zke?xBFYQC1u1Tdy$Tou0bv0WR8#y_1q{2R%1}7LPalRw zSSau5OI|Hfx+EhQ(^;u=cyvrONzZ;+24QTX++({*!DTLeXfRw zTw_ywcJI!i@?N<=Rl%*z`MMvE3CsdofMMUkb0yzOooPJjoyuSq##tN8Hy&coSBh>c zzBd3PbzElEY-011~`J}DtVjtQ+r$IAKD@1^3DYejtnwL4?lJw%Wv4;OE_g;xVVHS z2BsheKp(8$-HWYp2LuGzI+Qi7Bz42?=Pz_1u(kd^Uo7=m#?RCvyo|h=pU%S`SWtk) zYTu?wgF?O=QUNRQre&?#${4^;t!<&KdbNYEU$lSwpT#udEK=}< zUx)6tusN31wk7;Qj$M-t#QQCHp^Q!$`Is=Qx9*gmS*esyEeY9v1vkX}Q~Ge}{{ymUa@3eURUSuQd*Fk|7K^4oYGAo2EQd}kAb8Q~@`{>-Lw$;hn!cY) zIK_!BS48v$0*VejVz^q_JI4EQ7gC3{3&Is^U8A$3@TK z@F}ON;AXT21((9%{abX9(0PJ~-qR59xQ5-4OGsh6?+l3r+7RDUBG|uMlRo88EU@OD zCKp^ZMd74Xs7S*qrVEUe9Q?nYf)KuWRRsSTtG~*T^|>Z1U6ObwNMk`=YJd5`@d4!{ z25!SQxsJowEXLJ+nZI0=h^(lR*OK!`CD*Cg>$WY|vYyj&iw_Ghx>j9x?6EgVN`h9`mhAC-yE={~qh-9lc#DfPl!M zwq7U_`U>)}WZpve-l%JLIPy1Q24!vw>Y|;FCG!R3kcJnXEw%V_%N6376kwEKu#GD!F&_u51>8$YsTxJcJ$}pN~ zja^;_JJ6}`H!MLz$s3GZ+5r#?B~#Ig!PuJUHjJG)JQ?zVg^z(;P~cJq8Jlb|AoDi9 zB>IiSjCjD^?QtL@3-D}=4CO+oy!#K!d5rWHGt)Z-ibAYJkboPK6w(2~I05IdyowWP z`~iXrF4u35W_6MzD;ZfXsxNi?%ByU3M{+Q}xF)Fex=l=ASknS4(z4@46vU06t$0y- z?ubAm-3}lXFYR68q#C(~sF0>2ZZ1pc+S&MsxxzNn1!IxMe!mSNds5-?Qm4LrPA?C> z-xe~IX1tRZvyh7V9DLXO0QJM=(V0_ji+dA4#Lqr(YfP?HN`T{CQEv(S_LNdH{7;Rfl)W+IyS zmH2!71JY~D`tcak-@f1=)JZ*1yGe?hI;VYy3DivHY1rQLDAtA`b;%^2!@Q%aa^2IxgTiE4iZ)iA$2~soz z=1R8q_}D9I8{BwlA!UIWJZv@is_4)Y#8LJ29qQ77=rK^X+>*Jk9n5i0^;rkot76fLi42R*^&rT^HEzgh;nVR*KJ{~lGTF-fwW&G?4 zenx1_$c48R+XYPW&g%i&n+5;P0J4*bmu!+ceucC4{Ov$q3QHScTXdM9&T#^-tQWi< z?AO`I&J*>)8OF{~kXQhoi;gPG8@7-56EQ?U)nVxZ<&Hu%t?O3lPv;e=WB2 zg{zjA6J^{6Q~NpTccRw6bo`~t{gdeA*LG*Jb8G0&>g(F{9!^^$`^8uAnNmqUTS~hS zJyhuKo7o@znaarAD*Tsc$!P|dDa|U27}NNMK*E-%EAF58lasgz6MS{kUQYGju-03Y zsucStcER6`T%)-4ee1ZjO}z>dJ6;YBf#VjKMGGZAi`CWT7O4MEWa00V63=T%Or^sT z)Qd*=9CzdF>fi$}V$oV9GjVBd$_FbS)f#s{wBFK_++8Hsii-Udlozg2Pr=Dxk-sBl z7Z?s8q~PlFuFAq$jL_drsTDOmw9n+U)RBEI0_Bju_hXN>R5 zH@L{^=WQmFXr$OdC@J$tfs}3#B#;PlpeO$pv#uJnf5O!HTRf0De~rAYTVBqg5N`IL z8B0?^(lF{*X6?OXBf)-TwA&O=Psk0EtY);O z?@pm+jMqP_oq)zho#L34A0;JR4+yFz_2GFo36Q@vM^(7hdlC={(zMII$;BJr1mbLoW{2>R?lQHe*)3J+LQ#Px#VB#}n8uN>3{D`}|#&RDJ6gTnk=!AT&Ue@0Y&1|eyGu2lbevIqhiY#avPXnf zxTtR0$fn*s2?(kzFs2qrUebxzj9``XtqteN!Tw4!VD-sDTTDD$ji~2K&xGJ9sHhfi)IAU99T8!zunU??2Jotx=hp|r00l2Pf62S!H< z{%A)3hIg35dg&{b|# z$8t?^3qEKYX#5|km*!^14zACmZqosrS8YPat~QGGI1akMh@_l$;-uf zvAdo3;A-enh<@BR>W?CeaZj++p+sg=@s*HH(t66eaE%1G8E-f+wb$*#Ewb%8Q)bGJ zLM(=xc2Fr{>3YO_1x0%Bi+I!uXDhz$g(Y60 zx_z9hZ=dV>AZffsh$f63R6h{Z<}dvHV3mpRyauXL@+jO<|1y@8&_>h0JY2Jn`$4wmdoG6sFC{POs{uR_gnGOxr^N z$&f5RF&P-8ngJn&PM&7zQpV}~Bd=&w#Y*LphZNM(Cp3y57{^5f)dCRlSS8+=X&A^n z(<*Kt)zDcu^cmI|0PjNLW^cvSwpaUu%f#;JOuHt%DWtMD)p=Y zLBZ#1D|gunf}w=DsJXLBR}j2}$t|!m0<$@ALG1?smW|rya6Gj~`Y)LQh+96Vj$dd1 z5&rGcAMc!y7-~e0eU2U(aN;U ziPxB* zSQ`DZvknyF#_(l27~71Z4eaH(s{+c(T1m2z+bOY?R%**(BPlV-a|nZP=6^pvZp+`x zeWYgiYt*MOy?!vkUnzaxJ27L9Wv}L@I}Z?<@a})g4Iy)YFE!8e0|IJk^bA(_N9S{L zt%!iT%^|;wL(2~{_PWPq5@E1`K@{D-@EKHA|3cQMhsKyhYwopu0no(F`N{iL^R)I~bv!5uZg)N}X206W-4{%L8 zMa<~oL(a*97qX;nJ>^>sMin(k%ZkGV8sC^bhA3&lHp+S(dEL>Y^8Jydhhwei)5-Pl z9FoxT*`r&k7Mi||NW2o_DRx7gVS!}#E|EAaSSh97I$}Dnaqh^LF(G&YEFhorjW;Sf zcFnz5x%~{tya((yrL4O_SDAp0x8cACzH1=hmqBUEl^_P6-(`_ja$-l|7{-j#{!QxG zw&}ij(H8WPxH%(gW4`-&QKd;z)V;JEc;q3Pe(~96csVz*#hcm8F@2+x^WQKDn1R`B zj7~G!O8-3UX>0T++i9%bzaYRd;e)MNAw>&pvy=cNa|z5yn%e@TuXb~wd(x4}lM45F zSoU*3Nn?_8721FpX;;z8Wvc+Vi)7KgzHY^dU|6%CpsSJhMROxC!>_CERiO(O)#rpk z51*}B72aFvZub>7b;%EC1+O`3?NnZ{LhrPR_ku$TWiG{TVvxm8x3p=xoy_u~cvxmKlxdpSWp}VOA^G|zo z9(!g(TL(^dW)~wjV{T?{8yiDsW|#jOXc+U@k_Js0Rb|uR*#e} zXP&-P{-;L|Pj<}tKf3=JE@G`blvuuje3B7FTnP?1!h-}X*v zOM^QgZ?%e1d|138t(!=UCk$J7OO`)pQr?mUWAS*N3^)~%JyJe^zwhAM?{e?qGejA& z^1VeGRL-l`Oq^dcFskucCJ6rb-~~B;*Hh8oT8b;~Ku@RMtLO(d+*@2QxhA`@-6eRc zdkD|;exXU!x_ClVA0Bt6LYqX6%Q5O;X*SxhG1(Ws2+w6ZfXPc>mNOnDCR^cmktZ@& z`il?i;Jn@R9H{cW?-lnMskci7fqsS=gST8GXkodhY1#BZKpkE=c}C}s9Zn8Jp%0o3 z={qqF%g|!}Ot2mkVoc{Ywh$bbasiT4vh-x*D5ngB)8U==r>2566-e?Lkz8Ej%Vm6p(*6iiW z^#%o3Inel`!V4mWcNV3VC-mp})1dv}KQ9sxU~68QHR--!?>$yibi}UXB2;B;lcm8z zdyutt2N08`P?Dd;VHhbWCT5Z)-a|#{f!rLgHsykcaxJH0@ z?tr2Z#us)lLHag0j={4NeVK%;#%P=rrE1lMLWQ=Jr}wevbINBGT9+bwer+>b^84vG zh7mE(ri`=tOra*%ISA@x;TvkEIrXOvz(TjEaHco6$M=hI#zMxK$b|-O%9`Z> z0j0&J4DGLJx`D?*X4ipaQ&l*dQ~K7A_h|B;%4{Pg(+T=D6HSE929iMmnv8(KSuhJM z{ad>gKbtCnQO*j(lDj>Ix=gH&Ja95$d!6fI&lC`&TUxV!`sb^F7lPOp%CZ`Gw_q1q z#II~qMZy3NZjNOb;5$bKpRstoL=0KGyHh5<_fbFk*Jj`E{n4I@O$s<=1xHxM7Q|(Q zqeL$wb_H`fX@QF}QV`C=p$@16)Y~gO21yneXjJ1Yj++_oP#lhiuvQSG;fW! zow0#u1}U$^x~Wr(e_mG1Dp#{%S{Vg8!Nw8V8K0xYs!zp+jI-UU3VbI5SRDilW#BUJ&M>RNHWX~x?xP0#JaO z#v$^&FB1sKL$4bcq1ME%6wE7c@HHEJ{#I#iNacwN8`WdL2{|OL=mL69CRug7nxdUZ zB+W*p{7F#HqRL@US_!hb7PviO|C5ST5mx2?l}|zt4w(t;B8=g1yGH#6`G!#U+aT*J z{_<)G$_Az5Gz?chcTMCwdW3o^hEAYzg!)jHgh=`<(GmpLYx5syuX)Kh{y zL(iW-LGQ9eP$UA2_!DyWH=JJLBJmDkmSD8tfQ+wh@YKA!isrBwC--tIyc9P7iU{Vf zbm>*7Za?W)P4E*+a`;AJ&ZYnOL7LIsALrZvcuMGtM4U-!wu(cdqY7CG!_|F=EXS_Q zeV7;+-fp!JuaCEGA>rDb7?58(a_V*nokw%~<3b=O`LZ`0Jn6CtqoUFd zZ?~7g=KH*;3`+}wsexP1TgKn}L{VnFb%ZMsy?e9jdHru^r}wx=NUVm%xSWDImT zDmZ+?gdn=HmDP&tYb_IF25O<`%ZG5u@3i&Bw(>F`(tn=k#mXf|taT_%o7>mOz+@+& zVQX$;4^HK0Jp85KhPRZ=^`C!*g&!l_=stO)2AWT(w3}- z6n+7y?Hz!-EKBKyUaZm1yFn+Ro=?~tTbOFblsJ;k)zud!VVC0(OlX#t{J}=L#0oDt ziPru}iALwin|@+n$nvw9PgATI&hM5bY{AV;U9%p2(+ScTc0f=pH;9V-BvkJ&?UWBG z&=wcYuRzt90w|r)>C7gAkwdC}T*-$8i@HiZTg_AjcTs_}_nw}6Jhh$^HnWhoIB5LD zEst=nZL=?Bocg8S_(4#rsJV{ubwq9fnOr%#O}7OI3W>=hs7|Jcs8|5hh$#(tn6Izd z)Ao+k3|1XG%; zT`n*Nv?O_YT_B>}moIyuhWrA8YB9fhQN_Z3?K{S2Vgoj)P|ENBB>9kr|{IL2)iro3$>0MjpQ0s}^L=j&{{4UW* zeB`Ozjil;U9LEm#WuD28q^P-cLVjAq7-P{?Y5A5|VE6k%cblHGl<=B4MZS=jmfi34 z6$NfB8%$0hDBl5iWW4xBt{g#5@dX-Dvh$?X1{dth!_Tu{T_eu~j?mFV$-NC~d#^g;_c z(Tlw%HoB~+_(+ymoU`p6w$F>#A^-g!8G{fC=nJN$6hqj41RrjFRZGSqNOXT-_TH16 z430hd4ixAi5B2>}4htKg)>`&sdA&T16nV;@y;$X&er8mEa-e_M13^uqi@ax_Up~yB z-PU0}N+uYaH8{H-2;nGVBu|~k6E(@pOErtE_`-RY8zgs@I&I+g%9UxT74Fq>j(x9! zUoV2(GLgHY?>WBE8tREqC8N!GRV|%MloYga3-=LH;)?=72|=!j!v^|u3|)UGV|GsM zu!JTlZ2nm?4sdx z1M)|ld9Sw~ z0&gsNrC;^mf*YUs)J!@u7LG|+-a^}G;lNQ*i`Ku`XO12WNO|F%C(<&?=dzzys|Zu~ z-E`r$ZLRh{3=L%u4jO1KeeY*0A8>NPzKaUwSJ_AzxA3-~QCE=%5zXV5?f>vn)X_sJ zw1+)$MaL0#53{$N+F4+W?;vTChJk=M08~_jO2OfoV%Kpf#RD-1#`ivaM=w_G8|P^d zzROK5`b4B8QKiYz^h&<8MF}|W9Ho}7QO4)n5!+*)M!!w39hVwHa)?*DDJ)+kt$AmJnSH1%Q%2{SXLScsp2T05cWYJ~PO-cECPkBIRruw@(G|3p?w zOs|H{r!}+z0riK=sZUON-Aq#>G+3&~dZt8pMO+@fomqQBR{~!!7{UgMs73QD)d|N% zoMc{2!5&r8@Go!*Q)8atr}-IQ$buh)Tjub0)Owt?-7&K`z9H9tbb@l@41oKBXSSFIj}5X}i+kGbeJy_f773Z(m7H=|IWuj}El%h4O8K!Py%d&~xi2 zG58aF#%G+w)yeKzU4o&?;aKUaa>Ew;hOT}mKOXE=d>Q6WbCuv#ADP*@DQ&xZr@ny$ zLP(*3Coj(v+#`T@$6YE~r1w&gJ92Yh1OdE#ji;E`Jw zLH*vJNYJ)bavn%wncsuCko3QU9RCGb z{I4L#|HsIp_I?RA-bdy)13#uOAh&lH;xv-ny4IOz(%Wou_*3}M~g=v0|OeWqCEyca8MbijHQ+y+u6H{s%c70X(BMI08V{3 zuUItY12^22%6KP_GMwzNy_tiIxbViHmzIZ@0}Fptv!LGU9-t5n>$o&s7K7nHiu18( zAqr|w4v%gW7eccHHXJ99$?8ycn3HCR@{C%ELYGE$xz3l*d^jVY{`GJ$5{;aoc9qQE zoq%kqrl%H!mW2ouwoDlz_J^39)mB7BF~Os`mk+&lC0Jf+!+B?_ya3DcqXAfTxbrkj zhc81%yST5eq6{*E+k2+S-1+7c@q@R+wR$hY1R7c1QwFk2j`kklPsChN9ZbR$c$O}y ze$ZvP6;-Y}9~TDvQp57#v@N}6;AOsDEWJlR)A&a%r$Pe&w|g0E&7NPwOL5v9Gh8>m z^l6k+DJ5{6FL_suwI6bI22K#+!p{_7!=(n8CO|Yaje>=4Il zlAwb{sVb+V6qMiEidPWJLWkp`ASb?^8G&A7AgB}ESjBvY!Ufgr``2(j|8O0?tPJ+p zo2l4omX(SpCkSFZA9aVuU29q&*vG@VAnQ3)Zro+7#zc#gLIoJ^#m{<=q2o zAZ>VFavD4Sqj&P zXXFL_Mt}Xio1-XJ2p!diTk$uo1)LO%t0h9NVr3@hfIeIaLUoS{qq5CxQ(Du>7|`D5 z=O{;AJJP;948)4|k4*g_rOB=s#7I|9w@t$ql6YS{Zx0o48WC;c)AQ=B)aiPx0y z(*Rp7TcrEXzp&C^Too6i6zw(9+*7&mwP-_1D1}7Cwc?R-gl=|F($c{9 z6!<3L{#q;t#%`yV{-ts#6}`M2mMVJ1T;_ztM0 zPDw_;9fGesPP}ihh7TV4t(dQETp#gI4Wcb;OrAIpIFA}?jWL4g|5^kzJ!l=)HW~%{ zw3)ZSkqL)-)h^mFfYA$5E=H#o%P>#B$?`9MivpAQ7r^_f1)Rsr_8kOTON{6gHp5gh zcpOOt-Xz?RQxrEA@Md-$N7r%i+*BPwMM5F_rv*tx4XfxltF@BrHWc#4apjG$FW}kD zClvR_Fe!T!C^6|<-uin~$>OZ~A<$<-caJDYlp_J z+z?YR-iT_YCMKQn;ZRhZxeTF8SBnNqUhJ%2gLIjA&GFw6_3*+_xmS7 z21My6=y|d+4S$Lb4MW07YbT5EacYZVd-BepO98M(TLx5t(b`(wV7wE65q_9wm6|1! zX6xXFPX*5(8&tqNQ?Gjh^*LmJ@s#3qFJG1Q>jv{|BbxP{RuU{)QsB;Rnmc+-r@Z8E z2#PJucs>UUu1HMcS?Nwtyx3*djX%C*V~Z>HiFfYY|FSv*nbt_#d9~mo5d8^so~SrSQ%BouG&+iy&4cg4LDjJ&x4I?=s}6M%Nk;ivQKmGq%fHvYIR}h zK9eMQUj}!`E1PwmD5|ZX?Vf?dghDS#Xp~GuZEJY1*9$hFwA~By9nH#>U`n+=;kmld z75?J*qyiyRYyt%0>Ofss1^?v z^2?Jnc|xhCD-9>f5qZb7Gjc$gGyGhu9R?BXV3RY0@YsEAOEvXjEIY#TTr>aCuH*?U zTEI*rm+su5Ut2kY9NQc%G584_$jMxwGt}#SMsbW()opXvM+DdSIyZN_<>IyFXk|Mp zH{P3toY9*Wm!*`F!x-#R@68Qtku;yNgK^-#!{tUwl(@FZEnGMo*0iUDxrB1r;t;`d zTxf2AP7^w6i$56b_%9+|iV&hup!H3fp@Ga3-yMqG2@w4~oelihO#&ruc0P34P;*q9 z3wrTv+t?zohf%BpYux%sZmg&xDKNs}{FJ}4+#{ae^G!7)QT`zsFOYlnj%3<`Xzq5? z@TCKrzCp4pFmPWjX2r-Y*=9#V6WoW-B1h@XJ!4@D#^q2EuH$|msnZ@k*k}A1rMTdK zsYRkdB1N0C&rT;~IXDZJ^!YxaF6OKa!7K4kpNk2Nn=7yWx_4Fb9%;ei7mcgA+#V1V zIDIqgtkSFX$PMTD2O>;+%^lVe>)dzpmRWOsG@S3#*A8OrTleyh@qszPr35xvjHxI4 zQy$zoxD4Hq*rf#hFGr*^9_0F3QGDCHJz~APH@z#VP)(5m{Q9HyDQ?3WQ2brXslZ{Q>e6iJSQyLS6ID9y0WVZ3hL=MQN z>%p}r(FD)0muW$sTSmL*NnId*N|B^B#|gHS^{zfPS4+Yi4T2N zqnIC~w7iUy@=-)ojB~d6 z*3P-O9$m>H4~e&QfD^6v!LEZP#x)E~rBM7Ga2#;-CmP&+#mQR~5EB*qRF;g&ocS@x zVg41OR&Q)y-ZHGi2G__3(Sckb9njWj+DK)`AF z4yR5*Zb!ZImp`C?TT=sLZ~u7sza~6xKsN+?y$sZ82JcOvOK_XbE<9#mkKRW2=JRcR zCEgMYiK-9O@`K4sv&>3i48<7u0ArW16aIfCyx$o@a+~QN=9pz9K9UM#ZLg{L7Z+tAE# zsNH;=wTWF~VoFD*#a{&k)g9j6AiIXOiU<)8I!h+h&bhZ5WUuHBm(;3-z4&95#iLi%x?dDW|`hF#67|49))0(7& zem7bSClzeK1lI$3E+dTJjDfv3kSyk4flH7>5nKB8rE`RKg;m#m#ZkdW-f{z?Z$z*6 z3l0}LyDSvlOU{Bh=96+0@vO_-^{3N={F}CFNUu_Pz*U*~Rq-APf>sKHfO$E;61i1E zBpNvW^*qPR%dc?V(qKVc+3UbmGpmBDk}tdJtyMF^M9nUjOLfkiSfGrRT&Ea})aj~> z-S;Mk$AG&&R>+Cp_7=?GXpCT`YknXn^*V60^z$`0G<}LK8|KvqTn~m+ zjJouZW%UvMBV>_lIa%9L1T%Z-J7-y~E|>%ldV)FbcX&zt1?u3%0Wd$wpI{z=;Pid=f(`5El}?Xoe!0r=k|i#X?=g`mfs z%Mp(>u_dcloVmq{Rz#po6QgCZI$EuG&^2eVN zb5wP=>ZL@K?DU5r(k~13#H)dyN$yood=tvsHI`*3SfSq+Rj0u3k+zwbb*9k1N@vXF zN_=M<`1{=a7+E>PMW)ke$57C*g6SseFm#SP7c6Va&fvIs!wA-+5*kl~a{(@qqJ;DM zWp@Qs`2!=7K$dztX6E3VTfplN@E#(hzl9kR8Z;yH(K)bEZm zBrWDnoEDuuN5^`ry=1AwiW-s)30)dQ$)4gtZt`o&4GdC5LL{mAx&+sZBM1|TMvhK9 zosf^s-pDCU6x}QT!TT{-dWvL6zhI;)IZ$jsCxHX&xch z%7WJRKG6eb!hgE%12C;xVQ7jAn02Lh1&bx%7=49#!YJbNDgNU6eW=-!pA?~1eNHBvLd<1iJ$q`&rEoBoP;@HAK4C5a4FdFh-`EJB4( zCG|EdGSh9vaF><>ad$V@#z4Vb~RFicl3n8I3aP{Kb6q}yL_(#&eR#X*|hcOW#vpaLmXABjvXs$LRFuL^ zl9v7L()CXjz&f;+ZW^h%-U6#ajhHMW^(tT+L*f15$-j=Dr(Zvo9Zkl^6Rt^m8sqIU zxhS=^SYs6&l^i@eE9o$rBJ1 zR}_k3TYP{egv{hYLK2dRA)(kT%F6`>b(IP#2vWfZDk_5b7I0fpQR`|&M0|lOKB~AD zOVf!9tLw5APi#)+B=?+~|G(e;^4+;Nx%X3PPywP-OO=os7s-rJqLG=%fwXc?d_087 z6*wD05s6#_sggLT8ZsKucnlKhP-POdge}+0AYCFRpi?JM>|JSBS5;}k1J7Kh7Cef| zSLLt_O(oO4Oy6tfWbIeG24<%asSlGrbZ#c~9zYrD3jbwB9j}W!$GIl*{y#S_ZTv-F z6Gjm@ob~5F@W`x4IK(U~IQzusVRvlG90@Dz$6ci!y8&<~P@FWX&){Q$43|cz)USO$ zN+fEcD94DE`YNa({~l;g{-npL;s;&WL6JR#seJ>YQ`uKGS>-y%ZCZyw2lu4+aRY zz7l$X8k0G3k9$gqu{P7M=95QYfzO1lbjpy z=oYU{rv#~M=DCF5W}Fl%qmSI2TpTgMzn0x}tYSc&Sev_FCu;?)&hM(fZ1mf;Xuf=o zuBX}W^f$NiW>@`nPnpYvw%p0}-lgX=J`V}+nnhZDj=!eseRQ&Qe(KC!jAba2p=TFH zamc+ZnXPL!-|1l_oxh;{>UxA-It@NtQQY<&%~>7X{P(aobwV*EQ^uv{JsElj+12xz zI;5@m?ywuPL)_a6nwo2$1;oFh6Bk9Zb4bY5dtuHuAADgN@;CO&DI>gur#{NG3Gj)z zR2Mg(POR;}ew|dbd7e%+=}zn|zf7+dEqqy@*KlOLyd~!-eV)(oTFRE(oraRiAcdVK zh7lXkyLT~l%;B#$r~j}zE$s9&b{<-2Ubtvx)~b~Dqxzfo$G!izPPcqGPcb&@q)SF_+s(?sop8c&4$GXnbX(Yy~g%ia^ZIR^Q@aA ze|-|b(+{K*Yw`B$r1#>~ZPKx_9{$I@CxQ<}+`SxJI8V?L`{}m-B&$J^)+L9dut(#mzZ)x?6ff@`TVBF*727f?Kslg8`NKOnoYOOtY4_7TZUgO zZ!*%qS)X@&-SF^XB{d@-ai)K|&$G_FJLs!hOL;)$lzU|Qi;!-5d(M%vwCA_hE;8gq zXO=Y%BUsxz0Bcr?n%Y7FuUc4(Brf}Zvo?a&Xmc>h^GeNv`MbkYo z=9ZB!eYCuq>y|pJ!OJ`PfqAqec5=n{OY_Hk=2>#W^H}O;87a7~nB+U(WjDThis0w5 z3FFsixT_oq(h$%|sniOzx;Q0<3uGwO9UKR`N#;G4&kajl=*SoQ0h+11I4yR88}b#t z2Dxn+iTKn80Q^F!LNS3#jcJ6qO4C0vXQ|k1Da7FqRj=@$P3=lVP zq*|j|BC~ig3KasqREA>;nHHy#8~}o@9suON<=7|~tXm`X5Won6#XJU&Ef#WxLPUsi zMPeRISUQRsA`T2=EG~+OxGaRrfQ4Kx!efbe7?+Krut)?m>2!J=635p|aa^tC`}(3P zy;7kPqCTitrj+3ZAFV-)V+mScnaFprP4boKFf9(Lw7xnu;dF>WvIGf)VoTmA`rty1 zk5P*g;I{yvlSZY(EfWu1NEldBR|4RlL7MBwpd$$O|4k179giPNGL$R^> zuQ20Yhml*(jVR&D}K8;%Is=47^=9rUACKJHzun)Ro8#-t+(1@qxcozp}NL{P;Oq1EYZ708Wl(J^%m! literal 0 HcmV?d00001 diff --git a/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb b/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb new file mode 100644 index 000000000..fbab7df86 --- /dev/null +++ b/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/rs/ic-observability/multiservice-discovery/tests/tests.rs b/rs/ic-observability/multiservice-discovery/tests/tests.rs index eadaf97b1..7ce980d34 100644 --- a/rs/ic-observability/multiservice-discovery/tests/tests.rs +++ b/rs/ic-observability/multiservice-discovery/tests/tests.rs @@ -1,57 +1,90 @@ -use std::collections::BTreeSet; -use std::process::Command; -use tempdir::TempDir; -use std::time::Duration; -use assert_cmd::cargo::CommandCargoExt; -use tokio::runtime::Runtime; -use tokio::task::JoinHandle; -use tokio::time::sleep; -use multiservice_discovery_shared::builders::prometheus_config_structure::PrometheusStaticConfig; - -#[test] -fn mainnet_targets_tests() { - - let rt = Runtime::new().unwrap(); - let temp_dir = TempDir::new("target").expect("Failed to create temporary directory"); - let path_buf = temp_dir.path().to_path_buf(); - let args = vec!["--targets-dir", path_buf.to_str().unwrap()]; - let bazel_path = "rs/ic-observability/multiservice-discovery/multiservice-discovery"; - let mut cmd = Command::cargo_bin("multiservice-discovery").unwrap_or_else(|_| Command::new(bazel_path)); - let mut child_process = cmd - .args(&args) - .spawn() - .expect("Failed to run command"); - - let handle: JoinHandle>> = rt.spawn(async { - let timeout_duration = Duration::from_secs(300); - let start_time = std::time::Instant::now(); - - loop { - if start_time.elapsed() > timeout_duration { - return Err(anyhow::anyhow!("Timeout reached")); - } - sleep(Duration::from_secs(5)).await; +#[cfg(test)] +mod tests { + use std::collections::{BTreeMap, BTreeSet}; + use std::process::Command; + use assert_cmd::cargo::CommandCargoExt; + use std::time::Duration; + use tokio::runtime::Runtime; + use tokio::time::sleep; + use multiservice_discovery_shared::builders::prometheus_config_structure::{PrometheusStaticConfig, JOB, IC_NAME, IC_NODE, IC_SUBNET}; - let response = reqwest::get("http://localhost:8000/prom/targets").await?.text().await?; - let deserialized: Result, serde_json::Error> = serde_json::from_str(&response); + async fn fetch_targets() -> anyhow::Result> { + let timeout_duration = Duration::from_secs(300); + let start_time = std::time::Instant::now(); - match deserialized { - Ok(mainnet_targets) => { - if !mainnet_targets.is_empty() { - return Ok(mainnet_targets); - } - } - Err(err) => { - return Err(anyhow::anyhow!("Failed to deserialize: {}", err)); + loop { + if start_time.elapsed() > timeout_duration { + return Err(anyhow::anyhow!("Timeout reached")); + } + sleep(Duration::from_secs(5)).await; + + let response = reqwest::get("http://localhost:8000/prom/targets").await?.text().await?; + let deserialized: Result, serde_json::Error> = serde_json::from_str(&response); + + match deserialized { + Ok(mainnet_targets) => { + if !mainnet_targets.is_empty() { + return Ok(mainnet_targets); } } + Err(err) => { + return Err(anyhow::anyhow!("Failed to deserialize: {}", err)); + } } - }); + } + } + #[test] + fn prom_targets_tests() { + let rt = Runtime::new().unwrap(); + let args = [ + "--targets-dir", + "tests/test_data", + "--nns-url", + "http://donotupdate.app" + ]; + let bazel_path = "rs/ic-observability/multiservice-discovery/multiservice-discovery"; + + let mut cmd = Command::cargo_bin("multiservice-discovery").unwrap_or_else(|_| Command::new(bazel_path)); + + if let Ok(mut child) = cmd.args(args).spawn() { + let handle = rt.spawn(async { + fetch_targets().await + }); + let targets = rt.block_on(handle).unwrap().unwrap(); + child.kill().expect("command couldn't be killed"); + + assert_eq!(targets.len(), 6); + + let labels_set = targets + .iter() + .cloned() + .fold(BTreeMap::new(), |mut acc: BTreeMap>, v| { + for (key, value) in v.labels { + if let Some(grouped_set) = acc.get_mut(&key) { + grouped_set.insert(value); + } else { + let mut new_set = BTreeSet::new(); + new_set.insert(value); + acc.insert(key,new_set); + } + } + acc + }); + + println!(la) - let mainnet_targets = rt.block_on(handle).unwrap().unwrap(); + assert_eq!( + labels_set.get(IC_NAME).unwrap().iter().collect::>(), + vec!["mercury"] + ); - assert!(mainnet_targets.iter().count() >= 5895); + assert_eq!( + labels_set.get(JOB).unwrap().iter().collect::>(), + vec!["node_exporter", "orchestrator", "replica"] + ); - child_process.kill().unwrap(); - child_process.wait_with_output().unwrap(); -} \ No newline at end of file + } else { + panic!("yes command didn't start"); + } + } +} From 5e9be03449b7927ac1f1cd82e42ac6b50054e1cd Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 23 Jan 2024 11:12:15 +0100 Subject: [PATCH 14/27] Add bazel --- rs/ic-observability/multiservice-discovery/BUILD.bazel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rs/ic-observability/multiservice-discovery/BUILD.bazel b/rs/ic-observability/multiservice-discovery/BUILD.bazel index 404d87d93..6813a6740 100644 --- a/rs/ic-observability/multiservice-discovery/BUILD.bazel +++ b/rs/ic-observability/multiservice-discovery/BUILD.bazel @@ -53,7 +53,7 @@ rust_test( rust_test( name = "prom_targets_tests", srcs = ["tests/tests.rs"], - data = [":multiservice-discovery", "test_data/mercury"], + data = [":multiservice-discovery", "tests/test_data"], proc_macro_deps = all_crate_deps( proc_macro_dev = True, ), From 6e12e67adc8ccba585b7a1445ad58dcd5d6efaf5 Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 23 Jan 2024 11:21:14 +0100 Subject: [PATCH 15/27] Add IC_NODE test --- .../time.local_store.v1.CertificationTime.pb | 2 +- .../multiservice-discovery/tests/tests.rs | 20 ++++++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb b/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb index fbab7df86..0371fd6b7 100644 --- a/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb +++ b/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb @@ -1 +1 @@ - \ No newline at end of file +Լ \ No newline at end of file diff --git a/rs/ic-observability/multiservice-discovery/tests/tests.rs b/rs/ic-observability/multiservice-discovery/tests/tests.rs index 7ce980d34..cced8c6f3 100644 --- a/rs/ic-observability/multiservice-discovery/tests/tests.rs +++ b/rs/ic-observability/multiservice-discovery/tests/tests.rs @@ -70,9 +70,7 @@ mod tests { } acc }); - - println!(la) - + assert_eq!( labels_set.get(IC_NAME).unwrap().iter().collect::>(), vec!["mercury"] @@ -83,6 +81,22 @@ mod tests { vec!["node_exporter", "orchestrator", "replica"] ); + assert_eq!( + labels_set.get(IC_NODE).unwrap().iter().collect::>(), + vec![ + "4uphn-ptciz-qz3q7-sk7jj-eklt6-d4gkr-ox7dp-zzdje-cudnx-v6kwi-uqe", + "kxkkh-hhfjy-jn7ai-zwnp3-bcnts-npet2-m3qxb-dmz5b-4o4n3-dnb4w-eqe", + ] + ); + + assert_eq!( + labels_set.get(IC_SUBNET).unwrap().iter().collect::>(), + vec![ + "jmrpx-o3j3n-g57wn-wzq2o-cxyeg-k52f5-sqkvm-rnidf-jvbsa-oe4z2-6ae", + "oxqbs-zdhkh-ygwt2-lofma-yotgh-maxep-vog7o-amp42-tbwc6-6llas-tae", + ] + ); + } else { panic!("yes command didn't start"); } From bdc3579b8d451987e9eaf5d2a7c5c9cb447f28bc Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 23 Jan 2024 13:17:54 +0100 Subject: [PATCH 16/27] Add test for multiservice-discovery based on large02 testnet --- .bazelversion | 2 +- Cargo.lock | 95 ++++++++++++++++++ .../multiservice-discovery/Cargo.toml | 7 ++ .../mercury/targets/0000000000/00/00/01.pb | Bin 21977 -> 115359 bytes .../time.local_store.v1.CertificationTime.pb | 2 +- .../multiservice-discovery/tests/tests.rs | 18 ++-- 6 files changed, 111 insertions(+), 13 deletions(-) diff --git a/.bazelversion b/.bazelversion index 9ff157766..8cf77b432 100644 --- a/.bazelversion +++ b/.bazelversion @@ -1,2 +1,2 @@ -buildbuddy-io/5.0.28 +buildbuddy-io/5.0.9 6.3.0 diff --git a/Cargo.lock b/Cargo.lock index a66df96b2..696577294 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -395,6 +395,20 @@ dependencies = [ "serde_json", ] +[[package]] +name = "assert_cmd" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c98233c6673d8601ab23e77eb38f999c51100d46c5703b17288c57fddf3a1ffe" +dependencies = [ + "bstr", + "doc-comment", + "predicates", + "predicates-core", + "predicates-tree", + "wait-timeout", +] + [[package]] name = "assert_matches" version = "1.5.0" @@ -2132,6 +2146,12 @@ dependencies = [ "syn 2.0.48", ] +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + [[package]] name = "dotenv" version = "0.15.0" @@ -2516,6 +2536,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + [[package]] name = "funty" version = "2.0.0" @@ -5672,6 +5698,8 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" name = "multiservice-discovery" version = "0.2.0" dependencies = [ + "anyhow", + "assert_cmd", "base64 0.21.7", "clap 4.4.17", "crossbeam", @@ -5686,12 +5714,14 @@ dependencies = [ "ic-utils 0.9.0", "multiservice-discovery-shared", "regex", + "reqwest", "serde", "serde_json", "service-discovery", "slog", "slog-async", "slog-term", + "tempdir", "tokio", "url", "warp", @@ -6769,6 +6799,19 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +[[package]] +name = "rand" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +dependencies = [ + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "rdrand", + "winapi", +] + [[package]] name = "rand" version = "0.7.3" @@ -6813,6 +6856,21 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + [[package]] name = "rand_core" version = "0.5.1" @@ -6855,6 +6913,15 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "977b1e897f9d764566891689e642653e5ed90c6895106acd005eb4c1d0203991" +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + [[package]] name = "redox_syscall" version = "0.4.1" @@ -6968,6 +7035,15 @@ dependencies = [ "url", ] +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + [[package]] name = "rend" version = "0.4.1" @@ -8025,6 +8101,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "tempdir" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" +dependencies = [ + "rand 0.4.6", + "remove_dir_all", +] + [[package]] name = "tempfile" version = "3.9.0" @@ -8667,6 +8753,15 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + [[package]] name = "waker-fn" version = "1.1.1" diff --git a/rs/ic-observability/multiservice-discovery/Cargo.toml b/rs/ic-observability/multiservice-discovery/Cargo.toml index 5aa877498..7d6c04b8f 100644 --- a/rs/ic-observability/multiservice-discovery/Cargo.toml +++ b/rs/ic-observability/multiservice-discovery/Cargo.toml @@ -29,3 +29,10 @@ slog-term = { workspace = true } tokio = { workspace = true } url = { workspace = true } warp = { workspace = true } + +[dev-dependencies] +tempdir = "0.3.7" +reqwest = "0.11.23" +assert_cmd = "1.0" +anyhow = "1.0.79" + diff --git a/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/0000000000/00/00/01.pb b/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/0000000000/00/00/01.pb index a212f9c07f5f0b5b14c4bef655fdb63ebfd04661..1a6816c17318bd36f4ef41c0aa8787aff13b4fdc 100644 GIT binary patch literal 115359 zcmd>lWl$Yq(x4|Yinz3 z|1STisarG8bf50ir_Uh$K*BSyGIn${Hqv!4wzD!f)Yo+}c5pPewQ!XLmPNMn`)NPDe&gLk~w&Mm8fyD<{Tp?yd&< zjO>P}i?$(A@jIMU}9=41wPHY~gjJEd1nDzOPNR0|ete8j;|NZY3k`$7T9EtP@ z?}n0@?pWM}SpXq0;H74ubQd{$fyzV&qd1{jDB2Po`U}w)y07)?UkL`^@00kP^$X2; zAQjaNE@u^(D!SyLz7TyK`~JqUg~_rxpottx;@-wgm{H#$uJB7uHT@m9OdZ3TcWeze zePZ-w$2^mQ`FBO`tyN{pN6E&AH*ndRJs*yfHjDqK+m1#Xpa1rq3W{$o`N_u!tX&>( zIcVyZM#Oi!N<=39ORB^`-g0TX$HDL2OW^VmR^u@E)}V4p-Za-X zfsh%>&X*u2jaD*P!72p`ct8GfdG-}T&Al5*1j7?0; z4bA@(p**Yq`M*H0UY&}o$H#gwE5+1QYO@BjkSYENk=`xb<&51G~mj zm#aeZ`JYMbP?+TU2V4&VPYWU!jkMDP`H?4&^x8!W+ZGIG<*MTrI#%0D;lpF2D~N1C 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 *Q=3^h{)pN#^^844?i=ZZ> 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 DBcT&9 literal 21977 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 diff --git a/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb b/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb index 0371fd6b7..2926d12f5 100644 --- a/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb +++ b/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb @@ -1 +1 @@ -Լ \ No newline at end of file +ݗ \ No newline at end of file diff --git a/rs/ic-observability/multiservice-discovery/tests/tests.rs b/rs/ic-observability/multiservice-discovery/tests/tests.rs index cced8c6f3..f421cd9c9 100644 --- a/rs/ic-observability/multiservice-discovery/tests/tests.rs +++ b/rs/ic-observability/multiservice-discovery/tests/tests.rs @@ -53,7 +53,7 @@ mod tests { let targets = rt.block_on(handle).unwrap().unwrap(); child.kill().expect("command couldn't be killed"); - assert_eq!(targets.len(), 6); + assert_eq!(targets.len(), 72); let labels_set = targets .iter() @@ -70,7 +70,7 @@ mod tests { } acc }); - + assert_eq!( labels_set.get(IC_NAME).unwrap().iter().collect::>(), vec!["mercury"] @@ -81,19 +81,15 @@ mod tests { vec!["node_exporter", "orchestrator", "replica"] ); - assert_eq!( - labels_set.get(IC_NODE).unwrap().iter().collect::>(), - vec![ - "4uphn-ptciz-qz3q7-sk7jj-eklt6-d4gkr-ox7dp-zzdje-cudnx-v6kwi-uqe", - "kxkkh-hhfjy-jn7ai-zwnp3-bcnts-npet2-m3qxb-dmz5b-4o4n3-dnb4w-eqe", - ] - ); assert_eq!( labels_set.get(IC_SUBNET).unwrap().iter().collect::>(), vec![ - "jmrpx-o3j3n-g57wn-wzq2o-cxyeg-k52f5-sqkvm-rnidf-jvbsa-oe4z2-6ae", - "oxqbs-zdhkh-ygwt2-lofma-yotgh-maxep-vog7o-amp42-tbwc6-6llas-tae", + "5mlaw-duyx2-sq67s-7czsg-3dslt-5ywba-4t346-kymcl-wpqzo-vt3zg-oqe", + "grlkk-en3y6-lbkcb-qi4n2-hbikt-u7lhr-zwiqs-xkjt6-5mrto-3a2w7-7ae", + "hyrk7-bxql5-toski-dz327-pajhm-ml6h6-n2fps-oxbsi-4dz2n-4ba4t-nqe", + "quqe7-f73mp-keuge-3ywt4-k254o-kqzs2-z5gjb-2ehox-6iby5-54hbp-6qe", + "sunxw-go5eq-un4wt-qlueh-qrde6-fq6l5-svdzo-l4g43-yopxy-rtxji-dqe" ] ); From 84d584c6d4031b40719595de153d94578e9edad9 Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 23 Jan 2024 13:18:39 +0100 Subject: [PATCH 17/27] remove unused IC_NODE --- .../mercury/targets/time.local_store.v1.CertificationTime.pb | 2 +- rs/ic-observability/multiservice-discovery/tests/tests.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb b/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb index 2926d12f5..a27bd87df 100644 --- a/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb +++ b/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb @@ -1 +1 @@ -ݗ \ No newline at end of file + \ No newline at end of file diff --git a/rs/ic-observability/multiservice-discovery/tests/tests.rs b/rs/ic-observability/multiservice-discovery/tests/tests.rs index f421cd9c9..6b84ae8ba 100644 --- a/rs/ic-observability/multiservice-discovery/tests/tests.rs +++ b/rs/ic-observability/multiservice-discovery/tests/tests.rs @@ -6,7 +6,7 @@ mod tests { use std::time::Duration; use tokio::runtime::Runtime; use tokio::time::sleep; - use multiservice_discovery_shared::builders::prometheus_config_structure::{PrometheusStaticConfig, JOB, IC_NAME, IC_NODE, IC_SUBNET}; + use multiservice_discovery_shared::builders::prometheus_config_structure::{PrometheusStaticConfig, JOB, IC_NAME, IC_SUBNET}; async fn fetch_targets() -> anyhow::Result> { let timeout_duration = Duration::from_secs(300); From 97162ef0d14bccb51114e4b1e798393ade0ffcbd Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 23 Jan 2024 13:23:03 +0100 Subject: [PATCH 18/27] refactor child process --- .../time.local_store.v1.CertificationTime.pb | 2 +- .../multiservice-discovery/tests/tests.rs | 83 +++++++++---------- 2 files changed, 40 insertions(+), 45 deletions(-) diff --git a/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb b/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb index a27bd87df..211ee8289 100644 --- a/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb +++ b/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb @@ -1 +1 @@ - \ No newline at end of file +ը \ No newline at end of file diff --git a/rs/ic-observability/multiservice-discovery/tests/tests.rs b/rs/ic-observability/multiservice-discovery/tests/tests.rs index 6b84ae8ba..39999555e 100644 --- a/rs/ic-observability/multiservice-discovery/tests/tests.rs +++ b/rs/ic-observability/multiservice-discovery/tests/tests.rs @@ -45,56 +45,51 @@ mod tests { let bazel_path = "rs/ic-observability/multiservice-discovery/multiservice-discovery"; let mut cmd = Command::cargo_bin("multiservice-discovery").unwrap_or_else(|_| Command::new(bazel_path)); + let mut child = cmd.args(args).spawn().unwrap(); + let handle = rt.spawn(async { + fetch_targets().await + }); + let targets = rt.block_on(handle).unwrap().unwrap(); + child.kill().expect("command couldn't be killed"); - if let Ok(mut child) = cmd.args(args).spawn() { - let handle = rt.spawn(async { - fetch_targets().await - }); - let targets = rt.block_on(handle).unwrap().unwrap(); - child.kill().expect("command couldn't be killed"); - - assert_eq!(targets.len(), 72); + assert_eq!(targets.len(), 72); - let labels_set = targets - .iter() - .cloned() - .fold(BTreeMap::new(), |mut acc: BTreeMap>, v| { - for (key, value) in v.labels { - if let Some(grouped_set) = acc.get_mut(&key) { - grouped_set.insert(value); - } else { - let mut new_set = BTreeSet::new(); - new_set.insert(value); - acc.insert(key,new_set); - } + let labels_set = targets + .iter() + .cloned() + .fold(BTreeMap::new(), |mut acc: BTreeMap>, v| { + for (key, value) in v.labels { + if let Some(grouped_set) = acc.get_mut(&key) { + grouped_set.insert(value); + } else { + let mut new_set = BTreeSet::new(); + new_set.insert(value); + acc.insert(key,new_set); } - acc - }); - - assert_eq!( - labels_set.get(IC_NAME).unwrap().iter().collect::>(), - vec!["mercury"] - ); + } + acc + }); - assert_eq!( - labels_set.get(JOB).unwrap().iter().collect::>(), - vec!["node_exporter", "orchestrator", "replica"] - ); + assert_eq!( + labels_set.get(IC_NAME).unwrap().iter().collect::>(), + vec!["mercury"] + ); + assert_eq!( + labels_set.get(JOB).unwrap().iter().collect::>(), + vec!["node_exporter", "orchestrator", "replica"] + ); - assert_eq!( - labels_set.get(IC_SUBNET).unwrap().iter().collect::>(), - vec![ - "5mlaw-duyx2-sq67s-7czsg-3dslt-5ywba-4t346-kymcl-wpqzo-vt3zg-oqe", - "grlkk-en3y6-lbkcb-qi4n2-hbikt-u7lhr-zwiqs-xkjt6-5mrto-3a2w7-7ae", - "hyrk7-bxql5-toski-dz327-pajhm-ml6h6-n2fps-oxbsi-4dz2n-4ba4t-nqe", - "quqe7-f73mp-keuge-3ywt4-k254o-kqzs2-z5gjb-2ehox-6iby5-54hbp-6qe", - "sunxw-go5eq-un4wt-qlueh-qrde6-fq6l5-svdzo-l4g43-yopxy-rtxji-dqe" - ] - ); - } else { - panic!("yes command didn't start"); - } + assert_eq!( + labels_set.get(IC_SUBNET).unwrap().iter().collect::>(), + vec![ + "5mlaw-duyx2-sq67s-7czsg-3dslt-5ywba-4t346-kymcl-wpqzo-vt3zg-oqe", + "grlkk-en3y6-lbkcb-qi4n2-hbikt-u7lhr-zwiqs-xkjt6-5mrto-3a2w7-7ae", + "hyrk7-bxql5-toski-dz327-pajhm-ml6h6-n2fps-oxbsi-4dz2n-4ba4t-nqe", + "quqe7-f73mp-keuge-3ywt4-k254o-kqzs2-z5gjb-2ehox-6iby5-54hbp-6qe", + "sunxw-go5eq-un4wt-qlueh-qrde6-fq6l5-svdzo-l4g43-yopxy-rtxji-dqe" + ] + ); } } From a357e4d9861a7c4dd78225eef8c73730c6bce1b3 Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 23 Jan 2024 13:26:12 +0100 Subject: [PATCH 19/27] Update checksum --- Cargo.Bazel.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.Bazel.lock b/Cargo.Bazel.lock index 527b4c51c..9d4213aa7 100644 --- a/Cargo.Bazel.lock +++ b/Cargo.Bazel.lock @@ -1,5 +1,5 @@ { - "checksum": "901d395b0216193586a4afb96e66844e63fca2b6e83727764acb8529212fcaff", + "checksum": "89abffeee4038ac3ac50a11366522dcd64f745c81439ab40b76d72fe35b6d30c", "crates": { "actix-codec 0.5.1": { "name": "actix-codec", From f8f38bdd8f8482fbf4095c9ae341fa220541427c Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 23 Jan 2024 13:38:49 +0100 Subject: [PATCH 20/27] Repin bazel --- Cargo.Bazel.lock | 610 +++++++++++++++++- Cargo.lock | 35 +- .../multiservice-discovery/Cargo.toml | 2 +- 3 files changed, 636 insertions(+), 11 deletions(-) diff --git a/Cargo.Bazel.lock b/Cargo.Bazel.lock index 9d4213aa7..3e61072cb 100644 --- a/Cargo.Bazel.lock +++ b/Cargo.Bazel.lock @@ -1,5 +1,5 @@ { - "checksum": "89abffeee4038ac3ac50a11366522dcd64f745c81439ab40b76d72fe35b6d30c", + "checksum": "2698cdbc0a6928a03a7b95cdb1deb6e0e9d48a26e30e206224f3148b364a1b10", "crates": { "actix-codec 0.5.1": { "name": "actix-codec", @@ -1941,6 +1941,69 @@ }, "license": "MIT" }, + "assert_cmd 2.0.13": { + "name": "assert_cmd", + "version": "2.0.13", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/assert_cmd/2.0.13/download", + "sha256": "00ad3f3a942eee60335ab4342358c161ee296829e0d16ff42fc1d6cb07815467" + } + }, + "targets": [ + { + "Library": { + "crate_name": "assert_cmd", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "assert_cmd", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "anstyle 1.0.4", + "target": "anstyle" + }, + { + "id": "bstr 1.9.0", + "target": "bstr" + }, + { + "id": "doc-comment 0.3.3", + "target": "doc_comment" + }, + { + "id": "predicates 3.1.0", + "target": "predicates" + }, + { + "id": "predicates-core 1.0.6", + "target": "predicates_core" + }, + { + "id": "predicates-tree 1.0.9", + "target": "predicates_tree" + }, + { + "id": "wait-timeout 0.2.0", + "target": "wait_timeout" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "2.0.13" + }, + "license": "MIT OR Apache-2.0" + }, "assert_matches 1.5.0": { "name": "assert_matches", "version": "1.5.0", @@ -4568,6 +4631,58 @@ }, "license": "MIT OR Apache-2.0" }, + "bstr 1.9.0": { + "name": "bstr", + "version": "1.9.0", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/bstr/1.9.0/download", + "sha256": "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc" + } + }, + "targets": [ + { + "Library": { + "crate_name": "bstr", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "bstr", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "alloc", + "default", + "std", + "unicode" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "memchr 2.7.1", + "target": "memchr" + }, + { + "id": "regex-automata 0.4.3", + "target": "regex_automata" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "1.9.0" + }, + "license": "MIT OR Apache-2.0" + }, "build-info 0.0.26": { "name": "build-info", "version": "0.0.26", @@ -10681,6 +10796,59 @@ }, "license": "MIT OR Apache-2.0" }, + "doc-comment 0.3.3": { + "name": "doc-comment", + "version": "0.3.3", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/doc-comment/0.3.3/download", + "sha256": "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + } + }, + "targets": [ + { + "Library": { + "crate_name": "doc_comment", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "doc_comment", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "doc-comment 0.3.3", + "target": "build_script_build" + } + ], + "selects": {} + }, + "edition": "2015", + "version": "0.3.3" + }, + "build_script_attrs": { + "data_glob": [ + "**" + ] + }, + "license": "MIT" + }, "dotenv 0.15.0": { "name": "dotenv", "version": "0.15.0", @@ -12590,6 +12758,36 @@ }, "license": "MIT/Apache-2.0" }, + "fuchsia-cprng 0.1.1": { + "name": "fuchsia-cprng", + "version": "0.1.1", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/fuchsia-cprng/0.1.1/download", + "sha256": "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + } + }, + "targets": [ + { + "Library": { + "crate_name": "fuchsia_cprng", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "fuchsia_cprng", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2018", + "version": "0.1.1" + }, + "license": null + }, "funty 2.0.0": { "name": "funty", "version": "2.0.0", @@ -26910,13 +27108,32 @@ ], "crate_features": { "common": [ - "elf", - "errno", "general", "ioctl", "no_std" ], - "selects": {} + "selects": { + "aarch64-unknown-linux-gnu": [ + "elf", + "errno" + ], + "arm-unknown-linux-gnueabi": [ + "elf", + "errno" + ], + "armv7-unknown-linux-gnueabi": [ + "elf", + "errno" + ], + "i686-unknown-linux-gnu": [ + "elf", + "errno" + ], + "x86_64-unknown-linux-gnu": [ + "elf", + "errno" + ] + } }, "edition": "2021", "version": "0.4.12" @@ -28336,6 +28553,27 @@ ], "selects": {} }, + "deps_dev": { + "common": [ + { + "id": "anyhow 1.0.79", + "target": "anyhow" + }, + { + "id": "assert_cmd 2.0.13", + "target": "assert_cmd" + }, + { + "id": "reqwest 0.11.23", + "target": "reqwest" + }, + { + "id": "tempdir 0.3.7", + "target": "tempdir" + } + ], + "selects": {} + }, "edition": "2021", "version": "0.2.0" }, @@ -32239,6 +32477,59 @@ }, "license": "MIT OR Apache-2.0" }, + "predicates 3.1.0": { + "name": "predicates", + "version": "3.1.0", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/predicates/3.1.0/download", + "sha256": "68b87bfd4605926cdfefc1c3b5f8fe560e3feca9d5552cf68c466d3d8236c7e8" + } + }, + "targets": [ + { + "Library": { + "crate_name": "predicates", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "predicates", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "diff" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "anstyle 1.0.4", + "target": "anstyle" + }, + { + "id": "difflib 0.4.0", + "target": "difflib" + }, + { + "id": "predicates-core 1.0.6", + "target": "predicates_core" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "3.1.0" + }, + "license": "MIT OR Apache-2.0" + }, "predicates-core 1.0.6": { "name": "predicates-core", "version": "1.0.6", @@ -33987,6 +34278,77 @@ }, "license": "MIT" }, + "rand 0.4.6": { + "name": "rand", + "version": "0.4.6", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/rand/0.4.6/download", + "sha256": "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" + } + }, + "targets": [ + { + "Library": { + "crate_name": "rand", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "rand", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "default", + "libc", + "std" + ], + "selects": {} + }, + "deps": { + "common": [], + "selects": { + "cfg(target_env = \"sgx\")": [ + { + "id": "rand_core 0.3.1", + "target": "rand_core" + }, + { + "id": "rdrand 0.4.0", + "target": "rdrand" + } + ], + "cfg(target_os = \"fuchsia\")": [ + { + "id": "fuchsia-cprng 0.1.1", + "target": "fuchsia_cprng" + } + ], + "cfg(unix)": [ + { + "id": "libc 0.2.151", + "target": "libc" + } + ], + "cfg(windows)": [ + { + "id": "winapi 0.3.9", + "target": "winapi" + } + ] + } + }, + "edition": "2015", + "version": "0.4.6" + }, + "license": "MIT/Apache-2.0" + }, "rand 0.7.3": { "name": "rand", "version": "0.7.3", @@ -34223,6 +34585,75 @@ }, "license": "MIT OR Apache-2.0" }, + "rand_core 0.3.1": { + "name": "rand_core", + "version": "0.3.1", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/rand_core/0.3.1/download", + "sha256": "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" + } + }, + "targets": [ + { + "Library": { + "crate_name": "rand_core", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "rand_core", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "rand_core 0.4.2", + "target": "rand_core" + } + ], + "selects": {} + }, + "edition": "2015", + "version": "0.3.1" + }, + "license": "MIT/Apache-2.0" + }, + "rand_core 0.4.2": { + "name": "rand_core", + "version": "0.4.2", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/rand_core/0.4.2/download", + "sha256": "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + } + }, + "targets": [ + { + "Library": { + "crate_name": "rand_core", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "rand_core", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "edition": "2015", + "version": "0.4.2" + }, + "license": "MIT/Apache-2.0" + }, "rand_core 0.5.1": { "name": "rand_core", "version": "0.5.1", @@ -34425,6 +34856,45 @@ }, "license": "MIT/Apache-2.0" }, + "rdrand 0.4.0": { + "name": "rdrand", + "version": "0.4.0", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/rdrand/0.4.0/download", + "sha256": "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" + } + }, + "targets": [ + { + "Library": { + "crate_name": "rdrand", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "rdrand", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "rand_core 0.3.1", + "target": "rand_core" + } + ], + "selects": {} + }, + "edition": "2015", + "version": "0.4.0" + }, + "license": "ISC" + }, "redox_syscall 0.4.1": { "name": "redox_syscall", "version": "0.4.1", @@ -34660,6 +35130,7 @@ "common": [ "alloc", "dfa-onepass", + "dfa-search", "hybrid", "meta", "nfa-backtrack", @@ -35047,6 +35518,47 @@ }, "license": null }, + "remove_dir_all 0.5.3": { + "name": "remove_dir_all", + "version": "0.5.3", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/remove_dir_all/0.5.3/download", + "sha256": "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" + } + }, + "targets": [ + { + "Library": { + "crate_name": "remove_dir_all", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "remove_dir_all", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [], + "selects": { + "cfg(windows)": [ + { + "id": "winapi 0.3.9", + "target": "winapi" + } + ] + } + }, + "edition": "2015", + "version": "0.5.3" + }, + "license": "MIT/Apache-2.0" + }, "rend 0.4.1": { "name": "rend", "version": "0.4.1", @@ -40613,6 +41125,49 @@ }, "license": "MIT" }, + "tempdir 0.3.7": { + "name": "tempdir", + "version": "0.3.7", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/tempdir/0.3.7/download", + "sha256": "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" + } + }, + "targets": [ + { + "Library": { + "crate_name": "tempdir", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "tempdir", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "rand 0.4.6", + "target": "rand" + }, + { + "id": "remove_dir_all 0.5.3", + "target": "remove_dir_all" + } + ], + "selects": {} + }, + "edition": "2015", + "version": "0.3.7" + }, + "license": "MIT/Apache-2.0" + }, "tempfile 3.9.0": { "name": "tempfile", "version": "3.9.0", @@ -43953,6 +44508,47 @@ }, "license": "MIT" }, + "wait-timeout 0.2.0": { + "name": "wait-timeout", + "version": "0.2.0", + "repository": { + "Http": { + "url": "https://crates.io/api/v1/crates/wait-timeout/0.2.0/download", + "sha256": "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" + } + }, + "targets": [ + { + "Library": { + "crate_name": "wait_timeout", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "wait_timeout", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [], + "selects": { + "cfg(unix)": [ + { + "id": "libc 0.2.151", + "target": "libc" + } + ] + } + }, + "edition": "2015", + "version": "0.2.0" + }, + "license": "MIT/Apache-2.0" + }, "waker-fn 1.1.1": { "name": "waker-fn", "version": "1.1.1", @@ -44854,6 +45450,7 @@ "objbase", "processenv", "processthreadsapi", + "profileapi", "shlobj", "std", "sysinfoapi", @@ -48692,6 +49289,7 @@ "wasm32-unknown-unknown", "wasm32-wasi" ], + "cfg(target_env = \"sgx\")": [], "cfg(target_family = \"unix\")": [ "aarch64-apple-darwin", "aarch64-apple-ios", @@ -48727,6 +49325,10 @@ "i686-unknown-freebsd", "x86_64-unknown-freebsd" ], + "cfg(target_os = \"fuchsia\")": [ + "aarch64-fuchsia", + "x86_64-fuchsia" + ], "cfg(target_os = \"haiku\")": [], "cfg(target_os = \"hermit\")": [], "cfg(target_os = \"ios\")": [ diff --git a/Cargo.lock b/Cargo.lock index 696577294..c10d792d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -397,13 +397,14 @@ dependencies = [ [[package]] name = "assert_cmd" -version = "1.0.8" +version = "2.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c98233c6673d8601ab23e77eb38f999c51100d46c5703b17288c57fddf3a1ffe" +checksum = "00ad3f3a942eee60335ab4342358c161ee296829e0d16ff42fc1d6cb07815467" dependencies = [ - "bstr", + "anstyle", + "bstr 1.9.0", "doc-comment", - "predicates", + "predicates 3.1.0", "predicates-core", "predicates-tree", "wait-timeout", @@ -934,6 +935,17 @@ dependencies = [ "regex-automata 0.1.10", ] +[[package]] +name = "bstr" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc" +dependencies = [ + "memchr", + "regex-automata 0.4.3", + "serde", +] + [[package]] name = "build-info" version = "0.0.26" @@ -3024,7 +3036,7 @@ version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8b44a11846bda8c9fe9194f9924db7132c34635c7ce020f180f6c5d46d2308f" dependencies = [ - "bstr", + "bstr 0.2.17", "bytes", "crossbeam-channel", "form_urlencoded", @@ -5654,7 +5666,7 @@ dependencies = [ "fragile", "lazy_static", "mockall_derive", - "predicates", + "predicates 2.1.5", "predicates-tree", ] @@ -6461,6 +6473,17 @@ dependencies = [ "regex", ] +[[package]] +name = "predicates" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b87bfd4605926cdfefc1c3b5f8fe560e3feca9d5552cf68c466d3d8236c7e8" +dependencies = [ + "anstyle", + "difflib", + "predicates-core", +] + [[package]] name = "predicates-core" version = "1.0.6" diff --git a/rs/ic-observability/multiservice-discovery/Cargo.toml b/rs/ic-observability/multiservice-discovery/Cargo.toml index 7d6c04b8f..dff023c40 100644 --- a/rs/ic-observability/multiservice-discovery/Cargo.toml +++ b/rs/ic-observability/multiservice-discovery/Cargo.toml @@ -33,6 +33,6 @@ warp = { workspace = true } [dev-dependencies] tempdir = "0.3.7" reqwest = "0.11.23" -assert_cmd = "1.0" +assert_cmd = "2.0.13" anyhow = "1.0.79" From ef9eb3dafbb5b05faee89270662f3936407cbf66 Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 23 Jan 2024 14:05:32 +0100 Subject: [PATCH 21/27] Test ls in bazel --- .../multiservice-discovery/tests/tests.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/rs/ic-observability/multiservice-discovery/tests/tests.rs b/rs/ic-observability/multiservice-discovery/tests/tests.rs index 39999555e..504e1c97a 100644 --- a/rs/ic-observability/multiservice-discovery/tests/tests.rs +++ b/rs/ic-observability/multiservice-discovery/tests/tests.rs @@ -35,6 +35,18 @@ mod tests { } #[test] fn prom_targets_tests() { + let output = Command::new("ls") + .output() + .expect("Failed to execute command"); + + if output.status.success() { + let stdout = String::from_utf8_lossy(&output.stdout); + println!("ls command output:\n{}", stdout); + } else { + let stderr = String::from_utf8_lossy(&output.stderr); + eprintln!("Error running ls command:\n{}", stderr); + } + let rt = Runtime::new().unwrap(); let args = [ "--targets-dir", From df93df91e89b1d35c7ca2139e05cd4eadbf536f6 Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 23 Jan 2024 14:07:36 +0100 Subject: [PATCH 22/27] Test ls in bazel --- rs/ic-observability/multiservice-discovery/tests/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rs/ic-observability/multiservice-discovery/tests/tests.rs b/rs/ic-observability/multiservice-discovery/tests/tests.rs index 504e1c97a..f6482f32a 100644 --- a/rs/ic-observability/multiservice-discovery/tests/tests.rs +++ b/rs/ic-observability/multiservice-discovery/tests/tests.rs @@ -35,7 +35,7 @@ mod tests { } #[test] fn prom_targets_tests() { - let output = Command::new("ls") + let output = Command::new("ls -R") .output() .expect("Failed to execute command"); From c5f53995e2adb61d5cae4d4559fed932458d7f50 Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 23 Jan 2024 14:10:24 +0100 Subject: [PATCH 23/27] Test ls in bazel --- rs/ic-observability/multiservice-discovery/tests/tests.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rs/ic-observability/multiservice-discovery/tests/tests.rs b/rs/ic-observability/multiservice-discovery/tests/tests.rs index f6482f32a..abc3354b1 100644 --- a/rs/ic-observability/multiservice-discovery/tests/tests.rs +++ b/rs/ic-observability/multiservice-discovery/tests/tests.rs @@ -35,7 +35,8 @@ mod tests { } #[test] fn prom_targets_tests() { - let output = Command::new("ls -R") + let output = Command::new("ls") + .arg("-R") .output() .expect("Failed to execute command"); From 695bae7fb129c9818a545645ca4e260300c7ba4d Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 23 Jan 2024 14:12:35 +0100 Subject: [PATCH 24/27] Test ls in bazel --- rs/ic-observability/multiservice-discovery/BUILD.bazel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rs/ic-observability/multiservice-discovery/BUILD.bazel b/rs/ic-observability/multiservice-discovery/BUILD.bazel index 6813a6740..ae7c14c97 100644 --- a/rs/ic-observability/multiservice-discovery/BUILD.bazel +++ b/rs/ic-observability/multiservice-discovery/BUILD.bazel @@ -53,7 +53,7 @@ rust_test( rust_test( name = "prom_targets_tests", srcs = ["tests/tests.rs"], - data = [":multiservice-discovery", "tests/test_data"], + data = [":multiservice-discovery", "tests/test_data/**"], proc_macro_deps = all_crate_deps( proc_macro_dev = True, ), From 82528e9488b6581202d5655baf886800f83f23e0 Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 23 Jan 2024 14:13:40 +0100 Subject: [PATCH 25/27] Test ls in bazel --- rs/ic-observability/multiservice-discovery/BUILD.bazel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rs/ic-observability/multiservice-discovery/BUILD.bazel b/rs/ic-observability/multiservice-discovery/BUILD.bazel index ae7c14c97..4c7930204 100644 --- a/rs/ic-observability/multiservice-discovery/BUILD.bazel +++ b/rs/ic-observability/multiservice-discovery/BUILD.bazel @@ -53,7 +53,7 @@ rust_test( rust_test( name = "prom_targets_tests", srcs = ["tests/tests.rs"], - data = [":multiservice-discovery", "tests/test_data/**"], + data = [":multiservice-discovery", "tests/test_data/*"], proc_macro_deps = all_crate_deps( proc_macro_dev = True, ), From d9bca98602ba0536a16ec9c7c71e49597917f1bc Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 23 Jan 2024 14:57:42 +0100 Subject: [PATCH 26/27] Fix Bazel test --- .../multiservice-discovery/BUILD.bazel | 2 +- .../time.local_store.v1.CertificationTime.pb | 2 +- .../multiservice-discovery/tests/tests.rs | 39 ++++++++++--------- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/rs/ic-observability/multiservice-discovery/BUILD.bazel b/rs/ic-observability/multiservice-discovery/BUILD.bazel index 4c7930204..2ab1faf34 100644 --- a/rs/ic-observability/multiservice-discovery/BUILD.bazel +++ b/rs/ic-observability/multiservice-discovery/BUILD.bazel @@ -53,7 +53,7 @@ rust_test( rust_test( name = "prom_targets_tests", srcs = ["tests/tests.rs"], - data = [":multiservice-discovery", "tests/test_data/*"], + data = [":multiservice-discovery"] + glob(["tests/test_data/**"]), proc_macro_deps = all_crate_deps( proc_macro_dev = True, ), diff --git a/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb b/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb index 211ee8289..00bdb2616 100644 --- a/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb +++ b/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb @@ -1 +1 @@ -ը \ No newline at end of file +ƿ \ No newline at end of file diff --git a/rs/ic-observability/multiservice-discovery/tests/tests.rs b/rs/ic-observability/multiservice-discovery/tests/tests.rs index abc3354b1..43cc73b4b 100644 --- a/rs/ic-observability/multiservice-discovery/tests/tests.rs +++ b/rs/ic-observability/multiservice-discovery/tests/tests.rs @@ -35,29 +35,30 @@ mod tests { } #[test] fn prom_targets_tests() { - let output = Command::new("ls") - .arg("-R") - .output() - .expect("Failed to execute command"); - - if output.status.success() { - let stdout = String::from_utf8_lossy(&output.stdout); - println!("ls command output:\n{}", stdout); - } else { - let stderr = String::from_utf8_lossy(&output.stderr); - eprintln!("Error running ls command:\n{}", stderr); - } - let rt = Runtime::new().unwrap(); - let args = [ - "--targets-dir", - "tests/test_data", + let mut args = vec![ "--nns-url", - "http://donotupdate.app" + "http://donotupdate.app", + "--targets-dir", ]; - let bazel_path = "rs/ic-observability/multiservice-discovery/multiservice-discovery"; - let mut cmd = Command::cargo_bin("multiservice-discovery").unwrap_or_else(|_| Command::new(bazel_path)); + let cargo_bin_path = "multiservice-discovery"; + let cargo_data_path = "tests/test_data"; + + let bazel_bin_path = "rs/ic-observability/multiservice-discovery/multiservice-discovery"; + let bazel_data_path = "rs/ic-observability/multiservice-discovery/tests/test_data"; + + let mut cmd = match Command::cargo_bin(cargo_bin_path) { + Ok(command) => { + args.push(cargo_data_path); + command + }, + _ => { + args.push(bazel_data_path); + Command::new(bazel_bin_path) + } + }; + let mut child = cmd.args(args).spawn().unwrap(); let handle = rt.spawn(async { fetch_targets().await From 044702cbcb20138673e686db10fbbd02b5471990 Mon Sep 17 00:00:00 2001 From: Pietro Date: Tue, 23 Jan 2024 15:26:10 +0100 Subject: [PATCH 27/27] Add constants --- .../time.local_store.v1.CertificationTime.pb | 2 +- .../multiservice-discovery/tests/tests.rs | 20 +++++++++---------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb b/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb index 00bdb2616..3d16bf51d 100644 --- a/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb +++ b/rs/ic-observability/multiservice-discovery/tests/test_data/mercury/targets/time.local_store.v1.CertificationTime.pb @@ -1 +1 @@ -ƿ \ No newline at end of file + \ No newline at end of file diff --git a/rs/ic-observability/multiservice-discovery/tests/tests.rs b/rs/ic-observability/multiservice-discovery/tests/tests.rs index 43cc73b4b..245691a34 100644 --- a/rs/ic-observability/multiservice-discovery/tests/tests.rs +++ b/rs/ic-observability/multiservice-discovery/tests/tests.rs @@ -8,6 +8,11 @@ mod tests { use tokio::time::sleep; use multiservice_discovery_shared::builders::prometheus_config_structure::{PrometheusStaticConfig, JOB, IC_NAME, IC_SUBNET}; + const CRAGO_BIN_PATH: &str = "multiservice-discovery"; + const CRAGO_DATA_PATH: &str = "tests/test_data"; + const BAZEL_BIN_PATH: &str = "rs/ic-observability/multiservice-discovery/multiservice-discovery"; + const BAZEL_DATA_PATH: &str = "rs/ic-observability/multiservice-discovery/tests/test_data"; + async fn fetch_targets() -> anyhow::Result> { let timeout_duration = Duration::from_secs(300); let start_time = std::time::Instant::now(); @@ -41,21 +46,14 @@ mod tests { "http://donotupdate.app", "--targets-dir", ]; - - let cargo_bin_path = "multiservice-discovery"; - let cargo_data_path = "tests/test_data"; - - let bazel_bin_path = "rs/ic-observability/multiservice-discovery/multiservice-discovery"; - let bazel_data_path = "rs/ic-observability/multiservice-discovery/tests/test_data"; - - let mut cmd = match Command::cargo_bin(cargo_bin_path) { + let mut cmd = match Command::cargo_bin(CRAGO_BIN_PATH) { Ok(command) => { - args.push(cargo_data_path); + args.push(CRAGO_DATA_PATH); command }, _ => { - args.push(bazel_data_path); - Command::new(bazel_bin_path) + args.push(BAZEL_DATA_PATH); + Command::new(BAZEL_BIN_PATH) } };