Skip to content

Commit ab1d1c2

Browse files
committed
Fix linter warnings and clean up tests
1 parent b97558a commit ab1d1c2

File tree

13 files changed

+628
-395
lines changed

13 files changed

+628
-395
lines changed

pyrightconfig.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,5 @@
2121
"reportUnusedVariable": false,
2222
"reportDuplicateImport": true,
2323
"reportGeneralTypeIssues": false,
24-
- "reportPrivateImportUsage": false,
25-
+ "reportPrivateImportUsage": false
24+
"reportPrivateImportUsage": false
2625
}

src/adaptive_graph_of_thoughts/validation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def validate_query_content(cls, v):
2020

2121
for pattern in dangerous_patterns:
2222
if re.search(pattern, v, re.IGNORECASE | re.DOTALL):
23-
raise ValueError(f"Query contains potentially dangerous content")
23+
raise ValueError("Query contains potentially dangerous content")
2424

2525
return v.strip()
2626

tests/integration/api/test_mcp_inspector.py

Lines changed: 54 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9,34 +9,40 @@
99
import requests
1010
from unittest.mock import patch
1111

12+
1213
class ProcessManager:
1314
"""Manages background processes for HTTP server testing."""
14-
15+
1516
def __init__(self):
1617
self.processes = []
17-
18+
1819
def start_http_server(self, timeout=30):
1920
"""Start HTTP server in background and wait for it to be ready."""
2021
print("Starting HTTP server for testing...")
21-
22+
2223
# Change to project root directory
2324
project_root = Path(__file__).parent.parent.parent
24-
25+
2526
# Start server process
2627
cmd = [
27-
sys.executable, "-m", "uvicorn",
28+
sys.executable,
29+
"-m",
30+
"uvicorn",
2831
"src.adaptive_graph_of_thoughts.main:app",
29-
"--host", "0.0.0.0",
30-
"--port", "8000",
31-
"--log-level", "info"
32+
"--host",
33+
"0.0.0.0",
34+
"--port",
35+
"8000",
36+
"--log-level",
37+
"info",
3238
]
33-
39+
3440
process = subprocess.Popen(
3541
cmd,
3642
stdout=subprocess.PIPE,
3743
stderr=subprocess.PIPE,
3844
preexec_fn=os.setsid, # Create new process group
39-
cwd=project_root
45+
cwd=project_root,
4046
)
4147
self.processes.append(process)
4248

@@ -56,7 +62,7 @@ def start_http_server(self, timeout=30):
5662
time.sleep(2)
5763

5864
raise TimeoutError("HTTP server failed to start within timeout")
59-
65+
6066
def cleanup(self):
6167
"""Clean up all managed processes."""
6268
for proc in self.processes:
@@ -69,22 +75,22 @@ def cleanup(self):
6975
except ProcessLookupError:
7076
pass
7177

78+
7279
def run_with_retry(command, max_retries=2, timeout=180):
7380
"""Run command with retry logic and proper timeout handling."""
7481
for attempt in range(max_retries + 1):
7582
try:
7683
print(f"Attempt {attempt + 1}/{max_retries + 1}: {' '.join(command)}")
7784
result = subprocess.run(
78-
command,
79-
capture_output=True,
80-
text=True,
81-
timeout=timeout
85+
command, capture_output=True, text=True, timeout=timeout
8286
)
8387
if result.returncode == 0:
8488
print("✅ MCP Inspector validation passed!")
8589
print("Output:", result.stdout)
8690
return True
87-
print(f"❌ Exit {result.returncode}. Stdout: {result.stdout} Stderr: {result.stderr}")
91+
print(
92+
f"❌ Exit {result.returncode}. Stdout: {result.stdout} Stderr: {result.stderr}"
93+
)
8894
if attempt < max_retries:
8995
wait = 5 * (attempt + 1)
9096
print(f"⏳ Retrying in {wait}s...")
@@ -101,14 +107,13 @@ def run_with_retry(command, max_retries=2, timeout=180):
101107
time.sleep(5)
102108
return False
103109

110+
104111
@pytest.fixture(autouse=True)
105112
def setup_test_environment():
106113
"""Setup test environment and ensure dependencies are available."""
107114
try:
108115
res = subprocess.run(
109-
["mcp-inspector", "--version"],
110-
capture_output=True,
111-
timeout=10
116+
["mcp-inspector", "--version"], capture_output=True, timeout=10
112117
)
113118
if res.returncode != 0:
114119
pytest.skip("mcp-inspector not available")
@@ -120,21 +125,27 @@ def setup_test_environment():
120125
yield
121126
os.chdir(original_cwd)
122127

