test: add direct unit tests for Mimir mixin (#881)#1040
test: add direct unit tests for Mimir mixin (#881)#1040muddlebee merged 4 commits intoTracer-Cloud:mainfrom
Conversation
- Implements DummyMimirClient to mock internal requests without real network calls. - Validates PromQL query construction for both plain metrics and service-filtered queries. - Verifies result-series normalization of raw Grafana API JSON responses. - Covers edge cases including not-configured clients and exception-handling error envelopes. Closes Tracer-Cloud#881
Greptile SummaryAdds
Confidence Score: 4/5Safe to merge after fixing the two missing blank-line separators that would fail ruff/CI lint. All test assertions are logically correct against the mimir.py source. The only blocking issue is the ruff E302 lint violation (zero blank lines between two pairs of top-level functions) which would fail make lint in CI. Once fixed this is straightforward to merge. tests/services/test_grafana_mimir.py — blank lines before test_query_mimir_result_normalization (line 43) and test_query_mimir_not_configured (line 71). Important Files Changed
Sequence DiagramsequenceDiagram
participant Test as Test Function
participant DC as DummyMimirClient
participant MM as MimirMixin.query_mimir()
participant BDU as _build_datasource_url (MagicMock)
participant MR as _make_request (MagicMock)
Test->>DC: DummyMimirClient(is_configured=True)
Test->>MR: set return_value / side_effect
Test->>MM: query_mimir(metric_name, service_name?)
MM->>MM: check self.is_configured
MM->>BDU: _build_datasource_url(mimir_datasource_uid, "/api/v1/query")
BDU-->>MM: "https://fake-grafana.com/api/v1/query"
MM->>MR: _make_request(url, params={query})
MR-->>MM: fake_api_response
MM-->>Test: {success, metrics, total_series, query, account_id}
Test->>MR: assert_called_once_with(...)
Reviews (1): Last reviewed commit: "test: add direct unit tests for Mimir mi..." | Re-trigger Greptile |
| client._make_request.return_value = {"data": {"result": []}} | ||
|
|
||
| client.query_mimir("cpu_usage_total", service_name="backend-api") | ||
|
|
There was a problem hiding this comment.
Missing blank lines between top-level functions (E302)
Two top-level test functions are defined with zero blank lines separating them, violating PEP 8 / ruff rule E302 (expected 2 blank lines). make lint runs ruff check tests/, so this would fail CI.
test_query_mimir_service_filtered→test_query_mimir_result_normalization(line 43): 0 blank linestest_query_mimir_result_normalization→test_query_mimir_not_configured(line 71): 0 blank lines
Add two blank lines before each of those function definitions.
Context Used: Code style and conventions (source)
| # Requirement: Exception cases / error envelope | ||
| assert result["success"] is False | ||
| assert "Network timeout" in result["error"] | ||
| assert result["metrics"] == [] |
There was a problem hiding this comment.
Only the generic Exception path is covered. MimirMixin has a second branch (lines 69-71) that fires when the exception carries a .response attribute, rewriting error_msg to 'Mimir query failed: <status_code>' and capturing response.text. Add a test using a mock exception with a .response stub to cover that path — otherwise a status-code-parsing regression is invisible.
There was a problem hiding this comment.
Missed the hasattr block. I've added a new test with a mocked .response to cover the status code parsing. Thanks for the review!
|
|
||
| metric_data = result["metrics"][0] | ||
| assert metric_data["metric"]["instance"] == "server-1" | ||
| assert metric_data["value"][1] == "95.5" |
There was a problem hiding this comment.
The success response from query_mimir also includes account_id (set to self.account_id). Missing assertion here means a future refactor could drop or rename that field silently. Add: assert result["account_id"] == "test_acc_123"
There was a problem hiding this comment.
I've updated the test to include the account_id assertion so it doesn't get dropped in a future refactor. Just pushed!
| client._make_request.return_value = {"data": {"result": []}} | ||
|
|
||
| client.query_mimir("cpu_usage_total", service_name="backend-api") | ||
|
|
There was a problem hiding this comment.
The greptile E302 report (missing blank lines between top-level functions) appears to be a false positive — the diff shows two blank lines between every top-level function definition. No action needed here, but worth running make lint locally to confirm before merge.
…ount_id in normalized response
|
🎉 MERGED! @Piyushtiwari919 just shipped something. The diff gods are pleased. 🙌 👋 Join us on Discord - OpenSRE : hang out, contribute, or hunt for features and issues. Everyone's welcome. |

Introduces a
DummyMimirClientwith a mocked_make_requestmethod to isolate and test theMimirMixinwithout making real HTTP requests. Coverage includes PromQL query string construction (plain and service-filtered), result-series JSON normalization, and error envelope handling for missing configurations and network exceptions.Fixes #881
Describe the changes you have made in this PR -
tests/services/test_grafana_mimir.py.DummyMimirClientclass to attach the mixin and mock the internal_make_requestnetwork call usingMagicMock.cpu_usage_total).{service_name="backend-api"}).super().__init__()in the dummy class, adding proper-> Nonereturn type hints, and ensuring no unused imports remain in the file.Demo/Screenshot for feature changes and bug fixes -
Code Understanding and AI Usage
Did you use AI assistance (ChatGPT, Claude, Copilot, etc.) to write any part of this code?
If you used AI assistance:
Explain your implementation approach:
MimirMixinbuilds dynamic PromQL queries and parses complex Grafana API responses, but lacked direct test coverage. This created a risk for silent failures if the data shape changed or network calls failed.MagicMockacts as a spy, allowing us to intercept the_make_requestcall to assert exactly what URL and parameters were sent. Injecting a fake JSON response allows us to test thefor-loop parsing logic safely. This approach exactly mirrors the existingLokiMixintesting pattern, maintaining architectural consistency across the repository.DummyMimirClientsets up the mock environment. The fourtest_query_mimir_*functions handle the exact Acceptance Criteria from the issue: plain queries, filtered queries, data normalization, and exception catching.Checklist before requesting a review