mcp-proxy-adapter 4.1.1__py3-none-any.whl โ†’ 6.0.1__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.
Files changed (200) hide show
  1. mcp_proxy_adapter/__main__.py +32 -0
  2. mcp_proxy_adapter/api/app.py +290 -33
  3. mcp_proxy_adapter/api/handlers.py +32 -6
  4. mcp_proxy_adapter/api/middleware/__init__.py +38 -32
  5. mcp_proxy_adapter/api/middleware/command_permission_middleware.py +148 -0
  6. mcp_proxy_adapter/api/middleware/error_handling.py +9 -0
  7. mcp_proxy_adapter/api/middleware/factory.py +243 -0
  8. mcp_proxy_adapter/api/middleware/logging.py +32 -6
  9. mcp_proxy_adapter/api/middleware/protocol_middleware.py +201 -0
  10. mcp_proxy_adapter/api/middleware/transport_middleware.py +122 -0
  11. mcp_proxy_adapter/api/middleware/unified_security.py +197 -0
  12. mcp_proxy_adapter/api/middleware/user_info_middleware.py +158 -0
  13. mcp_proxy_adapter/commands/__init__.py +19 -4
  14. mcp_proxy_adapter/commands/auth_validation_command.py +408 -0
  15. mcp_proxy_adapter/commands/base.py +66 -32
  16. mcp_proxy_adapter/commands/builtin_commands.py +95 -0
  17. mcp_proxy_adapter/commands/catalog_manager.py +838 -0
  18. mcp_proxy_adapter/commands/cert_monitor_command.py +620 -0
  19. mcp_proxy_adapter/commands/certificate_management_command.py +608 -0
  20. mcp_proxy_adapter/commands/command_registry.py +711 -354
  21. mcp_proxy_adapter/commands/dependency_manager.py +245 -0
  22. mcp_proxy_adapter/commands/echo_command.py +81 -0
  23. mcp_proxy_adapter/commands/health_command.py +8 -1
  24. mcp_proxy_adapter/commands/help_command.py +21 -14
  25. mcp_proxy_adapter/commands/hooks.py +200 -167
  26. mcp_proxy_adapter/commands/key_management_command.py +506 -0
  27. mcp_proxy_adapter/commands/load_command.py +176 -0
  28. mcp_proxy_adapter/commands/plugins_command.py +235 -0
  29. mcp_proxy_adapter/commands/protocol_management_command.py +232 -0
  30. mcp_proxy_adapter/commands/proxy_registration_command.py +409 -0
  31. mcp_proxy_adapter/commands/reload_command.py +48 -50
  32. mcp_proxy_adapter/commands/result.py +1 -0
  33. mcp_proxy_adapter/commands/role_test_command.py +141 -0
  34. mcp_proxy_adapter/commands/roles_management_command.py +697 -0
  35. mcp_proxy_adapter/commands/security_command.py +488 -0
  36. mcp_proxy_adapter/commands/ssl_setup_command.py +366 -0
  37. mcp_proxy_adapter/commands/token_management_command.py +529 -0
  38. mcp_proxy_adapter/commands/transport_management_command.py +144 -0
  39. mcp_proxy_adapter/commands/unload_command.py +158 -0
  40. mcp_proxy_adapter/config.py +394 -14
  41. mcp_proxy_adapter/core/app_factory.py +410 -0
  42. mcp_proxy_adapter/core/app_runner.py +272 -0
  43. mcp_proxy_adapter/core/auth_validator.py +606 -0
  44. mcp_proxy_adapter/core/certificate_utils.py +1045 -0
  45. mcp_proxy_adapter/core/client.py +574 -0
  46. mcp_proxy_adapter/core/client_manager.py +284 -0
  47. mcp_proxy_adapter/core/client_security.py +384 -0
  48. mcp_proxy_adapter/core/config_converter.py +405 -0
  49. mcp_proxy_adapter/core/config_validator.py +218 -0
  50. mcp_proxy_adapter/core/logging.py +19 -3
  51. mcp_proxy_adapter/core/mtls_asgi.py +156 -0
  52. mcp_proxy_adapter/core/mtls_asgi_app.py +187 -0
  53. mcp_proxy_adapter/core/protocol_manager.py +385 -0
  54. mcp_proxy_adapter/core/proxy_client.py +602 -0
  55. mcp_proxy_adapter/core/proxy_registration.py +522 -0
  56. mcp_proxy_adapter/core/role_utils.py +426 -0
  57. mcp_proxy_adapter/core/security_adapter.py +370 -0
  58. mcp_proxy_adapter/core/security_factory.py +239 -0
  59. mcp_proxy_adapter/core/security_integration.py +286 -0
  60. mcp_proxy_adapter/core/server_adapter.py +282 -0
  61. mcp_proxy_adapter/core/server_engine.py +270 -0
  62. mcp_proxy_adapter/core/settings.py +1 -0
  63. mcp_proxy_adapter/core/ssl_utils.py +234 -0
  64. mcp_proxy_adapter/core/transport_manager.py +292 -0
  65. mcp_proxy_adapter/core/unified_config_adapter.py +579 -0
  66. mcp_proxy_adapter/custom_openapi.py +22 -11
  67. mcp_proxy_adapter/examples/__init__.py +13 -4
  68. mcp_proxy_adapter/examples/basic_framework/__init__.py +9 -0
  69. mcp_proxy_adapter/examples/basic_framework/commands/__init__.py +4 -0
  70. mcp_proxy_adapter/examples/basic_framework/hooks/__init__.py +4 -0
  71. mcp_proxy_adapter/examples/basic_framework/main.py +44 -0
  72. mcp_proxy_adapter/examples/commands/__init__.py +5 -0
  73. mcp_proxy_adapter/examples/create_certificates_simple.py +550 -0
  74. mcp_proxy_adapter/examples/debug_request_state.py +112 -0
  75. mcp_proxy_adapter/examples/debug_role_chain.py +158 -0
  76. mcp_proxy_adapter/examples/demo_client.py +275 -0
  77. mcp_proxy_adapter/examples/examples/basic_framework/__init__.py +9 -0
  78. mcp_proxy_adapter/examples/examples/basic_framework/commands/__init__.py +4 -0
  79. mcp_proxy_adapter/examples/examples/basic_framework/hooks/__init__.py +4 -0
  80. mcp_proxy_adapter/examples/examples/basic_framework/main.py +44 -0
  81. mcp_proxy_adapter/examples/examples/full_application/__init__.py +12 -0
  82. mcp_proxy_adapter/examples/examples/full_application/commands/__init__.py +7 -0
  83. mcp_proxy_adapter/examples/examples/full_application/commands/custom_echo_command.py +80 -0
  84. mcp_proxy_adapter/examples/examples/full_application/commands/dynamic_calculator_command.py +90 -0
  85. mcp_proxy_adapter/examples/examples/full_application/hooks/__init__.py +7 -0
  86. mcp_proxy_adapter/examples/examples/full_application/hooks/application_hooks.py +75 -0
  87. mcp_proxy_adapter/examples/examples/full_application/hooks/builtin_command_hooks.py +71 -0
  88. mcp_proxy_adapter/examples/examples/full_application/main.py +173 -0
  89. mcp_proxy_adapter/examples/examples/full_application/proxy_endpoints.py +154 -0
  90. mcp_proxy_adapter/examples/full_application/__init__.py +12 -0
  91. mcp_proxy_adapter/examples/full_application/commands/__init__.py +7 -0
  92. mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +80 -0
  93. mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +90 -0
  94. mcp_proxy_adapter/examples/full_application/hooks/__init__.py +7 -0
  95. mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +75 -0
  96. mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +71 -0
  97. mcp_proxy_adapter/examples/full_application/main.py +173 -0
  98. mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +154 -0
  99. mcp_proxy_adapter/examples/generate_all_certificates.py +362 -0
  100. mcp_proxy_adapter/examples/generate_certificates.py +177 -0
  101. mcp_proxy_adapter/examples/generate_certificates_and_tokens.py +369 -0
  102. mcp_proxy_adapter/examples/generate_test_configs.py +331 -0
  103. mcp_proxy_adapter/examples/proxy_registration_example.py +334 -0
  104. mcp_proxy_adapter/examples/run_example.py +59 -0
  105. mcp_proxy_adapter/examples/run_full_test_suite.py +318 -0
  106. mcp_proxy_adapter/examples/run_proxy_server.py +146 -0
  107. mcp_proxy_adapter/examples/run_security_tests.py +544 -0
  108. mcp_proxy_adapter/examples/run_security_tests_fixed.py +247 -0
  109. mcp_proxy_adapter/examples/scripts/config_generator.py +740 -0
  110. mcp_proxy_adapter/examples/scripts/create_certificates_simple.py +560 -0
  111. mcp_proxy_adapter/examples/scripts/generate_certificates_and_tokens.py +369 -0
  112. mcp_proxy_adapter/examples/security_test_client.py +782 -0
  113. mcp_proxy_adapter/examples/setup_test_environment.py +328 -0
  114. mcp_proxy_adapter/examples/test_config.py +148 -0
  115. mcp_proxy_adapter/examples/test_config_generator.py +86 -0
  116. mcp_proxy_adapter/examples/test_examples.py +281 -0
  117. mcp_proxy_adapter/examples/universal_client.py +620 -0
  118. mcp_proxy_adapter/main.py +93 -0
  119. mcp_proxy_adapter/utils/config_generator.py +1008 -0
  120. mcp_proxy_adapter/version.py +5 -2
  121. mcp_proxy_adapter-6.0.1.dist-info/METADATA +679 -0
  122. mcp_proxy_adapter-6.0.1.dist-info/RECORD +140 -0
  123. mcp_proxy_adapter-6.0.1.dist-info/entry_points.txt +2 -0
  124. {mcp_proxy_adapter-4.1.1.dist-info โ†’ mcp_proxy_adapter-6.0.1.dist-info}/licenses/LICENSE +2 -2
  125. mcp_proxy_adapter/api/middleware/auth.py +0 -146
  126. mcp_proxy_adapter/api/middleware/rate_limit.py +0 -152
  127. mcp_proxy_adapter/commands/reload_settings_command.py +0 -125
  128. mcp_proxy_adapter/examples/README.md +0 -124
  129. mcp_proxy_adapter/examples/basic_server/README.md +0 -60
  130. mcp_proxy_adapter/examples/basic_server/__init__.py +0 -7
  131. mcp_proxy_adapter/examples/basic_server/basic_custom_settings.json +0 -39
  132. mcp_proxy_adapter/examples/basic_server/config.json +0 -35
  133. mcp_proxy_adapter/examples/basic_server/custom_settings_example.py +0 -238
  134. mcp_proxy_adapter/examples/basic_server/server.py +0 -103
  135. mcp_proxy_adapter/examples/custom_commands/README.md +0 -127
  136. mcp_proxy_adapter/examples/custom_commands/__init__.py +0 -27
  137. mcp_proxy_adapter/examples/custom_commands/advanced_hooks.py +0 -250
  138. mcp_proxy_adapter/examples/custom_commands/auto_commands/__init__.py +0 -6
  139. mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_echo_command.py +0 -103
  140. mcp_proxy_adapter/examples/custom_commands/auto_commands/auto_info_command.py +0 -111
  141. mcp_proxy_adapter/examples/custom_commands/config.json +0 -35
  142. mcp_proxy_adapter/examples/custom_commands/custom_health_command.py +0 -169
  143. mcp_proxy_adapter/examples/custom_commands/custom_help_command.py +0 -215
  144. mcp_proxy_adapter/examples/custom_commands/custom_openapi_generator.py +0 -76
  145. mcp_proxy_adapter/examples/custom_commands/custom_settings.json +0 -96
  146. mcp_proxy_adapter/examples/custom_commands/custom_settings_manager.py +0 -241
  147. mcp_proxy_adapter/examples/custom_commands/data_transform_command.py +0 -135
  148. mcp_proxy_adapter/examples/custom_commands/echo_command.py +0 -122
  149. mcp_proxy_adapter/examples/custom_commands/hooks.py +0 -230
  150. mcp_proxy_adapter/examples/custom_commands/intercept_command.py +0 -123
  151. mcp_proxy_adapter/examples/custom_commands/manual_echo_command.py +0 -103
  152. mcp_proxy_adapter/examples/custom_commands/server.py +0 -228
  153. mcp_proxy_adapter/examples/custom_commands/test_hooks.py +0 -176
  154. mcp_proxy_adapter/examples/deployment/README.md +0 -49
  155. mcp_proxy_adapter/examples/deployment/__init__.py +0 -7
  156. mcp_proxy_adapter/examples/deployment/config.development.json +0 -8
  157. mcp_proxy_adapter/examples/deployment/config.json +0 -29
  158. mcp_proxy_adapter/examples/deployment/config.production.json +0 -12
  159. mcp_proxy_adapter/examples/deployment/config.staging.json +0 -11
  160. mcp_proxy_adapter/examples/deployment/docker-compose.yml +0 -31
  161. mcp_proxy_adapter/examples/deployment/run.sh +0 -43
  162. mcp_proxy_adapter/examples/deployment/run_docker.sh +0 -84
  163. mcp_proxy_adapter/schemas/base_schema.json +0 -114
  164. mcp_proxy_adapter/schemas/openapi_schema.json +0 -314
  165. mcp_proxy_adapter/tests/__init__.py +0 -0
  166. mcp_proxy_adapter/tests/api/__init__.py +0 -3
  167. mcp_proxy_adapter/tests/api/test_cmd_endpoint.py +0 -115
  168. mcp_proxy_adapter/tests/api/test_custom_openapi.py +0 -617
  169. mcp_proxy_adapter/tests/api/test_handlers.py +0 -522
  170. mcp_proxy_adapter/tests/api/test_middleware.py +0 -340
  171. mcp_proxy_adapter/tests/api/test_schemas.py +0 -546
  172. mcp_proxy_adapter/tests/api/test_tool_integration.py +0 -531
  173. mcp_proxy_adapter/tests/commands/__init__.py +0 -3
  174. mcp_proxy_adapter/tests/commands/test_config_command.py +0 -211
  175. mcp_proxy_adapter/tests/commands/test_echo_command.py +0 -127
  176. mcp_proxy_adapter/tests/commands/test_help_command.py +0 -136
  177. mcp_proxy_adapter/tests/conftest.py +0 -131
  178. mcp_proxy_adapter/tests/functional/__init__.py +0 -3
  179. mcp_proxy_adapter/tests/functional/test_api.py +0 -253
  180. mcp_proxy_adapter/tests/integration/__init__.py +0 -3
  181. mcp_proxy_adapter/tests/integration/test_cmd_integration.py +0 -129
  182. mcp_proxy_adapter/tests/integration/test_integration.py +0 -255
  183. mcp_proxy_adapter/tests/performance/__init__.py +0 -3
  184. mcp_proxy_adapter/tests/performance/test_performance.py +0 -189
  185. mcp_proxy_adapter/tests/stubs/__init__.py +0 -10
  186. mcp_proxy_adapter/tests/stubs/echo_command.py +0 -104
  187. mcp_proxy_adapter/tests/test_api_endpoints.py +0 -271
  188. mcp_proxy_adapter/tests/test_api_handlers.py +0 -289
  189. mcp_proxy_adapter/tests/test_base_command.py +0 -123
  190. mcp_proxy_adapter/tests/test_batch_requests.py +0 -117
  191. mcp_proxy_adapter/tests/test_command_registry.py +0 -281
  192. mcp_proxy_adapter/tests/test_config.py +0 -127
  193. mcp_proxy_adapter/tests/test_utils.py +0 -65
  194. mcp_proxy_adapter/tests/unit/__init__.py +0 -3
  195. mcp_proxy_adapter/tests/unit/test_base_command.py +0 -436
  196. mcp_proxy_adapter/tests/unit/test_config.py +0 -217
  197. mcp_proxy_adapter-4.1.1.dist-info/METADATA +0 -200
  198. mcp_proxy_adapter-4.1.1.dist-info/RECORD +0 -110
  199. {mcp_proxy_adapter-4.1.1.dist-info โ†’ mcp_proxy_adapter-6.0.1.dist-info}/WHEEL +0 -0
  200. {mcp_proxy_adapter-4.1.1.dist-info โ†’ mcp_proxy_adapter-6.0.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,281 @@
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
+ from typing import Dict, Any, List
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 = {
35
+ "admin": "admin-secret-key-123",
36
+ "user": "user-secret-key-456"
37
+ }
38
+ class ExampleTester:
39
+ """Test examples with different configurations."""
40
+ def __init__(self):
41
+ self.examples_dir = Path(__file__).parent
42
+ self.results = {}
43
+ self.processes = []
44
+ def generate_certificates(self):
45
+ """Generate certificates for testing."""
46
+ print("๐Ÿ” Generating certificates...")
47
+ cert_script = self.examples_dir.parent / "generate_certificates.py"
48
+ if cert_script.exists():
49
+ result = subprocess.run([sys.executable, str(cert_script)],
50
+ capture_output=True, text=True)
51
+ if result.returncode == 0:
52
+ print("โœ… Certificates generated successfully")
53
+ return True
54
+ else:
55
+ print(f"โŒ Certificate generation failed: {result.stderr}")
56
+ return False
57
+ else:
58
+ print("โš ๏ธ Certificate generation script not found, using existing certificates")
59
+ return True
60
+ def start_server(self, example_type: str, config_name: str) -> subprocess.Popen:
61
+ """Start a server with specific configuration."""
62
+ config_path = self.examples_dir / example_type / "configs" / f"{config_name}.json"
63
+ main_script = self.examples_dir / example_type / "main.py"
64
+ if not config_path.exists():
65
+ raise FileNotFoundError(f"Configuration file not found: {config_path}")
66
+ if not main_script.exists():
67
+ raise FileNotFoundError(f"Main script not found: {main_script}")
68
+ cmd = [
69
+ sys.executable, str(main_script),
70
+ "--config", str(config_path)
71
+ ]
72
+ print(f"๐Ÿš€ Starting {example_type} server with {config_name} config...")
73
+ process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
74
+ # Wait for server to start
75
+ time.sleep(5)
76
+ return process
77
+ def test_health_endpoint(self, port: int, ssl: bool = False, auth: bool = False,
78
+ api_key: str = None) -> Dict[str, Any]:
79
+ """Test health endpoint."""
80
+ protocol = "https" if ssl else "http"
81
+ url = f"{protocol}://localhost:{port}/health"
82
+ headers = {}
83
+ if auth and api_key:
84
+ headers["X-API-Key"] = api_key
85
+ try:
86
+ response = requests.get(url, headers=headers, verify=False, timeout=10)
87
+ return {
88
+ "success": True,
89
+ "status_code": response.status_code,
90
+ "response": response.json() if response.headers.get('content-type', '').startswith('application/json') else response.text
91
+ }
92
+ except Exception as e:
93
+ return {
94
+ "success": False,
95
+ "error": str(e)
96
+ }
97
+ def test_echo_command(self, port: int, ssl: bool = False, auth: bool = False,
98
+ api_key: str = None) -> Dict[str, Any]:
99
+ """Test echo command."""
100
+ protocol = "https" if ssl else "http"
101
+ url = f"{protocol}://localhost:{port}/cmd"
102
+ headers = {"Content-Type": "application/json"}
103
+ if auth and api_key:
104
+ headers["X-API-Key"] = api_key
105
+ data = {
106
+ "jsonrpc": "2.0",
107
+ "method": "echo",
108
+ "params": {"message": "Hello from test!"},
109
+ "id": 1
110
+ }
111
+ try:
112
+ response = requests.post(url, json=data, headers=headers, verify=False, timeout=10)
113
+ return {
114
+ "success": True,
115
+ "status_code": response.status_code,
116
+ "response": response.json()
117
+ }
118
+ except Exception as e:
119
+ return {
120
+ "success": False,
121
+ "error": str(e)
122
+ }
123
+ def test_full_application_commands(self, port: int, ssl: bool = False, auth: bool = False,
124
+ api_key: str = None) -> Dict[str, Any]:
125
+ """Test full application specific commands."""
126
+ protocol = "https" if ssl else "http"
127
+ url = f"{protocol}://localhost:{port}/cmd"
128
+ headers = {"Content-Type": "application/json"}
129
+ if auth and api_key:
130
+ headers["X-API-Key"] = api_key
131
+ results = {}
132
+ # Test custom echo command
133
+ data = {
134
+ "jsonrpc": "2.0",
135
+ "method": "custom_echo",
136
+ "params": {"message": "Custom echo test", "repeat": 3},
137
+ "id": 1
138
+ }
139
+ try:
140
+ response = requests.post(url, json=data, headers=headers, verify=False, timeout=10)
141
+ results["custom_echo"] = {
142
+ "success": True,
143
+ "status_code": response.status_code,
144
+ "response": response.json()
145
+ }
146
+ except Exception as e:
147
+ results["custom_echo"] = {
148
+ "success": False,
149
+ "error": str(e)
150
+ }
151
+ # Test dynamic calculator command
152
+ data = {
153
+ "jsonrpc": "2.0",
154
+ "method": "dynamic_calculator",
155
+ "params": {"operation": "add", "a": 10, "b": 5},
156
+ "id": 2
157
+ }
158
+ try:
159
+ response = requests.post(url, json=data, headers=headers, verify=False, timeout=10)
160
+ results["dynamic_calculator"] = {
161
+ "success": True,
162
+ "status_code": response.status_code,
163
+ "response": response.json()
164
+ }
165
+ except Exception as e:
166
+ results["dynamic_calculator"] = {
167
+ "success": False,
168
+ "error": str(e)
169
+ }
170
+ return results
171
+ def run_tests(self):
172
+ """Run all tests."""
173
+ print("๐Ÿงช Starting Example Tests")
174
+ print("=" * 60)
175
+ # Generate certificates first
176
+ if not self.generate_certificates():
177
+ print("โŒ Certificate generation failed, skipping tests")
178
+ return
179
+ for example_type, configs in CONFIGS.items():
180
+ print(f"\n๐Ÿ“ Testing {example_type.upper()}")
181
+ print("-" * 40)
182
+ for config_name, config_info in configs.items():
183
+ print(f"\n๐Ÿ”ง Testing {config_name} configuration...")
184
+ try:
185
+ # Start server
186
+ process = self.start_server(example_type, config_name)
187
+ self.processes.append(process)
188
+ port = config_info["port"]
189
+ ssl = config_info.get("ssl", False)
190
+ auth = config_info.get("auth", False)
191
+ # Test health endpoint
192
+ print(f" ๐Ÿ“Š Testing health endpoint...")
193
+ health_result = self.test_health_endpoint(port, ssl, auth)
194
+ print(f" Health: {'โœ…' if health_result['success'] else 'โŒ'}")
195
+ # Test echo command
196
+ print(f" ๐Ÿ“ Testing echo command...")
197
+ if auth:
198
+ # Test with admin key
199
+ echo_result = self.test_echo_command(port, ssl, auth, API_KEYS["admin"])
200
+ else:
201
+ echo_result = self.test_echo_command(port, ssl, auth)
202
+ print(f" Echo: {'โœ…' if echo_result['success'] else 'โŒ'}")
203
+ # Test full application specific commands
204
+ if example_type == "full_application":
205
+ print(f" ๐Ÿ”ง Testing full application commands...")
206
+ app_results = self.test_full_application_commands(port, ssl, auth,
207
+ API_KEYS["admin"] if auth else None)
208
+ for cmd_name, result in app_results.items():
209
+ print(f" {cmd_name}: {'โœ…' if result['success'] else 'โŒ'}")
210
+ # Store results
211
+ self.results[f"{example_type}_{config_name}"] = {
212
+ "health": health_result,
213
+ "echo": echo_result,
214
+ "config_info": config_info
215
+ }
216
+ if example_type == "full_application":
217
+ self.results[f"{example_type}_{config_name}"]["app_commands"] = app_results
218
+ except Exception as e:
219
+ print(f" โŒ Error testing {config_name}: {e}")
220
+ self.results[f"{example_type}_{config_name}"] = {
221
+ "error": str(e),
222
+ "config_info": config_info
223
+ }
224
+ finally:
225
+ # Stop server
226
+ if process:
227
+ process.terminate()
228
+ process.wait()
229
+ time.sleep(2)
230
+ self.print_results()
231
+ def print_results(self):
232
+ """Print test results."""
233
+ print("\n๐Ÿ“Š Test Results Summary")
234
+ print("=" * 60)
235
+ total_tests = len(self.results)
236
+ successful_tests = 0
237
+ for test_name, result in self.results.items():
238
+ print(f"\n๐Ÿ” {test_name}")
239
+ if "error" in result:
240
+ print(f" โŒ Error: {result['error']}")
241
+ continue
242
+ # Check health test
243
+ health_success = result.get("health", {}).get("success", False)
244
+ print(f" Health: {'โœ…' if health_success else 'โŒ'}")
245
+ # Check echo test
246
+ echo_success = result.get("echo", {}).get("success", False)
247
+ print(f" Echo: {'โœ…' if echo_success else 'โŒ'}")
248
+ # Check app commands for full application
249
+ if "app_commands" in result:
250
+ app_success = all(cmd_result.get("success", False)
251
+ for cmd_result in result["app_commands"].values())
252
+ print(f" App Commands: {'โœ…' if app_success else 'โŒ'}")
253
+ # Overall test success
254
+ test_success = health_success and echo_success
255
+ if test_success:
256
+ successful_tests += 1
257
+ print(f"\n๐ŸŽฏ Overall Results: {successful_tests}/{total_tests} tests passed")
258
+ if successful_tests == total_tests:
259
+ print("๐ŸŽ‰ All tests passed!")
260
+ else:
261
+ print("โš ๏ธ Some tests failed. Check the details above.")
262
+ def cleanup(self):
263
+ """Cleanup processes."""
264
+ for process in self.processes:
265
+ if process.poll() is None:
266
+ process.terminate()
267
+ process.wait()
268
+ def main():
269
+ """Main function."""
270
+ import sys
271
+ tester = ExampleTester()
272
+ try:
273
+ tester.run_tests()
274
+ except KeyboardInterrupt:
275
+ print("\n๐Ÿ›‘ Tests interrupted by user")
276
+ except Exception as e:
277
+ print(f"\nโŒ Test execution failed: {e}")
278
+ finally:
279
+ tester.cleanup()
280
+ if __name__ == "__main__":
281
+ main()