├── .gitignore
├── README.md
├── application
├── cert_files
│ ├── server.crt
│ └── server.key
├── orderservice.py
├── response.xml
└── templates
│ └── index.html
├── automation
├── auto_stress_test.sh
├── auto_stress_test_jenkins.sh
├── order_auto.jmx
├── order_auto_jenkins.jmx
└── users.csv
├── image
└── PKQ.jpg
├── jars
└── mysql-connector-java-8.0.15.jar
├── jmx
├── Class_BaiduNews_1117.jmx
├── PreClassJaveReq_1124.jmx
├── PreClassMenu.jmx
├── PreClassMenu_1117.jmx
├── PreClassPrepare_BaiduNews.jmx
├── UploadFile.jmx
├── grafana_test.jmx
├── jsr233_proc.jmx
├── orderservice.jmx
├── orderusers.csv
├── processors.jmx
├── test.jmx
├── timer.jmx
├── users.csv
└── xml_data.jmx
├── shell
├── jmeter_dashboard.json
├── startGrafana.sh
└── startInfluxdb.sh
├── sql
└── order.sql
└── unicode2utf8
└── unicode2utf8.js
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | *.iml
3 | .DS_Store
4 | target/
5 | *.swp
6 | *.swo
7 | *.txt12
8 | *.log
9 | logs/
10 | /target
11 | .project
12 | .vagrant
13 | .classpath
14 | .settings
15 | *.key
16 | ~*.doc
17 | *.pdb
18 | dependency-reduced-pom.xml
19 | ~$*.pptx
20 | myTestSpring/notify-subscription.log.*
21 | *.log.*
22 | *.txt
23 | automation/PreClassMenu_auto_*.jmx
24 | automation/test_*.jtl
25 | application/upload/*.*
26 | automation/web_*
27 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 压力测试项目,练习用
2 | 包含: JMeter压测脚本,模拟被测试的接口应用,自动化压测样例代码
3 |
4 | 1. jmeter演示知识点:
5 | - Get请求编写
6 | - Get请求的传参
7 | - 获取返回值
8 | - Post请求编写
9 | - Post请求传参数
10 | - 获取返回值
11 | - JSON解析
12 | - 正则匹配
13 | - 动态参数传递
14 | - 公共参数配置
15 | - CSV导入参数配置
16 |
17 | 2. 模拟接口服务的启动方法
18 | 路径:iJmeter/application
19 | python3 ${path}/orderservice.py
20 |
21 | 3. 自动化压测
22 | - 代码位置: automation/auto_stress_test.sh
23 | - 运行之前需要在本机配置环境变量 jmeter_path,将其指向jmeter安装的根目录
24 | export jmeter_path=/jmeter_root_path/
25 | - 自动化压测会在运行时依次、自动执行并发压测,并发数 10 20 30 40 50, 每组压测60秒
26 | - 运行代码的时候请先确保当前路径处于automation目录下,然后运行 ./auto_stress_test.sh
27 |
--------------------------------------------------------------------------------
/application/cert_files/server.crt:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIICTzCCAbgCCQDeWLuqGqflXDANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQGEwJj
3 | bjELMAkGA1UECAwCYmoxCzAJBgNVBAcMAmN5MQswCQYDVQQKDAJwdDELMAkGA1UE
4 | CwwCaG0xCzAJBgNVBAMMAnFxMRwwGgYJKoZIhvcNAQkBFg1xcUBwaW50ZWMuY29t
5 | MB4XDTIwMDkwNDA4NTkwOFoXDTIxMDkwNDA4NTkwOFowbDELMAkGA1UEBhMCY24x
6 | CzAJBgNVBAgMAmJqMQswCQYDVQQHDAJjeTELMAkGA1UECgwCcHQxCzAJBgNVBAsM
7 | AmhtMQswCQYDVQQDDAJxcTEcMBoGCSqGSIb3DQEJARYNcXFAcGludGVjLmNvbTCB
8 | nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1IX6zAeMKlz2p5BcpVxe/f41iWmK
9 | /ZRrpAPva9s+ZgY6F33AShonZFOulOYrcfmxXoeN/IGY0tAhnQrgYo3RsBh6KLRu
10 | lVYD6JKu1NAw5Pb5haFpcn0hMUFc16LnNcry4QL1nJhSxBGefu4x5zJYCtRCXr4H
11 | iv7FeB56EkbY5H8CAwEAATANBgkqhkiG9w0BAQUFAAOBgQDAyF4QFEpZ3riOxU/C
12 | l/0PVCxOhTiw0MMY0SpWkc4Qa5iBz3W2+XVhzZLnkwbOZZCh831cTTWPhijbi6r3
13 | OSW6Aa6FF4dLWtzpEQodteLzHI4g/m/gYtAyRci83woaP93aThl4bxl62JinUpny
14 | BUWQ3EnwFrgYOuA/vZkqJFgmLA==
15 | -----END CERTIFICATE-----
16 |
--------------------------------------------------------------------------------
/application/cert_files/server.key:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | Proc-Type: 4,ENCRYPTED
3 | DEK-Info: DES-EDE3-CBC,3663BEA7A3537664
4 |
5 | CHxu1v2jRzkQdw+LlLC5rhPcUB3eS1Pp94VjQQhjN5a5F8/nvvLWQ1gcG44qweF4
6 | ZxJwa3Ckgh/cpnyN2tSkxoP0Oge4VYxus3kLESidvpiFKCSgKwr8CpubDR79HgWY
7 | UYI6fXV0/6if1/Csezg27wcnByLAT8TuqGIl9mU7ILWpM/XNOJJhbytmUcCh56ST
8 | 24trbhE3fweVj4e63z/ddgKqPTTS6wRe1FZOiMkQ7+GCUG7mN+F9tLwFVUQyt8EF
9 | gDfHUOdt/ZoorciO+507VXV2PF5ahmhyTx2n7hSQsmIoqOL4o6E+OVgup9+BfkLR
10 | naFbYa7nUMRGYMPGsTxBWHg0bKQcuh397YAh2lmYn0nKcZQedM5OlN1IhtSosmun
11 | OQB7keEgk8QyrhBmuTdcrYgTNB+1kokDcsjopoI4rMJk/0sM4WgJhFT1PBv8pVVR
12 | ncFZkQZgAOFbhgEWdyYsRnHGt3FWSKEZ8YwWTV0f9sWWY43YsUGGqbgxDyuRECNu
13 | /SLj27aewaJAsfTfT2wkDOKZwg2nKVQ3dCBSg5LiwG4v0HMBtjbE497cr8Gf7xBF
14 | HZcdLFmQzmPTFa28IDtXi0ngklduRpbcrnEAF2LfaEF2GEEvXxhBIQvByTsfPtXD
15 | ZZ2sZbST57TyIB7tlMrZ55xBc9ycNxrEL9dyFGr4ZIhsPlKaminiapQUk2O8H1rO
16 | LYIynAXV/Zk19p0bXo+DqrY34dh/XFQSPKwP3hgVj+uPie/+8hQFMDnMUrBNwo6B
17 | YlGq1ie9+7I9epyq6I7IxWDB6hG11nD+7abBRbyTVio=
18 | -----END RSA PRIVATE KEY-----
19 |
--------------------------------------------------------------------------------
/application/orderservice.py:
--------------------------------------------------------------------------------
1 | import json
2 | import os
3 | import time
4 |
5 | from flask import Flask, request, make_response, jsonify, render_template
6 | from werkzeug.utils import secure_filename
7 | # from skywalking import agent, config
8 |
9 | app = Flask(__name__)
10 | user_token_dic = {
11 | 'user01': '3b6754f00bb0063071c5b71ce2b56b4ed0ce56a63493e785bea85b74c41ce200'
12 | , 'user02': 'dcdc7286f6822dc5a4b54d2ce53f40ae0e562d7fc06d64b8dd332f7d528c7c67'
13 | , 'user03': '04c4fba92b3451b16daedbbc7dd4cec84b8a88333f3da60626c6abbfdc829a02'
14 | , 'user04': '3c3a7fa64c34e2530b708ec9bdeedd49e0098bfd3239b1cd58985feeb38531b8'
15 | , 'user05': 'abb9d47918055902a8a6f3f8e86cd962d37d49647e9b51bdd7f7d67ff95f9864'
16 | , 'user06': '6b2b8f34dd4ad1812a76a7037ed23d9ebc0189070320fa32dc610a79852419c7'
17 | , 'user07': 'aac287a1eeb39d1983aaa732a7a5f33a64918adb1e88da6b344d2090eaed7239'
18 | , 'user08': '3d0c7ff2ad3063bc0e93befeef895def90290114ee590ca09b60f8e4476aca27'
19 | , 'user09': 'a0a9941e29cebdd732a2a57411f14d45e14bc3061d66c2e1c30eca421ed0b02d'
20 | , 'user10': '34467677a88fc7966807c26ced0972cc775be9e6983d4bfbd2a0981a4350dcfd'
21 | }
22 | menu_json = {
23 | "code": "200",
24 | "breakfast": [
25 | {
26 | "menu_nunber": "01",
27 | "menu_price": 5.50,
28 | "menu_name": "小笼包"
29 | },
30 | {
31 | "menu_nunber": "02",
32 | "menu_price": 3.00,
33 | "menu_name": "八宝粥"
34 | },
35 | {
36 | "menu_nunber": "03",
37 | "menu_price": 1.50,
38 | "menu_name": "油条"
39 | },
40 | {
41 | "menu_nunber": "04",
42 | "menu_price": 1.00,
43 | "menu_name": "茶叶蛋"
44 | },
45 | {
46 | "menu_nunber": "05",
47 | "menu_price": 1.50,
48 | "menu_name": "豆包"
49 | },
50 | {
51 | "menu_nunber": "06",
52 | "menu_price": 2.00,
53 | "menu_name": "烧饼"
54 | }
55 | ],
56 | "lunch": [
57 | {
58 | "menu_nunber": "07",
59 | "menu_price": 17.00,
60 | "menu_name": "宫保鸡丁"
61 | },
62 | {
63 | "menu_nunber": "08",
64 | "menu_price": 25.00,
65 | "menu_name": "锅包肉"
66 | },
67 | {
68 | "menu_nunber": "09",
69 | "menu_price": 35.00,
70 | "menu_name": "糖醋排骨"
71 | },
72 | {
73 | "menu_nunber": "10",
74 | "menu_price": 30.00,
75 | "menu_name": "蒜台炒肉片"
76 | },
77 | {
78 | "menu_nunber": "11",
79 | "menu_price": 25.50,
80 | "menu_name": "酸辣土豆丝"
81 | },
82 | {
83 | "menu_nunber": "12",
84 | "menu_price": 32.00,
85 | "menu_name": "红烧茄子"
86 | }
87 | ],
88 | "dinner": [
89 | {
90 | "menu_nunber": "13",
91 | "menu_price": 21.00,
92 | "menu_name": "辣椒炒肉"
93 | },
94 | {
95 | "menu_nunber": "14",
96 | "menu_price": 15.00,
97 | "menu_name": "豌豆肉片汤"
98 | },
99 | {
100 | "menu_nunber": "15",
101 | "menu_price": 26.00,
102 | "menu_name": "原味五花肉卷"
103 | },
104 | {
105 | "menu_nunber": "16",
106 | "menu_price": 20.00,
107 | "menu_name": "醋溜白菜"
108 | },
109 | {
110 | "menu_nunber": "17",
111 | "menu_price": 25.50,
112 | "menu_name": "地三鲜"
113 | },
114 | {
115 | "menu_nunber": "18",
116 | "menu_price": 39.00,
117 | "menu_name": "红烧排骨"
118 | }
119 | ]
120 | }
121 |
122 | server_internal_error_data = {
123 | "code": "500",
124 | "message": "Server internal error."
125 | }
126 |
127 | UPLOAD_FOLDER = 'upload'
128 | app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
129 | basedir = os.path.abspath(os.path.dirname(__file__))
130 | ALLOWED_EXTENSIONS = set(['txt', 'png', 'jpg', 'xls', 'JPG', 'PNG', 'xlsx', 'gif', 'GIF', 'doc', 'docx', 'ppt', 'pptx'])
131 |
132 | enable_agent = True if os.getenv('enable_agent', 'false') == 'true' else False
133 | if enable_agent:
134 | print('Start skywalking agent for monitoring.')
135 | config.init(
136 | agent_collector_backend_services="localhost:11800",
137 | agent_name="python-order-service",
138 | agent_instance_name="python-order-service-instance"
139 | )
140 | agent.start()
141 |
142 |
143 | @app.route("/api/v1/user/login", methods=['POST'])
144 | def login():
145 | """登录接口,输入参数格式:
146 | {
147 | "authRequest": {
148 | "userName": "[username]",
149 | "password": "[password]"
150 | }
151 | }
152 |
153 | :return
154 | Success : http code 200
155 | {
156 | "code": "200",
157 | "message": "login success",
158 | "access_token": "3b6754f00bb0063071c5b71ce2b56b4ed0ce56a63493e785bea85b74c41ce200"
159 | }
160 |
161 | Fail : http code 401
162 | {
163 | "code": "401",
164 | "message": "login fail"
165 | }
166 | """
167 | try:
168 | raw_data = request.get_data(as_text=True)
169 | data = json.loads(raw_data)
170 | username = data.get("authRequest").get("userName")
171 | password = data.get("authRequest").get("password")
172 |
173 | if username not in user_token_dic.keys() or password != 'pwd':
174 | print('Username or password error!')
175 | login_fail_resp_data = {
176 | "code": "401",
177 | "message": "login fail"
178 | }
179 | return make_response(jsonify(login_fail_resp_data), '401')
180 |
181 | login_succ_resp_data = {
182 | "code": "200",
183 | "message": "login success",
184 | "access_token": user_token_dic.get(username)
185 | }
186 |
187 | return make_response(jsonify(login_succ_resp_data), '200')
188 | except Exception as ex:
189 | print(ex.msg)
190 | return make_response(jsonify(server_internal_error_data), '500')
191 |
192 |
193 | @app.route('/api/v1/menu/list', methods=['GET'])
194 | def list():
195 | """菜单浏览接口
196 |
197 | :return: 菜单列表
198 | """
199 | access_token = request.headers.get("accesstoken")
200 |
201 | if access_token is None:
202 | login_fail_resp_data = {
203 | "code": "401",
204 | "message": "Please login first."
205 | }
206 | return make_response(jsonify(login_fail_resp_data), '401')
207 |
208 | if access_token not in user_token_dic.values():
209 | print('access_token error, please re-login.')
210 | login_fail_resp_data = {
211 | "code": "401",
212 | "message": "Unknown user info, please re-login."
213 | }
214 | return make_response(jsonify(login_fail_resp_data), '401')
215 |
216 | category = request.args.get("type")
217 |
218 | if category is not None:
219 | return make_response(jsonify(menu_json.get(category)), 200)
220 |
221 | return make_response(jsonify(menu_json), 200)
222 |
223 |
224 | @app.route("/api/v1/menu/confirm", methods=['POST'])
225 | def confirm():
226 | """下单接口,输入参数格式:
227 | header = {'accesstoken' : ''}
228 | data:
229 | {
230 | "order_list": [
231 | {
232 | "menu_nunber" : "01",
233 | "number" : 1
234 | },
235 | {
236 | "menu_nunber" : "03",
237 | "number" : 2
238 | },
239 | {
240 | "menu_nunber" : "04",
241 | "number" : 1
242 | },
243 | {
244 | "menu_nunber" : "05",
245 | "number" : 3
246 | }
247 | ]
248 | }
249 |
250 | :return
251 | Success : http code 200
252 | {
253 | "code": "200",
254 | "message": "Order success.",
255 | "total": 7
256 | }
257 |
258 | not login : http code 401
259 | {
260 | "code": "401",
261 | "message": "Please login first."
262 | }
263 | """
264 | try:
265 | access_token = request.headers.get("accesstoken")
266 | if access_token is None:
267 | login_fail_resp_data = {
268 | "code": "401",
269 | "message": "Please login first."
270 | }
271 | return make_response(jsonify(login_fail_resp_data), '401')
272 |
273 | raw_data = request.get_data(as_text=True)
274 | order_list = json.loads(raw_data).get("order_list")
275 | total = 0
276 | for order in order_list:
277 | total = total + order.get("number")
278 | time.sleep(0.6)
279 |
280 | order_success_resp_data = {
281 | "code": "200",
282 | "message": "Order success.",
283 | "total": total
284 | }
285 | return make_response(jsonify(order_success_resp_data), '200')
286 | except Exception:
287 | return make_response(jsonify(server_internal_error_data), '500')
288 |
289 |
290 | @app.route("/api/v1/user/logout", methods=['DELETE'])
291 | def logout():
292 | """用户注销接口,输入参数格式:
293 | header = {'accesstoken' : ''}
294 | """
295 | try:
296 | access_token = request.headers.get("accesstoken")
297 |
298 | if access_token not in user_token_dic.values():
299 | print('access_token error, logout failed.')
300 | login_fail_resp_data = {
301 | "code": "401",
302 | "message": "Unknown user info, logout fail."
303 | }
304 | return make_response(jsonify(login_fail_resp_data), '401')
305 |
306 | login_succ_resp_data = {
307 | "code": "200",
308 | "message": "logout success"
309 | }
310 |
311 | return make_response(jsonify(login_succ_resp_data), '200')
312 | except Exception:
313 | return make_response(jsonify(server_internal_error_data), '500')
314 |
315 |
316 | # suffix validation
317 | def allowed_file(filename):
318 | return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
319 |
320 |
321 | # upload file testing page
322 | @app.route('/', methods=['GET'], strict_slashes=False)
323 | def indexpage():
324 | return render_template('index.html')
325 |
326 |
327 | # upload file
328 | @app.route('/uploadfile', methods=['POST'], strict_slashes=False)
329 | def api_upload():
330 | file_dir = os.path.join(basedir, app.config['UPLOAD_FOLDER'])
331 | if not os.path.exists(file_dir):
332 | os.makedirs(file_dir)
333 | f = request.files['file'] # get the file name
334 |
335 | if f and allowed_file(f.filename): # Verify the file type
336 | fname = secure_filename(f.filename)
337 | ext = fname.rsplit('.', 1)[1]
338 | unix_time = time.time()
339 | new_filename = str(unix_time) + '.' + ext
340 | f.save(os.path.join(file_dir, new_filename))
341 | print(f'{f.filename} upload success!')
342 | return jsonify({'code': 200, 'result': 'success', 'msg': f'file {f.filename} upload success'})
343 | else:
344 | print(f'{f.filename} upload failed!')
345 | return jsonify(
346 | {'code': 500, 'result': 'failed', 'msg': f'file {f.filename} upload fail, please check the file type'})
347 |
348 |
349 | if __name__ == "__main__":
350 | app.run(port=9091, debug=True, host='0.0.0.0')
351 |
352 | # Demo for https, password = 1234
353 | # app.run('0.0.0.0', debug=True, port=9091, ssl_context=(f'{os.path.abspath(os.curdir)}/cert_files/server.crt'
354 | # , f'{os.path.abspath(os.curdir)}/cert_files/server.key'))
355 |
--------------------------------------------------------------------------------
/application/response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
9 |
15 |
16 |
--------------------------------------------------------------------------------
/application/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 |
上传文件
3 | 上传文件
4 |
--------------------------------------------------------------------------------
/automation/auto_stress_test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # 压测脚本中设定的压测时间应为20秒
4 | export jmx_filename="order_auto.jmx"
5 |
6 | # 需要在系统变量中定义jmeter根目录的位置,如下
7 | # export jmeter_path="/your jmeter path/"
8 |
9 | echo "自动化压测开始"
10 |
11 | # 压测并发数列表
12 | thread_number_array=(10 20 30)
13 | for num in "${thread_number_array[@]}"
14 | do
15 | echo "压测并发数 ${num}"
16 | # 定义jtl结果文件名与压测报告路径
17 | export jtl_filename="test_${num}.jtl"
18 | export web_report_path_name="web_${num}"
19 |
20 | rm -f ${jtl_filename}
21 | rm -rf ${web_report_path_name}
22 |
23 | # JMeter 静默压测 + 生成html压测报告
24 | ${jmeter_path}/bin/jmeter -n -t ${jmx_filename} -l ${jtl_filename} -Jthread=${num} -e -o ${web_report_path_name}
25 | echo "结束压测并发数 ${num}"
26 | done
27 | echo "自动化压测全部结束"
28 |
29 |
--------------------------------------------------------------------------------
/automation/auto_stress_test_jenkins.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # 压测脚本中设定的压测时间从Jenkins任务参数中传入,参数名称 duration
4 | # 生成的压测报告入口文件为 ./index.html
5 | export jmx_filename="order_auto_jenkins.jmx"
6 |
7 | # 需要在系统变量中定义jmeter根目录的位置,如下
8 | # export jmeter_path="/your jmeter path/"
9 |
10 | echo "自动化压测开始"
11 |
12 | rm -f index.html
13 | echo "" > index.html
14 |
15 |
16 | rm -f *.jtl
17 | rm -rf web_*
18 | # 压测并发数列表
19 | thread_number_array=($thread_number_list)
20 | for num in "${thread_number_array[@]}"
21 | do
22 | echo "压测并发数 ${num}"
23 | # 定义jtl结果文件名与压测报告路径
24 | export jtl_filename="test_${num}.jtl"
25 | export web_report_path_name="web_${num}"
26 |
27 | # JMeter 静默压测 + 生成html压测报告
28 | ${jmeter_path}/bin/jmeter -n -t ${jmx_filename} -l ${jtl_filename} -Jthread=${num} -Jduration=${duration} -e -o ${web_report_path_name}
29 | echo "结束压测并发数 ${num}"
30 | echo "${web_report_path_name}
" >> index.html
31 | done
32 | echo "自动化压测全部结束"
33 |
34 |
--------------------------------------------------------------------------------
/automation/order_auto.jmx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | false
7 | true
8 | false
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | continue
17 |
18 | false
19 | -1
20 |
21 | ${__P(thread,20)}
22 | 1
23 | true
24 | 20
25 |
26 | false
27 |
28 |
29 |
30 | false
31 |
32 | saveConfig
33 |
34 |
35 | true
36 | true
37 | true
38 |
39 | true
40 | true
41 | true
42 | true
43 | false
44 | true
45 | true
46 | false
47 | false
48 | false
49 | true
50 | false
51 | false
52 | false
53 | true
54 | 0
55 | true
56 | true
57 | true
58 | true
59 | true
60 | true
61 |
62 |
63 |
64 |
65 |
66 |
67 | false
68 |
69 | saveConfig
70 |
71 |
72 | true
73 | true
74 | true
75 |
76 | true
77 | true
78 | true
79 | true
80 | false
81 | true
82 | true
83 | false
84 | false
85 | false
86 | true
87 | false
88 | false
89 | false
90 | true
91 | 0
92 | true
93 | true
94 | true
95 | true
96 | true
97 | true
98 |
99 |
100 |
101 |
102 |
103 |
104 | ,
105 | UTF-8
106 | ./users.csv
107 | true
108 | true
109 | true
110 | shareMode.all
111 | false
112 | no,username,password
113 |
114 |
115 |
116 |
117 |
118 | host
119 | localhost
120 | =
121 |
122 |
123 | port
124 | 9091
125 | =
126 |
127 |
128 | protocol
129 | http
130 | =
131 |
132 |
133 | wait
134 | 100
135 | =
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 | accesstoken
144 | ${accesstoken}
145 |
146 |
147 | Content-Type
148 | application/json
149 |
150 |
151 |
152 |
153 |
154 | true
155 |
156 | saveConfig
157 |
158 |
159 | true
160 | true
161 | true
162 |
163 | true
164 | true
165 | true
166 | true
167 | false
168 | true
169 | true
170 | true
171 | false
172 | true
173 | true
174 | false
175 | true
176 | false
177 | true
178 | 0
179 | true
180 | true
181 | true
182 | true
183 | true
184 | true
185 |
186 |
187 | ./error_log.xml
188 |
189 |
190 |
191 | false
192 | true
193 |
194 |
195 |
196 | true
197 |
198 |
199 |
200 | false
201 | {
202 | "authRequest": {
203 | "userName": "${username}",
204 | "password": "${password}"
205 | }
206 | }
207 | =
208 |
209 |
210 |
211 | ${host}
212 | ${port}
213 | ${protocol}
214 |
215 | api/v1/user/login
216 | POST
217 | true
218 | false
219 | true
220 | false
221 |
222 | 1000
223 |
224 |
225 |
226 |
227 | accesstoken
228 | $.access_token
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 | ${host}
238 | ${port}
239 | ${protocol}
240 |
241 | /api/v1/menu/list
242 | GET
243 | true
244 | false
245 | true
246 | false
247 |
248 |
249 |
250 |
251 |
252 |
253 | ${wait}
254 |
255 |
256 |
257 |
258 |
259 | false
260 | String s2 = new String(prev.getResponseData(), "UTF-8");
261 | //---------------一下步骤为转码过程---------------
262 | char aChar;
263 | int len = s2.length();
264 | StringBuffer outBuffer = new StringBuffer(len);
265 | for (int x = 0; x < len;)
266 | {
267 | aChar = s2.charAt(x++);
268 | if (aChar == '\\') {
269 | aChar = s2.charAt(x++);
270 | if (aChar == 'u') {
271 | int
272 | value = 0;
273 | for (int i = 0;
274 | i < 4;
275 | i++
276 | )
277 | {
278 | aChar = s2.charAt(x++);
279 | switch (aChar) {
280 | case'0':
281 | case'1':
282 | case'2':
283 | case'3':
284 | case'4':
285 | case'5':
286 | case'6':
287 | case'7':
288 | case'8':
289 | case'9':
290 | value = (value << 4) + aChar - '0';
291 | break;
292 | case'a':
293 | case'b':
294 | case'c':
295 | case'd':
296 | case'e':
297 | case'f':
298 | value = (value << 4) + 10 + aChar - 'a';
299 | break;
300 | case'A':
301 | case'B':
302 | case'C':
303 | case'D':
304 | case'E':
305 | case'F':
306 | value = (value << 4) + 10 + aChar - 'A';
307 | break;
308 | default:
309 | throw new IllegalArgumentException(
310 | "Malformed \\uxxxx encoding.");
311 | }
312 | }
313 | outBuffer.append((char)
314 | value
315 | )
316 | ;
317 | } else {
318 | if (aChar == 't')
319 | aChar = '\t';
320 | else if (aChar == 'r')
321 | aChar = '\r';
322 | else if (aChar == 'n')
323 | aChar = '\n';
324 | else if (aChar == 'f')
325 | aChar = '\f';
326 | outBuffer.append(aChar);
327 | }
328 | } else
329 | outBuffer.append(aChar);
330 | }
331 | //-----------------以上内容为转码过程---------------------------
332 | //将转成中文的响应结果在查看结果树中显示
333 |
334 | prev.setResponseData(outBuffer.toString());
335 |
336 |
337 |
338 |
339 | true
340 |
341 |
342 |
343 | false
344 | {
345 | "order_list": [
346 | {
347 | "menu_nunber" : "01",
348 | "number" : 2
349 | },
350 | {
351 | "menu_nunber" : "03",
352 | "number" : 2
353 | },
354 | {
355 | "menu_nunber" : "04",
356 | "number" : 2
357 | },
358 | {
359 | "menu_nunber" : "05",
360 | "number" : 3
361 | }
362 | ]
363 | }
364 | =
365 |
366 |
367 |
368 | ${host}
369 | ${port}
370 | ${protocol}
371 |
372 | /api/v1/menu/confirm
373 | POST
374 | true
375 | false
376 | true
377 | false
378 |
379 |
380 |
381 |
382 |
383 |
384 | ${wait}
385 |
386 |
387 |
388 | $.message
389 | Order success.
390 | true
391 | false
392 | false
393 | true
394 |
395 |
396 |
397 | $.total
398 | 9
399 | true
400 | false
401 | false
402 | true
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 | ${host}
411 | ${port}
412 | ${protocol}
413 |
414 | /api/v1/user/logout
415 | DELETE
416 | true
417 | false
418 | true
419 | false
420 |
421 |
422 |
423 |
424 |
425 |
426 | ${wait}
427 |
428 |
429 |
430 |
431 |
432 | true
433 | true
434 | true
435 |
436 |
437 |
438 |
439 |
440 |
441 | influxdbMetricsSender
442 | org.apache.jmeter.visualizers.backend.influxdb.HttpMetricsSender
443 | =
444 |
445 |
446 | influxdbUrl
447 | http://localhost:8086/write?db=jmeter
448 | =
449 |
450 |
451 | application
452 | OrderService
453 | =
454 |
455 |
456 | measurement
457 | jmeter
458 | =
459 |
460 |
461 | summaryOnly
462 | false
463 | =
464 |
465 |
466 | samplersRegex
467 | .*
468 | =
469 |
470 |
471 | percentiles
472 | 90;95;99
473 | =
474 |
475 |
476 | testTitle
477 | OrderService
478 | =
479 |
480 |
481 | eventTags
482 |
483 | =
484 |
485 |
486 |
487 | org.apache.jmeter.visualizers.backend.influxdb.InfluxdbBackendListenerClient
488 |
489 |
490 |
491 |
492 |
493 |
494 |
--------------------------------------------------------------------------------
/automation/order_auto_jenkins.jmx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | false
7 | true
8 | false
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | continue
17 |
18 | false
19 | -1
20 |
21 | ${__P(thread, 20)}
22 | 1
23 | true
24 | ${__P(duration, 20)}
25 |
26 | false
27 |
28 |
29 |
30 | false
31 |
32 | saveConfig
33 |
34 |
35 | true
36 | true
37 | true
38 |
39 | true
40 | true
41 | true
42 | true
43 | false
44 | true
45 | true
46 | false
47 | false
48 | false
49 | true
50 | false
51 | false
52 | false
53 | true
54 | 0
55 | true
56 | true
57 | true
58 | true
59 | true
60 | true
61 |
62 |
63 |
64 |
65 |
66 |
67 | false
68 |
69 | saveConfig
70 |
71 |
72 | true
73 | true
74 | true
75 |
76 | true
77 | true
78 | true
79 | true
80 | false
81 | true
82 | true
83 | false
84 | false
85 | false
86 | true
87 | false
88 | false
89 | false
90 | true
91 | 0
92 | true
93 | true
94 | true
95 | true
96 | true
97 | true
98 |
99 |
100 |
101 |
102 |
103 |
104 | ,
105 | UTF-8
106 | /Users/jizhiqian/workspace/studio/iJmeter/jmx/users.csv
107 | true
108 | true
109 | true
110 | shareMode.all
111 | false
112 | no,username,password
113 |
114 |
115 |
116 |
117 |
118 | host
119 | localhost
120 | =
121 |
122 |
123 | port
124 | 9091
125 | =
126 |
127 |
128 | protocol
129 | http
130 | =
131 |
132 |
133 | wait
134 | 100
135 | =
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 | accesstoken
144 | ${access_token}
145 |
146 |
147 | Content-Type
148 | application/json
149 |
150 |
151 |
152 |
153 |
154 | true
155 |
156 |
157 |
158 | false
159 | {
160 | "authRequest": {
161 | "userName": "${username}",
162 | "password": "${password}"
163 | }
164 | }
165 | =
166 |
167 |
168 |
169 | ${host}
170 | ${port}
171 | ${protocol}
172 |
173 | api/v1/user/login
174 | POST
175 | true
176 | false
177 | true
178 | false
179 |
180 |
181 |
182 |
183 |
184 |
185 | access_token
186 | $.access_token
187 | 0
188 |
189 |
190 |
191 | $.message
192 | login success
193 | true
194 | false
195 | false
196 | true
197 |
198 |
199 |
200 | ${wait}
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 | ${host}
209 | ${port}
210 | ${protocol}
211 |
212 | /api/v1/menu/list
213 | GET
214 | true
215 | false
216 | true
217 | false
218 |
219 |
220 |
221 |
222 |
223 |
224 | ${wait}
225 |
226 |
227 |
228 |
229 | true
230 |
231 |
232 |
233 | false
234 | {
235 | "order_list": [
236 | {
237 | "menu_nunber" : "01",
238 | "number" : 2
239 | },
240 | {
241 | "menu_nunber" : "03",
242 | "number" : 2
243 | },
244 | {
245 | "menu_nunber" : "04",
246 | "number" : 2
247 | },
248 | {
249 | "menu_nunber" : "05",
250 | "number" : 3
251 | }
252 | ]
253 | }
254 | =
255 |
256 |
257 |
258 | ${host}
259 | ${port}
260 | ${protocol}
261 |
262 | /api/v1/menu/confirm
263 | POST
264 | true
265 | false
266 | true
267 | false
268 |
269 |
270 |
271 |
272 |
273 |
274 | ${wait}
275 |
276 |
277 |
278 | $.message
279 | Order success.
280 | true
281 | false
282 | false
283 | true
284 |
285 |
286 |
287 | $.total
288 | 9
289 | true
290 | false
291 | false
292 | true
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 | ${host}
301 | ${port}
302 | ${protocol}
303 |
304 | /api/v1/user/logout
305 | DELETE
306 | true
307 | false
308 | true
309 | false
310 |
311 |
312 |
313 |
314 |
315 |
316 | ${wait}
317 |
318 |
319 |
320 |
321 | false
322 | true
323 | false
324 |
325 |
326 |
327 |
328 |
329 |
330 | influxdbMetricsSender
331 | org.apache.jmeter.visualizers.backend.influxdb.HttpMetricsSender
332 | =
333 |
334 |
335 | influxdbUrl
336 | http://localhost:8086/write?db=jmeter
337 | =
338 |
339 |
340 | application
341 | order
342 | =
343 |
344 |
345 | measurement
346 | jmeter
347 | =
348 |
349 |
350 | summaryOnly
351 | true
352 | =
353 |
354 |
355 | samplersRegex
356 | .*
357 | =
358 |
359 |
360 | percentiles
361 | 90;95;99
362 | =
363 |
364 |
365 | testTitle
366 | Order Testing
367 | =
368 |
369 |
370 | eventTags
371 |
372 | =
373 |
374 |
375 |
376 | org.apache.jmeter.visualizers.backend.influxdb.InfluxdbBackendListenerClient
377 |
378 |
379 |
380 |
381 |
382 |
383 | influxdbMetricsSender
384 | org.apache.jmeter.visualizers.backend.influxdb.HttpMetricsSender
385 | =
386 |
387 |
388 | influxdbUrl
389 | http://localhost:8086/write?db=jmeter
390 | =
391 |
392 |
393 | application
394 | Order Service
395 | =
396 |
397 |
398 | measurement
399 | jmeter
400 | =
401 |
402 |
403 | summaryOnly
404 | false
405 | =
406 |
407 |
408 | samplersRegex
409 | .*
410 | =
411 |
412 |
413 | percentiles
414 | 90;95;99
415 | =
416 |
417 |
418 | testTitle
419 | Order Service
420 | =
421 |
422 |
423 | eventTags
424 |
425 | =
426 |
427 |
428 |
429 | org.apache.jmeter.visualizers.backend.influxdb.InfluxdbBackendListenerClient
430 |
431 |
432 |
433 |
434 |
435 |
436 |
--------------------------------------------------------------------------------
/automation/users.csv:
--------------------------------------------------------------------------------
1 | No.,username,password
2 | 1,user01,pwd
3 | 2,user02,pwd
4 | 3,user03,pwd
5 | 4,user04,pwd
6 | 5,user05,pwd
7 | 6,user06,pwd
8 | 7,user07,pwd
9 | 8,user08,pwd
10 | 9,user09,pwd
11 | 10,user10,pwd
--------------------------------------------------------------------------------
/image/PKQ.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/princeqjzh/iJmeter/d7e7b79ffebb62562b552182ea63ac6be6ed3c38/image/PKQ.jpg
--------------------------------------------------------------------------------
/jars/mysql-connector-java-8.0.15.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/princeqjzh/iJmeter/d7e7b79ffebb62562b552182ea63ac6be6ed3c38/jars/mysql-connector-java-8.0.15.jar
--------------------------------------------------------------------------------
/jmx/PreClassJaveReq_1124.jmx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | false
7 | true
8 | false
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | continue
17 |
18 | false
19 | 1
20 |
21 | 100
22 | 1
23 | false
24 | 10
25 |
26 |
27 |
28 |
29 | false
30 |
31 | saveConfig
32 |
33 |
34 | true
35 | true
36 | true
37 |
38 | true
39 | true
40 | true
41 | true
42 | false
43 | true
44 | true
45 | false
46 | false
47 | false
48 | true
49 | false
50 | false
51 | false
52 | true
53 | 0
54 | true
55 | true
56 | true
57 | true
58 | true
59 | true
60 |
61 |
62 |
63 |
64 |
65 |
66 | false
67 |
68 | saveConfig
69 |
70 |
71 | true
72 | true
73 | true
74 |
75 | true
76 | true
77 | true
78 | true
79 | false
80 | true
81 | true
82 | false
83 | false
84 | false
85 | true
86 | false
87 | false
88 | false
89 | true
90 | 0
91 | true
92 | true
93 | true
94 | true
95 | true
96 | true
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | hostname
107 | localhost
108 | =
109 |
110 |
111 |
112 | com.test.stress.JHttpRequestSample
113 |
114 |
115 |
116 | false
117 | true
118 | false
119 |
120 |
121 |
122 |
123 |
124 | port
125 | 9091
126 | =
127 |
128 |
129 | protocol
130 | http
131 | =
132 |
133 |
134 |
135 |
136 |
137 | ,
138 |
139 | /Users/jizhiqian/workspace/studio/iJmeter/jmx/users.csv
140 | true
141 | false
142 | true
143 | shareMode.all
144 | false
145 | no,username,password
146 |
147 |
148 |
149 |
150 |
151 |
152 |
--------------------------------------------------------------------------------
/jmx/PreClassMenu_1117.jmx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | false
7 | true
8 | false
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | continue
17 |
18 | false
19 | -1
20 |
21 | 5
22 | 1
23 | true
24 | 60
25 |
26 |
27 |
28 |
29 | false
30 |
31 | saveConfig
32 |
33 |
34 | true
35 | true
36 | true
37 |
38 | true
39 | true
40 | true
41 | true
42 | false
43 | true
44 | true
45 | false
46 | false
47 | false
48 | true
49 | false
50 | false
51 | false
52 | true
53 | 0
54 | true
55 | true
56 | true
57 | true
58 | true
59 | true
60 |
61 |
62 |
63 |
64 |
65 |
66 | ,
67 | UTF-8
68 | /Users/jizhiqian/workspace/studio/iJmeter/jmx/users.csv
69 | true
70 | true
71 | true
72 | shareMode.all
73 | false
74 | no,username,password
75 |
76 |
77 |
78 |
79 |
80 | host
81 | localhost
82 | =
83 |
84 |
85 | port
86 | 9091
87 | =
88 |
89 |
90 | protocol
91 | http
92 | =
93 |
94 |
95 |
96 |
97 |
98 | false
99 |
100 | saveConfig
101 |
102 |
103 | true
104 | true
105 | true
106 |
107 | true
108 | true
109 | true
110 | true
111 | false
112 | true
113 | true
114 | false
115 | false
116 | false
117 | true
118 | false
119 | false
120 | false
121 | true
122 | 0
123 | true
124 | true
125 | true
126 | true
127 | true
128 | true
129 |
130 |
131 |
132 |
133 |
134 |
135 | true
136 |
137 |
138 |
139 | false
140 | {
141 | "authRequest": {
142 | "userName": "${username}",
143 | "password": "${password}"
144 | }
145 | }
146 | =
147 |
148 |
149 |
150 | ${host}
151 | ${port}
152 | ${protocol}
153 |
154 | api/v1/user/login
155 | POST
156 | true
157 | false
158 | true
159 | false
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 | Content-Type
169 | application/json
170 |
171 |
172 |
173 |
174 |
175 | access_token
176 | $.access_token
177 | 0
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 | ${host}
186 | ${port}
187 | ${protocol}
188 |
189 | /api/v1/menu/list
190 | GET
191 | true
192 | false
193 | true
194 | false
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 | access_token
204 | ${access_token}
205 |
206 |
207 |
208 |
209 |
210 |
211 | true
212 |
213 |
214 |
215 | false
216 | {
217 | "order_list": [
218 | {
219 | "menu_nunber" : "01",
220 | "number" : 1
221 | },
222 | {
223 | "menu_nunber" : "03",
224 | "number" : 2
225 | },
226 | {
227 | "menu_nunber" : "04",
228 | "number" : 1
229 | },
230 | {
231 | "menu_nunber" : "05",
232 | "number" : 3
233 | }
234 | ]
235 | }
236 | =
237 |
238 |
239 |
240 | ${host}
241 | ${port}
242 | ${protocol}
243 |
244 | /api/v1/menu/confirm
245 | POST
246 | true
247 | false
248 | true
249 | false
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 | access_token
259 | ${access_token}
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 | ${host}
270 | ${port}
271 | ${protocol}
272 |
273 | /api/v1/user/logout
274 | DELETE
275 | true
276 | false
277 | true
278 | false
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 | access_token
288 | ${access_token}
289 |
290 |
291 |
292 |
293 |
294 |
295 | false
296 | true
297 | false
298 |
299 |
300 |
301 |
302 |
303 |
304 | influxdbMetricsSender
305 | org.apache.jmeter.visualizers.backend.influxdb.HttpMetricsSender
306 | =
307 |
308 |
309 | influxdbUrl
310 | http://localhost:8086/write?db=jmeter
311 | =
312 |
313 |
314 | application
315 | Order
316 | =
317 |
318 |
319 | measurement
320 | jmeter
321 | =
322 |
323 |
324 | summaryOnly
325 | true
326 | =
327 |
328 |
329 | samplersRegex
330 | .*
331 | =
332 |
333 |
334 | percentiles
335 | 90;95;99
336 | =
337 |
338 |
339 | testTitle
340 | JMeter Test
341 | =
342 |
343 |
344 | eventTags
345 |
346 | =
347 |
348 |
349 |
350 | org.apache.jmeter.visualizers.backend.influxdb.InfluxdbBackendListenerClient
351 |
352 |
353 |
354 |
355 |
356 |
357 |
--------------------------------------------------------------------------------
/jmx/UploadFile.jmx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | false
7 | true
8 | false
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | continue
17 |
18 | false
19 | 1
20 |
21 | 1
22 | 1
23 | false
24 | 10
25 |
26 | true
27 |
28 |
29 |
30 | false
31 |
32 | saveConfig
33 |
34 |
35 | true
36 | true
37 | true
38 |
39 | true
40 | true
41 | true
42 | true
43 | false
44 | true
45 | true
46 | false
47 | false
48 | false
49 | true
50 | false
51 | false
52 | false
53 | true
54 | 0
55 | true
56 | true
57 | true
58 | true
59 | true
60 | true
61 |
62 |
63 |
64 |
65 |
66 |
67 | false
68 |
69 | saveConfig
70 |
71 |
72 | true
73 | true
74 | true
75 |
76 | true
77 | true
78 | true
79 | true
80 | false
81 | true
82 | true
83 | false
84 | false
85 | false
86 | true
87 | false
88 | false
89 | false
90 | true
91 | 0
92 | true
93 | true
94 | true
95 | true
96 | true
97 | true
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 | ../image/PKQ.jpg
108 | file
109 | multipart/form-data
110 |
111 |
112 |
113 |
114 |
115 |
116 | localhost
117 | 9091
118 | http
119 |
120 | /uploadfile
121 | POST
122 | true
123 | false
124 | true
125 | false
126 |
127 |
128 |
129 |
130 |
131 |
132 | $.code
133 | 200
134 | true
135 | false
136 | false
137 | true
138 |
139 |
140 |
141 | $.result
142 | success
143 | true
144 | false
145 | false
146 | true
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 | stage.velobank.com
155 |
156 | https
157 |
158 | /content/dam/velobank-old-032020/Video-1-How-to-fund-your-Velo-account-through-international-wire.mp4
159 | GET
160 | true
161 | false
162 | true
163 | false
164 |
165 |
166 |
167 |
168 |
169 |
170 | import java.io.*;
171 |
172 | byte[] result = prev.getResponseData();
173 | String file_name = "E://download//keywords-${counter}.txt";
174 | File file = new File(file_name);
175 | FileOutputStream out = new FileOutputStream(file);
176 | out.write(result);
177 | out.close();
178 |
179 |
180 |
181 | false
182 |
183 |
184 |
185 | false
186 | true
187 | false
188 |
189 |
190 |
191 |
192 |
193 |
194 |
--------------------------------------------------------------------------------
/jmx/grafana_test.jmx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | false
7 | true
8 | false
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | continue
17 |
18 | false
19 | -1
20 |
21 | 1
22 | 1
23 | false
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | influxdbMetricsSender
33 | org.apache.jmeter.visualizers.backend.influxdb.HttpMetricsSender
34 | =
35 |
36 |
37 | influxdbUrl
38 | http://localhost:8086/write?db=jmeter
39 | =
40 |
41 |
42 | application
43 | application name
44 | =
45 |
46 |
47 | measurement
48 | jmeter
49 | =
50 |
51 |
52 | summaryOnly
53 | true
54 | =
55 |
56 |
57 | samplersRegex
58 | .*
59 | =
60 |
61 |
62 | percentiles
63 | 90;95;99
64 | =
65 |
66 |
67 | testTitle
68 | Test name
69 | =
70 |
71 |
72 | eventTags
73 |
74 | =
75 |
76 |
77 |
78 | org.apache.jmeter.visualizers.backend.influxdb.InfluxdbBackendListenerClient
79 |
80 |
81 |
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/jmx/jsr233_proc.jmx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | false
7 | true
8 | false
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | continue
17 |
18 | false
19 | 1
20 |
21 | 1
22 | 1
23 | false
24 |
25 |
26 | true
27 |
28 |
29 |
30 | false
31 |
32 | saveConfig
33 |
34 |
35 | true
36 | true
37 | true
38 |
39 | true
40 | true
41 | true
42 | true
43 | false
44 | true
45 | true
46 | false
47 | false
48 | false
49 | true
50 | false
51 | false
52 | false
53 | true
54 | 0
55 | true
56 | true
57 | true
58 | true
59 | true
60 | true
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | www.weather.com.cn
71 |
72 |
73 |
74 | /data/cityinfo/101280601.html
75 | GET
76 | true
77 | false
78 | true
79 | false
80 |
81 |
82 |
83 |
84 |
85 |
86 | groovy
87 |
88 |
89 | true
90 | import groovy.json.JsonSlurper;
91 |
92 | def jsonSlurper = new JsonSlurper();
93 | def response = jsonSlurper.parseText(prev.getResponseDataAsString());
94 | def city=response.weatherinfo.city.toString();
95 |
96 | log.info("JSR233 city = " + city);
97 | vars.put("city",city); //输出变量city
98 |
99 |
100 |
101 |
102 | false
103 | true
104 | false
105 |
106 |
107 |
108 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/jmx/orderservice.jmx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | false
7 | true
8 | false
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | continue
17 |
18 | false
19 | -1
20 |
21 | 10
22 | 1
23 | true
24 | 20
25 |
26 | false
27 |
28 |
29 |
30 | false
31 |
32 | saveConfig
33 |
34 |
35 | true
36 | true
37 | true
38 |
39 | true
40 | true
41 | true
42 | true
43 | false
44 | true
45 | true
46 | false
47 | false
48 | false
49 | true
50 | false
51 | false
52 | false
53 | true
54 | 0
55 | true
56 | true
57 | true
58 | true
59 | true
60 | true
61 |
62 |
63 |
64 |
65 |
66 |
67 | ,
68 | UTF-8
69 | ./orderusers.csv
70 | true
71 | true
72 | true
73 | shareMode.all
74 | false
75 | no,username,password
76 |
77 |
78 |
79 | false
80 |
81 | saveConfig
82 |
83 |
84 | true
85 | true
86 | true
87 |
88 | true
89 | true
90 | true
91 | true
92 | false
93 | true
94 | true
95 | false
96 | false
97 | false
98 | true
99 | false
100 | false
101 | false
102 | true
103 | 0
104 | true
105 | true
106 | true
107 | true
108 | true
109 | true
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 | host
119 | localhost
120 | =
121 |
122 |
123 | port
124 | 9091
125 | =
126 |
127 |
128 | protocol
129 | http
130 | =
131 |
132 |
133 | wait
134 | 10
135 | =
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 | accesstoken
144 | ${access_token}
145 |
146 |
147 | Content-Type
148 | application/json
149 |
150 |
151 |
152 |
153 |
154 | false
155 | true
156 | false
157 |
158 |
159 |
160 | false
161 | false
162 |
163 |
164 |
165 | true
166 |
167 |
168 |
169 | false
170 | {
171 | "authRequest": {
172 | "userName": "${username}",
173 | "password": "${password}"
174 | }
175 | }
176 | =
177 |
178 |
179 |
180 | ${host}
181 | ${port}
182 | ${protocol}
183 |
184 | api/v1/user/login
185 | POST
186 | true
187 | false
188 | true
189 | false
190 |
191 |
192 |
193 |
194 |
195 |
196 | access_token
197 | $.access_token
198 | 0
199 |
200 |
201 |
202 | $.message
203 | login success
204 | true
205 | false
206 | false
207 | true
208 |
209 |
210 |
211 | ${wait}
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 | ${host}
220 | ${port}
221 | ${protocol}
222 |
223 | /api/v1/menu/list
224 | GET
225 | true
226 | false
227 | true
228 | false
229 |
230 |
231 |
232 |
233 |
234 |
235 | ${wait}
236 |
237 |
238 |
239 | false
240 |
241 |
242 | String s2 = new String(prev.getResponseData(), "UTF-8");
243 | //---------------一下步骤为转码过程---------------
244 | char aChar;
245 | int len = s2.length();
246 | StringBuffer outBuffer = new StringBuffer(len);
247 | for (int x = 0; x < len;)
248 | {
249 | aChar = s2.charAt(x++);
250 | if (aChar == '\\') {
251 | aChar = s2.charAt(x++);
252 | if (aChar == 'u') {
253 | int
254 | value = 0;
255 | for (int i = 0;
256 | i < 4;
257 | i++
258 | )
259 | {
260 | aChar = s2.charAt(x++);
261 | switch (aChar) {
262 | case'0':
263 | case'1':
264 | case'2':
265 | case'3':
266 | case'4':
267 | case'5':
268 | case'6':
269 | case'7':
270 | case'8':
271 | case'9':
272 | value = (value << 4) + aChar - '0';
273 | break;
274 | case'a':
275 | case'b':
276 | case'c':
277 | case'd':
278 | case'e':
279 | case'f':
280 | value = (value << 4) + 10 + aChar - 'a';
281 | break;
282 | case'A':
283 | case'B':
284 | case'C':
285 | case'D':
286 | case'E':
287 | case'F':
288 | value = (value << 4) + 10 + aChar - 'A';
289 | break;
290 | default:
291 | throw new IllegalArgumentException(
292 | "Malformed \\uxxxx encoding.");
293 | }
294 | }
295 | outBuffer.append((char)
296 | value
297 | )
298 | ;
299 | } else {
300 | if (aChar == 't')
301 | aChar = '\t';
302 | else if (aChar == 'r')
303 | aChar = '\r';
304 | else if (aChar == 'n')
305 | aChar = '\n';
306 | else if (aChar == 'f')
307 | aChar = '\f';
308 | outBuffer.append(aChar);
309 | }
310 | } else
311 | outBuffer.append(aChar);
312 | }
313 | //-----------------以上内容为转码过程---------------------------
314 | //将转成中文的响应结果在查看结果树中显示
315 |
316 | prev.setResponseData(outBuffer.toString());
317 |
318 |
319 |
320 |
321 | true
322 |
323 |
324 |
325 | false
326 | {
327 | "order_list": [
328 | {
329 | "menu_nunber" : "01",
330 | "number" : 2
331 | },
332 | {
333 | "menu_nunber" : "03",
334 | "number" : 2
335 | },
336 | {
337 | "menu_nunber" : "04",
338 | "number" : 2
339 | },
340 | {
341 | "menu_nunber" : "05",
342 | "number" : 3
343 | }
344 | ]
345 | }
346 | =
347 |
348 |
349 |
350 | ${host}
351 | ${port}
352 | ${protocol}
353 |
354 | /api/v1/menu/confirm
355 | POST
356 | true
357 | false
358 | true
359 | false
360 |
361 |
362 |
363 |
364 |
365 |
366 | ${wait}
367 |
368 |
369 |
370 | $.message
371 | Order success.
372 | true
373 | false
374 | false
375 | true
376 |
377 |
378 |
379 | $.total
380 | 9
381 | true
382 | false
383 | false
384 | true
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 | ${host}
393 | ${port}
394 | ${protocol}
395 |
396 | /api/v1/user/logout
397 | DELETE
398 | true
399 | false
400 | true
401 | false
402 |
403 |
404 |
405 |
406 |
407 |
408 | ${wait}
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 | influxdbMetricsSender
418 | org.apache.jmeter.visualizers.backend.influxdb.HttpMetricsSender
419 | =
420 |
421 |
422 | influxdbUrl
423 | http://localhost:8086/write?db=jmeter
424 | =
425 |
426 |
427 | application
428 | Order Service
429 | =
430 |
431 |
432 | measurement
433 | jmeter
434 | =
435 |
436 |
437 | summaryOnly
438 | false
439 | =
440 |
441 |
442 | samplersRegex
443 | .*
444 | =
445 |
446 |
447 | percentiles
448 | 90;95;99
449 | =
450 |
451 |
452 | testTitle
453 | Order Service
454 | =
455 |
456 |
457 | eventTags
458 |
459 | =
460 |
461 |
462 |
463 | org.apache.jmeter.visualizers.backend.influxdb.InfluxdbBackendListenerClient
464 |
465 |
466 |
467 |
468 |
469 |
470 |
--------------------------------------------------------------------------------
/jmx/orderusers.csv:
--------------------------------------------------------------------------------
1 | No.,username,password
2 | 1,user01,pwd
3 | 2,user02,pwd
4 | 3,user03,pwd
5 | 4,user04,pwd
6 | 5,user05,pwd
7 | 6,user06,pwd
8 | 7,user07,pwd
9 | 8,user08,pwd
10 | 9,user09,pwd
11 | 10,user10,pwd
--------------------------------------------------------------------------------
/jmx/processors.jmx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | false
7 | true
8 | false
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | continue
17 |
18 | false
19 | 1
20 |
21 | 1
22 | 1
23 | false
24 |
25 |
26 | true
27 |
28 |
29 |
30 | false
31 |
32 | saveConfig
33 |
34 |
35 | true
36 | true
37 | true
38 |
39 | true
40 | true
41 | true
42 | true
43 | false
44 | true
45 | true
46 | false
47 | false
48 | false
49 | true
50 | false
51 | false
52 | false
53 | true
54 | 0
55 | true
56 | true
57 | true
58 | true
59 | true
60 | true
61 |
62 |
63 |
64 |
65 |
66 |
67 | 2
68 |
69 |
70 |
71 |
72 |
73 |
74 | false
75 | ${timestamp}
76 | =
77 | true
78 | time
79 |
80 |
81 |
82 | www.baidu.com
83 |
84 |
85 |
86 |
87 | GET
88 | true
89 | false
90 | true
91 | false
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 | false
101 | long timestamp = System.currentTimeMillis();
102 | vars.put("timestamp", timestamp + "");
103 |
104 |
105 |
106 | false
107 |
108 |
109 | import com.studio.test.utils.*;
110 |
111 | String idcardno = Tools.createIdcard();
112 | vars.put("idcardno", idcardno);
113 |
114 |
115 |
116 | false
117 | 1111 222 3333
118 |
119 |
120 | log.info("aaaaa=====" + bsh.args[2]);
121 |
122 |
123 |
124 |
125 | false
126 | true
127 | false
128 |
129 |
130 |
131 |
132 |
133 |
134 |
--------------------------------------------------------------------------------
/jmx/test.jmx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | false
7 | true
8 | false
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | continue
17 |
18 | false
19 | 1
20 |
21 | 1
22 | 1
23 | false
24 |
25 |
26 | true
27 |
28 |
29 |
30 |
31 |
32 | false
33 |
34 | saveConfig
35 |
36 |
37 | true
38 | true
39 | true
40 |
41 | true
42 | true
43 | true
44 | true
45 | false
46 | true
47 | true
48 | false
49 | false
50 | false
51 | true
52 | false
53 | false
54 | false
55 | true
56 | 0
57 | true
58 | true
59 | true
60 | true
61 | true
62 | true
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | rValue
72 | ${__Random(0,99,)}
73 | =
74 |
75 |
76 | date
77 | ${__RandomDate(,,2021-10-10,,)}
78 | =
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 | false
87 | long timestamp = System.currentTimeMillis();
88 | vars.put("timestamp", timestamp + "");
89 |
90 |
91 |
92 | 1
93 |
94 |
95 |
96 | true
97 | ${__Random(1,4,id)}
98 |
99 |
100 |
101 |
102 |
103 |
104 | www.baidu.com
105 |
106 |
107 |
108 |
109 | GET
110 | true
111 | false
112 | true
113 | false
114 |
115 |
116 |
117 |
118 |
119 |
120 | 10
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 | www.baidu.com
129 |
130 |
131 |
132 |
133 | GET
134 | true
135 | false
136 | true
137 | false
138 |
139 |
140 |
141 |
142 |
143 |
144 | 1000
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 | www.baidu.com
153 |
154 |
155 |
156 |
157 | GET
158 | true
159 | false
160 | true
161 | false
162 |
163 |
164 |
165 |
166 |
167 |
168 | 1000
169 |
170 |
171 |
172 |
173 |
174 | false
175 | true
176 | false
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
--------------------------------------------------------------------------------
/jmx/timer.jmx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | false
7 | true
8 | false
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | continue
17 |
18 | false
19 | -1
20 |
21 | 10
22 | 1
23 | true
24 | 60
25 |
26 | true
27 |
28 |
29 |
30 | false
31 |
32 | saveConfig
33 |
34 |
35 | true
36 | true
37 | true
38 |
39 | true
40 | true
41 | true
42 | true
43 | false
44 | true
45 | true
46 | false
47 | false
48 | false
49 | true
50 | false
51 | false
52 | false
53 | true
54 | 0
55 | true
56 | true
57 | true
58 | true
59 | true
60 | true
61 |
62 |
63 |
64 |
65 |
66 |
67 | false
68 |
69 | saveConfig
70 |
71 |
72 | true
73 | true
74 | true
75 |
76 | true
77 | true
78 | true
79 | true
80 | false
81 | true
82 | true
83 | false
84 | false
85 | false
86 | true
87 | false
88 | false
89 | false
90 | true
91 | 0
92 | true
93 | true
94 | true
95 | true
96 | true
97 | true
98 |
99 |
100 |
101 |
102 |
103 |
104 | false
105 |
106 | saveConfig
107 |
108 |
109 | true
110 | true
111 | true
112 |
113 | true
114 | true
115 | true
116 | true
117 | false
118 | true
119 | true
120 | false
121 | false
122 | false
123 | true
124 | false
125 | false
126 | false
127 | true
128 | 0
129 | true
130 | true
131 | true
132 | true
133 | true
134 | true
135 |
136 |
137 |
138 |
139 |
140 |
141 | false
142 | false
143 |
144 |
145 |
146 | 1
147 |
148 | throughput
149 | 60.0
150 | 0.0
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 | www.baidu.com
159 |
160 |
161 |
162 |
163 | GET
164 | true
165 | false
166 | true
167 | false
168 |
169 |
170 |
171 |
172 |
173 |
174 | 300
175 | 100
176 |
177 |
178 |
179 | false
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 | www.baidu.com
193 |
194 |
195 |
196 |
197 | GET
198 | true
199 | false
200 | true
201 | false
202 |
203 |
204 |
205 |
206 |
207 |
208 | 3000
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 | www.baidu.com
217 |
218 |
219 |
220 |
221 | GET
222 | true
223 | false
224 | true
225 | false
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
--------------------------------------------------------------------------------
/jmx/users.csv:
--------------------------------------------------------------------------------
1 | No.,username,password
2 | 1,user01,pwd
3 | 2,user02,pwd
4 | 3,user03,pwd
5 | 4,user04,pwd
6 | 5,user05,pwd
7 | 6,user06,pwd
8 | 7,user07,pwd
9 | 8,user08,pwd
10 | 9,user09,pwd
11 | 10,user10,pwd
--------------------------------------------------------------------------------
/jmx/xml_data.jmx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | false
7 | true
8 | false
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | continue
17 |
18 | false
19 | 1
20 |
21 | 1
22 | 1
23 | false
24 |
25 |
26 | true
27 |
28 |
29 |
30 | false
31 |
32 | saveConfig
33 |
34 |
35 | true
36 | true
37 | true
38 |
39 | true
40 | true
41 | true
42 | true
43 | false
44 | true
45 | true
46 | false
47 | false
48 | false
49 | true
50 | false
51 | false
52 | false
53 | true
54 | 0
55 | true
56 | true
57 | true
58 | true
59 | true
60 | true
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | localhost
71 | 8000
72 |
73 |
74 | response.xml
75 | GET
76 | true
77 | false
78 | true
79 | false
80 |
81 |
82 |
83 |
84 |
85 |
86 | false
87 | value
88 | <field name="orderId" value="(.+?)"/>
89 | $1$
90 | notfound
91 | 0
92 |
93 |
94 |
95 | notfound
96 | orderId
97 | 1
98 | //field[@name="orderId"]/@value
99 | false
100 | false
101 | false
102 |
103 |
104 |
105 |
106 | false
107 | true
108 | false
109 |
110 |
111 |
112 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/shell/startGrafana.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | docker stop jmeterGraf
4 | docker rm jmeterGraf
5 | docker run -d -p 3000:3000 --name=jmeterGraf grafana/grafana
--------------------------------------------------------------------------------
/shell/startInfluxdb.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | docker stop jmeterdb
4 | docker rm jmeterdb
5 | docker run -d -p 8086:8086 -p 8083:8083 --name=jmeterdb influxdb
--------------------------------------------------------------------------------
/sql/order.sql:
--------------------------------------------------------------------------------
1 | CREATE DATABASE IF NOT EXISTS `jmeter_class`;
2 | USE `jmeter_class`;
3 |
4 | DROP TABLE IF EXISTS `user`;
5 | CREATE TABLE `user` (
6 | `uid` int(11) NOT NULL AUTO_INCREMENT,
7 | `username` varchar(100) DEFAULT NULL,
8 | `password` varchar(100) DEFAULT NULL,
9 | PRIMARY KEY (`uid`)
10 | ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
11 |
12 | -- LOCK TABLES `user` WRITE;
13 | -- INSERT INTO `user` VALUES (1,'user1', '123456'),(2,'user1', '123456'),(3,'user1', '123456'),(4,'user1', '123456'),(5,'user1', '123456'),(6,'user1', '123456');
14 | -- UNLOCK TABLES;
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/unicode2utf8/unicode2utf8.js:
--------------------------------------------------------------------------------
1 | String s2 = new String(prev.getResponseData(), "UTF-8");
2 | //---------------一下步骤为转码过程---------------
3 | char aChar;
4 | int len = s2.length();
5 | StringBuffer outBuffer = new StringBuffer(len);
6 | for (int x = 0; x < len;)
7 | {
8 | aChar = s2.charAt(x++);
9 | if (aChar == '\\') {
10 | aChar = s2.charAt(x++);
11 | if (aChar == 'u') {
12 | int
13 | value = 0;
14 | for (int i = 0;
15 | i < 4;
16 | i++
17 | )
18 | {
19 | aChar = s2.charAt(x++);
20 | switch (aChar) {
21 | case'0':
22 | case'1':
23 | case'2':
24 | case'3':
25 | case'4':
26 | case'5':
27 | case'6':
28 | case'7':
29 | case'8':
30 | case'9':
31 | value = (value << 4) + aChar - '0';
32 | break;
33 | case'a':
34 | case'b':
35 | case'c':
36 | case'd':
37 | case'e':
38 | case'f':
39 | value = (value << 4) + 10 + aChar - 'a';
40 | break;
41 | case'A':
42 | case'B':
43 | case'C':
44 | case'D':
45 | case'E':
46 | case'F':
47 | value = (value << 4) + 10 + aChar - 'A';
48 | break;
49 | default:
50 | throw new IllegalArgumentException(
51 | "Malformed \\uxxxx encoding.");
52 | }
53 | }
54 | outBuffer.append((char)
55 | value
56 | )
57 | ;
58 | } else {
59 | if (aChar == 't')
60 | aChar = '\t';
61 | else if (aChar == 'r')
62 | aChar = '\r';
63 | else if (aChar == 'n')
64 | aChar = '\n';
65 | else if (aChar == 'f')
66 | aChar = '\f';
67 | outBuffer.append(aChar);
68 | }
69 | } else
70 | outBuffer.append(aChar);
71 | }
72 | //-----------------以上内容为转码过程---------------------------
73 | //将转成中文的响应结果在查看结果树中显示
74 |
75 | prev.setResponseData(outBuffer.toString());
--------------------------------------------------------------------------------