elm-explorations / test

Write unit and fuzz tests for Elm code.
https://package.elm-lang.org/packages/elm-explorations/test/latest
BSD 3-Clause "New" or "Revised" License
237 stars 39 forks source link

JUnit output incomplete, truncated at ^2kB boundary #138

Open allenap opened 4 years ago

allenap commented 4 years ago

Running elm-test and redirecting to a file works as expected:

$ elm-test --report=junit > foo.xml
$ ls -l foo.xml
.rw-r--r-- gavin staff 789.9 KB Fri May 22 13:28:05 2020 foo.xml
                       ^^^^^^^^

Piping via another process results in a truncated output file:

$ elm-test --report=junit | cat > foo.xml
$ ls -l foo.xml
.rw-r--r-- gavin staff 64 KB Fri May 22 13:23:39 2020 foo.xml
                       ^^^^^

Observed on macOS (truncates at 64kB) and Linux (truncates at 128kB).

Just a guess, but I suspect there's a missing flush somewhere.

$ elm-test --version
0.19.1-revision3
harrysarson commented 4 years ago

I would expect that everything is flushed when the procress exits even if we forget to flush when we should?

allenap commented 4 years ago

There's some discussion of a similar bug here – and the root cause seems to be that Node does not flush process.stdout before exiting.

harrysarson commented 4 years ago

Ouch that is nasty paper cut in node. Here is a list of all the places the test-runner exits:

https://github.com/rtfeldman/node-test-runner/search?q=%22process.exit%22&unscoped_q=%22process.exit%22

PR that addsprocess.[stdout|stderr].flush() before each welcome!

harrysarson commented 4 years ago

Or there is the following recomendation here https://github.com/nodejs/node/issues/6456


[process.stdout, process.stderr].forEach((s) => {
  s && s.isTTY && s._handle && s._handle.setBlocking &&
    s._handle.setBlocking(true)
})
allenap commented 4 years ago
[process.stdout, process.stderr].forEach((s) => {
  s && s.isTTY && s._handle && s._handle.setBlocking &&
  ...

Interesting that this checks for a TTY. This is what the set-blocking package does too, which is mentioned in node-test-runner's package-lock.json – though I can't find any uses of it.

Anyway, this issue is about behavior when writing to a pipe, not an interactive terminal, so I don't think that code snippet as is, or the set-blocking package, would resolve this bug.

One possible solution might be to call process.stdout._handle.setBlocking(true) regardless of whether we're connected to a TTY or not. The set-blocking package used to do this but changed its mind. The comments linked from there and other reading about this I've done lead me to believe that this situation in Node.js is a minefield, and far from resolved.

If calling setBlocking(true) regardless of TTY works, I suspect that might be a good solution right now for node-test-runner, on the basis that it's simple, not invasive, and easy to revert.

(Aside: should I refile this issue against node-test-runner? I always forget about the split between this package and that.)