From c79186de3b60f281a76dfc55e230841c68ad6104 Mon Sep 17 00:00:00 2001 From: Andre Kurait Date: Fri, 3 Jan 2025 15:58:27 -0600 Subject: [PATCH] Update console_link logic on clearing snapshots with missing repo (#1219) * Update console_link logic on clearing snapshots with missing repo Signed-off-by: Andre Kurait * Run 6.8 and 7.10 e2e tests on PR Signed-off-by: Andre Kurait * Revert "Run 6.8 and 7.10 e2e tests on PR" This reverts commit d49877d9b3751d3c358f8930c5a992fa13bc1dd8. Signed-off-by: Andre Kurait --------- Signed-off-by: Andre Kurait --- .../console_link/middleware/clusters.py | 18 +++-- .../tests/test_clusters_middleware.py | 68 +++++++++++++++++++ 2 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 TrafficCapture/dockerSolution/src/main/docker/migrationConsole/lib/console_link/tests/test_clusters_middleware.py diff --git a/TrafficCapture/dockerSolution/src/main/docker/migrationConsole/lib/console_link/console_link/middleware/clusters.py b/TrafficCapture/dockerSolution/src/main/docker/migrationConsole/lib/console_link/console_link/middleware/clusters.py index 81a279926..26ee21d86 100644 --- a/TrafficCapture/dockerSolution/src/main/docker/migrationConsole/lib/console_link/console_link/middleware/clusters.py +++ b/TrafficCapture/dockerSolution/src/main/docker/migrationConsole/lib/console_link/console_link/middleware/clusters.py @@ -1,6 +1,7 @@ from console_link.models.cluster import Cluster, HttpMethod from dataclasses import dataclass import logging +from requests.exceptions import HTTPError logger = logging.getLogger(__name__) @@ -68,6 +69,7 @@ def clear_cluster(cluster: Cluster): def clear_snapshots(cluster: Cluster, repository: str) -> None: + logger.info(f"Clearing snapshots from repository '{repository}'") """ Clears all snapshots from the specified repository. @@ -79,7 +81,9 @@ def clear_snapshots(cluster: Cluster, repository: str) -> None: # List all snapshots in the repository snapshots_path = f"/_snapshot/{repository}/_all" response = call_api(cluster, snapshots_path, raise_error=True) + logger.debug(f"Raw response: {response.json()}") snapshots = response.json().get("snapshots", []) + logger.info(f"Found {len(snapshots)} snapshots in repository '{repository}'.") if not snapshots: logger.info(f"No snapshots found in repository '{repository}'.") @@ -94,9 +98,11 @@ def clear_snapshots(cluster: Cluster, repository: str) -> None: except Exception as e: # Handle 404 errors specifically for missing repository - if "repository_missing_exception" in str(e): - logger.info(f"Repository '{repository}' is missing. Skipping snapshot clearing.") - else: - # Re-raise other errors - logger.error(f"Error clearing snapshots from repository '{repository}': {e}") - raise e + if isinstance(e, HTTPError) and e.response.status_code == 404: + error_details = e.response.json().get('error', {}) + if error_details.get('type') == 'repository_missing_exception': + logger.info(f"Repository '{repository}' is missing. Skipping snapshot clearing.") + return + # Re-raise other errors + logger.error(f"Error clearing snapshots from repository '{repository}': {e}") + raise e diff --git a/TrafficCapture/dockerSolution/src/main/docker/migrationConsole/lib/console_link/tests/test_clusters_middleware.py b/TrafficCapture/dockerSolution/src/main/docker/migrationConsole/lib/console_link/tests/test_clusters_middleware.py new file mode 100644 index 000000000..8a3951ce2 --- /dev/null +++ b/TrafficCapture/dockerSolution/src/main/docker/migrationConsole/lib/console_link/tests/test_clusters_middleware.py @@ -0,0 +1,68 @@ +import pytest +from unittest.mock import MagicMock +from console_link.middleware.clusters import clear_snapshots +from console_link.models.cluster import Cluster +import requests +import logging + + +# Helper to mock HTTPError with response +def create_http_error_mock(status_code, json_data): + response_mock = MagicMock() + response_mock.status_code = status_code + response_mock.json.return_value = json_data + return requests.exceptions.HTTPError(response=response_mock) + + +@pytest.fixture +def mock_cluster_with_missing_repo(mocker): + cluster = MagicMock(spec=Cluster) + # Simulate repository missing exception + error_mock = create_http_error_mock( + status_code=404, + json_data={ + 'error': { + 'type': 'repository_missing_exception', + 'reason': '[migration_assistant_repo] missing' + } + } + ) + mocker.patch.object(cluster, 'call_api', side_effect=error_mock) + return cluster + + +@pytest.fixture +def mock_cluster_with_snapshots(mocker): + cluster = MagicMock(spec=Cluster) + # Mock the response for listing snapshots + mock_response = MagicMock() + mock_response.json.return_value = { + 'snapshots': [ + {'snapshot': 'snapshot_1'}, + {'snapshot': 'snapshot_2'} + ] + } + mock_response.status_code = 200 + + def mock_call_api(path, *args, **kwargs): + if "_all" in path: + return mock_response + elif "snapshot_1" in path or "snapshot_2" in path: + return MagicMock() # Simulate successful deletion + raise ValueError(f"Unexpected path: {path}") + + mocker.patch.object(cluster, 'call_api', side_effect=mock_call_api) + return cluster + + +def test_clear_snapshots_repository_missing(mock_cluster_with_missing_repo, caplog): + with caplog.at_level(logging.INFO, logger='console_link.middleware.clusters'): + clear_snapshots(mock_cluster_with_missing_repo, 'migration_assistant_repo') + assert "Repository 'migration_assistant_repo' is missing. Skipping snapshot clearing." in caplog.text + + +def test_clear_snapshots_success(mock_cluster_with_snapshots, caplog): + with caplog.at_level(logging.INFO, logger='console_link.middleware.clusters'): + clear_snapshots(mock_cluster_with_snapshots, 'migration_assistant_repo') + assert "Deleted snapshot: snapshot_1 from repository 'migration_assistant_repo'." in caplog.text + assert "Deleted snapshot: snapshot_2 from repository 'migration_assistant_repo'." in caplog.text