mcp-proxy-adapter 6.2.24__py3-none-any.whl → 6.2.26__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 (33) hide show
  1. mcp_proxy_adapter/api/app.py +0 -3
  2. mcp_proxy_adapter/api/middleware/protocol_middleware.py +10 -10
  3. mcp_proxy_adapter/commands/health_command.py +1 -1
  4. mcp_proxy_adapter/config.py +234 -23
  5. mcp_proxy_adapter/core/protocol_manager.py +9 -9
  6. mcp_proxy_adapter/examples/create_certificates_simple.py +7 -17
  7. mcp_proxy_adapter/examples/examples/basic_framework/__init__.py +9 -0
  8. mcp_proxy_adapter/examples/examples/basic_framework/commands/__init__.py +4 -0
  9. mcp_proxy_adapter/examples/examples/basic_framework/hooks/__init__.py +4 -0
  10. mcp_proxy_adapter/examples/examples/basic_framework/main.py +44 -0
  11. mcp_proxy_adapter/examples/examples/full_application/__init__.py +12 -0
  12. mcp_proxy_adapter/examples/examples/full_application/commands/__init__.py +7 -0
  13. mcp_proxy_adapter/examples/examples/full_application/commands/custom_echo_command.py +80 -0
  14. mcp_proxy_adapter/examples/examples/full_application/commands/dynamic_calculator_command.py +90 -0
  15. mcp_proxy_adapter/examples/examples/full_application/hooks/__init__.py +7 -0
  16. mcp_proxy_adapter/examples/examples/full_application/hooks/application_hooks.py +75 -0
  17. mcp_proxy_adapter/examples/examples/full_application/hooks/builtin_command_hooks.py +71 -0
  18. mcp_proxy_adapter/examples/examples/full_application/main.py +173 -0
  19. mcp_proxy_adapter/examples/examples/full_application/proxy_endpoints.py +154 -0
  20. mcp_proxy_adapter/examples/generate_test_configs.py +70 -33
  21. mcp_proxy_adapter/examples/run_full_test_suite.py +302 -109
  22. mcp_proxy_adapter/examples/run_security_tests.py +14 -5
  23. mcp_proxy_adapter/examples/scripts/config_generator.py +740 -0
  24. mcp_proxy_adapter/examples/scripts/create_certificates_simple.py +560 -0
  25. mcp_proxy_adapter/examples/scripts/generate_certificates_and_tokens.py +369 -0
  26. mcp_proxy_adapter/main.py +0 -2
  27. mcp_proxy_adapter/utils/config_generator.py +275 -7
  28. {mcp_proxy_adapter-6.2.24.dist-info → mcp_proxy_adapter-6.2.26.dist-info}/METADATA +1 -1
  29. {mcp_proxy_adapter-6.2.24.dist-info → mcp_proxy_adapter-6.2.26.dist-info}/RECORD +33 -17
  30. {mcp_proxy_adapter-6.2.24.dist-info → mcp_proxy_adapter-6.2.26.dist-info}/WHEEL +0 -0
  31. {mcp_proxy_adapter-6.2.24.dist-info → mcp_proxy_adapter-6.2.26.dist-info}/entry_points.txt +0 -0
  32. {mcp_proxy_adapter-6.2.24.dist-info → mcp_proxy_adapter-6.2.26.dist-info}/licenses/LICENSE +0 -0
  33. {mcp_proxy_adapter-6.2.24.dist-info → mcp_proxy_adapter-6.2.26.dist-info}/top_level.txt +0 -0
@@ -9,7 +9,7 @@ import json
9
9
  import os
10
10
  import argparse
11
11
  from typing import Dict, Any
12
- def generate_http_simple_config(port: int = 20000, certs_dir: str = "./certs", keys_dir: str = "./keys") -> Dict[str, Any]:
12
+ def generate_http_simple_config(port: int = 20000, certs_dir: str = "certs", keys_dir: str = "keys") -> Dict[str, Any]:
13
13
  """Generate HTTP configuration without authorization."""
