-
Notifications
You must be signed in to change notification settings - Fork 4.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve cli args parsing in bench-tps #30307
Improve cli args parsing in bench-tps #30307
Conversation
Rust compiler shows warnings which looks weird for me: error: unused imports: `read_keypair_file`, `super::*`, `write_keypair_file`
--> bench-tps/src/cli.rs:559:9
|
559 | super::*,
| ^^^^^^^^
560 | solana_sdk::signature::{read_keypair_file, write_keypair_file, Keypair, Signer},
| ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^
|
= note: `-D unused-imports` implied by `-D warnings`
Checking solana-validator v1.16.0 (/solana/validator)
Checking solana-rpc-test v1.16.0 (/solana/rpc-test)
Checking solana-client-test v1.16.0 (/solana/client-test)
error: function `make_tmp_path` is never used
--> bench-tps/src/cli.rs:563:8
|
563 | fn make_tmp_path(name: &str) -> String {
| ^^^^^^^^^^^^^
|
= note: `-D dead-code` implied by `-D warnings` because these imports and function are clearly used |
This is because tests are not part of the normal compilation profile. #[test]
#[allow(clippy::cognitive_complexity)]
fn test_cli_parse() { is ignored by the compiler. The compiler will then see that fn make_tmp_path(name: &str) -> String { is not called by anyone in the same module. Adding diff --git bench-tps/src/cli.rs bench-tps/src/cli.rs
index b6eb6..2956d 100644
--- bench-tps/src/cli.rs
+++ bench-tps/src/cli.rs
@@ -554,6 +554,7 @@ pub fn parse_args(matches: &ArgMatches) -> Result<Config, &'static str> {
Ok(args)
}
+#[cfg(test)]
mod tests {
use {
super::*, |
mod tests { | ||
use { | ||
super::*, | ||
solana_sdk::signature::{read_keypair_file, write_keypair_file, Keypair, Signer}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, since you are using super::*
, you don't need to reimport elements imported in the top-level module.
solana_sdk::signature::{read_keypair_file, write_keypair_file, Keypair, Signer}, | |
solana_sdk::signature::{write_keypair_file, Signer}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The evil of the wildcard imports is raising its ugly head
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Grumble. This is now inconsistent with the pattern in nearly every other test module in the repo, where we use super::*
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you clarify what exactly is inconsistent?
After using super::*
it looks similar to the other tests that use super::*
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But this one isn't using super::*
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lol, yeah, it's weird it's not showing that preview as outdated.
Oh well. I'm not going to fight on this one anymore anyway.
mod tests { | ||
use { | ||
super::*, | ||
solana_sdk::signature::{read_keypair_file, write_keypair_file, Keypair, Signer}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The evil of the wildcard imports is raising its ugly head
bench-tps/src/cli.rs
Outdated
@@ -35,12 +35,14 @@ impl Default for ExternalClientType { | |||
} | |||
} | |||
|
|||
#[derive(PartialEq, Debug)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor
When deriving PartialEq
, you normally also want to derive Eq
.
Only a rather specific set of types (such as floating point numbers) implement only PartialEq
without Eq
.
But as the compiler can not check it, it is up to the person writing the code to make this call.
Here are the details on when absence of Eq
matters: https://doc.rust-lang.org/book/appendix-03-derivable-traits.html?highlight=partialeq#partialeq-and-eq-for-equality-comparisons
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here the problem with Eq
is that Keypair
is not implementing it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure why it is the case.
Keypair
is just a PublicKey
and a SecretKey
.
Seems like it might be intentional, as PublicKey
does implement it.
Not sure why SecretKey
would not.
I've opened an issue, with a few questions, in the library repo.
But you can still add Eq
to the other places where you are adding PartialEq
.
At least, I personally, try to do it by default.
When someone needs it, they need to go and figure out if Eq
was omitted by accident or not. Which is generally more complex, compared to adding 3 characters when the code is written :))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realized that PartialEq
was implemented for Keypair
in https://github.com/solana-labs/solana/blob/master/sdk/src/signer/keypair.rs#L107-L114
Seems like this is exactly the case when PartialEq
was implemented, without adding Eq
in there.
Here is a PR to fix it: #30381
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like leaving as it is
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yay to the unit tests and proper error handling!
bench-tps/src/cli.rs
Outdated
@@ -35,12 +35,14 @@ impl Default for ExternalClientType { | |||
} | |||
} | |||
|
|||
#[derive(PartialEq, Debug)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure why it is the case.
Keypair
is just a PublicKey
and a SecretKey
.
Seems like it might be intentional, as PublicKey
does implement it.
Not sure why SecretKey
would not.
I've opened an issue, with a few questions, in the library repo.
But you can still add Eq
to the other places where you are adding PartialEq
.
At least, I personally, try to do it by default.
When someone needs it, they need to go and figure out if Eq
was omitted by accident or not. Which is generally more complex, compared to adding 3 characters when the code is written :))
bench-tps/src/cli.rs
Outdated
let parsed_data_size = data_size | ||
.to_string() | ||
.parse() | ||
.map_err(|_| "Can't parse padded instruction data size")?; | ||
args.instruction_padding_config = Some(InstructionPaddingConfig { | ||
program_id, | ||
data_size: data_size | ||
.to_string() | ||
.parse() | ||
.expect("Can't parse padded instruction data size"), | ||
data_size: parsed_data_size, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<minor-style>
I think it is totaly fine to shadow data_size
here:
let data_size = data_size
.to_string()
.parse()
.map_err(|_| "Can't parse padded instruction data size")?;
args.instruction_padding_config = Some(InstructionPaddingConfig {
program_id,
data_size,
});
</minor-style>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By the way, .to_string()
is unnecessary here.
.parse()
works just fine on a &str
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
b59c1a0
to
7a7105c
Compare
e542f39
to
5542876
Compare
mod tests { | ||
use { | ||
super::*, | ||
solana_sdk::signature::{read_keypair_file, write_keypair_file, Keypair, Signer}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Grumble. This is now inconsistent with the pattern in nearly every other test module in the repo, where we use super::*
fcad6aa
5542876
to
fcad6aa
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few minor comments, but looks good to me otherwise :)
bench-tps/src/cli.rs
Outdated
.parse() | ||
.expect("can't parse tpu_connection_pool_size"); | ||
.parse::<usize>() | ||
.map_err(|_| "can't parse tpu_connection_pool_size")?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the user standpoint, the argument name is tpu-connection-pool-size
, with dashes, right?
Here and in a few other places.
Technically, this issue was there before. But, maybe, you would want to fix it as well, as you are doing this cleanup.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is correct, so I've fixed it.
The plan is to eliminate this manual parsing by using clap-v3 with derive feature
bench-tps/src/cli.rs
Outdated
@@ -486,23 +485,25 @@ pub fn extract_args(matches: &ArgMatches) -> Config { | |||
} | |||
|
|||
if let Some(v) = matches.value_of("target_lamports_per_signature") { | |||
args.target_lamports_per_signature = v.to_string().parse().expect("can't parse lamports"); | |||
args.target_lamports_per_signature = | |||
v.to_string().parse().map_err(|_| "can't parse lamports")?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
v.to_string().parse().map_err(|_| "can't parse lamports")?; | |
v.to_string().parse().map_err(|_| "can't parse target-lamports-per-signature")?; |
bench-tps/src/cli.rs
Outdated
args.target_node = matches | ||
.value_of("target_node") | ||
.map(|target_str| target_str.parse().unwrap()); | ||
.map(|target_str| target_str.parse::<Pubkey>().unwrap()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still panicking. Here is how to fix it, to make it similar the other cases:
args.target_node = matches | |
.value_of("target_node") | |
.map(|target_str| target_str.parse().unwrap()); | |
.map(|target_str| target_str.parse::<Pubkey>().unwrap()); | |
args.target_node = matches | |
.value_of("target_node") | |
.map(|target_str| target_str.parse::<Pubkey>()) | |
.transpose() | |
.map_err(|_| "Failed to parse target-node")?; |
bench-tps/src/cli.rs
Outdated
|
||
if let Some(v) = matches.value_of("num_lamports_per_account") { | ||
args.num_lamports_per_account = v.to_string().parse().expect("can't parse lamports"); | ||
args.num_lamports_per_account = | ||
v.to_string().parse().map_err(|_| "can't parse lamports")?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
v.to_string().parse().map_err(|_| "can't parse lamports")?; | |
v.to_string().parse().map_err(|_| "can't parse num-lamports-per-account")?; |
bench-tps/src/cli.rs
Outdated
} | ||
|
||
if let Some(t) = matches.value_of("target_slots_per_epoch") { | ||
args.target_slots_per_epoch = t | ||
.to_string() | ||
.parse() | ||
.expect("can't parse target slots per epoch"); | ||
.map_err(|_| "can't parse target slots per epoch")?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.map_err(|_| "can't parse target slots per epoch")?; | |
.map_err(|_| "can't parse target-slots-per-epoch")?; |
bench-tps/src/cli.rs
Outdated
); | ||
let parsed_num_conflict_groups = num_conflict_groups | ||
.parse() | ||
.map_err(|_| "Can't parse conflict groups")?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.map_err(|_| "Can't parse conflict groups")?; | |
.map_err(|_| "Can't parse num-conflict-groups")?; |
bench-tps/src/cli.rs
Outdated
exit(1) | ||
}); | ||
args.bind_address = | ||
solana_net_utils::parse_host(addr).map_err(|_| "Failed to parse bind_address")?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
solana_net_utils::parse_host(addr).map_err(|_| "Failed to parse bind_address")?; | |
solana_net_utils::parse_host(addr).map_err(|_| "Failed to parse bind-address")?; |
1c35fe9
* Rename parse funciton * Get rid of panics, exit and println * Add basic unit tests
1c35fe9
to
df748f2
Compare
* Improve cli args parsing in bench-tps * Rename parse funciton * Get rid of panics, exit and println * Add basic unit tests * add allow dead_code and unused_imports for cli tests * simplify code by using map_err instead of macro * simplify data_size parsing * use tempfile crate to create temp keypair files * fix bug with reading client_id from config by default, re-added client_id tests * minor fix of an error message * add Eq to bench_tps::cli::Congig * some minor error messages corrections
Problem
Parsing cli args is different from other places (due to exit, panic, println), it also makes it more difficult to test.
Added a basic unit test for cli.
This is preliminary work to migrate it to clap-v3, most of the things will be rewritten during migration to clap-v3
Summary of Changes