Skip to content

Commit 638bb54

Browse files
rflorencndokos
authored andcommitted
Add blazemeter taurus script to bench-scripts/contrib.
Added a description in the beginning of the file similar to the one found in the other bench tools. Removed yaml (PyYaml) dependency. pbench_bzt now uses/generates json scenario files. Added initial platform detection code. Move pbench-bzt to bench-scripts/contrib: it will be moved to bench-scripts/ (which is in the PATH) when it conforms to the standard conventions. Right now, it's just a convenience wrapper.
1 parent 357f7de commit 638bb54

File tree

1 file changed

+182
-0
lines changed

1 file changed

+182
-0
lines changed
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
#!/usr/bin/env python
2+
3+
"""
4+
This script generates a bzt taurus json file and executes a performance test based on it.
5+
It is a wrapper for the bzt tool.
6+
7+
By default, it uses the jmeter executor with the simple scenario set up [1].
8+
It is required to have a file containing the URL's of the websites to test.
9+
10+
cat urls_to_test.lst
11+
pod1.cloudapps.example.com
12+
pod2.cloudapps.example.com
13+
pod3.cloudapps.example.comz
14+
15+
The simplest way of running it would then be be:
16+
./pbench_bzt -u urls_to_test.lst
17+
18+
For HTTP/TLS testing, use:
19+
./pbench_bzt -u urls_to_test.lst -p https://
20+
21+
It outputs a post-test summary using the final stats module [2]
22+
This is the simplest reporter that prints out basic KPIs in the console log after test execution.
23+
24+
pbench_bzt uses the following load profiles for the jmeter executor:
25+
concurrency - number of target concurrent virtual users
26+
ramp-up - ramp-up time to reach target concurrency
27+
hold-for - time to hold target concurrency
28+
29+
These are customizable using the -c, -r and -d command line arguments.
30+
31+
By default, pbench_bzt outputs a taurus.csv and a bzt.json file under the /tmp directory with the test results
32+
and scenario data, respectively. This can be changed using the -f and -o arguments.
33+
34+
35+
[1] "http://gettaurus.org/docs/ExecutionSettings/"
36+
[2] "http://gettaurus.org/docs/Reporting/"
37+
38+
"""
39+
40+
import argparse
41+
import subprocess
42+
import os
43+
import sys
44+
import platform
45+
import json
46+
47+
48+
class OSType(object):
49+
"""
50+
Detects Red Hat / CentOS / Fedora distributions
51+
"""
52+
53+
def __getattr__(self, attr):
54+
if attr == "fedora":
55+
return "fedora"
56+
elif attr == "rhel":
57+
return "redhat"
58+
elif attr == "unknown":
59+
return "unknown"
60+
else:
61+
raise (AttributeError, attr)
62+
63+
def platform_type(self):
64+
if platform.dist()[0] == self.rhel:
65+
return self.rhel
66+
elif platform.dist()[0] == self.fedora:
67+
return self.fedora
68+
else:
69+
return self.unknown
70+
71+
def query_os(self):
72+
if platform.system() == "Linux":
73+
return self.platform_type()
74+
75+
76+
class BztConfigWriter:
77+
"""
78+
Writes a template json config file for testing endpoints with taurus bzt
79+
"""
80+
def __init__(self, args):
81+
self.args = args
82+
self.bzt_conf = dict()
83+
self.bzt_conf['execution'] = []
84+
self.bzt_conf['reporting'] = []
85+
self.bzt_conf['scenarios'] = {}
86+
87+
def create_scenario_file(self):
88+
if self.args.scenario == "simple":
89+
count = 1
90+
with open(self.args.url_file) as f:
91+
for line in f:
92+
scenario_nbr = self.args.scenario + str(count)
93+
self.bzt_conf['execution'].append({'concurrency': self.args.concurrency,
94+
'hold-for': self.args.hold_for,
95+
'ramp-up': self.args.ramp_up,
96+
'scenario': scenario_nbr})
97+
self.bzt_conf['scenarios'][scenario_nbr] = {'requests': [self.args.prefix + line.strip()]}
98+
count += 1
99+
100+
self.bzt_conf['modules'] = {'blazemeter': {'browser-open': False, 'test': self.args.test_name},
101+
'console': {'disable': True}}
102+
self.bzt_conf['reporting'].append({'module': 'final_stats', 'dump-csv': self.args.stats_file})
103+
self.write_json_file(self.args.out_json_file)
104+
105+
def write_json_file(self, f):
106+
with open(f, mode='w') as fd:
107+
json.dump(self.bzt_conf, fd, sort_keys=True, indent=2)
108+
109+
110+
def which(cmd):
111+
"""
112+
Basic function that mimics the linux `which` cmd
113+
:param cmd: executable to look up for
114+
:return:
115+
"""
116+
def is_executable(path):
117+
return os.path.isfile(path) and os.access(path, os.X_OK)
118+
119+
path, name = os.path.split(cmd)
120+
if path:
121+
if is_executable(cmd):
122+
return cmd
123+
else:
124+
for path in os.environ["PATH"].split(os.pathsep):
125+
path = path.strip('"')
126+
cmdpath = os.path.join(path, cmd)
127+
if is_executable(cmdpath):
128+
return cmdpath
129+
return None
130+
131+
132+
def fingerprint():
133+
"""
134+
Detects OS type/distro
135+
TODO: install dependencies based on the result
136+
:return:
137+
"""
138+
ost = OSType()
139+
if 'fedora' == ost.query_os():
140+
print(ost.query_os())
141+
if 'redhat' == ost.query_os():
142+
print(ost.query_os())
143+
144+
145+
def parser():
146+
parser_obj = argparse.ArgumentParser(description="This script generates a taurus scenario file and, based on \
147+
that file, executes a bzt jmeter performance test.\
148+
E.g.: pbench_bzt.py -u jmeter_urls/4_http_urls")
149+
150+
parser_obj.add_argument('-u', '--url_file', action="store", dest="url_file", type=str, required=True)
151+
parser_obj.add_argument('-c', '--concurrency', action="store", dest="concurrency", type=str, default=10)
152+
parser_obj.add_argument('-r', '--ramp-up', action="store", dest="ramp_up", type=str, default='10s')
153+
parser_obj.add_argument('-d', '--hold_for', action="store", dest="hold_for", type=str, default='1m')
154+
parser_obj.add_argument('-s', '--scenario', action="store", dest="scenario", type=str, default='simple')
155+
parser_obj.add_argument('-o', '--out_json_file', action="store", dest="out_json_file",
156+
type=str, default='/tmp/bzt.json')
157+
parser_obj.add_argument('-n', '--test_name', action="store", dest="test_name", type=str, default='OSE')
158+
parser_obj.add_argument('-p', '--prefix', action="store", dest="prefix", type=str, default='http://')
159+
parser_obj.add_argument('-f', '--stats_file', action="store", dest="stats_file",
160+
type=str, default='/tmp/taurus.csv')
161+
parser_obj.add_argument('-P', '--program', action="store", dest="program", default='bzt')
162+
163+
return parser_obj.parse_args()
164+
165+
166+
if __name__ == '__main__':
167+
fingerprint()
168+
opt_args = parser()
169+
170+
bzt = BztConfigWriter(opt_args)
171+
bzt.create_scenario_file()
172+
173+
executable = which(opt_args.program)
174+
if executable is not None:
175+
try:
176+
# check_call: blocking code
177+
subprocess.check_call([executable, opt_args.out_json_file])
178+
except subprocess.CalledProcessError:
179+
print("%s has returned in error: %s" % (opt_args.program, subprocess.CalledProcessError.message))
180+
else:
181+
sys.exit("Either %s is not installed, or the current user does not have permission to execute it.\n"
182+
"http://gettaurus.org/docs/Installation/" % opt_args.program)

0 commit comments

Comments
 (0)