mcp-proxy-adapter 2.0.1__py3-none-any.whl โ 6.9.50__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of mcp-proxy-adapter might be problematic. Click here for more details.
- mcp_proxy_adapter/__init__.py +47 -0
- mcp_proxy_adapter/__main__.py +13 -0
- mcp_proxy_adapter/api/__init__.py +0 -0
- mcp_proxy_adapter/api/app.py +66 -0
- mcp_proxy_adapter/api/core/__init__.py +18 -0
- mcp_proxy_adapter/api/core/app_factory.py +400 -0
- mcp_proxy_adapter/api/core/lifespan_manager.py +55 -0
- mcp_proxy_adapter/api/core/registration_context.py +356 -0
- mcp_proxy_adapter/api/core/registration_manager.py +307 -0
- mcp_proxy_adapter/api/core/registration_tasks.py +84 -0
- mcp_proxy_adapter/api/core/ssl_context_factory.py +88 -0
- mcp_proxy_adapter/api/handlers.py +181 -0
- mcp_proxy_adapter/api/middleware/__init__.py +21 -0
- mcp_proxy_adapter/api/middleware/base.py +54 -0
- mcp_proxy_adapter/api/middleware/command_permission_middleware.py +73 -0
- mcp_proxy_adapter/api/middleware/error_handling.py +76 -0
- mcp_proxy_adapter/api/middleware/factory.py +147 -0
- mcp_proxy_adapter/api/middleware/logging.py +31 -0
- mcp_proxy_adapter/api/middleware/performance.py +51 -0
- mcp_proxy_adapter/api/middleware/protocol_middleware.py +140 -0
- mcp_proxy_adapter/api/middleware/transport_middleware.py +87 -0
- mcp_proxy_adapter/api/middleware/unified_security.py +223 -0
- mcp_proxy_adapter/api/middleware/user_info_middleware.py +132 -0
- mcp_proxy_adapter/api/openapi/__init__.py +21 -0
- mcp_proxy_adapter/api/openapi/command_integration.py +105 -0
- mcp_proxy_adapter/api/openapi/openapi_generator.py +40 -0
- mcp_proxy_adapter/api/openapi/openapi_registry.py +62 -0
- mcp_proxy_adapter/api/openapi/schema_loader.py +116 -0
- mcp_proxy_adapter/api/schemas.py +270 -0
- mcp_proxy_adapter/api/tool_integration.py +131 -0
- mcp_proxy_adapter/api/tools.py +163 -0
- mcp_proxy_adapter/cli/__init__.py +12 -0
- mcp_proxy_adapter/cli/commands/__init__.py +15 -0
- mcp_proxy_adapter/cli/commands/client.py +100 -0
- mcp_proxy_adapter/cli/commands/config_generate.py +105 -0
- mcp_proxy_adapter/cli/commands/config_validate.py +94 -0
- mcp_proxy_adapter/cli/commands/generate.py +259 -0
- mcp_proxy_adapter/cli/commands/server.py +174 -0
- mcp_proxy_adapter/cli/commands/sets.py +132 -0
- mcp_proxy_adapter/cli/commands/testconfig.py +177 -0
- mcp_proxy_adapter/cli/examples/__init__.py +8 -0
- mcp_proxy_adapter/cli/examples/http_basic.py +82 -0
- mcp_proxy_adapter/cli/examples/https_token.py +96 -0
- mcp_proxy_adapter/cli/examples/mtls_roles.py +103 -0
- mcp_proxy_adapter/cli/main.py +63 -0
- mcp_proxy_adapter/cli/parser.py +338 -0
- mcp_proxy_adapter/cli/validators.py +231 -0
- mcp_proxy_adapter/client/jsonrpc_client/__init__.py +9 -0
- mcp_proxy_adapter/client/jsonrpc_client/client.py +42 -0
- mcp_proxy_adapter/client/jsonrpc_client/command_api.py +45 -0
- mcp_proxy_adapter/client/jsonrpc_client/proxy_api.py +224 -0
- mcp_proxy_adapter/client/jsonrpc_client/queue_api.py +60 -0
- mcp_proxy_adapter/client/jsonrpc_client/transport.py +108 -0
- mcp_proxy_adapter/client/proxy.py +123 -0
- mcp_proxy_adapter/commands/__init__.py +66 -0
- mcp_proxy_adapter/commands/auth_validation_command.py +69 -0
- mcp_proxy_adapter/commands/base.py +389 -0
- mcp_proxy_adapter/commands/builtin_commands.py +30 -0
- mcp_proxy_adapter/commands/catalog/__init__.py +20 -0
- mcp_proxy_adapter/commands/catalog/catalog_loader.py +34 -0
- mcp_proxy_adapter/commands/catalog/catalog_manager.py +122 -0
- mcp_proxy_adapter/commands/catalog/catalog_syncer.py +149 -0
- mcp_proxy_adapter/commands/catalog/command_catalog.py +43 -0
- mcp_proxy_adapter/commands/catalog/dependency_manager.py +37 -0
- mcp_proxy_adapter/commands/catalog_manager.py +97 -0
- mcp_proxy_adapter/commands/cert_monitor_command.py +552 -0
- mcp_proxy_adapter/commands/certificate_management_command.py +562 -0
- mcp_proxy_adapter/commands/command_registry.py +298 -0
- mcp_proxy_adapter/commands/config_command.py +102 -0
- mcp_proxy_adapter/commands/dependency_container.py +40 -0
- mcp_proxy_adapter/commands/dependency_manager.py +143 -0
- mcp_proxy_adapter/commands/echo_command.py +48 -0
- mcp_proxy_adapter/commands/health_command.py +142 -0
- mcp_proxy_adapter/commands/help_command.py +175 -0
- mcp_proxy_adapter/commands/hooks.py +172 -0
- mcp_proxy_adapter/commands/key_management_command.py +484 -0
- mcp_proxy_adapter/commands/load_command.py +123 -0
- mcp_proxy_adapter/commands/plugins_command.py +246 -0
- mcp_proxy_adapter/commands/protocol_management_command.py +216 -0
- mcp_proxy_adapter/commands/proxy_registration_command.py +319 -0
- mcp_proxy_adapter/commands/queue_commands.py +750 -0
- mcp_proxy_adapter/commands/registration_status_command.py +76 -0
- mcp_proxy_adapter/commands/registry/__init__.py +18 -0
- mcp_proxy_adapter/commands/registry/command_info.py +103 -0
- mcp_proxy_adapter/commands/registry/command_loader.py +207 -0
- mcp_proxy_adapter/commands/registry/command_manager.py +119 -0
- mcp_proxy_adapter/commands/registry/command_registry.py +217 -0
- mcp_proxy_adapter/commands/reload_command.py +136 -0
- mcp_proxy_adapter/commands/result.py +157 -0
- mcp_proxy_adapter/commands/role_test_command.py +99 -0
- mcp_proxy_adapter/commands/roles_management_command.py +502 -0
- mcp_proxy_adapter/commands/security_command.py +472 -0
- mcp_proxy_adapter/commands/settings_command.py +113 -0
- mcp_proxy_adapter/commands/ssl_setup_command.py +306 -0
- mcp_proxy_adapter/commands/token_management_command.py +500 -0
- mcp_proxy_adapter/commands/transport_management_command.py +129 -0
- mcp_proxy_adapter/commands/unload_command.py +92 -0
- mcp_proxy_adapter/config.py +32 -0
- mcp_proxy_adapter/core/__init__.py +8 -0
- mcp_proxy_adapter/core/app_factory.py +560 -0
- mcp_proxy_adapter/core/app_runner.py +318 -0
- mcp_proxy_adapter/core/auth_validator.py +508 -0
- mcp_proxy_adapter/core/certificate/__init__.py +20 -0
- mcp_proxy_adapter/core/certificate/certificate_creator.py +372 -0
- mcp_proxy_adapter/core/certificate/certificate_extractor.py +185 -0
- mcp_proxy_adapter/core/certificate/certificate_utils.py +249 -0
- mcp_proxy_adapter/core/certificate/certificate_validator.py +481 -0
- mcp_proxy_adapter/core/certificate/ssl_context_manager.py +65 -0
- mcp_proxy_adapter/core/certificate_utils.py +249 -0
- mcp_proxy_adapter/core/client.py +608 -0
- mcp_proxy_adapter/core/client_manager.py +271 -0
- mcp_proxy_adapter/core/client_security.py +411 -0
- mcp_proxy_adapter/core/config/__init__.py +18 -0
- mcp_proxy_adapter/core/config/config.py +237 -0
- mcp_proxy_adapter/core/config/config_factory.py +22 -0
- mcp_proxy_adapter/core/config/config_loader.py +66 -0
- mcp_proxy_adapter/core/config/feature_manager.py +31 -0
- mcp_proxy_adapter/core/config/simple_config.py +204 -0
- mcp_proxy_adapter/core/config/simple_config_generator.py +131 -0
- mcp_proxy_adapter/core/config/simple_config_validator.py +476 -0
- mcp_proxy_adapter/core/config_converter.py +252 -0
- mcp_proxy_adapter/core/config_validator.py +211 -0
- mcp_proxy_adapter/core/crl_utils.py +362 -0
- mcp_proxy_adapter/core/errors.py +276 -0
- mcp_proxy_adapter/core/job_manager.py +54 -0
- mcp_proxy_adapter/core/logging.py +250 -0
- mcp_proxy_adapter/core/mtls_asgi.py +140 -0
- mcp_proxy_adapter/core/mtls_asgi_app.py +187 -0
- mcp_proxy_adapter/core/mtls_proxy.py +229 -0
- mcp_proxy_adapter/core/mtls_server.py +154 -0
- mcp_proxy_adapter/core/protocol_manager.py +232 -0
- mcp_proxy_adapter/core/proxy/__init__.py +19 -0
- mcp_proxy_adapter/core/proxy/auth_manager.py +26 -0
- mcp_proxy_adapter/core/proxy/proxy_registration_manager.py +160 -0
- mcp_proxy_adapter/core/proxy/registration_client.py +186 -0
- mcp_proxy_adapter/core/proxy/ssl_manager.py +101 -0
- mcp_proxy_adapter/core/proxy_client.py +184 -0
- mcp_proxy_adapter/core/proxy_registration.py +80 -0
- mcp_proxy_adapter/core/role_utils.py +103 -0
- mcp_proxy_adapter/core/security_adapter.py +343 -0
- mcp_proxy_adapter/core/security_factory.py +96 -0
- mcp_proxy_adapter/core/security_integration.py +342 -0
- mcp_proxy_adapter/core/server_adapter.py +251 -0
- mcp_proxy_adapter/core/server_engine.py +217 -0
- mcp_proxy_adapter/core/settings.py +260 -0
- mcp_proxy_adapter/core/signal_handler.py +107 -0
- mcp_proxy_adapter/core/ssl_utils.py +161 -0
- mcp_proxy_adapter/core/transport_manager.py +153 -0
- mcp_proxy_adapter/core/unified_config_adapter.py +471 -0
- mcp_proxy_adapter/core/utils.py +101 -0
- mcp_proxy_adapter/core/validation/__init__.py +21 -0
- mcp_proxy_adapter/core/validation/config_validator.py +219 -0
- mcp_proxy_adapter/core/validation/file_validator.py +131 -0
- mcp_proxy_adapter/core/validation/protocol_validator.py +205 -0
- mcp_proxy_adapter/core/validation/security_validator.py +140 -0
- mcp_proxy_adapter/core/validation/validation_result.py +27 -0
- mcp_proxy_adapter/custom_openapi.py +58 -0
- mcp_proxy_adapter/examples/__init__.py +16 -0
- mcp_proxy_adapter/examples/basic_framework/__init__.py +9 -0
- mcp_proxy_adapter/examples/basic_framework/commands/__init__.py +4 -0
- mcp_proxy_adapter/examples/basic_framework/hooks/__init__.py +4 -0
- mcp_proxy_adapter/examples/basic_framework/main.py +52 -0
- mcp_proxy_adapter/examples/bugfix_certificate_config.py +261 -0
- mcp_proxy_adapter/examples/cert_manager_bugfix.py +203 -0
- mcp_proxy_adapter/examples/check_config.py +413 -0
- mcp_proxy_adapter/examples/client_usage_example.py +164 -0
- mcp_proxy_adapter/examples/commands/__init__.py +5 -0
- mcp_proxy_adapter/examples/config_builder.py +234 -0
- mcp_proxy_adapter/examples/config_cli.py +282 -0
- mcp_proxy_adapter/examples/create_test_configs.py +174 -0
- mcp_proxy_adapter/examples/debug_request_state.py +130 -0
- mcp_proxy_adapter/examples/debug_role_chain.py +191 -0
- mcp_proxy_adapter/examples/demo_client.py +287 -0
- mcp_proxy_adapter/examples/full_application/__init__.py +12 -0
- mcp_proxy_adapter/examples/full_application/commands/__init__.py +8 -0
- mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +45 -0
- mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +52 -0
- mcp_proxy_adapter/examples/full_application/commands/echo_command.py +32 -0
- mcp_proxy_adapter/examples/full_application/commands/help_command.py +54 -0
- mcp_proxy_adapter/examples/full_application/commands/list_command.py +57 -0
- mcp_proxy_adapter/examples/full_application/hooks/__init__.py +5 -0
- mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +29 -0
- mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +27 -0
- mcp_proxy_adapter/examples/full_application/main.py +311 -0
- mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +161 -0
- mcp_proxy_adapter/examples/full_application/run_mtls.py +252 -0
- mcp_proxy_adapter/examples/full_application/run_simple.py +152 -0
- mcp_proxy_adapter/examples/full_application/test_minimal_server.py +45 -0
- mcp_proxy_adapter/examples/full_application/test_server.py +163 -0
- mcp_proxy_adapter/examples/full_application/test_simple_server.py +62 -0
- mcp_proxy_adapter/examples/generate_config.py +502 -0
- mcp_proxy_adapter/examples/proxy_registration_example.py +335 -0
- mcp_proxy_adapter/examples/queue_demo_simple.py +632 -0
- mcp_proxy_adapter/examples/queue_integration_example.py +578 -0
- mcp_proxy_adapter/examples/queue_server_demo.py +82 -0
- mcp_proxy_adapter/examples/queue_server_example.py +85 -0
- mcp_proxy_adapter/examples/queue_server_simple.py +173 -0
- mcp_proxy_adapter/examples/required_certificates.py +208 -0
- mcp_proxy_adapter/examples/run_example.py +77 -0
- mcp_proxy_adapter/examples/run_full_test_suite.py +619 -0
- mcp_proxy_adapter/examples/run_proxy_server.py +153 -0
- mcp_proxy_adapter/examples/run_security_tests_fixed.py +435 -0
- mcp_proxy_adapter/examples/security_test/__init__.py +18 -0
- mcp_proxy_adapter/examples/security_test/auth_manager.py +14 -0
- mcp_proxy_adapter/examples/security_test/ssl_context_manager.py +28 -0
- mcp_proxy_adapter/examples/security_test/test_client.py +159 -0
- mcp_proxy_adapter/examples/security_test/test_result.py +22 -0
- mcp_proxy_adapter/examples/security_test_client.py +72 -0
- mcp_proxy_adapter/examples/setup/__init__.py +24 -0
- mcp_proxy_adapter/examples/setup/certificate_manager.py +215 -0
- mcp_proxy_adapter/examples/setup/config_generator.py +12 -0
- mcp_proxy_adapter/examples/setup/config_validator.py +118 -0
- mcp_proxy_adapter/examples/setup/environment_setup.py +62 -0
- mcp_proxy_adapter/examples/setup/test_files_generator.py +10 -0
- mcp_proxy_adapter/examples/setup/test_runner.py +89 -0
- mcp_proxy_adapter/examples/setup_test_environment.py +235 -0
- mcp_proxy_adapter/examples/simple_protocol_test.py +125 -0
- mcp_proxy_adapter/examples/test_chk_hostname_automated.py +211 -0
- mcp_proxy_adapter/examples/test_config.py +205 -0
- mcp_proxy_adapter/examples/test_config_builder.py +110 -0
- mcp_proxy_adapter/examples/test_examples.py +308 -0
- mcp_proxy_adapter/examples/test_framework_complete.py +267 -0
- mcp_proxy_adapter/examples/test_mcp_server.py +187 -0
- mcp_proxy_adapter/examples/test_protocol_examples.py +337 -0
- mcp_proxy_adapter/examples/universal_client.py +674 -0
- mcp_proxy_adapter/examples/update_config_certificates.py +135 -0
- mcp_proxy_adapter/examples/validate_generator_compatibility.py +385 -0
- mcp_proxy_adapter/examples/validate_generator_compatibility_simple.py +61 -0
- mcp_proxy_adapter/integrations/__init__.py +25 -0
- mcp_proxy_adapter/integrations/queuemgr_integration.py +462 -0
- mcp_proxy_adapter/main.py +311 -0
- mcp_proxy_adapter/openapi.py +375 -0
- mcp_proxy_adapter/schemas/base_schema.json +114 -0
- mcp_proxy_adapter/schemas/openapi_schema.json +314 -0
- mcp_proxy_adapter/schemas/roles.json +37 -0
- mcp_proxy_adapter/schemas/roles_schema.json +162 -0
- mcp_proxy_adapter/version.py +5 -0
- mcp_proxy_adapter-6.9.50.dist-info/METADATA +1088 -0
- mcp_proxy_adapter-6.9.50.dist-info/RECORD +242 -0
- {mcp_proxy_adapter-2.0.1.dist-info โ mcp_proxy_adapter-6.9.50.dist-info}/WHEEL +1 -1
- mcp_proxy_adapter-6.9.50.dist-info/entry_points.txt +14 -0
- mcp_proxy_adapter-6.9.50.dist-info/top_level.txt +1 -0
- adapters/__init__.py +0 -16
- analyzers/__init__.py +0 -14
- analyzers/docstring_analyzer.py +0 -199
- analyzers/type_analyzer.py +0 -151
- cli/__init__.py +0 -12
- cli/__main__.py +0 -79
- cli/command_runner.py +0 -233
- dispatchers/__init__.py +0 -14
- dispatchers/base_dispatcher.py +0 -85
- dispatchers/json_rpc_dispatcher.py +0 -198
- generators/__init__.py +0 -14
- generators/endpoint_generator.py +0 -172
- generators/openapi_generator.py +0 -254
- generators/rest_api_generator.py +0 -207
- mcp_proxy_adapter-2.0.1.dist-info/METADATA +0 -272
- mcp_proxy_adapter-2.0.1.dist-info/RECORD +0 -28
- mcp_proxy_adapter-2.0.1.dist-info/licenses/LICENSE +0 -21
- mcp_proxy_adapter-2.0.1.dist-info/top_level.txt +0 -7
- openapi_schema/__init__.py +0 -38
- openapi_schema/command_registry.py +0 -312
- openapi_schema/rest_schema.py +0 -510
- openapi_schema/rpc_generator.py +0 -307
- openapi_schema/rpc_schema.py +0 -416
- validators/__init__.py +0 -14
- validators/base_validator.py +0 -23
- validators/docstring_validator.py +0 -75
- validators/metadata_validator.py +0 -76
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Author: Vasiliy Zdanovskiy
|
|
4
|
+
email: vasilyvz@gmail.com
|
|
5
|
+
Script for testing MCP Proxy Adapter configurations.
|
|
6
|
+
Tests a specific configuration by creating an application and validating it.
|
|
7
|
+
Uses mcp_security_framework for security validation.
|
|
8
|
+
"""
|
|
9
|
+
import json
|
|
10
|
+
import os
|
|
11
|
+
import sys
|
|
12
|
+
import argparse
|
|
13
|
+
import time
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
|
|
16
|
+
# Import mcp_security_framework
|
|
17
|
+
try:
|
|
18
|
+
from mcp_security_framework import SecurityManager
|
|
19
|
+
from mcp_security_framework.schemas.config import SecurityConfig
|
|
20
|
+
|
|
21
|
+
SECURITY_FRAMEWORK_AVAILABLE = True
|
|
22
|
+
except ImportError:
|
|
23
|
+
SECURITY_FRAMEWORK_AVAILABLE = False
|
|
24
|
+
print("Warning: mcp_security_framework not available")
|
|
25
|
+
# Add parent directory to path to import mcp_proxy_adapter
|
|
26
|
+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "../.."))
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def validate_config_with_new_system(config: Dict[str, Any]) -> bool:
|
|
30
|
+
"""
|
|
31
|
+
Validate configuration using the new validation system.
|
|
32
|
+
Args:
|
|
33
|
+
config: Configuration dictionary
|
|
34
|
+
Returns:
|
|
35
|
+
True if validation passed, False otherwise
|
|
36
|
+
"""
|
|
37
|
+
try:
|
|
38
|
+
from mcp_proxy_adapter.core.config_validator import ConfigValidator
|
|
39
|
+
|
|
40
|
+
print("๐ Validating configuration with new validation system...")
|
|
41
|
+
validator = ConfigValidator()
|
|
42
|
+
validator.config_data = config
|
|
43
|
+
results = validator.validate_config()
|
|
44
|
+
|
|
45
|
+
if results:
|
|
46
|
+
print("โ ๏ธ Validation issues found:")
|
|
47
|
+
for result in results:
|
|
48
|
+
level_symbol = {
|
|
49
|
+
"error": "โ",
|
|
50
|
+
"warning": "โ ๏ธ",
|
|
51
|
+
"info": "โน๏ธ"
|
|
52
|
+
}[result.level]
|
|
53
|
+
print(f" {level_symbol} {result.message}")
|
|
54
|
+
if result.suggestion:
|
|
55
|
+
print(f" Suggestion: {result.suggestion}")
|
|
56
|
+
return False
|
|
57
|
+
else:
|
|
58
|
+
print("โ
Configuration validation passed!")
|
|
59
|
+
return True
|
|
60
|
+
|
|
61
|
+
except ImportError:
|
|
62
|
+
print("โ ๏ธ New validation system not available")
|
|
63
|
+
return True
|
|
64
|
+
except Exception as e:
|
|
65
|
+
print(f"โ Validation error: {e}")
|
|
66
|
+
return False
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def validate_security_config(config: Dict[str, Any]) -> bool:
|
|
70
|
+
"""
|
|
71
|
+
Validate security configuration using mcp_security_framework (legacy).
|
|
72
|
+
Args:
|
|
73
|
+
config: Configuration dictionary
|
|
74
|
+
Returns:
|
|
75
|
+
True if validation passed, False otherwise
|
|
76
|
+
"""
|
|
77
|
+
if not SECURITY_FRAMEWORK_AVAILABLE:
|
|
78
|
+
print("โ ๏ธ Skipping security validation (mcp_security_framework not available)")
|
|
79
|
+
return True
|
|
80
|
+
try:
|
|
81
|
+
security_section = config.get("security", {})
|
|
82
|
+
if not security_section.get("enabled", False):
|
|
83
|
+
print("๐ Security framework disabled in configuration")
|
|
84
|
+
return True
|
|
85
|
+
print("๐ Validating security configuration with mcp_security_framework...")
|
|
86
|
+
# Create SecurityConfig from configuration
|
|
87
|
+
security_config = SecurityConfig(
|
|
88
|
+
auth=security_section.get("auth", {}),
|
|
89
|
+
ssl=security_section.get("ssl", {}),
|
|
90
|
+
permissions=security_section.get("permissions", {}),
|
|
91
|
+
rate_limit=security_section.get("rate_limit", {}),
|
|
92
|
+
)
|
|
93
|
+
# Create SecurityManager for validation
|
|
94
|
+
security_manager = SecurityManager(security_config)
|
|
95
|
+
# Validate configuration
|
|
96
|
+
validation_result = security_manager.validate_configuration()
|
|
97
|
+
if validation_result.is_valid:
|
|
98
|
+
print("โ
Security configuration validation passed")
|
|
99
|
+
return True
|
|
100
|
+
else:
|
|
101
|
+
print("โ Security configuration validation failed:")
|
|
102
|
+
for error in validation_result.errors:
|
|
103
|
+
print(f" - {error}")
|
|
104
|
+
return False
|
|
105
|
+
except Exception as e:
|
|
106
|
+
print(f"โ Error validating security configuration: {e}")
|
|
107
|
+
return False
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def test_configuration(config_path: str, timeout: int = 30) -> bool:
|
|
111
|
+
"""
|
|
112
|
+
Test a configuration by creating an application and validating it.
|
|
113
|
+
Args:
|
|
114
|
+
config_path: Path to configuration file
|
|
115
|
+
timeout: Timeout in seconds for server startup
|
|
116
|
+
Returns:
|
|
117
|
+
True if test passed, False otherwise
|
|
118
|
+
"""
|
|
119
|
+
print(f"๐งช Testing configuration: {config_path}")
|
|
120
|
+
print("=" * 60)
|
|
121
|
+
try:
|
|
122
|
+
# Load configuration
|
|
123
|
+
with open(config_path, "r") as f:
|
|
124
|
+
config = json.load(f)
|
|
125
|
+
# Import required modules
|
|
126
|
+
from mcp_proxy_adapter.core.app_factory import create_application
|
|
127
|
+
from mcp_proxy_adapter.core.app_runner import ApplicationRunner
|
|
128
|
+
|
|
129
|
+
# Create application
|
|
130
|
+
print("๐ง Creating application...")
|
|
131
|
+
app = create_application(config)
|
|
132
|
+
print("โ
Application created successfully")
|
|
133
|
+
# Create runner and validate configuration
|
|
134
|
+
print("๐ Validating configuration...")
|
|
135
|
+
runner = ApplicationRunner(app, config)
|
|
136
|
+
errors = runner.validate_configuration()
|
|
137
|
+
if errors:
|
|
138
|
+
print("โ Configuration validation failed:")
|
|
139
|
+
for error in errors:
|
|
140
|
+
print(f" - {error}")
|
|
141
|
+
return False
|
|
142
|
+
print("โ
Configuration validation passed")
|
|
143
|
+
# Validate configuration with new system
|
|
144
|
+
if not validate_config_with_new_system(config):
|
|
145
|
+
return False
|
|
146
|
+
|
|
147
|
+
# Validate security configuration (legacy)
|
|
148
|
+
if not validate_security_config(config):
|
|
149
|
+
return False
|
|
150
|
+
# Test server startup (without actually starting)
|
|
151
|
+
print("๐ Testing server startup...")
|
|
152
|
+
server_config = config.get("server", {})
|
|
153
|
+
host = server_config.get("host", "127.0.0.1")
|
|
154
|
+
port = server_config.get("port", 8000)
|
|
155
|
+
print(f"โ
Server configuration: {host}:{port}")
|
|
156
|
+
# Test SSL configuration if enabled
|
|
157
|
+
ssl_config = config.get("ssl", {})
|
|
158
|
+
if ssl_config.get("enabled", False):
|
|
159
|
+
print("๐ SSL configuration:")
|
|
160
|
+
print(f" - Certificate: {ssl_config.get('cert_file', 'N/A')}")
|
|
161
|
+
print(f" - Key: {ssl_config.get('key_file', 'N/A')}")
|
|
162
|
+
print(f" - Client verification: {ssl_config.get('verify_client', False)}")
|
|
163
|
+
# Test security configuration if enabled
|
|
164
|
+
security_config = config.get("security", {})
|
|
165
|
+
if security_config.get("enabled", False):
|
|
166
|
+
print("๐ Security configuration:")
|
|
167
|
+
auth_config = security_config.get("auth", {})
|
|
168
|
+
if auth_config.get("enabled", False):
|
|
169
|
+
methods = auth_config.get("methods", [])
|
|
170
|
+
print(f" - Authentication methods: {methods}")
|
|
171
|
+
permissions_config = security_config.get("permissions", {})
|
|
172
|
+
if permissions_config.get("enabled", False):
|
|
173
|
+
print(f" - Roles file: {permissions_config.get('roles_file', 'N/A')}")
|
|
174
|
+
# Test protocol configuration
|
|
175
|
+
protocols_config = config.get("protocols", {})
|
|
176
|
+
if protocols_config.get("enabled", False):
|
|
177
|
+
allowed_protocols = protocols_config.get("allowed_protocols", [])
|
|
178
|
+
print(f"๐ Allowed protocols: {allowed_protocols}")
|
|
179
|
+
print("=" * 60)
|
|
180
|
+
print("โ
Configuration test completed successfully!")
|
|
181
|
+
return True
|
|
182
|
+
except Exception as e:
|
|
183
|
+
print(f"โ Configuration test failed: {e}")
|
|
184
|
+
return False
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def main():
|
|
188
|
+
"""Main function for command line execution."""
|
|
189
|
+
parser = argparse.ArgumentParser(description="Test MCP Proxy Adapter configuration")
|
|
190
|
+
parser.add_argument(
|
|
191
|
+
"--config", "-c", required=True, help="Path to configuration file"
|
|
192
|
+
)
|
|
193
|
+
parser.add_argument(
|
|
194
|
+
"--timeout", "-t", type=int, default=30, help="Timeout in seconds"
|
|
195
|
+
)
|
|
196
|
+
args = parser.parse_args()
|
|
197
|
+
if not os.path.exists(args.config):
|
|
198
|
+
print(f"โ Configuration file not found: {args.config}")
|
|
199
|
+
return 1
|
|
200
|
+
success = test_configuration(args.config, args.timeout)
|
|
201
|
+
return 0 if success else 1
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
if __name__ == "__main__":
|
|
205
|
+
exit(main())
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Comprehensive Tests for Configuration Builder
|
|
4
|
+
Tests all combinations of protocols, authentication methods, and other parameters.
|
|
5
|
+
|
|
6
|
+
Author: Vasiliy Zdanovskiy
|
|
7
|
+
email: vasilyvz@gmail.com
|
|
8
|
+
"""
|
|
9
|
+
import json
|
|
10
|
+
import tempfile
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
from config_builder import ConfigBuilder, ConfigFactory, Protocol, AuthMethod
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class TestConfigBuilder:
|
|
17
|
+
"""Test cases for ConfigBuilder class."""
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class TestConfigFactory:
|
|
38
|
+
"""Test cases for ConfigFactory class."""
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class TestConfigurationCombinations:
|
|
50
|
+
"""Test all possible combinations of configuration parameters."""
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def run_comprehensive_tests():
|
|
58
|
+
"""Run comprehensive tests and generate report."""
|
|
59
|
+
print("๐งช Running Comprehensive Configuration Builder Tests")
|
|
60
|
+
print("=" * 60)
|
|
61
|
+
|
|
62
|
+
test_classes = [
|
|
63
|
+
TestConfigBuilder,
|
|
64
|
+
TestConfigFactory,
|
|
65
|
+
TestConfigurationCombinations
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
total_tests = 0
|
|
69
|
+
passed_tests = 0
|
|
70
|
+
failed_tests = []
|
|
71
|
+
|
|
72
|
+
for test_class in test_classes:
|
|
73
|
+
print(f"\n๐ Testing {test_class.__name__}")
|
|
74
|
+
print("-" * 40)
|
|
75
|
+
|
|
76
|
+
test_instance = test_class()
|
|
77
|
+
test_methods = [method for method in dir(test_instance) if method.startswith('test_')]
|
|
78
|
+
|
|
79
|
+
for test_method in test_methods:
|
|
80
|
+
total_tests += 1
|
|
81
|
+
try:
|
|
82
|
+
getattr(test_instance, test_method)()
|
|
83
|
+
print(f"โ
{test_method}")
|
|
84
|
+
passed_tests += 1
|
|
85
|
+
except Exception as e:
|
|
86
|
+
print(f"โ {test_method}: {e}")
|
|
87
|
+
failed_tests.append(f"{test_class.__name__}.{test_method}: {e}")
|
|
88
|
+
|
|
89
|
+
# Print summary
|
|
90
|
+
print(f"\n{'=' * 60}")
|
|
91
|
+
print("๐ TEST SUMMARY")
|
|
92
|
+
print(f"{'=' * 60}")
|
|
93
|
+
print(f"Total tests: {total_tests}")
|
|
94
|
+
print(f"Passed: {passed_tests}")
|
|
95
|
+
print(f"Failed: {len(failed_tests)}")
|
|
96
|
+
print(f"Success rate: {(passed_tests/total_tests)*100:.1f}%")
|
|
97
|
+
|
|
98
|
+
if failed_tests:
|
|
99
|
+
print(f"\nโ Failed tests:")
|
|
100
|
+
for failure in failed_tests:
|
|
101
|
+
print(f" โข {failure}")
|
|
102
|
+
else:
|
|
103
|
+
print(f"\n๐ All tests passed!")
|
|
104
|
+
|
|
105
|
+
return len(failed_tests) == 0
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
if __name__ == "__main__":
|
|
109
|
+
success = run_comprehensive_tests()
|
|
110
|
+
exit(0 if success else 1)
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Test Examples Script
|
|
4
|
+
This script tests all examples with different configurations.
|
|
5
|
+
Author: Vasiliy Zdanovskiy
|
|
6
|
+
email: vasilyvz@gmail.com
|
|
7
|
+
"""
|
|
8
|
+
import json
|
|
9
|
+
import os
|
|
10
|
+
import subprocess
|
|
11
|
+
import time
|
|
12
|
+
import requests
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
# Configuration for testing
|
|
16
|
+
CONFIGS = {
|
|
17
|
+
"basic_framework": {
|
|
18
|
+
"http_simple": {"port": 8000, "ssl": False, "auth": False},
|
|
19
|
+
"https_simple": {"port": 8443, "ssl": True, "auth": False},
|
|
20
|
+
"http_auth": {"port": 8001, "ssl": False, "auth": True},
|
|
21
|
+
"https_auth": {"port": 8444, "ssl": True, "auth": True},
|
|
22
|
+
"mtls_no_roles": {"port": 9443, "ssl": True, "auth": True, "mtls": True},
|
|
23
|
+
"mtls_with_roles": {"port": 9444, "ssl": True, "auth": True, "mtls": True},
|
|
24
|
+
},
|
|
25
|
+
"full_application": {
|
|
26
|
+
"http_simple": {"port": 9000, "ssl": False, "auth": False},
|
|
27
|
+
"https_simple": {"port": 9445, "ssl": True, "auth": False},
|
|
28
|
+
"http_auth": {"port": 9001, "ssl": False, "auth": True},
|
|
29
|
+
"https_auth": {"port": 9446, "ssl": True, "auth": True},
|
|
30
|
+
"mtls_no_roles": {"port": 9447, "ssl": True, "auth": True, "mtls": True},
|
|
31
|
+
"mtls_with_roles": {"port": 9448, "ssl": True, "auth": True, "mtls": True},
|
|
32
|
+
},
|
|
33
|
+
}
|
|
34
|
+
API_KEYS = {"admin": "admin-secret-key-123", "user": "user-secret-key-456"}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class ExampleTester:
|
|
38
|
+
"""Test examples with different configurations."""
|
|
39
|
+
|
|
40
|
+
def __init__(self):
|
|
41
|
+
self.examples_dir = Path(__file__).parent
|
|
42
|
+
self.results = {}
|
|
43
|
+
self.processes = []
|
|
44
|
+
|
|
45
|
+
def generate_certificates(self):
|
|
46
|
+
"""Generate certificates for testing."""
|
|
47
|
+
print("๐ Generating certificates...")
|
|
48
|
+
cert_script = self.examples_dir.parent / "generate_certificates.py"
|
|
49
|
+
if cert_script.exists():
|
|
50
|
+
result = subprocess.run(
|
|
51
|
+
[sys.executable, str(cert_script)], capture_output=True, text=True
|
|
52
|
+
)
|
|
53
|
+
if result.returncode == 0:
|
|
54
|
+
print("โ
Certificates generated successfully")
|
|
55
|
+
return True
|
|
56
|
+
else:
|
|
57
|
+
print(f"โ Certificate generation failed: {result.stderr}")
|
|
58
|
+
return False
|
|
59
|
+
else:
|
|
60
|
+
print(
|
|
61
|
+
"โ ๏ธ Certificate generation script not found, using existing certificates"
|
|
62
|
+
)
|
|
63
|
+
return True
|
|
64
|
+
|
|
65
|
+
def start_server(self, example_type: str, config_name: str) -> subprocess.Popen:
|
|
66
|
+
"""Start a server with specific configuration."""
|
|
67
|
+
config_path = (
|
|
68
|
+
self.examples_dir / example_type / "configs" / f"{config_name}.json"
|
|
69
|
+
)
|
|
70
|
+
main_script = self.examples_dir / example_type / "main.py"
|
|
71
|
+
if not config_path.exists():
|
|
72
|
+
raise FileNotFoundError(f"Configuration file not found: {config_path}")
|
|
73
|
+
if not main_script.exists():
|
|
74
|
+
raise FileNotFoundError(f"Main script not found: {main_script}")
|
|
75
|
+
cmd = [sys.executable, str(main_script), "--config", str(config_path)]
|
|
76
|
+
print(f"๐ Starting {example_type} server with {config_name} config...")
|
|
77
|
+
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
78
|
+
# Wait for server to start
|
|
79
|
+
time.sleep(5)
|
|
80
|
+
return process
|
|
81
|
+
|
|
82
|
+
def test_health_endpoint(
|
|
83
|
+
self, port: int, ssl: bool = False, auth: bool = False, api_key: str = None
|
|
84
|
+
) -> Dict[str, Any]:
|
|
85
|
+
"""Test health endpoint."""
|
|
86
|
+
protocol = "https" if ssl else "http"
|
|
87
|
+
url = f"{protocol}://localhost:{port}/health"
|
|
88
|
+
headers = {}
|
|
89
|
+
if auth and api_key:
|
|
90
|
+
headers["X-API-Key"] = api_key
|
|
91
|
+
try:
|
|
92
|
+
response = requests.get(url, headers=headers, verify=False, timeout=10)
|
|
93
|
+
return {
|
|
94
|
+
"success": True,
|
|
95
|
+
"status_code": response.status_code,
|
|
96
|
+
"response": (
|
|
97
|
+
response.json()
|
|
98
|
+
if response.headers.get("content-type", "").startswith(
|
|
99
|
+
"application/json"
|
|
100
|
+
)
|
|
101
|
+
else response.text
|
|
102
|
+
),
|
|
103
|
+
}
|
|
104
|
+
except Exception as e:
|
|
105
|
+
return {"success": False, "error": str(e)}
|
|
106
|
+
|
|
107
|
+
def test_echo_command(
|
|
108
|
+
self, port: int, ssl: bool = False, auth: bool = False, api_key: str = None
|
|
109
|
+
) -> Dict[str, Any]:
|
|
110
|
+
"""Test echo command."""
|
|
111
|
+
protocol = "https" if ssl else "http"
|
|
112
|
+
url = f"{protocol}://localhost:{port}/cmd"
|
|
113
|
+
headers = {"Content-Type": "application/json"}
|
|
114
|
+
if auth and api_key:
|
|
115
|
+
headers["X-API-Key"] = api_key
|
|
116
|
+
data = {
|
|
117
|
+
"jsonrpc": "2.0",
|
|
118
|
+
"method": "echo",
|
|
119
|
+
"params": {"message": "Hello from test!"},
|
|
120
|
+
"id": 1,
|
|
121
|
+
}
|
|
122
|
+
try:
|
|
123
|
+
response = requests.post(
|
|
124
|
+
url, json=data, headers=headers, verify=False, timeout=10
|
|
125
|
+
)
|
|
126
|
+
return {
|
|
127
|
+
"success": True,
|
|
128
|
+
"status_code": response.status_code,
|
|
129
|
+
"response": response.json(),
|
|
130
|
+
}
|
|
131
|
+
except Exception as e:
|
|
132
|
+
return {"success": False, "error": str(e)}
|
|
133
|
+
|
|
134
|
+
def test_full_application_commands(
|
|
135
|
+
self, port: int, ssl: bool = False, auth: bool = False, api_key: str = None
|
|
136
|
+
) -> Dict[str, Any]:
|
|
137
|
+
"""Test full application specific commands."""
|
|
138
|
+
protocol = "https" if ssl else "http"
|
|
139
|
+
url = f"{protocol}://localhost:{port}/cmd"
|
|
140
|
+
headers = {"Content-Type": "application/json"}
|
|
141
|
+
if auth and api_key:
|
|
142
|
+
headers["X-API-Key"] = api_key
|
|
143
|
+
results = {}
|
|
144
|
+
# Test custom echo command
|
|
145
|
+
data = {
|
|
146
|
+
"jsonrpc": "2.0",
|
|
147
|
+
"method": "custom_echo",
|
|
148
|
+
"params": {"message": "Custom echo test", "repeat": 3},
|
|
149
|
+
"id": 1,
|
|
150
|
+
}
|
|
151
|
+
try:
|
|
152
|
+
response = requests.post(
|
|
153
|
+
url, json=data, headers=headers, verify=False, timeout=10
|
|
154
|
+
)
|
|
155
|
+
results["custom_echo"] = {
|
|
156
|
+
"success": True,
|
|
157
|
+
"status_code": response.status_code,
|
|
158
|
+
"response": response.json(),
|
|
159
|
+
}
|
|
160
|
+
except Exception as e:
|
|
161
|
+
results["custom_echo"] = {"success": False, "error": str(e)}
|
|
162
|
+
# Test dynamic calculator command
|
|
163
|
+
data = {
|
|
164
|
+
"jsonrpc": "2.0",
|
|
165
|
+
"method": "dynamic_calculator",
|
|
166
|
+
"params": {"operation": "add", "a": 10, "b": 5},
|
|
167
|
+
"id": 2,
|
|
168
|
+
}
|
|
169
|
+
try:
|
|
170
|
+
response = requests.post(
|
|
171
|
+
url, json=data, headers=headers, verify=False, timeout=10
|
|
172
|
+
)
|
|
173
|
+
results["dynamic_calculator"] = {
|
|
174
|
+
"success": True,
|
|
175
|
+
"status_code": response.status_code,
|
|
176
|
+
"response": response.json(),
|
|
177
|
+
}
|
|
178
|
+
except Exception as e:
|
|
179
|
+
results["dynamic_calculator"] = {"success": False, "error": str(e)}
|
|
180
|
+
return results
|
|
181
|
+
|
|
182
|
+
def run_tests(self):
|
|
183
|
+
"""Run all tests."""
|
|
184
|
+
print("๐งช Starting Example Tests")
|
|
185
|
+
print("=" * 60)
|
|
186
|
+
# Generate certificates first
|
|
187
|
+
if not self.generate_certificates():
|
|
188
|
+
print("โ Certificate generation failed, skipping tests")
|
|
189
|
+
return
|
|
190
|
+
for example_type, configs in CONFIGS.items():
|
|
191
|
+
print(f"\n๐ Testing {example_type.upper()}")
|
|
192
|
+
print("-" * 40)
|
|
193
|
+
for config_name, config_info in configs.items():
|
|
194
|
+
print(f"\n๐ง Testing {config_name} configuration...")
|
|
195
|
+
try:
|
|
196
|
+
# Start server
|
|
197
|
+
process = self.start_server(example_type, config_name)
|
|
198
|
+
self.processes.append(process)
|
|
199
|
+
port = config_info["port"]
|
|
200
|
+
ssl = config_info.get("ssl", False)
|
|
201
|
+
auth = config_info.get("auth", False)
|
|
202
|
+
# Test health endpoint
|
|
203
|
+
print(f" ๐ Testing health endpoint...")
|
|
204
|
+
health_result = self.test_health_endpoint(port, ssl, auth)
|
|
205
|
+
print(f" Health: {'โ
' if health_result['success'] else 'โ'}")
|
|
206
|
+
# Test echo command
|
|
207
|
+
print(f" ๐ Testing echo command...")
|
|
208
|
+
if auth:
|
|
209
|
+
# Test with admin key
|
|
210
|
+
echo_result = self.test_echo_command(
|
|
211
|
+
port, ssl, auth, API_KEYS["admin"]
|
|
212
|
+
)
|
|
213
|
+
else:
|
|
214
|
+
echo_result = self.test_echo_command(port, ssl, auth)
|
|
215
|
+
print(f" Echo: {'โ
' if echo_result['success'] else 'โ'}")
|
|
216
|
+
# Test full application specific commands
|
|
217
|
+
if example_type == "full_application":
|
|
218
|
+
print(f" ๐ง Testing full application commands...")
|
|
219
|
+
app_results = self.test_full_application_commands(
|
|
220
|
+
port, ssl, auth, API_KEYS["admin"] if auth else None
|
|
221
|
+
)
|
|
222
|
+
for cmd_name, result in app_results.items():
|
|
223
|
+
print(
|
|
224
|
+
f" {cmd_name}: {'โ
' if result['success'] else 'โ'}"
|
|
225
|
+
)
|
|
226
|
+
# Store results
|
|
227
|
+
self.results[f"{example_type}_{config_name}"] = {
|
|
228
|
+
"health": health_result,
|
|
229
|
+
"echo": echo_result,
|
|
230
|
+
"config_info": config_info,
|
|
231
|
+
}
|
|
232
|
+
if example_type == "full_application":
|
|
233
|
+
self.results[f"{example_type}_{config_name}"][
|
|
234
|
+
"app_commands"
|
|
235
|
+
] = app_results
|
|
236
|
+
except Exception as e:
|
|
237
|
+
print(f" โ Error testing {config_name}: {e}")
|
|
238
|
+
self.results[f"{example_type}_{config_name}"] = {
|
|
239
|
+
"error": str(e),
|
|
240
|
+
"config_info": config_info,
|
|
241
|
+
}
|
|
242
|
+
finally:
|
|
243
|
+
# Stop server
|
|
244
|
+
if process:
|
|
245
|
+
process.terminate()
|
|
246
|
+
process.wait()
|
|
247
|
+
time.sleep(2)
|
|
248
|
+
self.print_results()
|
|
249
|
+
|
|
250
|
+
def print_results(self):
|
|
251
|
+
"""Print test results."""
|
|
252
|
+
print("\n๐ Test Results Summary")
|
|
253
|
+
print("=" * 60)
|
|
254
|
+
total_tests = len(self.results)
|
|
255
|
+
successful_tests = 0
|
|
256
|
+
for test_name, result in self.results.items():
|
|
257
|
+
print(f"\n๐ {test_name}")
|
|
258
|
+
if "error" in result:
|
|
259
|
+
print(f" โ Error: {result['error']}")
|
|
260
|
+
continue
|
|
261
|
+
# Check health test
|
|
262
|
+
health_success = result.get("health", {}).get("success", False)
|
|
263
|
+
print(f" Health: {'โ
' if health_success else 'โ'}")
|
|
264
|
+
# Check echo test
|
|
265
|
+
echo_success = result.get("echo", {}).get("success", False)
|
|
266
|
+
print(f" Echo: {'โ
' if echo_success else 'โ'}")
|
|
267
|
+
# Check app commands for full application
|
|
268
|
+
if "app_commands" in result:
|
|
269
|
+
app_success = all(
|
|
270
|
+
cmd_result.get("success", False)
|
|
271
|
+
for cmd_result in result["app_commands"].values()
|
|
272
|
+
)
|
|
273
|
+
print(f" App Commands: {'โ
' if app_success else 'โ'}")
|
|
274
|
+
# Overall test success
|
|
275
|
+
test_success = health_success and echo_success
|
|
276
|
+
if test_success:
|
|
277
|
+
successful_tests += 1
|
|
278
|
+
print(f"\n๐ฏ Overall Results: {successful_tests}/{total_tests} tests passed")
|
|
279
|
+
if successful_tests == total_tests:
|
|
280
|
+
print("๐ All tests passed!")
|
|
281
|
+
else:
|
|
282
|
+
print("โ ๏ธ Some tests failed. Check the details above.")
|
|
283
|
+
|
|
284
|
+
def cleanup(self):
|
|
285
|
+
"""Cleanup processes."""
|
|
286
|
+
for process in self.processes:
|
|
287
|
+
if process.poll() is None:
|
|
288
|
+
process.terminate()
|
|
289
|
+
process.wait()
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def main():
|
|
293
|
+
"""Main function."""
|
|
294
|
+
import sys
|
|
295
|
+
|
|
296
|
+
tester = ExampleTester()
|
|
297
|
+
try:
|
|
298
|
+
tester.run_tests()
|
|
299
|
+
except KeyboardInterrupt:
|
|
300
|
+
print("\n๐ Tests interrupted by user")
|
|
301
|
+
except Exception as e:
|
|
302
|
+
print(f"\nโ Test execution failed: {e}")
|
|
303
|
+
finally:
|
|
304
|
+
tester.cleanup()
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
if __name__ == "__main__":
|
|
308
|
+
main()
|