@@ -7,11 +7,11 @@ use crate::{net, platform};
7
7
use anyhow:: { bail, Context , Result } ;
8
8
use regex:: bytes:: Regex ;
9
9
use serde_json:: { json, Value } ;
10
+ use std:: env;
10
11
use std:: ffi:: OsString ;
11
12
use std:: io:: { BufRead , BufReader , Read , Write } ;
12
13
use std:: path:: { Path , PathBuf } ;
13
14
use std:: process:: { Child , Command , Stdio } ;
14
- use std:: { env, thread} ;
15
15
use tempfile:: TempDir ;
16
16
17
17
#[ derive( Clone , Copy , Debug ) ]
@@ -281,35 +281,22 @@ impl Io {
281
281
}
282
282
}
283
283
284
- fn echo_filtered_stdout ( mut child_io : Io ) {
284
+ fn process_qemu_io ( mut monitor_io : Io , mut serial_io : Io , tmp_dir : & Path ) -> Result < ( ) > {
285
285
// This regex is used to detect and strip ANSI escape codes. These
286
286
// escapes are added by the console output protocol when writing to
287
287
// the serial device.
288
288
let ansi_escape = Regex :: new ( r"(\x9b|\x1b\[)[0-?]*[ -/]*[@-~]" ) . expect ( "invalid regex" ) ;
289
289
290
- while let Ok ( line) = child_io. read_line ( ) {
291
- let line = line. trim ( ) ;
292
- let stripped = ansi_escape. replace_all ( line. as_bytes ( ) , & b"" [ ..] ) ;
293
- let stripped = String :: from_utf8 ( stripped. into ( ) ) . expect ( "line is not utf8" ) ;
294
-
295
- // Print out the processed QEMU output for logging & inspection.
296
- println ! ( "{stripped}" ) ;
297
- }
298
- }
299
-
300
- fn process_qemu_io ( mut monitor_io : Io , mut serial_io : Io , tmp_dir : & Path ) -> Result < ( ) > {
301
290
// Execute the QEMU monitor handshake, doing basic sanity checks.
302
291
assert ! ( monitor_io. read_line( ) ?. starts_with( r#"{"QMP":"# ) ) ;
303
292
monitor_io. write_json ( json ! ( { "execute" : "qmp_capabilities" } ) ) ?;
304
293
assert_eq ! ( monitor_io. read_json( ) ?, json!( { "return" : { } } ) ) ;
305
294
306
295
while let Ok ( line) = serial_io. read_line ( ) {
307
- // Strip whitespace from the end. No need to strip ANSI escape
308
- // codes like in the stdout, because those escape codes are
309
- // inserted by the console output protocol, whereas the
310
- // "SCREENSHOT" line we are interested in is written via the
311
- // serial protocol.
296
+ // Strip whitespace and ANSI escape codes.
312
297
let line = line. trim_end ( ) ;
298
+ let line = ansi_escape. replace_all ( line. as_bytes ( ) , & b"" [ ..] ) ;
299
+ let line = String :: from_utf8 ( line. into ( ) ) . expect ( "line is not utf8" ) ;
313
300
314
301
// If the app requests a screenshot, take it.
315
302
if let Some ( reference_name) = line. strip_prefix ( "SCREENSHOT: " ) {
@@ -343,6 +330,8 @@ fn process_qemu_io(mut monitor_io: Io, mut serial_io: Io, tmp_dir: &Path) -> Res
343
330
expected == actual,
344
331
"screenshot does not match reference image"
345
332
)
333
+ } else {
334
+ println ! ( "{line}" ) ;
346
335
}
347
336
}
348
337
@@ -510,16 +499,10 @@ pub fn run_qemu(arch: UefiArch, opt: &QemuOpt) -> Result<()> {
510
499
cmd. arg ( drive_arg) ;
511
500
512
501
let qemu_monitor_pipe = Pipe :: new ( tmp_dir, "qemu-monitor" ) ?;
513
- let serial_pipe = Pipe :: new ( tmp_dir, "serial" ) ?;
514
-
515
- // Open two serial devices. The first one is connected to the host's
516
- // stdout, and serves to just transport logs. The second one is
517
- // connected to a pipe, and used to receive the SCREENSHOT command
518
- // and send the response. That second will also receive logs up
519
- // until the test runner opens the handle in exclusive mode, but we
520
- // can just read and ignore those lines.
502
+
503
+ // Open a serial device connected to stdio. This is used for
504
+ // printing logs and to receive and reply to commands.
521
505
cmd. args ( [ "-serial" , "stdio" ] ) ;
522
- cmd. args ( [ "-serial" , serial_pipe. qemu_arg ( ) ] ) ;
523
506
524
507
// Map the QEMU monitor to a pair of named pipes
525
508
cmd. args ( [ "-qmp" , qemu_monitor_pipe. qemu_arg ( ) ] ) ;
@@ -543,21 +526,16 @@ pub fn run_qemu(arch: UefiArch, opt: &QemuOpt) -> Result<()> {
543
526
let mut child = ChildWrapper ( cmd. spawn ( ) . context ( "failed to launch qemu" ) ?) ;
544
527
545
528
let monitor_io = qemu_monitor_pipe. open_io ( ) ?;
546
- let serial_io = serial_pipe. open_io ( ) ?;
547
529
let child_io = Io :: new (
548
530
child. 0 . stdout . take ( ) . unwrap ( ) ,
549
531
child. 0 . stdin . take ( ) . unwrap ( ) ,
550
532
) ;
551
533
552
- // Start a thread to process stdout from the child.
553
- let stdout_thread = thread:: spawn ( || echo_filtered_stdout ( child_io) ) ;
554
-
555
534
// Capture the result to check it, but first wait for the child to
556
535
// exit.
557
- let res = process_qemu_io ( monitor_io, serial_io , tmp_dir) ;
536
+ let res = process_qemu_io ( monitor_io, child_io , tmp_dir) ;
558
537
let status = child. 0 . wait ( ) ?;
559
538
560
- stdout_thread. join ( ) . expect ( "stdout thread panicked" ) ;
561
539
if let Some ( echo_service) = echo_service {
562
540
echo_service. stop ( ) ;
563
541
}
0 commit comments