def test_retry_timeout(): class MockTransport(HttpTransport): def __init__(self): self.count = 0 def __exit__(self, exc_type, exc_val, exc_tb): pass def close(self): pass def open(self): pass def send(self, request, **kwargs): # type: (PipelineRequest, Any) -> PipelineResponse self.count += 1 if self.count > 2: assert self.count <= 2 time.sleep(0.5) raise ServiceResponseError('timeout') http_request = HttpRequest('GET', 'http://127.0.0.1/') headers = {'Content-Type': "multipart/form-data"} http_request.headers = headers http_retry = RetryPolicy(retry_total=10, timeout=1) pipeline = Pipeline(MockTransport(), [http_retry]) with pytest.raises(ServiceResponseTimeoutError): pipeline.run(http_request)
async def test_retry_seekable_file(): class MockTransport(AsyncHttpTransport): def __init__(self): self._first = True async def __aexit__(self, exc_type, exc_val, exc_tb): pass async def close(self): pass async def open(self): pass async def send( self, request, **kwargs): # type: (PipelineRequest, Any) -> PipelineResponse if self._first: self._first = False for value in request.files.values(): name, body = value[0], value[1] if name and body and hasattr(body, 'read'): body.seek(0, 2) raise AzureError('fail on first') for value in request.files.values(): name, body = value[0], value[1] if name and body and hasattr(body, 'read'): position = body.tell() assert not position response = HttpResponse(request, None) response.status_code = 400 return response file = tempfile.NamedTemporaryFile(delete=False) file.write(b'Lots of dataaaa') file.close() http_request = HttpRequest('GET', 'http://127.0.0.1/') headers = {'Content-Type': "multipart/form-data"} http_request.headers = headers with open(file.name, 'rb') as f: form_data_content = { 'fileContent': f, 'fileName': f.name, } http_request.set_formdata_body(form_data_content) http_retry = AsyncRetryPolicy(retry_total=1) pipeline = AsyncPipeline(MockTransport(), [http_retry]) await pipeline.run(http_request) os.unlink(f.name)
def test_retry_seekable_file(): class MockTransport(HttpTransport): def __init__(self): self._first = True def __exit__(self, exc_type, exc_val, exc_tb): pass def close(self): pass def open(self): pass def send(self, request, **kwargs): # type: (PipelineRequest, Any) -> PipelineResponse if self._first: self._first = False for value in request.files.values(): name, body = value[0], value[1] if name and body and hasattr(body, 'read'): body.seek(0, 2) raise AzureError('fail on first') for value in request.files.values(): name, body = value[0], value[1] if name and body and hasattr(body, 'read'): position = body.tell() assert not position return HttpResponse(request, None) file_name = 'test_retry_seekable_file' with open(file_name, "w+") as f: f.write('Lots of dataaaa') http_request = HttpRequest('GET', 'http://127.0.0.1/') headers = {'Content-Type': "multipart/form-data"} http_request.headers = headers form_data_content = { 'fileContent': open(file_name, 'rb'), 'fileName': file_name, } http_request.set_formdata_body(form_data_content) http_retry = RetryPolicy(retry_total=1) pipeline = Pipeline(MockTransport(), [http_retry]) pipeline.run(http_request)
def _set_content_body(content: ContentType, internal_request: _PipelineTransportHttpRequest) -> None: headers = internal_request.headers content_type = headers.get("Content-Type") if _is_stream_or_str_bytes(content): # stream will be bytes / str, or iterator of bytes / str internal_request.set_streamed_data_body(content) if isinstance(content, str) and content: _set_content_length_header("Content-Length", str(len(internal_request.data)), internal_request) _set_content_type_header("text/plain", internal_request) elif isinstance(content, bytes) and content: _set_content_length_header("Content-Length", str(len(internal_request.data)), internal_request) _set_content_type_header("application/octet-stream", internal_request) elif isinstance(content, (Iterable, AsyncIterable)): _set_content_length_header("Transfer-Encoding", "chunked", internal_request) _set_content_type_header("application/octet-stream", internal_request) elif isinstance(content, ET.Element): # XML body internal_request.set_xml_body(content) _set_content_type_header("application/xml", internal_request) _set_content_length_header("Content-Length", str(len(internal_request.data)), internal_request) elif content_type and content_type.startswith("text/"): # Text body internal_request.set_text_body(content) _set_content_length_header("Content-Length", str(len(internal_request.data)), internal_request) else: # Other body internal_request.data = content internal_request.headers = headers
def test_http_logger(): class MockHandler(logging.Handler): def __init__(self): super(MockHandler, self).__init__() self.messages = [] def reset(self): self.messages = [] def emit(self, record): self.messages.append(record) mock_handler = MockHandler() logger = logging.getLogger("testlogger") logger.addHandler(mock_handler) logger.setLevel(logging.DEBUG) policy = HttpLoggingPolicy(logger=logger) universal_request = HttpRequest('GET', 'http://127.0.0.1/') http_response = HttpResponse(universal_request, None) http_response.status_code = 202 request = PipelineRequest(universal_request, PipelineContext(None)) # Basics policy.on_request(request) response = PipelineResponse(request, http_response, request.context) policy.on_response(request, response) assert all(m.levelname == 'INFO' for m in mock_handler.messages) assert len(mock_handler.messages) == 5 assert mock_handler.messages[ 0].message == "Request URL: 'http://127.0.0.1/'" assert mock_handler.messages[1].message == "Request method: 'GET'" assert mock_handler.messages[2].message == 'Request headers:' assert mock_handler.messages[3].message == 'Response status: 202' assert mock_handler.messages[4].message == 'Response headers:' mock_handler.reset() # Let's make this request a failure, retried twice policy.on_request(request) response = PipelineResponse(request, http_response, request.context) policy.on_response(request, response) policy.on_request(request) response = PipelineResponse(request, http_response, request.context) policy.on_response(request, response) assert all(m.levelname == 'INFO' for m in mock_handler.messages) assert len(mock_handler.messages) == 10 assert mock_handler.messages[ 0].message == "Request URL: 'http://127.0.0.1/'" assert mock_handler.messages[1].message == "Request method: 'GET'" assert mock_handler.messages[2].message == 'Request headers:' assert mock_handler.messages[3].message == 'Response status: 202' assert mock_handler.messages[4].message == 'Response headers:' assert mock_handler.messages[ 0].message == "Request URL: 'http://127.0.0.1/'" assert mock_handler.messages[1].message == "Request method: 'GET'" assert mock_handler.messages[2].message == 'Request headers:' assert mock_handler.messages[3].message == 'Response status: 202' assert mock_handler.messages[4].message == 'Response headers:' mock_handler.reset() # Headers and query parameters policy.allowed_query_params = ['country'] universal_request.headers = { "Accept": "Caramel", "Hate": "Chocolat", } http_response.headers = { "Content-Type": "Caramel", "HateToo": "Chocolat", } universal_request.url = "http://127.0.0.1/?country=france&city=aix" policy.on_request(request) response = PipelineResponse(request, http_response, request.context) policy.on_response(request, response) assert all(m.levelname == 'INFO' for m in mock_handler.messages) assert len(mock_handler.messages) == 9 assert mock_handler.messages[ 0].message == "Request URL: 'http://127.0.0.1/?country=france&city=REDACTED'" assert mock_handler.messages[1].message == "Request method: 'GET'" assert mock_handler.messages[2].message == "Request headers:" # Dict not ordered in Python, exact logging order doesn't matter assert set([ mock_handler.messages[3].message, mock_handler.messages[4].message ]) == set([" 'Accept': 'Caramel'", " 'Hate': 'REDACTED'"]) assert mock_handler.messages[5].message == "Response status: 202" assert mock_handler.messages[6].message == "Response headers:" # Dict not ordered in Python, exact logging order doesn't matter assert set([ mock_handler.messages[7].message, mock_handler.messages[8].message ]) == set([" 'Content-Type': 'Caramel'", " 'HateToo': 'REDACTED'"]) mock_handler.reset()