From fab5c812f31627ea5d57d5710cd3ccbd73244a2b Mon Sep 17 00:00:00 2001
From: Andrew Gallant <jamslam@gmail.com>
Date: Wed, 19 Feb 2020 07:28:08 -0500
Subject: [PATCH] tests: add debugging output

The transient failures appear to be persisting and they are quite
difficult to debug. So include a full directory listing in the output of
every test failure.
---
 Cargo.lock    |  1 +
 Cargo.toml    |  1 +
 tests/util.rs | 30 +++++++++++++++++++++++++++---
 3 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 3c6dacb9..1367b859 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -406,6 +406,7 @@ dependencies = [
  "serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
  "termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
diff --git a/Cargo.toml b/Cargo.toml
index 02e9724a..0fefcfab 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -75,6 +75,7 @@ features = ["suggestions"]
 [dev-dependencies]
 serde = "1.0.77"
 serde_derive = "1.0.77"
+walkdir = "2"
 
 [features]
 simd-accel = ["grep/simd-accel"]
diff --git a/tests/util.rs b/tests/util.rs
index 9256ca33..75fe92c1 100644
--- a/tests/util.rs
+++ b/tests/util.rs
@@ -337,11 +337,13 @@ impl TestCommand {
                 "\n\n===== {:?} =====\n\
                  command succeeded but expected failure!\
                  \n\ncwd: {}\
+                 \n\ndir list: {:?}\
                  \n\nstatus: {}\
                  \n\nstdout: {}\n\nstderr: {}\
                  \n\n=====\n",
                 self.cmd,
                 self.dir.dir.display(),
+                dir_list(&self.dir.dir),
                 o.status,
                 String::from_utf8_lossy(&o.stdout),
                 String::from_utf8_lossy(&o.stderr)
@@ -354,13 +356,20 @@ impl TestCommand {
     pub fn assert_exit_code(&mut self, expected_code: i32) {
         let code = self.cmd.output().unwrap().status.code().unwrap();
         assert_eq!(
-            expected_code, code,
+            expected_code,
+            code,
             "\n\n===== {:?} =====\n\
              expected exit code did not match\
+             \n\ncwd: {}\
+             \n\ndir list: {:?}\
              \n\nexpected: {}\
              \n\nfound: {}\
              \n\n=====\n",
-            self.cmd, expected_code, code
+            self.cmd,
+            self.dir.dir.display(),
+            dir_list(&self.dir.dir),
+            expected_code,
+            code
         );
     }
 
@@ -372,11 +381,13 @@ impl TestCommand {
                 "\n\n===== {:?} =====\n\
                  command succeeded but expected failure!\
                  \n\ncwd: {}\
+                 \n\ndir list: {:?}\
                  \n\nstatus: {}\
                  \n\nstdout: {}\n\nstderr: {}\
                  \n\n=====\n",
                 self.cmd,
                 self.dir.dir.display(),
+                dir_list(&self.dir.dir),
                 o.status,
                 String::from_utf8_lossy(&o.stdout),
                 String::from_utf8_lossy(&o.stderr)
@@ -397,7 +408,8 @@ impl TestCommand {
                     command failed but expected success!\
                     {}\
                     \n\ncommand: {:?}\
-                    \ncwd: {}\
+                    \n\ncwd: {}\
+                    \n\ndir list: {:?}\
                     \n\nstatus: {}\
                     \n\nstdout: {}\
                     \n\nstderr: {}\
@@ -405,6 +417,7 @@ impl TestCommand {
                 suggest,
                 self.cmd,
                 self.dir.dir.display(),
+                dir_list(&self.dir.dir),
                 o.status,
                 String::from_utf8_lossy(&o.stdout),
                 String::from_utf8_lossy(&o.stderr)
@@ -434,6 +447,17 @@ fn repeat<F: FnMut() -> io::Result<()>>(mut f: F) -> io::Result<()> {
     Err(last_err.unwrap())
 }
 
+/// Return a recursive listing of all files and directories in the given
+/// directory. This is useful for debugging transient and odd failures in
+/// integration tests.
+fn dir_list<P: AsRef<Path>>(dir: P) -> Vec<String> {
+    walkdir::WalkDir::new(dir)
+        .follow_links(true)
+        .into_iter()
+        .map(|result| result.unwrap().path().to_string_lossy().into_owned())
+        .collect()
+}
+
 /// When running tests with cross, we need to be a bit smarter about how we
 /// run our `rg` binary. We can't just run it directly since it might be
 /// compiled for a totally different target. Instead, it's likely that `cross`