Skip to content

Regression-test driver hides errors: stderr is not captured, failures appear "without a message" #3448

Description

@luwang00

Summary

When a regression test that goes through the Python driver layer fails, the actual error (Fortran fatal error, Python traceback, or shared-library load failure) is not shown anywhere the user normally looks. The test simply reports ***Failed with no diagnostic, and the per-case .log file ends mid-run with no error text. This makes these failures very hard to triage.

I hit this with py_wavetank_test1, but the defect is in the shared driver helper and affects every case routed through it (the run*DriverCase family and the C-binding Python tests).

Root cause

_runCase in reg_tests/lib/openfastDrivers.py redirects only stdout to the log file; stderr is never redirected:

def _runCase(executable, inputFile, logFile, stdout, restart=False, ExtraFlags=""):
    if logFile is None:
        command = f"{executable} {inputFile} {ExtraFlags}"
    elif restart:
        command = f"{executable} -restart {os.path.splitext(inputFile)[0]} > {logFile}"
    else:
        command = f"{executable} {inputFile} {ExtraFlags} > {logFile}"
    print(command)
    return subprocess.call(command, stdout=stdout, shell=True)

Three effects combine to make the failure look silent:

  1. stdout → log file. The > {logFile} redirect sends normal progress output into <case>.log, so nothing appears on the console.
  2. stderr is dropped. There is no 2> / 2>&1, so Python tracebacks, the ctypes "cannot find module / one of its dependencies" DLL-load error, and Fortran fatal errors raised back through the C-binding (e.g. RuntimeError: ... Fatal Error: ...) go to stderr and are written neither to the log file nor merged with stdout.
  3. ctest hides output by default. Without --output-on-failure (or -V), ctest captures the streams and only prints ***Failed, so the stderr text that would otherwise reach the console is suppressed too.

Net result: the real error exists but is split — benign stdout into the .log file and the actual error on stderr, which is discarded. The .log for py_wavetank_test1, for example, ended at Running AeroDyn. with no indication of what went wrong.

Steps to reproduce

  1. Cause any driver-based case to fail for a reason that reports on stderr, e.g. a C-binding fatal error, a missing Python dependency, or a missing/incompatible shared library.
  2. Run it via ctest: ctest -R py_wavetank_test1.
  3. Observe ***Failed with no error message; inspect <build>/.../<case>.log and note it ends mid-run with no error text.
  4. Run the driver directly capturing all streams (python <driver>.py *> out.txt, or 2>&1) to finally see the real error.

Expected behavior

The failing command's stderr should be captured into the case .log file (and/or shown by ctest on failure) so the actual error is discoverable without manually re-running the driver.

Proposed fix

Merge stderr into the redirected log in _runCase, e.g.:

    elif restart:
        command = f"{executable} -restart {os.path.splitext(inputFile)[0]} > {logFile} 2>&1"
    else:
        command = f"{executable} {inputFile} {ExtraFlags} > {logFile} 2>&1"

(Equivalently, pass stderr=subprocess.STDOUT and write to the log via the file object instead of a shell redirect.) This keeps the console clean while ensuring the .log always contains the error.

Environment

  • File: reg_tests/lib/openfastDrivers.py (_runCase)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions