From 59ff20f11dd563a837fce8b94538554d9a391511 Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Fri, 17 Feb 2023 00:53:30 +0100 Subject: [PATCH 01/36] Bumped clap to v4 --- Cargo.lock | 192 +++++++++++++++++++++++++++++++++++++++++++---------- Cargo.toml | 2 +- 2 files changed, 158 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 79998c8..b6aa6b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,17 +23,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - [[package]] name = "autocfg" version = "1.0.1" @@ -78,26 +67,24 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "3.2.2" +version = "4.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e538f9ee5aa3b3963f09a997035f883677966ed50fce0292611927ce6f6d8c6" +checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76" dependencies = [ - "atty", "bitflags", "clap_derive", "clap_lex", - "indexmap", - "lazy_static", + "is-terminal", + "once_cell", "strsim", "termcolor", - "textwrap", ] [[package]] name = "clap_derive" -version = "3.2.2" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7f98063cac4652f23ccda556b8d04347a7fc4b2cff1f7577cc8c6546e0d8078" +checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8" dependencies = [ "heck", "proc-macro-error", @@ -108,9 +95,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.2.4" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +checksum = "783fe232adfca04f90f56201b26d79682d4cd2625e0bc7290b95123afe558ade" dependencies = [ "os_str_bytes", ] @@ -140,6 +127,27 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "fastrand" version = "1.7.0" @@ -279,6 +287,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + [[package]] name = "http" version = "0.2.6" @@ -380,12 +394,34 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "io-lifetimes" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3" +dependencies = [ + "libc", + "windows-sys", +] + [[package]] name = "ipnet" version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9" +[[package]] +name = "is-terminal" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0a45d56fe973d6db23972bf5bc46f988a4a2385deac9cc29572f09daef" +dependencies = [ + "hermit-abi 0.3.1", + "io-lifetimes", + "rustix", + "windows-sys", +] + [[package]] name = "itoa" version = "0.4.8" @@ -415,9 +451,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.112" +version = "0.2.139" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" + +[[package]] +name = "linux-raw-sys" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" [[package]] name = "log" @@ -501,15 +543,15 @@ version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", ] [[package]] name = "once_cell" -version = "1.9.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" +checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" [[package]] name = "openssl" @@ -606,11 +648,11 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] @@ -733,6 +775,20 @@ dependencies = [ "winreg", ] +[[package]] +name = "rustix" +version = "0.36.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys", +] + [[package]] name = "ryu" version = "1.0.9" @@ -871,12 +927,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "textwrap" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" - [[package]] name = "tinyvec" version = "1.5.1" @@ -969,6 +1019,12 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" +[[package]] +name = "unicode-ident" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" + [[package]] name = "unicode-normalization" version = "0.1.19" @@ -1131,6 +1187,72 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" + [[package]] name = "winreg" version = "0.7.0" diff --git a/Cargo.toml b/Cargo.toml index d6b6388..d1f1ee6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ rand = "0.8.4" reqwest = { version = "0.11.9", features = ["blocking"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.74" -clap = { version = "3.1.7", features = ["derive"] } +clap = { version = "4.1.4", features = ["derive"] } [dev-dependencies] regex = "1.5.4" From 17749e027e775c67b8f3e58e9ca9ebcc8d8a5fda Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Fri, 17 Feb 2023 01:09:47 +0100 Subject: [PATCH 02/36] Resolve build warning --- Cargo.lock | 113 ++++++++++++++++++++++++++--------------------------- 1 file changed, 56 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b6aa6b1..3ffbfe0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,15 +25,15 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "base64" -version = "0.13.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" [[package]] name = "bitflags" @@ -244,7 +244,7 @@ checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.10.2+wasi-snapshot-preview1", ] [[package]] @@ -301,7 +301,7 @@ checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" dependencies = [ "bytes", "fnv", - "itoa 1.0.1", + "itoa", ] [[package]] @@ -317,9 +317,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.5.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" @@ -329,9 +329,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.16" +version = "0.14.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7ec3e62bdc98a2f0393a5048e4c30ef659440ea6e0e572965103e72bd836f55" +checksum = "5e011372fa0b68db8350aa7a248930ecc7839bf46d8485577d69f117a75f164c" dependencies = [ "bytes", "futures-channel", @@ -342,7 +342,7 @@ dependencies = [ "http-body", "httparse", "httpdate", - "itoa 0.4.8", + "itoa", "pin-project-lite", "socket2", "tokio", @@ -401,7 +401,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -419,15 +419,9 @@ dependencies = [ "hermit-abi 0.3.1", "io-lifetimes", "rustix", - "windows-sys", + "windows-sys 0.45.0", ] -[[package]] -name = "itoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" - [[package]] name = "itoa" version = "1.0.1" @@ -490,31 +484,21 @@ checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" [[package]] name = "mio" -version = "0.7.14" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" dependencies = [ "libc", "log", - "miow", - "ntapi", - "winapi", -] - -[[package]] -name = "miow" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" -dependencies = [ - "winapi", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.45.0", ] [[package]] name = "native-tls" -version = "0.2.8" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" dependencies = [ "lazy_static", "libc", @@ -528,15 +512,6 @@ dependencies = [ "tempfile", ] -[[package]] -name = "ntapi" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" -dependencies = [ - "winapi", -] - [[package]] name = "num_cpus" version = "1.13.1" @@ -741,9 +716,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.9" +version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f242f1488a539a79bac6dbe7c8609ae43b7914b7736210f239a37cccb32525" +checksum = "21eed90ec8570952d53b772ecf8f206aa1ec9a3d76b2521c56c42973f2d91ee9" dependencies = [ "base64", "bytes", @@ -757,10 +732,10 @@ dependencies = [ "hyper-tls", "ipnet", "js-sys", - "lazy_static", "log", "mime", "native-tls", + "once_cell", "percent-encoding", "pin-project-lite", "serde", @@ -768,6 +743,7 @@ dependencies = [ "serde_urlencoded", "tokio", "tokio-native-tls", + "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", @@ -786,7 +762,7 @@ dependencies = [ "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -854,7 +830,7 @@ version = "1.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee2bb9cd061c5865d345bb02ca49fcef1391741b672b54a0bf7b679badec3142" dependencies = [ - "itoa 1.0.1", + "itoa", "ryu", "serde", ] @@ -866,7 +842,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", - "itoa 1.0.1", + "itoa", "ryu", "serde", ] @@ -879,9 +855,9 @@ checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" [[package]] name = "socket2" -version = "0.4.2" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516" +checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" dependencies = [ "libc", "winapi", @@ -944,17 +920,19 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.15.0" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbbf1c778ec206785635ce8ad57fe52b3009ae9e0c9f574a728f3049d3e55838" +checksum = "c8e00990ebabbe4c14c08aca901caed183ecd5c09562a12c824bb53d3c3fd3af" dependencies = [ + "autocfg", "bytes", "libc", "memchr", "mio", "num_cpus", "pin-project-lite", - "winapi", + "socket2", + "windows-sys 0.42.0", ] [[package]] @@ -1080,6 +1058,12 @@ version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "wasm-bindgen" version = "0.2.79" @@ -1187,6 +1171,21 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -1255,9 +1254,9 @@ checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" [[package]] name = "winreg" -version = "0.7.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" dependencies = [ "winapi", ] From 75a54007a7927317b05f8678ffe50983a365d03d Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Fri, 17 Feb 2023 01:10:00 +0100 Subject: [PATCH 03/36] Moved some stuff to cargo.toml --- Cargo.toml | 2 ++ src/lib.rs | 13 ++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d1f1ee6..0d6b13c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,7 @@ [package] name = "ambi_mock_client" +authors = ["Rust Never Sleeps community (https://github.com/Jim-Hodapp-Coaching/)"] +description = "Provides a mock Ambi client that emulates real sensor hardware such as an Edge client." version = "0.1.0" edition = "2021" diff --git a/src/lib.rs b/src/lib.rs index e4b8560..c818c64 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,13 +18,11 @@ use std::fmt; /// Defines the Ambi Mock Client command line interface as a struct #[derive(Parser, Debug)] -#[clap(name = "Ambi Mock Client")] -#[clap(author = "Rust Never Sleeps community (https://github.com/Jim-Hodapp-Coaching/)")] -#[clap(version = "0.1.0")] -#[clap( - about = "Provides a mock Ambi client that emulates real sensor hardware such as an Edge client." -)] -#[clap( +#[command( + name = "Ambi Mock Client", + author, + version, + about, long_about = "This application emulates a real set of hardware sensors that can report on environmental conditions such as temperature, pressure, humidity, etc." )] pub struct Cli { @@ -131,6 +129,7 @@ pub fn run(cli: &Cli) { ); let json = serde_json::to_string(&reading).unwrap(); + // TODO: Make the port configurable const URL: &str = "http://localhost:4000/api/readings/add"; println!("Sending POST request to {} as JSON: {}", URL, json); From c286692e0839ca4e2c8c7583c87bdcb8c0309525 Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Fri, 17 Feb 2023 01:14:24 +0100 Subject: [PATCH 04/36] Fix some clippy warnings --- src/lib.rs | 8 ++++---- src/main.rs | 3 --- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index c818c64..8cc616c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -69,10 +69,10 @@ enum AirPurity { impl AirPurity { fn from_value(value: f64) -> AirPurity { match value { - value if value >= f64::MIN && value <= 50.0 => return AirPurity::FreshAir, - value if value > 50.0 && value <= 100.0 => return AirPurity::Low, - value if value > 100.0 && value <= 150.0 => return AirPurity::High, - _ => return AirPurity::Dangerous, + value if (f64::MIN..=50.0).contains(&value) => AirPurity::FreshAir, + value if value > 50.0 && value <= 100.0 => AirPurity::Low, + value if value > 100.0 && value <= 150.0 => AirPurity::High, + _ => AirPurity::Dangerous, } } } diff --git a/src/main.rs b/src/main.rs index bab8a18..4c33926 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,9 +12,6 @@ use clap::{Parser}; -// Internal library namespace for separation of app logic -use ambi_mock_client; - fn main() { // Parses the provided command line interface arguments and flags let cli = ambi_mock_client::Cli::parse(); From 7eb9a970835c905cfc65d7d5ae73c65031b4e350 Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Fri, 17 Feb 2023 01:20:17 +0100 Subject: [PATCH 05/36] fmt --- src/main.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main.rs b/src/main.rs index 4c33926..35fe678 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,16 @@ -//! # Provides a mock Ambi client that emulates real sensor hardware such as +//! # Provides a mock Ambi client that emulates real sensor hardware such as //! an Edge client. //! //! This application emulates a real set of hardware sensors that can report on //! environmental conditions such as temperature, pressure, humidity, etc. -//! +//! //! Please see the `ambi` repository for the web backend that this client connects to //! and the `edge-rs` repository for what this client is emulating. //! //! See the `LICENSE` file for Copyright and license details. -//! +//! -use clap::{Parser}; +use clap::Parser; fn main() { // Parses the provided command line interface arguments and flags @@ -18,8 +18,8 @@ fn main() { match cli.debug { true => println!("Debug mode is now *on*"), - false => println!("Debug mode is now *off*") + false => println!("Debug mode is now *off*"), } - + ambi_mock_client::run(&cli); } From f2e152f9893cc5d67ab9f6fff961dad61fdfb724 Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Fri, 17 Feb 2023 01:20:25 +0100 Subject: [PATCH 06/36] Split to data.rs --- src/data.rs | 107 ++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 114 ++++------------------------------------------------ 2 files changed, 115 insertions(+), 106 deletions(-) create mode 100644 src/data.rs diff --git a/src/data.rs b/src/data.rs new file mode 100644 index 0000000..40cc883 --- /dev/null +++ b/src/data.rs @@ -0,0 +1,107 @@ +use core::fmt; + +use rand::{thread_rng, Rng}; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize)] +pub(crate) struct Reading { + temperature: f64, + humidity: f64, + pressure: i32, + dust_concentration: f64, + air_purity: String, +} + +impl Reading { + pub(crate) fn new( + temperature: f64, + humidity: f64, + pressure: i32, + dust_concentration: f64, + air_purity: String, + ) -> Reading { + Reading { + temperature, + humidity, + pressure, + dust_concentration, + air_purity, + } + } +} + +#[derive(Debug, PartialEq)] +pub(crate) enum AirPurity { + Dangerous, + High, + Low, + FreshAir, +} + +impl AirPurity { + pub(crate) fn from_value(value: f64) -> AirPurity { + match value { + value if (f64::MIN..=50.0).contains(&value) => AirPurity::FreshAir, + value if value > 50.0 && value <= 100.0 => AirPurity::Low, + value if value > 100.0 && value <= 150.0 => AirPurity::High, + _ => AirPurity::Dangerous, + } + } +} + +// implements fmt::Display for AirPurity so that we can call .to_string() on +// each enum value +impl fmt::Display for AirPurity { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + AirPurity::Low => write!(f, "Fresh Air"), + AirPurity::High => write!(f, "Low Pollution"), + AirPurity::Dangerous => write!(f, "High Pollution"), + AirPurity::FreshAir => write!(f, "Dangerous Pollution"), + } + } +} + +pub(crate) fn random_gen_humidity() -> f64 { + let mut rng = thread_rng(); + let value = rng.gen_range(0.0..=100.0); + // Limit to 2 decimals + f64::trunc(value * 100.0) / 100.0 +} + +pub(crate) fn random_gen_temperature() -> f64 { + let mut rng = thread_rng(); + let value = rng.gen_range(15.0..=35.0); + // Limit to 2 decimals + f64::trunc(value * 100.0) / 100.0 +} + +pub(crate) fn random_gen_pressure() -> i32 { + let mut rng = thread_rng(); + rng.gen_range(900..=1100) +} + +pub(crate) fn random_gen_dust_concentration() -> f64 { + let mut rng = thread_rng(); + let value = rng.gen_range(0.0..=1000.0); + f64::trunc(value * 100.0) / 100.0 +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn air_purity_from_value_returns_correct_enum() { + let mut rng = thread_rng(); + let fresh_air = rng.gen_range(0.0..=50.0); + let low = rng.gen_range(51.0..=100.0); + let high = rng.gen_range(101.0..=150.0); + let dangerous = rng.gen_range(151.0..f64::MAX); + + assert_eq!(AirPurity::from_value(fresh_air), AirPurity::FreshAir); + assert_eq!(AirPurity::from_value(low), AirPurity::Low); + assert_eq!(AirPurity::from_value(high), AirPurity::High); + assert_eq!(AirPurity::from_value(dangerous), AirPurity::Dangerous); + } +} diff --git a/src/lib.rs b/src/lib.rs index 8cc616c..fada005 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,12 +9,17 @@ //! See the `LICENSE` file for Copyright and license details. //! +mod data; + +use crate::data::Reading; +use crate::data::{ + random_gen_dust_concentration, random_gen_humidity, random_gen_pressure, random_gen_temperature, +}; use clap::Parser; -use rand::{thread_rng, Rng}; use reqwest::blocking::Client; use reqwest::header::CONTENT_TYPE; -use serde::{Deserialize, Serialize}; -use std::fmt; + +use crate::data::AirPurity; /// Defines the Ambi Mock Client command line interface as a struct #[derive(Parser, Debug)] @@ -31,90 +36,6 @@ pub struct Cli { pub debug: bool, } -#[derive(Serialize, Deserialize)] -struct Reading { - temperature: f64, - humidity: f64, - pressure: i32, - dust_concentration: f64, - air_purity: String, -} - -impl Reading { - fn new( - temperature: f64, - humidity: f64, - pressure: i32, - dust_concentration: f64, - air_purity: String, - ) -> Reading { - Reading { - temperature, - humidity, - pressure, - dust_concentration, - air_purity, - } - } -} - -#[derive(Debug, PartialEq)] -enum AirPurity { - Dangerous, - High, - Low, - FreshAir, -} - -impl AirPurity { - fn from_value(value: f64) -> AirPurity { - match value { - value if (f64::MIN..=50.0).contains(&value) => AirPurity::FreshAir, - value if value > 50.0 && value <= 100.0 => AirPurity::Low, - value if value > 100.0 && value <= 150.0 => AirPurity::High, - _ => AirPurity::Dangerous, - } - } -} - -// implements fmt::Display for AirPurity so that we can call .to_string() on -// each enum value -impl fmt::Display for AirPurity { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - AirPurity::Low => write!(f, "Fresh Air"), - AirPurity::High => write!(f, "Low Pollution"), - AirPurity::Dangerous => write!(f, "High Pollution"), - AirPurity::FreshAir => write!(f, "Dangerous Pollution"), - } - } -} - -fn random_gen_humidity() -> f64 { - let mut rng = thread_rng(); - let value = rng.gen_range(0.0..=100.0); - // Limit to 2 decimals - f64::trunc(value * 100.0) / 100.0 -} - -fn random_gen_temperature() -> f64 { - let mut rng = thread_rng(); - let value = rng.gen_range(15.0..=35.0); - // Limit to 2 decimals - f64::trunc(value * 100.0) / 100.0 -} - -fn random_gen_pressure() -> i32 { - let mut rng = thread_rng(); - rng.gen_range(900..=1100) -} - -fn random_gen_dust_concentration() -> f64 { - let mut rng = thread_rng(); - let value = rng.gen_range(0.0..=1000.0); - f64::trunc(value * 100.0) / 100.0 -} - pub fn run(cli: &Cli) { println!("\r\ncli: {:?}\r\n", cli); @@ -167,22 +88,3 @@ pub fn run(cli: &Cli) { } } } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn air_purity_from_value_returns_correct_enum() { - let mut rng = thread_rng(); - let fresh_air = rng.gen_range(0.0..=50.0); - let low = rng.gen_range(51.0..=100.0); - let high = rng.gen_range(101.0..=150.0); - let dangerous = rng.gen_range(151.0..f64::MAX); - - assert_eq!(AirPurity::from_value(fresh_air), AirPurity::FreshAir); - assert_eq!(AirPurity::from_value(low), AirPurity::Low); - assert_eq!(AirPurity::from_value(high), AirPurity::High); - assert_eq!(AirPurity::from_value(dangerous), AirPurity::Dangerous); - } -} From ffd318147f82b414154adbc2bf5e45e1a3fccdb7 Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Fri, 17 Feb 2023 03:06:50 +0100 Subject: [PATCH 07/36] Export url --- src/lib.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index fada005..c461478 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,6 +10,7 @@ //! mod data; +mod requests; use crate::data::Reading; use crate::data::{ @@ -21,6 +22,9 @@ use reqwest::header::CONTENT_TYPE; use crate::data::AirPurity; +// TODO: Make the port configurable +const URL: &str = "http://localhost:4000/api/readings/add"; + /// Defines the Ambi Mock Client command line interface as a struct #[derive(Parser, Debug)] #[command( @@ -50,8 +54,6 @@ pub fn run(cli: &Cli) { ); let json = serde_json::to_string(&reading).unwrap(); - // TODO: Make the port configurable - const URL: &str = "http://localhost:4000/api/readings/add"; println!("Sending POST request to {} as JSON: {}", URL, json); From 84d8655690db95ab79816a6eba8c399be90c7a25 Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Fri, 17 Feb 2023 03:07:20 +0100 Subject: [PATCH 08/36] WIP --- src/requests.rs | 128 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 src/requests.rs diff --git a/src/requests.rs b/src/requests.rs new file mode 100644 index 0000000..08c642d --- /dev/null +++ b/src/requests.rs @@ -0,0 +1,128 @@ +#![allow(dead_code)] + +use std::{ + thread, + time::{Duration, SystemTime}, +}; + +use reqwest::blocking::Client; + +const DEFAULT_REQUEST_AMOUNT: u32 = 1; +const DEFAULT_TIME_PER_REQUEST: Duration = Duration::from_secs(10); +const DEFAULT_NUM_THREADS: u32 = 1; + +#[derive(Clone, Copy)] +struct RequestSchedulerBuilder { + request_amount: Option, + time_per_request: Option, + total_time: Option, + num_threads: Option, +} + +impl RequestSchedulerBuilder { + fn default() -> Self { + RequestSchedulerBuilder { + request_amount: None, + time_per_request: None, + total_time: None, + num_threads: None, + } + } + + fn with_request_amount(&mut self, request_amount: u32) -> &mut Self { + self.request_amount = Some(request_amount); + self + } + + fn with_time_per_request(&mut self, time_per_request: Duration) -> &mut Self { + self.time_per_request = Some(time_per_request); + self + } + + fn with_total_time(&mut self, total_time: Duration) -> &mut Self { + self.total_time = Some(total_time); + self + } + + fn with_num_threads(&mut self, num_threads: u32) -> &mut Self { + self.num_threads = Some(num_threads); + self + } + + fn build(self) -> RequestScheduler { + let request_amount = self.request_amount.unwrap_or(DEFAULT_REQUEST_AMOUNT); + + let time_per_request = match (&self.time_per_request, &self.total_time) { + (None, None) => DEFAULT_TIME_PER_REQUEST, + (None, Some(total_time)) => *total_time / request_amount, + (Some(time_per_request), None) => *time_per_request, + (Some(time_per_request), Some(_)) => *time_per_request, + }; + + let num_threads = self.num_threads.unwrap_or(DEFAULT_NUM_THREADS); + + RequestScheduler { + request_amount, + time_per_request, + num_threads, + } + } +} + +#[derive(Clone, Copy)] +pub(crate) struct RequestScheduler { + request_amount: u32, + time_per_request: Duration, + num_threads: u32, +} + +/// -s 5: 1 req every 5 seconds. +pub(crate) fn send_data(req_scheduler: RequestScheduler, json: String) { + let handles = (0..req_scheduler.num_threads) + .map(|_| { + let json_clone = json.clone(); + thread::spawn(move || send_data_internal(req_scheduler, json_clone)) + }) + .collect::>(); + + let _result: Vec<_> = handles.into_iter().map(|x| x.join()).collect(); +} + +fn send_data_internal(req_scheduler: RequestScheduler, json: String) { + // TODO: Actually make the API calls. + let client = Client::new(); + let start = SystemTime::now(); + + for _ in 0..req_scheduler.request_amount { + // let res = client + // .post(URL) + // .header(CONTENT_TYPE, "application/json") + // .body(json.clone()) + // .send(); + + println!("{:?}", SystemTime::elapsed(&start)); + + thread::sleep(req_scheduler.time_per_request) + } +} + +#[cfg(test)] +mod tests { + use std::time::Duration; + + use super::{send_data, RequestSchedulerBuilder}; + + // Used for manual testing, will be removed/edited later + // cargo t -- send_data_test --nocapture + #[test] + fn send_data_test() { + let req_scheduler = RequestSchedulerBuilder::default() + .with_num_threads(2) + .with_request_amount(5) + .with_time_per_request(Duration::from_secs(1)) + // .with_total_time(Duration::from_secs(1)) + .build(); + + send_data(req_scheduler, "{}".to_owned()); + } +} From 96b749ddc87daafda67024a5a893085a8b40b026 Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Fri, 17 Feb 2023 03:13:09 +0100 Subject: [PATCH 09/36] Upgrade dependencies (cargo-audit/dependabot alerts) --- Cargo.lock | 351 +++++++++++++++++++++++++---------------------------- Cargo.toml | 4 +- 2 files changed, 169 insertions(+), 186 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3ffbfe0..7b7474a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "aho-corasick" -version = "0.7.18" +version = "0.7.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" dependencies = [ "memchr", ] @@ -43,21 +43,21 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bumpalo" -version = "3.9.1" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" +checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" [[package]] name = "bytes" -version = "1.1.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" [[package]] name = "cc" -version = "1.0.72" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] name = "cfg-if" @@ -67,9 +67,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.1.4" +version = "4.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76" +checksum = "ec0b0588d44d4d63a87dbd75c136c166bbfd9a86a31cb89e09906521c7d3f5e3" dependencies = [ "bitflags", "clap_derive", @@ -104,9 +104,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" dependencies = [ "core-foundation-sys", "libc", @@ -120,9 +120,9 @@ checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "encoding_rs" -version = "0.8.30" +version = "0.8.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dc8abb250ffdda33912550faa54c88ec8b998dec0b2c55ab224921ce11df" +checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" dependencies = [ "cfg-if", ] @@ -150,9 +150,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.7.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" dependencies = [ "instant", ] @@ -180,52 +180,51 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" dependencies = [ - "matches", "percent-encoding", ] [[package]] name = "futures-channel" -version = "0.3.19" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3dda0b6588335f360afc675d0564c17a77a2bda81ca178a4b6081bd86c7f0b" +checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.19" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c8ff0461b82559810cdccfde3215c3f373807f5e5232b71479bff7bb2583d7" +checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608" [[package]] name = "futures-io" -version = "0.3.19" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f9d34af5a1aac6fb380f735fe510746c38067c5bf16c7fd250280503c971b2" +checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531" [[package]] name = "futures-sink" -version = "0.3.19" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3055baccb68d74ff6480350f8d6eb8fcfa3aa11bdc1a1ae3afdd0514617d508" +checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364" [[package]] name = "futures-task" -version = "0.3.19" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ee7c6485c30167ce4dfb83ac568a849fe53274c831081476ee13e0dce1aad72" +checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366" [[package]] name = "futures-util" -version = "0.3.19" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164" +checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1" dependencies = [ "futures-core", "futures-io", @@ -238,20 +237,20 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.3" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", "libc", - "wasi 0.10.2+wasi-snapshot-preview1", + "wasi", ] [[package]] name = "h2" -version = "0.3.10" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c9de88456263e249e241fcd211d3954e2c9b0ef7ccfc235a444eb367cae3689" +checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" dependencies = [ "bytes", "fnv", @@ -268,21 +267,21 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.11.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "heck" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.1.19" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" dependencies = [ "libc", ] @@ -295,9 +294,9 @@ checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" [[package]] name = "http" -version = "0.2.6" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" +checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" dependencies = [ "bytes", "fnv", @@ -306,9 +305,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ "bytes", "http", @@ -366,20 +365,19 @@ dependencies = [ [[package]] name = "idna" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" dependencies = [ - "matches", "unicode-bidi", "unicode-normalization", ] [[package]] name = "indexmap" -version = "1.8.0" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" dependencies = [ "autocfg", "hashbrown", @@ -406,9 +404,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.3.1" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9" +checksum = "30e22bd8629359895450b59ea7a776c850561b96a3b1d31321c1949d9e6c9146" [[package]] name = "is-terminal" @@ -424,15 +422,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.1" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" +checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" [[package]] name = "js-sys" -version = "0.3.56" +version = "0.3.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04" +checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" dependencies = [ "wasm-bindgen", ] @@ -457,24 +455,18 @@ checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" [[package]] name = "log" -version = "0.4.14" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", ] -[[package]] -name = "matches" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" - [[package]] name = "memchr" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "mime" @@ -490,7 +482,7 @@ checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" dependencies = [ "libc", "log", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "windows-sys 0.45.0", ] @@ -514,34 +506,46 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.13.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi 0.1.19", + "hermit-abi 0.2.6", "libc", ] [[package]] name = "once_cell" -version = "1.17.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "openssl" -version = "0.10.38" +version = "0.10.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" +checksum = "b102428fd03bc5edf97f62620f7298614c45cedf287c271e7ed450bbaf83f2e1" dependencies = [ "bitflags", "cfg-if", "foreign-types", "libc", "once_cell", + "openssl-macros", "openssl-sys", ] +[[package]] +name = "openssl-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "openssl-probe" version = "0.1.5" @@ -550,9 +554,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.72" +version = "0.9.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb" +checksum = "23bbbf7854cd45b83958ebe919f0e8e516793727652e27fda10a8384cfc790b7" dependencies = [ "autocfg", "cc", @@ -563,21 +567,21 @@ dependencies = [ [[package]] name = "os_str_bytes" -version = "6.1.0" +version = "6.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa" +checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" [[package]] name = "percent-encoding" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pin-project-lite" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" [[package]] name = "pin-utils" @@ -587,15 +591,15 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.24" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" [[package]] name = "ppv-lite86" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro-error" @@ -632,23 +636,22 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.14" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" dependencies = [ "proc-macro2", ] [[package]] name = "rand" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", "rand_core", - "rand_hc", ] [[package]] @@ -663,36 +666,27 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", ] -[[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core", -] - [[package]] name = "redox_syscall" -version = "0.2.10" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ "bitflags", ] [[package]] name = "regex" -version = "1.5.4" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" dependencies = [ "aho-corasick", "memchr", @@ -701,9 +695,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.25" +version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" [[package]] name = "remove_dir_all" @@ -767,25 +761,24 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" +checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" [[package]] name = "schannel" -version = "0.1.19" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" +checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" dependencies = [ - "lazy_static", - "winapi", + "windows-sys 0.42.0", ] [[package]] name = "security-framework" -version = "2.5.0" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d09d3c15d814eda1d6a836f2f2b56a6abc1446c8a34351cb3180d3db92ffe4ce" +checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" dependencies = [ "bitflags", "core-foundation", @@ -796,9 +789,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.5.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e90dd10c41c6bfc633da6e0c659bd25d31e0791e5974ac42970267d59eba87f7" +checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" dependencies = [ "core-foundation-sys", "libc", @@ -806,18 +799,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.133" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a" +checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.133" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537" +checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" dependencies = [ "proc-macro2", "quote", @@ -826,9 +819,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.74" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2bb9cd061c5865d345bb02ca49fcef1391741b672b54a0bf7b679badec3142" +checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76" dependencies = [ "itoa", "ryu", @@ -849,9 +842,12 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.5" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] [[package]] name = "socket2" @@ -871,13 +867,13 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.85" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -896,27 +892,27 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.1.3" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" dependencies = [ "winapi-util", ] [[package]] name = "tinyvec" -version = "1.5.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" dependencies = [ "tinyvec_macros", ] [[package]] name = "tinyvec_macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" @@ -937,9 +933,9 @@ dependencies = [ [[package]] name = "tokio-native-tls" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ "native-tls", "tokio", @@ -947,29 +943,29 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.6.9" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" +checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2" dependencies = [ "bytes", "futures-core", "futures-sink", - "log", "pin-project-lite", "tokio", + "tracing", ] [[package]] name = "tower-service" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.29" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", "pin-project-lite", @@ -978,24 +974,24 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.21" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" dependencies = [ - "lazy_static", + "once_cell", ] [[package]] name = "try-lock" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "unicode-bidi" -version = "0.3.7" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" +checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58" [[package]] name = "unicode-ident" @@ -1005,28 +1001,21 @@ checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" [[package]] name = "unicode-normalization" -version = "0.1.19" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - [[package]] name = "url" -version = "2.2.2" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" dependencies = [ "form_urlencoded", "idna", - "matches", "percent-encoding", ] @@ -1052,12 +1041,6 @@ dependencies = [ "try-lock", ] -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -1066,9 +1049,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.79" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06" +checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1076,13 +1059,13 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.79" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca" +checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" dependencies = [ "bumpalo", - "lazy_static", "log", + "once_cell", "proc-macro2", "quote", "syn", @@ -1091,9 +1074,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.29" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb6ec270a31b1d3c7e266b999739109abce8b6c87e4b31fcfcd788b65267395" +checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" dependencies = [ "cfg-if", "js-sys", @@ -1103,9 +1086,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.79" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01" +checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1113,9 +1096,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.79" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc" +checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" dependencies = [ "proc-macro2", "quote", @@ -1126,15 +1109,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.79" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2" +checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" [[package]] name = "web-sys" -version = "0.3.56" +version = "0.3.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c060b319f29dd25724f09a2ba1418f142f539b2be99fbf4d2d5a8f7330afb8eb" +checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/Cargo.toml b/Cargo.toml index 0d6b13c..63dec11 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,13 +9,13 @@ edition = "2021" [dependencies] rand = "0.8.4" -reqwest = { version = "0.11.9", features = ["blocking"] } +reqwest = { version = "0.11.14", features = ["blocking"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.74" clap = { version = "4.1.4", features = ["derive"] } [dev-dependencies] -regex = "1.5.4" +regex = "1.7.1" [lib] name = "ambi_mock_client" From 188248d9ae312bee39d29012a884d33d4445b3ae Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Fri, 17 Feb 2023 03:20:20 +0100 Subject: [PATCH 10/36] Added a few TODOs --- src/requests.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/requests.rs b/src/requests.rs index 08c642d..ee08873 100644 --- a/src/requests.rs +++ b/src/requests.rs @@ -59,6 +59,7 @@ impl RequestSchedulerBuilder { (Some(time_per_request), Some(_)) => *time_per_request, }; + // TODO: Come up with a reasonable upper limit. let num_threads = self.num_threads.unwrap_or(DEFAULT_NUM_THREADS); RequestScheduler { @@ -78,6 +79,8 @@ pub(crate) struct RequestScheduler { /// -s 5: 1 req every 5 seconds. pub(crate) fn send_data(req_scheduler: RequestScheduler, json: String) { + // TODO: https://github.com/Jim-Hodapp-Coaching/ambi_mock_client/pull/8#pullrequestreview-932531277 + // TODO: Debug logging? let handles = (0..req_scheduler.num_threads) .map(|_| { let json_clone = json.clone(); From a17b4886ce0bb2c83694d24d4024ebf24f609754 Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Fri, 17 Feb 2023 14:58:56 +0100 Subject: [PATCH 11/36] Added more TODOs, max number of threads and some logs --- src/requests.rs | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/requests.rs b/src/requests.rs index ee08873..b85c22d 100644 --- a/src/requests.rs +++ b/src/requests.rs @@ -1,15 +1,16 @@ -#![allow(dead_code)] +// TODO: Remove this +#![allow(dead_code, unused_variables)] use std::{ + cmp::min, thread, time::{Duration, SystemTime}, }; -use reqwest::blocking::Client; - const DEFAULT_REQUEST_AMOUNT: u32 = 1; const DEFAULT_TIME_PER_REQUEST: Duration = Duration::from_secs(10); const DEFAULT_NUM_THREADS: u32 = 1; +const MAX_NUM_THREADS: u32 = 10; #[derive(Clone, Copy)] struct RequestSchedulerBuilder { @@ -59,8 +60,12 @@ impl RequestSchedulerBuilder { (Some(time_per_request), Some(_)) => *time_per_request, }; - // TODO: Come up with a reasonable upper limit. - let num_threads = self.num_threads.unwrap_or(DEFAULT_NUM_THREADS); + // Make sure that the number of threads is never above `MAX_NUM_THREADS`. + // TODO: If num_threads == 0: Invalid (make this return a Result) + let num_threads = match self.num_threads { + Some(num_threads) => min(num_threads, MAX_NUM_THREADS), + None => DEFAULT_NUM_THREADS, + }; RequestScheduler { request_amount, @@ -77,23 +82,23 @@ pub(crate) struct RequestScheduler { num_threads: u32, } -/// -s 5: 1 req every 5 seconds. -pub(crate) fn send_data(req_scheduler: RequestScheduler, json: String) { +pub(crate) fn send_data(req_scheduler: RequestScheduler, json: String, debug: bool) { // TODO: https://github.com/Jim-Hodapp-Coaching/ambi_mock_client/pull/8#pullrequestreview-932531277 // TODO: Debug logging? + // TODO: If num_threads == 1: don't spawn a separate thread let handles = (0..req_scheduler.num_threads) - .map(|_| { + .map(|thread_id| { let json_clone = json.clone(); - thread::spawn(move || send_data_internal(req_scheduler, json_clone)) + thread::spawn(move || send_data_internal(req_scheduler, json_clone, debug, thread_id)) }) .collect::>(); let _result: Vec<_> = handles.into_iter().map(|x| x.join()).collect(); } -fn send_data_internal(req_scheduler: RequestScheduler, json: String) { +fn send_data_internal(req_scheduler: RequestScheduler, json: String, debug: bool, thread_id: u32) { // TODO: Actually make the API calls. - let client = Client::new(); + // let client = Client::new(); let start = SystemTime::now(); for _ in 0..req_scheduler.request_amount { @@ -103,7 +108,10 @@ fn send_data_internal(req_scheduler: RequestScheduler, json: String) { // .body(json.clone()) // .send(); - println!("{:?}", SystemTime::elapsed(&start)); + // TODO: Discuss what should be logged (verbose or not) and whether we should use a logger. + // A logger would make the info/verbose level separation a bit cleaner. I've used + // in the past. + println!("[Thread {}]: {:?}", thread_id, SystemTime::elapsed(&start)); thread::sleep(req_scheduler.time_per_request) } @@ -126,6 +134,6 @@ mod tests { // .with_total_time(Duration::from_secs(1)) .build(); - send_data(req_scheduler, "{}".to_owned()); + send_data(req_scheduler, "{}".to_owned(), true); } } From 4b2bd4af5136cf3e9ae4db4c621144228db38ccc Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Fri, 17 Feb 2023 15:21:32 +0100 Subject: [PATCH 12/36] Thread number error handling --- Cargo.lock | 21 +++++++++++++++++++ Cargo.toml | 1 + src/error.rs | 11 ++++++++++ src/lib.rs | 1 + src/requests.rs | 54 ++++++++++++++++++++++++++++++++++++++++++------- 5 files changed, 81 insertions(+), 7 deletions(-) create mode 100644 src/error.rs diff --git a/Cargo.lock b/Cargo.lock index 7b7474a..dc0f7ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,6 +21,7 @@ dependencies = [ "reqwest", "serde", "serde_json", + "thiserror", ] [[package]] @@ -899,6 +900,26 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "thiserror" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tinyvec" version = "1.6.0" diff --git a/Cargo.toml b/Cargo.toml index 63dec11..e7a776f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ reqwest = { version = "0.11.14", features = ["blocking"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.74" clap = { version = "4.1.4", features = ["derive"] } +thiserror = "1.0.38" [dev-dependencies] regex = "1.7.1" diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..c6a248d --- /dev/null +++ b/src/error.rs @@ -0,0 +1,11 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum RequestSchedulerError { + #[error("Invalid value \"{value}\" for argument {argument_name}. {message}")] + InvalidArgument { + argument_name: String, + value: String, + message: String, + }, +} diff --git a/src/lib.rs b/src/lib.rs index c461478..a9b883d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,6 +10,7 @@ //! mod data; +mod error; mod requests; use crate::data::Reading; diff --git a/src/requests.rs b/src/requests.rs index b85c22d..ee5d91b 100644 --- a/src/requests.rs +++ b/src/requests.rs @@ -7,6 +7,8 @@ use std::{ time::{Duration, SystemTime}, }; +use crate::error::RequestSchedulerError; + const DEFAULT_REQUEST_AMOUNT: u32 = 1; const DEFAULT_TIME_PER_REQUEST: Duration = Duration::from_secs(10); const DEFAULT_NUM_THREADS: u32 = 1; @@ -50,7 +52,7 @@ impl RequestSchedulerBuilder { self } - fn build(self) -> RequestScheduler { + fn build(self) -> Result { let request_amount = self.request_amount.unwrap_or(DEFAULT_REQUEST_AMOUNT); let time_per_request = match (&self.time_per_request, &self.total_time) { @@ -60,18 +62,35 @@ impl RequestSchedulerBuilder { (Some(time_per_request), Some(_)) => *time_per_request, }; - // Make sure that the number of threads is never above `MAX_NUM_THREADS`. - // TODO: If num_threads == 0: Invalid (make this return a Result) let num_threads = match self.num_threads { - Some(num_threads) => min(num_threads, MAX_NUM_THREADS), + Some(num_threads) => num_threads, None => DEFAULT_NUM_THREADS, }; - RequestScheduler { + // Make sure that the number of threads is in [1, `MAX_NUM_THREADS`]. + match num_threads { + 0 => { + return Err(RequestSchedulerError::InvalidArgument { + argument_name: "num_threads".to_owned(), + value: "0".to_owned(), + message: "You must use at least 1 thread.".to_owned(), + }) + } + 1..=MAX_NUM_THREADS => (), + _ => { + return Err(RequestSchedulerError::InvalidArgument { + argument_name: "num_threads".to_owned(), + value: format!("{num_threads}"), + message: format!("You can't use more than {MAX_NUM_THREADS} threads."), + }) + } + } + + Ok(RequestScheduler { request_amount, time_per_request, num_threads, - } + }) } } @@ -121,7 +140,7 @@ fn send_data_internal(req_scheduler: RequestScheduler, json: String, debug: bool mod tests { use std::time::Duration; - use super::{send_data, RequestSchedulerBuilder}; + use super::{send_data, RequestSchedulerBuilder, MAX_NUM_THREADS}; // Used for manual testing, will be removed/edited later // cargo t -- send_data_test --nocapture @@ -134,6 +153,27 @@ mod tests { // .with_total_time(Duration::from_secs(1)) .build(); + assert!(req_scheduler.is_ok()); + let req_scheduler = req_scheduler.unwrap(); + send_data(req_scheduler, "{}".to_owned(), true); } + + #[test] + fn test_invalid_num_threads_low() { + let req_scheduler = RequestSchedulerBuilder::default() + .with_num_threads(0) + .build(); + + assert!(req_scheduler.is_err()) + } + + #[test] + fn test_invalid_num_threads_high() { + let req_scheduler = RequestSchedulerBuilder::default() + .with_num_threads(MAX_NUM_THREADS + 1) + .build(); + + assert!(req_scheduler.is_err()) + } } From 071d04ea3f71ba28b80d5f7fc674cbce6fd7466e Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Fri, 17 Feb 2023 15:21:58 +0100 Subject: [PATCH 13/36] Don't spawn threads unless needed --- src/requests.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/requests.rs b/src/requests.rs index ee5d91b..5571db2 100644 --- a/src/requests.rs +++ b/src/requests.rs @@ -104,7 +104,13 @@ pub(crate) struct RequestScheduler { pub(crate) fn send_data(req_scheduler: RequestScheduler, json: String, debug: bool) { // TODO: https://github.com/Jim-Hodapp-Coaching/ambi_mock_client/pull/8#pullrequestreview-932531277 // TODO: Debug logging? - // TODO: If num_threads == 1: don't spawn a separate thread + + // If 1 thread is specified, we can use the current thread. + if req_scheduler.num_threads == 1 { + send_data_internal(req_scheduler, json, debug, 0); + return; + } + let handles = (0..req_scheduler.num_threads) .map(|thread_id| { let json_clone = json.clone(); From f7af22487bf71291bcde890c8450b535ca18398e Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Fri, 17 Feb 2023 15:23:49 +0100 Subject: [PATCH 14/36] Remove outdated TODO --- src/requests.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/requests.rs b/src/requests.rs index 5571db2..7707eb9 100644 --- a/src/requests.rs +++ b/src/requests.rs @@ -102,7 +102,6 @@ pub(crate) struct RequestScheduler { } pub(crate) fn send_data(req_scheduler: RequestScheduler, json: String, debug: bool) { - // TODO: https://github.com/Jim-Hodapp-Coaching/ambi_mock_client/pull/8#pullrequestreview-932531277 // TODO: Debug logging? // If 1 thread is specified, we can use the current thread. From 093aac4d6f12ef0772cf8d37ff3503fcb9c094e2 Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Thu, 23 Feb 2023 16:55:11 +0100 Subject: [PATCH 15/36] Added logging --- Cargo.lock | 21 +++++++++++++++++++++ Cargo.toml | 2 ++ src/lib.rs | 38 ++++++++++++++++++-------------------- src/main.rs | 20 ++++++++++++++++---- src/requests.rs | 18 +++++++++++------- 5 files changed, 68 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dc0f7ca..02f881f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -16,6 +16,8 @@ name = "ambi_mock_client" version = "0.1.0" dependencies = [ "clap", + "env_logger", + "log", "rand", "regex", "reqwest", @@ -128,6 +130,19 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "env_logger" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + [[package]] name = "errno" version = "0.2.8" @@ -327,6 +342,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "hyper" version = "0.14.24" diff --git a/Cargo.toml b/Cargo.toml index e7a776f..a00a0cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,8 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.74" clap = { version = "4.1.4", features = ["derive"] } thiserror = "1.0.38" +log = "0.4.0" +env_logger = "0.10.0" [dev-dependencies] regex = "1.7.1" diff --git a/src/lib.rs b/src/lib.rs index a9b883d..f8a9086 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,6 +18,7 @@ use crate::data::{ random_gen_dust_concentration, random_gen_humidity, random_gen_pressure, random_gen_temperature, }; use clap::Parser; +use log::{debug, error, info}; use reqwest::blocking::Client; use reqwest::header::CONTENT_TYPE; @@ -42,7 +43,7 @@ pub struct Cli { } pub fn run(cli: &Cli) { - println!("\r\ncli: {:?}\r\n", cli); + debug!("cli: {cli:?}"); let dust_concentration = random_gen_dust_concentration(); let air_purity = AirPurity::from_value(dust_concentration).to_string(); @@ -56,7 +57,8 @@ pub fn run(cli: &Cli) { let json = serde_json::to_string(&reading).unwrap(); - println!("Sending POST request to {} as JSON: {}", URL, json); + info!("Sending POST request to {}", URL); + debug!("Request JSON: {}", json); let client = Client::new(); let res = client @@ -66,28 +68,24 @@ pub fn run(cli: &Cli) { .send(); match res { - Ok(response) => match cli.debug { - true => println!("Response from Ambi backend: {:#?}", response), - false => println!( + Ok(response) => { + info!( "Response from Ambi backend: {:?}", response.status().as_str() - ), - }, + ); + debug!("Response from Ambi backend: {:#?}", response); + } Err(e) => { - match cli.debug { - // Print out the entire reqwest::Error for verbose debugging - true => eprintln!("Response error from Ambi backend: {:?}", e), - // Keep the error reports more succinct - false => { - if e.is_request() { - eprintln!("Response error from Ambi backend: request error"); - } else if e.is_timeout() { - eprintln!("Response error from Ambi backend: request timed out"); - } else { - eprintln!("Response error from Ambi backend: specific error type unknown"); - } - } + if e.is_request() { + error!("Response error from Ambi backend: request error"); + } else if e.is_timeout() { + error!("Response error from Ambi backend: request timed out"); + } else { + error!("Response error from Ambi backend: specific error type unknown"); } + + debug!("{}", e.to_string()); + debug!("Response error from Ambi backend: {:?}", e); } } } diff --git a/src/main.rs b/src/main.rs index 35fe678..77f2ca3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,15 +11,27 @@ //! use clap::Parser; +use log::LevelFilter; fn main() { // Parses the provided command line interface arguments and flags let cli = ambi_mock_client::Cli::parse(); - match cli.debug { - true => println!("Debug mode is now *on*"), - false => println!("Debug mode is now *off*"), - } + init_logging(cli.debug); ambi_mock_client::run(&cli); } + +fn init_logging(is_debug: bool) { + let mut logger_builder = env_logger::Builder::new(); + + match is_debug { + true => logger_builder.filter_level(LevelFilter::Debug), + false => logger_builder.filter_level(LevelFilter::Info), + }; + + // The format_target is what makes the logs include `ambi_mock_client` everywhere. I left it + // here in case anyone wants to disable it in the future. It is enabled because not all logs + // originate from this crate (reqwest for instance makes a few as well). + logger_builder.format_target(true).init(); +} diff --git a/src/requests.rs b/src/requests.rs index 7707eb9..529dd9d 100644 --- a/src/requests.rs +++ b/src/requests.rs @@ -2,11 +2,12 @@ #![allow(dead_code, unused_variables)] use std::{ - cmp::min, thread, time::{Duration, SystemTime}, }; +use log::{debug, info}; + use crate::error::RequestSchedulerError; const DEFAULT_REQUEST_AMOUNT: u32 = 1; @@ -102,14 +103,16 @@ pub(crate) struct RequestScheduler { } pub(crate) fn send_data(req_scheduler: RequestScheduler, json: String, debug: bool) { - // TODO: Debug logging? - // If 1 thread is specified, we can use the current thread. if req_scheduler.num_threads == 1 { + debug!("num_threads is set to 1, use current thread."); + send_data_internal(req_scheduler, json, debug, 0); return; } + debug!("Spawning {} threads.", req_scheduler.num_threads); + let handles = (0..req_scheduler.num_threads) .map(|thread_id| { let json_clone = json.clone(); @@ -117,7 +120,11 @@ pub(crate) fn send_data(req_scheduler: RequestScheduler, json: String, debug: bo }) .collect::>(); + debug!("Threads spawned."); + let _result: Vec<_> = handles.into_iter().map(|x| x.join()).collect(); + + debug!("Threads joined."); } fn send_data_internal(req_scheduler: RequestScheduler, json: String, debug: bool, thread_id: u32) { @@ -132,10 +139,7 @@ fn send_data_internal(req_scheduler: RequestScheduler, json: String, debug: bool // .body(json.clone()) // .send(); - // TODO: Discuss what should be logged (verbose or not) and whether we should use a logger. - // A logger would make the info/verbose level separation a bit cleaner. I've used - // in the past. - println!("[Thread {}]: {:?}", thread_id, SystemTime::elapsed(&start)); + info!("[Thread {}]: {:?}", thread_id, SystemTime::elapsed(&start)); thread::sleep(req_scheduler.time_per_request) } From 88148b5fe42d4b70bc7678fca8eac5d279d007e9 Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Thu, 23 Feb 2023 18:05:57 +0100 Subject: [PATCH 16/36] Change default url to 8000 for now --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index f8a9086..d48a1e3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,7 +25,7 @@ use reqwest::header::CONTENT_TYPE; use crate::data::AirPurity; // TODO: Make the port configurable -const URL: &str = "http://localhost:4000/api/readings/add"; +const URL: &str = "http://localhost:8000/api/readings/add"; /// Defines the Ambi Mock Client command line interface as a struct #[derive(Parser, Debug)] From e6c04f5464062fec1ab6bc51508382fa24372eb1 Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Thu, 23 Feb 2023 18:06:09 +0100 Subject: [PATCH 17/36] Simplify log --- src/lib.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index d48a1e3..ccce334 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -69,10 +69,7 @@ pub fn run(cli: &Cli) { match res { Ok(response) => { - info!( - "Response from Ambi backend: {:?}", - response.status().as_str() - ); + info!("Response from Ambi backend: {}", response.status().as_str()); debug!("Response from Ambi backend: {:#?}", response); } Err(e) => { From 3e35f7cae995f7f30bb894c7b5a60b9d3c8eeea1 Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Sun, 26 Feb 2023 23:57:24 +0100 Subject: [PATCH 18/36] Add flags (WIP) --- src/lib.rs | 89 +++++++++++++++++++++++++++++---------------- src/main.rs | 2 +- src/requests.rs | 97 ++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 133 insertions(+), 55 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ccce334..7ad6ed1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,18 +13,21 @@ mod data; mod error; mod requests; -use crate::data::Reading; +use std::time::Duration; + use crate::data::{ random_gen_dust_concentration, random_gen_humidity, random_gen_pressure, random_gen_temperature, }; +use crate::{ + data::Reading, + requests::{send_data, RequestSchedulerBuilder}, +}; use clap::Parser; -use log::{debug, error, info}; -use reqwest::blocking::Client; -use reqwest::header::CONTENT_TYPE; +use error::RequestSchedulerError; +use log::debug; use crate::data::AirPurity; -// TODO: Make the port configurable const URL: &str = "http://localhost:8000/api/readings/add"; /// Defines the Ambi Mock Client command line interface as a struct @@ -38,13 +41,31 @@ const URL: &str = "http://localhost:8000/api/readings/add"; )] pub struct Cli { /// Turns verbose console debug output on - #[clap(short, long)] + #[arg(short, long)] pub debug: bool, + #[arg(short = 'n', long)] + pub request_amount: Option, + #[arg(short = 't', long = "time-per-request")] + pub time_per_request_s: Option, + #[arg(short = 'T', long = "total-time")] + pub total_time_s: Option, + #[arg(short = 'p', long)] + pub num_threads: Option, + #[arg(short = 'l', long, action)] + pub loop_indefinitely: bool, } -pub fn run(cli: &Cli) { +pub fn run(cli: &Cli) -> Result<(), RequestSchedulerError> { debug!("cli: {cli:?}"); + let req_scheduler = RequestSchedulerBuilder::default() + .with_some_request_amount(&cli.request_amount) + .with_some_time_per_request(&cli.time_per_request_s.map(Duration::from_secs)) + .with_some_total_time(&cli.total_time_s.map(Duration::from_secs)) + .with_some_num_threads(&cli.num_threads) + .with_loop_indefinitely(cli.loop_indefinitely) + .build()?; + let dust_concentration = random_gen_dust_concentration(); let air_purity = AirPurity::from_value(dust_concentration).to_string(); let reading = Reading::new( @@ -57,32 +78,36 @@ pub fn run(cli: &Cli) { let json = serde_json::to_string(&reading).unwrap(); - info!("Sending POST request to {}", URL); - debug!("Request JSON: {}", json); + send_data(req_scheduler, json, cli.debug); + + Ok(()) - let client = Client::new(); - let res = client - .post(URL) - .header(CONTENT_TYPE, "application/json") - .body(json) - .send(); + // info!("Sending POST request to {}", URL); + // debug!("Request JSON: {}", json); + // + // let client = Client::new(); + // let res = client + // .post(URL) + // .header(CONTENT_TYPE, "application/json") + // .body(json) + // .send(); - match res { - Ok(response) => { - info!("Response from Ambi backend: {}", response.status().as_str()); - debug!("Response from Ambi backend: {:#?}", response); - } - Err(e) => { - if e.is_request() { - error!("Response error from Ambi backend: request error"); - } else if e.is_timeout() { - error!("Response error from Ambi backend: request timed out"); - } else { - error!("Response error from Ambi backend: specific error type unknown"); - } + // match res { + // Ok(response) => { + // info!("Response from Ambi backend: {}", response.status().as_str()); + // debug!("Response from Ambi backend: {:#?}", response); + // } + // Err(e) => { + // if e.is_request() { + // error!("Response error from Ambi backend: request error"); + // } else if e.is_timeout() { + // error!("Response error from Ambi backend: request timed out"); + // } else { + // error!("Response error from Ambi backend: specific error type unknown"); + // } - debug!("{}", e.to_string()); - debug!("Response error from Ambi backend: {:?}", e); - } - } + // debug!("{}", e.to_string()); + // debug!("Response error from Ambi backend: {:?}", e); + // } + // } } diff --git a/src/main.rs b/src/main.rs index 77f2ca3..721d658 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,7 +19,7 @@ fn main() { init_logging(cli.debug); - ambi_mock_client::run(&cli); + let _ = ambi_mock_client::run(&cli); } fn init_logging(is_debug: bool) { diff --git a/src/requests.rs b/src/requests.rs index 529dd9d..3ec9ba1 100644 --- a/src/requests.rs +++ b/src/requests.rs @@ -7,8 +7,9 @@ use std::{ }; use log::{debug, info}; +use reqwest::{blocking::Client, header::CONTENT_TYPE}; -use crate::error::RequestSchedulerError; +use crate::{error::RequestSchedulerError, URL}; const DEFAULT_REQUEST_AMOUNT: u32 = 1; const DEFAULT_TIME_PER_REQUEST: Duration = Duration::from_secs(10); @@ -16,44 +17,79 @@ const DEFAULT_NUM_THREADS: u32 = 1; const MAX_NUM_THREADS: u32 = 10; #[derive(Clone, Copy)] -struct RequestSchedulerBuilder { +pub struct RequestSchedulerBuilder { request_amount: Option, time_per_request: Option, total_time: Option, num_threads: Option, + loop_indefinitely: Option, } impl RequestSchedulerBuilder { - fn default() -> Self { + pub fn default() -> Self { RequestSchedulerBuilder { request_amount: None, time_per_request: None, total_time: None, num_threads: None, + loop_indefinitely: None, } } - fn with_request_amount(&mut self, request_amount: u32) -> &mut Self { + pub fn with_request_amount(&mut self, request_amount: u32) -> &mut Self { self.request_amount = Some(request_amount); self } - fn with_time_per_request(&mut self, time_per_request: Duration) -> &mut Self { - self.time_per_request = Some(time_per_request); + pub fn with_some_request_amount(&mut self, request_amount: &Option) -> &mut Self { + self.request_amount = *request_amount; self } - fn with_total_time(&mut self, total_time: Duration) -> &mut Self { - self.total_time = Some(total_time); + pub fn with_time_per_request(&mut self, time_per_request: &Duration) -> &mut Self { + self.time_per_request = Some(*time_per_request); self } - fn with_num_threads(&mut self, num_threads: u32) -> &mut Self { + pub fn with_some_time_per_request(&mut self, time_per_request: &Option) -> &mut Self { + self.time_per_request = *time_per_request; + self + } + + pub fn with_total_time(&mut self, total_time: &Duration) -> &mut Self { + self.total_time = Some(*total_time); + self + } + + pub fn with_some_total_time(&mut self, total_time: &Option) -> &mut Self { + self.total_time = *total_time; + self + } + + pub fn with_num_threads(&mut self, num_threads: u32) -> &mut Self { self.num_threads = Some(num_threads); self } - fn build(self) -> Result { + pub fn with_some_num_threads(&mut self, num_threads: &Option) -> &mut Self { + self.num_threads = *num_threads; + self + } + + pub fn with_loop_indefinitely(&mut self, loop_indefinitely: bool) -> &mut Self { + self.loop_indefinitely = Some(loop_indefinitely); + self + } + + pub fn with_some_loop_indefinitely(&mut self, loop_indefinitely: &Option) -> &mut Self { + self.loop_indefinitely = *loop_indefinitely; + self + } + + pub fn build(self) -> Result { + // Determine to loop indefinitely + let loop_indefinitely = self.loop_indefinitely.unwrap_or(false); + let request_amount = self.request_amount.unwrap_or(DEFAULT_REQUEST_AMOUNT); let time_per_request = match (&self.time_per_request, &self.total_time) { @@ -91,18 +127,20 @@ impl RequestSchedulerBuilder { request_amount, time_per_request, num_threads, + loop_indefinitely, }) } } #[derive(Clone, Copy)] -pub(crate) struct RequestScheduler { +pub struct RequestScheduler { request_amount: u32, time_per_request: Duration, num_threads: u32, + loop_indefinitely: bool, } -pub(crate) fn send_data(req_scheduler: RequestScheduler, json: String, debug: bool) { +pub fn send_data(req_scheduler: RequestScheduler, json: String, debug: bool) { // If 1 thread is specified, we can use the current thread. if req_scheduler.num_threads == 1 { debug!("num_threads is set to 1, use current thread."); @@ -128,23 +166,38 @@ pub(crate) fn send_data(req_scheduler: RequestScheduler, json: String, debug: bo } fn send_data_internal(req_scheduler: RequestScheduler, json: String, debug: bool, thread_id: u32) { - // TODO: Actually make the API calls. - // let client = Client::new(); let start = SystemTime::now(); - for _ in 0..req_scheduler.request_amount { - // let res = client - // .post(URL) - // .header(CONTENT_TYPE, "application/json") - // .body(json.clone()) - // .send(); + if req_scheduler.loop_indefinitely { + loop { + info!("[Thread {}]: {:?}", thread_id, SystemTime::elapsed(&start)); + // make_request(json.clone(), debug, thread_id); + thread::sleep(req_scheduler.time_per_request) + } + } + for i in 0..req_scheduler.request_amount { info!("[Thread {}]: {:?}", thread_id, SystemTime::elapsed(&start)); + // make_request(json.clone(), debug, thread_id); - thread::sleep(req_scheduler.time_per_request) + // Only use thread.sleep if we are not on the last request + if i != req_scheduler.request_amount - 1 { + thread::sleep(req_scheduler.time_per_request) + } } } +// TODO: Currently unused for debugging. +fn make_request(json: String, debug: bool, thread_id: u32) { + let client = Client::new(); + + let res = client + .post(URL) + .header(CONTENT_TYPE, "application/json") + .body(json) + .send(); +} + #[cfg(test)] mod tests { use std::time::Duration; @@ -158,7 +211,7 @@ mod tests { let req_scheduler = RequestSchedulerBuilder::default() .with_num_threads(2) .with_request_amount(5) - .with_time_per_request(Duration::from_secs(1)) + .with_time_per_request(&Duration::from_secs(1)) // .with_total_time(Duration::from_secs(1)) .build(); From 36a3f48267604266f3f3b08e638b75d4c926e811 Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Sun, 26 Feb 2023 23:58:19 +0100 Subject: [PATCH 19/36] Added TODO --- src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib.rs b/src/lib.rs index 7ad6ed1..0bc462b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -82,6 +82,7 @@ pub fn run(cli: &Cli) -> Result<(), RequestSchedulerError> { Ok(()) + // TODO: Move these logs to the requests file // info!("Sending POST request to {}", URL); // debug!("Request JSON: {}", json); // From 5133de9c1b3ce7afa5b824b4a33bb0e639ba1dc8 Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Mon, 27 Feb 2023 00:14:11 +0100 Subject: [PATCH 20/36] Cleanup builder --- src/requests.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/requests.rs b/src/requests.rs index 3ec9ba1..f7a86e4 100644 --- a/src/requests.rs +++ b/src/requests.rs @@ -36,52 +36,52 @@ impl RequestSchedulerBuilder { } } - pub fn with_request_amount(&mut self, request_amount: u32) -> &mut Self { + pub fn with_request_amount(mut self, request_amount: u32) -> Self { self.request_amount = Some(request_amount); self } - pub fn with_some_request_amount(&mut self, request_amount: &Option) -> &mut Self { + pub fn with_some_request_amount(mut self, request_amount: &Option) -> Self { self.request_amount = *request_amount; self } - pub fn with_time_per_request(&mut self, time_per_request: &Duration) -> &mut Self { + pub fn with_time_per_request(mut self, time_per_request: &Duration) -> Self { self.time_per_request = Some(*time_per_request); self } - pub fn with_some_time_per_request(&mut self, time_per_request: &Option) -> &mut Self { + pub fn with_some_time_per_request(mut self, time_per_request: &Option) -> Self { self.time_per_request = *time_per_request; self } - pub fn with_total_time(&mut self, total_time: &Duration) -> &mut Self { + pub fn with_total_time(mut self, total_time: &Duration) -> Self { self.total_time = Some(*total_time); self } - pub fn with_some_total_time(&mut self, total_time: &Option) -> &mut Self { + pub fn with_some_total_time(mut self, total_time: &Option) -> Self { self.total_time = *total_time; self } - pub fn with_num_threads(&mut self, num_threads: u32) -> &mut Self { + pub fn with_num_threads(mut self, num_threads: u32) -> Self { self.num_threads = Some(num_threads); self } - pub fn with_some_num_threads(&mut self, num_threads: &Option) -> &mut Self { + pub fn with_some_num_threads(mut self, num_threads: &Option) -> Self { self.num_threads = *num_threads; self } - pub fn with_loop_indefinitely(&mut self, loop_indefinitely: bool) -> &mut Self { + pub fn with_loop_indefinitely(mut self, loop_indefinitely: bool) -> Self { self.loop_indefinitely = Some(loop_indefinitely); self } - pub fn with_some_loop_indefinitely(&mut self, loop_indefinitely: &Option) -> &mut Self { + pub fn with_some_loop_indefinitely(mut self, loop_indefinitely: &Option) -> Self { self.loop_indefinitely = *loop_indefinitely; self } From 9e0bf59feb873fc1833f43b31ff80577efa591e1 Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Tue, 28 Feb 2023 21:29:56 +0100 Subject: [PATCH 21/36] Add clap's debug assert test --- src/lib.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 0bc462b..b8858dc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -112,3 +112,15 @@ pub fn run(cli: &Cli) -> Result<(), RequestSchedulerError> { // } // } } + +#[cfg(test)] +mod tests { + use clap::CommandFactory; + + use crate::Cli; + + #[test] + fn verify_cli() { + Cli::command().debug_assert(); + } +} From 1e08e6a89eb595eca06601185ad40ff17c0199f7 Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Tue, 28 Feb 2023 21:30:53 +0100 Subject: [PATCH 22/36] Only use 1 http client per thread --- src/requests.rs | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/src/requests.rs b/src/requests.rs index f7a86e4..44e07a1 100644 --- a/src/requests.rs +++ b/src/requests.rs @@ -145,7 +145,7 @@ pub fn send_data(req_scheduler: RequestScheduler, json: String, debug: bool) { if req_scheduler.num_threads == 1 { debug!("num_threads is set to 1, use current thread."); - send_data_internal(req_scheduler, json, debug, 0); + send_data_internal(req_scheduler, json, debug, 0, Client::new()); return; } @@ -154,7 +154,7 @@ pub fn send_data(req_scheduler: RequestScheduler, json: String, debug: bool) { let handles = (0..req_scheduler.num_threads) .map(|thread_id| { let json_clone = json.clone(); - thread::spawn(move || send_data_internal(req_scheduler, json_clone, debug, thread_id)) + thread::spawn(move || send_data_internal(req_scheduler, json_clone, debug, thread_id, Client::new())) }) .collect::>(); @@ -165,7 +165,7 @@ pub fn send_data(req_scheduler: RequestScheduler, json: String, debug: bool) { debug!("Threads joined."); } -fn send_data_internal(req_scheduler: RequestScheduler, json: String, debug: bool, thread_id: u32) { +fn send_data_internal(req_scheduler: RequestScheduler, json: String, debug: bool, thread_id: u32, client: Client) { let start = SystemTime::now(); if req_scheduler.loop_indefinitely { @@ -188,9 +188,7 @@ fn send_data_internal(req_scheduler: RequestScheduler, json: String, debug: bool } // TODO: Currently unused for debugging. -fn make_request(json: String, debug: bool, thread_id: u32) { - let client = Client::new(); - +fn make_request(json: String, debug: bool, thread_id: u32, client: Client) { let res = client .post(URL) .header(CONTENT_TYPE, "application/json") @@ -200,26 +198,9 @@ fn make_request(json: String, debug: bool, thread_id: u32) { #[cfg(test)] mod tests { - use std::time::Duration; - - use super::{send_data, RequestSchedulerBuilder, MAX_NUM_THREADS}; - - // Used for manual testing, will be removed/edited later - // cargo t -- send_data_test --nocapture - #[test] - fn send_data_test() { - let req_scheduler = RequestSchedulerBuilder::default() - .with_num_threads(2) - .with_request_amount(5) - .with_time_per_request(&Duration::from_secs(1)) - // .with_total_time(Duration::from_secs(1)) - .build(); + use super::{RequestSchedulerBuilder, MAX_NUM_THREADS}; - assert!(req_scheduler.is_ok()); - let req_scheduler = req_scheduler.unwrap(); - - send_data(req_scheduler, "{}".to_owned(), true); - } + // TODO: Add some tests for the parameter logic. #[test] fn test_invalid_num_threads_low() { From 34f9631a1df3af051e4941756cb42033d2c84739 Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Tue, 28 Feb 2023 21:37:24 +0100 Subject: [PATCH 23/36] Take a reference to the client instead of ownership --- src/requests.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/requests.rs b/src/requests.rs index 44e07a1..c21d894 100644 --- a/src/requests.rs +++ b/src/requests.rs @@ -154,7 +154,9 @@ pub fn send_data(req_scheduler: RequestScheduler, json: String, debug: bool) { let handles = (0..req_scheduler.num_threads) .map(|thread_id| { let json_clone = json.clone(); - thread::spawn(move || send_data_internal(req_scheduler, json_clone, debug, thread_id, Client::new())) + thread::spawn(move || { + send_data_internal(req_scheduler, json_clone, debug, thread_id, Client::new()) + }) }) .collect::>(); @@ -165,20 +167,26 @@ pub fn send_data(req_scheduler: RequestScheduler, json: String, debug: bool) { debug!("Threads joined."); } -fn send_data_internal(req_scheduler: RequestScheduler, json: String, debug: bool, thread_id: u32, client: Client) { +fn send_data_internal( + req_scheduler: RequestScheduler, + json: String, + debug: bool, + thread_id: u32, + client: Client, +) { let start = SystemTime::now(); if req_scheduler.loop_indefinitely { loop { info!("[Thread {}]: {:?}", thread_id, SystemTime::elapsed(&start)); - // make_request(json.clone(), debug, thread_id); + // make_request(json.clone(), debug, thread_id, &client); thread::sleep(req_scheduler.time_per_request) } } for i in 0..req_scheduler.request_amount { info!("[Thread {}]: {:?}", thread_id, SystemTime::elapsed(&start)); - // make_request(json.clone(), debug, thread_id); + // make_request(json.clone(), debug, thread_id, &client); // Only use thread.sleep if we are not on the last request if i != req_scheduler.request_amount - 1 { @@ -188,7 +196,7 @@ fn send_data_internal(req_scheduler: RequestScheduler, json: String, debug: bool } // TODO: Currently unused for debugging. -fn make_request(json: String, debug: bool, thread_id: u32, client: Client) { +fn make_request(json: String, debug: bool, thread_id: u32, client: &Client) { let res = client .post(URL) .header(CONTENT_TYPE, "application/json") From fd317350d8dd254a51a90c610da252b6849b5976 Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Wed, 1 Mar 2023 17:06:11 +0100 Subject: [PATCH 24/36] Remove loop param --- src/lib.rs | 3 --- src/requests.rs | 16 ++-------------- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b8858dc..aabe17b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -51,8 +51,6 @@ pub struct Cli { pub total_time_s: Option, #[arg(short = 'p', long)] pub num_threads: Option, - #[arg(short = 'l', long, action)] - pub loop_indefinitely: bool, } pub fn run(cli: &Cli) -> Result<(), RequestSchedulerError> { @@ -63,7 +61,6 @@ pub fn run(cli: &Cli) -> Result<(), RequestSchedulerError> { .with_some_time_per_request(&cli.time_per_request_s.map(Duration::from_secs)) .with_some_total_time(&cli.total_time_s.map(Duration::from_secs)) .with_some_num_threads(&cli.num_threads) - .with_loop_indefinitely(cli.loop_indefinitely) .build()?; let dust_concentration = random_gen_dust_concentration(); diff --git a/src/requests.rs b/src/requests.rs index c21d894..96e0aee 100644 --- a/src/requests.rs +++ b/src/requests.rs @@ -22,7 +22,6 @@ pub struct RequestSchedulerBuilder { time_per_request: Option, total_time: Option, num_threads: Option, - loop_indefinitely: Option, } impl RequestSchedulerBuilder { @@ -32,7 +31,6 @@ impl RequestSchedulerBuilder { time_per_request: None, total_time: None, num_threads: None, - loop_indefinitely: None, } } @@ -76,19 +74,9 @@ impl RequestSchedulerBuilder { self } - pub fn with_loop_indefinitely(mut self, loop_indefinitely: bool) -> Self { - self.loop_indefinitely = Some(loop_indefinitely); - self - } - - pub fn with_some_loop_indefinitely(mut self, loop_indefinitely: &Option) -> Self { - self.loop_indefinitely = *loop_indefinitely; - self - } - pub fn build(self) -> Result { - // Determine to loop indefinitely - let loop_indefinitely = self.loop_indefinitely.unwrap_or(false); + // Loop indefinitely if no req amt is set. If time per req is also not set then don't loop. + let loop_indefinitely = self.request_amount.is_none() && self.time_per_request.is_some(); let request_amount = self.request_amount.unwrap_or(DEFAULT_REQUEST_AMOUNT); From d8f37dabe1757b31afefd206625d30f6e6e6668c Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Wed, 1 Mar 2023 17:34:59 +0100 Subject: [PATCH 25/36] Cleanup --- src/lib.rs | 57 ++-------------------- src/requests.rs | 122 +++++++++++++++++++++++++++--------------------- 2 files changed, 73 insertions(+), 106 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index aabe17b..1e95fca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,20 +13,11 @@ mod data; mod error; mod requests; -use std::time::Duration; - -use crate::data::{ - random_gen_dust_concentration, random_gen_humidity, random_gen_pressure, random_gen_temperature, -}; -use crate::{ - data::Reading, - requests::{send_data, RequestSchedulerBuilder}, -}; +use crate::requests::{send_data, RequestSchedulerBuilder}; use clap::Parser; use error::RequestSchedulerError; use log::debug; - -use crate::data::AirPurity; +use std::time::Duration; const URL: &str = "http://localhost:8000/api/readings/add"; @@ -63,51 +54,9 @@ pub fn run(cli: &Cli) -> Result<(), RequestSchedulerError> { .with_some_num_threads(&cli.num_threads) .build()?; - let dust_concentration = random_gen_dust_concentration(); - let air_purity = AirPurity::from_value(dust_concentration).to_string(); - let reading = Reading::new( - random_gen_temperature(), - random_gen_humidity(), - random_gen_pressure(), - dust_concentration, - air_purity, - ); - - let json = serde_json::to_string(&reading).unwrap(); - - send_data(req_scheduler, json, cli.debug); + send_data(req_scheduler); Ok(()) - - // TODO: Move these logs to the requests file - // info!("Sending POST request to {}", URL); - // debug!("Request JSON: {}", json); - // - // let client = Client::new(); - // let res = client - // .post(URL) - // .header(CONTENT_TYPE, "application/json") - // .body(json) - // .send(); - - // match res { - // Ok(response) => { - // info!("Response from Ambi backend: {}", response.status().as_str()); - // debug!("Response from Ambi backend: {:#?}", response); - // } - // Err(e) => { - // if e.is_request() { - // error!("Response error from Ambi backend: request error"); - // } else if e.is_timeout() { - // error!("Response error from Ambi backend: request timed out"); - // } else { - // error!("Response error from Ambi backend: specific error type unknown"); - // } - - // debug!("{}", e.to_string()); - // debug!("Response error from Ambi backend: {:?}", e); - // } - // } } #[cfg(test)] diff --git a/src/requests.rs b/src/requests.rs index 96e0aee..8c293e1 100644 --- a/src/requests.rs +++ b/src/requests.rs @@ -1,15 +1,16 @@ -// TODO: Remove this -#![allow(dead_code, unused_variables)] +use std::{thread, time::Duration}; -use std::{ - thread, - time::{Duration, SystemTime}, -}; - -use log::{debug, info}; +use log::{debug, error, info}; use reqwest::{blocking::Client, header::CONTENT_TYPE}; -use crate::{error::RequestSchedulerError, URL}; +use crate::{ + data::{ + random_gen_dust_concentration, random_gen_humidity, random_gen_pressure, + random_gen_temperature, AirPurity, Reading, + }, + error::RequestSchedulerError, + URL, +}; const DEFAULT_REQUEST_AMOUNT: u32 = 1; const DEFAULT_TIME_PER_REQUEST: Duration = Duration::from_secs(10); @@ -34,41 +35,21 @@ impl RequestSchedulerBuilder { } } - pub fn with_request_amount(mut self, request_amount: u32) -> Self { - self.request_amount = Some(request_amount); - self - } - pub fn with_some_request_amount(mut self, request_amount: &Option) -> Self { self.request_amount = *request_amount; self } - pub fn with_time_per_request(mut self, time_per_request: &Duration) -> Self { - self.time_per_request = Some(*time_per_request); - self - } - pub fn with_some_time_per_request(mut self, time_per_request: &Option) -> Self { self.time_per_request = *time_per_request; self } - pub fn with_total_time(mut self, total_time: &Duration) -> Self { - self.total_time = Some(*total_time); - self - } - pub fn with_some_total_time(mut self, total_time: &Option) -> Self { self.total_time = *total_time; self } - pub fn with_num_threads(mut self, num_threads: u32) -> Self { - self.num_threads = Some(num_threads); - self - } - pub fn with_some_num_threads(mut self, num_threads: &Option) -> Self { self.num_threads = *num_threads; self @@ -128,12 +109,12 @@ pub struct RequestScheduler { loop_indefinitely: bool, } -pub fn send_data(req_scheduler: RequestScheduler, json: String, debug: bool) { +pub fn send_data(req_scheduler: RequestScheduler) { // If 1 thread is specified, we can use the current thread. if req_scheduler.num_threads == 1 { debug!("num_threads is set to 1, use current thread."); - send_data_internal(req_scheduler, json, debug, 0, Client::new()); + send_data_internal(req_scheduler, 0, Client::new()); return; } @@ -141,10 +122,7 @@ pub fn send_data(req_scheduler: RequestScheduler, json: String, debug: bool) { let handles = (0..req_scheduler.num_threads) .map(|thread_id| { - let json_clone = json.clone(); - thread::spawn(move || { - send_data_internal(req_scheduler, json_clone, debug, thread_id, Client::new()) - }) + thread::spawn(move || send_data_internal(req_scheduler, thread_id, Client::new())) }) .collect::>(); @@ -155,26 +133,20 @@ pub fn send_data(req_scheduler: RequestScheduler, json: String, debug: bool) { debug!("Threads joined."); } -fn send_data_internal( - req_scheduler: RequestScheduler, - json: String, - debug: bool, - thread_id: u32, - client: Client, -) { - let start = SystemTime::now(); - +/// This code might run on separate threads, any logs should be prefixed by the thread id +/// for easier debugging. +/// +/// You can log the thread id by prepending `[Thread {thread_id}]: ` to your logs. +fn send_data_internal(req_scheduler: RequestScheduler, thread_id: u32, client: Client) { if req_scheduler.loop_indefinitely { loop { - info!("[Thread {}]: {:?}", thread_id, SystemTime::elapsed(&start)); - // make_request(json.clone(), debug, thread_id, &client); + make_request(thread_id, &client); thread::sleep(req_scheduler.time_per_request) } } for i in 0..req_scheduler.request_amount { - info!("[Thread {}]: {:?}", thread_id, SystemTime::elapsed(&start)); - // make_request(json.clone(), debug, thread_id, &client); + make_request(thread_id, &client); // Only use thread.sleep if we are not on the last request if i != req_scheduler.request_amount - 1 { @@ -183,13 +155,59 @@ fn send_data_internal( } } -// TODO: Currently unused for debugging. -fn make_request(json: String, debug: bool, thread_id: u32, client: &Client) { +/// This also can run in parallel, refer to [`send_data_internal`]. +fn make_request(thread_id: u32, client: &Client) { + let json = generate_random_reading(); + info!("[Thread {thread_id}]: Sending POST request to {}", URL); + debug!("[Thread {thread_id}]: Request JSON: {}", json); + let res = client .post(URL) .header(CONTENT_TYPE, "application/json") .body(json) .send(); + + match res { + Ok(response) => { + info!( + "[Thread {thread_id}]: Response from Ambi backend: {}", + response.status().as_str() + ); + debug!( + "[Thread {thread_id}]: Response from Ambi backend: {:#?}", + response + ); + } + Err(e) => { + if e.is_request() { + error!("[Thread {thread_id}]: Response error from Ambi backend: request error"); + } else if e.is_timeout() { + error!("[Thread {thread_id}]: Response error from Ambi backend: request timed out"); + } else { + error!("[Thread {thread_id}]: Response error from Ambi backend: specific error type unknown"); + } + + debug!("[Thread {thread_id}]: {}", e.to_string()); + debug!( + "[Thread {thread_id}]: Response error from Ambi backend: {:?}", + e + ); + } + } +} + +fn generate_random_reading() -> String { + let dust_concentration = random_gen_dust_concentration(); + let air_purity = AirPurity::from_value(dust_concentration).to_string(); + let reading = Reading::new( + random_gen_temperature(), + random_gen_humidity(), + random_gen_pressure(), + dust_concentration, + air_purity, + ); + + serde_json::to_string(&reading).unwrap() } #[cfg(test)] @@ -201,7 +219,7 @@ mod tests { #[test] fn test_invalid_num_threads_low() { let req_scheduler = RequestSchedulerBuilder::default() - .with_num_threads(0) + .with_some_num_threads(&Some(0)) .build(); assert!(req_scheduler.is_err()) @@ -210,7 +228,7 @@ mod tests { #[test] fn test_invalid_num_threads_high() { let req_scheduler = RequestSchedulerBuilder::default() - .with_num_threads(MAX_NUM_THREADS + 1) + .with_some_num_threads(&Some(MAX_NUM_THREADS + 1)) .build(); assert!(req_scheduler.is_err()) From 95f283b4374f06b934676c6d90b11c81b4c2d3d8 Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Wed, 1 Mar 2023 17:41:15 +0100 Subject: [PATCH 26/36] Added flag docs --- src/lib.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 1e95fca..f8ec077 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,12 +34,19 @@ pub struct Cli { /// Turns verbose console debug output on #[arg(short, long)] pub debug: bool, + /// The amount of requests to make + /// [DEFAULT: 1] #[arg(short = 'n', long)] pub request_amount: Option, + /// The time between each request (in seconds) + /// [DEFAULT: 10] #[arg(short = 't', long = "time-per-request")] pub time_per_request_s: Option, + /// The total time over which all the requests must be sent (in seconds, alternative to -t) #[arg(short = 'T', long = "total-time")] pub total_time_s: Option, + /// The number of threads to spawn. The workload will be cloned to each thread, not divided + /// [DEFAULT: 1] #[arg(short = 'p', long)] pub num_threads: Option, } From d1e1f1a1437c6324e83b6eb02915f8e9991f3b48 Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Wed, 1 Mar 2023 18:09:09 +0100 Subject: [PATCH 27/36] Print errors. --- src/lib.rs | 2 +- src/main.rs | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index f8ec077..3e608ae 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,7 +10,7 @@ //! mod data; -mod error; +pub mod error; mod requests; use crate::requests::{send_data, RequestSchedulerBuilder}; diff --git a/src/main.rs b/src/main.rs index 721d658..f0105c4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,16 +10,17 @@ //! See the `LICENSE` file for Copyright and license details. //! +use ambi_mock_client::error::RequestSchedulerError; use clap::Parser; use log::LevelFilter; -fn main() { +fn main() -> Result<(), RequestSchedulerError> { // Parses the provided command line interface arguments and flags let cli = ambi_mock_client::Cli::parse(); init_logging(cli.debug); - let _ = ambi_mock_client::run(&cli); + ambi_mock_client::run(&cli) } fn init_logging(is_debug: bool) { From 450b7db6da99ad180b087a9e7af83c4cc9f1e2b7 Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Sat, 4 Mar 2023 21:23:02 +0100 Subject: [PATCH 28/36] Resolve PR comments --- src/data.rs | 18 ++++++-------- src/lib.rs | 17 ++++++++++++- src/requests.rs | 65 ++++++++++++++++++++++--------------------------- 3 files changed, 52 insertions(+), 48 deletions(-) diff --git a/src/data.rs b/src/data.rs index 40cc883..2c20f26 100644 --- a/src/data.rs +++ b/src/data.rs @@ -1,6 +1,6 @@ use core::fmt; -use rand::{thread_rng, Rng}; +use rand::{rngs::ThreadRng, Rng}; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] @@ -41,7 +41,7 @@ pub(crate) enum AirPurity { impl AirPurity { pub(crate) fn from_value(value: f64) -> AirPurity { match value { - value if (f64::MIN..=50.0).contains(&value) => AirPurity::FreshAir, + value if value < 50.0 => AirPurity::FreshAir, value if value > 50.0 && value <= 100.0 => AirPurity::Low, value if value > 100.0 && value <= 150.0 => AirPurity::High, _ => AirPurity::Dangerous, @@ -62,27 +62,23 @@ impl fmt::Display for AirPurity { } } -pub(crate) fn random_gen_humidity() -> f64 { - let mut rng = thread_rng(); +pub(crate) fn random_gen_humidity(rng: &mut ThreadRng) -> f64 { let value = rng.gen_range(0.0..=100.0); // Limit to 2 decimals f64::trunc(value * 100.0) / 100.0 } -pub(crate) fn random_gen_temperature() -> f64 { - let mut rng = thread_rng(); +pub(crate) fn random_gen_temperature(rng: &mut ThreadRng) -> f64 { let value = rng.gen_range(15.0..=35.0); // Limit to 2 decimals f64::trunc(value * 100.0) / 100.0 } -pub(crate) fn random_gen_pressure() -> i32 { - let mut rng = thread_rng(); +pub(crate) fn random_gen_pressure(rng: &mut ThreadRng) -> i32 { rng.gen_range(900..=1100) } -pub(crate) fn random_gen_dust_concentration() -> f64 { - let mut rng = thread_rng(); +pub(crate) fn random_gen_dust_concentration(rng: &mut ThreadRng) -> f64 { let value = rng.gen_range(0.0..=1000.0); f64::trunc(value * 100.0) / 100.0 } @@ -93,7 +89,7 @@ mod tests { #[test] fn air_purity_from_value_returns_correct_enum() { - let mut rng = thread_rng(); + let mut rng = rand::thread_rng(); let fresh_air = rng.gen_range(0.0..=50.0); let low = rng.gen_range(51.0..=100.0); let high = rng.gen_range(101.0..=150.0); diff --git a/src/lib.rs b/src/lib.rs index 3e608ae..1b37961 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,6 +17,7 @@ use crate::requests::{send_data, RequestSchedulerBuilder}; use clap::Parser; use error::RequestSchedulerError; use log::debug; +use requests::MAX_NUM_THREADS; use std::time::Duration; const URL: &str = "http://localhost:8000/api/readings/add"; @@ -47,10 +48,24 @@ pub struct Cli { pub total_time_s: Option, /// The number of threads to spawn. The workload will be cloned to each thread, not divided /// [DEFAULT: 1] - #[arg(short = 'p', long)] + #[arg(short = 'p', long, value_parser = is_valid_num_of_threads)] pub num_threads: Option, } +/// Ensures that the number of threads are in [1, `MAX_NUM_THREADS`]. +fn is_valid_num_of_threads(val: &str) -> Result { + match val.parse::() { + Ok(num_threads) => match num_threads { + 0 => Err("You must use at least 1 thread.".to_string()), + 1..=MAX_NUM_THREADS => Ok(num_threads), + _ => Err(format!( + "You can't use more than {MAX_NUM_THREADS} threads." + )), + }, + Err(_) => Err(String::from("value wasn't a number!")), + } +} + pub fn run(cli: &Cli) -> Result<(), RequestSchedulerError> { debug!("cli: {cli:?}"); diff --git a/src/requests.rs b/src/requests.rs index 8c293e1..c5e86f3 100644 --- a/src/requests.rs +++ b/src/requests.rs @@ -1,6 +1,7 @@ use std::{thread, time::Duration}; use log::{debug, error, info}; +use rand::rngs::ThreadRng; use reqwest::{blocking::Client, header::CONTENT_TYPE}; use crate::{ @@ -15,7 +16,7 @@ use crate::{ const DEFAULT_REQUEST_AMOUNT: u32 = 1; const DEFAULT_TIME_PER_REQUEST: Duration = Duration::from_secs(10); const DEFAULT_NUM_THREADS: u32 = 1; -const MAX_NUM_THREADS: u32 = 10; +pub const MAX_NUM_THREADS: u32 = 10; #[derive(Clone, Copy)] pub struct RequestSchedulerBuilder { @@ -68,29 +69,9 @@ impl RequestSchedulerBuilder { (Some(time_per_request), Some(_)) => *time_per_request, }; - let num_threads = match self.num_threads { - Some(num_threads) => num_threads, - None => DEFAULT_NUM_THREADS, - }; - - // Make sure that the number of threads is in [1, `MAX_NUM_THREADS`]. - match num_threads { - 0 => { - return Err(RequestSchedulerError::InvalidArgument { - argument_name: "num_threads".to_owned(), - value: "0".to_owned(), - message: "You must use at least 1 thread.".to_owned(), - }) - } - 1..=MAX_NUM_THREADS => (), - _ => { - return Err(RequestSchedulerError::InvalidArgument { - argument_name: "num_threads".to_owned(), - value: format!("{num_threads}"), - message: format!("You can't use more than {MAX_NUM_THREADS} threads."), - }) - } - } + let num_threads = self.num_threads.unwrap_or(DEFAULT_NUM_THREADS); + // At this point we know that the number of threads is in [1, `MAX_NUM_THREADS`]. + // Validation is done in `lib::is_valid_num_of_threads`. Ok(RequestScheduler { request_amount, @@ -114,7 +95,7 @@ pub fn send_data(req_scheduler: RequestScheduler) { if req_scheduler.num_threads == 1 { debug!("num_threads is set to 1, use current thread."); - send_data_internal(req_scheduler, 0, Client::new()); + send_data_internal(req_scheduler, 0, Client::new(), &mut rand::thread_rng()); return; } @@ -122,7 +103,14 @@ pub fn send_data(req_scheduler: RequestScheduler) { let handles = (0..req_scheduler.num_threads) .map(|thread_id| { - thread::spawn(move || send_data_internal(req_scheduler, thread_id, Client::new())) + thread::spawn(move || { + send_data_internal( + req_scheduler, + thread_id, + Client::new(), + &mut rand::thread_rng(), + ) + }) }) .collect::>(); @@ -137,16 +125,21 @@ pub fn send_data(req_scheduler: RequestScheduler) { /// for easier debugging. /// /// You can log the thread id by prepending `[Thread {thread_id}]: ` to your logs. -fn send_data_internal(req_scheduler: RequestScheduler, thread_id: u32, client: Client) { +fn send_data_internal( + req_scheduler: RequestScheduler, + thread_id: u32, + client: Client, + rng: &mut ThreadRng, +) { if req_scheduler.loop_indefinitely { loop { - make_request(thread_id, &client); + make_request(thread_id, &client, rng); thread::sleep(req_scheduler.time_per_request) } } for i in 0..req_scheduler.request_amount { - make_request(thread_id, &client); + make_request(thread_id, &client, rng); // Only use thread.sleep if we are not on the last request if i != req_scheduler.request_amount - 1 { @@ -156,8 +149,8 @@ fn send_data_internal(req_scheduler: RequestScheduler, thread_id: u32, client: C } /// This also can run in parallel, refer to [`send_data_internal`]. -fn make_request(thread_id: u32, client: &Client) { - let json = generate_random_reading(); +fn make_request(thread_id: u32, client: &Client, rng: &mut ThreadRng) { + let json = generate_random_reading(rng); info!("[Thread {thread_id}]: Sending POST request to {}", URL); debug!("[Thread {thread_id}]: Request JSON: {}", json); @@ -196,13 +189,13 @@ fn make_request(thread_id: u32, client: &Client) { } } -fn generate_random_reading() -> String { - let dust_concentration = random_gen_dust_concentration(); +fn generate_random_reading(rng: &mut ThreadRng) -> String { + let dust_concentration = random_gen_dust_concentration(rng); let air_purity = AirPurity::from_value(dust_concentration).to_string(); let reading = Reading::new( - random_gen_temperature(), - random_gen_humidity(), - random_gen_pressure(), + random_gen_temperature(rng), + random_gen_humidity(rng), + random_gen_pressure(rng), dust_concentration, air_purity, ); From b4241f65333e4e1da68b4f27ab80309d14f48f8c Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Sat, 4 Mar 2023 21:29:26 +0100 Subject: [PATCH 29/36] Changed air purity messages --- src/data.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/data.rs b/src/data.rs index 2c20f26..820b579 100644 --- a/src/data.rs +++ b/src/data.rs @@ -54,10 +54,10 @@ impl AirPurity { impl fmt::Display for AirPurity { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - AirPurity::Low => write!(f, "Fresh Air"), - AirPurity::High => write!(f, "Low Pollution"), - AirPurity::Dangerous => write!(f, "High Pollution"), - AirPurity::FreshAir => write!(f, "Dangerous Pollution"), + AirPurity::Low => write!(f, "Low Pollution"), + AirPurity::High => write!(f, "High Pollution"), + AirPurity::Dangerous => write!(f, "Dangerous Pollution"), + AirPurity::FreshAir => write!(f, "Fresh Air"), } } } From 9807ab5d02a0cc97ba7a61d684bf9eaac200f5f3 Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Sun, 5 Mar 2023 14:56:50 +0100 Subject: [PATCH 30/36] Resolve PR comments --- src/error.rs | 2 +- src/lib.rs | 18 +++++++++--------- src/main.rs | 4 ++-- src/requests.rs | 24 ++++++++++++------------ 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/error.rs b/src/error.rs index c6a248d..c478a3a 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,7 +1,7 @@ use thiserror::Error; #[derive(Error, Debug)] -pub enum RequestSchedulerError { +pub enum PostSchedulerError { #[error("Invalid value \"{value}\" for argument {argument_name}. {message}")] InvalidArgument { argument_name: String, diff --git a/src/lib.rs b/src/lib.rs index 1b37961..9daadcc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,9 +13,9 @@ mod data; pub mod error; mod requests; -use crate::requests::{send_data, RequestSchedulerBuilder}; +use crate::requests::{send_data, PostSchedulerBuilder}; use clap::Parser; -use error::RequestSchedulerError; +use error::PostSchedulerError; use log::debug; use requests::MAX_NUM_THREADS; use std::time::Duration; @@ -32,21 +32,21 @@ const URL: &str = "http://localhost:8000/api/readings/add"; long_about = "This application emulates a real set of hardware sensors that can report on environmental conditions such as temperature, pressure, humidity, etc." )] pub struct Cli { - /// Turns verbose console debug output on + /// Turns verbose console debug output on. #[arg(short, long)] pub debug: bool, - /// The amount of requests to make + /// The number of sensor readings to post. /// [DEFAULT: 1] #[arg(short = 'n', long)] pub request_amount: Option, - /// The time between each request (in seconds) + /// The time between each sensor reading post (in seconds). /// [DEFAULT: 10] #[arg(short = 't', long = "time-per-request")] pub time_per_request_s: Option, - /// The total time over which all the requests must be sent (in seconds, alternative to -t) + /// The total time over which all the sensor reading posts must be sent (in seconds, alternative to -t). #[arg(short = 'T', long = "total-time")] pub total_time_s: Option, - /// The number of threads to spawn. The workload will be cloned to each thread, not divided + /// The number of threads to spawn. The workload will be cloned to each thread, not divided. /// [DEFAULT: 1] #[arg(short = 'p', long, value_parser = is_valid_num_of_threads)] pub num_threads: Option, @@ -66,10 +66,10 @@ fn is_valid_num_of_threads(val: &str) -> Result { } } -pub fn run(cli: &Cli) -> Result<(), RequestSchedulerError> { +pub fn run(cli: &Cli) -> Result<(), PostSchedulerError> { debug!("cli: {cli:?}"); - let req_scheduler = RequestSchedulerBuilder::default() + let req_scheduler = PostSchedulerBuilder::default() .with_some_request_amount(&cli.request_amount) .with_some_time_per_request(&cli.time_per_request_s.map(Duration::from_secs)) .with_some_total_time(&cli.total_time_s.map(Duration::from_secs)) diff --git a/src/main.rs b/src/main.rs index f0105c4..e67392f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,11 +10,11 @@ //! See the `LICENSE` file for Copyright and license details. //! -use ambi_mock_client::error::RequestSchedulerError; +use ambi_mock_client::error::PostSchedulerError; use clap::Parser; use log::LevelFilter; -fn main() -> Result<(), RequestSchedulerError> { +fn main() -> Result<(), PostSchedulerError> { // Parses the provided command line interface arguments and flags let cli = ambi_mock_client::Cli::parse(); diff --git a/src/requests.rs b/src/requests.rs index c5e86f3..dbd6f36 100644 --- a/src/requests.rs +++ b/src/requests.rs @@ -9,7 +9,7 @@ use crate::{ random_gen_dust_concentration, random_gen_humidity, random_gen_pressure, random_gen_temperature, AirPurity, Reading, }, - error::RequestSchedulerError, + error::PostSchedulerError, URL, }; @@ -19,16 +19,16 @@ const DEFAULT_NUM_THREADS: u32 = 1; pub const MAX_NUM_THREADS: u32 = 10; #[derive(Clone, Copy)] -pub struct RequestSchedulerBuilder { +pub struct PostSchedulerBuilder { request_amount: Option, time_per_request: Option, total_time: Option, num_threads: Option, } -impl RequestSchedulerBuilder { +impl PostSchedulerBuilder { pub fn default() -> Self { - RequestSchedulerBuilder { + PostSchedulerBuilder { request_amount: None, time_per_request: None, total_time: None, @@ -56,7 +56,7 @@ impl RequestSchedulerBuilder { self } - pub fn build(self) -> Result { + pub fn build(self) -> Result { // Loop indefinitely if no req amt is set. If time per req is also not set then don't loop. let loop_indefinitely = self.request_amount.is_none() && self.time_per_request.is_some(); @@ -73,7 +73,7 @@ impl RequestSchedulerBuilder { // At this point we know that the number of threads is in [1, `MAX_NUM_THREADS`]. // Validation is done in `lib::is_valid_num_of_threads`. - Ok(RequestScheduler { + Ok(PostScheduler { request_amount, time_per_request, num_threads, @@ -83,14 +83,14 @@ impl RequestSchedulerBuilder { } #[derive(Clone, Copy)] -pub struct RequestScheduler { +pub struct PostScheduler { request_amount: u32, time_per_request: Duration, num_threads: u32, loop_indefinitely: bool, } -pub fn send_data(req_scheduler: RequestScheduler) { +pub fn send_data(req_scheduler: PostScheduler) { // If 1 thread is specified, we can use the current thread. if req_scheduler.num_threads == 1 { debug!("num_threads is set to 1, use current thread."); @@ -126,7 +126,7 @@ pub fn send_data(req_scheduler: RequestScheduler) { /// /// You can log the thread id by prepending `[Thread {thread_id}]: ` to your logs. fn send_data_internal( - req_scheduler: RequestScheduler, + req_scheduler: PostScheduler, thread_id: u32, client: Client, rng: &mut ThreadRng, @@ -205,13 +205,13 @@ fn generate_random_reading(rng: &mut ThreadRng) -> String { #[cfg(test)] mod tests { - use super::{RequestSchedulerBuilder, MAX_NUM_THREADS}; + use super::{PostSchedulerBuilder, MAX_NUM_THREADS}; // TODO: Add some tests for the parameter logic. #[test] fn test_invalid_num_threads_low() { - let req_scheduler = RequestSchedulerBuilder::default() + let req_scheduler = PostSchedulerBuilder::default() .with_some_num_threads(&Some(0)) .build(); @@ -220,7 +220,7 @@ mod tests { #[test] fn test_invalid_num_threads_high() { - let req_scheduler = RequestSchedulerBuilder::default() + let req_scheduler = PostSchedulerBuilder::default() .with_some_num_threads(&Some(MAX_NUM_THREADS + 1)) .build(); From 5782646641471f87fc0b032e2d9c2b8ddb1e89aa Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Sun, 5 Mar 2023 16:53:09 +0100 Subject: [PATCH 31/36] Renamed `request` to `post` --- src/lib.rs | 16 +++---- src/{requests.rs => sensor_posts.rs} | 66 +++++++++++++++------------- 2 files changed, 44 insertions(+), 38 deletions(-) rename src/{requests.rs => sensor_posts.rs} (76%) diff --git a/src/lib.rs b/src/lib.rs index 9daadcc..cdaf83d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,13 +11,13 @@ mod data; pub mod error; -mod requests; +mod sensor_posts; -use crate::requests::{send_data, PostSchedulerBuilder}; +use crate::sensor_posts::{send_data, PostSchedulerBuilder}; use clap::Parser; use error::PostSchedulerError; use log::debug; -use requests::MAX_NUM_THREADS; +use sensor_posts::MAX_NUM_THREADS; use std::time::Duration; const URL: &str = "http://localhost:8000/api/readings/add"; @@ -38,11 +38,11 @@ pub struct Cli { /// The number of sensor readings to post. /// [DEFAULT: 1] #[arg(short = 'n', long)] - pub request_amount: Option, + pub post_amount: Option, /// The time between each sensor reading post (in seconds). /// [DEFAULT: 10] - #[arg(short = 't', long = "time-per-request")] - pub time_per_request_s: Option, + #[arg(short = 't', long = "time-per-post")] + pub time_per_post_s: Option, /// The total time over which all the sensor reading posts must be sent (in seconds, alternative to -t). #[arg(short = 'T', long = "total-time")] pub total_time_s: Option, @@ -70,8 +70,8 @@ pub fn run(cli: &Cli) -> Result<(), PostSchedulerError> { debug!("cli: {cli:?}"); let req_scheduler = PostSchedulerBuilder::default() - .with_some_request_amount(&cli.request_amount) - .with_some_time_per_request(&cli.time_per_request_s.map(Duration::from_secs)) + .with_some_post_amount(&cli.post_amount) + .with_some_time_per_post(&cli.time_per_post_s.map(Duration::from_secs)) .with_some_total_time(&cli.total_time_s.map(Duration::from_secs)) .with_some_num_threads(&cli.num_threads) .build()?; diff --git a/src/requests.rs b/src/sensor_posts.rs similarity index 76% rename from src/requests.rs rename to src/sensor_posts.rs index dbd6f36..f90f7fd 100644 --- a/src/requests.rs +++ b/src/sensor_posts.rs @@ -13,15 +13,15 @@ use crate::{ URL, }; -const DEFAULT_REQUEST_AMOUNT: u32 = 1; -const DEFAULT_TIME_PER_REQUEST: Duration = Duration::from_secs(10); +const DEFAULT_POST_AMOUNT: u32 = 1; +const DEFAULT_TIME_PER_POST: Duration = Duration::from_secs(10); const DEFAULT_NUM_THREADS: u32 = 1; pub const MAX_NUM_THREADS: u32 = 10; #[derive(Clone, Copy)] pub struct PostSchedulerBuilder { - request_amount: Option, - time_per_request: Option, + post_amount: Option, + time_per_post: Option, total_time: Option, num_threads: Option, } @@ -29,20 +29,20 @@ pub struct PostSchedulerBuilder { impl PostSchedulerBuilder { pub fn default() -> Self { PostSchedulerBuilder { - request_amount: None, - time_per_request: None, + post_amount: None, + time_per_post: None, total_time: None, num_threads: None, } } - pub fn with_some_request_amount(mut self, request_amount: &Option) -> Self { - self.request_amount = *request_amount; + pub fn with_some_post_amount(mut self, post_amount: &Option) -> Self { + self.post_amount = *post_amount; self } - pub fn with_some_time_per_request(mut self, time_per_request: &Option) -> Self { - self.time_per_request = *time_per_request; + pub fn with_some_time_per_post(mut self, time_per_post: &Option) -> Self { + self.time_per_post = *time_per_post; self } @@ -58,15 +58,15 @@ impl PostSchedulerBuilder { pub fn build(self) -> Result { // Loop indefinitely if no req amt is set. If time per req is also not set then don't loop. - let loop_indefinitely = self.request_amount.is_none() && self.time_per_request.is_some(); + let loop_indefinitely = self.post_amount.is_none() && self.time_per_post.is_some(); - let request_amount = self.request_amount.unwrap_or(DEFAULT_REQUEST_AMOUNT); + let post_amount = self.post_amount.unwrap_or(DEFAULT_POST_AMOUNT); - let time_per_request = match (&self.time_per_request, &self.total_time) { - (None, None) => DEFAULT_TIME_PER_REQUEST, - (None, Some(total_time)) => *total_time / request_amount, - (Some(time_per_request), None) => *time_per_request, - (Some(time_per_request), Some(_)) => *time_per_request, + let time_per_post = match (&self.time_per_post, &self.total_time) { + (None, None) => DEFAULT_TIME_PER_POST, + (None, Some(total_time)) => *total_time / post_amount, + (Some(time_per_post), None) => *time_per_post, + (Some(time_per_post), Some(_)) => *time_per_post, }; let num_threads = self.num_threads.unwrap_or(DEFAULT_NUM_THREADS); @@ -74,8 +74,8 @@ impl PostSchedulerBuilder { // Validation is done in `lib::is_valid_num_of_threads`. Ok(PostScheduler { - request_amount, - time_per_request, + post_amount, + time_per_post, num_threads, loop_indefinitely, }) @@ -84,8 +84,8 @@ impl PostSchedulerBuilder { #[derive(Clone, Copy)] pub struct PostScheduler { - request_amount: u32, - time_per_request: Duration, + post_amount: u32, + time_per_post: Duration, num_threads: u32, loop_indefinitely: bool, } @@ -133,26 +133,26 @@ fn send_data_internal( ) { if req_scheduler.loop_indefinitely { loop { - make_request(thread_id, &client, rng); - thread::sleep(req_scheduler.time_per_request) + make_post(thread_id, &client, rng); + thread::sleep(req_scheduler.time_per_post) } } - for i in 0..req_scheduler.request_amount { - make_request(thread_id, &client, rng); + for i in 0..req_scheduler.post_amount { + make_post(thread_id, &client, rng); // Only use thread.sleep if we are not on the last request - if i != req_scheduler.request_amount - 1 { - thread::sleep(req_scheduler.time_per_request) + if i != req_scheduler.post_amount - 1 { + thread::sleep(req_scheduler.time_per_post) } } } /// This also can run in parallel, refer to [`send_data_internal`]. -fn make_request(thread_id: u32, client: &Client, rng: &mut ThreadRng) { +fn make_post(thread_id: u32, client: &Client, rng: &mut ThreadRng) { let json = generate_random_reading(rng); info!("[Thread {thread_id}]: Sending POST request to {}", URL); - debug!("[Thread {thread_id}]: Request JSON: {}", json); + debug!("[Thread {thread_id}]: Post JSON: {}", json); let res = client .post(URL) @@ -162,10 +162,16 @@ fn make_request(thread_id: u32, client: &Client, rng: &mut ThreadRng) { match res { Ok(response) => { - info!( + let info_msg = format!( "[Thread {thread_id}]: Response from Ambi backend: {}", response.status().as_str() ); + + match response.status().is_success() { + true => info!("{}", info_msg), + false => error!("{}", info_msg), + } + debug!( "[Thread {thread_id}]: Response from Ambi backend: {:#?}", response From 863425fb6a47f69fbce63f5cd34ab91bc33c8b94 Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Sun, 5 Mar 2023 16:55:14 +0100 Subject: [PATCH 32/36] Renamed response_format_str --- src/sensor_posts.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sensor_posts.rs b/src/sensor_posts.rs index f90f7fd..e32cee1 100644 --- a/src/sensor_posts.rs +++ b/src/sensor_posts.rs @@ -162,14 +162,14 @@ fn make_post(thread_id: u32, client: &Client, rng: &mut ThreadRng) { match res { Ok(response) => { - let info_msg = format!( + let response_format_str = format!( "[Thread {thread_id}]: Response from Ambi backend: {}", response.status().as_str() ); match response.status().is_success() { - true => info!("{}", info_msg), - false => error!("{}", info_msg), + true => info!("{}", response_format_str), + false => error!("{}", response_format_str), } debug!( From 1b8ed920a36281bb74268d031802eb35a50ce09f Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Mon, 6 Mar 2023 23:09:01 +0100 Subject: [PATCH 33/36] Fix tests --- src/lib.rs | 24 ++++++++++++++++++++++-- src/sensor_posts.rs | 25 ------------------------- 2 files changed, 22 insertions(+), 27 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index cdaf83d..2d3173c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -83,12 +83,32 @@ pub fn run(cli: &Cli) -> Result<(), PostSchedulerError> { #[cfg(test)] mod tests { - use clap::CommandFactory; + use clap::{error::ErrorKind, CommandFactory, Parser}; - use crate::Cli; + use crate::{sensor_posts::MAX_NUM_THREADS, Cli}; #[test] fn verify_cli() { Cli::command().debug_assert(); } + + #[test] + // #[should_panic] + fn test_invalid_num_threads_low() { + let cli = Cli::try_parse_from(vec!["", "-p", "0"]); + assert!(cli.is_err()); + + let cli_err = cli.unwrap_err(); + assert_eq!(cli_err.kind(), ErrorKind::ValueValidation); + } + + #[test] + fn test_invalid_num_threads_high() { + let num = MAX_NUM_THREADS + 1; + let cli = Cli::try_parse_from(vec!["", "-p", &num.to_string()]); + assert!(cli.is_err()); + + let cli_err = cli.unwrap_err(); + assert_eq!(cli_err.kind(), ErrorKind::ValueValidation); + } } diff --git a/src/sensor_posts.rs b/src/sensor_posts.rs index e32cee1..d1fe390 100644 --- a/src/sensor_posts.rs +++ b/src/sensor_posts.rs @@ -208,28 +208,3 @@ fn generate_random_reading(rng: &mut ThreadRng) -> String { serde_json::to_string(&reading).unwrap() } - -#[cfg(test)] -mod tests { - use super::{PostSchedulerBuilder, MAX_NUM_THREADS}; - - // TODO: Add some tests for the parameter logic. - - #[test] - fn test_invalid_num_threads_low() { - let req_scheduler = PostSchedulerBuilder::default() - .with_some_num_threads(&Some(0)) - .build(); - - assert!(req_scheduler.is_err()) - } - - #[test] - fn test_invalid_num_threads_high() { - let req_scheduler = PostSchedulerBuilder::default() - .with_some_num_threads(&Some(MAX_NUM_THREADS + 1)) - .build(); - - assert!(req_scheduler.is_err()) - } -} From 40be489decb72406b909d5cd69cde1466372fd49 Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Mon, 6 Mar 2023 23:11:24 +0100 Subject: [PATCH 34/36] Added CI --- .github/workflows/ci.yml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..4931b23 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,32 @@ +name: Build & Tests + +on: + push: + pull_request: + +env: + CARGO_TERM_COLOR: always + + +jobs: + build_test: + name: Build & test + runs-on: ubuntu-22.04 + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + targets: ${{ matrix.job.target }} + + - name: Use cached dependencies + uses: Swatinem/rust-cache@v2 + + - name: Build + run: cargo build + + - name: Test + run: cargo test From e4fe9b109b81d98202e17c04a88a9459b7a499d4 Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Mon, 6 Mar 2023 23:12:10 +0100 Subject: [PATCH 35/36] Removed extra newline --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4931b23..5c70449 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,6 @@ on: env: CARGO_TERM_COLOR: always - jobs: build_test: name: Build & test From f8510ad54997403e65ed223c1d93e16c18fed517 Mon Sep 17 00:00:00 2001 From: Antonios Barotsis Date: Mon, 6 Mar 2023 23:12:54 +0100 Subject: [PATCH 36/36] Removed unused comment --- src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 2d3173c..1cdf594 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -93,7 +93,6 @@ mod tests { } #[test] - // #[should_panic] fn test_invalid_num_threads_low() { let cli = Cli::try_parse_from(vec!["", "-p", "0"]); assert!(cli.is_err());