14
14
  return {
15
15
  "server": {"host": "127.0.0.1", "port": port},
@@ -29,7 +29,7 @@ def generate_http_simple_config(port: int = 20000, certs_dir: str = "./certs", k
29
29
  },
30
30
  "protocols": {"enabled": True, "allowed_protocols": ["http"]}
31
31
  }
32
- def generate_http_token_config(port: int = 20001, certs_dir: str = "./certs", keys_dir: str = "./keys") -> Dict[str, Any]:
32
+ def generate_http_token_config(port: int = 20001, certs_dir: str = "certs", keys_dir: str = "keys", roles_file: str = "configs/roles.json") -> Dict[str, Any]:
33
33
  """Generate HTTP configuration with token authorization."""
34
34
  return {
35
35
  "server": {"host": "127.0.0.1", "port": port},
@@ -48,7 +48,7 @@ def generate_http_token_config(port: int = 20001, certs_dir: str = "./certs", ke
48
48
  "proxy-token-123": "proxy"
49
49
  }
50
50
  },
51
- "permissions": {"enabled": True, "roles_file": "./roles.json"}
51
+ "permissions": {"enabled": True, "roles_file": roles_file}
52
52
  },
53
53
  "registration": {
54
54
  "enabled": True,
@@ -61,14 +61,14 @@ def generate_http_token_config(port: int = 20001, certs_dir: str = "./certs", ke
61
61
  },
62
62
  "protocols": {"enabled": True, "allowed_protocols": ["http"]}
63
63
  }
64
- def generate_https_simple_config(port: int = 20002, certs_dir: str = "./certs", keys_dir: str = "./keys") -> Dict[str, Any]:
64
+ def generate_https_simple_config(port: int = 20002, certs_dir: str = "certs", keys_dir: str = "keys") -> Dict[str, Any]:
65
65
  """Generate HTTPS configuration without client certificate verification and authorization."""
