1616"""MCP Load Test Entry Point Script.
1717
1818Run load tests against MCP servers using YAML configuration files.
19-
20- Usage:
21- python cli.py --config_file=./configs/config.yml
22- python cli.py -c configs/config.yml --verbose
2319"""
2420
2521import argparse
@@ -43,35 +39,14 @@ def parse_args():
4339 parser = argparse .ArgumentParser (
4440 description = "Run MCP server load tests using YAML configuration" ,
4541 formatter_class = argparse .RawDescriptionHelpFormatter ,
46- epilog = """
47- Examples:
48- # Run with config file
49- python cli.py --config_file=configs/config.yml
50-
51- # With verbose logging
52- python cli.py --config_file=configs/config.yml --verbose
53-
54- # Short form
55- python cli.py -c configs/config.yml
56-
57- Configuration File Format:
58- The YAML config file should contain:
59- - config_file: Path to NAT workflow config
60- - server: Server configuration (host, port, transport)
61- - load_test: Test parameters (num_concurrent_users, duration_seconds, etc.)
62- - output: Output directory configuration
63- - tool_calls: List of tool calls to execute
64-
65- See configs/config.yml for a complete example.
66- """ ,
6742 )
6843
6944 parser .add_argument (
7045 "-c" ,
7146 "--config_file" ,
7247 type = str ,
7348 required = True ,
74- help = "Path to YAML configuration file (e.g., configs/config.yml) " ,
49+ help = "Path to YAML configuration file" ,
7550 )
7651
7752 parser .add_argument (
@@ -94,7 +69,6 @@ def print_summary(results: dict):
9469 logger .info ("LOAD TEST RESULTS SUMMARY" )
9570 logger .info ("=" * 70 )
9671
97- # Summary metrics
9872 summary = results .get ("summary" , {})
9973 logger .info ("\n Summary Metrics:" )
10074 logger .info (" Total Requests: %d" , summary .get ("total_requests" , 0 ))
@@ -104,7 +78,6 @@ def print_summary(results: dict):
10478 logger .info (" Test Duration: %.2f seconds" , summary .get ("test_duration_seconds" , 0 ))
10579 logger .info (" Requests/Second: %.2f" , summary .get ("requests_per_second" , 0 ))
10680
107- # Latency statistics
10881 latency = results .get ("latency_statistics" , {})
10982 logger .info ("\n Latency Statistics:" )
11083 logger .info (" Mean: %.2f ms" , latency .get ("mean_ms" , 0 ))
@@ -114,7 +87,6 @@ def print_summary(results: dict):
11487 logger .info (" Min: %.2f ms" , latency .get ("min_ms" , 0 ))
11588 logger .info (" Max: %.2f ms" , latency .get ("max_ms" , 0 ))
11689
117- # Memory statistics
11890 memory = results .get ("memory_statistics" , {})
11991 if memory :
12092 logger .info ("\n Memory Statistics:" )
@@ -125,7 +97,6 @@ def print_summary(results: dict):
12597 logger .info (" Mean Memory Usage: %.2f%%" , memory .get ("percent_mean" , 0 ))
12698 logger .info (" Max Memory Usage: %.2f%%" , memory .get ("percent_max" , 0 ))
12799
128- # Per-tool statistics
129100 tool_stats = results .get ("per_tool_statistics" , {})
130101 if tool_stats :
131102 logger .info ("\n Per-Tool Statistics:" )
@@ -135,14 +106,12 @@ def print_summary(results: dict):
135106 logger .info (" Success Rate: %.2f%%" , stats .get ("success_rate" , 0 ))
136107 logger .info (" Mean Latency: %.2f ms" , stats .get ("mean_latency_ms" , 0 ))
137108
138- # Errors
139109 errors = results .get ("errors" , {})
140110 if errors :
141111 logger .info ("\n Errors:" )
142112 for error_msg , count in sorted (errors .items (), key = lambda x : x [1 ], reverse = True )[:5 ]:
143113 logger .info (" [%d] %s" , count , error_msg [:80 ])
144114
145- # Output location
146115 test_config = results .get ("test_configuration" , {})
147116 output_dir = test_config .get ("output_dir" , "load_test_results" )
148117 logger .info ("\n " + "=" * 70 )
@@ -154,18 +123,14 @@ def main():
154123 """Main entry point."""
155124 args = parse_args ()
156125
157- # Set logging level
158126 if args .verbose :
159127 logging .getLogger ().setLevel (logging .DEBUG )
160128 logger .debug ("Verbose logging enabled" )
161129
162- # Validate config file path
163130 config_path = Path (args .config_file )
164131
165132 if not config_path .exists ():
166133 logger .error ("Configuration file not found: %s" , config_path )
167-
168- # Try to find it relative to script directory
169134 script_dir = Path (__file__ ).parent
170135 alternative_path = script_dir / args .config_file
171136
@@ -179,18 +144,15 @@ def main():
179144 logger .info ("Configuration file: %s" , config_path .absolute ())
180145
181146 try :
182- # Run the load test
183147 results = run_load_test_from_yaml (str (config_path ))
184148
185- # Print summary
186149 print_summary (results )
187150
188- # Return success
189151 return 0
190152
191153 except KeyboardInterrupt :
192154 logger .warning ("\n Load test interrupted by user" )
193- return 130 # Standard exit code for SIGINT
155+ return 130
194156
195157 except Exception as e :
196158 logger .error ("Load test failed: %s" , e , exc_info = args .verbose )
0 commit comments