Skip to content

Commit 968a559

Browse files
committed
test(api): cover scan-perform no-op when provider is deleted
Adds unit tests asserting perform_scan_task and perform_scheduled_scan_task return None without raising or calling perform_prowler_scan when the target provider does not exist. Also records the fix in api/CHANGELOG.md under 1.28.0.
1 parent f7ebf1c commit 968a559

2 files changed

Lines changed: 53 additions & 3 deletions

File tree

api/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ All notable changes to the **Prowler API** are documented in this file.
1313
- Replace `poetry` with `uv` (`0.11.14`) as the API package manager; migrate `pyproject.toml` to `[dependency-groups]` and regenerate as `uv.lock` [(#10775)](https://github.com/prowler-cloud/prowler/pull/10775)
1414
- Remove orphaned `gin_resources_search_idx` declaration from `Resource.Meta.indexes` (DB index dropped in `0072_drop_unused_indexes`) [(#11001)](https://github.com/prowler-cloud/prowler/pull/11001)
1515

16+
### 🐞 Fixed
17+
18+
- `perform_scan_task` and `perform_scheduled_scan_task` now short-circuit with a warning and `return None` when the target provider no longer exists, instead of letting `handle_provider_deletion` raise `ProviderDeletedException`. Prevents queued messages for deleted providers from being recorded as `FAILURE` and, in one-shot scan-worker deployments, from burning a fresh container per redelivery [(#11185)](https://github.com/prowler-cloud/prowler/pull/11185)
19+
1620
---
1721

1822
## [1.27.2] (Prowler UNRELEASED)

api/src/backend/tasks/tests/test_tasks.py

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
check_lighthouse_provider_connection_task,
2222
generate_outputs_task,
2323
perform_attack_paths_scan_task,
24+
perform_scan_task,
2425
perform_scheduled_scan_task,
2526
reaggregate_all_finding_group_summaries_task,
2627
refresh_lighthouse_provider_models_task,
@@ -1433,9 +1434,9 @@ def factory(*args, **kwargs):
14331434
)
14341435

14351436
# Verify ASFF was NOT created for non-AWS provider
1436-
assert (
1437-
"asff" not in created_writers
1438-
), "ASFF writer should NOT be created for non-AWS providers"
1437+
assert "asff" not in created_writers, (
1438+
"ASFF writer should NOT be created for non-AWS providers"
1439+
)
14391440
assert "csv" in created_writers, "CSV writer should be created"
14401441
assert "ocsf" in created_writers, "OCSF writer should be created"
14411442

@@ -2454,6 +2455,51 @@ def _complete_scan(tenant_id, scan_id, provider_id):
24542455
== 1
24552456
)
24562457

2458+
def test_no_op_when_provider_does_not_exist(self, tenants_fixture):
2459+
"""Return None without raising when the provider was already deleted."""
2460+
tenant = tenants_fixture[0]
2461+
missing_provider_id = str(uuid.uuid4())
2462+
task_id = str(uuid.uuid4())
2463+
self._create_task_result(tenant.id, task_id)
2464+
2465+
with (
2466+
patch("tasks.tasks.perform_prowler_scan") as mock_scan,
2467+
patch("tasks.tasks._perform_scan_complete_tasks") as mock_complete_tasks,
2468+
self._override_task_request(perform_scheduled_scan_task, id=task_id),
2469+
):
2470+
result = perform_scheduled_scan_task.run(
2471+
tenant_id=str(tenant.id), provider_id=missing_provider_id
2472+
)
2473+
2474+
assert result is None
2475+
mock_scan.assert_not_called()
2476+
mock_complete_tasks.assert_not_called()
2477+
2478+
2479+
@pytest.mark.django_db
2480+
class TestPerformScanTask:
2481+
"""Unit tests for perform_scan_task."""
2482+
2483+
def test_no_op_when_provider_does_not_exist(self, tenants_fixture):
2484+
"""Return None without raising when the provider was already deleted."""
2485+
tenant = tenants_fixture[0]
2486+
missing_provider_id = str(uuid.uuid4())
2487+
scan_id = str(uuid.uuid4())
2488+
2489+
with (
2490+
patch("tasks.tasks.perform_prowler_scan") as mock_scan,
2491+
patch("tasks.tasks._perform_scan_complete_tasks") as mock_complete_tasks,
2492+
):
2493+
result = perform_scan_task.run(
2494+
tenant_id=str(tenant.id),
2495+
scan_id=scan_id,
2496+
provider_id=missing_provider_id,
2497+
)
2498+
2499+
assert result is None
2500+
mock_scan.assert_not_called()
2501+
mock_complete_tasks.assert_not_called()
2502+
24572503

24582504
@pytest.mark.django_db
24592505
class TestReaggregateAllFindingGroupSummaries:

0 commit comments

Comments
 (0)