-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsmoke_test.py
270 lines (207 loc) · 8.36 KB
/
smoke_test.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
import config
from my_exceptions import TestFail
from my_print import MyPrint
from http_request_maker import HTTPRequestMaker
import utils_auth as ua
import utils
import yaml
import re
import datetime
import os
import sys
sys.path.insert(0, os.getcwd())
AUTH_ARG = '--auth'
LOCAL_ARG = '--localhost'
REQUEST_PARAM_ARG = '--request-param='
ONLY_GET_METHODS_ARG = '--only-get' # The smoke test will only test GET methods
def main():
if len(sys.argv) < 2:
print('Usage: python api-smoke-test\smoke_test.py name_of_the_spec_file '
'[' + AUTH_ARG + '] [' + LOCAL_ARG + '] [' + REQUEST_PARAM_ARG +
'] [' + ONLY_GET_METHODS_ARG + '] ')
sys.exit(1)
spec_file = sys.argv[1]
if spec_file.startswith('http'):
content = utils.get_resource_content_string(spec_file)
spec = yaml.safe_load(content)
else:
spec = parse_spec_file(spec_file)
base_api_url = spec['servers'][0]['url']
paths_dict = spec['paths']
print('')
print('Testing ' + spec['info']['title'])
print('')
endpoints_list = return_list_of_parameterless_get_methods(paths_dict)
endpoints_with_params = return_list_of_get_methods_with_parameters(
paths_dict)
if there_are_no_get_endpoints(endpoints_list, endpoints_with_params):
raise TestFail('Spec file ' + spec_file +
' does not contain any GET methods.')
token = None
if authorization_is_necessary():
token = get_auth_token()
maker = HTTPRequestMaker(base_api_url, token)
print('Testing GET methods')
maker.make_get_requests(endpoints_list)
req_param = get_request_param_arg()
if len(endpoints_with_params) > 0:
call_get_methods_with_parameters(
endpoints_with_params, maker, req_param)
if not only_make_get_requests():
endpoints_list = return_list_of_parameterless_post_methods(paths_dict)
if len(endpoints_list) > 0:
print('')
print('Testing POST methods')
maker.make_post_requests(endpoints_list)
endpoints_with_params = return_list_of_post_methods_with_parameters(
paths_dict)
if len(endpoints_with_params) > 0:
new_list = replace_parameters_with(
endpoints_with_params, req_param)
maker.make_post_requests_with_parameters(new_list)
endpoints_with_params = return_list_of_put_methods_with_parameters(
paths_dict)
if len(endpoints_with_params) > 0:
new_list = replace_parameters_with(
endpoints_with_params, req_param)
print('')
print('Testing PUT methods')
maker.make_put_requests_with_parameters(new_list)
endpoints_with_params = return_list_of_delete_methods_with_parameters(
paths_dict)
if len(endpoints_with_params) > 0:
new_list = replace_parameters_with(
endpoints_with_params, '13013013013013')
print('')
print('Testing DELETE methods')
maker.make_delete_requests_with_parameters(new_list)
# End if not only_make_get_requests()
print_test_results(maker, spec['info']['title'])
# Exit with error code is needed by Azure to show test as failed
if len(maker.failed_requests_list) > 0:
sys.exit(1)
if config.WARNING_FAIL and len(maker.warning_requests_list) > 0:
sys.exit(1)
# main()
######################################## Support functions ########################################
def there_are_no_get_endpoints(endpoints_list, endpoints_with_params):
return len(endpoints_list) == 0 and len(endpoints_with_params) == 0
def parse_spec_file(spec_file):
# Load OpenAPI spec file and read yaml or json data
with open(file=spec_file, encoding='utf-8') as f:
content = f.read()
spec = yaml.safe_load(content)
return spec
def authorization_is_necessary():
result = False
for arg in sys.argv:
if arg == AUTH_ARG:
result = True
return result
def only_make_get_requests():
result = False
for arg in sys.argv:
if arg == ONLY_GET_METHODS_ARG:
result = True
return result
def get_request_param_arg():
tenant_id = '1'
for arg in sys.argv:
if arg.startswith(REQUEST_PARAM_ARG):
tenant_id = arg.split('=')[1]
return tenant_id
def get_auth_token():
localhost = False
for arg in sys.argv:
if arg == LOCAL_ARG:
localhost = True
if localhost:
token = ua.get_authorization_token(local=True)
else:
token = ua.get_auth_token_secret() # ua.get_authorization_token()
return token
def return_list_of_parameterless_get_methods(paths):
result = _return_list_of_parameterless_methods(paths, 'get')
return result
def return_list_of_parameterless_post_methods(paths):
result = _return_list_of_parameterless_methods(paths, 'post')
return result
def _return_list_of_parameterless_methods(paths, method):
result = []
for key in paths:
if '{' not in key and method in paths[key].keys():
result.append(key)
return result
def return_list_of_get_methods_with_parameters(paths):
result = _return_list_of_methods_with_parameters(paths, 'get')
return result
def return_list_of_post_methods_with_parameters(paths):
result = _return_list_of_methods_with_parameters(paths, 'post')
return result
def return_list_of_put_methods_with_parameters(paths):
result = _return_list_of_methods_with_parameters(paths, 'put')
return result
def return_list_of_delete_methods_with_parameters(paths):
result = _return_list_of_methods_with_parameters(paths, 'delete')
return result
def replace_parameters_with(endpoints_list, replacement):
new_list = []
for el in endpoints_list:
new_list.append(re.sub('{[a-zA-Z]*}', replacement, el))
return new_list
def call_get_methods_with_parameters(endpoints_with_params, maker, param):
new_list = replace_parameters_with(endpoints_with_params, param)
maker.make_get_requests_with_parameters(new_list)
print('')
print('Testing with non existing values of parameters:')
new_list = replace_parameters_with(endpoints_with_params, '13013')
maker.make_get_requests_with_parameters(new_list)
def there_were_failed_or_warning_requests(maker):
return len(maker.failed_requests_list) > 0 or len(maker.warning_requests_list) > 0
def print_test_results(maker, api_title):
mp = MyPrint()
print('')
date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print('Date: ' + date)
print(api_title)
timestamp = str(datetime.datetime.now()).replace(' ', 'T')
header3 = '<system-out><![CDATA['
if there_were_failed_or_warning_requests(maker):
header = '<testsuite errors="1" failures="0" skipped="0" tests="1" timestamp="' + timestamp + '">'
header2 = '<testcase status="failed" name="' + api_title + '">'
header21 = '<error message="Test failed"></error>'
mp.append_result_str(header + header2 + header21 + header3)
if len(maker.warning_requests_list) > 0:
mp.my_print('')
mp.my_print('REQUESTS WHICH EXCEEDED WARNING TIMEOUT:')
for r in maker.warning_requests_list:
mp.my_print(r)
mp.my_print('')
if len(maker.failed_requests_list) == 0:
mp.my_print('*** Test result: Warning ***')
if len(maker.failed_requests_list) > 0:
mp.my_print('FAILED REQUESTS:')
for r in maker.failed_requests_list:
mp.my_print(r)
mp.my_print('')
mp.my_print('!!! TEST FAIL !!!')
else:
header = '<testsuite errors="0" failures="0" skipped="0" tests="1" timestamp="' + timestamp + '">'
header2 = '<testcase status="passed" name="' + api_title + '">'
mp.append_result_str(header + header2 + header3)
mp.my_print('*** Test Pass ***')
end = ']]></system-out></testcase></testsuite>'
mp.append_result_str(end)
filename = api_title.replace(" ", "_") + '_test_results.xml'
mp.save_result_str_to_file(filename)
print('')
print('')
print('')
def _return_list_of_methods_with_parameters(paths, method):
result = []
for key in paths:
if '{' in key and method in paths[key].keys():
result.append(key)
return result
if __name__ == '__main__':
main()