Skip to content

Panic messages sometimes eaten in tests #1066

@alexcrichton

Description

@alexcrichton

This is a problem I've been encountering in the Wasmtime repository for quite some time now and I've only just now taken the time to minimize it and debug it. The problem I'm having is that often a cargo test run will fail for one reason or another but there's no actual logs to what went wrong. Not in the failures section printed by libtest nor interspersed throughout the output of the tests. The test log is 100% clean with no panic messages, yet one of the threads panicked. The odd behavior is that running a single test prints the output of the test and panic message as expected, so it hasn't been a huge issue overall.

I reduced this down to rayon, however, showcased by this example:

use rayon::prelude::*;

#[test]
fn foo() {
    [1, 2].par_iter().for_each(|_| {
        // ..
    });
}

#[test]
fn bar() {
    [1, 2].par_iter().for_each(|i| {
        if *i % 2 == 0 {
            panic!();
        }
    });
}

Most of the time the output looks like this:

$ cargo test -q
running 2 tests
.F
failures:

---- bar stdout ----
thread '<unnamed>' panicked at 'explicit panic', src/main.rs:14:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    bar

test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

error: test failed, to rerun pass `--bin wat`

but sometimes the output looks like this:

$ cargo test -q

running 2 tests
.F
failures:

failures:
    bar

test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

error: test failed, to rerun pass `--bin wat`

In this tiny example it's nondeterministic, but in the larger context of Wasmtime at least I've found that it almost never prints panic messages in some circumstances.

My best guess as to what's going on here is that somehow the foo test steals the work of the bar test. This work then panics and rayon transmits the result back to bar, but libtest/libstd's capturing of output means that when foo succeeds it swallows all the output and nothing ends up making its way to bar. I'm not sure if there's a way to confirm that this is happening though (or whether it's something else entirely)

My guess is that rayon probably can't do much about this, but I wanted to open up an issue anyway since it's been quite perplexing to me historically as to why CI runs for example fail but there's nothing in the logs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions