From 250ec2a9f66fa7eedae6d8dfe34c7b3edc92ce2b Mon Sep 17 00:00:00 2001 From: Augie Fackler Date: Thu, 12 May 2022 11:38:10 -0400 Subject: [PATCH] compiletest: never truncate stderr if we'll use it as json I started observing some strange failures in larger ui tests that were caused by environmental conditions (probably paths?) pushing the stderr size over the truncation limit, causing the tests to fail because the ui output wasn't valid json due to the truncation marker. Since that seems like a circumstance we never want, just never truncate output that we'll interpret as json output. --- src/tools/compiletest/src/read2.rs | 23 +++++++++++++++++++++-- src/tools/compiletest/src/runtest.rs | 7 +++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/tools/compiletest/src/read2.rs b/src/tools/compiletest/src/read2.rs index 897b9dd400793..d26678ecbeb0d 100644 --- a/src/tools/compiletest/src/read2.rs +++ b/src/tools/compiletest/src/read2.rs @@ -5,7 +5,7 @@ pub use self::imp::read2; use std::io; use std::process::{Child, Output}; -pub fn read2_abbreviated(mut child: Child) -> io::Result { +pub fn read2_abbreviated(mut child: Child, allow_stderr_truncation: bool) -> io::Result { use io::Write; use std::mem::replace; @@ -45,6 +45,17 @@ pub fn read2_abbreviated(mut child: Child) -> io::Result { *self = new_self; } + fn extend_no_truncate(&mut self, data: &[u8]) { + match *self { + ProcOutput::Full(ref mut bytes) => { + bytes.extend_from_slice(data); + } + ProcOutput::Abbreviated { .. } => { + panic!("must not use extend_no_truncate on abbreviated output") + } + }; + } + fn into_bytes(self) -> Vec { match self { ProcOutput::Full(bytes) => bytes, @@ -65,7 +76,15 @@ pub fn read2_abbreviated(mut child: Child) -> io::Result { child.stdout.take().unwrap(), child.stderr.take().unwrap(), &mut |is_stdout, data, _| { - if is_stdout { &mut stdout } else { &mut stderr }.extend(data); + if is_stdout { + stdout.extend(data); + } else { + if allow_stderr_truncation { + stderr.extend(data); + } else { + stderr.extend_no_truncate(data); + } + } data.clear(); }, )?; diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index a59a0584d5e99..aebe43ec0b3c7 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1769,8 +1769,10 @@ impl<'test> TestCx<'test> { child.stdin.as_mut().unwrap().write_all(input.as_bytes()).unwrap(); } + // For Ui tests we parse the stderr as json, which breaks if the output gets truncated. + let allow_truncation = self.config.mode != Ui; let Output { status, stdout, stderr } = - read2_abbreviated(child).expect("failed to read output"); + read2_abbreviated(child, allow_truncation).expect("failed to read output"); let result = ProcRes { status, @@ -2959,7 +2961,8 @@ impl<'test> TestCx<'test> { } } - let output = cmd.spawn().and_then(read2_abbreviated).expect("failed to spawn `make`"); + let output = + cmd.spawn().and_then(|c| read2_abbreviated(c, true)).expect("failed to spawn `make`"); if !output.status.success() { let res = ProcRes { status: output.status,