compiletest: only truncate at the end, to make it more clearly visible
This commit is contained in:
parent
38bbc2ce03
commit
ef46066271
@ -27,8 +27,7 @@ pub fn read2_abbreviated(mut child: Child, filter_paths_from_len: &[String]) ->
|
|||||||
Ok(Output { status, stdout: stdout.into_bytes(), stderr: stderr.into_bytes() })
|
Ok(Output { status, stdout: stdout.into_bytes(), stderr: stderr.into_bytes() })
|
||||||
}
|
}
|
||||||
|
|
||||||
const HEAD_LEN: usize = 160 * 1024;
|
const MAX_OUT_LEN: usize = 512 * 1024;
|
||||||
const TAIL_LEN: usize = 256 * 1024;
|
|
||||||
|
|
||||||
// Whenever a path is filtered when counting the length of the output, we need to add some
|
// Whenever a path is filtered when counting the length of the output, we need to add some
|
||||||
// placeholder length to ensure a compiler emitting only filtered paths doesn't cause a OOM.
|
// placeholder length to ensure a compiler emitting only filtered paths doesn't cause a OOM.
|
||||||
@ -39,7 +38,7 @@ pub fn read2_abbreviated(mut child: Child, filter_paths_from_len: &[String]) ->
|
|||||||
|
|
||||||
enum ProcOutput {
|
enum ProcOutput {
|
||||||
Full { bytes: Vec<u8>, filtered_len: usize },
|
Full { bytes: Vec<u8>, filtered_len: usize },
|
||||||
Abbreviated { head: Vec<u8>, skipped: usize, tail: Box<[u8]> },
|
Abbreviated { head: Vec<u8>, skipped: usize },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProcOutput {
|
impl ProcOutput {
|
||||||
@ -83,24 +82,21 @@ fn extend(&mut self, data: &[u8], filter_paths_from_len: &[String]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let new_len = bytes.len();
|
let new_len = bytes.len();
|
||||||
if (*filtered_len).min(new_len) <= HEAD_LEN + TAIL_LEN {
|
if (*filtered_len).min(new_len) <= MAX_OUT_LEN {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut head = replace(bytes, Vec::new());
|
let mut head = replace(bytes, Vec::new());
|
||||||
let mut middle = head.split_off(HEAD_LEN);
|
// Don't truncate if this as a whole line.
|
||||||
let tail = middle.split_off(middle.len() - TAIL_LEN).into_boxed_slice();
|
// That should make it less likely that we cut a JSON line in half.
|
||||||
let skipped = new_len - HEAD_LEN - TAIL_LEN;
|
if head.last() != Some(&('\n' as u8)) {
|
||||||
ProcOutput::Abbreviated { head, skipped, tail }
|
head.truncate(MAX_OUT_LEN);
|
||||||
}
|
|
||||||
ProcOutput::Abbreviated { ref mut skipped, ref mut tail, .. } => {
|
|
||||||
*skipped += data.len();
|
|
||||||
if data.len() <= TAIL_LEN {
|
|
||||||
tail[..data.len()].copy_from_slice(data);
|
|
||||||
tail.rotate_left(data.len());
|
|
||||||
} else {
|
|
||||||
tail.copy_from_slice(&data[(data.len() - TAIL_LEN)..]);
|
|
||||||
}
|
}
|
||||||
|
let skipped = new_len - head.len();
|
||||||
|
ProcOutput::Abbreviated { head, skipped }
|
||||||
|
}
|
||||||
|
ProcOutput::Abbreviated { ref mut skipped, .. } => {
|
||||||
|
*skipped += data.len();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -110,18 +106,12 @@ fn extend(&mut self, data: &[u8], filter_paths_from_len: &[String]) {
|
|||||||
fn into_bytes(self) -> Vec<u8> {
|
fn into_bytes(self) -> Vec<u8> {
|
||||||
match self {
|
match self {
|
||||||
ProcOutput::Full { bytes, .. } => bytes,
|
ProcOutput::Full { bytes, .. } => bytes,
|
||||||
ProcOutput::Abbreviated { mut head, mut skipped, tail } => {
|
ProcOutput::Abbreviated { mut head, skipped } => {
|
||||||
let mut tail = &*tail;
|
let head_note =
|
||||||
|
format!("<<<<<< TRUNCATED, SHOWING THE FIRST {} BYTES >>>>>>\n\n", head.len());
|
||||||
// Skip over '{' at the start of the tail, so we don't later wrongfully consider this as json.
|
head.splice(0..0, head_note.into_bytes());
|
||||||
// See <https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/Weird.20CI.20failure/near/321797811>
|
write!(&mut head, "\n\n<<<<<< TRUNCATED, DROPPED {} BYTES >>>>>>", skipped)
|
||||||
while tail.get(0) == Some(&b'{') {
|
.unwrap();
|
||||||
tail = &tail[1..];
|
|
||||||
skipped += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
write!(&mut head, "\n\n<<<<<< SKIPPED {} BYTES >>>>>>\n\n", skipped).unwrap();
|
|
||||||
head.extend_from_slice(tail);
|
|
||||||
head
|
head
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
use crate::read2::{ProcOutput, FILTERED_PATHS_PLACEHOLDER_LEN, HEAD_LEN, TAIL_LEN};
|
use std::io::Write;
|
||||||
|
|
||||||
|
use crate::read2::{ProcOutput, FILTERED_PATHS_PLACEHOLDER_LEN, MAX_OUT_LEN};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_abbreviate_short_string() {
|
fn test_abbreviate_short_string() {
|
||||||
@ -21,35 +23,13 @@ fn test_abbreviate_short_string_multiple_steps() {
|
|||||||
fn test_abbreviate_long_string() {
|
fn test_abbreviate_long_string() {
|
||||||
let mut out = ProcOutput::new();
|
let mut out = ProcOutput::new();
|
||||||
|
|
||||||
let data = vec![b'.'; HEAD_LEN + TAIL_LEN + 16];
|
let data = vec![b'.'; MAX_OUT_LEN + 16];
|
||||||
out.extend(&data, &[]);
|
out.extend(&data, &[]);
|
||||||
|
|
||||||
let mut expected = vec![b'.'; HEAD_LEN];
|
let mut expected = Vec::new();
|
||||||
expected.extend_from_slice(b"\n\n<<<<<< SKIPPED 16 BYTES >>>>>>\n\n");
|
write!(expected, "<<<<<< TRUNCATED, SHOWING THE FIRST {MAX_OUT_LEN} BYTES >>>>>>\n\n").unwrap();
|
||||||
expected.extend_from_slice(&vec![b'.'; TAIL_LEN]);
|
expected.extend_from_slice(&[b'.'; MAX_OUT_LEN]);
|
||||||
|
expected.extend_from_slice(b"\n\n<<<<<< TRUNCATED, DROPPED 16 BYTES >>>>>>");
|
||||||
// We first check the length to avoid endless terminal output if the length differs, since
|
|
||||||
// `out` is hundreds of KBs in size.
|
|
||||||
let out = out.into_bytes();
|
|
||||||
assert_eq!(expected.len(), out.len());
|
|
||||||
assert_eq!(expected, out);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_abbreviate_long_string_multiple_steps() {
|
|
||||||
let mut out = ProcOutput::new();
|
|
||||||
|
|
||||||
out.extend(&vec![b'.'; HEAD_LEN], &[]);
|
|
||||||
out.extend(&vec![b'.'; TAIL_LEN], &[]);
|
|
||||||
// Also test whether the rotation works
|
|
||||||
out.extend(&vec![b'!'; 16], &[]);
|
|
||||||
out.extend(&vec![b'?'; 16], &[]);
|
|
||||||
|
|
||||||
let mut expected = vec![b'.'; HEAD_LEN];
|
|
||||||
expected.extend_from_slice(b"\n\n<<<<<< SKIPPED 32 BYTES >>>>>>\n\n");
|
|
||||||
expected.extend_from_slice(&vec![b'.'; TAIL_LEN - 32]);
|
|
||||||
expected.extend_from_slice(&vec![b'!'; 16]);
|
|
||||||
expected.extend_from_slice(&vec![b'?'; 16]);
|
|
||||||
|
|
||||||
// We first check the length to avoid endless terminal output if the length differs, since
|
// We first check the length to avoid endless terminal output if the length differs, since
|
||||||
// `out` is hundreds of KBs in size.
|
// `out` is hundreds of KBs in size.
|
||||||
@ -86,9 +66,8 @@ fn test_abbreviate_filters_avoid_abbreviations() {
|
|||||||
let mut out = ProcOutput::new();
|
let mut out = ProcOutput::new();
|
||||||
let filters = &[std::iter::repeat('a').take(64).collect::<String>()];
|
let filters = &[std::iter::repeat('a').take(64).collect::<String>()];
|
||||||
|
|
||||||
let mut expected = vec![b'.'; HEAD_LEN - FILTERED_PATHS_PLACEHOLDER_LEN as usize];
|
let mut expected = vec![b'.'; MAX_OUT_LEN - FILTERED_PATHS_PLACEHOLDER_LEN as usize];
|
||||||
expected.extend_from_slice(filters[0].as_bytes());
|
expected.extend_from_slice(filters[0].as_bytes());
|
||||||
expected.extend_from_slice(&vec![b'.'; TAIL_LEN]);
|
|
||||||
|
|
||||||
out.extend(&expected, filters);
|
out.extend(&expected, filters);
|
||||||
|
|
||||||
@ -104,14 +83,13 @@ fn test_abbreviate_filters_can_still_cause_abbreviations() {
|
|||||||
let mut out = ProcOutput::new();
|
let mut out = ProcOutput::new();
|
||||||
let filters = &[std::iter::repeat('a').take(64).collect::<String>()];
|
let filters = &[std::iter::repeat('a').take(64).collect::<String>()];
|
||||||
|
|
||||||
let mut input = vec![b'.'; HEAD_LEN];
|
let mut input = vec![b'.'; MAX_OUT_LEN];
|
||||||
input.extend_from_slice(&vec![b'.'; TAIL_LEN]);
|
|
||||||
input.extend_from_slice(filters[0].as_bytes());
|
input.extend_from_slice(filters[0].as_bytes());
|
||||||
|
|
||||||
let mut expected = vec![b'.'; HEAD_LEN];
|
let mut expected = Vec::new();
|
||||||
expected.extend_from_slice(b"\n\n<<<<<< SKIPPED 64 BYTES >>>>>>\n\n");
|
write!(expected, "<<<<<< TRUNCATED, SHOWING THE FIRST {MAX_OUT_LEN} BYTES >>>>>>\n\n").unwrap();
|
||||||
expected.extend_from_slice(&vec![b'.'; TAIL_LEN - 64]);
|
expected.extend_from_slice(&[b'.'; MAX_OUT_LEN]);
|
||||||
expected.extend_from_slice(&vec![b'a'; 64]);
|
expected.extend_from_slice(b"\n\n<<<<<< TRUNCATED, DROPPED 64 BYTES >>>>>>");
|
||||||
|
|
||||||
out.extend(&input, filters);
|
out.extend(&input, filters);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user