diff --git a/bbot/test/benchmarks/test_excavate_benchmarks.py b/bbot/test/benchmarks/test_excavate_benchmarks.py index bbf2f04b4a..8dbeb82fe4 100644 --- a/bbot/test/benchmarks/test_excavate_benchmarks.py +++ b/bbot/test/benchmarks/test_excavate_benchmarks.py @@ -1,7 +1,11 @@ +import importlib.util + import pytest import asyncio from bbot.scanner import Scanner +HTTP_MODULE = "httpx" if importlib.util.find_spec("bbot.modules.httpx") else "http" + class TestExcavateDirectBenchmarks: """ @@ -99,7 +103,7 @@ def _generate_realistic_content(self, index): async def _run_excavate_single_thread(self, text_segments): """Run excavate processing in single thread""" # Create scanner and initialize excavate - scan = Scanner("example.com", modules=["httpx"], config={"excavate": True}) + scan = Scanner("example.com", modules=[HTTP_MODULE], config={"excavate": True}) await scan._prep() excavate_module = scan.modules.get("excavate") @@ -140,7 +144,7 @@ async def track_emit_event(event_data, *args, **kwargs): async def _run_excavate_parallel_tasks(self, text_segments): """Run excavate processing with parallel asyncio tasks""" # Create scanner and initialize excavate - scan = Scanner("example.com", modules=["httpx"], config={"excavate": True}) + scan = Scanner("example.com", modules=[HTTP_MODULE], config={"excavate": True}) await scan._prep() excavate_module = scan.modules.get("excavate") diff --git a/bbot/test/benchmarks/test_scan_throughput_benchmarks.py b/bbot/test/benchmarks/test_scan_throughput_benchmarks.py new file mode 100644 index 0000000000..eaf1c5c3b9 --- /dev/null +++ b/bbot/test/benchmarks/test_scan_throughput_benchmarks.py @@ -0,0 +1,91 @@ +""" +Scan throughput benchmark — measures end-to-end HTTP probing performance. + +Runs a real BBOT scan against a local httpserver, measuring how many +HTTP_RESPONSE events are produced per second through the full scan pipeline. + +Automatically detects the available HTTP scan module (httpx or http/blasthttp). + +Run with: + pytest bbot/test/benchmarks/test_scan_throughput_benchmarks.py -v --benchmark-only +""" + +import asyncio +import importlib.util +from threading import Thread +from http.server import HTTPServer, BaseHTTPRequestHandler + +import pytest + + +BENCH_PORT = 18899 + +# On 3.0: scan module is "httpx", output module is "http" +# On blasthttp branch: scan module is "http", output module is "webhook" +HTTP_MODULE = "httpx" if importlib.util.find_spec("bbot.modules.httpx") else "http" + + +class _BenchHandler(BaseHTTPRequestHandler): + """Minimal HTTP handler — returns 200 with a small HTML body for all paths.""" + + def do_GET(self): + body = f"