From ac6a3f0edc4b1150e919a9fe8b060ec784180d51 Mon Sep 17 00:00:00 2001 From: Trevor McMaster Date: Fri, 27 Jan 2023 10:10:25 -0700 Subject: [PATCH] Updated clap and base64 dependencies --- Cargo.lock | 101 ++++++++++++++++++++++++++++++----------- Cargo.toml | 4 +- src/bin/pewpew.rs | 111 ++++++++++++++++++++++++++-------------------- src/stats.rs | 5 ++- 4 files changed, 144 insertions(+), 77 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 01084cea..ac66c056 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -87,6 +87,12 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "base64" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" + [[package]] name = "bitflags" version = "1.3.2" @@ -212,25 +218,21 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.23" +version = "4.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" +checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76" dependencies = [ - "atty", "bitflags", "clap_lex", - "indexmap", "once_cell", - "strsim", - "termcolor", - "textwrap", + "terminal_size", ] [[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", ] @@ -258,7 +260,7 @@ dependencies = [ name = "config" version = "0.0.0" dependencies = [ - "base64", + "base64 0.13.1", "ether", "futures", "http", @@ -508,6 +510,27 @@ dependencies = [ "termcolor", ] +[[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 = "ether" version = "0.0.0" @@ -726,7 +749,7 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" name = "hdr-histogram-wasm" version = "0.0.0" dependencies = [ - "base64", + "base64 0.13.1", "hdrhistogram", "log", "wasm-bindgen", @@ -739,7 +762,7 @@ version = "7.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f19b9f54f7c7f55e31401bb647626ce0cf0f67b0004982ce815b3ee72a02aa8" dependencies = [ - "base64", + "base64 0.13.1", "byteorder", "crossbeam-channel", "flate2", @@ -904,6 +927,16 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "io-lifetimes" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e" +dependencies = [ + "libc", + "windows-sys", +] + [[package]] name = "itertools" version = "0.10.5" @@ -1016,6 +1049,12 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" +[[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" + [[package]] name = "lock_api" version = "0.4.9" @@ -1323,7 +1362,7 @@ name = "pewpew" version = "0.5.11" dependencies = [ "atty", - "base64", + "base64 0.21.0", "body_reader", "bytes", "channel", @@ -1487,6 +1526,20 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422" +[[package]] +name = "rustix" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys", +] + [[package]] name = "ryu" version = "1.0.12" @@ -1638,12 +1691,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "sval" version = "1.0.0-alpha.5" @@ -1684,6 +1731,16 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "terminal_size" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb20089a8ba2b69debd491f8d2d023761cbf196e999218c591fa1e7e15a21907" +dependencies = [ + "rustix", + "windows-sys", +] + [[package]] name = "test_common" version = "0.1.0" @@ -1698,12 +1755,6 @@ dependencies = [ "url", ] -[[package]] -name = "textwrap" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" - [[package]] name = "thiserror" version = "1.0.38" diff --git a/Cargo.toml b/Cargo.toml index e7eb03ff..1d27f4df 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,11 +19,11 @@ path = "src/bin/test_server.rs" [dependencies] atty = "0.2" -base64 = "0.13" +base64 = "0.21" body_reader = { path = "./lib/body_reader" } bytes = "1" channel = { path = "./lib/channel" } -clap = { version = "3", features = ["cargo"] } +clap = { version = "4", features = ["cargo", "std", "help", "usage", "error-context", "wrap_help"], default-features = false } config = { path = "./lib/config" } csv = "1" ctrlc = "3" diff --git a/src/bin/pewpew.rs b/src/bin/pewpew.rs index dc07455d..144af846 100644 --- a/src/bin/pewpew.rs +++ b/src/bin/pewpew.rs @@ -1,4 +1,6 @@ -use std::{convert::TryInto, ffi::OsStr, fs::create_dir_all, io, path::PathBuf, time::UNIX_EPOCH}; +use std::{ + convert::TryInto, ffi::OsString, fs::create_dir_all, io, path::PathBuf, time::UNIX_EPOCH, +}; use clap::{builder::ValueParser, crate_version, Arg, ArgMatches, Command}; use config::duration_from_string; @@ -16,8 +18,23 @@ fn get_filter_reg() -> Regex { Regex::new("^(.*?)(!=|=)(.*)").expect("is a valid regex") } -fn get_arg_matcher() -> clap::App<'static> { +fn parse_duration(arg: &str) -> Result { + match duration_from_string(arg.into()) { + Ok(_) => Ok(arg.to_string()), + Err(error) => Err(error), + } +} + +fn parse_filter(arg: &str) -> Result { let filter_reg2: Regex = get_filter_reg(); + if filter_reg2.is_match(arg) { + Ok(arg.to_string()) + } else { + Err("include filters must be in the format `tag=value` or `tag!=value`") + } +} + +fn get_arg_matcher() -> clap::Command { Command::new("pewpew") .about("The HTTP load test tool https://familysearch.github.io/pewpew") .version(crate_version!()) @@ -35,8 +52,7 @@ fn get_arg_matcher() -> clap::App<'static> { .long("output-format") .help("Formatting for stats printed to stderr") .value_name("FORMAT") - .possible_value("human") - .possible_value("json") + .value_parser(["human","json"]) .default_value("human") ) .arg( @@ -45,7 +61,7 @@ fn get_arg_matcher() -> clap::App<'static> { .long("stats-file") .help("Specify the filename for the stats file") .value_name("STATS_FILE") - .value_parser(ValueParser::os_string()) // https://github.com/clap-rs/clap/issues/3344 + .value_parser(ValueParser::os_string()) ) .arg( Arg::new("start-at") @@ -53,12 +69,7 @@ fn get_arg_matcher() -> clap::App<'static> { .long("start-at") .help("Specify the time the test should start at") .value_name("START_AT") - .validator(|s| { - match duration_from_string(s.into()) { - Ok(_) => Ok(()), - Err(_) => Err("".to_string()), - } - }) + .value_parser(parse_duration) ) .arg( Arg::new("results-directory") @@ -67,7 +78,7 @@ fn get_arg_matcher() -> clap::App<'static> { .number_of_values(1) .help("Directory to store results and logs") .value_name("DIRECTORY") - .value_parser(ValueParser::os_string()) // https://github.com/clap-rs/clap/issues/3344 + .value_parser(ValueParser::os_string()) ) .arg( Arg::new("stats-file-format") @@ -75,9 +86,8 @@ fn get_arg_matcher() -> clap::App<'static> { .long("stats-file-format") .help("Format for the stats file") .value_name("FORMAT") - .possible_value("json") - // .possible_value("html") - // .possible_value("none") + .value_parser(["json"]) + // .value_parser(["json", "html", "none"]) .default_value("json") ) .arg( @@ -85,11 +95,13 @@ fn get_arg_matcher() -> clap::App<'static> { .short('w') .long("watch") .help("Watch the config file for changes and update the test accordingly") + .action(clap::ArgAction::SetTrue) ) .arg( Arg::new("CONFIG") .help("Load test config file to use") - .required(true), + .required(true) + .value_parser(ValueParser::os_string()), ) ) .subcommand(Command::new("try") @@ -100,6 +112,7 @@ fn get_arg_matcher() -> clap::App<'static> { .short('l') .long("loggers") .help("Enable loggers defined in the config file") + .action(clap::ArgAction::SetTrue) ) .arg( Arg::new("file") @@ -114,8 +127,7 @@ fn get_arg_matcher() -> clap::App<'static> { .long("format") .help("Specify the format for the try run output") .value_name("FORMAT") - .possible_value("human") - .possible_value("json") + .value_parser(["human","json"]) .default_value("human") ) .arg( @@ -123,15 +135,9 @@ fn get_arg_matcher() -> clap::App<'static> { .short('i') .long("include") .long_help(r#"Filter which endpoints are included in the try run. Filters work based on an endpoint's tags. Filters are specified in the format "key=value" where "*" is a wildcard. Any endpoint matching the filter is included in the test"#) - .multiple_occurrences(true) - .number_of_values(1) - .validator(move |s| { - if filter_reg2.is_match(s) { - Ok(()) - } else { - Err("include filters must be in the format `tag=value` or `tag!=value`".to_string()) - } - }) + // .multiple_occurrences(true) + .num_args(0..) + .value_parser(parse_filter) .value_name("INCLUDE") ) .arg( @@ -141,12 +147,13 @@ fn get_arg_matcher() -> clap::App<'static> { .number_of_values(1) .help("Directory to store logs (if enabled with --loggers)") .value_name("DIRECTORY") - .value_parser(ValueParser::os_string()) // https://github.com/clap-rs/clap/issues/3344 + .value_parser(ValueParser::os_string()) ) .arg( Arg::new("CONFIG") .help("Load test config file to use") - .required(true), + .required(true) + .value_parser(ValueParser::os_string()), ) ) } @@ -155,21 +162,26 @@ fn get_cli_config(matches: ArgMatches) -> ExecConfig { let filter_reg: Regex = get_filter_reg(); if let Some(matches) = matches.subcommand_matches("run") { let config_file: PathBuf = matches - .value_of("CONFIG") + .get_one::("CONFIG") .expect("should have CONFIG param") + // .as_str() .into(); - let results_dir = matches.value_of_os("results-directory").map(|d: &OsStr| { - create_dir_all(d).unwrap(); - PathBuf::from(d) - }); - let output_format = TryInto::try_into( + let results_dir: Option = + matches + .get_one::("results-directory") + .map(|d: &OsString| { + create_dir_all(d).unwrap(); + PathBuf::from(d) + }); + let output_format: RunOutputFormat = TryInto::try_into( matches - .value_of("output-format") - .expect("should have output_format cli arg"), + .get_one::("output-format") + .expect("should have output_format cli arg") + .as_str(), ) .expect("output_format cli arg unrecognized"); - let stats_file = matches - .value_of_os("stats-file") + let stats_file: PathBuf = matches + .get_one::("stats-file") .map(PathBuf::from) .unwrap_or_else(|| { let start_sec = UNIX_EPOCH @@ -192,9 +204,9 @@ fn get_cli_config(matches: ArgMatches) -> ExecConfig { stats_file }; let stats_file_format = StatsFileFormat::Json; - let watch_config_file = matches.is_present("watch"); + let watch_config_file = matches.get_flag("watch"); let start_at = matches - .value_of("start-at") + .get_one::("start-at") .map(|s| duration_from_string(s.to_string()).expect("start_at should match pattern")); let run_config = RunConfig { config_file, @@ -208,11 +220,13 @@ fn get_cli_config(matches: ArgMatches) -> ExecConfig { ExecConfig::Run(run_config) } else if let Some(matches) = matches.subcommand_matches("try") { let config_file: PathBuf = matches - .value_of("CONFIG") + .get_one::("CONFIG") .expect("should have CONFIG param") .into(); - let results_dir = matches.value_of_os("results-directory"); - let loggers_on = matches.is_present("loggers"); + let results_dir = matches + .get_one::("results-directory") + .map(|s| s.as_os_str()); + let loggers_on = matches.get_flag("loggers"); let results_dir = match (results_dir, loggers_on) { (Some(d), true) => { create_dir_all(d).unwrap(); @@ -220,8 +234,9 @@ fn get_cli_config(matches: ArgMatches) -> ExecConfig { } _ => None, }; - let filters = matches.values_of("include").map(|v| { + let filters = matches.get_many::("include").map(|v| { v.map(|s| { + let s = s.as_str(); let captures = filter_reg .captures(s) .expect("include cli arg should match regex"); @@ -248,10 +263,10 @@ fn get_cli_config(matches: ArgMatches) -> ExecConfig { .collect() }); let format: TryRunFormat = matches - .value_of("format") - .and_then(|f| f.try_into().ok()) + .get_one::("format") + .and_then(|f| f.as_str().try_into().ok()) .unwrap_or_default(); - let file = matches.value_of("file").map(Into::into); + let file = matches.get_one::("file").map(Into::into); let try_config = TryConfig { config_file, file, diff --git a/src/stats.rs b/src/stats.rs index 66d05b91..1c7c52a3 100644 --- a/src/stats.rs +++ b/src/stats.rs @@ -39,6 +39,7 @@ use std::{ // A helper module which tells serde how to serialize (and deserialize, though that's not currently // used anywhere) an HDRHistogram mod histogram_serde { + use base64::{engine::general_purpose::STANDARD_NO_PAD, Engine}; use hdrhistogram::{ serialization::{ Deserializer as HDRDeserializer, Serializer as HDRSerializer, V2Serializer, @@ -56,7 +57,7 @@ mod histogram_serde { v2_serializer .serialize(histogram, &mut buf) .map_err(|_e| serde::ser::Error::custom("could not serialize HDRHistogram"))?; - serializer.serialize_str(&base64::encode_config(&buf, base64::STANDARD_NO_PAD)) + serializer.serialize_str(&STANDARD_NO_PAD.encode(&buf)) } pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> @@ -64,7 +65,7 @@ mod histogram_serde { D: Deserializer<'de>, { let string = String::deserialize(deserializer)?; - let bytes = base64::decode_config(string, base64::STANDARD_NO_PAD).map_err(|_| { + let bytes = STANDARD_NO_PAD.decode(string).map_err(|_| { serde::de::Error::custom("could not base64 decode string for HDRHistogram") })?; let mut hdr_deserializer = HDRDeserializer::new();