Tests: Reorganize test suite into functional subdirectories
- Categorized scripts into tests/unit/, tests/integration/, tests/e2e/, and tests/tools/. - Adopted consistent naming prefixes (test_unit_*, test_int_*, test_e2e_*, tool_*). - Renamed conftest_mock.py to mock_config_helper.py for clarity. - Updated test_int_boot_diagnosis.py with sys.path setup for root-level execution.
This commit is contained in:
70
tests/tools/tool_generate_registry.py
Normal file
70
tests/tools/tool_generate_registry.py
Normal file
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
import datetime
|
||||
import sqlalchemy
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
# 1. Setup Path to ensure we can import the app
|
||||
sys.path.append("/srv/aether_api")
|
||||
sys.path.append(os.getcwd()) # For local execution
|
||||
|
||||
# 2. Mock app.config BEFORE importing app modules
|
||||
mock_config = MagicMock()
|
||||
mock_config.settings = MagicMock()
|
||||
sys.modules["app.config"] = mock_config
|
||||
|
||||
# 3. Setup REAL DB connection for introspection
|
||||
DB_USER = "aether_dev"
|
||||
DB_PASS = "$1sky.AE_dev.2023"
|
||||
DB_SERVER = "vpn-db.oneskyit.com"
|
||||
DB_PORT = "3306"
|
||||
DB_NAME = "aether_dev"
|
||||
DB_URI = f"mysql://{DB_USER}:{DB_PASS}@{DB_SERVER}:{DB_PORT}/{DB_NAME}"
|
||||
|
||||
mock_db = MagicMock()
|
||||
mock_db.execute = lambda stmt: engine.execute(stmt)
|
||||
engine = sqlalchemy.create_engine(DB_URI)
|
||||
sys.modules["app.db_sql"] = MagicMock(db=mock_db)
|
||||
|
||||
def type_handler(x):
|
||||
if isinstance(x, (datetime.datetime, datetime.date)):
|
||||
return x.isoformat()
|
||||
if isinstance(x, type):
|
||||
return x.__name__
|
||||
return str(x)
|
||||
|
||||
def export_registry():
|
||||
try:
|
||||
from app.ae_obj_types_def import obj_type_kv_li
|
||||
from app.lib_schema_v3 import get_object_schema_info
|
||||
except ImportError as e:
|
||||
print(f"Error: Could not import Aether API definitions. {e}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
final_output = {}
|
||||
allowed_keys = ["tbl", "tbl_default", "tbl_update", "table_name", "tbl_name_update", "searchable_fields", "exp_default"]
|
||||
|
||||
for obj_key, obj_def in obj_type_kv_li.items():
|
||||
final_output[obj_key] = {}
|
||||
for k in allowed_keys:
|
||||
if k in obj_def: final_output[obj_key][k] = obj_def[k]
|
||||
|
||||
for k in ["mdl", "mdl_out", "mdl_in", "mdl_default"]:
|
||||
if k in obj_def:
|
||||
model = obj_def[k]
|
||||
try:
|
||||
if hasattr(model, "schema"): final_output[obj_key][f"{k}_schema"] = model.schema()
|
||||
final_output[obj_key][k] = model.__name__
|
||||
except Exception: final_output[obj_key][k] = str(model)
|
||||
|
||||
try:
|
||||
schema_info = get_object_schema_info(obj_key)
|
||||
if "database" in schema_info: final_output[obj_key]["db_schema"] = schema_info["database"]
|
||||
except Exception as e: final_output[obj_key]["db_schema_error"] = str(e)
|
||||
|
||||
print(json.dumps(final_output, indent=2, default=type_handler))
|
||||
|
||||
if __name__ == "__main__":
|
||||
export_registry()
|
||||
60
tests/tools/tool_mcp_docker_explorer.py
Normal file
60
tests/tools/tool_mcp_docker_explorer.py
Normal file
@@ -0,0 +1,60 @@
|
||||
import asyncio
|
||||
import sys
|
||||
import json
|
||||
from mcp import ClientSession, StdioServerParameters
|
||||
from mcp.client.stdio import stdio_client
|
||||
|
||||
async def run_docker_mcp_explorer():
|
||||
# Define the server parameters to run the Docker MCP server via npx
|
||||
# Using the official Docker MCP server from the Model Context Protocol organization
|
||||
server_params = StdioServerParameters(
|
||||
command="npx",
|
||||
args=["-y", "@modelcontextprotocol/server-docker"],
|
||||
env=None
|
||||
)
|
||||
|
||||
print("--- Connecting to Docker MCP Server ---")
|
||||
|
||||
try:
|
||||
async with stdio_client(server_params) as (read, write):
|
||||
async with ClientSession(read, write) as session:
|
||||
# Initialize the session
|
||||
print("Initializing session...")
|
||||
await session.initialize()
|
||||
|
||||
# 1. List available tools
|
||||
print("\n--- Available Tools ---")
|
||||
tools_result = await session.list_tools()
|
||||
for tool in tools_result.tools:
|
||||
print(f"- {tool.name}: {tool.description}")
|
||||
|
||||
# 2. Call 'docker_list_containers'
|
||||
print("\n--- Calling 'docker_list_containers' ---")
|
||||
# The official server tool name is 'docker_list_containers'
|
||||
# It doesn't require arguments for a basic list
|
||||
containers_result = await session.call_tool("docker_list_containers", arguments={})
|
||||
|
||||
# The result comes back as a list of Content objects
|
||||
if containers_result.content:
|
||||
for item in containers_result.content:
|
||||
if item.type == 'text':
|
||||
# Parse the text (which is usually a JSON string for this tool)
|
||||
try:
|
||||
containers = json.loads(item.text)
|
||||
print(f"Found {len(containers)} containers:")
|
||||
for c in containers:
|
||||
status = c.get('Status', 'Unknown')
|
||||
names = ", ".join(c.get('Names', []))
|
||||
print(f" [{c.get('Id')[:12]}] {names} ({status})")
|
||||
except json.JSONDecodeError:
|
||||
print(item.text)
|
||||
else:
|
||||
print("No containers found or empty response.")
|
||||
|
||||
except Exception as e:
|
||||
print(f"\nError: {e}")
|
||||
if "npx" in str(e):
|
||||
print("Ensure 'npx' is installed and available in your PATH.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(run_docker_mcp_explorer())
|
||||
Reference in New Issue
Block a user