-
Notifications
You must be signed in to change notification settings - Fork 43
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
Remove unwrap() in integration/e2e tests #512
Conversation
Pull Request Test Coverage Report for Build 13057514318Details
💛 - Coveralls |
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.
cACK, partial review with a few comments.
Main takeaway is I'm not sure about when .expect()
is preferred over .map_err()
with format!
and bubbling up...
ISTM that the benefits, in descending priority order are:
- eliminate
unwrap()
to avoid vague failures without context (though?
doesn't materially improve that), and to make any snippets copied from tests be better behaved in whatever context they end up in (where?
does make a material difference) - simplifying types for things that should never fail
- concision helping readability
is that correct?
payjoin-cli/tests/e2e.rs
Outdated
fn find_free_port() -> u16 { | ||
let listener = std::net::TcpListener::bind("127.0.0.1:0").unwrap(); | ||
listener.local_addr().unwrap().port() | ||
assert!(payjoin_sent??.unwrap_or(false), "Payjoin send was not detected"); |
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'm confused by .unwrap().unwrap_or(Some(false)).unwrap()
becoming payjoin_sent??.unwrap_or(false)
.
It's a Result<Result<Option<bool>, Elapsed>, JoinError>
, where the Option
originates from the mpsc's recv()
, the `bool is the value sent through the channel.
So isn't this equivalent to payjoin_sent.unwrap().unwrap().unwrap_or(false)
instead, i.e. that a timeout bubbles up instead of becoming an assertion error? isn't it more appropriate for the assertion to fail in case of a timeout in which case .unwrap_or(Some(false)).ok_or(...)?
would be closer in spirit to what it was, with i guess an anyhow error in the ...
indicating the mpsc recv
should have worked
also, using await?
on the task seems like it reduce some of the noise... if you agree with this suggestion and the previous paragraph, i guess this implies the unwrap_or(Some(false).ok_or()
is better done inside the task, so that await??
can bubble the task joining error if any, followed by the ok_or
, and leaving payjoin_sent
as just a bool
?
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.
Great catch! I applied your suggestion, with expect
instead of ok_or
since the rx channel should never close early.
pub fn take_directory_handle(&mut self) -> Option<JoinHandle<Result<(), BoxSendSyncError>>> { | ||
self.directory.1.take() | ||
pub fn take_directory_handle(&mut self) -> JoinHandle<Result<(), BoxSendSyncError>> { | ||
self.directory.1.take().expect("directory handle not found") |
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.
hmm, i prefer the simpler type here over expecting the caller to bubble this up, since this kind of thing should never fail a test but indicates the test environment is not as expected, having an expect message puts that kind of failure into context...
but i want to make sure i'm not missing anything about tests returning Result
, is it equivalent to the test runner doing .unwrap()
for us? i found this mentioned in rust by example, which links to a seemingly stale doc link that leads back to rust by example discussing this in the context of main (https://doc.rust-lang.org/edition-guide/rust-2018/error-handling-and-panics/question-mark-in-main-and-tests.html) and ?
is ~impossible to websearch for
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.
Yes, when an Error
result bubbles up all the way to the test runner it fails the test and prints a debug representation of the error. The way it's displayed is slightly cleaner than when calling unwrap
directly, e.g.:
unwrap
:
---- integration::v1::v1_to_v1_p2pkh stdout ----
thread 'integration::v1::v1_to_v1_p2pkh' panicked at payjoin/tests/integration.rs:998:51:
called `Result::unwrap()` on an `Err` value: PsbtEncoding(ConsensusEncoding(Io(Error { kind: UnexpectedEof, error: None })))
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
?
:
---- integration::v1::v1_to_v1_p2pkh stdout ----
Error: PsbtEncoding(ConsensusEncoding(Io(Error { kind: UnexpectedEof, error: None })))
payjoin-test-utils/src/lib.rs
Outdated
Ok(ClientBuilder::new() | ||
.danger_accept_invalid_certs(true) | ||
.use_rustls_tls() | ||
.add_root_certificate(reqwest::tls::Certificate::from_der(cert_der.as_slice()).unwrap())) | ||
.add_root_certificate(reqwest::tls::Certificate::from_der(cert_der.as_slice())?)) |
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.
in line with the remark on take_...
variants, is this perhaps better handled with .expect()
?
5ca026e
to
988ded4
Compare
Yes - I'd add another benefit which is that |
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.
ACK 988ded4
I left some comments on further cleanups, but I think everything here is pointed in the right direction i.e. cleans up tech debt rather than takes new on and don't see big reasons not to merge and address the concerns in a follow up referencing the issues stated here.
@@ -137,7 +137,7 @@ mod e2e { | |||
|
|||
#[cfg(feature = "v2")] | |||
#[tokio::test(flavor = "multi_thread", worker_threads = 4)] | |||
async fn send_receive_payjoin() { | |||
async fn send_receive_payjoin() -> Result<(), Box<dyn std::error::Error + Send + Sync>> { |
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.
nit: Why not use BoxSendSyncError here?
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.
It would have to be imported in mod e2e
but that results in a "unused" warning when the v2
feature is disabled. I suppose we could feature-gate the import, or put the v1
and v2
tests in separate modules like we do in integration.rs
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.
That's a good reason. It would also be more organized to separate v1, v2 modules (and even separate files that use super::*
but is not a necessity.
988ded4
to
2f14846
Compare
My latest push addresses the minor issues Dan brought up, and should be good to merge as-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.
ACK 2f14846
@@ -137,7 +137,7 @@ mod e2e { | |||
|
|||
#[cfg(feature = "v2")] | |||
#[tokio::test(flavor = "multi_thread", worker_threads = 4)] | |||
async fn send_receive_payjoin() { | |||
async fn send_receive_payjoin() -> Result<(), Box<dyn std::error::Error + Send + Sync>> { |
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.
That's a good reason. It would also be more organized to separate v1, v2 modules (and even separate files that use super::*
but is not a necessity.
Partially address #487.
There are other places to clean up, notably unit tests, that can be addressed in later PRs.
The commit messages might be a little repetitive but I wanted to keep each commit bite-sized for easier review. I can squash them if preferred.