Skip to content

Commit 9fa8e38

Browse files
[Test EngSys] adding compression to scrubbers (Azure#18930)
* adding compression to scrubbers * updates from pair programming with mccoy * decompressed body stored as a string now * moving subscription id replacing to a helper function, adding to response url * restructuring * adding six to utilities * fixes based on charles/laurent
1 parent 3b847f6 commit 9fa8e38

File tree

3 files changed

+50
-25
lines changed

3 files changed

+50
-25
lines changed

tools/azure-devtools/src/azure_devtools/scenario_tests/base.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
from .config import TestConfig
1818
from .const import ENV_TEST_DIAGNOSE
19-
from .utilities import create_random_name
19+
from .utilities import create_random_name, _decompress_response_body
2020
from .decorators import live_only
2121

2222

@@ -186,6 +186,7 @@ def _process_response_recording(self, response):
186186
response['headers'] = headers
187187

188188
body = response['body']['string']
189+
response = _decompress_response_body(response)
189190
if is_text_payload(response) and body and not isinstance(body, six.string_types):
190191
try:
191192
response['body']['string'] = body.decode('utf-8')

tools/azure-devtools/src/azure_devtools/scenario_tests/recording_processors.py

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,15 @@
33
# Licensed under the MIT License. See License.txt in the project root for license information.
44
# --------------------------------------------------------------------------------------------
55
from copy import deepcopy
6+
from zlib import decompress
67
import six
78

8-
from .utilities import is_text_payload, is_json_payload, is_batch_payload
9+
from .utilities import (
10+
is_text_payload,
11+
is_json_payload,
12+
is_batch_payload,
13+
replace_subscription_id
14+
)
915

1016

1117
class RecordingProcessor(object):
@@ -36,42 +42,27 @@ def __init__(self, replacement):
3642
self._replacement = replacement
3743

3844
def process_request(self, request):
39-
request.uri = self._replace_subscription_id(request.uri)
45+
request.uri = replace_subscription_id(request.uri, replacement=self._replacement)
4046

4147
if is_text_payload(request) and request.body:
42-
request.body = self._replace_subscription_id(request.body.decode()).encode()
48+
request.body = replace_subscription_id(request.body.decode(), replacement=self._replacement).encode()
4349

4450
return request
4551

4652
def process_response(self, response):
4753
if is_text_payload(response) and response['body']['string']:
48-
response['body']['string'] = self._replace_subscription_id(response['body']['string'])
54+
response['body']['string'] = replace_subscription_id(response['body']['string'], replacement=self._replacement)
4955

50-
self.replace_header_fn(response, 'location', self._replace_subscription_id)
51-
self.replace_header_fn(response, 'azure-asyncoperation', self._replace_subscription_id)
56+
self.replace_header_fn(response, 'location', replace_subscription_id)
57+
self.replace_header_fn(response, 'azure-asyncoperation', replace_subscription_id)
5258

5359
try:
54-
response["url"] = self._replace_subscription_id(response["url"])
60+
response["url"] = replace_subscription_id(response["url"], replacement=self._replacement)
5561
except KeyError:
5662
pass
5763

5864
return response
5965

60-
def _replace_subscription_id(self, val):
61-
import re
62-
# subscription presents in all api call
63-
retval = re.sub('/(subscriptions)/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}',
64-
r'/\1/{}'.format(self._replacement),
65-
val,
66-
flags=re.IGNORECASE)
67-
68-
# subscription is also used in graph call
69-
retval = re.sub('https://(graph.windows.net)/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}',
70-
r'https://\1/{}'.format(self._replacement),
71-
retval,
72-
flags=re.IGNORECASE)
73-
return retval
74-
7566

7667
class LargeRequestBodyProcessor(RecordingProcessor):
7768
def __init__(self, max_request_body=128):
@@ -238,6 +229,8 @@ def process_response(self, response):
238229
self.replace_header(response, 'azure-asyncoperation', old, new)
239230
self.replace_header(response, "www-authenticate", old, new)
240231

232+
response["url"] = replace_subscription_id(response["url"])
233+
241234
try:
242235
for old, new in self.names_name:
243236
response["url"].replace(old, new)

tools/azure-devtools/src/azure_devtools/scenario_tests/utilities.py

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33
# Licensed under the MIT License. See License.txt in the project root for license information.
44
# --------------------------------------------------------------------------------------------
55

6+
import base64
67
import hashlib
8+
import inspect
79
import math
810
import os
9-
import base64
10-
import inspect
11+
import re
12+
import six
13+
import zlib
1114

1215

1316
def create_random_name(prefix='aztest', length=24):
@@ -88,3 +91,31 @@ def trim_kwargs_from_test_function(fn, kwargs):
8891

8992
def is_preparer_func(fn):
9093
return getattr(fn, '__is_preparer', False)
94+
95+
96+
def _decompress_response_body(response):
97+
if "content-encoding" in response["headers"]:
98+
enc = response['headers']['content-encoding'].lower()
99+
if enc in ["gzip", "deflate"] and isinstance(response["body"]["string"], six.binary_type):
100+
zlib_mode = 16 + zlib.MAX_WBITS if enc == "gzip" else zlib.MAX_WBITS
101+
decompressor = zlib.decompressobj(wbits=zlib_mode)
102+
decompressed = decompressor.decompress(response["body"]["string"])
103+
decompressed = decompressed.decode("utf-8")
104+
response["body"]["string"] = decompressed
105+
response["headers"].pop("content-encoding")
106+
return response
107+
108+
109+
def replace_subscription_id(val, replacement="00000000-0000-0000-0000-000000000000"):
110+
# subscription presents in all api call
111+
retval = re.sub('/(subscriptions)/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}',
112+
r'/\1/{}'.format(replacement),
113+
val,
114+
flags=re.IGNORECASE)
115+
116+
# subscription is also used in graph call
117+
retval = re.sub('https://(graph.windows.net)/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}',
118+
r'https://\1/{}'.format(replacement),
119+
retval,
120+
flags=re.IGNORECASE)
121+
return retval

0 commit comments

Comments
 (0)