Skip to content

Commit b9f9fda

Browse files
committed
release 1.0.1
1 parent 05efd2d commit b9f9fda

File tree

13 files changed

+423
-0
lines changed

13 files changed

+423
-0
lines changed

build/lib/swaggerjmx/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .version import __version__

build/lib/swaggerjmx/convert.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# -*- coding: utf-8 -*-
2+
import os
3+
import time
4+
5+
from .get_swagger import get_test_plan
6+
from .to_jmx import *
7+
from .settings import Settings as ST
8+
9+
10+
def conversion():
11+
12+
result = get_test_plan(ST.swagger_url)
13+
jmeterTestPlan = etree.Element("jmeterTestPlan")
14+
hashTree = jmeter_test_plan(jmeterTestPlan)
15+
testPlan = test_plan(hashTree)
16+
threadGroup = thread_group(testPlan)
17+
controller(threadGroup, result)
18+
etree.tostring(jmeterTestPlan, pretty_print=True)
19+
tree = etree.ElementTree(jmeterTestPlan)
20+
now = time.strftime("%Y-%m-%d_%H-%M-%S")
21+
try:
22+
if not os.path.exists(ST.report_path):
23+
os.mkdir(ST.report_path)
24+
tree.write('{}/jmeter-'.format(ST.report_path) + now + '.jmx', pretty_print=True, xml_declaration=True, encoding='utf-8')
25+
print('swagger convert jmx is success!')
26+
except FileNotFoundError as e:
27+
print(e)
28+
print('swagger convert jmx is fail!')
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# -*- coding: utf-8 -*-
2+
# @Time : 2020/6/30 17:05
3+
# @Author : 李佳玮
4+
# @Email : lijiawei@symbio.com
5+
# @File : get_swagger.py
6+
# @Software: PyCharm
7+
8+
import requests
9+
import json
10+
11+
12+
def get_test_plan(swagger_url):
13+
response = requests.get(swagger_url)
14+
data = json.loads(response.text)
15+
print(data.get("swagger"))
16+
host = data.get("host")
17+
base_path = data.get("basePath")
18+
path = data.get("paths")
19+
thread_groups = data.get("tags")
20+
definitions = data.get("definitions")
21+
for thread_group in thread_groups:
22+
thread_group['host'] = str(host).split(":")[0]
23+
thread_group["port"] = str(host).split(":")[1]
24+
thread_group['sample'] = []
25+
for path_key, path_value in path.items():
26+
if isinstance(path_value, dict):
27+
for method, sample_value in path_value.items():
28+
if isinstance(sample_value, dict):
29+
if sample_value.get("tags")[0] == thread_group.get("name"):
30+
parameters = {}
31+
if isinstance(sample_value.get("parameters"), list):
32+
if sample_value.get("parameters").__len__() > 1:
33+
for param in sample_value.get("parameters"):
34+
parameters[param.get("name")] = "${" + param.get("name") + "}"
35+
else:
36+
for param in sample_value.get("parameters"):
37+
model_name = (param.get("name"))[0].upper() + (param.get("name"))[1:]
38+
if model_name in list(definitions.keys()):
39+
model_value = definitions.get(model_name)
40+
for param_name, param_value in model_value.get("properties").items():
41+
parameters[param_name] = "${" + param_name + "}"
42+
thread_group['sample'].append(
43+
{"path": base_path + path_key, "method": method, "params": parameters,
44+
"sampler_comments": sample_value.get("description")})
45+
46+
return thread_groups

build/lib/swaggerjmx/settings.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# -*- coding: utf-8 -*-
2+
3+
"""
4+
Parameter initialization is a global variable by default. When calling the relevant API,
5+
you need to inherit the setting class and set the corresponding parameters.
6+
7+
"""
8+
9+
10+
class Settings(object):
11+
"""
12+
# swagger_url
13+
ST.swagger_url = 'https://www.baidu.com/'
14+
# 报告生成路径
15+
ST.report_path = 'jmx'
16+
"""
17+
report_path = 'jmx' # 默认在当前路径生成jmx文件夹
18+
swagger_url = None

