From 86ad4e7c923f0f3b6107c1df7cc3e61a8118ef3f Mon Sep 17 00:00:00 2001 From: 72004 Date: Sat, 7 Nov 2026 15:20:52 +0500 Subject: [PATCH] Report raw-request HTTP errors as failed requests SolrClient.raw_request returns the response without checking its status, and RawRequest never checked it either, so a 4xx or 5xx from Solr was recorded as a successful operation. RawRequest is now a SolrRunner and raises for error statuses, so the existing translation turns them into BenchmarkTransportError and the sample is recorded as an error with its http-status. --- solrorbit/worker_coordinator/runner.py | 7 +++++- tests/unit/solr/test_runner.py | 30 ++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/solrorbit/worker_coordinator/runner.py b/solrorbit/worker_coordinator/runner.py index 73d65605..e38cec11 100644 --- a/solrorbit/worker_coordinator/runner.py +++ b/solrorbit/worker_coordinator/runner.py @@ -1526,10 +1526,12 @@ def __str__(self): # Runner: raw-request # --------------------------------------------------------------------------- -class RawRequest(Runner): +class RawRequest(SolrRunner): """ Send an arbitrary HTTP request to any Solr endpoint. + A 4xx or 5xx response is reported as a failed request, like the other runners. + Params: - ``method`` (default "GET"), ``path``, ``body``, ``headers`` """ @@ -1544,6 +1546,9 @@ async def __call__(self, client, params): start = time.perf_counter() resp = await _run_in_executor(sc.raw_request, method, path, body, headers) elapsed = time.perf_counter() - start + # raw_request returns error responses instead of raising; SolrRunner turns this + # HTTPError into a BenchmarkTransportError, so the request counts as an error. + resp.raise_for_status() return { "weight": 1, diff --git a/tests/unit/solr/test_runner.py b/tests/unit/solr/test_runner.py index 352ab808..f4ea7b81 100644 --- a/tests/unit/solr/test_runner.py +++ b/tests/unit/solr/test_runner.py @@ -21,7 +21,11 @@ import unittest from unittest.mock import MagicMock +import requests + +from solrorbit import exceptions from solrorbit.worker_coordinator.runner import ( + RawRequest, _translate_ndjson_batch, SolrBulkIndex, SolrOptimize, @@ -435,5 +439,31 @@ def test_search_via_framework(self): self.assertEqual(5, result["hits"]) +class TestRawRequest(unittest.TestCase): + @staticmethod + def _client(status_code): + resp = requests.Response() + resp.status_code = status_code + resp.url = "http://localhost:8983/api/collections/test" + mock_sc = MagicMock() + mock_sc.raw_request.return_value = resp + return mock_sc + + def test_success_reports_http_status(self): + result = _run(RawRequest()(self._client(200), {"path": "/api/collections/test"})) + self.assertEqual(200, result["http-status"]) + self.assertEqual(1, result["weight"]) + + def test_server_error_is_a_transport_error(self): + """A rejected request must count as an error, not as a successful operation.""" + with self.assertRaises(exceptions.BenchmarkTransportError) as ctx: + _run(RawRequest()(self._client(500), {"path": "/api/collections/test", "method": "POST"})) + self.assertEqual(500, ctx.exception.status_code) + + def test_not_found_is_a_transport_error(self): + with self.assertRaises(exceptions.BenchmarkNotFoundError): + _run(RawRequest()(self._client(404), {"path": "/api/collections/missing"})) + + if __name__ == "__main__": unittest.main()