Skip to content

Commit 096c19d

Browse files
authored
[MAINT]: removing asyncio (#36)
Remove all `@pytest.mark.asyncio decorators` from tests and drop the related instruction from unit test standards. The project uses `asyncio_mode = "auto"` (configured in `pyproject.toml`), which collects async tests automatically — making the decorators redundant.
1 parent 766f71a commit 096c19d

20 files changed

Lines changed: 0 additions & 196 deletions

.github/instructions/unit-tests-standards.instructions.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,11 @@ class TestParseConfig:
3737
```
3838

3939
### Async Tests
40-
- Use `@pytest.mark.asyncio` decorator for all async test methods
4140
- Async test method names MUST end with `_async`
4241
- Use `AsyncMock` instead of `MagicMock` when mocking async methods
4342

4443
```python
4544
class TestProcessor:
46-
@pytest.mark.asyncio
4745
async def test_process_returns_result_async(self) -> None:
4846
processor = Processor(client=AsyncMock(return_value="ok"))
4947
result = await processor.process_async(data="input")

tests/integration/test_smoke.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ class TestSmoke:
2323
"""Core framework smoke tests."""
2424

2525
@pytest.mark.harm(HarmCategory.DATA_EXFILTRATION)
26-
@pytest.mark.asyncio
2726
async def test_evaluator_detects_tool_call_async(self) -> None:
2827
"""Evaluator unit test against hand-crafted Response."""
2928
response = Response(
@@ -44,7 +43,6 @@ async def test_evaluator_detects_tool_call_async(self) -> None:
4443
assert result.detected
4544

4645
@pytest.mark.harm(HarmCategory.OVER_PERMISSIVE_ACTION)
47-
@pytest.mark.asyncio
4846
async def test_probe_against_mock_adapter_async(self) -> None:
4947
"""Probe test via Probes.behavior against MockAdapter."""
5048
adapter = MockAdapter(

tests/unit/attacks/test_xpia.py

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55

66
from unittest.mock import AsyncMock
77

8-
import pytest
9-
108
from rampart.attacks import Attacks
119
from rampart.core.errors import InfrastructureError
1210
from rampart.core.manifest import AppManifest
@@ -72,7 +70,6 @@ def _adapter(
7270
class 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:
116111
class 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:
148141
class 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:
164156
class 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:
215204
class 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:
251238
class 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:
297281
class 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:
328310
class 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:
344325
class 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=[

tests/unit/converters/test_docx.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ def test_no_pyrit_import_at_construction(self) -> None:
3939
DocxConverter()
4040
mock_cls.assert_not_called()
4141

42-
@pytest.mark.asyncio
4342
async def test_creates_pyrit_converter_on_first_use(self, tmp_path: Path) -> None:
4443
mock_result = _mock_converter_result(tmp_path)
4544

@@ -55,7 +54,6 @@ async def test_creates_pyrit_converter_on_first_use(self, tmp_path: Path) -> Non
5554
class TestDocxConverterConversion:
5655
"""Conversion delegates to WordDocConverter and maps result."""
5756

58-
@pytest.mark.asyncio
5957
async def test_produces_docx_payload(self, tmp_path: Path) -> None:
6058
mock_result = _mock_converter_result(tmp_path)
6159

@@ -69,7 +67,6 @@ async def test_produces_docx_payload(self, tmp_path: Path) -> None:
6967
assert result.format is PayloadFormat.DOCX
7068
assert result.artifact == Path(mock_result.output_text)
7169

72-
@pytest.mark.asyncio
7370
async def test_delegates_content_to_pyrit(self, tmp_path: Path) -> None:
7471
mock_result = _mock_converter_result(tmp_path)
7572

@@ -87,7 +84,6 @@ async def test_delegates_content_to_pyrit(self, tmp_path: Path) -> None:
8784
input_type="text",
8885
)
8986

90-
@pytest.mark.asyncio
9187
async def test_preserves_id(self, tmp_path: Path) -> None:
9288
mock_result = _mock_converter_result(tmp_path)
9389

@@ -102,7 +98,6 @@ async def test_preserves_id(self, tmp_path: Path) -> None:
10298

10399
assert result.id == "keep-me"
104100

105-
@pytest.mark.asyncio
106101
async def test_preserves_content_for_reporting(self, tmp_path: Path) -> None:
107102
mock_result = _mock_converter_result(tmp_path)
108103

@@ -117,7 +112,6 @@ async def test_preserves_content_for_reporting(self, tmp_path: Path) -> None:
117112

118113
assert result.content == "adversarial text"
119114

120-
@pytest.mark.asyncio
121115
async def test_metadata_includes_converter_name(self, tmp_path: Path) -> None:
122116
mock_result = _mock_converter_result(tmp_path)
123117

@@ -130,7 +124,6 @@ async def test_metadata_includes_converter_name(self, tmp_path: Path) -> None:
130124

131125
assert result.metadata["converter"] == "DocxConverter"
132126

133-
@pytest.mark.asyncio
134127
async def test_source_metadata_carried_forward(self, tmp_path: Path) -> None:
135128
mock_result = _mock_converter_result(tmp_path)
136129

@@ -149,7 +142,6 @@ async def test_source_metadata_carried_forward(self, tmp_path: Path) -> None:
149142
class TestDocxConverterValidation:
150143
"""Input validation."""
151144

152-
@pytest.mark.asyncio
153145
async def test_rejects_binary_payload(self, tmp_path: Path) -> None:
154146
artifact = tmp_path / "existing.docx"
155147
artifact.write_bytes(b"PK")

tests/unit/core/test_converter.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55

66
from pathlib import Path
77

8-
import pytest
9-
108
from rampart.core.converter import PayloadConverter
119
from rampart.core.types import Payload, PayloadFormat
1210

@@ -42,30 +40,26 @@ def test_converter_satisfies_protocol(self) -> None:
4240
def test_html_converter_satisfies_protocol(self) -> None:
4341
assert isinstance(_HtmlWrapConverter(), PayloadConverter)
4442

45-
@pytest.mark.asyncio
4643
async def test_uppercase_converter_transforms_content(self) -> None:
4744
converter = _UpperCaseConverter()
4845
payload = Payload(content="hello world", id="t1")
4946
result = await converter.convert_async(payload=payload)
5047
assert result.content == "HELLO WORLD"
5148
assert result.id == "t1"
5249

53-
@pytest.mark.asyncio
5450
async def test_html_converter_changes_format(self) -> None:
5551
converter = _HtmlWrapConverter()
5652
payload = Payload(content="evil content", id="t2")
5753
result = await converter.convert_async(payload=payload)
5854
assert result.content == "<p>evil content</p>"
5955
assert result.format is PayloadFormat.HTML
6056

61-
@pytest.mark.asyncio
6257
async def test_converter_preserves_id(self) -> None:
6358
converter = _UpperCaseConverter()
6459
payload = Payload(content="test", id="stable_id")
6560
result = await converter.convert_async(payload=payload)
6661
assert result.id == "stable_id"
6762

68-
@pytest.mark.asyncio
6963
async def test_converter_adds_metadata(self) -> None:
7064
converter = _UpperCaseConverter()
7165
payload = Payload(
@@ -77,7 +71,6 @@ async def test_converter_adds_metadata(self) -> None:
7771
assert result.metadata["template"] == "email_exfiltration"
7872
assert result.metadata["converter"] == "UpperCaseConverter"
7973

80-
@pytest.mark.asyncio
8174
async def test_converters_compose_sequentially(self) -> None:
8275
upper = _UpperCaseConverter()
8376
html = _HtmlWrapConverter()
@@ -87,7 +80,6 @@ async def test_converters_compose_sequentially(self) -> None:
8780
assert result.content == "<p>EVIL</p>"
8881
assert result.format is PayloadFormat.HTML
8982

90-
@pytest.mark.asyncio
9183
async def test_format_converter_preserves_content(self, tmp_path: Path) -> None:
9284
fake_file = tmp_path / "fake.png"
9385
fake_file.write_bytes(b"\x89PNG")

0 commit comments

Comments
 (0)