diff --git a/shared/python/utils.py b/shared/python/utils.py index aab551c..e7378ec 100644 --- a/shared/python/utils.py +++ b/shared/python/utils.py @@ -152,7 +152,6 @@ def create_infrastructure(self, bypass_infrastructure_check: bool = False, allow print_error('Infrastructure deployment cancelled by user.') raise SystemExit("User cancelled deployment") except (KeyboardInterrupt, EOFError) as exc: - print_error('Infrastructure deployment cancelled by user (Escape/Ctrl+C pressed).') raise SystemExit("User cancelled deployment") from exc # Check infrastructure existence for the normal flow @@ -213,9 +212,9 @@ def create_infrastructure(self, bypass_infrastructure_check: bool = False, allow return True - except KeyboardInterrupt as exc: # pragma: no cover + except (KeyboardInterrupt, EOFError): # pragma: no cover print_error('\nInfrastructure deployment cancelled by user.') - raise SystemExit("User cancelled deployment") from exc + return False except Exception as e: # pragma: no cover print_error(f'Infrastructure deployment failed with error: {e}') raise SystemExit(1) from e @@ -740,13 +739,13 @@ def _prompt_for_infrastructure_update(rg_name: str) -> tuple[bool, int | None]: print_plain('ℹ️ Choose an option (input box at the top of the screen):') print_plain(' 1. Update the existing infrastructure (recommended)') print_plain(' 2. Use a different index') - print_plain(' 3. Delete the existing resource group first using the clean-up notebook\n') + print_plain(' 3. Delete the existing resource group first using the clean-up notebook') + print_plain(' (Press ESC to cancel)\n') while True: choice = input('\nEnter your choice (1, 2, or 3): ').strip() - # Default to option 1 if user just presses Enter - if choice == '1' or not choice: + if choice == '1': return True, None elif choice == '2': # Option 2: Prompt for a different index @@ -767,6 +766,9 @@ def _prompt_for_infrastructure_update(rg_name: str) -> tuple[bool, int | None]: print_plain('❌ Please enter a valid integer for the index.') elif choice == '3': return False, None + elif not choice: + # Empty input (ESC pressed in Jupyter) - cancel + raise EOFError() else: print_plain('❌ Invalid choice. Please enter 1, 2, or 3.') @@ -783,8 +785,7 @@ def does_infrastructure_exist(infrastructure: INFRASTRUCTURE, index: int, allow_ bool: True if the infrastructure exists and no update is desired, False if infrastructure doesn't exist or update is confirmed. """ - print_plain(f'� Debug: does_infrastructure_exist called with allow_update_option={allow_update_option}') - print_plain('�🔍 Checking if infrastructure already exists...') + print_plain('🔍 Checking if infrastructure already exists...') rg_name = az.get_infra_rg_name(infrastructure, index) @@ -801,16 +802,19 @@ def does_infrastructure_exist(infrastructure: INFRASTRUCTURE, index: int, allow_ print_info('Choose an option (input box at the top of the screen):') print_plain(' 1. Update the existing infrastructure (recommended and not destructive if samples already exist)') print_plain(' 2. Use a different index') - print_plain(' 3. Exit, then delete the existing resource group separately via the clean-up notebook\n') + print_plain(' 3. Exit, then delete the existing resource group separately via the clean-up notebook') + print_plain(' (Press ESC to cancel)\n') while True: choice = input('\nEnter your choice (1, 2, or 3): ').strip() - # Default to option 1 if user just presses Enter if choice == '1': return False # Allow deployment to proceed - elif not choice or choice in('2', '3'): + elif choice in ('2', '3'): return True # Block deployment + elif not choice: + # Empty input (ESC pressed in Jupyter) - cancel + raise EOFError() else: print_plain('❌ Invalid choice. Please enter 1, 2, or 3.') else: diff --git a/tests/python/check_python.ps1 b/tests/python/check_python.ps1 index 0850c41..1a63d2c 100644 --- a/tests/python/check_python.ps1 +++ b/tests/python/check_python.ps1 @@ -153,8 +153,8 @@ Write-Host "╚═════════════════════ Write-Host "" # Determine statuses -$LintStatus = if ($LintExitCode -eq 0) { "✅ PASSED" } else { "⚠️ ISSUES FOUND" } -$TestStatus = if ($TestExitCode -eq 0) { "✅ PASSED" } else { "❌ FAILED" } +$LintStatus = if ($LintExitCode -eq 0) { "✅ PASSED" } else { "⚠️ ISSUES FOUND" } # leave two spaces after yellow triangle to display correctly +$TestStatus = if ($FailedTests -eq 0) { "✅ PASSED" } else { "❌ FAILED" } # Get pylint score $PylintScore = $null @@ -168,11 +168,7 @@ if (Test-Path $LatestPylintText) { # Set colors $LintColor = if ($LintExitCode -eq 0) { "Green" } else { "Yellow" } -$TestColor = if ($TestExitCode -eq 0) { "Green" } else { "Red" } - -# Calculate column widths for alignment -$LabelWidth = "Pylint :".Length # 7 -$Padding = " " * ($LabelWidth - 1) +$TestColor = if ($FailedTests -eq 0) { "Green" } else { "Red" } # Display Pylint status with score Write-Host "Pylint : " -NoNewline diff --git a/tests/python/check_python.sh b/tests/python/check_python.sh index 55c5ac8..8084c0e 100644 --- a/tests/python/check_python.sh +++ b/tests/python/check_python.sh @@ -116,11 +116,11 @@ echo "" if [ $LINT_EXIT_CODE -eq 0 ]; then LINT_STATUS="✅ PASSED" else - LINT_STATUS="⚠️ ISSUES FOUND" + LINT_STATUS="⚠️ ISSUES FOUND" # leave two spaces after yellow triangle to display correctly fi # Determine Test status -if [ $TEST_EXIT_CODE -eq 0 ]; then +if [ $FAILED_TESTS -eq 0 ]; then TEST_STATUS="✅ PASSED" else TEST_STATUS="❌ FAILED" @@ -132,7 +132,11 @@ if [ -n "$PYLINT_SCORE" ]; then echo " ($PYLINT_SCORE)" fi -echo "Tests : $TEST_STATUS" +if [ $FAILED_TESTS -eq 0 ]; then + echo "Tests : $TEST_STATUS" +else + echo -e "Tests : \e[31m$TEST_STATUS\e[0m" # Red color for failed tests +fi if [ $TOTAL_TESTS -gt 0 ]; then # Calculate percentages (using bc for floating point) PASSED_PERCENT=$(echo "scale=2; $PASSED_TESTS / $TOTAL_TESTS * 100" | bc) diff --git a/tests/python/test_apimtypes.py b/tests/python/test_apimtypes.py index 360ff64..d3988e1 100644 --- a/tests/python/test_apimtypes.py +++ b/tests/python/test_apimtypes.py @@ -760,6 +760,49 @@ def test_sleep_time_constant(self): assert SLEEP_TIME_BETWEEN_REQUESTS_MS > 0 +# ------------------------------ +# PROJECT ROOT TESTS +# ------------------------------ + +# ------------------------------ +# PRIVATE FUNCTION TESTS +# ------------------------------ + +class TestReadPolicyXml: + """Test suite for _read_policy_xml private function.""" + + def test_read_policy_xml_returns_string(self): + """Test that _read_policy_xml returns a string when given a valid file.""" + # Use an actual policy file from the repository + result = apimtypes._read_policy_xml(DEFAULT_XML_POLICY_PATH) + assert isinstance(result, str) + assert len(result) > 0 + + def test_read_policy_xml_returns_xml_structure(self): + """Test that returned content has basic XML structure.""" + result = apimtypes._read_policy_xml(DEFAULT_XML_POLICY_PATH) + assert '<' in result + assert '>' in result + + def test_read_policy_xml_with_backend_file(self): + """Test reading backend policy XML file from repository.""" + result = apimtypes._read_policy_xml(BACKEND_XML_POLICY_PATH) + assert isinstance(result, str) + assert len(result) > 0 + + def test_read_policy_xml_with_hello_world_file(self): + """Test reading hello-world policy XML file from repository.""" + result = apimtypes._read_policy_xml(HELLO_WORLD_XML_POLICY_PATH) + assert isinstance(result, str) + assert len(result) > 0 + + def test_read_policy_xml_with_request_headers_file(self): + """Test reading request-headers policy XML file from repository.""" + result = apimtypes._read_policy_xml(REQUEST_HEADERS_XML_POLICY_PATH) + assert isinstance(result, str) + assert len(result) > 0 + + # ------------------------------ # PROJECT ROOT TESTS # ------------------------------ diff --git a/tests/python/test_slowness_detection.py b/tests/python/test_miscellaneous.py similarity index 80% rename from tests/python/test_slowness_detection.py rename to tests/python/test_miscellaneous.py index 76f4e89..21024ec 100644 --- a/tests/python/test_slowness_detection.py +++ b/tests/python/test_miscellaneous.py @@ -1,8 +1,15 @@ -"""Verification tests for test infrastructure slowness detection.""" +"""Miscellaneous tests that are used sporadically to assess test harness behavior.""" +#import pytest #from __future__ import annotations +# @pytest.mark.unit +# def test_true_is_false(): +# assert True is False + + + # @pytest.mark.unit # def test_slowness_detection_verification(): # """Intentionally slow test to verify slowness detection feature works. diff --git a/tests/python/test_utils.py b/tests/python/test_utils.py index 5811b51..5d4709d 100644 --- a/tests/python/test_utils.py +++ b/tests/python/test_utils.py @@ -993,8 +993,8 @@ def test_prompt_for_infrastructure_update_option_1(monkeypatch): assert result == (True, None) def test_prompt_for_infrastructure_update_option_1_default(monkeypatch): - """Test _prompt_for_infrastructure_update when user presses Enter (defaults to option 1).""" - monkeypatch.setattr('builtins.input', lambda prompt: '') + """Test _prompt_for_infrastructure_update when user selects option 1 explicitly.""" + monkeypatch.setattr('builtins.input', lambda prompt: '1') result = utils._prompt_for_infrastructure_update('test-rg') assert result == (True, None)