Swallowing of input in FileCheck

Hi,

Debugging tests which make use of FileCheck can be a frustrating experience, as all input will be swallowed (even with -v flag passed to lit),
and one would often need to copy-and-paste and rerun the failing command manually without piping into FileCheck.
Initially I’ve assumed that this is done due to stream processing, but looking at FileCheck source code I can see that
it actually gets the entire input into RAM anyway:

  do {
    Buffer.reserve(Buffer.size() + ChunkSize);
    ReadBytes = read(FD, Buffer.end(), ChunkSize);
    if (ReadBytes == -1) {
      if (errno == EINTR) continue;
      return std::error_code(errno, std::generic_category());
    }
    Buffer.set_size(Buffer.size() + ReadBytes);
  } while (ReadBytes != 0);

Thus, I propose modifying FileCheck default behavior to dump all swallowed output on stderr when the test has failed.
Would there be any objections to such a change?
I understand the concern that log files might become unnecessarily large, but since it would only be done for failed
test I think the added readability would be worth it.

Regards,
George

Thus, I propose modifying FileCheck default behavior to dump all swallowed
output on stderr when the test has failed.
Would there be any objections to such a change?

Yes.

I understand the concern that log files might become unnecessarily large,
but since it would only be done for failed
test I think the added readability would be worth it.

I disagree, it would be too much output. During development, it's pretty
common to cause tens of tests to fail. I don't really want 10 entire
assembly files dumped into my console during incremental development. Our
test output is already long, and I wish it were shorter.

I agree that this is a real problem when remote buildbots in different
configurations get involved. Locally debugging FileCheck failures is easy,
you just copy-paste the command like you said and pipe it to less. It's
only a pain when you aren't sure if a failure on a bot will reproduce
locally. So, I would be in favor of an option to lit that we enable on
buildslaves that dumps the output. We already have a '\bFileCheck\b'
substitution in lit. We'd just expand it to 'FileCheck --dump-on-failure'
or something on bots.

Could this be solved by having lit be intelligent about showing less output when there are large numbers of test failures (w/o other output), and truncating very large outputs?

I do think there are situations where having the output just show up by default locally could prevent needing to rerun a command, which is handy.

This sounds reasonable to me, no matter what on the above question.

  • Daniel

What about having an environment variable FILECHECKER_VERBOSE=1?
This would not require substitutions, and could be even set automatically by “lit” when launched with “-v”.
At least to me that would make debugging tests much easier.

Ideally/the better integration with Buildbot would be to have these outputs referenced as “associated files” (it’s been a while since I played with buildbot - I remember finding this and considering how it could be done, but not getting all the way through) so they’d come back as actual files on the build master, linked from the results page that you could click on to view/download.

(similarly in the local output, having these files written to disk and the name of the file mentioned in the output would seem nice to me - some tests use the %t, etc, to create temporary files and you can see their names in the output, but some stream directly - it’d be great if the direct streaming still allowed the user to inspect the files along pipe chain)

(aside: I’d love it if lit would tell me /which/ of the RUN commands it was running when it failed, or which one the output came from (in the case of a single RUN line having multiple commands… ) somehow - would simplify things a bit too)

FYI, I had a diff. https://reviews.llvm.org/D20105
I am not interested to it atm, though.

Ideally/the better integration with Buildbot would be to have these outputs referenced as “associated files” (it’s been a while since I played with buildbot - I remember finding this and considering how it could be done, but not getting all the way through) so they’d come back as actual files on the build master, linked from the results page that you could click on to view/download.

(similarly in the local output, having these files written to disk and the name of the file mentioned in the output would seem nice to me - some tests use the %t, etc, to create temporary files and you can see their names in the output, but some stream directly - it’d be great if the direct streaming still allowed the user to inspect the files along pipe chain)

(aside: I’d love it if lit would tell me /which/ of the RUN commands it was running when it failed, or which one the output came from (in the case of a single RUN line having multiple commands… ) somehow - would simplify things a bit too)

It actually will already do this if LLVM switched to the “internal test runner” (as opposed to the mode which runs the entire thing as one bash script).

  • Daniel

Ideally/the better integration with Buildbot would be to have these outputs referenced as “associated files” (it’s been a while since I played with buildbot - I remember finding this and considering how it could be done, but not getting all the way through) so they’d come back as actual files on the build master, linked from the results page that you could click on to view/download.

(similarly in the local output, having these files written to disk and the name of the file mentioned in the output would seem nice to me - some tests use the %t, etc, to create temporary files and you can see their names in the output, but some stream directly - it’d be great if the direct streaming still allowed the user to inspect the files along pipe chain)

(aside: I’d love it if lit would tell me /which/ of the RUN commands it was running when it failed, or which one the output came from (in the case of a single RUN line having multiple commands… ) somehow - would simplify things a bit too)

It actually will already do this if LLVM switched to the “internal test runner” (as opposed to the mode which runs the entire thing as one bash script).

Is that the default on windows/platforms that might not have bash?

Is there a CMake flag/config for it?

Ideally/the better integration with Buildbot would be to have these outputs referenced as “associated files” (it’s been a while since I played with buildbot - I remember finding this and considering how it could be done, but not getting all the way through) so they’d come back as actual files on the build master, linked from the results page that you could click on to view/download.

(similarly in the local output, having these files written to disk and the name of the file mentioned in the output would seem nice to me - some tests use the %t, etc, to create temporary files and you can see their names in the output, but some stream directly - it’d be great if the direct streaming still allowed the user to inspect the files along pipe chain)

(aside: I’d love it if lit would tell me /which/ of the RUN commands it was running when it failed, or which one the output came from (in the case of a single RUN line having multiple commands… ) somehow - would simplify things a bit too)

It actually will already do this if LLVM switched to the “internal test runner” (as opposed to the mode which runs the entire thing as one bash script).

Is that the default on windows/platforms that might not have bash?

Yup.

Is there a CMake flag/config for it?

It looks like there is an env var for it (from LLVM’s lit.cfg):


# Choose between lit's internal shell pipeline runner and a real shell. If
# LIT_USE_INTERNAL_SHELL is in the environment, we use that as an override.
use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL")
if use_lit_shell:
# 0 is external, "" is default, and everything else is internal.
execute_external = (use_lit_shell == "0")
else:
# Otherwise we default to internal on Windows and external elsewhere, as
# bash on Windows is usually very slow.
execute_external = (not sys.platform in ['win32'])
  • Daniel

Copy-pasting a run line to debug a failure is trivial… when you know which line to copy/paste!
To be the frustration has rather been that lit does not say which of the command fails when there are multiple run lines in a test.

Oh I didn't read all the thread (gmail always confuses me). Thanks Daniel
this seems to be exactly what I was looking for!

Copy-pasting a run line to debug a failure is trivial… when you know which line to copy/paste!
To be the frustration has rather been that lit does not say which of the command fails when there are multiple run lines in a test.

Somewhat orthogonally to the current discussion I’ve submitted https://reviews.llvm.org/D35330 which aims to solve this issue.
[though the patch can of course can be improved]