Skip to content

Commit 7740cd8

Browse files
Add sample tests
1 parent 70b96e1 commit 7740cd8

File tree

6 files changed

+100
-32
lines changed

6 files changed

+100
-32
lines changed

samples/authX-pro/create.ipynb

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,13 @@
170170
"source": [
171171
"import utils\n",
172172
"from apimrequests import ApimRequests\n",
173+
"from apimtesting import ApimTesting\n",
173174
"from apimtypes import Role\n",
174175
"from users import UserHelper\n",
175176
"from authfactory import AuthFactory\n",
176177
"\n",
178+
"tests = ApimTesting(\"AuthX-Pro Sample Tests\")\n",
179+
"\n",
177180
"# Preflight: Check if the infrastructure architecture deployment uses Azure Front Door. If so, assume that APIM is not directly accessible and use the Front Door URL instead.\n",
178181
"endpoint_url = utils.test_url_preflight_check(deployment, rg_name, apim_gateway_url)\n",
179182
"\n",
@@ -187,10 +190,17 @@
187190
"reqsApimAdmin.headers['Authorization'] = f'Bearer {encoded_jwt_token_hr_admin}'\n",
188191
"\n",
189192
"# Call APIM\n",
190-
"reqsApimAdmin.singleGet(hremployees_api_path, msg = 'Calling GET Employees API via API Management Gateway URL. Expect 200.')\n",
191-
"reqsApimAdmin.singlePost(hremployees_api_path, msg = 'Calling POST Employees API via API Management Gateway URL. Expect 200.')\n",
192-
"reqsApimAdmin.singleGet(hrbenefits_api_path, msg = 'Calling GET Benefits API via API Management Gateway URL. Expect 200.')\n",
193-
"reqsApimAdmin.singlePost(hrbenefits_api_path, msg = 'Calling POST Benefits API via API Management Gateway URL. Expect 200.')\n",
193+
"output = reqsApimAdmin.singleGet(hremployees_api_path, msg = 'Calling GET Employees API via API Management Gateway URL. Expect 200.')\n",
194+
"tests.verify(output, 'Successful GET')\n",
195+
"\n",
196+
"output = reqsApimAdmin.singlePost(hremployees_api_path, msg = 'Calling POST Employees API via API Management Gateway URL. Expect 200.')\n",
197+
"tests.verify(output, 'Successful POST')\n",
198+
"\n",
199+
"output = reqsApimAdmin.singleGet(hrbenefits_api_path, msg = 'Calling GET Benefits API via API Management Gateway URL. Expect 200.')\n",
200+
"tests.verify(output, 'Successful GET')\n",
201+
"\n",
202+
"output = reqsApimAdmin.singlePost(hrbenefits_api_path, msg = 'Calling POST Benefits API via API Management Gateway URL. Expect 200.')\n",
203+
"tests.verify(output, 'Successful POST')\n",
194204
"\n",
195205
"# 2) HR Associate\n",
196206
"# Create a JSON Web Token with a payload and sign it with the symmetric key from above.\n",
@@ -202,10 +212,19 @@
202212
"reqsApimAssociate.headers['Authorization'] = f'Bearer {encoded_jwt_token_hr_associate}'\n",
203213
"\n",
204214
"# Call APIM\n",
205-
"reqsApimAssociate.singleGet(hremployees_api_path, msg = 'Calling GET Employees API via API Management Gateway URL. Expect 200.')\n",
206-
"reqsApimAssociate.singlePost(hremployees_api_path, msg = 'Calling POST Employees API via API Management Gateway URL. Expect 403.')\n",
207-
"reqsApimAssociate.singleGet(hrbenefits_api_path, msg = 'Calling GET Benefits API via API Management Gateway URL. Expect 200.')\n",
208-
"reqsApimAssociate.singlePost(hrbenefits_api_path, msg = 'Calling POST Benefits API via API Management Gateway URL. Expect 403.')\n",
215+
"output = reqsApimAssociate.singleGet(hremployees_api_path, msg = 'Calling GET Employees API via API Management Gateway URL. Expect 200.')\n",
216+
"tests.verify(output, 'Successful GET')\n",
217+
"\n",
218+
"output = reqsApimAssociate.singlePost(hremployees_api_path, msg = 'Calling POST Employees API via API Management Gateway URL. Expect 403.')\n",
219+
"tests.verify(output, 'Access denied - no matching roles found')\n",
220+
"\n",
221+
"output = reqsApimAssociate.singleGet(hrbenefits_api_path, msg = 'Calling GET Benefits API via API Management Gateway URL. Expect 200.')\n",
222+
"tests.verify(output, 'Successful GET')\n",
223+
"\n",
224+
"output = reqsApimAssociate.singlePost(hrbenefits_api_path, msg = 'Calling POST Benefits API via API Management Gateway URL. Expect 403.')\n",
225+
"tests.verify(output, 'Access denied - no matching roles found')\n",
226+
"\n",
227+
"tests.print_summary()\n",
209228
"\n",
210229
"utils.print_ok('All done!')"
211230
]