build/lib/swaggerjmx/to_jmx.py

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
# -*- coding: utf-8 -*-
2+
3+
import json
4+
from lxml import etree
5+
6+
7+
8+
def jmeter_test_plan(root_xml):
9+
JmeterTestPlan = root_xml
10+
JmeterTestPlan.set('version', '1.2')
11+
JmeterTestPlan.set('properties', '2.3')
12+
JmeterTestPlan.set('jmeter', '5.1.1 r1855137')
13+
return etree.SubElement(JmeterTestPlan, 'hashTree')
14+
15+
16+
def test_plan(parent_xml):
17+
testPlan = etree.SubElement(parent_xml, 'TestPlan')
18+
testPlan.set("guiclass", "TestPlanGui")
19+
testPlan.set("testclass", "TestPlan")
20+
testPlan.set("testname", "Test Plan")
21+
testPlan.set("enabled", "true")
22+
stringProp = etree.SubElement(testPlan, "stringProp")
23+
stringProp.set("name", "TestPlan.comments")
24+
stringProp.text = ''
25+
boolProp1 = etree.SubElement(testPlan, "boolProp")
26+
boolProp1.set("name", "TestPlan.functional_mode")
27+
boolProp1.text = "false"
28+
boolProp2 = etree.SubElement(testPlan, "boolProp")
29+
boolProp2.set("name", "TestPlan.tearDown_on_shutdown")
30+
boolProp2.text = "true"
31+
boolProp3 = etree.SubElement(testPlan, "boolProp")
32+
boolProp3.set("name", "TestPlan.serialize_threadgroups")
33+
boolProp3.text = "false"
34+
elementProp = etree.SubElement(testPlan, "elementProp")
35+
elementProp.set("name", "TestPlan.user_defined_variables")
36+
elementProp.set("elementType", "Arguments")
37+
elementProp.set("guiclass", "ArgumentsPanel")
38+
elementProp.set("testclass", "Arguments")
39+
elementProp.set("testname", "User Defined Variables")
40+
elementProp.set("enabled", "true")
41+
collectionProp = etree.SubElement(elementProp, "collectionProp")
42+
collectionProp.set("name", "Arguments.arguments")
43+
stringProp2 = etree.SubElement(testPlan, "stringProp")
44+
stringProp2.set("name", "TestPlan.user_define_classpath")
45+
stringProp2.text = ''
46+
return etree.SubElement(parent_xml, 'hashTree')
47+
48+
49+
def thread_group(parent_xml):
50+
theadGroup = etree.SubElement(parent_xml, "ThreadGroup")
51+
theadGroup.set("guiclass", "ThreadGroupGui")
52+
theadGroup.set("testclass", "ThreadGroup")
53+
theadGroup.set("testname", "Thread Group")
54+
theadGroup.set("enabled", "true")
55+
stringProp = etree.SubElement(theadGroup, "stringProp")
56+
stringProp.set("name", "ThreadGroup.on_sample_error")
57+
stringProp.text = "continue"
58+
elementProp = etree.SubElement(theadGroup, "elementProp")
59+
common_api(elementProp,
60+
{"name": "ThreadGroup.main_controller", "elementType": "LoopController", "guiclass": "LoopControlPanel",
61+
"testclass": "LoopController", "testname": "Loop Controller", "enabled": "true"})
62+
boolProp = etree.SubElement(elementProp, "boolProp")
63+
boolProp.set("name", "LoopController.continue_forever")
64+
boolProp.text = "false"
65+
stringProp = etree.SubElement(elementProp, "stringProp")
66+
stringProp.set("name", "LoopController.loops")
67+
stringProp.text = "1"
68+
stringProp = etree.SubElement(theadGroup, "stringProp")
69+
stringProp.set("name", "ThreadGroup.num_threads")
70+
stringProp.text = "1"
71+
boolProp = etree.SubElement(theadGroup, "boolProp")
72+
boolProp.set("name", "ThreadGroup.scheduler")
73+
boolProp.text = "false"
74+
stringProp = etree.SubElement(theadGroup, "stringProp")
75+
stringProp.set("name", "ThreadGroup.duration")
76+
stringProp.text = ''
77+
stringProp = etree.SubElement(theadGroup, "stringProp")
78+
stringProp.set("name", "ThreadGroup.delay")
79+
stringProp.text = ''
80+
return etree.SubElement(parent_xml, "hashTree")
81+
82+
83+
def controller(parent_xml, result):
84+
for data in result:
85+
GenericController = etree.SubElement(parent_xml, "GenericController")
86+
GenericController.set("guiclass", "LogicControllerGui")
87+
GenericController.set("testclass", "GenericController")
88+
GenericController.set("testname", data.get("name"))
89+
GenericController.set("enabled", "true")
90+
stringProp = etree.SubElement(GenericController, "stringProp")
91+
stringProp.set("name", "TestPlan.comments")
92+
stringProp.text = data.get("description")
93+
shashTree = etree.SubElement(parent_xml, "hashTree")
94+
for sample in data.get("sample"):
95+
HTTPSamplerProxy = etree.SubElement(shashTree, "HTTPSamplerProxy")
96+
common_api(HTTPSamplerProxy,
97+
{"guiclass": "HttpTestSampleGui", "testclass": "HTTPSamplerProxy",
98+
"testname": sample.get('path'),
99+
"enabled": "true"})
100+
if sample.get("params").__len__() < 1:
101+
elementProp = etree.SubElement(HTTPSamplerProxy, "elementProp")
102+
common_api(elementProp, {"name": "HTTPsampler.Arguments", "elementType": "Arguments",
103+
"guiclass": "HTTPArgumentsPanel", "testclass": "Arguments",
104+
"testname": "User Defined Variables", "enabled": "true"})
105+
collectionProp = etree.SubElement(elementProp, "collectionProp")
106+
collectionProp.set("name", "Arguments.arguments")
107+
else:
108+
boolProp = etree.SubElement(HTTPSamplerProxy, "boolProp")
109+
boolProp.set("name", "HTTPSampler.postBodyRaw")
110+
boolProp.text = "true"
111+
elementProp = etree.SubElement(HTTPSamplerProxy, "elementProp")
112+
common_api(elementProp, {"name": "HTTPsampler.Arguments", "elementType": "Arguments"})
113+
collectionProp = etree.SubElement(elementProp, "collectionProp")
114+
collectionProp.set("name", "Arguments.arguments")
115+
elementProp = etree.SubElement(collectionProp, "elementProp")
116+
elementProp.set("name", "")
117+
elementProp.set("elementType", "HTTPArgument")
118+
boolProp = etree.SubElement(elementProp, "boolProp")
119+
boolProp.set("name", "HTTPArgument.always_encode")
120+
boolProp.text = "false"
121+
stringProp = etree.SubElement(elementProp, "stringProp")
122+
stringProp.set("name", "Argument.value")
123+
# stringProp.text = json.dumps(sample.get("params")).replace("\"", "&quot;")
124+
stringProp.text = json.dumps(sample.get("params"))
125+
stringProp = etree.SubElement(elementProp, "stringProp")
126+
stringProp.set("name", "Argument.metadata")
127+
stringProp.text = "="
128+
###host
129+
stringProp = etree.SubElement(HTTPSamplerProxy, "stringProp")
130+
stringProp.set("name", "HTTPSampler.domain")
131+
stringProp.text = data.get("host")
132+
133+
###port
134+
stringProp = etree.SubElement(HTTPSamplerProxy, "stringProp")
135+
stringProp.set("name", "HTTPSampler.port")
136+
stringProp.text = data.get("port")
137+
138+
##protocol
139+
stringProp = etree.SubElement(HTTPSamplerProxy, "stringProp")
140+
stringProp.set("name", "HTTPSampler.protocol")
141+
stringProp.text = "http"
142+
143+
# encoding
144+
stringProp = etree.SubElement(HTTPSamplerProxy, "stringProp")
145+
stringProp.set("name", "HTTPSampler.contentEncoding")
146+
stringProp.text = "utf8"
147+
148+
# path
149+
stringProp = etree.SubElement(HTTPSamplerProxy, "stringProp")
150+
stringProp.set("name", "HTTPSampler.path")
151+
stringProp.text = sample.get("path")
152+
153+
# method
154+
stringProp = etree.SubElement(HTTPSamplerProxy, "stringProp")
155+
stringProp.set("name", "HTTPSampler.method")
156+
stringProp.text = sample.get("method")
157+
158+
# follow redirects
159+
boolProp = etree.SubElement(HTTPSamplerProxy, "boolProp")
160+
boolProp.set("name", "HTTPSampler.follow_redirects")
161+
boolProp.text = "true"
162+
163+
# auto redirects
164+
boolProp = etree.SubElement(HTTPSamplerProxy, "boolProp")
165+
boolProp.set("name", "HTTPSampler.auto_redirects")
166+
boolProp.text = "false"
167+
168+
# use keepalive
169+
boolProp = etree.SubElement(HTTPSamplerProxy, "boolProp")
170+
boolProp.set("name", "HTTPSampler.use_keepalive")
171+
boolProp.text = "true"
172+
173+
# DO MULTIPART POST
174+
boolProp = etree.SubElement(HTTPSamplerProxy, "boolProp")
175+
boolProp.set("name", "HTTPSampler.DO_MULTIPART_POST")
176+
boolProp.text = "false"
177+
178+
# embedded url re
179+
stringProp = etree.SubElement(HTTPSamplerProxy, "stringProp")
180+
stringProp.set("name", "HTTPSampler.embedded_url_re")
181+
stringProp.text = ""
182+
183+
# connect timeout
184+
stringProp = etree.SubElement(HTTPSamplerProxy, "stringProp")
185+
stringProp.set("name", "HTTPSampler.connect_timeout")
186+
stringProp.text = ""
187+
188+
# response timeout
189+
stringProp = etree.SubElement(HTTPSamplerProxy, "stringProp")
190+
stringProp.set("name", "HTTPSampler.response_timeout")
191+
stringProp.text = ""
192+
193+
# comments
194+
stringProp = etree.SubElement(HTTPSamplerProxy, "stringProp")
195+
stringProp.set("name", "TestPlan.comments")
196+
stringProp.text = sample.get("sampler_comments")
197+
hash_tree = etree.SubElement(shashTree, "hashTree")
198+
199+
200+
def common_api(obj_xml, datas):
201+
for key, value in datas.items():
202+
obj_xml.set(key, value)
203+

build/lib/swaggerjmx/version.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# -*- coding: utf-8 -*-
2+
__version__ = "1.0.1"
3+
4+
import os
5+
import sys
6+
7+
8+
def get_swagger_jmx_version():
9+
pip_pkg_dir = os.path.join(os.path.dirname(__file__), "..", "..")
10+
pip_pkg_dir = os.path.abspath(pip_pkg_dir)
11+
12+
return (
13+
'swaggerjmx {} from {} (python {})'.format(
14+
__version__, pip_pkg_dir, sys.version[:3],
15+
)
16+
)
17+
18+
19+
def show_version():
20+
sys.stdout.write(get_swagger_jmx_version())
21+
sys.stdout.write(os.linesep)
22+
sys.exit()
7.07 KB
Binary file not shown.

dist/swaggerjmx-1.0.1.tar.gz

5.09 KB
Binary file not shown.

0 commit comments

Comments
 (0)