@@ -146,7 +146,7 @@ mod e2e {
146
146
use std:: path:: PathBuf ;
147
147
148
148
use payjoin_test_utils:: { init_tracing, TestServices } ;
149
- use tokio:: process:: Child ;
149
+ use tokio:: process:: { Child , ChildStdout } ;
150
150
151
151
type Result < T > = std:: result:: Result < T , BoxError > ;
152
152
@@ -266,117 +266,94 @@ mod e2e {
266
266
}
267
267
268
268
async fn get_bip21_from_receiver ( mut cli_receiver : Child ) -> String {
269
- let stdout =
270
- cli_receiver. stdout . take ( ) . expect ( "Failed to take stdout of child process" ) ;
271
- let reader = BufReader :: new ( stdout) ;
272
- let mut stdout = tokio:: io:: stdout ( ) ;
273
- let mut bip21 = String :: new ( ) ;
274
-
275
- let mut lines = reader. lines ( ) ;
276
-
277
- while let Some ( line) = lines. next_line ( ) . await . expect ( "Failed to read line from stdout" )
278
- {
279
- // Write to stdout regardless
280
- stdout
281
- . write_all ( format ! ( "{}\n " , line) . as_bytes ( ) )
282
- . await
283
- . expect ( "Failed to write to stdout" ) ;
284
-
285
- if line. to_ascii_uppercase ( ) . starts_with ( "BITCOIN" ) {
286
- bip21 = line;
287
- break ;
288
- }
289
- }
269
+ let mut stdout =
270
+ cli_receiver. stdout . take ( ) . expect ( "failed to take stdout of child process" ) ;
271
+ let bip21 = wait_for_stdout_match ( & mut stdout, |line| {
272
+ line. to_ascii_uppercase ( ) . starts_with ( "BITCOIN" )
273
+ } )
274
+ . await
275
+ . expect ( "payjoin-cli receiver should output a bitcoin URI" ) ;
290
276
log:: debug!( "Got bip21 {}" , & bip21) ;
291
277
292
278
sigint ( cli_receiver) . await . expect ( "Failed to kill payjoin-cli" ) ;
293
279
bip21
294
280
}
295
281
296
282
async fn send_until_request_timeout ( mut cli_sender : Child ) -> Result < ( ) > {
297
- let stdout = cli_sender. stdout . take ( ) . expect ( "Failed to take stdout of child process" ) ;
298
- let reader = BufReader :: new ( stdout) ;
299
- let mut stdout = tokio:: io:: stdout ( ) ;
300
- let ( tx, mut rx) = tokio:: sync:: mpsc:: channel ( 1 ) ;
301
-
302
- let mut lines = reader. lines ( ) ;
303
- while let Some ( line) = lines. next_line ( ) . await . expect ( "Failed to read line from stdout" )
304
- {
305
- stdout
306
- . write_all ( format ! ( "{}\n " , line) . as_bytes ( ) )
307
- . await
308
- . expect ( "Failed to write to stdout" ) ;
309
- if line. contains ( "No response yet." ) {
310
- let _ = tx. send ( true ) . await ;
311
- break ;
312
- }
313
- }
314
-
283
+ let mut stdout =
284
+ cli_sender. stdout . take ( ) . expect ( "failed to take stdout of child process" ) ;
315
285
let timeout = tokio:: time:: Duration :: from_secs ( 35 ) ;
316
- let fallback_sent = tokio:: time:: timeout ( timeout, rx. recv ( ) ) . await ?;
286
+ let res = tokio:: time:: timeout (
287
+ timeout,
288
+ wait_for_stdout_match ( & mut stdout, |line| line. contains ( "No response yet." ) ) ,
289
+ )
290
+ . await ?;
317
291
318
292
sigint ( cli_sender) . await . expect ( "Failed to kill payjoin-cli initial sender" ) ;
319
-
320
- assert ! ( fallback_sent. unwrap_or( false ) , "Fallback send was not detected" ) ;
293
+ assert ! ( res. is_some( ) , "Fallback send was not detected" ) ;
321
294
Ok ( ( ) )
322
295
}
323
296
324
297
async fn respond_with_payjoin ( mut cli_receive_resumer : Child ) -> Result < ( ) > {
325
- let stdout =
298
+ let mut stdout =
326
299
cli_receive_resumer. stdout . take ( ) . expect ( "Failed to take stdout of child process" ) ;
327
- let reader = BufReader :: new ( stdout) ;
328
- let mut stdout = tokio:: io:: stdout ( ) ;
329
- let ( tx, mut rx) = tokio:: sync:: mpsc:: channel ( 1 ) ;
330
-
331
- let mut lines = reader. lines ( ) ;
332
- while let Some ( line) = lines. next_line ( ) . await . expect ( "Failed to read line from stdout" )
333
- {
334
- stdout
335
- . write_all ( format ! ( "{}\n " , line) . as_bytes ( ) )
336
- . await
337
- . expect ( "Failed to write to stdout" ) ;
338
- if line. contains ( "Response successful" ) {
339
- let _ = tx. send ( true ) . await ;
340
- break ;
341
- }
342
- }
343
-
344
300
let timeout = tokio:: time:: Duration :: from_secs ( 10 ) ;
345
- let response_successful = tokio:: time:: timeout ( timeout, rx. recv ( ) ) . await ?;
301
+ let res = tokio:: time:: timeout (
302
+ timeout,
303
+ wait_for_stdout_match ( & mut stdout, |line| line. contains ( "Response successful" ) ) ,
304
+ )
305
+ . await ?;
346
306
347
307
sigint ( cli_receive_resumer) . await . expect ( "Failed to kill payjoin-cli" ) ;
348
-
349
- assert ! ( response_successful. unwrap_or( false ) , "Did not respond with Payjoin PSBT" ) ;
308
+ assert ! ( res. is_some( ) , "Did not respond with Payjoin PSBT" ) ;
350
309
Ok ( ( ) )
351
310
}
352
311
353
312
async fn check_payjoin_sent ( mut cli_send_resumer : Child ) -> Result < ( ) > {
354
- let stdout =
313
+ let mut stdout =
355
314
cli_send_resumer. stdout . take ( ) . expect ( "Failed to take stdout of child process" ) ;
356
- let reader = BufReader :: new ( stdout) ;
357
- let mut stdout = tokio:: io:: stdout ( ) ;
358
- let ( tx, mut rx) = tokio:: sync:: mpsc:: channel ( 1 ) ;
315
+ let timeout = tokio:: time:: Duration :: from_secs ( 10 ) ;
316
+ let res = tokio:: time:: timeout (
317
+ timeout,
318
+ wait_for_stdout_match ( & mut stdout, |line| line. contains ( "Payjoin sent" ) ) ,
319
+ )
320
+ . await ?;
321
+
322
+ sigint ( cli_send_resumer) . await . expect ( "Failed to kill payjoin-cli" ) ;
323
+ assert ! ( res. is_some( ) , "Payjoin send was not detected" ) ;
324
+ Ok ( ( ) )
325
+ }
359
326
327
+ /// Read lines from `child_stdout` until `match_pattern` is found and the corresponding
328
+ /// line is returned.
329
+ /// Also writes every read line to tokio::io::stdout();
330
+ async fn wait_for_stdout_match < F > (
331
+ child_stdout : & mut ChildStdout ,
332
+ match_pattern : F ,
333
+ ) -> Option < String >
334
+ where
335
+ F : Fn ( & str ) -> bool ,
336
+ {
337
+ let reader = BufReader :: new ( child_stdout) ;
360
338
let mut lines = reader. lines ( ) ;
339
+ let mut res = None ;
340
+
341
+ let mut stdout = tokio:: io:: stdout ( ) ;
361
342
while let Some ( line) = lines. next_line ( ) . await . expect ( "Failed to read line from stdout" )
362
343
{
344
+ // Write all output to tests stdout
363
345
stdout
364
346
. write_all ( format ! ( "{}\n " , line) . as_bytes ( ) )
365
347
. await
366
348
. expect ( "Failed to write to stdout" ) ;
367
- if line. contains ( "Payjoin sent" ) {
368
- let _ = tx. send ( true ) . await ;
349
+
350
+ if match_pattern ( & line) {
351
+ res = Some ( line) ;
369
352
break ;
370
353
}
371
354
}
372
355
373
- let timeout = tokio:: time:: Duration :: from_secs ( 10 ) ;
374
- let payjoin_sent = tokio:: time:: timeout ( timeout, rx. recv ( ) ) . await ?;
375
-
376
- sigint ( cli_send_resumer) . await . expect ( "Failed to kill payjoin-cli" ) ;
377
-
378
- assert ! ( payjoin_sent. unwrap_or( false ) , "Payjoin send was not detected" ) ;
379
- Ok ( ( ) )
356
+ res
380
357
}
381
358
382
359
Ok ( ( ) )
0 commit comments