samples/authX/create.ipynb

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,13 @@
136136
"source": [
137137
"import utils\n",
138138
"from apimrequests import ApimRequests\n",
139+
"from apimtesting import ApimTesting\n",
139140
"from apimtypes import Role\n",
140141
"from users import UserHelper\n",
141142
"from authfactory import AuthFactory\n",
142143
"\n",
144+
"tests = ApimTesting(\"AuthX Sample Tests\")\n",
145+
"\n",
143146
"# Preflight: Check if the infrastructure architecture deployment uses Azure Front Door. If so, assume that APIM is not directly accessible and use the Front Door URL instead.\n",
144147
"endpoint_url = utils.test_url_preflight_check(deployment, rg_name, apim_gateway_url)\n",
145148
"\n",
@@ -153,8 +156,11 @@
153156
"reqsApimAdmin.headers['Authorization'] = f'Bearer {encoded_jwt_token_hr_admin}'\n",
154157
"\n",
155158
"# Call APIM\n",
156-
"reqsApimAdmin.singleGet('/employees', msg = 'Calling GET Employees API via API Management Gateway URL. Expect 200.')\n",
157-
"reqsApimAdmin.singlePost('/employees', msg = 'Calling POST Employees API via API Management Gateway URL. Expect 200.')\n",
159+
"output = reqsApimAdmin.singleGet('/employees', msg = 'Calling GET Employees API via API Management Gateway URL. Expect 200.')\n",
160+
"tests.verify(output, 'Returning a mock employee')\n",
161+
"\n",
162+
"output = reqsApimAdmin.singlePost('/employees', msg = 'Calling POST Employees API via API Management Gateway URL. Expect 200.')\n",
163+
"tests.verify(output, 'A mock employee has been created.')\n",
158164
"\n",
159165
"# 2) HR Associate\n",
160166
"# Create a JSON Web Token with a payload and sign it with the symmetric key from above.\n",
@@ -166,8 +172,14 @@
166172
"reqsApimAssociate.headers['Authorization'] = f'Bearer {encoded_jwt_token_hr_associate}'\n",
167173
"\n",
168174
"# Call APIM\n",
169-
"reqsApimAssociate.singleGet('/employees', msg = 'Calling GET Employees API via API Management Gateway URL. Expect 200.')\n",
170-
"reqsApimAssociate.singlePost('/employees', msg = 'Calling POST Employees API via API Management Gateway URL. Expect 403.')\n",
175+
"output = reqsApimAssociate.singleGet('/employees', msg = 'Calling GET Employees API via API Management Gateway URL. Expect 200.')\n",
176+
"tests.verify(output, 'Returning a mock employee')\n",
177+
"\n",
178+
"output = reqsApimAssociate.singlePost('/employees', msg = 'Calling POST Employees API via API Management Gateway URL. Expect 403.')\n",
179+
"# The return value is not good enough, but checking for an empty string is the best we can do for now.\n",
180+
"tests.verify(output, '')\n",
181+
"\n",
182+
"tests.print_summary()\n",
171183
"\n",
172184
"utils.print_ok('All done!')"
173185
]

samples/general/create.ipynb

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,14 @@
111111
"source": [
112112
"import utils\n",
113113
"from apimrequests import ApimRequests\n",
114+
"from apimtesting import ApimTesting\n",
115+
"\n",
116+
"tests = ApimTesting(\"General Sample Tests\")\n",
114117
"\n",
115118
"# 1) Issue a direct request to API Management\n",
116119
"reqsApim = ApimRequests(apim_gateway_url)\n",
117-
"reqsApim.singleGet('/request-headers', msg = 'Calling Request Headers API via API Management Gateway URL. Response codes 200 and 403 are both valid depending on the infrastructure used.')\n",
120+
"output = reqsApim.singleGet('/request-headers', msg = 'Calling Request Headers API via API Management Gateway URL. Response codes 200 and 403 are both valid depending on the infrastructure used.')\n",
121+
"tests.verify('Host:' in output, True)\n",
118122
"\n",
119123
"# 2) Issue requests against Front Door.\n",
120124
"# Check if the infrastructure architecture deployment uses Azure Front Door.\n",
@@ -123,7 +127,10 @@
123127
"\n",
124128
"if afd_endpoint_url:\n",
125129
" reqsAfd = ApimRequests(afd_endpoint_url)\n",
126-
" reqsAfd.singleGet('/request-headers', msg = 'Calling Request Headers API via via Azure Front Door. Expect 200.')\n",
130+
" output = reqsAfd.singleGet('/request-headers', msg = 'Calling Request Headers API via via Azure Front Door. Expect 200.')\n",
131+
" tests.verify('Host:' in output, True)\n",
132+
"\n",
133+
"tests.print_summary()\n",
127134
"\n",
128135
"utils.print_ok('All done!')"
129136
]

