mcp-proxy-adapter 6.1.1__py3-none-any.whl โ 6.2.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.
- mcp_proxy_adapter/__main__.py +27 -7
- mcp_proxy_adapter/api/app.py +18 -7
- mcp_proxy_adapter/commands/ssl_setup_command.py +234 -351
- mcp_proxy_adapter/core/app_factory.py +87 -3
- mcp_proxy_adapter/core/app_runner.py +272 -0
- mcp_proxy_adapter/core/certificate_utils.py +291 -73
- mcp_proxy_adapter/core/client.py +574 -0
- mcp_proxy_adapter/core/client_manager.py +284 -0
- mcp_proxy_adapter/core/server_adapter.py +17 -80
- mcp_proxy_adapter/core/server_engine.py +5 -99
- mcp_proxy_adapter/core/ssl_utils.py +13 -12
- mcp_proxy_adapter/core/transport_manager.py +5 -5
- mcp_proxy_adapter/examples/__init__.py +16 -0
- mcp_proxy_adapter/examples/basic_framework/__init__.py +7 -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 +21 -40
- mcp_proxy_adapter/examples/commands/__init__.py +5 -1
- mcp_proxy_adapter/examples/create_certificates_simple.py +260 -75
- mcp_proxy_adapter/examples/debug_request_state.py +4 -36
- mcp_proxy_adapter/examples/debug_role_chain.py +2 -49
- mcp_proxy_adapter/examples/demo_client.py +0 -66
- mcp_proxy_adapter/examples/full_application/__init__.py +11 -0
- mcp_proxy_adapter/examples/full_application/commands/__init__.py +7 -0
- mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +0 -19
- mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +0 -16
- mcp_proxy_adapter/examples/full_application/hooks/__init__.py +7 -0
- mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +0 -22
- mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +0 -24
- mcp_proxy_adapter/examples/full_application/main.py +65 -44
- mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +154 -0
- mcp_proxy_adapter/examples/generate_all_certificates.py +0 -67
- mcp_proxy_adapter/examples/generate_certificates.py +0 -15
- mcp_proxy_adapter/examples/generate_certificates_and_tokens.py +369 -0
- mcp_proxy_adapter/examples/generate_test_configs.py +204 -0
- mcp_proxy_adapter/examples/proxy_registration_example.py +3 -70
- mcp_proxy_adapter/examples/run_example.py +1 -23
- mcp_proxy_adapter/examples/run_security_tests.py +2 -60
- mcp_proxy_adapter/examples/run_security_tests_fixed.py +0 -53
- mcp_proxy_adapter/examples/security_test_client.py +18 -123
- mcp_proxy_adapter/examples/setup_test_environment.py +179 -0
- mcp_proxy_adapter/examples/test_config.py +148 -0
- mcp_proxy_adapter/examples/test_config_generator.py +1 -25
- mcp_proxy_adapter/examples/test_examples.py +4 -67
- mcp_proxy_adapter/examples/universal_client.py +154 -162
- mcp_proxy_adapter/main.py +51 -161
- mcp_proxy_adapter/version.py +1 -1
- mcp_proxy_adapter-6.2.1.dist-info/METADATA +676 -0
- mcp_proxy_adapter-6.2.1.dist-info/RECORD +119 -0
- mcp_proxy_adapter/docs/EN/TROUBLESHOOTING.md +0 -285
- mcp_proxy_adapter/docs/RU/TROUBLESHOOTING.md +0 -285
- mcp_proxy_adapter/examples/README.md +0 -257
- mcp_proxy_adapter/examples/README_EN.md +0 -258
- mcp_proxy_adapter/examples/SECURITY_TESTING.md +0 -455
- mcp_proxy_adapter/examples/basic_framework/configs/http_auth.json +0 -37
- mcp_proxy_adapter/examples/basic_framework/configs/http_simple.json +0 -23
- mcp_proxy_adapter/examples/basic_framework/configs/https_auth.json +0 -43
- mcp_proxy_adapter/examples/basic_framework/configs/https_no_protocol_middleware.json +0 -36
- mcp_proxy_adapter/examples/basic_framework/configs/https_simple.json +0 -29
- mcp_proxy_adapter/examples/basic_framework/configs/mtls_no_protocol_middleware.json +0 -34
- mcp_proxy_adapter/examples/basic_framework/configs/mtls_no_roles.json +0 -39
- mcp_proxy_adapter/examples/basic_framework/configs/mtls_simple.json +0 -35
- mcp_proxy_adapter/examples/basic_framework/configs/mtls_with_roles.json +0 -45
- mcp_proxy_adapter/examples/basic_framework/roles.json +0 -21
- mcp_proxy_adapter/examples/cert_config.json +0 -9
- mcp_proxy_adapter/examples/certs/admin.crt +0 -32
- mcp_proxy_adapter/examples/certs/admin.key +0 -52
- mcp_proxy_adapter/examples/certs/admin_cert.pem +0 -21
- mcp_proxy_adapter/examples/certs/admin_key.pem +0 -28
- mcp_proxy_adapter/examples/certs/ca_cert.pem +0 -23
- mcp_proxy_adapter/examples/certs/ca_cert.srl +0 -1
- mcp_proxy_adapter/examples/certs/ca_key.pem +0 -28
- mcp_proxy_adapter/examples/certs/cert_config.json +0 -9
- mcp_proxy_adapter/examples/certs/client.crt +0 -32
- mcp_proxy_adapter/examples/certs/client.key +0 -52
- mcp_proxy_adapter/examples/certs/client_admin.crt +0 -32
- mcp_proxy_adapter/examples/certs/client_admin.key +0 -52
- mcp_proxy_adapter/examples/certs/client_user.crt +0 -32
- mcp_proxy_adapter/examples/certs/client_user.key +0 -52
- mcp_proxy_adapter/examples/certs/guest_cert.pem +0 -21
- mcp_proxy_adapter/examples/certs/guest_key.pem +0 -28
- mcp_proxy_adapter/examples/certs/mcp_proxy_adapter_ca_ca.crt +0 -23
- mcp_proxy_adapter/examples/certs/proxy_cert.pem +0 -21
- mcp_proxy_adapter/examples/certs/proxy_key.pem +0 -28
- mcp_proxy_adapter/examples/certs/readonly.crt +0 -32
- mcp_proxy_adapter/examples/certs/readonly.key +0 -52
- mcp_proxy_adapter/examples/certs/readonly_cert.pem +0 -21
- mcp_proxy_adapter/examples/certs/readonly_key.pem +0 -28
- mcp_proxy_adapter/examples/certs/server.crt +0 -32
- mcp_proxy_adapter/examples/certs/server.key +0 -52
- mcp_proxy_adapter/examples/certs/server_cert.pem +0 -32
- mcp_proxy_adapter/examples/certs/server_key.pem +0 -52
- mcp_proxy_adapter/examples/certs/test_ca_ca.crt +0 -20
- mcp_proxy_adapter/examples/certs/user.crt +0 -32
- mcp_proxy_adapter/examples/certs/user.key +0 -52
- mcp_proxy_adapter/examples/certs/user_cert.pem +0 -21
- mcp_proxy_adapter/examples/certs/user_key.pem +0 -28
- mcp_proxy_adapter/examples/client_configs/api_key_client.json +0 -13
- mcp_proxy_adapter/examples/client_configs/basic_auth_client.json +0 -13
- mcp_proxy_adapter/examples/client_configs/certificate_client.json +0 -22
- mcp_proxy_adapter/examples/client_configs/jwt_client.json +0 -15
- mcp_proxy_adapter/examples/client_configs/no_auth_client.json +0 -9
- mcp_proxy_adapter/examples/full_application/configs/http_auth.json +0 -37
- mcp_proxy_adapter/examples/full_application/configs/http_simple.json +0 -23
- mcp_proxy_adapter/examples/full_application/configs/https_auth.json +0 -39
- mcp_proxy_adapter/examples/full_application/configs/https_simple.json +0 -25
- mcp_proxy_adapter/examples/full_application/configs/mtls_no_roles.json +0 -39
- mcp_proxy_adapter/examples/full_application/configs/mtls_with_roles.json +0 -45
- mcp_proxy_adapter/examples/full_application/roles.json +0 -21
- mcp_proxy_adapter/examples/keys/ca_key.pem +0 -28
- mcp_proxy_adapter/examples/keys/mcp_proxy_adapter_ca_ca.key +0 -28
- mcp_proxy_adapter/examples/keys/test_ca_ca.key +0 -28
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log +0 -220
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.1 +0 -1
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.2 +0 -1
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.3 +0 -1
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.4 +0 -1
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter.log.5 +0 -1
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log +0 -220
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.1 +0 -1
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.2 +0 -1
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.3 +0 -1
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.4 +0 -1
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_access.log.5 +0 -1
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log +0 -2
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.1 +0 -1
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.2 +0 -1
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.3 +0 -1
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.4 +0 -1
- mcp_proxy_adapter/examples/logs/mcp_proxy_adapter_error.log.5 +0 -1
- mcp_proxy_adapter/examples/roles.json +0 -38
- mcp_proxy_adapter/examples/server_configs/config_basic_http.json +0 -204
- mcp_proxy_adapter/examples/server_configs/config_http_token.json +0 -238
- mcp_proxy_adapter/examples/server_configs/config_https.json +0 -215
- mcp_proxy_adapter/examples/server_configs/config_https_token.json +0 -231
- mcp_proxy_adapter/examples/server_configs/config_mtls.json +0 -215
- mcp_proxy_adapter/examples/server_configs/config_proxy_registration.json +0 -250
- mcp_proxy_adapter/examples/server_configs/config_simple.json +0 -46
- mcp_proxy_adapter/examples/server_configs/roles.json +0 -38
- mcp_proxy_adapter/utils/config_generator.py +0 -727
- mcp_proxy_adapter-6.1.1.dist-info/METADATA +0 -205
- mcp_proxy_adapter-6.1.1.dist-info/RECORD +0 -197
- mcp_proxy_adapter-6.1.1.dist-info/entry_points.txt +0 -2
- mcp_proxy_adapter-6.1.1.dist-info/licenses/LICENSE +0 -21
- {mcp_proxy_adapter-6.1.1.dist-info โ mcp_proxy_adapter-6.2.1.dist-info}/WHEEL +0 -0
- {mcp_proxy_adapter-6.1.1.dist-info โ mcp_proxy_adapter-6.2.1.dist-info}/top_level.txt +0 -0
@@ -1,13 +1,10 @@
|
|
1
1
|
#!/usr/bin/env python3
|
2
2
|
"""
|
3
3
|
Test Examples Script
|
4
|
-
|
5
4
|
This script tests all examples with different configurations.
|
6
|
-
|
7
5
|
Author: Vasiliy Zdanovskiy
|
8
6
|
email: vasilyvz@gmail.com
|
9
7
|
"""
|
10
|
-
|
11
8
|
import json
|
12
9
|
import os
|
13
10
|
import subprocess
|
@@ -15,7 +12,6 @@ import time
|
|
15
12
|
import requests
|
16
13
|
from pathlib import Path
|
17
14
|
from typing import Dict, Any, List
|
18
|
-
|
19
15
|
# Configuration for testing
|
20
16
|
CONFIGS = {
|
21
17
|
"basic_framework": {
|
@@ -35,28 +31,22 @@ CONFIGS = {
|
|
35
31
|
"mtls_with_roles": {"port": 9448, "ssl": True, "auth": True, "mtls": True}
|
36
32
|
}
|
37
33
|
}
|
38
|
-
|
39
34
|
API_KEYS = {
|
40
35
|
"admin": "admin-secret-key-123",
|
41
36
|
"user": "user-secret-key-456"
|
42
37
|
}
|
43
|
-
|
44
|
-
|
45
38
|
class ExampleTester:
|
46
39
|
"""Test examples with different configurations."""
|
47
|
-
|
48
40
|
def __init__(self):
|
49
41
|
self.examples_dir = Path(__file__).parent
|
50
42
|
self.results = {}
|
51
43
|
self.processes = []
|
52
|
-
|
53
44
|
def generate_certificates(self):
|
54
45
|
"""Generate certificates for testing."""
|
55
46
|
print("๐ Generating certificates...")
|
56
|
-
|
57
47
|
cert_script = self.examples_dir.parent / "generate_certificates.py"
|
58
48
|
if cert_script.exists():
|
59
|
-
result = subprocess.run([sys.executable, str(cert_script)],
|
49
|
+
result = subprocess.run([sys.executable, str(cert_script)],
|
60
50
|
capture_output=True, text=True)
|
61
51
|
if result.returncode == 0:
|
62
52
|
print("โ
Certificates generated successfully")
|
@@ -67,41 +57,31 @@ class ExampleTester:
|
|
67
57
|
else:
|
68
58
|
print("โ ๏ธ Certificate generation script not found, using existing certificates")
|
69
59
|
return True
|
70
|
-
|
71
60
|
def start_server(self, example_type: str, config_name: str) -> subprocess.Popen:
|
72
61
|
"""Start a server with specific configuration."""
|
73
62
|
config_path = self.examples_dir / example_type / "configs" / f"{config_name}.json"
|
74
63
|
main_script = self.examples_dir / example_type / "main.py"
|
75
|
-
|
76
64
|
if not config_path.exists():
|
77
65
|
raise FileNotFoundError(f"Configuration file not found: {config_path}")
|
78
|
-
|
79
66
|
if not main_script.exists():
|
80
67
|
raise FileNotFoundError(f"Main script not found: {main_script}")
|
81
|
-
|
82
68
|
cmd = [
|
83
69
|
sys.executable, str(main_script),
|
84
70
|
"--config", str(config_path)
|
85
71
|
]
|
86
|
-
|
87
72
|
print(f"๐ Starting {example_type} server with {config_name} config...")
|
88
73
|
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
89
|
-
|
90
74
|
# Wait for server to start
|
91
75
|
time.sleep(5)
|
92
|
-
|
93
76
|
return process
|
94
|
-
|
95
|
-
def test_health_endpoint(self, port: int, ssl: bool = False, auth: bool = False,
|
77
|
+
def test_health_endpoint(self, port: int, ssl: bool = False, auth: bool = False,
|
96
78
|
api_key: str = None) -> Dict[str, Any]:
|
97
79
|
"""Test health endpoint."""
|
98
80
|
protocol = "https" if ssl else "http"
|
99
81
|
url = f"{protocol}://localhost:{port}/health"
|
100
|
-
|
101
82
|
headers = {}
|
102
83
|
if auth and api_key:
|
103
84
|
headers["X-API-Key"] = api_key
|
104
|
-
|
105
85
|
try:
|
106
86
|
response = requests.get(url, headers=headers, verify=False, timeout=10)
|
107
87
|
return {
|
@@ -114,24 +94,20 @@ class ExampleTester:
|
|
114
94
|
"success": False,
|
115
95
|
"error": str(e)
|
116
96
|
}
|
117
|
-
|
118
97
|
def test_echo_command(self, port: int, ssl: bool = False, auth: bool = False,
|
119
98
|
api_key: str = None) -> Dict[str, Any]:
|
120
99
|
"""Test echo command."""
|
121
100
|
protocol = "https" if ssl else "http"
|
122
101
|
url = f"{protocol}://localhost:{port}/cmd"
|
123
|
-
|
124
102
|
headers = {"Content-Type": "application/json"}
|
125
103
|
if auth and api_key:
|
126
104
|
headers["X-API-Key"] = api_key
|
127
|
-
|
128
105
|
data = {
|
129
106
|
"jsonrpc": "2.0",
|
130
107
|
"method": "echo",
|
131
108
|
"params": {"message": "Hello from test!"},
|
132
109
|
"id": 1
|
133
110
|
}
|
134
|
-
|
135
111
|
try:
|
136
112
|
response = requests.post(url, json=data, headers=headers, verify=False, timeout=10)
|
137
113
|
return {
|
@@ -144,19 +120,15 @@ class ExampleTester:
|
|
144
120
|
"success": False,
|
145
121
|
"error": str(e)
|
146
122
|
}
|
147
|
-
|
148
123
|
def test_full_application_commands(self, port: int, ssl: bool = False, auth: bool = False,
|
149
124
|
api_key: str = None) -> Dict[str, Any]:
|
150
125
|
"""Test full application specific commands."""
|
151
126
|
protocol = "https" if ssl else "http"
|
152
127
|
url = f"{protocol}://localhost:{port}/cmd"
|
153
|
-
|
154
128
|
headers = {"Content-Type": "application/json"}
|
155
129
|
if auth and api_key:
|
156
130
|
headers["X-API-Key"] = api_key
|
157
|
-
|
158
131
|
results = {}
|
159
|
-
|
160
132
|
# Test custom echo command
|
161
133
|
data = {
|
162
134
|
"jsonrpc": "2.0",
|
@@ -164,7 +136,6 @@ class ExampleTester:
|
|
164
136
|
"params": {"message": "Custom echo test", "repeat": 3},
|
165
137
|
"id": 1
|
166
138
|
}
|
167
|
-
|
168
139
|
try:
|
169
140
|
response = requests.post(url, json=data, headers=headers, verify=False, timeout=10)
|
170
141
|
results["custom_echo"] = {
|
@@ -177,7 +148,6 @@ class ExampleTester:
|
|
177
148
|
"success": False,
|
178
149
|
"error": str(e)
|
179
150
|
}
|
180
|
-
|
181
151
|
# Test dynamic calculator command
|
182
152
|
data = {
|
183
153
|
"jsonrpc": "2.0",
|
@@ -185,7 +155,6 @@ class ExampleTester:
|
|
185
155
|
"params": {"operation": "add", "a": 10, "b": 5},
|
186
156
|
"id": 2
|
187
157
|
}
|
188
|
-
|
189
158
|
try:
|
190
159
|
response = requests.post(url, json=data, headers=headers, verify=False, timeout=10)
|
191
160
|
results["dynamic_calculator"] = {
|
@@ -198,40 +167,31 @@ class ExampleTester:
|
|
198
167
|
"success": False,
|
199
168
|
"error": str(e)
|
200
169
|
}
|
201
|
-
|
202
170
|
return results
|
203
|
-
|
204
171
|
def run_tests(self):
|
205
172
|
"""Run all tests."""
|
206
173
|
print("๐งช Starting Example Tests")
|
207
174
|
print("=" * 60)
|
208
|
-
|
209
175
|
# Generate certificates first
|
210
176
|
if not self.generate_certificates():
|
211
177
|
print("โ Certificate generation failed, skipping tests")
|
212
178
|
return
|
213
|
-
|
214
179
|
for example_type, configs in CONFIGS.items():
|
215
180
|
print(f"\n๐ Testing {example_type.upper()}")
|
216
181
|
print("-" * 40)
|
217
|
-
|
218
182
|
for config_name, config_info in configs.items():
|
219
183
|
print(f"\n๐ง Testing {config_name} configuration...")
|
220
|
-
|
221
184
|
try:
|
222
185
|
# Start server
|
223
186
|
process = self.start_server(example_type, config_name)
|
224
187
|
self.processes.append(process)
|
225
|
-
|
226
188
|
port = config_info["port"]
|
227
189
|
ssl = config_info.get("ssl", False)
|
228
190
|
auth = config_info.get("auth", False)
|
229
|
-
|
230
191
|
# Test health endpoint
|
231
192
|
print(f" ๐ Testing health endpoint...")
|
232
193
|
health_result = self.test_health_endpoint(port, ssl, auth)
|
233
194
|
print(f" Health: {'โ
' if health_result['success'] else 'โ'}")
|
234
|
-
|
235
195
|
# Test echo command
|
236
196
|
print(f" ๐ Testing echo command...")
|
237
197
|
if auth:
|
@@ -240,96 +200,75 @@ class ExampleTester:
|
|
240
200
|
else:
|
241
201
|
echo_result = self.test_echo_command(port, ssl, auth)
|
242
202
|
print(f" Echo: {'โ
' if echo_result['success'] else 'โ'}")
|
243
|
-
|
244
203
|
# Test full application specific commands
|
245
204
|
if example_type == "full_application":
|
246
205
|
print(f" ๐ง Testing full application commands...")
|
247
|
-
app_results = self.test_full_application_commands(port, ssl, auth,
|
206
|
+
app_results = self.test_full_application_commands(port, ssl, auth,
|
248
207
|
API_KEYS["admin"] if auth else None)
|
249
208
|
for cmd_name, result in app_results.items():
|
250
209
|
print(f" {cmd_name}: {'โ
' if result['success'] else 'โ'}")
|
251
|
-
|
252
210
|
# Store results
|
253
211
|
self.results[f"{example_type}_{config_name}"] = {
|
254
212
|
"health": health_result,
|
255
213
|
"echo": echo_result,
|
256
214
|
"config_info": config_info
|
257
215
|
}
|
258
|
-
|
259
216
|
if example_type == "full_application":
|
260
217
|
self.results[f"{example_type}_{config_name}"]["app_commands"] = app_results
|
261
|
-
|
262
218
|
except Exception as e:
|
263
219
|
print(f" โ Error testing {config_name}: {e}")
|
264
220
|
self.results[f"{example_type}_{config_name}"] = {
|
265
221
|
"error": str(e),
|
266
222
|
"config_info": config_info
|
267
223
|
}
|
268
|
-
|
269
224
|
finally:
|
270
225
|
# Stop server
|
271
226
|
if process:
|
272
227
|
process.terminate()
|
273
228
|
process.wait()
|
274
229
|
time.sleep(2)
|
275
|
-
|
276
230
|
self.print_results()
|
277
|
-
|
278
231
|
def print_results(self):
|
279
232
|
"""Print test results."""
|
280
233
|
print("\n๐ Test Results Summary")
|
281
234
|
print("=" * 60)
|
282
|
-
|
283
235
|
total_tests = len(self.results)
|
284
236
|
successful_tests = 0
|
285
|
-
|
286
237
|
for test_name, result in self.results.items():
|
287
238
|
print(f"\n๐ {test_name}")
|
288
|
-
|
289
239
|
if "error" in result:
|
290
240
|
print(f" โ Error: {result['error']}")
|
291
241
|
continue
|
292
|
-
|
293
242
|
# Check health test
|
294
243
|
health_success = result.get("health", {}).get("success", False)
|
295
244
|
print(f" Health: {'โ
' if health_success else 'โ'}")
|
296
|
-
|
297
245
|
# Check echo test
|
298
246
|
echo_success = result.get("echo", {}).get("success", False)
|
299
247
|
print(f" Echo: {'โ
' if echo_success else 'โ'}")
|
300
|
-
|
301
248
|
# Check app commands for full application
|
302
249
|
if "app_commands" in result:
|
303
|
-
app_success = all(cmd_result.get("success", False)
|
250
|
+
app_success = all(cmd_result.get("success", False)
|
304
251
|
for cmd_result in result["app_commands"].values())
|
305
252
|
print(f" App Commands: {'โ
' if app_success else 'โ'}")
|
306
|
-
|
307
253
|
# Overall test success
|
308
254
|
test_success = health_success and echo_success
|
309
255
|
if test_success:
|
310
256
|
successful_tests += 1
|
311
|
-
|
312
257
|
print(f"\n๐ฏ Overall Results: {successful_tests}/{total_tests} tests passed")
|
313
|
-
|
314
258
|
if successful_tests == total_tests:
|
315
259
|
print("๐ All tests passed!")
|
316
260
|
else:
|
317
261
|
print("โ ๏ธ Some tests failed. Check the details above.")
|
318
|
-
|
319
262
|
def cleanup(self):
|
320
263
|
"""Cleanup processes."""
|
321
264
|
for process in self.processes:
|
322
265
|
if process.poll() is None:
|
323
266
|
process.terminate()
|
324
267
|
process.wait()
|
325
|
-
|
326
|
-
|
327
268
|
def main():
|
328
269
|
"""Main function."""
|
329
270
|
import sys
|
330
|
-
|
331
271
|
tester = ExampleTester()
|
332
|
-
|
333
272
|
try:
|
334
273
|
tester.run_tests()
|
335
274
|
except KeyboardInterrupt:
|
@@ -338,7 +277,5 @@ def main():
|
|
338
277
|
print(f"\nโ Test execution failed: {e}")
|
339
278
|
finally:
|
340
279
|
tester.cleanup()
|
341
|
-
|
342
|
-
|
343
280
|
if __name__ == "__main__":
|
344
281
|
main()
|