@@ -22,19 +22,11 @@ def load_scenarios(scenarios):
2222
2323
2424class Stress (object ):
25+ DEFAULT_VU = 100
26+ DEFAULT_DURATION = "60s"
27+
2528 def __init__ (
26- self ,
27- folder ,
28- address ,
29- user ,
30- password ,
31- space ,
32- vid_type ,
33- scenarios ,
34- vu ,
35- duration ,
36- dry_run ,
37- ** kwargs
29+ self , folder , address , user , password , space , vid_type , scenarios , args , dry_run , ** kwargs
3830 ):
3931 self .folder = folder or setting .DATA_FOLDER
4032 self .address = address or setting .NEBULA_ADDRESS
@@ -44,9 +36,8 @@ def __init__(
4436 self .vid_type = vid_type
4537 self .scenarios = []
4638 self .output_folder = "output"
47- self .vu = vu
48- self .duration = duration
4939 self .dry_run = dry_run
40+ self .args = args
5041 self .scenarios = load_scenarios (scenarios )
5142 logger .info ("total stress test scenarios is {}" .format (len (self .scenarios )))
5243
@@ -72,27 +63,18 @@ def gen_stress(
7263 space ,
7364 vid_type ,
7465 scenarios ,
75- vu ,
76- duration ,
66+ args ,
7767 dry_run = None ,
7868 ** kwargs
7969 ):
8070 if _type .upper () not in cls .type_list :
8171 raise Exception ("not impletment this test tool, tool is {}" .format (_type ))
8272
8373 clazz = cls .get_all_stress_class ().get ("{}Stress" .format (_type .upper ()), None )
74+ if args is not None :
75+ args = args .strip ()
8476 return clazz (
85- folder ,
86- address ,
87- user ,
88- password ,
89- space ,
90- vid_type ,
91- scenarios ,
92- vu ,
93- duration ,
94- dry_run ,
95- ** kwargs
77+ folder , address , user , password , space , vid_type , scenarios , args , dry_run , ** kwargs
9678 )
9779
9880 @classmethod
@@ -140,35 +122,99 @@ def dump_config(self, scenario):
140122 )
141123 jinja_dump (template_file , "{}/{}.js" .format (self .output_folder , name ), kwargs )
142124
125+ def _get_params (self ):
126+ """
127+ e.g.
128+ args:
129+ "-s 60s:0 -s 40s:30 -v"
130+ return:
131+ {
132+ "-s": ["60s:0", "40s:30"],
133+ "-v": None
134+ }
135+ """
136+ r = {}
137+ if self .args is None :
138+ return r
139+
140+ key , value = None , None
141+ for item in self .args .split (" " ):
142+ if item .startswith ("-" ):
143+ if key is not None and key not in r :
144+ r [key ] = None
145+ key = item
146+ elif item .strip () != "" :
147+ value = item
148+ if key not in r :
149+ r [key ] = [value ]
150+ else :
151+ r [key ].append (value )
152+
153+ if key is not None and key not in r :
154+ r [key ] = None
155+ return r
156+
143157 def run (self ):
144158 logger .info ("run stress test in k6" )
145- logger .info (
146- "every scenario would run by {} vus and last {} secconds" .format (self .vu , self .duration )
147- )
159+ params = self ._get_params ()
160+
161+ # cannot use both stage and vu
162+ run_with_stage = "-s" in params or "--stage" in params
163+ vu = self .DEFAULT_VU
164+ duration = self .DEFAULT_DURATION
165+ if "-u" in params :
166+ vu = params .pop ("-u" )[0 ]
167+ if "--vus" in params :
168+ vu = params .pop ("--vus" )[0 ]
169+ if "-vu" in params :
170+ vu = params .pop ("-vu" )[0 ]
171+
172+ if "-d" in params :
173+ duration = params .pop ("-d" )[0 ]
174+ if "--duration" in params :
175+ duration = params .pop ("--duration" )[0 ]
176+
177+ logger .info ("every scenario would run by {} vus and last {}" .format (vu , duration ))
148178 Path (self .output_folder ).mkdir (exist_ok = True )
149- for scenario in self .scenarios :
179+ if "--summary-trend-stats" not in params :
180+ params ["--summary-trend-stats" ] = ["min,avg,med,max,p(90),p(95),p(99)" ]
181+ if setting .INFLUXDB_URL is not None and "--out" not in params and "-o" not in params :
182+ params ["--out" ] = ["influxdb={}" .format (setting .INFLUXDB_URL )]
150183
184+ for scenario in self .scenarios :
151185 self .dump_config (scenario )
152- # run k6
153- command = [
154- "scripts/k6" ,
155- "run" ,
156- "{}/{}.js" .format (self .output_folder , scenario .name ),
157- "-u" ,
158- str (self .vu ),
159- "-d" ,
160- "{}s" .format (self .duration ),
161- "--summary-trend-stats" ,
162- "min,avg,med,max,p(90),p(95),p(99)" ,
163- "--summary-export" ,
164- "{}/result_{}.json" .format (self .output_folder , scenario .name ),
165- ]
166- if setting .INFLUXDB_URL is not None :
167- command .append ("--out" )
168- command .append ("influxdb={}" .format (setting .INFLUXDB_URL ))
186+ if run_with_stage :
187+ command = [
188+ "scripts/k6" ,
189+ "run" ,
190+ "{}/{}.js" .format (self .output_folder , scenario .name ),
191+ ]
192+ else :
193+ command = [
194+ "scripts/k6" ,
195+ "run" ,
196+ "{}/{}.js" .format (self .output_folder , scenario .name ),
197+ "-u" ,
198+ str (vu ),
199+ "-d" ,
200+ str (duration ),
201+ ]
202+
203+ if "--summary-export" not in params :
204+ params ["--summary-export" ] = [
205+ "{}/result_{}.json" .format (self .output_folder , scenario .name )
206+ ]
207+
208+ for param , values in params .items ():
209+ if values is None :
210+ command .append (param )
211+ else :
212+ for v in values :
213+ command .append (param )
214+ command .append (v )
169215
170216 click .echo ("run command as below:" )
171- click .echo (" " .join (command ))
217+ click .echo (" " .join ([ x if "(" not in x else '"{}"' . format ( x ) for x in command ] ))
172218 if self .dry_run is not None and self .dry_run :
173219 continue
174220 run_process (command )
0 commit comments