samples/load-balancing/create.ipynb

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -114,42 +114,61 @@
114114
"metadata": {},
115115
"outputs": [],
116116
"source": [
117+
"import json\n",
117118
"import time\n",
118119
"import utils\n",
119120
"from apimrequests import ApimRequests\n",
121+
"from apimtesting import ApimTesting\n",
120122
"\n",
121123
"def zzzs():\n",
122124
" sleep_in_s = 5\n",
123125
" utils.print_message(f'Waiting for {sleep_in_s} seconds for the backend timeouts to reset before starting the next set of calls', blank_above = True)\n",
124126
" time.sleep(sleep_in_s) # Wait a bit before the next set of calls to allow for the backend timeouts to reset\n",
125127
"\n",
128+
"tests = ApimTesting(\"Load Balancing Sample Tests\")\n",
129+
"\n",
126130
"# Preflight: Check if the infrastructure architecture deployment uses Azure Front Door. If so, assume that APIM is not directly accessible and use the Front Door URL instead.\n",
127131
"endpoint_url = utils.test_url_preflight_check(deployment, rg_name, apim_gateway_url)\n",
128132
"reqs = ApimRequests(endpoint_url)\n",
129133
"\n",
134+
"# Quick test to verify load balancing API is accessible\n",
135+
"output = reqs.singleGet('/lb-prioritized', msg = 'Quick test of load balancing API')\n",
136+
"# We expect to see a priority 1 backend (at index 0) with a count of 1 as this is the first request.\n",
137+
"tests.verify(json.loads(output)['index'], 0)\n",
138+
"tests.verify(json.loads(output)['count'], 1)\n",
139+
"\n",
140+
"# The following test assertions are rather basic. The real verification comes in the charts in the subsequent cell.\n",
141+
"\n",
130142
"# 1) Prioritized API calls\n",
131-
"utils.print_message('1/4: Starting API calls for prioritized distribution (50/50)')\n",
132-
"api_results_prioritized = reqs.multiGet('/lb-prioritized', runs = 15, msg = 'Calling prioritized APIs')\n",
133-
"zzzs()\n",
143+
"utils.print_message('1/5: Starting API calls for prioritized distribution (50/50)')\n",
144+
"output = reqs.multiGet('/lb-prioritized', runs = 15, msg = 'Calling prioritized APIs')\n",
145+
"tests.verify(len(output), 15)\n",
134146
"\n",
135-
"# 2) Weighted API calls\n",
136-
"utils.print_message('2/4: Starting API calls for weighted distribution (50/50)', blank_above = True)\n",
137-
"api_results_weighted_equal = reqs.multiGet('/lb-weighted-equal', runs = 15, msg = 'Calling weighted (equal) APIs')\n",
147+
"# # 2) Weighted API calls\n",
138148
"zzzs()\n",
149+
"utils.print_message('2/5: Starting API calls for weighted distribution (50/50)', blank_above = True)\n",
150+
"output = reqs.multiGet('/lb-weighted-equal', runs = 15, msg = 'Calling weighted (equal) APIs')\n",
151+
"tests.verify(len(output), 15)\n",
139152
"\n",
140-
"# 3) Weighted API calls\n",
141-
"utils.print_message('3/4: Starting API calls for weighted distribution (80/20)', blank_above = True)\n",
142-
"api_results_weighted_unequal = reqs.multiGet('/lb-weighted-unequal', runs = 15, msg = 'Calling weighted (unequal) APIs')\n",
153+
"# # 3) Weighted API calls\n",
143154
"zzzs()\n",
155+
"utils.print_message('3/5: Starting API calls for weighted distribution (80/20)', blank_above = True)\n",
156+
"output = reqs.multiGet('/lb-weighted-unequal', runs = 15, msg = 'Calling weighted (unequal) APIs')\n",
157+
"tests.verify(len(output), 15)\n",
144158
"\n",
145159
"# 4) Prioritized & weighted API calls\n",
146-
"utils.print_message('4/4: Starting API calls for prioritized & weighted distribution', blank_above = True)\n",
147-
"api_results_prioritized_and_weighted = reqs.multiGet('/lb-prioritized-weighted', runs = 20, msg = 'Calling prioritized & weighted APIs')\n",
148160
"zzzs()\n",
161+
"utils.print_message('4/5: Starting API calls for prioritized & weighted distribution', blank_above = True)\n",
162+
"output = reqs.multiGet('/lb-prioritized-weighted', runs = 20, msg = 'Calling prioritized & weighted APIs')\n",
163+
"tests.verify(len(output), 20)\n",
149164
"\n",
150165
"# 5) Prioritized & weighted API calls (500ms sleep)\n",
151-
"utils.print_message('5/4: Starting API calls for prioritized & weighted distribution (500ms sleep)', blank_above = True)\n",
152-
"api_results_prioritized_and_weighted_sleep = reqs.multiGet('/lb-prioritized-weighted', runs = 20, msg = 'Calling prioritized & weighted APIs', sleepMs = 500)\n",
166+
"zzzs()\n",
167+
"utils.print_message('5/5: Starting API calls for prioritized & weighted distribution (500ms sleep)', blank_above = True)\n",
168+
"output = reqs.multiGet('/lb-prioritized-weighted', runs = 20, msg = 'Calling prioritized & weighted APIs', sleepMs = 500)\n",
169+
"tests.verify(len(output), 20)\n",
170+
"\n",
171+
"tests.print_summary()\n",
153172
"\n",
154173
"utils.print_ok('All done!')"
155174
]