128+
123129
def test_inspector_http():
124130
"""Test MCP Inspector with HTTP transport using improved process management."""
125131
pm = ProcessManager()
126132
try:
127133
pm.start_http_server(timeout=30)
128134
cmd = ["mcp-inspector", "-v", "validate", "http://localhost:8000/mcp"]
129-
assert run_with_retry(cmd, max_retries=2, timeout=120), \
135+
assert run_with_retry(cmd, max_retries=2, timeout=120), (
130136
"MCP Inspector HTTP validation failed after retries"
137+
)
131138
except Exception as e:
132139
pytest.fail(f"HTTP server setup failed: {e}")
133140
finally:
134141
print("🧹 Cleaning up HTTP server...")
135142
pm.cleanup()
136143

137-
@pytest.mark.parametrize("transport_mode", ["stdio"])
144+
145+
@pytest.mark.parametrize(
146+
"transport_mode",
147+
["stdio"],
148+
)
138149
def test_inspector_stdio(transport_mode):
139150
"""Test MCP Inspector with STDIO transport using improved protocol handling."""
140151
os.chdir(Path(__file__).parent.parent.parent)
@@ -147,34 +158,44 @@ def test_inspector_stdio(transport_mode):
147158
sys.executable,
148159
"src/adaptive_graph_of_thoughts/main_stdio.py",
149160
]
150-
assert run_with_retry(cmd, max_retries=2, timeout=180), \
161+
assert run_with_retry(cmd, max_retries=2, timeout=180), (
151162
f"MCP Inspector {transport_mode} validation failed after retries"
163+
)
164+
152165

153166
def test_inspector_both_transports():
154167
"""Test MCP Inspector with both HTTP and STDIO transports comprehensively."""
155168
pm = ProcessManager()
156169
results = {}
157170
try:
158-
print("\n" + "="*50 + "\nTesting STDIO transport\n" + "="*50)
171+
print("\n" + "=" * 50 + "\nTesting STDIO transport\n" + "=" * 50)
159172
stdio_cmd = [
160-
"mcp-inspector", "-v", "validate", "stdio",
161-
"--program", sys.executable, "src/adaptive_graph_of_thoughts/main_stdio.py",
173+
"mcp-inspector",
174+
"-v",
175+
"validate",
176+
"stdio",
177+
"--program",
178+
sys.executable,
179+
"src/adaptive_graph_of_thoughts/main_stdio.py",
162180
]
163-
results['stdio'] = run_with_retry(stdio_cmd, max_retries=2, timeout=180)
181+
results["stdio"] = run_with_retry(stdio_cmd, max_retries=2, timeout=180)
164182

165-
print("\n" + "="*50 + "\nTesting HTTP transport\n" + "="*50)
183+
print("\n" + "=" * 50 + "\nTesting HTTP transport\n" + "=" * 50)
166184
pm.start_http_server(timeout=30)
167185
http_cmd = ["mcp-inspector", "-v", "validate", "http://localhost:8000/mcp"]
168-
results['http'] = run_with_retry(http_cmd, max_retries=2, timeout=120)
186+
results["http"] = run_with_retry(http_cmd, max_retries=2, timeout=120)
169187
except Exception as e:
170188
pytest.fail(f"Transport testing failed: {e}")
171189
finally:
172190
pm.cleanup()
173191

174-
print(f"\n📊 Test Results:\nSTDIO: {'✅ PASS' if results.get('stdio') else '❌ FAIL'}\n" +
175-
f"HTTP: {'✅ PASS' if results.get('http') else '❌ FAIL'}")
176-
assert results.get('stdio'), "STDIO transport validation failed"
177-
assert results.get('http'), "HTTP transport validation failed"
192+
print(
193+
f"\n📊 Test Results:\nSTDIO: {'✅ PASS' if results.get('stdio') else '❌ FAIL'}\n"
194+
+ f"HTTP: {'✅ PASS' if results.get('http') else '❌ FAIL'}"
195+
)
196+
assert results.get("stdio"), "STDIO transport validation failed"
197+
assert results.get("http"), "HTTP transport validation failed"
198+
178199

179200
def test_mcp_configuration_validity():
180201
"""Test that MCP configuration is valid and includes necessary timeout settings."""
@@ -183,4 +204,4 @@ def test_mcp_configuration_validity():
183204
content = cfg.read_text()
184205
for key in ("mcp_stdio_timeout", "mcp_http_timeout", "mcp_inspector_retries"):
185206
assert key in content, f"Missing {key} setting"
186-
print("✅ MCP configuration includes required timeout and retry settings")
207+
print("✅ MCP configuration includes required timeout and retry settings")

