From c6f50985c6964b2381e0de6436474c5d1f1730b9 Mon Sep 17 00:00:00 2001 From: nightcityblade Date: Fri, 21 Aug 2026 11:13:08 +0800 Subject: [PATCH] fix(secops): avoid stdout logging in investigations --- .../tools/investigation_management.py | 8 ++-- .../test_investigation_management_unit.py | 37 +++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 server/secops/tests/test_investigation_management_unit.py diff --git a/server/secops/secops_mcp/tools/investigation_management.py b/server/secops/secops_mcp/tools/investigation_management.py index f419eee0..02a738bd 100644 --- a/server/secops/secops_mcp/tools/investigation_management.py +++ b/server/secops/secops_mcp/tools/investigation_management.py @@ -76,19 +76,21 @@ async def list_investigations( """ try: chronicle = get_chronicle_client(project_id, customer_id, region) - print(f"Listing investigations (page_size={page_size})...") + logger.info("Listing investigations (page_size=%s)...", page_size) result = chronicle.list_investigations( page_size=page_size, page_token=page_token ) investigations = result.get("investigations", []) - print(f"Successfully retrieved {len(investigations)} investigation(s)") + logger.info( + "Successfully retrieved %s investigation(s)", len(investigations) + ) return result except Exception as e: error_msg = f"Error listing investigations: {str(e)}" - print(error_msg) + logger.exception(error_msg) return {"error": error_msg} diff --git a/server/secops/tests/test_investigation_management_unit.py b/server/secops/tests/test_investigation_management_unit.py new file mode 100644 index 00000000..881ec9f2 --- /dev/null +++ b/server/secops/tests/test_investigation_management_unit.py @@ -0,0 +1,37 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Unit tests for investigation management tools.""" + +import pytest + +from secops_mcp.tools.investigation_management import list_investigations + + +@pytest.mark.asyncio +async def test_list_investigations_does_not_write_stdout( + monkeypatch, capsys +) -> None: + """Ensure list diagnostics cannot corrupt the MCP stdio transport.""" + + class ChronicleStub: + def list_investigations(self, **kwargs): + return {"investigations": []} + + monkeypatch.setattr( + "secops_mcp.tools.investigation_management.get_chronicle_client", + lambda *args: ChronicleStub(), + ) + + assert await list_investigations(page_size=1) == {"investigations": []} + assert capsys.readouterr().out == ""