compiletest: show the difference between the normalized output and th… · rust-lang/rust@8aacd1c (original) (raw)

`@@ -22,7 +22,7 @@ use crate::common::{

`

22

22

`UI_STDERR, UI_STDOUT, UI_SVG, UI_WINDOWS_SVG, Ui, expected_output_path, incremental_dir,

`

23

23

` output_base_dir, output_base_name, output_testname_unique,

`

24

24

`};

`

25

``

`-

use crate::compute_diff::{write_diff, write_filtered_diff};

`

``

25

`+

use crate::compute_diff::{DiffLine, make_diff, write_diff, write_filtered_diff};

`

26

26

`use crate::errors::{self, Error, ErrorKind};

`

27

27

`use crate::header::TestProps;

`

28

28

`use crate::read2::{Truncated, read2_abbreviated};

`

`@@ -2295,17 +2295,31 @@ impl<'test> TestCx<'test> {

`

2295

2295

`match output_kind {

`

2296

2296

`TestOutput::Compile => {

`

2297

2297

`if !self.props.dont_check_compiler_stdout {

`

2298

``

`-

errors +=

`

2299

``

`-

self.compare_output(stdout_kind, &normalized_stdout, &expected_stdout);

`

``

2298

`+

errors += self.compare_output(

`

``

2299

`+

stdout_kind,

`

``

2300

`+

&normalized_stdout,

`

``

2301

`+

&proc_res.stdout,

`

``

2302

`+

&expected_stdout,

`

``

2303

`+

);

`

2300

2304

`}

`

2301

2305

`if !self.props.dont_check_compiler_stderr {

`

2302

``

`-

errors +=

`

2303

``

`-

self.compare_output(stderr_kind, &normalized_stderr, &expected_stderr);

`

``

2306

`+

errors += self.compare_output(

`

``

2307

`+

stderr_kind,

`

``

2308

`+

&normalized_stderr,

`

``

2309

`+

&stderr,

`

``

2310

`+

&expected_stderr,

`

``

2311

`+

);

`

2304

2312

`}

`

2305

2313

`}

`

2306

2314

`TestOutput::Run => {

`

2307

``

`-

errors += self.compare_output(stdout_kind, &normalized_stdout, &expected_stdout);

`

2308

``

`-

errors += self.compare_output(stderr_kind, &normalized_stderr, &expected_stderr);

`

``

2315

`+

errors += self.compare_output(

`

``

2316

`+

stdout_kind,

`

``

2317

`+

&normalized_stdout,

`

``

2318

`+

&proc_res.stdout,

`

``

2319

`+

&expected_stdout,

`

``

2320

`+

);

`

``

2321

`+

errors +=

`

``

2322

`+

self.compare_output(stderr_kind, &normalized_stderr, &stderr, &expected_stderr);

`

2309

2323

`}

`

2310

2324

`}

`

2311

2325

` errors

`

`@@ -2533,7 +2547,13 @@ impl<'test> TestCx<'test> {

`

2533

2547

`}

`

2534

2548

`}

`

2535

2549

``

2536

``

`-

fn compare_output(&self, stream: &str, actual: &str, expected: &str) -> usize {

`

``

2550

`+

fn compare_output(

`

``

2551

`+

&self,

`

``

2552

`+

stream: &str,

`

``

2553

`+

actual: &str,

`

``

2554

`+

actual_unnormalized: &str,

`

``

2555

`+

expected: &str,

`

``

2556

`+

) -> usize {

`

2537

2557

`let are_different = match (self.force_color_svg(), expected.find('\n'), actual.find('\n')) {

`

2538

2558

`// FIXME: We ignore the first line of SVG files

`

2539

2559

`// because the width parameter is non-deterministic.

`

`@@ -2590,28 +2610,14 @@ impl<'test> TestCx<'test> {

`

2590

2610

`if expected.is_empty() {

`

2591

2611

`println!("normalized {}:\n{}\n", stream, actual);

`

2592

2612

`} else {

`

2593

``

`-

println!("diff of {stream}:\n");

`

2594

``

`-

if let Some(diff_command) = self.config.diff_command.as_deref() {

`

2595

``

`-

let mut args = diff_command.split_whitespace();

`

2596

``

`-

let name = args.next().unwrap();

`

2597

``

`-

match Command::new(name)

`

2598

``

`-

.args(args)

`

2599

``

`-

.args([&expected_path, &actual_path])

`

2600

``

`-

.output()

`

2601

``

`-

{

`

2602

``

`-

Err(err) => {

`

2603

``

`-

self.fatal(&format!(

`

2604

``

`` -

"failed to call custom diff command {diff_command}: {err}"

``

2605

``

`-

));

`

2606

``

`-

}

`

2607

``

`-

Ok(output) => {

`

2608

``

`-

let output = String::from_utf8_lossy(&output.stdout);

`

2609

``

`-

print!("{output}");

`

2610

``

`-

}

`

2611

``

`-

}

`

2612

``

`-

} else {

`

2613

``

`-

print!("{}", write_diff(expected, actual, 3));

`