tests/integration/api/test_stdio_mcp.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,10 @@ def test_stdio_initialize(stdio_process):
7777
assert "mcp_version" in result_data and isinstance(result_data["mcp_version"], str)
7878

7979

80-
@pytest.mark.parametrize("query", ["test question"])
80+
@pytest.mark.parametrize(
81+
"query",
82+
["test question"],
83+
)
8184
def test_stdio_call_tool(stdio_process, query):
8285
"""Test calling the asr_got_query tool over STDIO."""
8386
request = {

tests/integration/stages/test_integration_initialization_stage.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,19 @@
1010
from dataclasses import dataclass
1111
import sys
1212
import types
13-
from typing import Generator
13+
from typing import ClassVar, Generator
1414

1515
class DummyDefaultParams:
16-
initial_confidence = [0.9, 0.9, 0.9, 0.9]
17-
initial_layer = "root_layer"
16+
initial_confidence: ClassVar[list[float]] = [0.9, 0.9, 0.9, 0.9]
17+
initial_layer: ClassVar[str] = "root_layer"
18+
19+
20+
DummyASRGot = type("obj", (), {"default_parameters": DummyDefaultParams()})
1821

1922

2023
@dataclass
2124
class DummySettings:
22-
asr_got: type = type("obj", (), {"default_parameters": DummyDefaultParams()})
25+
asr_got: type = DummyASRGot
2326

2427
@pytest.fixture(scope="module", autouse=True)
2528
def stub_modules(monkeypatch: pytest.MonkeyPatch) -> Generator[None, None, None]:
@@ -582,7 +585,7 @@ async def test_initialization_stage_concurrent_execution_safety(settings_instanc
582585

583586
# Execute multiple times concurrently
584587
tasks = []
585-
for i in range(5):
588+
for _ in range(5):
586589
session_data = GoTProcessorSessionData(query=query)
587590
tasks.append(stage.execute(current_session_data=session_data))
588591

tests/test_security.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
import pytest
22
from fastapi.testclient import TestClient
33
from src.adaptive_graph_of_thoughts.app_setup import create_app
4+
import re
5+
6+
7+
def validate_identifier(identifier: str, allowed_labels: set[str]) -> str:
8+
"""Validate Neo4j identifier to prevent injection attacks."""
9+
if not re.match(r"^[A-Za-z][A-Za-z0-9_]*$", identifier):
10+
raise ValueError("Invalid identifier")
11+
if identifier not in allowed_labels:
12+
raise ValueError("Identifier not allowed")
13+
return identifier
414

515
class TestSecurity:
616
def test_authentication_required(self):

tests/unit/api/test_nlq.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,7 @@ def test_nlq_endpoint_llm_query_logs_management(client, auth_headers, monkeypatc
658658

659659
def tracking_llm(prompt: str) -> str:
660660
if "Convert" in prompt:
661-
return f"MATCH (n) RETURN n // Query for test"
661+
return "MATCH (n) RETURN n // Query for test"
662662
return "Test response"
663663

664664
monkeypatch.setattr("adaptive_graph_of_thoughts.services.llm.ask_llm", tracking_llm)

tests/unit/config/test_config_validation.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@ def test_minimal_config(minimal_config):
5757
assert "google_scholar" not in config_data_to_validate
5858

5959

60-
@pytest.mark.parametrize("missing_key", ["app", "asr_got", "mcp_settings"])
60+
@pytest.mark.parametrize(
61+
"missing_key",
62+
["app", "asr_got", "mcp_settings"],
63+
)
6164
def test_missing_keys(tmp_path, base_config_dict, missing_key):
6265
cfg = copy.deepcopy(base_config_dict)
6366
cfg.pop(missing_key)
@@ -120,7 +123,10 @@ def test_unreadable_file(tmp_path):
120123
file_path.chmod(stat.S_IRUSR | stat.S_IWUSR)
121124

122125

123-
@pytest.mark.parametrize("port", [1, 65535])
126+
@pytest.mark.parametrize(
127+
"port",
128+
[1, 65535],
129+
)
124130
def test_boundary_values(tmp_path, port):
125131
cfg = copy.deepcopy(base_config_dict)
126132
cfg["app"]["port"] = port

0 commit comments

Comments
 (0)