feat(clp-mcp-server): Add search_by_kql_with_timestamp_range MCP tool call.#1457
Conversation
WalkthroughAdds ISO‑8601 ↔ epoch utilities and tests; updates SYSTEM_PROMPT guidance to require ISO‑8601(Z) timestamps; and adds server helpers Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Server as server.py
participant Utils as utils.py
participant Query as QueryEngine
participant Cache as SessionManager
Client->>Server: search_by_kql_with_timestamp_range(kql, begin_iso, end_iso)
Server->>Utils: parse_timestamp_range(begin_iso, end_iso)
Utils-->>Server: (begin_epoch_ms, end_epoch_ms)
Server->>Server: _execute_kql_query(session_id, kql, begin_epoch_ms, end_epoch_ms)
Server->>Query: submit_timed_query(kql, begin_epoch_ms, end_epoch_ms)
Query-->>Server: query_id
Server->>Query: wait_for_completion(query_id)
Query-->>Server: query_results
Server->>Utils: sort_by_timestamp(query_results)
Utils-->>Server: sorted_results
Server->>Utils: format_query_results(sorted_results)
Utils-->>Server: formatted_results
Server->>Cache: cache_first_page(session_id, formatted_results)
Cache-->>Server: ack
Server-->>Client: response { results } or { "Error": "..." }
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: ASSERTIVE Plan: Pro 📒 Files selected for processing (2)
🧰 Additional context used🧬 Code graph analysis (1)components/clp-mcp-server/clp_mcp_server/server/server.py (3)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
🔇 Additional comments (4)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@20001020ycx let's merge main into this branch |
search_kql_query_with_timestamp tool call in MCP Serversearch_kql_query_with_timestamp MCP tool call.
search_kql_query_with_timestamp MCP tool call.search_by_kql_with_timestamp MCP tool call.
search_by_kql_with_timestamp MCP tool call.search_by_kql_with_timestamp_range MCP tool call.
There was a problem hiding this comment.
Actionable comments posted: 19
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
components/clp-mcp-server/clp_mcp_server/clp_mcp_server.py (1)
42-85: Use Click exceptions for error handling
Replace the manualexit_codetracking andsys.exit(main(standalone_mode=False))hack with idiomatic Click errors—raiseclick.BadParameterfor invalid host/port andclick.ClickExceptionorclick.Exit(code)on config‐load failures—so Click’s normal exit behavior produces the right exit code and user messaging. Also update your--config-pathoption to useclick.Path(exists=True, path_type=Path)to validate the file up front.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (8)
components/clp-mcp-server/clp_mcp_server/clp_connector.py(2 hunks)components/clp-mcp-server/clp_mcp_server/clp_mcp_server.py(3 hunks)components/clp-mcp-server/clp_mcp_server/server/constants.py(1 hunks)components/clp-mcp-server/clp_mcp_server/server/server.py(3 hunks)components/clp-mcp-server/clp_mcp_server/server/session_manager.py(1 hunks)components/clp-mcp-server/clp_mcp_server/server/utils.py(1 hunks)components/clp-mcp-server/tests/server/__init__.py(1 hunks)components/clp-mcp-server/tests/server/test_utils.py(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-20T20:19:40.504Z
Learnt from: 20001020ycx
PR: y-scope/clp#1436
File: components/clp-mcp-server/clp_mcp_server/clp_mcp_server.py:22-27
Timestamp: 2025-10-20T20:19:40.504Z
Learning: In the clp-mcp-server project (components/clp-mcp-server/clp_mcp_server/clp_mcp_server.py), the --config Click option should use exists=True to validate the configuration file path at option processing time, even though this requires the default path to exist on all machines.
Applied to files:
components/clp-mcp-server/clp_mcp_server/clp_mcp_server.py
🧬 Code graph analysis (3)
components/clp-mcp-server/clp_mcp_server/clp_mcp_server.py (3)
components/clp-py-utils/clp_py_utils/clp_config.py (1)
CLPConfig(557-739)components/clp-py-utils/clp_py_utils/core.py (1)
read_yaml_config_file(56-62)components/clp-mcp-server/clp_mcp_server/server/server.py (1)
create_mcp_server(15-151)
components/clp-mcp-server/tests/server/test_utils.py (1)
components/clp-mcp-server/clp_mcp_server/server/utils.py (4)
convert_date_string_to_epoch(12-31)format_query_results(78-108)parse_timestamp_range(34-60)sort_by_timestamp(111-131)
components/clp-mcp-server/clp_mcp_server/server/server.py (4)
components/clp-py-utils/clp_py_utils/clp_config.py (1)
CLPConfig(557-739)components/clp-mcp-server/clp_mcp_server/clp_connector.py (4)
ClpConnector(23-177)submit_query(43-99)wait_query_completion(121-155)read_results(157-177)components/clp-mcp-server/clp_mcp_server/server/session_manager.py (4)
SessionManager(157-237)start(176-179)cache_query_result_and_get_first_page(79-96)cache_query_result_and_get_first_page(194-204)components/clp-mcp-server/clp_mcp_server/server/utils.py (3)
format_query_results(78-108)parse_timestamp_range(34-60)sort_by_timestamp(111-131)
🪛 Ruff (0.14.1)
components/clp-mcp-server/tests/server/test_utils.py
21-34: Mutable class attributes should be annotated with typing.ClassVar
(RUF012)
35-39: Mutable class attributes should be annotated with typing.ClassVar
(RUF012)
42-51: Mutable class attributes should be annotated with typing.ClassVar
(RUF012)
52-55: Mutable class attributes should be annotated with typing.ClassVar
(RUF012)
58-70: Mutable class attributes should be annotated with typing.ClassVar
(RUF012)
71-73: Mutable class attributes should be annotated with typing.ClassVar
(RUF012)
76-115: Mutable class attributes should be annotated with typing.ClassVar
(RUF012)
117-138: Mutable class attributes should be annotated with typing.ClassVar
(RUF012)
143-143: Magic value used in comparison, consider replacing 1729267200123 with a constant variable
(PLR2004)
146-146: Magic value used in comparison, consider replacing 1729267200123 with a constant variable
(PLR2004)
149-149: Magic value used in comparison, consider replacing 1729267200000 with a constant variable
(PLR2004)
152-152: Magic value used in comparison, consider replacing 1729267200000 with a constant variable
(PLR2004)
155-155: Magic value used in comparison, consider replacing 1729267200000 with a constant variable
(PLR2004)
160-160: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception
(PT011)
164-164: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception
(PT011)
168-168: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception
(PT011)
172-172: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception
(PT011)
173-173: print found
Remove print
(T201)
176-176: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception
(PT011)
177-177: print found
Remove print
(T201)
191-191: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception
(PT011)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: package-image
- GitHub Check: lint-check (ubuntu-24.04)
- GitHub Check: lint-check (macos-15)
🔇 Additional comments (7)
components/clp-mcp-server/clp_mcp_server/server/session_manager.py (1)
112-114: Docstring sync note looks good.Clear cross-reference to MCP tools; no action needed.
components/clp-mcp-server/tests/server/__init__.py (1)
1-1: OK to keep.Package initialiser is fine.
components/clp-mcp-server/tests/server/test_utils.py (1)
214-219: Be aware: sort_by_timestamp mutates the input list.No change required, but future tests shouldn’t rely on RAW_LOG_ENTRIES remaining unsorted after this call.
If that’s a concern, copy before sorting:
sorted_result = sort_by_timestamp(self.RAW_LOG_ENTRIES.copy())components/clp-mcp-server/clp_mcp_server/server/server.py (2)
15-23: create_mcp_server signature and wiring look good.Constructor injection via CLPConfig is clean.
77-110: I’ve requested the fullSYSTEM_PROMPTto verify whether it indeed instructs hyperlink wrapping. Awaiting those results.components/clp-mcp-server/clp_mcp_server/server/utils.py (2)
63-76: Confirm Python version for timespec="milliseconds"; provide fallback if needed.Some older environments don’t support the "milliseconds" timespec. If you support such runtimes, fall back to rounding microseconds.
# Fallback pattern if needed: dt = datetime.fromtimestamp(epoch_seconds, tz=timezone.utc) try: return dt.isoformat(timespec="milliseconds").replace("+00:00", "Z") except TypeError: # Older Python: emulate milliseconds ms = int(dt.microsecond / 1000) base = dt.replace(microsecond=0).isoformat().replace("+00:00", "Z") return f"{base[:-1]}.{ms:03d}Z"
111-131: Sorting helper looks good.Stable, simple key; treats invalid/missing timestamps as oldest. No issues.
| EXPECTED_RESULTS = [ | ||
| ( | ||
| 'timestamp: 2024-10-18T16:00:00.123Z, message: ' | ||
| '{"ts":1729267200123,"pid":1234,"tid":5678,' | ||
| '"message":"Log with millisecond precision"}\n' | ||
| ), | ||
| ( | ||
| 'timestamp: 2024-10-18T16:00:00.000Z, message: ' | ||
| '{"ts":1729267200000,"pid":1234,"tid":5678,' | ||
| '"message":"Log with zero milliseconds"}\n' | ||
| ), | ||
| ( | ||
| 'timestamp: 1970-01-01T00:00:00.000Z, message: ' | ||
| '{"ts":0,"pid":null,"tid":null,' | ||
| '"message":"Log at epoch zero"}\n' | ||
| ), | ||
| ( | ||
| 'timestamp: N/A, message: ' | ||
| '{"pid":null,"tid":null,' | ||
| '"message":"Log at epoch none"}\n' | ||
| ), | ||
| ] |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
EXPECTED_RESULTS: keep as-is or switch to constants for clarity (optional).
No functional issue; optional to reference the named epoch constants for symmetry.
🧰 Tools
🪛 Ruff (0.14.1)
117-138: Mutable class attributes should be annotated with typing.ClassVar
(RUF012)
🤖 Prompt for AI Agents
components/clp-mcp-server/tests/server/test_utils.py around lines 117 to 138:
the EXPECTED_RESULTS block currently uses hard-coded timestamp strings; either
leave it unchanged or refactor to reference named constants for clarity — if you
choose refactor, add descriptive constants (e.g., TS_MILLI=
"2024-10-18T16:00:00.123Z", TS_ZERO="1970-01-01T00:00:00.000Z", TS_NA="N/A") (or
reuse existing epoch constants if present), then replace the literal timestamp
substrings in each tuple with those constants so the expected values remain
identical but are clearer and easier to maintain.
…cx/clp into 10-20-substring-search-with-ts
|
@coderabbitai, review my recent change, make sure I didn't make any stupid mistakes |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 6985 🏁 Script executed: Length of output: 4955 🏁 Script executed: Length of output: 7648 🏁 Script executed: Length of output: 1612 @20001020ycx, I found several issues in your changes that need fixing: Critical Issues1. Misleading Parameter Names in
|
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 13531 🏁 Script executed: Length of output: 7675 @20001020ycx, I've reviewed your changes and found a few issues to fix: Issues Found1. Misleading Parameter Names in
|
|
@coderabbitai, great catches on point 2,3,4, do it again to make sure I didn't commit similar mistakes |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 30982 @20001020ycx, I found one additional issue similar to the ones I caught before: New Issue FoundDocstring Parameter Mismatch in
|
|
@coderabbitai, I forgot to push, do it again |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 19556 @20001020ycx, great progress! You fixed 3 out of 4 issues. Here's the status: ✅ Fixed Issues
❌ Remaining Issuetest_utils.py line 19: Still missing space before INVALID_DATE_STRING_VALUE= "is earlier than `begin_timestamp`"Should be: INVALID_DATE_STRING_VALUE = "is earlier than `begin_timestamp`"Once you fix this last spacing issue, all the previously identified problems will be resolved! 🎯 |
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (3)
components/clp-mcp-server/clp_mcp_server/server/utils.py (2)
35-36: Complete the parameter documentation.The docstring is missing descriptions for
formatted_begin_timestampandformatted_end_timestamp. These should document that both parameters accept ISO 8601 UTC date strings (with second or millisecond precision) ending with 'Z'.
14-15: Docstring overly restrictive on accepted timestamp formats.The docstring states "millisecond precision (YYYY-MM-DDTHH:mm:ss.fffZ)" but
datetime.fromisoformaton line 21 also accepts second precision (e.g., YYYY-MM-DDTHH:mm:ssZ). Update the docstring to reflect both accepted formats for accuracy.components/clp-mcp-server/clp_mcp_server/server/server.py (1)
134-136: Broaden docstring to accept both second and millisecond precision.The docstring specifies
YYYY-MM-DDTHH:mm:ss.fffZ(millisecond precision) but the implementation viaparse_timestamp_range→convert_date_string_to_epochalso accepts second precision (e.g.,YYYY-MM-DDTHH:mm:ssZ). Update to document both accepted formats.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (3)
components/clp-mcp-server/clp_mcp_server/server/server.py(3 hunks)components/clp-mcp-server/clp_mcp_server/server/session_manager.py(1 hunks)components/clp-mcp-server/clp_mcp_server/server/utils.py(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
components/clp-mcp-server/clp_mcp_server/server/server.py (3)
components/clp-mcp-server/clp_mcp_server/server/utils.py (3)
format_query_results(80-110)parse_timestamp_range(31-62)sort_by_timestamp(113-133)components/clp-mcp-server/clp_mcp_server/clp_connector.py (3)
submit_query(43-99)wait_query_completion(121-155)read_results(157-177)components/clp-mcp-server/clp_mcp_server/server/session_manager.py (3)
cache_query_result_and_get_first_page(79-96)cache_query_result_and_get_first_page(195-205)start(177-180)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: package-image
- GitHub Check: lint-check (macos-15)
- GitHub Check: lint-check (ubuntu-24.04)
| - "has_previous": Whether a page exists before the returned one. | ||
| :return: A dictionary with the following key-value pair on failures: | ||
| - "Error": An error message describing the failure. | ||
| :return: Forwards `_execute_kql_query`'s return values. |
There was a problem hiding this comment.
Are u sure this is OK? I thought the purpose was not to confuse AI...
There was a problem hiding this comment.
damn, was thinking about code formatting. I dont think AI would read this...
But, this makes Docstring very repetitive, shall we revert to the earlier version?
There was a problem hiding this comment.
Considering the future release, we may have more metadata queries being made, so I guess this helper function would be useful in the future. The only problem is having repetitive docstring..., that's a trade off we must make I guess.
I will add back the full return type then.
There was a problem hiding this comment.
I think we can add them back for now.
But in the meanwhile, is there any documentation we can find or an experiment we can do, for us to test whether AI will read the Forwards... docstrings?
There was a problem hiding this comment.
I asked AI, it doesn't read private functions
LinZhihao-723
left a comment
There was a problem hiding this comment.
Left one comment in the test cases.
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (3)
components/clp-mcp-server/tests/server/test_utils.py (1)
154-175: Remove print statements and use pytest.raises match parameter.Lines 169 and 173 contain
print()statements that serve no purpose in tests. Additionally, allpytest.raisesblocks should use thematchparameter to validate exception messages more precisely.Apply this diff to improve the test:
def test_convert_date_string_to_epoch_invalid_date_string(self): """Validates the handling of invalid date string.""" - with pytest.raises(ValueError) as exc_info: + with pytest.raises(ValueError, match=self.INVALID_DATE_STRING_ERROR): convert_date_string_to_epoch("not-a-date") - assert self.INVALID_DATE_STRING_ERROR in str(exc_info.value) - with pytest.raises(ValueError) as exc_info: + with pytest.raises(ValueError, match=self.INVALID_DATE_STRING_ERROR): convert_date_string_to_epoch("2024-13-45T25:99:99Z") - assert self.INVALID_DATE_STRING_ERROR in str(exc_info.value) - with pytest.raises(ValueError) as exc_info: + with pytest.raises(ValueError, match=self.INVALID_DATE_STRING_ERROR): convert_date_string_to_epoch("") - assert self.INVALID_DATE_STRING_ERROR in str(exc_info.value) - with pytest.raises(ValueError) as exc_info: - print(convert_date_string_to_epoch("2024.10.18T16:00:00.123")) - assert self.INVALID_DATE_STRING_ERROR in str(exc_info.value) + with pytest.raises(ValueError, match=self.INVALID_DATE_STRING_ERROR): + convert_date_string_to_epoch("2024.10.18T16:00:00.123") - with pytest.raises(ValueError) as exc_info: - print(convert_date_string_to_epoch("2024-10-18T16-00-00-123")) - assert self.INVALID_DATE_STRING_ERROR in str(exc_info.value) + with pytest.raises(ValueError, match=self.INVALID_DATE_STRING_ERROR): + convert_date_string_to_epoch("2024-10-18T16-00-00-123")components/clp-mcp-server/clp_mcp_server/server/server.py (2)
30-64: Clarify timestamp units in the docstring.The parameters
begin_tsandend_tsrepresent Unix epoch timestamps in milliseconds (as expected byconnector.submit_queryon line 54), but the docstring on lines 41-42 doesn't specify the units.Apply this diff to clarify:
- :param begin_ts: The beginning of the time range (inclusive). - :param end_ts: The end of the time range (inclusive). + :param begin_ts: The beginning of the time range in Unix epoch milliseconds (inclusive). + :param end_ts: The end of the time range in Unix epoch milliseconds (inclusive).
136-169: Update docstring to document both accepted timestamp formats.The docstring on line 142 specifies only millisecond precision (
YYYY-MM-DDTHH:mm:ss.fffZ), but the implementation viaparse_timestamp_rangeandconvert_date_string_to_epochalso accepts second precision without milliseconds (e.g.,YYYY-MM-DDTHH:mm:ssZ). This discrepancy can mislead callers.Apply this diff to document both accepted formats:
Searches log events that match the given Kibana Query Language (KQL) query within the given - time range. Timestamps must follow the ISO 8601 UTC format (`YYYY-MM-DDTHH:mm:ss.fffZ`), - where the trailing `Z` indicates UTC. Timestamps that do not follow this format will be - rejected. + time range. Timestamps must follow the ISO 8601 UTC format (e.g., `YYYY-MM-DDTHH:mm:ssZ` + or `YYYY-MM-DDTHH:mm:ss.fffZ`), where the trailing `Z` indicates UTC. Timestamps that do + not follow this format will be rejected.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
components/clp-mcp-server/clp_mcp_server/server/server.py(3 hunks)components/clp-mcp-server/tests/server/test_utils.py(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
components/clp-mcp-server/tests/server/test_utils.py (1)
components/clp-mcp-server/clp_mcp_server/server/utils.py (4)
convert_date_string_to_epoch(12-28)format_query_results(80-110)parse_timestamp_range(31-62)sort_by_timestamp(113-133)
components/clp-mcp-server/clp_mcp_server/server/server.py (3)
components/clp-mcp-server/clp_mcp_server/server/utils.py (3)
format_query_results(80-110)parse_timestamp_range(31-62)sort_by_timestamp(113-133)components/clp-mcp-server/clp_mcp_server/clp_connector.py (3)
submit_query(43-99)wait_query_completion(121-155)read_results(157-177)components/clp-mcp-server/clp_mcp_server/server/session_manager.py (3)
cache_query_result_and_get_first_page(79-96)cache_query_result_and_get_first_page(195-205)start(177-180)
🪛 Ruff (0.14.1)
components/clp-mcp-server/tests/server/test_utils.py
145-145: Magic value used in comparison, consider replacing 1729267200123 with a constant variable
(PLR2004)
148-148: Magic value used in comparison, consider replacing 1729267200000 with a constant variable
(PLR2004)
151-151: Magic value used in comparison, consider replacing 1729267200000 with a constant variable
(PLR2004)
156-156: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception
(PT011)
160-160: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception
(PT011)
164-164: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception
(PT011)
168-168: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception
(PT011)
169-169: print found
Remove print
(T201)
172-172: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception
(PT011)
173-173: print found
Remove print
(T201)
179-179: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception
(PT011)
184-184: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception
(PT011)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: lint-check (ubuntu-24.04)
🔇 Additional comments (3)
components/clp-mcp-server/tests/server/test_utils.py (1)
3-10: LGTM!The imports are clean and all imported functions are exercised in the test methods below.
components/clp-mcp-server/clp_mcp_server/server/server.py (2)
12-12: LGTM!The addition of
parse_timestamp_rangeto the imports is necessary for the new timestamp-bounded search functionality and is correctly placed.
134-134: LGTM!The refactoring to delegate to
_execute_kql_querysuccessfully eliminates code duplication and maintains the original functionality. This addresses the refactoring suggestion from previous reviews.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
components/clp-mcp-server/tests/server/test_utils.py (2)
16-20: Fix the spacing before the assignment operator on Line 19.Line 19 is missing a space before the
=operator, which violates PEP 8 style guidelines. This issue was previously flagged but remains unresolved.Apply this diff to fix the spacing:
- INVALID_DATE_STRING_VALUE_ERROR= "is earlier than `formatted_begin_timestamp`" + INVALID_DATE_STRING_VALUE_ERROR = "is earlier than `formatted_begin_timestamp`"
154-175: Use pytest.raises match parameter and remove print statements.The test logic is correct, but it violates pytest best practices (PT011) and contains debug print statements (T201) that should be removed. Use the
matchparameter to validate exception messages inline for consistency with the rest of the test suite.Apply this diff to address the issues:
- with pytest.raises(ValueError) as exc_info: - convert_date_string_to_epoch("not-a-date") - assert self.INVALID_DATE_STRING_ERROR in str(exc_info.value) + with pytest.raises(ValueError, match=self.INVALID_DATE_STRING_ERROR): + convert_date_string_to_epoch("not-a-date") - with pytest.raises(ValueError) as exc_info: - convert_date_string_to_epoch("2024-13-45T25:99:99Z") - assert self.INVALID_DATE_STRING_ERROR in str(exc_info.value) + with pytest.raises(ValueError, match=self.INVALID_DATE_STRING_ERROR): + convert_date_string_to_epoch("2024-13-45T25:99:99Z") - with pytest.raises(ValueError) as exc_info: - convert_date_string_to_epoch("") - assert self.INVALID_DATE_STRING_ERROR in str(exc_info.value) + with pytest.raises(ValueError, match=self.INVALID_DATE_STRING_ERROR): + convert_date_string_to_epoch("") - with pytest.raises(ValueError) as exc_info: - print(convert_date_string_to_epoch("2024.10.18T16:00:00.123")) - assert self.INVALID_DATE_STRING_ERROR in str(exc_info.value) + with pytest.raises(ValueError, match=self.INVALID_DATE_STRING_ERROR): + convert_date_string_to_epoch("2024.10.18T16:00:00.123") - with pytest.raises(ValueError) as exc_info: - print(convert_date_string_to_epoch("2024-10-18T16-00-00-123")) - assert self.INVALID_DATE_STRING_ERROR in str(exc_info.value) + with pytest.raises(ValueError, match=self.INVALID_DATE_STRING_ERROR): + convert_date_string_to_epoch("2024-10-18T16-00-00-123")
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
components/clp-mcp-server/tests/server/test_utils.py(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
components/clp-mcp-server/tests/server/test_utils.py (1)
components/clp-mcp-server/clp_mcp_server/server/utils.py (4)
convert_date_string_to_epoch(12-28)format_query_results(80-110)parse_timestamp_range(31-62)sort_by_timestamp(113-133)
🪛 Ruff (0.14.1)
components/clp-mcp-server/tests/server/test_utils.py
145-145: Magic value used in comparison, consider replacing 1729267200123 with a constant variable
(PLR2004)
148-148: Magic value used in comparison, consider replacing 1729267200000 with a constant variable
(PLR2004)
151-151: Magic value used in comparison, consider replacing 1729267200000 with a constant variable
(PLR2004)
156-156: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception
(PT011)
160-160: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception
(PT011)
164-164: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception
(PT011)
168-168: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception
(PT011)
169-169: print found
Remove print
(T201)
172-172: pytest.raises(ValueError) is too broad, set the match parameter or use a more specific exception
(PT011)
173-173: print found
Remove print
(T201)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: package-image
- GitHub Check: lint-check (macos-15)
🔇 Additional comments (2)
components/clp-mcp-server/tests/server/test_utils.py (2)
3-10: LGTM!The import statements are clean and all imported functions are properly used in the test suite.
177-184: Excellent use of pytest best practices!The test correctly uses the
matchparameter for exception validation, following PT011 guidelines. The test coverage for both format and value errors is comprehensive and well-structured.
| def test_convert_date_string_to_epoch(self): | ||
| """Validates converting ISO 8601 format to a Unix epoch.""" | ||
| result = convert_date_string_to_epoch("2024-10-18T16:00:00.123Z") | ||
| assert result == 1729267200123 | ||
|
|
||
| result = convert_date_string_to_epoch("2024-10-18T16:00:00Z") | ||
| assert result == 1729267200000 | ||
|
|
||
| result = convert_date_string_to_epoch("2024-10-18T16:00Z") | ||
| assert result == 1729267200000 | ||
|
|
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Consider using named constants for epoch values (optional).
The test logic is correct and validates the conversion properly. To improve maintainability and reduce duplication, consider extracting the epoch values (1729267200123, 1729267200000) as named constants at the class level, similar to the pattern used in RAW_LOG_ENTRIES.
🧰 Tools
🪛 Ruff (0.14.1)
145-145: Magic value used in comparison, consider replacing 1729267200123 with a constant variable
(PLR2004)
148-148: Magic value used in comparison, consider replacing 1729267200000 with a constant variable
(PLR2004)
151-151: Magic value used in comparison, consider replacing 1729267200000 with a constant variable
(PLR2004)
🤖 Prompt for AI Agents
In components/clp-mcp-server/tests/server/test_utils.py around lines 142 to 152,
the test uses literal epoch numbers (1729267200123, 1729267200000) inline;
extract these magic numbers into named constants at the class/module level
(e.g., EXPECTED_EPOCH_MS_WITH_MS and EXPECTED_EPOCH_MS) and replace the inline
literals in the three assertions to reference those constants to improve
readability and maintainability.
Co-authored-by: Lin Zhihao <59785146+LinZhihao-723@users.noreply.github.com>
…cx/clp into 10-20-substring-search-with-ts
…cx/clp into 10-20-substring-search-with-ts
…ol call. (y-scope#1457) Co-authored-by: Lin Zhihao <59785146+LinZhihao-723@users.noreply.github.com>
Description
This PR implements search API for MCP server:
search_by_kql_with_timestamp_range.The documentation of
search_by_kql_with_timestamp_rangeis listed below:search_by_kql_with_timestamp_rangeDescription:
Runs a search query that returns the 10 newest log messages that satisfy this KQL query and fall under the specified timestamp with pagination support for up to 1000 log messages.
Inputs:
Outputs:
Errors:
Checklist
breaking change.
Validation performed
uv run --group dev pytest tests/server/test-utils.py -v.uv run ruff check clp/components/clp-mcp-server && task lint:check-py.task docker-images:packagewith docker compose. Connected Claude Desktop agent to the running MCP server service in docker compose. Manually instructed LLM to perform asearch_kql_query_with_timestampin a bounded time range where only one log message satisfies the kql query. The retruned result is consistent with the log message we selected. You can see the end-to-end result using this linkSummary by CodeRabbit
New Features
Improvements
Tests
Documentation