66
66
  return {
67
67
  "server": {"host": "127.0.0.1", "port": port},
68
68
  "ssl": {
69
69
  "enabled": True,
70
- "cert_file": "./certs/localhost_server.crt",
71
- "key_file": "./keys/localhost_server.key"
70
+ "cert_file": f"{certs_dir}/localhost_server.crt",
71
+ "key_file": f"{keys_dir}/localhost_server.key"
72
72
  },
73
73
  "security": {"enabled": False},
74
74
  "registration": {
@@ -82,14 +82,14 @@ def generate_https_simple_config(port: int = 20002, certs_dir: str = "./certs",
82
82
  },
83
83
  "protocols": {"enabled": True, "allowed_protocols": ["http", "https"]}
84
84
  }
85
- def generate_https_token_config(port: int = 20003, certs_dir: str = "./certs", keys_dir: str = "./keys") -> Dict[str, Any]:
85
+ def generate_https_token_config(port: int = 20003, certs_dir: str = "certs", keys_dir: str = "keys") -> Dict[str, Any]:
86
86
  """Generate HTTPS configuration without client certificate verification with token authorization."""
87
87
  return {
88
88
  "server": {"host": "127.0.0.1", "port": port},
89
89
  "ssl": {
90
90
  "enabled": True,
91
- "cert_file": "./certs/localhost_server.crt",
92
- "key_file": "./keys/localhost_server.key"
91
+ "cert_file": f"{certs_dir}/localhost_server.crt",
92
+ "key_file": f"{keys_dir}/localhost_server.key"
93
93
  },
94
94
  "security": {
95
95
  "enabled": True,
@@ -104,7 +104,7 @@ def generate_https_token_config(port: int = 20003, certs_dir: str = "./certs", k
104
104
  "proxy-token-123": "proxy"
105
105
  }
106
106
  },
107
- "permissions": {"enabled": True, "roles_file": "./roles.json"}
107
+ "permissions": {"enabled": True, "roles_file": "./configs/roles.json"}
108
108
  },
109
109
  "registration": {
110
110
  "enabled": True,
@@ -117,33 +117,33 @@ def generate_https_token_config(port: int = 20003, certs_dir: str = "./certs", k
117
117
  },
118
118
  "protocols": {"enabled": True, "allowed_protocols": ["http", "https"]}
119
119
  }
120
- def generate_mtls_no_roles_config(port: int = 20004, certs_dir: str = "./certs", keys_dir: str = "./keys") -> Dict[str, Any]:
120
+ def generate_mtls_no_roles_config(port: int = 20004, certs_dir: str = "certs", keys_dir: str = "keys") -> Dict[str, Any]:
121
121
  """Generate mTLS configuration without roles."""
122
122
  return {
123
123
  "server": {"host": "127.0.0.1", "port": port},
124
124
  "ssl": {
125
125
  "enabled": True,
126
- "cert_file": "./certs/localhost_server.crt",
127
- "key_file": "./keys/localhost_server.key",
128
- "ca_cert": "./certs/mcp_proxy_adapter_ca_ca.crt",
126
+ "cert_file": f"{certs_dir}/localhost_server.crt",
127
+ "key_file": f"{keys_dir}/localhost_server.key",
128
+ "ca_cert": f"{certs_dir}/mcp_proxy_adapter_ca_ca.crt",
129
129
  "verify_client": True
130
130
  },
131
131
  "security": {
132
132
  "enabled": True,
133
133
  "auth": {"enabled": True, "methods": ["certificate"]},
134
- "permissions": {"enabled": True, "roles_file": "./roles.json"}
134
+ "permissions": {"enabled": False}
135
135
  },
136
136
  "protocols": {"enabled": True, "allowed_protocols": ["https", "mtls"]}
137
137
  }
138
- def generate_mtls_with_roles_config(port: int = 20005, certs_dir: str = "./certs", keys_dir: str = "./keys") -> Dict[str, Any]:
138
+ def generate_mtls_with_roles_config(port: int = 20005, certs_dir: str = "certs", keys_dir: str = "keys", roles_file: str = "configs/roles.json") -> Dict[str, Any]:
139
139
  """Generate mTLS configuration with roles."""
140
140
  return {
141
141
  "server": {"host": "127.0.0.1", "port": port},
142
142
  "ssl": {
143
143
  "enabled": True,
144
- "cert_file": "./certs/localhost_server.crt",
145
- "key_file": "./keys/localhost_server.key",
146
- "ca_cert": "./certs/mcp_proxy_adapter_ca_ca.crt",
144
+ "cert_file": f"{certs_dir}/localhost_server.crt",
145
+ "key_file": f"{keys_dir}/localhost_server.key",
146
+ "ca_cert": f"{certs_dir}/mcp_proxy_adapter_ca_ca.crt",
147
147
  "verify_client": True
148
148
  },
149
149
  "registration": {
@@ -161,7 +161,7 @@ def generate_mtls_with_roles_config(port: int = 20005, certs_dir: str = "./certs
161
161
  "security": {
162
162
  "enabled": True,
163
163
  "auth": {"enabled": True, "methods": ["certificate"]},
164
- "permissions": {"enabled": True, "roles_file": "./roles.json"}
164
+ "permissions": {"enabled": True, "roles_file": roles_file}
165
165
  },
166
166
  "protocols": {"enabled": True, "allowed_protocols": ["https", "mtls"]}
167
167
  }
@@ -222,15 +222,18 @@ def generate_roles_config() -> Dict[str, Any]:
222
222
  "tokens": ["proxy-token-123"]
223
223
  }
224
224
  }
225
- def generate_all_configs(output_dir: str, certs_dir: str = "./certs", keys_dir: str = "./keys") -> None:
225
+ def generate_all_configs(output_dir: str, certs_dir: str = "certs", keys_dir: str = "keys", roles_file: str = "configs/roles.json") -> None:
226
226
  """Generate all 6 configuration types and save them to files."""
227
+ # Ensure output directory exists first
228
+ os.makedirs(output_dir, exist_ok=True)
229
+
227
230
  configs = {
228
231
  "http_simple": generate_http_simple_config(20000, certs_dir, keys_dir),
229
- "http_token": generate_http_token_config(20001, certs_dir, keys_dir),
232
+ "http_token": generate_http_token_config(20001, certs_dir, keys_dir, roles_file),
230
233
  "https_simple": generate_https_simple_config(20002, certs_dir, keys_dir),
231
234
  "https_token": generate_https_token_config(20003, certs_dir, keys_dir),
232
235
  "mtls_no_roles": generate_mtls_no_roles_config(20004, certs_dir, keys_dir),
233
- "mtls_with_roles": generate_mtls_with_roles_config(20005, certs_dir, keys_dir)
236
+ "mtls_with_roles": generate_mtls_with_roles_config(20005, certs_dir, keys_dir, roles_file)
234
237
  }
235
238
  # Ensure output directory exists
236
239
  os.makedirs(output_dir, exist_ok=True)
@@ -242,17 +245,36 @@ def generate_all_configs(output_dir: str, certs_dir: str = "./certs", keys_dir:
242
245
  print(f"Generated: {filename}")
243
246
  # Generate roles configuration
244
247
  roles_config = generate_roles_config()
248
+
249
+ # Create roles.json in the root directory (test environment root) for compatibility
250
+ # When running as module, we need to create roles.json in the current working directory
251
+ # This is the directory where the user is running the command from
252
+ try:
253
+ # Get the current working directory where the user is running the command
254
+ current_dir = os.getcwd()
255
+ root_roles_filename = os.path.join(current_dir, "roles.json")
256
+
257
+ # Create roles.json in the current working directory
258
+ with open(root_roles_filename, 'w', encoding='utf-8') as f:
259
+ json.dump(roles_config, f, indent=2, ensure_ascii=False)
260
+ print(f"Generated: {root_roles_filename}")
261
+
262
+ # Also create a copy in the output directory for reference
263
+ backup_roles_filename = os.path.join(output_dir, "roles_backup.json")
264
+ with open(backup_roles_filename, 'w', encoding='utf-8') as f:
265
+ json.dump(roles_config, f, indent=2, ensure_ascii=False)
266
+ print(f"Generated backup: {backup_roles_filename}")
267
+
268
+ except Exception as e:
269
+ print(f"Warning: Could not create roles.json in current directory: {e}")
270
+ print(f"Current working directory: {os.getcwd()}")
271
+ print(f"Script directory: {os.path.dirname(os.path.abspath(__file__))}")
272
+
273
+ # Also create roles.json in configs directory for reference
245
274
  roles_filename = os.path.join(output_dir, "roles.json")
246
275
  with open(roles_filename, 'w', encoding='utf-8') as f:
247
276
  json.dump(roles_config, f, indent=2, ensure_ascii=False)
248
277
  print(f"Generated: {roles_filename}")
249
- # Also create roles.json in certs directory for compatibility
250
- certs_dir = os.path.join(os.path.dirname(output_dir), "certs")
251
- if os.path.exists(certs_dir):
252
- certs_roles_filename = os.path.join(certs_dir, "roles.json")
253
- with open(certs_roles_filename, 'w', encoding='utf-8') as f:
254
- json.dump(roles_config, f, indent=2, ensure_ascii=False)
255
- print(f"Generated: {certs_roles_filename}")
256
278
  print(f"\nGenerated {len(configs)} configuration files and roles.json in {output_dir}")
257
279
 
258
280
  print("\n" + "=" * 60)
@@ -273,12 +295,27 @@ def main():
273
295
  )
274
296
  parser.add_argument(
275
297
  "--output-dir",
276
- default="./configs",
277
- help="Output directory for configuration files (default: ./configs)"
298
+ default="configs",
299
+ help="Output directory for configuration files (default: configs)"
300
+ )
301
+ parser.add_argument(
302
+ "--certs-dir",
303
+ default="certs",
304
+ help="Certificates directory (default: certs)"
305
+ )
306
+ parser.add_argument(
307
+ "--keys-dir",
308
+ default="keys",
309
+ help="Keys directory (default: keys)"
310
+ )
311
+ parser.add_argument(
312
+ "--roles-file",
313
+ default="configs/roles.json",
314
+ help="Roles file path (default: configs/roles.json)"
278
315
  )
279
316
  args = parser.parse_args()
280
317
  try:
281
- generate_all_configs(args.output_dir)
318
+ generate_all_configs(args.output_dir, args.certs_dir, args.keys_dir, args.roles_file)
282
319
  print("Configuration generation completed successfully!")
283
320
  except Exception as e:
284
321
  print(f"\n❌ CONFIGURATION GENERATION FAILED: {e}")
@@ -1,125 +1,318 @@
1
1
  #!/usr/bin/env python3
2
2
  """
3
- Full Test Suite Runner for MCP Proxy Adapter
4
- This script automatically runs the complete test suite:
5
- 1. Setup test environment
6
- 2. Generate configurations
7
- 3. Create certificates
8
- 4. Run security tests
9
-
10
3
  Author: Vasiliy Zdanovskiy
11
4
  email: vasilyvz@gmail.com
5
+ Full test suite runner for MCP Proxy Adapter.
6
+ Automates the complete testing workflow.
12
7
  """
8
+ import os
13
9
  import sys
14
10
  import subprocess
15
- import os
11
+ import time
16
12
  from pathlib import Path
13
+ from typing import List, Dict, Optional
17
14
 
18
-
19
- def run_command(cmd: list, description: str) -> bool:
20
- """Run a command and return success status."""
21
- try:
22
- print(f"\n🚀 {description}")
23
- print("=" * 60)
24
-
25
- # Change to script directory if running from package
26
- script_dir = Path(__file__).parent
27
- if script_dir.name == "examples":
28
- os.chdir(script_dir)
29
-
30
- result = subprocess.run(
31
- cmd,
32
- capture_output=False,
33
- text=True,
34
- check=True,
35
- cwd=script_dir
36
- )
37
- print(f"✅ {description} completed successfully")
38
- return True
39
- except subprocess.CalledProcessError as e:
40
- print(f" {description} failed:")
41
- print(f" Command: {' '.join(cmd)}")
42
- print(f" Error: {e.stderr}")
43
- return False
44
- except Exception as e:
45
- print(f"{description} failed: {e}")
46
- return False
47
-
48
-
49
- def main():
50
- """Run the complete test suite."""
51
- print("🧪 MCP Proxy Adapter - Full Test Suite")
52
- print("=" * 60)
53
-
54
- # Check if we're in the right directory
55
- current_dir = Path.cwd()
56
- if not (current_dir / "setup_test_environment.py").exists():
57
- print("❌ Please run this script from the examples directory")
58
- return 1
59
-
60
- success = True
61
-
62
- # 1. Setup test environment
63
- if not run_command([
64
- sys.executable, "-m", "mcp_proxy_adapter.examples.setup_test_environment",
65
- "--output-dir", "."
66
- ], "Setting up test environment"):
67
- success = False
68
-
69
- # 2. Generate configurations
70
- if success and not run_command([
71
- sys.executable, "-m", "mcp_proxy_adapter.examples.generate_test_configs",
72
- "--output-dir", "configs"
73
- ], "Generating test configurations"):
74
- success = False
75
-
76
- # 3. Create certificates
77
- if success and not run_command([
78
- sys.executable, "-m", "mcp_proxy_adapter.examples.create_certificates_simple"
79
- ], "Creating certificates"):
80
- success = False
81
-
82
- # 4. Copy roles.json to root directory
83
- if success:
84
- import shutil
85
- from pathlib import Path
86
- roles_file = Path("configs/roles.json")
87
- if roles_file.exists():
88
- shutil.copy2(roles_file, "roles.json")
89
- print("✅ Copied roles.json to root directory")
15
+ class FullTestSuiteRunner:
16
+ """Comprehensive test suite runner that automates the entire testing process."""
17
+
18
+ def __init__(self):
19
+ """Initialize the test suite runner."""
20
+ self.working_dir = Path.cwd()
21
+ self.configs_dir = self.working_dir / "configs"
22
+ self.certs_dir = self.working_dir / "certs"
23
+ self.keys_dir = self.working_dir / "keys"
24
+ self.roles_file = self.working_dir / "configs" / "roles.json"
25
+
26
+ def print_step(self, step: str, description: str):
27
+ """Print a formatted step header."""
28
+ print(f"\n{'='*60}")
29
+ print(f"🔧 STEP {step}: {description}")
30
+ print(f"{'='*60}")
31
+
32
+ def print_success(self, message: str):
33
+ """Print a success message."""
34
+ print(f"✅ {message}")
35
+
36
+ def print_error(self, message: str):
37
+ """Print an error message."""
38
+ print(f" {message}")
39
+
40
+ def print_info(self, message: str):
41
+ """Print an info message."""
42
+ print(f"ℹ️ {message}")
43
+
44
+ def check_environment(self) -> bool:
45
+ """Check if the environment is properly set up."""
46
+ self.print_step("1", "Environment Validation")
47
+
48
+ # Check if we're in a virtual environment
49
+ if not hasattr(sys, 'real_prefix') and not (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix):
50
+ self.print_error("Not running in a virtual environment!")
51
+ self.print_info("Please activate your virtual environment first:")
52
+ self.print_info(" source venv/bin/activate # or .venv/bin/activate")
53
+ return False
54
+
55
+ self.print_success("Virtual environment is active")
56
+
57
+ # Check if mcp_proxy_adapter is installed
58
+ try:
59
+ import mcp_proxy_adapter
60
+ self.print_success(f"mcp_proxy_adapter is installed (version: {mcp_proxy_adapter.__version__})")
61
+ except ImportError:
62
+ self.print_error("mcp_proxy_adapter is not installed!")
63
+ self.print_info("Please install it first:")
64
+ self.print_info(" pip install mcp_proxy_adapter")
65
+ return False
66
+
67
+ # Check Python version
68
+ python_version = sys.version_info
69
+ if python_version.major >= 3 and python_version.minor >= 8:
70
+ self.print_success(f"Python version: {python_version.major}.{python_version.minor}.{python_version.micro}")
90
71
  else:
91
- success = False
92
- print("❌ roles.json not found in configs directory")
72
+ self.print_error(f"Python {python_version.major}.{python_version.minor} is not supported. Need Python 3.8+")
73
+ return False
74
+
75
+ return True
76
+
77
+ def create_directories(self) -> bool:
78
+ """Create necessary directories for testing."""
79
+ self.print_step("2", "Directory Creation")
80
+
81
+ try:
82
+ # Create configs directory
83
+ self.configs_dir.mkdir(exist_ok=True)
84
+ self.print_success(f"Created/verified configs directory: {self.configs_dir}")
85
+
86
+ # Create certs directory
87
+ self.certs_dir.mkdir(exist_ok=True)
88
+ self.print_success(f"Created/verified certs directory: {self.certs_dir}")
89
+
90
+ # Create keys directory
91
+ self.keys_dir.mkdir(exist_ok=True)
92
+ self.print_success(f"Created/verified keys directory: {self.keys_dir}")
93
+
94
+ return True
95
+
96
+ except Exception as e:
97
+ self.print_error(f"Failed to create directories: {e}")
98
+ return False
99
+
100
+ def generate_certificates(self) -> bool:
101
+ """Generate SSL certificates for testing."""
102
+ self.print_step("3", "Certificate Generation")
103
+
104
+ try:
105
+ # Run certificate generation script
106
+ cmd = [sys.executable, "-m", "mcp_proxy_adapter.examples.create_certificates_simple"]
107
+ self.print_info("Running certificate generation script...")
108
+
109
+ result = subprocess.run(cmd, capture_output=True, text=True, cwd=self.working_dir)
110
+
111
+ if result.returncode == 0:
112
+ self.print_success("Certificates generated successfully")
113
+ if result.stdout:
114
+ print(result.stdout)
115
+ return True
116
+ else:
117
+ self.print_error("Certificate generation failed!")
118
+ if result.stderr:
119
+ print("Error output:")
120
+ print(result.stderr)
121
+ return False
122
+
123
+ except Exception as e:
124
+ self.print_error(f"Failed to generate certificates: {e}")
125
+ return False
126
+
127
+ def generate_configurations(self) -> bool:
128
+ """Generate test configurations."""
129
+ self.print_step("4", "Configuration Generation")
130
+
131
+ try:
132
+ # Run configuration generation script
133
+ cmd = [sys.executable, "-m", "mcp_proxy_adapter.examples.generate_test_configs"]
134
+ self.print_info("Running configuration generation script...")
135
+
136
+ result = subprocess.run(cmd, capture_output=True, text=True, cwd=self.working_dir)
137
+
138
+ if result.returncode == 0:
139
+ self.print_success("Configurations generated successfully")
140
+ if result.stdout:
141
+ print(result.stdout)
142
+ return True
143
+ else:
144
+ self.print_error("Configuration generation failed!")
145
+ if result.stderr:
146
+ print("Error output:")
147
+ print(result.stderr)
148
+ return False
149
+
150
+ except Exception as e:
151
+ self.print_error(f"Failed to generate configurations: {e}")
152
+ return False
153
+
154
+ def run_security_tests(self) -> bool:
155
+ """Run the security test suite."""
156
+ self.print_step("5", "Security Testing")
157
+
158
+ try:
159
+ # Run security tests
160
+ cmd = [sys.executable, "-m", "mcp_proxy_adapter.examples.run_security_tests", "--verbose"]
161
+ self.print_info("Running security tests...")
162
+
163
+ # Debug: show current working directory and check files
164
+ self.print_info(f"DEBUG: Current working directory: {os.getcwd()}")
165
+ self.print_info(f"DEBUG: Working directory from class: {self.working_dir}")
166
+
167
+ # Check if certificates exist before running tests
168
+ localhost_cert = self.certs_dir / "localhost_server.crt"
169
+ self.print_info(f"DEBUG: localhost_server.crt exists: {localhost_cert.exists()}")
170
+ if localhost_cert.exists():
171
+ self.print_info(f"DEBUG: localhost_server.crt is symlink: {localhost_cert.is_symlink()}")
172
+ if localhost_cert.is_symlink():
173
+ self.print_info(f"DEBUG: localhost_server.crt symlink target: {localhost_cert.readlink()}")
174
+
175
+ # List all files in certs directory
176
+ self.print_info("DEBUG: Files in certs directory:")
177
+ for file in self.certs_dir.iterdir():
178
+ self.print_info(f"DEBUG: {file.name} -> {file}")
179
+
180
+ result = subprocess.run(cmd, capture_output=True, text=True, cwd=self.working_dir)
181
+
182
+ if result.returncode == 0:
183
+ self.print_success("Security tests completed successfully!")
184
+ if result.stdout:
185
+ print(result.stdout)
186
+ return True
187
+ else:
188
+ self.print_error("Security tests failed!")
189
+ if result.stdout:
190
+ print("Test output:")
191
+ print(result.stdout)
192
+ if result.stderr:
193
+ print("Error output:")
194
+ print(result.stderr)
195
+ return False
196
+
197
+ except Exception as e:
198
+ self.print_error(f"Failed to run security tests: {e}")
199
+ return False
200
+
201
+ def cleanup(self):
202
+ """Clean up temporary files and processes."""
203
+ self.print_info("Cleaning up...")
204
+
205
+ # Simple cleanup - just print success message
206
+ # Process cleanup is handled by the test scripts themselves
207
+ print("✅ Cleanup completed")
208
+
93
209
 
94
- # 5. Run security tests
95
- if success and not run_command([
96
- sys.executable, "-m", "mcp_proxy_adapter.examples.run_security_tests"
97
- ], "Running security tests"):
98
- success = False
99
210
 
100
- # Final result
101
- print("\n" + "=" * 60)
102
- if success:
103
- print("🎉 FULL TEST SUITE COMPLETED SUCCESSFULLY!")
104
- print("=" * 60)
105
- print("\n📋 SUMMARY:")
106
- print("✅ Test environment setup")
107
- print("✅ Configuration generation")
108
- print("✅ Certificate creation")
109
- print("✅ Roles configuration")
110
- print("✅ Security testing")
111
- print("\n🚀 All systems are working correctly!")
112
- return 0
113
- else:
114
- print("❌ FULL TEST SUITE FAILED!")
211
+ def cleanup_directories(self) -> bool:
212
+ """Clean up existing test directories before starting."""
213
+ self.print_info("Cleaning up existing test directories...")
214
+
215
+ try:
216
+ import shutil
217
+
218
+ # Directories to clean
219
+ dirs_to_clean = [self.configs_dir, self.certs_dir, self.keys_dir]
220
+ files_to_clean = [self.working_dir / "roles.json"]
221
+
222
+ # Remove directories
223
+ for dir_path in dirs_to_clean:
224
+ if dir_path.exists():
225
+ shutil.rmtree(dir_path)
226
+ print(f"🗑️ Removed directory: {dir_path}")
227
+
228
+ # Remove files
229
+ for file_path in files_to_clean:
230
+ if file_path.exists():
231
+ file_path.unlink()
232
+ print(f"🗑️ Removed file: {file_path}")
233
+
234
+ self.print_success("Directory cleanup completed")
235
+ return True
236
+
237
+ except Exception as e:
238
+ self.print_error(f"Failed to cleanup directories: {e}")
239
+ return False
240
+
241
+ def run_full_suite(self) -> bool:
242
+ """Run the complete test suite."""
243
+ print("🚀 MCP Proxy Adapter - Full Test Suite")
115
244
  print("=" * 60)
116
- print("\n🔧 TROUBLESHOOTING:")
117
- print("1. Check the error messages above")
118
- print("2. Ensure you have write permissions")
119
- print("3. Make sure ports 20000-20010 are free")
120
- print("4. Check if mcp_security_framework is installed")
121
- return 1
245
+ print(f"Working directory: {self.working_dir}")
246
+ print(f"Python executable: {sys.executable}")
247
+
248
+ try:
249
+ # Step 0: Clean up existing directories
250
+ if not self.cleanup_directories():
251
+ return False
252
+
253
+ # Step 1: Environment validation
254
+ if not self.check_environment():
255
+ return False
256
+
257
+ # Step 2: Directory creation
258
+ if not self.create_directories():
259
+ return False
260
+
261
+ # Step 3: Certificate generation
262
+ if not self.generate_certificates():
263
+ return False
264
+
265
+ # Step 4: Configuration generation
266
+ if not self.generate_configurations():
267
+ return False
268
+
269
+ # Step 5: Security testing
270
+ if not self.run_security_tests():
271
+ return False
272
+
273
+ # All steps completed successfully
274
+ print(f"\n{'='*60}")
275
+ print("🎉 FULL TEST SUITE COMPLETED SUCCESSFULLY!")
276
+ print("="*60)
277
+ print("✅ Environment validated")
278
+ print("✅ Directories cleaned")
279
+ print("✅ Directories created")
280
+ print("✅ Certificates generated")
281
+ print("✅ Configurations generated")
282
+ print("✅ Security tests passed")
283
+ print(f"\n📁 Test artifacts created in: {self.working_dir}")
284
+ print(f"📁 Configurations: {self.configs_dir}")
285
+ print(f"📁 Certificates: {self.certs_dir}")
286
+ print(f"📁 Keys: {self.keys_dir}")
287
+
288
+ return True
289
+
290
+ except KeyboardInterrupt:
291
+ print("\n\n⚠️ Test suite interrupted by user")
292
+ return False
293
+ except Exception as e:
294
+ self.print_error(f"Unexpected error during test suite execution: {e}")
295
+ return False
296
+ finally:
297
+ try:
298
+ self.print_info("Starting cleanup in finally block...")
299
+ self.cleanup()
300
+ self.print_info("Cleanup in finally block completed")
301
+ except Exception as e:
302
+ self.print_error(f"Cleanup failed in finally block: {e}")
303
+ import traceback
304
+ traceback.print_exc()
122
305
 
306
+ def main():
307
+ """Main entry point."""
308
+ runner = FullTestSuiteRunner()
309
+
310
+ try:
311
+ success = runner.run_full_suite()
312
+ sys.exit(0 if success else 1)
313
+ except Exception as e:
314
+ print(f"❌ Fatal error: {e}")
315
+ sys.exit(1)
123
316
 
124
317
  if __name__ == "__main__":
125
- exit(main())
318
+ main()