test(resource): add coverage for remove_resource exception rollback path
CI / benchmark-publish (pull_request) Has been skipped
CI / helm (pull_request) Successful in 1m5s
CI / build (pull_request) Successful in 1m11s
CI / lint (pull_request) Successful in 1m18s
CI / benchmark-regression (pull_request) Failing after 1m36s
CI / typecheck (pull_request) Successful in 1m49s
CI / quality (pull_request) Successful in 1m55s
CI / security (pull_request) Successful in 1m58s
CI / push-validation (pull_request) Successful in 21s
CI / e2e_tests (pull_request) Successful in 4m53s
CI / integration_tests (pull_request) Successful in 4m57s
CI / unit_tests (pull_request) Successful in 6m9s
CI / docker (pull_request) Successful in 1m30s
CI / coverage (pull_request) Failing after 16m14s
CI / status-check (pull_request) Failing after 4s
CI / benchmark-publish (pull_request) Has been skipped
CI / helm (pull_request) Successful in 1m5s
CI / build (pull_request) Successful in 1m11s
CI / lint (pull_request) Successful in 1m18s
CI / benchmark-regression (pull_request) Failing after 1m36s
CI / typecheck (pull_request) Successful in 1m49s
CI / quality (pull_request) Successful in 1m55s
CI / security (pull_request) Successful in 1m58s
CI / push-validation (pull_request) Successful in 21s
CI / e2e_tests (pull_request) Successful in 4m53s
CI / integration_tests (pull_request) Successful in 4m57s
CI / unit_tests (pull_request) Successful in 6m9s
CI / docker (pull_request) Successful in 1m30s
CI / coverage (pull_request) Failing after 16m14s
CI / status-check (pull_request) Failing after 4s
Add Behave scenario to cover the except Exception rollback path in ResourceInstanceMixin.remove_resource() in _resource_registry_ops.py. This uncovered branch was causing the CI coverage gate to fail below the 97% threshold. ISSUES CLOSED: #6329
This commit is contained in:
@@ -29,6 +29,14 @@ Feature: Resource registry service coverage boost
|
||||
Then the unlink_child session should have been rolled back
|
||||
And the generic exception from unlink_child should propagate
|
||||
|
||||
# ── remove_resource generic exception rollback ───────────────────
|
||||
|
||||
Scenario: remove_resource rolls back on unexpected generic exception
|
||||
Given a resource registry service prepared for remove_resource with a faulty session
|
||||
When I attempt remove_resource and a generic exception occurs
|
||||
Then the remove_resource session should have been rolled back
|
||||
And the generic exception from remove_resource should propagate
|
||||
|
||||
# ── _build_tree_node type_filter filtering ───────────────────────
|
||||
|
||||
Scenario: get_resource_tree with type_filter excludes non-matching children
|
||||
|
||||
@@ -5,6 +5,9 @@ Covers the remaining uncovered lines in resource_registry_service.py:
|
||||
- Lines 646-648: link_child generic exception rollback
|
||||
- Lines 686-688: unlink_child generic exception rollback
|
||||
- Line 785: _build_tree_node type_filter skips non-matching children
|
||||
|
||||
Also covers _resource_registry_ops.py:
|
||||
- remove_resource generic exception rollback path
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -51,6 +54,9 @@ _TREE_PARENT = "01JK00000000000000000000KK"
|
||||
_TREE_CHILD1 = "01JM00000000000000000000MM"
|
||||
_TREE_CHILD2 = "01JN00000000000000000000NN"
|
||||
|
||||
# Scenario 5: remove_resource generic error
|
||||
_REMOVE_RES_5 = "01JP00000000000000000000PP"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -400,6 +406,66 @@ def step_verify_unlink_child_error_propagates(context: Any) -> None:
|
||||
assert "disk I/O error in unlink_child" in str(context.boost_unlink_generic_error)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Scenario: remove_resource rolls back on unexpected generic exception
|
||||
# (targets _resource_registry_ops.py except Exception path)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
@given("a resource registry service prepared for remove_resource with a faulty session")
|
||||
def step_setup_faulty_remove_resource(context: Any) -> None:
|
||||
"""Set up a service whose session blows up during remove_resource DB ops."""
|
||||
resource = Resource(
|
||||
resource_id=_REMOVE_RES_5,
|
||||
name="test/remove-me",
|
||||
resource_type_name="git-checkout",
|
||||
classification=PhysVirt.PHYSICAL,
|
||||
description=None,
|
||||
properties={},
|
||||
location="/tmp/rm",
|
||||
content_hash=None,
|
||||
sandbox_strategy=None,
|
||||
)
|
||||
|
||||
# Mock session: count() returns 0 (no links/edges), but delete() on the
|
||||
# resource row blows up with a generic exception.
|
||||
mock_session = MagicMock()
|
||||
mock_session.query.return_value.filter.return_value.count.return_value = 0
|
||||
mock_session.query.return_value.filter_by.return_value.first.return_value = (
|
||||
MagicMock() # non-None row so delete() is called
|
||||
)
|
||||
mock_session.delete.side_effect = OSError("disk I/O error in remove_resource")
|
||||
|
||||
context.boost_remove_mock_session = mock_session
|
||||
|
||||
svc = ResourceRegistryService.__new__(ResourceRegistryService)
|
||||
svc._session_factory = lambda: mock_session
|
||||
svc.show_resource = lambda name_or_id: resource # type: ignore[assignment]
|
||||
context.boost_remove_svc = svc
|
||||
|
||||
|
||||
@when("I attempt remove_resource and a generic exception occurs")
|
||||
def step_attempt_remove_resource_generic_error(context: Any) -> None:
|
||||
context.boost_remove_generic_error = None
|
||||
try:
|
||||
context.boost_remove_svc.remove_resource("test/remove-me")
|
||||
except OSError as exc:
|
||||
context.boost_remove_generic_error = exc
|
||||
|
||||
|
||||
@then("the remove_resource session should have been rolled back")
|
||||
def step_verify_remove_resource_rollback(context: Any) -> None:
|
||||
context.boost_remove_mock_session.rollback.assert_called()
|
||||
|
||||
|
||||
@then("the generic exception from remove_resource should propagate")
|
||||
def step_verify_remove_resource_error_propagates(context: Any) -> None:
|
||||
assert context.boost_remove_generic_error is not None
|
||||
assert "disk I/O error in remove_resource" in str(
|
||||
context.boost_remove_generic_error
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Scenario: get_resource_tree with type_filter excludes non-matching children
|
||||
# (targets line 785)
|
||||
|
||||
Reference in New Issue
Block a user