samples/secure-blob-access/create.ipynb

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@
218218
"source": [
219219
"import utils\n",
220220
"from apimrequests import ApimRequests\n",
221+
"from apimtesting import ApimTesting\n",
221222
"import requests\n",
222223
"import json\n",
223224
"from users import UserHelper\n",
@@ -230,7 +231,7 @@
230231
" sas_url = access_info.get('sas_url', 'N/A')\n",
231232
"\n",
232233
" if sas_url == 'N/A':\n",
233-
" return\n",
234+
" return response\n",
234235
"\n",
235236
" print(f\"\\nSecure Blob URL: {sas_url}\")\n",
236237
" print(f\"Expires At: {access_info.get('expire_at', 'N/A')}\") \n",
@@ -243,14 +244,18 @@
243244
" if blob_response.status_code == 200:\n",
244245
" utils.print_info(\"Direct blob access successful!\")\n",
245246
" content_preview = blob_response.text[:200] + \"...\" if len(blob_response.text) > 200 else blob_response.text\n",
246-
" utils.print_val(f\"Content preview:\", content_preview, True)\n",
247+
" utils.print_val(f\"Content preview:\", content_preview.strip(), True)\n",
248+
" return content_preview.strip()\n",
247249
" else:\n",
248250
" utils.print_error(f\"Direct blob access failed: {blob_response.status_code}\")\n",
251+
" return blob_response.status_code\n",
249252
" except Exception as e:\n",
250253
" utils.print_error(f\"Error accessing blob directly: {str(e)}\")\n",
251254
" except (json.JSONDecodeError, AttributeError):\n",
252255
" utils.print_error(\"Failed to parse JSON response or response is not in expected format.\")\n",
256+
" return response\n",
253257
"\n",
258+
"tests = ApimTesting(\"Secure Blob Access Sample Tests\")\n",
254259
"\n",
255260
"# Preflight: Check if the infrastructure architecture deployment uses Azure Front Door\n",
256261
"endpoint_url = utils.test_url_preflight_check(deployment, rg_name, apim_gateway_url)\n",
@@ -269,7 +274,8 @@
269274
"# Test sample file access\n",
270275
"print(f\"\\n🔒 Getting secure access for {file_name} with authorized user...\")\n",
271276
"response = reqsApimAuthorized.singleGet(f'/{api_prefix}secure-files/{file_name}', msg = f'Requesting secure access for {file_name} (authorized)')\n",
272-
"handleResponse(response)\n",
277+
"output = handleResponse(response)\n",
278+
"tests.verify(output, 'This is an HR document.')\n",
273279
"\n",
274280
"# 2) Test with unauthorized user (has blob access role)\n",
275281
"utils.print_message('2) Testing with Unauthorized User', blank_above = True)\n",
@@ -284,7 +290,12 @@
284290
"# Test sample file access\n",
285291
"print(f\"\\n🔒 Attempting to obtain secure access for {file_name} with unauthorized user (expect 401/403)...\")\n",
286292
"response = reqsApimAuthorized.singleGet(f'/{api_prefix}secure-files/{file_name}', msg = f'Requesting secure access for {file_name} (authorized)')\n",
287-
"handleResponse(response)\n"
293+
"output = handleResponse(response)\n",
294+
"tests.verify(json.loads(output)['statusCode'], 401)\n",
295+
"\n",
296+
"tests.print_summary()\n",
297+
"\n",
298+
"utils.print_ok('All done!')\n"
288299
]
289300
}
290301
],

shared/python/apimtesting.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def print_summary(self):
8484
print('🔍 Detailed Error Analysis:')
8585
print('─' * 50)
8686
for i, error in enumerate(self.errors, 1):
87-
print(f' {i:>2}. {error}')
87+
print(f'{i:>2}.\n{error}')
8888
else:
8989
print('✅ No errors encountered - Everything looks great!')
9090

0 commit comments

Comments
 (0)