2614

``

`-

}

`

``

2613

`+

self.show_diff(

`

``

2614

`+

stream,

`

``

2615

`+

&expected_path,

`

``

2616

`+

&actual_path,

`

``

2617

`+

expected,

`

``

2618

`+

actual,

`

``

2619

`+

actual_unnormalized,

`

``

2620

`+

);

`

2615

2621

`}

`

2616

2622

`} else {

`

2617

2623

`// Delete non-revision .stderr/.stdout file if revisions are used.

`

`@@ -2633,6 +2639,76 @@ impl<'test> TestCx<'test> {

`

2633

2639

`if self.config.bless { 0 } else { 1 }

`

2634

2640

`}

`

2635

2641

``

``

2642

`+

/// Returns whether to show the full stderr/stdout.

`

``

2643

`+

fn show_diff(

`

``

2644

`+

&self,

`

``

2645

`+

stream: &str,

`

``

2646

`+

expected_path: &Path,

`

``

2647

`+

actual_path: &Path,

`

``

2648

`+

expected: &str,

`

``

2649

`+

actual: &str,

`

``

2650

`+

actual_unnormalized: &str,

`

``

2651

`+

) {

`

``

2652

`+

eprintln!("diff of {stream}:\n");

`

``

2653

`+

if let Some(diff_command) = self.config.diff_command.as_deref() {

`

``

2654

`+

let mut args = diff_command.split_whitespace();

`

``

2655

`+

let name = args.next().unwrap();

`

``

2656

`+

match Command::new(name).args(args).args([expected_path, actual_path]).output() {

`

``

2657

`+

Err(err) => {

`

``

2658

`+

self.fatal(&format!(

`

``

2659

`` +

"failed to call custom diff command {diff_command}: {err}"

``

``

2660

`+

));

`

``

2661

`+

}

`

``

2662

`+

Ok(output) => {

`

``

2663

`+

let output = String::from_utf8_lossy(&output.stdout);

`

``

2664

`+

eprint!("{output}");

`

``

2665

`+

}

`

``

2666

`+

}

`

``

2667

`+

} else {

`

``

2668

`+

eprint!("{}", write_diff(expected, actual, 3));

`

``

2669

`+

}

`

``

2670

+

``

2671

`` +

// NOTE: argument order is important, we need actual to be on the left so the line number match up when we compare it to actual_unnormalized below.

``

``

2672

`+

let diff_results = make_diff(actual, expected, 0);

`

``

2673

+

``

2674

`+

let (mut mismatches_normalized, mut mismatch_line_nos) = (String::new(), vec![]);

`

``

2675

`+

for hunk in diff_results {

`

``

2676

`+

let mut line_no = hunk.line_number;

`

``

2677

`+

for line in hunk.lines {

`

``

2678

`` +

// NOTE: Expected is actually correct here, the argument order is reversed so our line numbers match up

``

``

2679

`+

if let DiffLine::Expected(normalized) = line {

`

``

2680

`+

mismatches_normalized += &normalized;

`

``

2681

`+

mismatches_normalized += "\n";

`

``

2682

`+

mismatch_line_nos.push(line_no);

`

``

2683

`+

line_no += 1;

`

``

2684

`+

}

`

``

2685

`+

}

`

``

2686

`+

}

`

``

2687

`+

let mut mismatches_unnormalized = String::new();

`

``

2688

`+

let diff_normalized = make_diff(actual, actual_unnormalized, 0);

`

``

2689

`+

for hunk in diff_normalized {

`

``

2690

`+

if mismatch_line_nos.contains(&hunk.line_number) {

`

``

2691

`+

for line in hunk.lines {

`

``

2692

`+

if let DiffLine::Resulting(unnormalized) = line {

`

``

2693

`+

mismatches_unnormalized += &unnormalized;

`

``

2694

`+

mismatches_unnormalized += "\n";

`

``

2695

`+

}

`

``

2696

`+

}

`

``

2697

`+

}

`

``

2698

`+

}

`

``

2699

+

``

2700

`+

let normalized_diff = make_diff(&mismatches_normalized, &mismatches_unnormalized, 0);

`

``

2701

`+

// HACK: instead of checking if each hunk is empty, this only checks if the whole input is empty. we should be smarter about this so we don't treat added or removed output as normalized.

`

``

2702

`+

if !normalized_diff.is_empty()

`

``

2703

`+

&& !mismatches_unnormalized.is_empty()

`

``

2704

`+

&& !mismatches_normalized.is_empty()

`

``

2705

`+

{

`

``

2706

`+

eprintln!("Note: some mismatched output was normalized before being compared");

`

``

2707

`+

// FIXME: respect diff_command

`

``

2708

`+

eprint!("{}", write_diff(&mismatches_unnormalized, &mismatches_normalized, 0));

`

``

2709

`+

}

`

``

2710

`+

}

`

``

2711

+

2636

2712

`fn check_and_prune_duplicate_outputs(

`

2637

2713

`&self,

`

2638

2714

`proc_res: &ProcRes,

`