Skip to content

Framework tests / test validators now return exit codes (-1) when failures are detected#9

Merged
ethan-thompson merged 1 commit intomainfrom
fix-non-zero-code-on-failure
Apr 7, 2026
Merged

Framework tests / test validators now return exit codes (-1) when failures are detected#9
ethan-thompson merged 1 commit intomainfrom
fix-non-zero-code-on-failure

Conversation

@marc-casavant
Copy link
Copy Markdown
Contributor

@marc-casavant marc-casavant commented Mar 27, 2026

  • Understand the codebase and identify all sys.exit uses
  • Fix sys.exit(1) in run_tests() async coroutine → use had_exception flag and return -1
  • Guard task.result() calls against cancelled/exceptional tasks in run_tests()
  • Fix isinstance(result, Exception)isinstance(result, BaseException) in run_all_tests_and_shutdown()
  • Change main() to return int instead of calling sys.exit
  • Update interface() to call sys.exit based on main() return value
  • All remaining sys.exit calls are properly in interface() (topmost entry point)

⚡ Quickly spin up Copilot coding agent tasks from anywhere on your macOS or Windows machine with Raycast.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the multi-server test framework so individual validators/tests return explicit result codes (0 on success, non-zero on failure) and attempts to propagate those codes up to the framework’s top-level execution.

Changes:

  • Validator.get_results_str() now returns (results_str, result_code) where result_code is 0 or -1.
  • Test.run() / Test.__run() now return an integer exit code derived from per-state validator results (and timeout handling).
  • multi_server_test.run_tests() / main() were updated to aggregate test return codes and exit non-zero on failures.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
src/multi_server_test.py Propagates async test return codes to main() and attempts to convert failures into a non-zero process exit.
src/custom_test.py Makes Test.run() and internal state runner return an int result code; logs validator result codes per state.
src/Validator.py Extends validator result reporting to include an explicit pass/fail result code alongside the formatted output.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/multi_server_test.py Outdated
Comment thread src/multi_server_test.py Outdated
Comment thread src/multi_server_test.py Outdated
Comment thread src/custom_test.py Outdated
Comment thread src/Validator.py Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/multi_server_test.py Outdated
Comment thread src/multi_server_test.py Outdated
Comment thread src/Validator.py Outdated
Comment thread src/multi_server_test.py Outdated
Comment thread src/multi_server_test.py
@marc-casavant marc-casavant changed the title Framework tests now return exit codes, -1 on failure Framework tests / test validators now return exit codes (-1) when failures are detected Mar 30, 2026
Comment thread src/multi_server_test.py Outdated
@marc-casavant marc-casavant requested a review from arr2036 March 31, 2026 19:05
Comment thread src/custom_test.py Outdated
"%s %s", f"Test.{self.name}.{self.compose_file.stem}", result
)

return ExitCodes.VALIDATION_FAILURE if any(has_failure for has_failure in test_has_failures) else ExitCodes.SUCCESS
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return ExitCodes.VALIDATION_FAILURE if (True in test_has_failures) else ExitCodes.SUCCESS

Comment thread src/multi_server_test.py Outdated
tests (list[Test]): List of Test objects to run.

Returns:
int: 0 if all tests passed, -1 if any test had failures.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does not return -1. Returns a specific ExitCode

Comment thread src/multi_server_test.py
Comment thread src/multi_server_test.py
Comment thread src/multi_server_test.py Outdated
Comment on lines +226 to +235
for task in tasks:
if task.cancelled():
logger.error("A test task was cancelled: %s", task.get_name())
return ExitCodes.GENERAL_EXCEPTION
exc = task.exception()
if exc is not None:
logger.error("A test task raised an exception: %s", exc)
return ExitCodes.GENERAL_EXCEPTION
if task.result() != 0:
return ExitCodes.VALIDATION_FAILURE
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is going to exit at the first test that had a problem. In that case, you would loose the results of the other tests.

Comment thread src/multi_server_test.py Outdated
codes.append(ExitCodes.GENERAL_EXCEPTION if isinstance(result, BaseException) else result)
await cleanup_and_shutdown()

loop.create_task(run_all_tests_and_shutdown())
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means that the shutdown of the tests is going to be blocked/waiting for all of the tests to finish up.

Instead, look at the callback that is being registered for when the test_task is "done". That method should look at the "result" and then track that using some shared thing. It looks like currently that could be the "codes" list.

Comment thread src/multi_server_test.py Outdated
logger.info("Multi-server tests completed.")

# If any of the test exit codes are non-zero, return 1 to indicate a failure
if any(code != ExitCodes.SUCCESS for code in codes):
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be able to just do if ExitCodes.SUCCESS in codes:

Comment thread src/multi_server_test.py Outdated
)
logger.info("Exiting.")
sys.exit(1)
#sys.exit(1)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove commented code

Comment thread src/multi_server_test.py Outdated
Comment on lines +603 to +604
if ret:
sys.exit(ret)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set a default return value for ret at the top. Let it be overwritten by the other returns. Then, just do sys.exit(ret) here with no conditional

Comment thread src/multi_server_test.py Outdated
logger = logging_helper.get_logger()

async def cleanup_and_shutdown() -> None:
ret = ExitCodes.SUCCESS
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be at the top of interface() since it does not need to be globally scoped.

Comment thread src/multi_server_test.py
Comment thread src/multi_server_test.py
@marc-casavant marc-casavant force-pushed the fix-non-zero-code-on-failure branch from 0e76f88 to 971cd1f Compare April 7, 2026 16:20
@marc-casavant
Copy link
Copy Markdown
Contributor Author

@ethan-thompson last minor update included, all commits squashed. I think we are good to merge.

@ethan-thompson ethan-thompson merged commit b4000ef into main Apr 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants