From c29453faf50fdb2816e34efb8c5145dba92d87a4 Mon Sep 17 00:00:00 2001 From: Eriq Augustine Date: Thu, 5 Sep 2024 11:59:21 -0700 Subject: [PATCH] Added the ability for tests to avoid a CLI executable exiting on errors. --- autograder/api/common.py | 2 +- autograder/api/config.py | 2 +- autograder/api/error.py | 17 +++++++++++++++++ tests/cli/test_cli.py | 5 ++--- tests/server/base.py | 7 +++++++ 5 files changed, 28 insertions(+), 5 deletions(-) diff --git a/autograder/api/common.py b/autograder/api/common.py index e528ae16..660cc8a2 100644 --- a/autograder/api/common.py +++ b/autograder/api/common.py @@ -20,7 +20,7 @@ def handle_api_request(arguments, params, endpoint, exit_on_error = False, files except autograder.api.error.AutograderError as ex: if (exit_on_error): print("ERROR: " + ex.args[0], file = sys.stderr) - sys.exit(1) + autograder.api.error.exit_from_error(1) raise ex diff --git a/autograder/api/config.py b/autograder/api/config.py index 34b68595..38fa9e9d 100644 --- a/autograder/api/config.py +++ b/autograder/api/config.py @@ -57,7 +57,7 @@ def parse_api_config(config, params, except autograder.api.error.APIError as ex: if (exit_on_error): print("ERROR: " + ex.args[0], file = sys.stderr) - sys.exit(1) + autograder.api.error.exit_from_error(1) raise ex diff --git a/autograder/api/error.py b/autograder/api/error.py index 256cbb22..e92f1096 100644 --- a/autograder/api/error.py +++ b/autograder/api/error.py @@ -1,3 +1,20 @@ +import sys + +# Control if exit_from_error() should actually exit. +# Testing infrastructure can set this to control exit behavior. +_exit_on_error_for_testing = True + +def exit_from_error(exit_status = 1): + """ + Exit because an error occurred. + Tetsing infrastructure can set _exit_on_error_for_testing to false to avoid exiting. + """ + + if (not _exit_on_error_for_testing): + return + + sys.exit(exit_status) + class AutograderError(Exception): pass diff --git a/tests/cli/test_cli.py b/tests/cli/test_cli.py index f89ca993..b13bc838 100644 --- a/tests/cli/test_cli.py +++ b/tests/cli/test_cli.py @@ -7,10 +7,9 @@ import re import sys -import requests - import tests.server.base import tests.server.server +import autograder.api.error import autograder.util.dirent THIS_DIR = os.path.abspath(os.path.dirname(os.path.realpath(__file__))) @@ -175,7 +174,7 @@ def __method(self): if (is_error): self.fail("No error was not raised when one was expected ('%s')." % ( str(expected_output))) - except requests.exceptions.ConnectionError: + except autograder.api.error.ConnectionError: # Catch errors where the server does not responsed and suppress large connection errors. try: self.fail("Server had an error. See earlier output from the server.") diff --git a/tests/server/base.py b/tests/server/base.py index 8e55e27d..c745fc6e 100644 --- a/tests/server/base.py +++ b/tests/server/base.py @@ -2,6 +2,7 @@ import unittest import sys +import autograder.api.error import tests.server.server SERVER_URL_FORMAT = "http://127.0.0.1:%s" @@ -25,11 +26,17 @@ def setUpClass(cls): cls._server_process, cls._port = tests.server.server.start() cls._base_arguments['server'] = SERVER_URL_FORMAT % cls._port + # Do not actually exit on errors, raise instead. + autograder.api.error._exit_on_error_for_testing = False + @classmethod def tearDownClass(cls): tests.server.server.stop(cls._server_process) cls._server_process = None + # Reset. + autograder.api.error._exit_on_error_for_testing = True + def get_base_arguments(self): return ServerBaseTest._base_arguments.copy()