One runner failing must not block the others.
(monkeypatch)
| 109 | |
| 110 | |
| 111 | def test_engine_fanout_partial_failure(monkeypatch): |
| 112 | """One runner failing must not block the others.""" |
| 113 | from recon_engine import ReconEngine, ReconType, ReconResult |
| 114 | |
| 115 | engine = ReconEngine.__new__(ReconEngine) |
| 116 | engine._lock = __import__("threading").Lock() |
| 117 | engine.active_scans = {} |
| 118 | engine._tool_paths = {} |
| 119 | from collections import deque |
| 120 | engine._scan_history = deque(maxlen=100) |
| 121 | |
| 122 | def ok_runner(target): |
| 123 | return ReconResult(recon_type=ReconType.TLS_AUDIT, target=target, status="ok") |
| 124 | |
| 125 | def failing_runner(target): |
| 126 | raise RuntimeError("simulated failure") |
| 127 | |
| 128 | def slow_ok_runner(target): |
| 129 | time.sleep(0.05) |
| 130 | return ReconResult(recon_type=ReconType.CONTENT_DISCOVERY, target=target, status="ok") |
| 131 | |
| 132 | monkeypatch.setattr(engine, "_run_tls_audit", ok_runner) |
| 133 | monkeypatch.setattr(engine, "_run_dns_passive", failing_runner) |
| 134 | monkeypatch.setattr(engine, "_run_content_discovery", slow_ok_runner) |
| 135 | |
| 136 | from recon_engine import ReconScanState |
| 137 | state = ReconScanState( |
| 138 | scan_id="TEST", |
| 139 | target="https://example.com", |
| 140 | recon_types=[ReconType.TLS_AUDIT, ReconType.DNS_PASSIVE, ReconType.CONTENT_DISCOVERY], |
| 141 | ) |
| 142 | engine.active_scans["TEST"] = state |
| 143 | |
| 144 | engine._run_scan("TEST", "https://example.com", |
| 145 | [ReconType.TLS_AUDIT, ReconType.DNS_PASSIVE, ReconType.CONTENT_DISCOVERY], |
| 146 | timeout=10) |
| 147 | |
| 148 | assert state.status == "completed" |
| 149 | assert state.results[ReconType.TLS_AUDIT].status == "ok" |
| 150 | assert state.results[ReconType.DNS_PASSIVE].status == "error" |
| 151 | assert "simulated failure" in state.results[ReconType.DNS_PASSIVE].error_message |
| 152 | assert state.results[ReconType.CONTENT_DISCOVERY].status == "ok" |
| 153 | |
| 154 | |
| 155 | def test_assert_handoff_scope_same_domain(): |
nothing calls this directly
no test coverage detected