Skip to content

spp test / test_single_module.sh: a failing run prints no TEST RESULTS block and ./spp t exits 0 #528

Description

@gonzalesedwin1123

Found while running the negative control for #383 / PR #525 (reverting the fix, expecting red): ./spp t spp_base_common exited 0 and printed nothing after "Running tests (this may take a few minutes)...", while the log said 1 failed, 1 error(s) of 10 tests. The CLAUDE.md pitfall "./spp t can exit 0 even when the run failed; read the log" describes the symptom; this is the mechanism.

Mechanism (three separate defects, scripts/test_single_module.sh + spp)

  1. set -e aborts the script before the results are parsed. The script runs under set -e (line 21). run_tests_docker() correctly wraps docker compose run in set +e / set -e, captures TEST_EXIT_CODE and returns it (lines 193-217; run_tests_local() does the same). But the call site is a bare statement:

    if [ "$MODE" = "docker" ]; then
        run_tests_docker        # line 514: non-zero return under set -e => script exits here
    else
        run_tests_local
    fi
    parse_and_display_results   # line 520: never reached when odoo-bin exited non-zero
    exit $?

    odoo-bin exits non-zero whenever a test fails or the registry fails to load, so exactly the runs that matter skip parse_and_display_results: no TEST RESULTS header, no result line, no --- Test failures --- excerpt, no CRITICAL: line. A green run prints the block; a red run prints nothing. (The test DB cleanup inside the function still runs because it precedes the return.)

  2. parse_and_display_results never returns non-zero. Its last statement is echo "", so exit $? at line 521 is always exit 0, even when it just printed Failed: 2 or CRITICAL: ... Failed to load registry. The odoo-bin exit code captured in step 1 is never propagated.

  3. spp discards the script's status. spp (cmd_test, ~line 363) calls run(cmd, check=False) and does not sys.exit with the returned code, so ./spp t is exit 0 regardless of what the script did.

Net effect: CI is unaffected (the workflow greps the log's N failed, M error(s) line itself), but every local/agent run has to open /tmp/openspp-test-logs/<module>_unittest_*.log and grep odoo.tests.result to learn the verdict, and any tooling that trusts the exit code (subagents, scripts, && chains) sees success on failure.

Proposed fix

  • Call the runner under set +e (or if ! run_tests_docker; then ...; fi, or run_tests_docker || TEST_EXIT_CODE=$?) so the script always reaches parse_and_display_results.
  • Make parse_and_display_results return 1 when FAILED > 0, TEST_ERRORS > 0, CRITICAL_ERROR is set, or no result line was found at all (the "No tests were executed" branch), and return 0 otherwise; exit with that.
  • In spp, sys.exit(run(cmd, check=False).returncode) so ./spp t mirrors the script.
  • Optional: when the result line is missing but the log exists, print the last 20 log lines so the failure is visible without opening the file.

Repro

Any module with a failing test: e.g. on a branch where a test asserts something false, run ./spp t <module>; observe exit 0 and no TEST RESULTS block; grep odoo.tests.result /tmp/openspp-test-logs/<module>_unittest_*.log | tail -1 shows the failures. Logs from the #525 negative control: /tmp/openspp-test-logs/spp_base_common_unittest_20260918_103209.log (local machine).

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

    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