55
66from unittest .mock import AsyncMock
77
8- import pytest
9-
108from rampart .attacks import Attacks
119from rampart .core .errors import InfrastructureError
1210from rampart .core .manifest import AppManifest
@@ -72,7 +70,6 @@ def _adapter(
7270class TestXPIADetection :
7371 """Attack semantics: DETECTED->UNSAFE, NOT_DETECTED->SAFE."""
7472
75- @pytest .mark .asyncio
7673 async def test_detected_returns_unsafe_with_evidence_in_summary (self ) -> None :
7774 result = await Attacks .xpia (
7875 inject = _mock_handle (),
@@ -87,7 +84,6 @@ async def test_detected_returns_unsafe_with_evidence_in_summary(self) -> None:
8784 assert result .status is SafetyStatus .UNSAFE
8885 assert "exfil_call_found" in result .summary
8986
90- @pytest .mark .asyncio
9187 async def test_not_detected_returns_safe (self ) -> None :
9288 result = await Attacks .xpia (
9389 inject = _mock_handle (),
@@ -98,7 +94,6 @@ async def test_not_detected_returns_safe(self) -> None:
9894 assert result .safe is True
9995 assert result .status is SafetyStatus .SAFE
10096
101- @pytest .mark .asyncio
10297 async def test_undetermined_returns_undetermined (self ) -> None :
10398 result = await Attacks .xpia (
10499 inject = _mock_handle (),
@@ -116,7 +111,6 @@ async def test_undetermined_returns_undetermined(self) -> None:
116111class TestXPIAEarlyStop :
117112 """Per-turn evaluation stops the conversation on first detection."""
118113
119- @pytest .mark .asyncio
120114 async def test_stops_after_first_detection (self ) -> None :
121115 evaluator = AsyncMock ()
122116 evaluator .evaluate_async .side_effect = [
@@ -133,7 +127,6 @@ async def test_stops_after_first_detection(self) -> None:
133127 assert result .status is SafetyStatus .UNSAFE
134128 assert len (result .turns ) == 2
135129
136- @pytest .mark .asyncio
137130 async def test_completes_all_turns_when_not_detected (self ) -> None :
138131 result = await Attacks .xpia (
139132 inject = _mock_handle (),
@@ -148,7 +141,6 @@ async def test_completes_all_turns_when_not_detected(self) -> None:
148141class TestXPIAMaxTurns :
149142 """Max-turns resolves normally via resolve_as_attack."""
150143
151- @pytest .mark .asyncio
152144 async def test_max_turns_resolves_normally (self ) -> None :
153145 result = await Attacks .xpia (
154146 inject = _mock_handle (),
@@ -164,7 +156,6 @@ async def test_max_turns_resolves_normally(self) -> None:
164156class TestXPIACleanup :
165157 """Injection handles are always activated and cleaned up."""
166158
167- @pytest .mark .asyncio
168159 async def test_handle_entered_and_exited (self ) -> None :
169160 handle = _mock_handle ()
170161
@@ -178,7 +169,6 @@ async def test_handle_entered_and_exited(self) -> None:
178169 handle .__aexit__ .assert_awaited_once ()
179170 handle .wait_until_ready .assert_awaited_once ()
180171
181- @pytest .mark .asyncio
182172 async def test_multiple_handles_all_cleaned (self ) -> None :
183173 h1 = _mock_handle (surface_name = "SP" )
184174 h2 = _mock_handle (surface_name = "Exchange" )
@@ -194,7 +184,6 @@ async def test_multiple_handles_all_cleaned(self) -> None:
194184 h .__aexit__ .assert_awaited_once ()
195185 h .wait_until_ready .assert_awaited_once ()
196186
197- @pytest .mark .asyncio
198187 async def test_cleanup_on_evaluator_exception (self ) -> None :
199188 """Handles are cleaned up even if the evaluator raises."""
200189 handle = _mock_handle ()
@@ -215,7 +204,6 @@ async def test_cleanup_on_evaluator_exception(self) -> None:
215204class TestXPIAInfrastructureError :
216205 """InfrastructureError produces ERROR result (base class concern)."""
217206
218- @pytest .mark .asyncio
219207 async def test_handle_activation_failure (self ) -> None :
220208 handle = _mock_handle ()
221209 handle .__aenter__ .side_effect = InfrastructureError ("SharePoint 503" )
@@ -229,7 +217,6 @@ async def test_handle_activation_failure(self) -> None:
229217 assert result .status is SafetyStatus .ERROR
230218 assert "SharePoint 503" in result .summary
231219
232- @pytest .mark .asyncio
233220 async def test_session_creation_failure (self ) -> None :
234221 adapter = AsyncMock ()
235222 adapter .create_session_async .side_effect = InfrastructureError (
@@ -251,7 +238,6 @@ async def test_session_creation_failure(self) -> None:
251238class TestXPIAObservabilityAdjustment :
252239 """SAFE is downgraded to UNDETERMINED when observability is insufficient."""
253240
254- @pytest .mark .asyncio
255241 async def test_response_only_no_tools_downgrades_to_undetermined (self ) -> None :
256242 result = await Attacks .xpia (
257243 inject = _mock_handle (),
@@ -264,7 +250,6 @@ async def test_response_only_no_tools_downgrades_to_undetermined(self) -> None:
264250 assert result .safe is False
265251 assert result .status is SafetyStatus .UNDETERMINED
266252
267- @pytest .mark .asyncio
268253 async def test_response_only_with_tool_calls_stays_safe (self ) -> None :
269254 result = await Attacks .xpia (
270255 inject = _mock_handle (),
@@ -280,7 +265,6 @@ async def test_response_only_with_tool_calls_stays_safe(self) -> None:
280265 assert result .safe is True
281266 assert result .status is SafetyStatus .SAFE
282267
283- @pytest .mark .asyncio
284268 async def test_non_response_only_levels_are_not_downgraded (self ) -> None :
285269 result = await Attacks .xpia (
286270 inject = _mock_handle (),
@@ -297,7 +281,6 @@ async def test_non_response_only_levels_are_not_downgraded(self) -> None:
297281class TestXPIAInjectionRecords :
298282 """Result carries injection records for reproduction."""
299283
300- @pytest .mark .asyncio
301284 async def test_single_handle_recorded (self ) -> None :
302285 result = await Attacks .xpia (
303286 inject = _mock_handle (surface_name = "SharePoint" , payload_id = "px-42" ),
@@ -309,7 +292,6 @@ async def test_single_handle_recorded(self) -> None:
309292 assert result .injections [0 ].payload_id == "px-42"
310293 assert result .injections [0 ].surface_name == "SharePoint"
311294
312- @pytest .mark .asyncio
313295 async def test_multi_handle_records (self ) -> None :
314296 result = await Attacks .xpia (
315297 inject = [
@@ -328,7 +310,6 @@ async def test_multi_handle_records(self) -> None:
328310class TestXPIAAttachments :
329311 """Inline attachments flow through to turns via Request."""
330312
331- @pytest .mark .asyncio
332313 async def test_attachments_recorded_in_turns (self ) -> None :
333314 attachment = Payload (content = "malicious doc" , id = "att-1" )
334315
@@ -344,7 +325,6 @@ async def test_attachments_recorded_in_turns(self) -> None:
344325class TestResponseMetadataPropagation :
345326 """Response.metadata from the adapter flows into Result.metadata."""
346327
347- @pytest .mark .asyncio
348328 async def test_single_turn_metadata_promoted_to_top_level (self ) -> None :
349329 adapter = _adapter (
350330 responses = [Response (text = "ok" , metadata = {"conversation_id" : "c-01" })],
@@ -357,7 +337,6 @@ async def test_single_turn_metadata_promoted_to_top_level(self) -> None:
357337
358338 assert result .metadata == {"conversation_id" : "c-01" }
359339
360- @pytest .mark .asyncio
361340 async def test_empty_response_metadata_produces_empty_result_metadata (self ) -> None :
362341 result = await Attacks .xpia (
363342 inject = _mock_handle (),
@@ -367,7 +346,6 @@ async def test_empty_response_metadata_produces_empty_result_metadata(self) -> N
367346
368347 assert result .metadata == {}
369348
370- @pytest .mark .asyncio
371349 async def test_multi_turn_metadata_keyed_by_turn_number (self ) -> None :
372350 adapter = _adapter (
373351 responses = [
0 commit comments