From 79c3863bbe26e82bed4d4248a923409a143aec23 Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Tue, 15 Oct 2019 14:45:03 -0700 Subject: [PATCH 1/8] Initital Commit --- .../storage/file/aio/file_client_async.py | 90 ++++++--------- .../azure/storage/file/file_client.py | 104 ++++++++---------- 2 files changed, 79 insertions(+), 115 deletions(-) diff --git a/sdk/storage/azure-storage-file/azure/storage/file/aio/file_client_async.py b/sdk/storage/azure-storage-file/azure/storage/file/aio/file_client_async.py index a9ff29044a29..99217758c1a6 100644 --- a/sdk/storage/azure-storage-file/azure/storage/file/aio/file_client_async.py +++ b/sdk/storage/azure-storage-file/azure/storage/file/aio/file_client_async.py @@ -630,8 +630,8 @@ async def set_file_metadata(self, metadata=None, timeout=None, **kwargs): # typ async def upload_range( # type: ignore self, data, # type: bytes - start_range, # type: int - end_range, # type: int + offset, # type: int + length, # type: int validate_content=False, # type: Optional[bool] timeout=None, # type: Optional[int] encoding="UTF-8", @@ -642,16 +642,12 @@ async def upload_range( # type: ignore :param bytes data: The data to upload. - :param int start_range: + :param int offset: Start of byte range to use for uploading a section of the file. The range can be up to 4 MB in size. - The start_range and end_range params are inclusive. - Ex: start_range=0, end_range=511 will upload first 512 bytes of file. - :param int end_range: - End of byte range to use for uploading a section of the file. + :param int length: + Number of bytes to use for uploading a section of the file. The range can be up to 4 MB in size. - The start_range and end_range params are inclusive. - Ex: start_range=0, end_range=511 will upload first 512 bytes of file. :param bool validate_content: If true, calculates an MD5 hash of the page content. The storage service checks the hash of the content that has arrived @@ -671,8 +667,8 @@ async def upload_range( # type: ignore if isinstance(data, six.text_type): data = data.encode(encoding) - content_range = "bytes={0}-{1}".format(start_range, end_range) - content_length = end_range - start_range + 1 + content_range = "bytes={0}-{1}".format(offset, length) + content_length = length - offset + 1 try: return await self._client.file.upload_range( # type: ignore range=content_range, @@ -688,25 +684,21 @@ async def upload_range( # type: ignore @distributed_trace_async async def upload_range_from_url(self, source_url, # type: str - range_start, # type: int - range_end, # type: int - source_range_start, # type: int + offset, # type: int + length, # type: int + source_offset, # type: int **kwargs # type: Any ): # type: (str, int, int, int, **Any) -> Dict[str, Any] ''' Writes the bytes from one Azure File endpoint into the specified range of another Azure File endpoint. - :param int range_start: + :param int offset: Start of byte range to use for updating a section of the file. The range can be up to 4 MB in size. - The start_range and end_range params are inclusive. - Ex: start_range=0, end_range=511 will download first 512 bytes of file. - :param int range_end: - End of byte range to use for updating a section of the file. + :param int length: + Number of bytes to use for updating a section of the file. The range can be up to 4 MB in size. - The start_range and end_range params are inclusive. - Ex: start_range=0, end_range=511 will download first 512 bytes of file. :param str source_url: A URL of up to 2 KB in length that specifies an Azure file or blob. The value should be URL-encoded as it would appear in a request URI. @@ -716,20 +708,18 @@ async def upload_range_from_url(self, source_url, # type: str Examples: https://myaccount.file.core.windows.net/myshare/mydir/myfile https://otheraccount.file.core.windows.net/myshare/mydir/myfile?sastoken - :param int source_range_start: + :param int source_offset: Start of byte range to use for updating a section of the file. The range can be up to 4 MB in size. - The start_range and end_range params are inclusive. - Ex: start_range=0, end_range=511 will download first 512 bytes of file. :param int timeout: The timeout parameter is expressed in seconds. ''' options = self._upload_range_from_url_options( source_url=source_url, - range_start=range_start, - range_end=range_end, - source_range_start=source_range_start, + offset=offset, + length=length, + source_offset=source_offset, **kwargs ) try: @@ -740,22 +730,18 @@ async def upload_range_from_url(self, source_url, # type: str @distributed_trace_async async def get_ranges( # type: ignore self, - start_range=None, # type: Optional[int] - end_range=None, # type: Optional[int] + offset=None, # type: Optional[int] + length=None, # type: Optional[int] timeout=None, # type: Optional[int] **kwargs ): # type: (...) -> List[dict[str, int]] """Returns the list of valid ranges of a file. - :param int start_range: + :param int offset: Specifies the start offset of bytes over which to get ranges. - The start_range and end_range params are inclusive. - Ex: start_range=0, end_range=511 will download first 512 bytes of file. - :param int end_range: - Specifies the end offset of bytes over which to get ranges. - The start_range and end_range params are inclusive. - Ex: start_range=0, end_range=511 will download first 512 bytes of file. + :param int length: + Number of bytes to use over which to get ranges. :param int timeout: The timeout parameter is expressed in seconds. :returns: A list of valid ranges. @@ -765,11 +751,11 @@ async def get_ranges( # type: ignore raise ValueError("Unsupported method for encryption.") content_range = None - if start_range is not None: - if end_range is not None: - content_range = "bytes={0}-{1}".format(start_range, end_range) + if offset is not None: + if length is not None: + content_range = "bytes={0}-{1}".format(offset, length) else: - content_range = "bytes={0}-".format(start_range) + content_range = "bytes={0}-".format(offset) try: ranges = await self._client.file.get_range_list( sharesnapshot=self.snapshot, timeout=timeout, range=content_range, **kwargs @@ -781,8 +767,8 @@ async def get_ranges( # type: ignore @distributed_trace_async async def clear_range( # type: ignore self, - start_range, # type: int - end_range, # type: int + offset, # type: int + length, # type: int timeout=None, # type: Optional[int] **kwargs ): @@ -790,16 +776,12 @@ async def clear_range( # type: ignore """Clears the specified range and releases the space used in storage for that range. - :param int start_range: + :param int offset: Start of byte range to use for clearing a section of the file. The range can be up to 4 MB in size. - The start_range and end_range params are inclusive. - Ex: start_range=0, end_range=511 will download first 512 bytes of file. - :param int end_range: - End of byte range to use for clearing a section of the file. + :param int length: + Number of bytes to use for clearing a section of the file. The range can be up to 4 MB in size. - The start_range and end_range params are inclusive. - Ex: start_range=0, end_range=511 will download first 512 bytes of file. :param int timeout: The timeout parameter is expressed in seconds. :returns: File-updated property dict (Etag and last modified). @@ -808,11 +790,11 @@ async def clear_range( # type: ignore if self.require_encryption or (self.key_encryption_key is not None): raise ValueError("Unsupported method for encryption.") - if start_range is None or start_range % 512 != 0: - raise ValueError("start_range must be an integer that aligns with 512 file size") - if end_range is None or end_range % 512 != 511: - raise ValueError("end_range must be an integer that aligns with 512 file size") - content_range = "bytes={0}-{1}".format(start_range, end_range) + if offset is None or offset % 512 != 0: + raise ValueError("offset must be an integer that aligns with 512 file size") + if length is None or length % 512 != 511: + raise ValueError("length must be an integer that aligns with 512 file size") + content_range = "bytes={0}-{1}".format(offset, length) try: return await self._client.file.upload_range( # type: ignore timeout=timeout, diff --git a/sdk/storage/azure-storage-file/azure/storage/file/file_client.py b/sdk/storage/azure-storage-file/azure/storage/file/file_client.py index ae3608c56a38..4ba4320c3c51 100644 --- a/sdk/storage/azure-storage-file/azure/storage/file/file_client.py +++ b/sdk/storage/azure-storage-file/azure/storage/file/file_client.py @@ -845,8 +845,8 @@ def set_file_metadata(self, metadata=None, timeout=None, **kwargs): # type: igno @distributed_trace def upload_range( # type: ignore self, data, # type: bytes - start_range, # type: int - end_range, # type: int + offset, # type: int + length, # type: int validate_content=False, # type: Optional[bool] timeout=None, # type: Optional[int] encoding='UTF-8', @@ -857,16 +857,12 @@ def upload_range( # type: ignore :param bytes data: The data to upload. - :param int start_range: + :param int offset: Start of byte range to use for uploading a section of the file. The range can be up to 4 MB in size. - The start_range and end_range params are inclusive. - Ex: start_range=0, end_range=511 will upload first 512 bytes of file. - :param int end_range: - End of byte range to use for uploading a section of the file. + :param int length: + Number of bytes to use for uploading a section of the file. The range can be up to 4 MB in size. - The start_range and end_range params are inclusive. - Ex: start_range=0, end_range=511 will upload first 512 bytes of file. :param bool validate_content: If true, calculates an MD5 hash of the page content. The storage service checks the hash of the content that has arrived @@ -886,8 +882,8 @@ def upload_range( # type: ignore if isinstance(data, six.text_type): data = data.encode(encoding) - content_range = 'bytes={0}-{1}'.format(start_range, end_range) - content_length = end_range - start_range + 1 + content_range = 'bytes={0}-{1}'.format(offset, length) + content_length = length - offset + 1 try: return self._client.file.upload_range( # type: ignore range=content_range, @@ -902,19 +898,19 @@ def upload_range( # type: ignore @staticmethod def _upload_range_from_url_options(source_url, # type: str - range_start, # type: int - range_end, # type: int - source_range_start, # type: int + offset, # type: int + length, # type: int + source_offset, # type: int **kwargs ): # type: (...) -> Dict[str, Any] - if range_start is None or range_end is None or source_range_start is None: - raise ValueError("start_range must be specified") + if offset is None or length is None or source_offset is None: + raise ValueError("offset must be specified") # Format range - destination_range = 'bytes={0}-{1}'.format(range_start, range_end) - source_range = 'bytes={0}-{1}'.format(source_range_start, source_range_start + (range_end - range_start)) + destination_range = 'bytes={0}-{1}'.format(offset, length) + source_range = 'bytes={0}-{1}'.format(source_offset, source_offset + (length - offset)) options = { 'copy_source': source_url, @@ -928,25 +924,21 @@ def _upload_range_from_url_options(source_url, # type: str @distributed_trace def upload_range_from_url(self, source_url, # type: str - range_start, # type: int - range_end, # type: int - source_range_start, # type: int + offset, # type: int + length, # type: int + source_offset, # type: int **kwargs # type: Any ): # type: (str, int, int, int, **Any) -> Dict[str, Any] ''' Writes the bytes from one Azure File endpoint into the specified range of another Azure File endpoint. - :param int range_start: + :param int offset: Start of byte range to use for updating a section of the file. The range can be up to 4 MB in size. - The start_range and end_range params are inclusive. - Ex: start_range=0, end_range=511 will download first 512 bytes of file. - :param int range_end: - End of byte range to use for updating a section of the file. + :param int length: + Number of bytes to use for updating a section of the file. The range can be up to 4 MB in size. - The start_range and end_range params are inclusive. - Ex: start_range=0, end_range=511 will download first 512 bytes of file. :param str source_url: A URL of up to 2 KB in length that specifies an Azure file or blob. The value should be URL-encoded as it would appear in a request URI. @@ -956,20 +948,18 @@ def upload_range_from_url(self, source_url, # type: str Examples: https://myaccount.file.core.windows.net/myshare/mydir/myfile https://otheraccount.file.core.windows.net/myshare/mydir/myfile?sastoken - :param int source_range_start: + :param int source_offset: Start of byte range to use for updating a section of the file. The range can be up to 4 MB in size. - The start_range and end_range params are inclusive. - Ex: start_range=0, end_range=511 will download first 512 bytes of file. :param int timeout: The timeout parameter is expressed in seconds. ''' options = self._upload_range_from_url_options( source_url=source_url, - range_start=range_start, - range_end=range_end, - source_range_start=source_range_start, + offset=offset, + length=length, + source_offset=source_offset, **kwargs ) try: @@ -979,22 +969,18 @@ def upload_range_from_url(self, source_url, # type: str @distributed_trace def get_ranges( # type: ignore - self, start_range=None, # type: Optional[int] - end_range=None, # type: Optional[int] + self, offset=None, # type: Optional[int] + length=None, # type: Optional[int] timeout=None, # type: Optional[int] **kwargs ): # type: (...) -> List[dict[str, int]] """Returns the list of valid ranges of a file. - :param int start_range: + :param int offset: Specifies the start offset of bytes over which to get ranges. - The start_range and end_range params are inclusive. - Ex: start_range=0, end_range=511 will download first 512 bytes of file. - :param int end_range: - Specifies the end offset of bytes over which to get ranges. - The start_range and end_range params are inclusive. - Ex: start_range=0, end_range=511 will download first 512 bytes of file. + :param int length: + Number of bytes to use over which to get ranges. :param int timeout: The timeout parameter is expressed in seconds. :returns: A list of valid ranges. @@ -1004,11 +990,11 @@ def get_ranges( # type: ignore raise ValueError("Unsupported method for encryption.") content_range = None - if start_range is not None: - if end_range is not None: - content_range = 'bytes={0}-{1}'.format(start_range, end_range) + if offset is not None: + if length is not None: + content_range = 'bytes={0}-{1}'.format(offset, length) else: - content_range = 'bytes={0}-'.format(start_range) + content_range = 'bytes={0}-'.format(offset) try: ranges = self._client.file.get_range_list( sharesnapshot=self.snapshot, @@ -1021,8 +1007,8 @@ def get_ranges( # type: ignore @distributed_trace def clear_range( # type: ignore - self, start_range, # type: int - end_range, # type: int + self, offset, # type: int + length, # type: int timeout=None, # type: Optional[int] **kwargs ): @@ -1030,16 +1016,12 @@ def clear_range( # type: ignore """Clears the specified range and releases the space used in storage for that range. - :param int start_range: - Start of byte range to use for clearing a section of the file. + :param int offset: + Number of bytes to use for clearing a section of the file. The range can be up to 4 MB in size. - The start_range and end_range params are inclusive. - Ex: start_range=0, end_range=511 will download first 512 bytes of file. - :param int end_range: + :param int length: End of byte range to use for clearing a section of the file. The range can be up to 4 MB in size. - The start_range and end_range params are inclusive. - Ex: start_range=0, end_range=511 will download first 512 bytes of file. :param int timeout: The timeout parameter is expressed in seconds. :returns: File-updated property dict (Etag and last modified). @@ -1048,11 +1030,11 @@ def clear_range( # type: ignore if self.require_encryption or (self.key_encryption_key is not None): raise ValueError("Unsupported method for encryption.") - if start_range is None or start_range % 512 != 0: - raise ValueError("start_range must be an integer that aligns with 512 file size") - if end_range is None or end_range % 512 != 511: - raise ValueError("end_range must be an integer that aligns with 512 file size") - content_range = 'bytes={0}-{1}'.format(start_range, end_range) + if offset is None or offset % 512 != 0: + raise ValueError("offset must be an integer that aligns with 512 file size") + if length is None or length % 512 != 511: + raise ValueError("length must be an integer that aligns with 512 file size") + content_range = 'bytes={0}-{1}'.format(offset, length) try: return self._client.file.upload_range( # type: ignore timeout=timeout, From 14f0c776d7699942e99b1867ecea131e32a99340 Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Tue, 15 Oct 2019 15:22:49 -0700 Subject: [PATCH 2/8] length changes --- .../storage/file/aio/file_client_async.py | 18 +++++++----- .../azure/storage/file/file_client.py | 29 ++++++++++++------- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/sdk/storage/azure-storage-file/azure/storage/file/aio/file_client_async.py b/sdk/storage/azure-storage-file/azure/storage/file/aio/file_client_async.py index 99217758c1a6..55290a0ab80f 100644 --- a/sdk/storage/azure-storage-file/azure/storage/file/aio/file_client_async.py +++ b/sdk/storage/azure-storage-file/azure/storage/file/aio/file_client_async.py @@ -467,7 +467,8 @@ async def download_file( raise ValueError("Encryption not supported.") if length is not None and offset is None: raise ValueError("Offset value must not be None if length is set.") - + if length is not None: + length = offset + length - 1 # Service actually uses an end-range inclusive index downloader = StorageStreamDownloader( client=self._client.file, config=self._config, @@ -666,13 +667,12 @@ async def upload_range( # type: ignore raise ValueError("Encryption not supported.") if isinstance(data, six.text_type): data = data.encode(encoding) - - content_range = "bytes={0}-{1}".format(offset, length) - content_length = length - offset + 1 + end_range = offset + length - 1 # Reformat to an inclusive range index + content_range = "bytes={0}-{1}".format(offset, end_range) try: return await self._client.file.upload_range( # type: ignore range=content_range, - content_length=content_length, + content_length=length, optionalbody=data, timeout=timeout, validate_content=validate_content, @@ -709,8 +709,8 @@ async def upload_range_from_url(self, source_url, # type: str https://myaccount.file.core.windows.net/myshare/mydir/myfile https://otheraccount.file.core.windows.net/myshare/mydir/myfile?sastoken :param int source_offset: - Start of byte range to use for updating a section of the file. - The range can be up to 4 MB in size. + This indicates the start of the range of bytes(inclusive) that has to be taken from the copy source. + The service will read the same number of bytes as the destination range (length-offset). :param int timeout: The timeout parameter is expressed in seconds. ''' @@ -753,6 +753,7 @@ async def get_ranges( # type: ignore content_range = None if offset is not None: if length is not None: + length = offset + length - 1 # Reformat to an inclusive range index content_range = "bytes={0}-{1}".format(offset, length) else: content_range = "bytes={0}-".format(offset) @@ -794,7 +795,8 @@ async def clear_range( # type: ignore raise ValueError("offset must be an integer that aligns with 512 file size") if length is None or length % 512 != 511: raise ValueError("length must be an integer that aligns with 512 file size") - content_range = "bytes={0}-{1}".format(offset, length) + end_range = length + offset - 1 # Reformat to an inclusive range index + content_range = "bytes={0}-{1}".format(offset, end_range) try: return await self._client.file.upload_range( # type: ignore timeout=timeout, diff --git a/sdk/storage/azure-storage-file/azure/storage/file/file_client.py b/sdk/storage/azure-storage-file/azure/storage/file/file_client.py index 4ba4320c3c51..02fc9a766aa2 100644 --- a/sdk/storage/azure-storage-file/azure/storage/file/file_client.py +++ b/sdk/storage/azure-storage-file/azure/storage/file/file_client.py @@ -680,7 +680,8 @@ def download_file( raise ValueError("Encryption not supported.") if length is not None and offset is None: raise ValueError("Offset value must not be None if length is set.") - + if length is not None: + length = offset + length - 1 # Service actually uses an end-range inclusive index return StorageStreamDownloader( client=self._client.file, config=self._config, @@ -882,12 +883,13 @@ def upload_range( # type: ignore if isinstance(data, six.text_type): data = data.encode(encoding) - content_range = 'bytes={0}-{1}'.format(offset, length) + end_range = offset + length - 1 # Reformat to an inclusive range index + content_range = 'bytes={0}-{1}'.format(offset, end_range) content_length = length - offset + 1 try: return self._client.file.upload_range( # type: ignore range=content_range, - content_length=content_length, + content_length=length, optionalbody=data, timeout=timeout, validate_content=validate_content, @@ -905,12 +907,17 @@ def _upload_range_from_url_options(source_url, # type: str ): # type: (...) -> Dict[str, Any] - if offset is None or length is None or source_offset is None: - raise ValueError("offset must be specified") + if offset is None or offset % 512 != 0: + raise ValueError("offset must be an integer that aligns with 512 page size") + if length is None or length % 512 != 0: + raise ValueError("length must be an integer that aligns with 512 page size") + if source_offset is None or offset % 512 != 0: + raise ValueError("source_offset must be an integer that aligns with 512 page size") # Format range - destination_range = 'bytes={0}-{1}'.format(offset, length) - source_range = 'bytes={0}-{1}'.format(source_offset, source_offset + (length - offset)) + end_range = offset + length - 1 + destination_range = 'bytes={0}-{1}'.format(offset, end_range) + source_range = 'bytes={0}-{1}'.format(source_offset, source_offset + length - 1) # should subtract 1 here? options = { 'copy_source': source_url, @@ -949,8 +956,8 @@ def upload_range_from_url(self, source_url, # type: str https://myaccount.file.core.windows.net/myshare/mydir/myfile https://otheraccount.file.core.windows.net/myshare/mydir/myfile?sastoken :param int source_offset: - Start of byte range to use for updating a section of the file. - The range can be up to 4 MB in size. + This indicates the start of the range of bytes(inclusive) that has to be taken from the copy source. + The service will read the same number of bytes as the destination range (length-offset). :param int timeout: The timeout parameter is expressed in seconds. ''' @@ -992,6 +999,7 @@ def get_ranges( # type: ignore content_range = None if offset is not None: if length is not None: + length = offset + length - 1 # Reformat to an inclusive range index content_range = 'bytes={0}-{1}'.format(offset, length) else: content_range = 'bytes={0}-'.format(offset) @@ -1034,7 +1042,8 @@ def clear_range( # type: ignore raise ValueError("offset must be an integer that aligns with 512 file size") if length is None or length % 512 != 511: raise ValueError("length must be an integer that aligns with 512 file size") - content_range = 'bytes={0}-{1}'.format(offset, length) + end_range = length + offset - 1 # Reformat to an inclusive range index + content_range = 'bytes={0}-{1}'.format(offset, end_range) try: return self._client.file.upload_range( # type: ignore timeout=timeout, From 17002e88e1eefd4e136da4b7d9bb4e78ebd1eb63 Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Tue, 15 Oct 2019 23:22:41 -0700 Subject: [PATCH 3/8] some test changes --- .../azure/storage/file/file_client.py | 17 +++++------ .../azure-storage-file/tests/test_file.py | 29 ++++++++++--------- .../tests/test_file_async.py | 26 ++++++++--------- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/sdk/storage/azure-storage-file/azure/storage/file/file_client.py b/sdk/storage/azure-storage-file/azure/storage/file/file_client.py index 02fc9a766aa2..e93de9d7247b 100644 --- a/sdk/storage/azure-storage-file/azure/storage/file/file_client.py +++ b/sdk/storage/azure-storage-file/azure/storage/file/file_client.py @@ -885,7 +885,6 @@ def upload_range( # type: ignore end_range = offset + length - 1 # Reformat to an inclusive range index content_range = 'bytes={0}-{1}'.format(offset, end_range) - content_length = length - offset + 1 try: return self._client.file.upload_range( # type: ignore range=content_range, @@ -907,12 +906,12 @@ def _upload_range_from_url_options(source_url, # type: str ): # type: (...) -> Dict[str, Any] - if offset is None or offset % 512 != 0: - raise ValueError("offset must be an integer that aligns with 512 page size") - if length is None or length % 512 != 0: - raise ValueError("length must be an integer that aligns with 512 page size") - if source_offset is None or offset % 512 != 0: - raise ValueError("source_offset must be an integer that aligns with 512 page size") + if offset is None: + raise ValueError("offset must be provided.") + if length is None: + raise ValueError("length must be provided.") + if source_offset is None: + raise ValueError("source_offset must be provided.") # Format range end_range = offset + length - 1 @@ -999,8 +998,8 @@ def get_ranges( # type: ignore content_range = None if offset is not None: if length is not None: - length = offset + length - 1 # Reformat to an inclusive range index - content_range = 'bytes={0}-{1}'.format(offset, length) + end_range = offset + length - 1 # Reformat to an inclusive range index + content_range = 'bytes={0}-{1}'.format(offset, end_range) else: content_range = 'bytes={0}-'.format(offset) try: diff --git a/sdk/storage/azure-storage-file/tests/test_file.py b/sdk/storage/azure-storage-file/tests/test_file.py index 2f54e618c567..e69e623e9a50 100644 --- a/sdk/storage/azure-storage-file/tests/test_file.py +++ b/sdk/storage/azure-storage-file/tests/test_file.py @@ -568,10 +568,11 @@ def test_update_range(self): # Act data = b'abcdefghijklmnop' * 32 - file_client.upload_range(data, 0, 511) + file_client.upload_range(data, offset=0, length=512) # Assert content = file_client.download_file().content_as_bytes() + self.assertEqual(len(data), 512) self.assertEqual(data, content[:512]) self.assertEqual(self.short_byte_data[512:], content[512:]) @@ -582,7 +583,7 @@ def test_update_range_with_md5(self): # Act data = b'abcdefghijklmnop' * 32 - file_client.upload_range(data, 0, 511, validate_content=True) + file_client.upload_range(data, offset=0, length=512, validate_content=True) # Assert @@ -604,7 +605,7 @@ def test_update_range_from_file_url_when_source_file_does_not_have_enough_bytes( # Act with self.assertRaises(HttpResponseError): # when the source file has less bytes than 2050, throw exception - destination_file_client.upload_range_from_url(source_file_url, 0, 2049, 0) + destination_file_client.upload_range_from_url(source_file_url, offset=0, length=2050, source_offset=0) @record def test_update_range_from_file_url(self): @@ -612,7 +613,7 @@ def test_update_range_from_file_url(self): source_file_name = 'testfile' source_file_client = self._create_file(file_name=source_file_name) data = b'abcdefghijklmnop' * 32 - source_file_client.upload_range(data, 0, 511) + source_file_client.upload_range(data, offset=0, length=512) destination_file_name = 'filetoupdate' destination_file_client = self._create_empty_file(file_name=destination_file_name) @@ -625,12 +626,12 @@ def test_update_range_from_file_url(self): source_file_url = source_file_client.url + '?' + sas_token_for_source_file # Act - destination_file_client.upload_range_from_url(source_file_url, 0, 511, 0) + destination_file_client.upload_range_from_url(source_file_url, offset=0, length=512, source_offset=0) # Assert # To make sure the range of the file is actually updated file_ranges = destination_file_client.get_ranges() - file_content = destination_file_client.download_file(offset=0, length=511).content_as_bytes() + file_content = destination_file_client.download_file(offset=0, length=512).content_as_bytes() self.assertEquals(1, len(file_ranges)) self.assertEquals(0, file_ranges[0].get('start')) self.assertEquals(511, file_ranges[0].get('end')) @@ -644,7 +645,7 @@ def test_update_big_range_from_file_url(self): source_file_client = self._create_empty_file(file_name=source_file_name, file_size=1024 * 1024) data = b'abcdefghijklmnop' * 65536 - source_file_client.upload_range(data, 0, end) + source_file_client.upload_range(data, offset=0, length=end+1) destination_file_name = 'filetoupdate1' destination_file_client = self._create_empty_file(file_name=destination_file_name, file_size=1024 * 1024) @@ -658,7 +659,7 @@ def test_update_big_range_from_file_url(self): source_file_url = source_file_client.url + '?' + sas_token_for_source_file # Act - destination_file_client.upload_range_from_url(source_file_url, 0, end, 0) + destination_file_client.upload_range_from_url(source_file_url, offset=0, length=end+1, source_offset=0) # Assert # To make sure the range of the file is actually updated @@ -677,7 +678,7 @@ def test_clear_range(self): file_client = self._create_file() # Act - resp = file_client.clear_range(0, 511) + resp = file_client.clear_range(offset=0, length=512) # Assert content = file_client.download_file().content_as_bytes() @@ -691,7 +692,7 @@ def test_update_file_unicode(self): # Act data = u'abcdefghijklmnop' * 32 - file_client.upload_range(data, 0, 511) + file_client.upload_range(data, offset=0, length=512) encoded = data.encode('utf-8') @@ -732,8 +733,8 @@ def test_list_ranges_2(self): file_client.create_file(2048) data = b'abcdefghijklmnop' * 32 - resp1 = file_client.upload_range(data, 0, 511) - resp2 = file_client.upload_range(data, 1024, 1535) + resp1 = file_client.upload_range(data, offset=0, length=512) + resp2 = file_client.upload_range(data, offset=1024, length=512) # Act ranges = file_client.get_ranges() @@ -786,8 +787,8 @@ def test_list_ranges_2_from_snapshot(self): credential=self.settings.STORAGE_ACCOUNT_KEY) file_client.create_file(2048) data = b'abcdefghijklmnop' * 32 - resp1 = file_client.upload_range(data, 0, 511) - resp2 = file_client.upload_range(data, 1024, 1535) + resp1 = file_client.upload_range(data, offset=0, length=512) + resp2 = file_client.upload_range(data, offset=1024, length=512) share_client = self.fsc.get_share_client(self.share_name) snapshot = share_client.create_snapshot() diff --git a/sdk/storage/azure-storage-file/tests/test_file_async.py b/sdk/storage/azure-storage-file/tests/test_file_async.py index 3c0c5367d1e1..409357b5586b 100644 --- a/sdk/storage/azure-storage-file/tests/test_file_async.py +++ b/sdk/storage/azure-storage-file/tests/test_file_async.py @@ -703,7 +703,7 @@ async def _test_update_range_async(self): # Act data = b'abcdefghijklmnop' * 32 - await file_client.upload_range(data, 0, 511) + await file_client.upload_range(data, offset=0, length=512) # Assert content = await file_client.download_file() @@ -722,7 +722,7 @@ async def _test_update_range_with_md5_async(self): # Act data = b'abcdefghijklmnop' * 32 - await file_client.upload_range(data, 0, 511, validate_content=True) + await file_client.upload_range(data, offset=0, length=512, validate_content=True) # Assert @@ -748,7 +748,7 @@ async def _test_update_range_from_file_url_when_source_file_does_not_have_enough # Act with self.assertRaises(HttpResponseError): # when the source file has less bytes than 2050, throw exception - await destination_file_client.upload_range_from_url(source_file_url, 0, 2049, 0) + await destination_file_client.upload_range_from_url(source_file_url, offset=0, length=2050, source_offset=0) @record def test_update_range_from_file_url_when_source_file_does_not_have_enough_bytes_async(self): @@ -760,7 +760,7 @@ async def _test_update_range_from_file_url(self): source_file_name = 'testfile' source_file_client = await self._create_file(file_name=source_file_name) data = b'abcdefghijklmnop' * 32 - await source_file_client.upload_range(data, 0, 511) + await source_file_client.upload_range(data, offset=0, length=512) destination_file_name = 'filetoupdate' destination_file_client = await self._create_empty_file(file_name=destination_file_name) @@ -773,7 +773,7 @@ async def _test_update_range_from_file_url(self): source_file_url = source_file_client.url + '?' + sas_token_for_source_file # Act - await destination_file_client.upload_range_from_url(source_file_url, 0, 511, 0) + await destination_file_client.upload_range_from_url(source_file_url, offset=0, length=512, source_offset=0) # Assert # To make sure the range of the file is actually updated @@ -797,7 +797,7 @@ async def _test_update_big_range_from_file_url(self): source_file_client = await self._create_empty_file(file_name=source_file_name, file_size=1024 * 1024) data = b'abcdefghijklmnop' * 65536 - await source_file_client.upload_range(data, 0, end) + await source_file_client.upload_range(data, offset=0, length=end+1) destination_file_name = 'filetoupdate1' destination_file_client = await self._create_empty_file(file_name=destination_file_name, file_size=1024 * 1024) @@ -811,7 +811,7 @@ async def _test_update_big_range_from_file_url(self): source_file_url = source_file_client.url + '?' + sas_token_for_source_file # Act - await destination_file_client.upload_range_from_url(source_file_url, 0, end, 0) + await destination_file_client.upload_range_from_url(source_file_url, offset=0, length=end+1, source_offset=0) # Assert # To make sure the range of the file is actually updated @@ -833,7 +833,7 @@ async def _test_clear_range_async(self): file_client = await self._create_file() # Act - resp = await file_client.clear_range(0, 511) + resp = await file_client.clear_range(offset=0, length=512) # Assert content = await file_client.download_file() @@ -854,7 +854,7 @@ async def _test_update_file_unicode_async(self): # Act data = u'abcdefghijklmnop' * 32 - await file_client.upload_range(data, 0, 511) + await file_client.upload_range(data, offset=0, length=512) encoded = data.encode('utf-8') @@ -908,8 +908,8 @@ async def _test_list_ranges_2_async(self): await file_client.create_file(2048) data = b'abcdefghijklmnop' * 32 - resp1 = await file_client.upload_range(data, 0, 511) - resp2 = await file_client.upload_range(data, 1024, 1535) + resp1 = await file_client.upload_range(data, offset=0, length=512) + resp2 = await file_client.upload_range(data, offset=1024, length=512) # Act ranges = await file_client.get_ranges() @@ -974,8 +974,8 @@ async def _test_list_ranges_2_from_snapshot_async(self): transport=AiohttpTestTransport()) await file_client.create_file(2048) data = b'abcdefghijklmnop' * 32 - resp1 = await file_client.upload_range(data, 0, 511) - resp2 = await file_client.upload_range(data, 1024, 1535) + resp1 = await file_client.upload_range(data, offset=0, length=512) + resp2 = await file_client.upload_range(data, offset=1024, length=512) share_client = self.fsc.get_share_client(self.share_name) snapshot = await share_client.create_snapshot() From 37aa247daba22e7d46a8785f0faeddc7ea644dcb Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Wed, 16 Oct 2019 10:43:45 -0700 Subject: [PATCH 4/8] some more changes --- .../azure/storage/file/_shared/uploads.py | 5 +++-- .../azure/storage/file/_shared/uploads_async.py | 5 +++-- .../azure/storage/file/aio/file_client_async.py | 2 +- .../azure/storage/file/file_client.py | 2 +- sdk/storage/azure-storage-file/tests/test_file.py | 6 +++--- .../azure-storage-file/tests/test_file_async.py | 6 +++--- .../azure-storage-file/tests/test_get_file.py | 14 ++++++++------ .../tests/test_get_file_async.py | 14 ++++++++------ 8 files changed, 30 insertions(+), 24 deletions(-) diff --git a/sdk/storage/azure-storage-file/azure/storage/file/_shared/uploads.py b/sdk/storage/azure-storage-file/azure/storage/file/_shared/uploads.py index 6ed1f9084df5..2e6d62edd4ac 100644 --- a/sdk/storage/azure-storage-file/azure/storage/file/_shared/uploads.py +++ b/sdk/storage/azure-storage-file/azure/storage/file/_shared/uploads.py @@ -339,11 +339,12 @@ def _upload_chunk(self, chunk_offset, chunk_data): class FileChunkUploader(_ChunkUploader): # pylint: disable=abstract-method def _upload_chunk(self, chunk_offset, chunk_data): - chunk_end = chunk_offset + len(chunk_data) - 1 + length = len(chunk_data) + chunk_end = chunk_offset + length - 1 response = self.service.upload_range( chunk_data, chunk_offset, - chunk_end, + length, data_stream_total=self.total_size, upload_stream_current=self.progress_total, **self.request_options diff --git a/sdk/storage/azure-storage-file/azure/storage/file/_shared/uploads_async.py b/sdk/storage/azure-storage-file/azure/storage/file/_shared/uploads_async.py index 92fcab5ef5f0..0b4611297614 100644 --- a/sdk/storage/azure-storage-file/azure/storage/file/_shared/uploads_async.py +++ b/sdk/storage/azure-storage-file/azure/storage/file/_shared/uploads_async.py @@ -337,11 +337,12 @@ async def _upload_chunk(self, chunk_offset, chunk_data): class FileChunkUploader(_ChunkUploader): # pylint: disable=abstract-method async def _upload_chunk(self, chunk_offset, chunk_data): - chunk_end = chunk_offset + len(chunk_data) - 1 + length = len(chunk_data) + chunk_end = chunk_offset + length - 1 response = await self.service.upload_range( chunk_data, chunk_offset, - chunk_end, + length, data_stream_total=self.total_size, upload_stream_current=self.progress_total, **self.request_options diff --git a/sdk/storage/azure-storage-file/azure/storage/file/aio/file_client_async.py b/sdk/storage/azure-storage-file/azure/storage/file/aio/file_client_async.py index 55290a0ab80f..bf641ab31d22 100644 --- a/sdk/storage/azure-storage-file/azure/storage/file/aio/file_client_async.py +++ b/sdk/storage/azure-storage-file/azure/storage/file/aio/file_client_async.py @@ -668,7 +668,7 @@ async def upload_range( # type: ignore if isinstance(data, six.text_type): data = data.encode(encoding) end_range = offset + length - 1 # Reformat to an inclusive range index - content_range = "bytes={0}-{1}".format(offset, end_range) + content_range = 'bytes={0}-{1}'.format(offset, end_range) try: return await self._client.file.upload_range( # type: ignore range=content_range, diff --git a/sdk/storage/azure-storage-file/azure/storage/file/file_client.py b/sdk/storage/azure-storage-file/azure/storage/file/file_client.py index e93de9d7247b..ff8f8c70a53e 100644 --- a/sdk/storage/azure-storage-file/azure/storage/file/file_client.py +++ b/sdk/storage/azure-storage-file/azure/storage/file/file_client.py @@ -208,7 +208,7 @@ def from_file_url( path_snapshot, _ = parse_query(parsed_url.query) snapshot = snapshot or path_snapshot share_name = unquote(path_share) - file_path = [unquote(p) for p in path_file.split('/')] + file_path = '/'.join([unquote(p) for p in path_file.split('/')]) return cls(account_url, share_name, file_path, snapshot, credential, **kwargs) def _format_url(self, hostname): diff --git a/sdk/storage/azure-storage-file/tests/test_file.py b/sdk/storage/azure-storage-file/tests/test_file.py index e69e623e9a50..8325a4fd7cfc 100644 --- a/sdk/storage/azure-storage-file/tests/test_file.py +++ b/sdk/storage/azure-storage-file/tests/test_file.py @@ -263,7 +263,7 @@ def test_create_file_with_metadata(self): def test_create_file_when_file_permission_is_too_long(self): file_client = self._get_file_client() - permission = str(self.get_random_bytes(8 * 1024 + 1)) + permission = str(self.get_random_bytes(8 * 1024)) with self.assertRaises(ValueError): file_client.create_file(1024, file_permission=permission) @@ -664,7 +664,7 @@ def test_update_big_range_from_file_url(self): # Assert # To make sure the range of the file is actually updated file_ranges = destination_file_client.get_ranges() - file_content = destination_file_client.download_file(offset=0, length=end).content_as_bytes() + file_content = destination_file_client.download_file(offset=0, length=end+1).content_as_bytes() self.assertEquals(1, len(file_ranges)) self.assertEquals(0, file_ranges[0].get('start')) self.assertEquals(end, file_ranges[0].get('end')) @@ -1439,7 +1439,7 @@ def test_sas_signed_identifier(self): token = file_client.generate_shared_access_signature(policy_id='testid') # Act - sas_file = FileClient( + sas_file = FileClient.from_file_url( file_client.url, credential=token) diff --git a/sdk/storage/azure-storage-file/tests/test_file_async.py b/sdk/storage/azure-storage-file/tests/test_file_async.py index 409357b5586b..c48664a90c86 100644 --- a/sdk/storage/azure-storage-file/tests/test_file_async.py +++ b/sdk/storage/azure-storage-file/tests/test_file_async.py @@ -778,7 +778,7 @@ async def _test_update_range_from_file_url(self): # Assert # To make sure the range of the file is actually updated file_ranges = await destination_file_client.get_ranges() - file_content = await destination_file_client.download_file(offset=0, length=511) + file_content = await destination_file_client.download_file(offset=0, length=512) file_content = await file_content.content_as_bytes() self.assertEquals(1, len(file_ranges)) self.assertEquals(0, file_ranges[0].get('start')) @@ -816,7 +816,7 @@ async def _test_update_big_range_from_file_url(self): # Assert # To make sure the range of the file is actually updated file_ranges = await destination_file_client.get_ranges() - file_content = await destination_file_client.download_file(offset=0, length=end) + file_content = await destination_file_client.download_file(offset=0, length=end+1) file_content = await file_content.content_as_bytes() self.assertEquals(1, len(file_ranges)) self.assertEquals(0, file_ranges[0].get('start')) @@ -1774,7 +1774,7 @@ async def _test_sas_signed_identifier_async(self): token = file_client.generate_shared_access_signature(policy_id='testid') # Act - sas_file = FileClient( + sas_file = FileClient.from_file_url( file_client.url, credential=token) diff --git a/sdk/storage/azure-storage-file/tests/test_get_file.py b/sdk/storage/azure-storage-file/tests/test_get_file.py index 1a82fe868408..e0b4d714a96e 100644 --- a/sdk/storage/azure-storage-file/tests/test_get_file.py +++ b/sdk/storage/azure-storage-file/tests/test_get_file.py @@ -654,7 +654,7 @@ def test_ranged_get_file_to_path_with_single_byte(self): # Act end_range = self.MAX_SINGLE_GET_SIZE + 1024 with open(FILE_PATH, 'wb') as stream: - props = file_client.download_file(offset=0, length=0).download_to_stream(stream) + props = file_client.download_file(offset=0, length=1).download_to_stream(stream) # Assert self.assertIsInstance(props, FileProperties) @@ -711,7 +711,7 @@ def callback(response): end_range = self.MAX_SINGLE_GET_SIZE + 1024 with open(FILE_PATH, 'wb') as stream: props = file_client.download_file( - offset=start_range, length=end_range, raw_response_hook=callback).download_to_stream( + offset=start_range, length=end_range-start_range+1, raw_response_hook=callback).download_to_stream( stream, max_concurrency=2) # Assert @@ -789,16 +789,17 @@ def test_ranged_get_file_to_path_invalid_range_parallel(self): file_client.upload_file(file_data) # Act + start = 3 end_range = 2 * self.MAX_SINGLE_GET_SIZE with open(FILE_PATH, 'wb') as stream: props = file_client.download_file( - offset=1, length=end_range).download_to_stream(stream, max_concurrency=2) + offset=start, length=end_range-start+1).download_to_stream(stream, max_concurrency=2) # Assert self.assertIsInstance(props, FileProperties) with open(FILE_PATH, 'rb') as stream: actual = stream.read() - self.assertEqual(file_data[1:file_size], actual) + self.assertEqual(file_data[start:file_size], actual) @record def test_ranged_get_file_to_path_invalid_range_non_parallel(self): @@ -817,16 +818,17 @@ def test_ranged_get_file_to_path_invalid_range_non_parallel(self): file_client.upload_file(file_data) # Act + start = 3 end_range = 2 * self.MAX_SINGLE_GET_SIZE with open(FILE_PATH, 'wb') as stream: props = file_client.download_file( - offset=1, length=end_range).download_to_stream(stream, max_concurrency=1) + offset=start, length=end_range-start+1).download_to_stream(stream, max_concurrency=1) # Assert self.assertIsInstance(props, FileProperties) with open(FILE_PATH, 'rb') as stream: actual = stream.read() - self.assertEqual(file_data[1:file_size], actual) + self.assertEqual(file_data[start:file_size], actual) def test_get_file_to_text(self): # parallel tests introduce random order of requests, can only run live diff --git a/sdk/storage/azure-storage-file/tests/test_get_file_async.py b/sdk/storage/azure-storage-file/tests/test_get_file_async.py index 515b0171be87..d35336c1fc86 100644 --- a/sdk/storage/azure-storage-file/tests/test_get_file_async.py +++ b/sdk/storage/azure-storage-file/tests/test_get_file_async.py @@ -745,16 +745,17 @@ async def _test_ranged_get_file_to_path_async(self): max_chunk_get_size=self.MAX_CHUNK_GET_SIZE) # Act + start = 4 end_range = self.MAX_SINGLE_GET_SIZE + 1024 with open(FILE_PATH, 'wb') as stream: - props = await file_client.download_file(offset=1, length=end_range) + props = await file_client.download_file(offset=start, length=end_range-start+1) props = await props.download_to_stream(stream, max_concurrency=2) # Assert self.assertIsInstance(props, FileProperties) with open(FILE_PATH, 'rb') as stream: actual = stream.read() - self.assertEqual(self.byte_data[1:end_range + 1], actual) + self.assertEqual(self.byte_data[start:end_range + 1], actual) @record def test_ranged_get_file_to_path_async(self): @@ -779,7 +780,7 @@ async def _test_ranged_get_file_to_path_with_single_byte_async(self): # Act end_range = self.MAX_SINGLE_GET_SIZE + 1024 with open(FILE_PATH, 'wb') as stream: - props = await file_client.download_file(offset=0, length=0) + props = await file_client.download_file(offset=0, length=1) props = await props.download_to_stream(stream) # Assert @@ -850,7 +851,7 @@ def callback(response): start_range = 3 end_range = self.MAX_SINGLE_GET_SIZE + 1024 with open(FILE_PATH, 'wb') as stream: - props = await file_client.download_file(offset=start_range, length=end_range, raw_response_hook=callback) + props = await file_client.download_file(offset=start_range, length=end_range-start_range+1, raw_response_hook=callback) props = await props.download_to_stream(stream, max_concurrency=2) # Assert @@ -976,16 +977,17 @@ async def _test_ranged_get_file_to_path_invalid_range_non_parallel_async(self): await file_client.upload_file(file_data) # Act + start = 4 end_range = 2 * self.MAX_SINGLE_GET_SIZE with open(FILE_PATH, 'wb') as stream: - props = await file_client.download_file(offset=1, length=end_range) + props = await file_client.download_file(offset=start, length=end_range-start+1) props = await props.download_to_stream(stream, max_concurrency=1) # Assert self.assertIsInstance(props, FileProperties) with open(FILE_PATH, 'rb') as stream: actual = stream.read() - self.assertEqual(file_data[1:file_size], actual) + self.assertEqual(file_data[start:file_size], actual) @record def test_ranged_get_file_to_path_invalid_range_non_parallel_async(self): From 5d4db545e37dbb31fc89ebf9f6bffd9fa0c948cd Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Wed, 16 Oct 2019 11:06:37 -0700 Subject: [PATCH 5/8] history.md --- sdk/storage/azure-storage-file/HISTORY.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/sdk/storage/azure-storage-file/HISTORY.md b/sdk/storage/azure-storage-file/HISTORY.md index 4887eb95b418..1a2f24c99adc 100644 --- a/sdk/storage/azure-storage-file/HISTORY.md +++ b/sdk/storage/azure-storage-file/HISTORY.md @@ -13,15 +13,20 @@ To use a directory_url, the method `from_directory_url` must be used. - `file_permission_key` parameter has been renamed to `permission_key` - `set_share_access_policy` has required parameter `signed_identifiers`. - NoRetry policy has been removed. Use keyword argument `retry_total=0` for no retries. -- Removed types that were accidentally exposed from two modules. Only `FileServiceClient`, `ShareClient`, -`DirectoryClient` and `FileClient` should be imported from azure.storage.file.aio +- Removed types that were accidentally exposed from two modules. Only `FileServiceClient`, `ShareClient`, `DirectoryClient` and `FileClient` should be imported from azure.storage.file.aio - NoRetry policy has been removed. Use keyword argument `retry_total=0` for no retries. - Some parameters have become keyword only, rather than positional. Some examples include: - `loop` - `max_concurrency` - `validate_content` - `timeout` etc. - +- `start_range` and `end_range` params are now renamed to and behave like`offset` and `length` in +the following APIs: + - download_file + - upload_range + - upload_range_from_url + - clear_range + - get_ranges **New features** From 2c17e8c910a456b9d3eb4c2919c2a20738088b94 Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Wed, 16 Oct 2019 13:37:10 -0700 Subject: [PATCH 6/8] Update a couple of recrodings --- ...le_to_path_invalid_range_non_parallel.yaml | 112 +++++----- ...path_invalid_range_non_parallel_async.yaml | 203 +++++++++--------- 2 files changed, 156 insertions(+), 159 deletions(-) diff --git a/sdk/storage/azure-storage-file/tests/recordings/test_get_file.test_ranged_get_file_to_path_invalid_range_non_parallel.yaml b/sdk/storage/azure-storage-file/tests/recordings/test_get_file.test_ranged_get_file_to_path_invalid_range_non_parallel.yaml index 31e311874d60..95327bc8d511 100644 --- a/sdk/storage/azure-storage-file/tests/recordings/test_get_file.test_ranged_get_file_to_path_invalid_range_non_parallel.yaml +++ b/sdk/storage/azure-storage-file/tests/recordings/test_get_file.test_ranged_get_file_to_path_invalid_range_non_parallel.yaml @@ -11,15 +11,13 @@ interactions: Content-Length: - '0' User-Agent: - - azsdk-python-storage-file/12.0.0b3 Python/3.7.3 (Windows-10-10.0.18362-SP0) - content-type: - - application/xml; charset=utf-8 + - azsdk-python-storage-file/12.0.0b4 Python/3.7.3 (Windows-10-10.0.17763-SP0) x-ms-client-request-id: - - 6c5f59a4-d9a9-11e9-8bbf-001a7dda7113 + - adba5c66-f054-11e9-9742-2816a845e8c6 x-ms-content-length: - '1024' x-ms-date: - - Wed, 18 Sep 2019 00:15:30 GMT + - Wed, 16 Oct 2019 20:36:49 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -41,29 +39,29 @@ interactions: Content-Length: - '0' Date: - - Wed, 18 Sep 2019 00:15:29 GMT + - Wed, 16 Oct 2019 20:36:48 GMT ETag: - - '"0x8D73BCD5098930D"' + - '"0x8D7527891817A96"' Last-Modified: - - Wed, 18 Sep 2019 00:15:30 GMT + - Wed, 16 Oct 2019 20:36:48 GMT Server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: - Archive x-ms-file-change-time: - - '2019-09-18T00:15:30.2725389Z' + - '2019-10-16T20:36:48.6949526Z' x-ms-file-creation-time: - - '2019-09-18T00:15:30.2725389Z' + - '2019-10-16T20:36:48.6949526Z' x-ms-file-id: - '13835163608398430208' x-ms-file-last-write-time: - - '2019-09-18T00:15:30.2725389Z' + - '2019-10-16T20:36:48.6949526Z' x-ms-file-parent-id: - '13835128424026341376' x-ms-file-permission-key: - - 4099112195243312672*10394889115079208622 + - 3501246319223038625*10967959146200238639 x-ms-request-id: - - c3492641-701a-00d9-16b6-6d2b71000000 + - 43d5c2e6-d01a-0003-1a61-846707000000 x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -103,11 +101,11 @@ interactions: Content-Type: - application/octet-stream User-Agent: - - azsdk-python-storage-file/12.0.0b3 Python/3.7.3 (Windows-10-10.0.18362-SP0) + - azsdk-python-storage-file/12.0.0b4 Python/3.7.3 (Windows-10-10.0.17763-SP0) x-ms-client-request-id: - - 6c7431d8-d9a9-11e9-b7f8-001a7dda7113 + - adf82612-f054-11e9-9c7f-2816a845e8c6 x-ms-date: - - Wed, 18 Sep 2019 00:15:30 GMT + - Wed, 16 Oct 2019 20:36:49 GMT x-ms-range: - bytes=0-1023 x-ms-version: @@ -125,15 +123,15 @@ interactions: Content-MD5: - w4K7XcRVEiqgHdQNiSA8bw== Date: - - Wed, 18 Sep 2019 00:15:29 GMT + - Wed, 16 Oct 2019 20:36:48 GMT ETag: - - '"0x8D73BCD509F728A"' + - '"0x8D75278918F5FC7"' Last-Modified: - - Wed, 18 Sep 2019 00:15:30 GMT + - Wed, 16 Oct 2019 20:36:48 GMT Server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-request-id: - - c3492646-701a-00d9-1ab6-6d2b71000000 + - 43d5c2e8-d01a-0003-1b61-846707000000 x-ms-request-server-encrypted: - 'true' x-ms-version: @@ -151,15 +149,13 @@ interactions: Connection: - keep-alive User-Agent: - - azsdk-python-storage-file/12.0.0b3 Python/3.7.3 (Windows-10-10.0.18362-SP0) - content-type: - - application/xml; charset=utf-8 + - azsdk-python-storage-file/12.0.0b4 Python/3.7.3 (Windows-10-10.0.17763-SP0) x-ms-client-request-id: - - 6c7b31ee-d9a9-11e9-a545-001a7dda7113 + - ae05ff38-f054-11e9-8bf8-2816a845e8c6 x-ms-date: - - Wed, 18 Sep 2019 00:15:30 GMT + - Wed, 16 Oct 2019 20:36:49 GMT x-ms-range: - - bytes=1-32768 + - bytes=3-32770 x-ms-version: - '2019-02-02' method: GET @@ -167,57 +163,63 @@ interactions: response: body: string: !!binary | - XojBnSm+iwnRwCI7fnpt9W5qYhsAuFBm5I2u6AN8TCepFnzaAC77Q/hC5Bfaf0pqU0lvVYlL0sRT - vRYz07+v5xcAYtbULg5kMNe2DbqsDD3qhHGaajvX+Bdx7ZRa9PoNnkevtCU8WwhOY+NJijHIA7ig - Ka+e1F19MjB7JnapFn3j132rB/DSxS4ZTYYcME2PQtE2R3S/Qabi1d8cZFy8/UHcHJeh8zxtb8nm - +T7z1+/N/PEM81nkLWkSVf1t74aw1wl5yYmKF0xNcDsq1QP6oXCQpi6H4zK6gUHwmQXbVboPJLcv - 92l+jz1sOvmledO0VqodgLkzbG89ohndYItzENzrKizyQBLA2C1nQFdZCXKyEaqmGvm+L9JHwauU - fWO7G1tXboLcjn8643SBkwnsi50ruFiQWiwzR07fl6SpENvf8jmqIcqSSdug6++dhVqXmyHtqLbk - 6jrSzjP657xmQP5+SqRDABc5DKMt4HsM6/0Km7u5pElZiA9nS92RQTTjoEcFathcuWjmUsB5UWOn - VvT0wH6TGCfDHdsJtpmpAVegz8aFw2bFDYX4a+HIINJ26RfATzaaSTOA3qJfqn0I/u4s4YMTGvOY - LTdLWQI/Vi2D2eJKZRCksI0EiI/xL9ShGh/wYJAQ8xtw8lX3D6600rtixDCPuM3UpPgN/EEUdCex - rz4GtJ+TEBaQgxgZibDmym/d7XXLUjPoRVtPF+EDm21JyT/jtWsUXrvYebXleg/PEQS2kstwcidF - mTk4ujMqfj+P7MGR34G+jHSf/renyo+AyxoVQ7I9qLBhFO0UdAZpr/Z8c0xyxo/lfdzo6jKvWTf7 - cir2eDe0Xzia/vK+vVRRIV0dt0C+K7ZsnqP+5Jx/Mh+i5h2PBApOEbLNKvkaAL4xc/zpsYSIh7E1 - O4rFwfOHWiIuDNv+voTUqsT0FyfXtXKmUouaeN4yb/UqTUW6JMXmmo9F5Vt51DMVv6PHZRTbOtuJ - uoObEJPTSxWhgFBX2SkZ3MUcLT7yG86FK1q7JFXsuXY0tvTRrpGSaBr33GdjV91OMRuDLPjL2JO0 - Pja6QOXBlvOqpOEvI5pyG2oa1hyKWaN/IP7baWEZ31JiRRcuEHkYFSe2O3nB9F+2sbAcu/jGEVR+ - Ou32SCYW8xu5YupRZIfeNIZRUBvMuI8du/5cqeqgTi/smEByBrwouDaduuSJABmh1Fja0pq2JC9g - pnE2Pn68qCivtQRFJu5NMjEl67TSVazaigLA5gS4Y4Njmv7RVnOju7q4FcCenCDjB94vr+ZeMQPq - eQTBUFzEDyWIJ/Nd74O3V9JLUhYuyGt/tUPQ/LQ9jOC24g1cwC03L1ezookeoKODZ3jN3Tb3 + wZ0pvosJ0cAiO356bfVuamIbALhQZuSNrugDfEwnqRZ82gAu+0P4QuQX2n9KalNJb1WJS9LEU70W + M9O/r+cXAGLW1C4OZDDXtg26rAw96oRxmmo71/gXce2UWvT6DZ5Hr7QlPFsITmPjSYoxyAO4oCmv + ntRdfTIweyZ2qRZ949d9qwfw0sUuGU2GHDBNj0LRNkd0v0Gm4tXfHGRcvP1B3ByXofM8bW/J5vk+ + 89fvzfzxDPNZ5C1pElX9be+GsNcJecmJihdMTXA7KtUD+qFwkKYuh+MyuoFB8JkF21W6DyS3L/dp + fo89bDr5pXnTtFaqHYC5M2xvPaIZ3WCLcxDc6yos8kASwNgtZ0BXWQlyshGqphr5vi/SR8GrlH1j + uxtbV26C3I5/OuN0gZMJ7IudK7hYkFosM0dO35ekqRDb3/I5qiHKkknboOvvnYVal5sh7ai25Oo6 + 0s4z+ue8ZkD+fkqkQwAXOQyjLeB7DOv9Cpu7uaRJWYgPZ0vdkUE046BHBWrYXLlo5lLAeVFjp1b0 + 9MB+kxgnwx3bCbaZqQFXoM/GhcNmxQ2F+GvhyCDSdukXwE82mkkzgN6iX6p9CP7uLOGDExrzmC03 + S1kCP1Ytg9niSmUQpLCNBIiP8S/UoRof8GCQEPMbcPJV9w+utNK7YsQwj7jN1KT4DfxBFHQnsa8+ + BrSfkxAWkIMYGYmw5spv3e11y1Iz6EVbTxfhA5ttSck/47VrFF672Hm15XoPzxEEtpLLcHInRZk5 + OLozKn4/j+zBkd+Bvox0n/63p8qPgMsaFUOyPaiwYRTtFHQGaa/2fHNMcsaP5X3c6Ooyr1k3+3Iq + 9ng3tF84mv7yvr1UUSFdHbdAviu2bJ6j/uScfzIfouYdjwQKThGyzSr5GgC+MXP86bGEiIexNTuK + xcHzh1oiLgzb/r6E1KrE9Bcn17VyplKLmnjeMm/1Kk1FuiTF5pqPReVbedQzFb+jx2UU2zrbibqD + mxCT00sVoYBQV9kpGdzFHC0+8hvOhStauyRV7Ll2NLb00a6Rkmga99xnY1fdTjEbgyz4y9iTtD42 + ukDlwZbzqqThLyOachtqGtYcilmjfyD+22lhGd9SYkUXLhB5GBUntjt5wfRftrGwHLv4xhFUfjrt + 9kgmFvMbuWLqUWSH3jSGUVAbzLiPHbv+XKnqoE4v7JhAcga8KLg2nbrkiQAZodRY2tKatiQvYKZx + Nj5+vKgor7UERSbuTTIxJeu00lWs2ooCwOYEuGODY5r+0VZzo7u6uBXAnpwg4wfeL6/mXjED6nkE + wVBcxA8liCfzXe+Dt1fSS1IWLshrf7VD0Py0PYzgtuINXMAtNy9Xs6KJHqCjg2d4zd029w== headers: Accept-Ranges: - bytes Content-Length: - - '1023' + - '1021' Content-Range: - - bytes 1-1023/1024 + - bytes 3-1023/1024 Content-Type: - - application/xml; charset=utf-8 + - application/octet-stream Date: - - Wed, 18 Sep 2019 00:15:29 GMT + - Wed, 16 Oct 2019 20:36:48 GMT ETag: - - '"0x8D73BCD509F728A"' + - '"0x8D75278918F5FC7"' Last-Modified: - - Wed, 18 Sep 2019 00:15:30 GMT + - Wed, 16 Oct 2019 20:36:48 GMT Server: - Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + Vary: + - Origin x-ms-file-attributes: - Archive x-ms-file-change-time: - - '2019-09-18T00:15:30.2725389Z' + - '2019-10-16T20:36:48.6949526Z' x-ms-file-creation-time: - - '2019-09-18T00:15:30.2725389Z' + - '2019-10-16T20:36:48.6949526Z' x-ms-file-id: - '13835163608398430208' x-ms-file-last-write-time: - - '2019-09-18T00:15:30.2725389Z' + - '2019-10-16T20:36:48.6949526Z' x-ms-file-parent-id: - '13835128424026341376' x-ms-file-permission-key: - - 4099112195243312672*10394889115079208622 + - 3501246319223038625*10967959146200238639 + x-ms-lease-state: + - available + x-ms-lease-status: + - unlocked x-ms-request-id: - - c3492648-701a-00d9-1cb6-6d2b71000000 + - 43d5c2e9-d01a-0003-1c61-846707000000 x-ms-server-encrypted: - 'true' x-ms-type: diff --git a/sdk/storage/azure-storage-file/tests/recordings/test_get_file_async.test_ranged_get_file_to_path_invalid_range_non_parallel_async.yaml b/sdk/storage/azure-storage-file/tests/recordings/test_get_file_async.test_ranged_get_file_to_path_invalid_range_non_parallel_async.yaml index 7303d5fe0104..781ae8692640 100644 --- a/sdk/storage/azure-storage-file/tests/recordings/test_get_file_async.test_ranged_get_file_to_path_invalid_range_non_parallel_async.yaml +++ b/sdk/storage/azure-storage-file/tests/recordings/test_get_file_async.test_ranged_get_file_to_path_invalid_range_non_parallel_async.yaml @@ -3,13 +3,11 @@ interactions: body: null headers: User-Agent: - - azsdk-python-storage-file/12.0.0b3 Python/3.7.3 (Windows-10-10.0.18362-SP0) - content-type: - - application/xml; charset=utf-8 + - azsdk-python-storage-file/12.0.0b4 Python/3.7.3 (Windows-10-10.0.17763-SP0) x-ms-client-request-id: - - 7ed0f4fa-d9a9-11e9-bca9-001a7dda7113 + - ae326dae-f054-11e9-9a3a-2816a845e8c6 x-ms-date: - - Wed, 18 Sep 2019 00:16:01 GMT + - Wed, 16 Oct 2019 20:36:50 GMT x-ms-version: - '2019-02-02' method: PUT @@ -23,17 +21,17 @@ interactions: : '0' ? !!python/object/new:multidict._istr.istr - Date - : Wed, 18 Sep 2019 00:16:00 GMT + : Wed, 16 Oct 2019 20:36:50 GMT ? !!python/object/new:multidict._istr.istr - Etag - : '"0x8D73BCD62FCBA28"' + : '"0x8D7527892489102"' ? !!python/object/new:multidict._istr.istr - Last-Modified - : Wed, 18 Sep 2019 00:16:01 GMT + : Wed, 16 Oct 2019 20:36:49 GMT ? !!python/object/new:multidict._istr.istr - Server : Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 - x-ms-request-id: 81c5ad43-a01a-0073-69b6-6d0b67000000 + x-ms-request-id: ed75c1ed-301a-0009-2f61-847e8e000000 x-ms-version: '2019-02-02' status: code: 201 @@ -42,7 +40,7 @@ interactions: state: !!python/tuple - !!python/object/new:urllib.parse.SplitResult - https - - emilydevtest.file.core.windows.net + - amqptest.file.core.windows.net - /utshare48a0210b - restype=share - '' @@ -50,13 +48,11 @@ interactions: body: null headers: User-Agent: - - azsdk-python-storage-file/12.0.0b3 Python/3.7.3 (Windows-10-10.0.18362-SP0) - content-type: - - application/xml; charset=utf-8 + - azsdk-python-storage-file/12.0.0b4 Python/3.7.3 (Windows-10-10.0.17763-SP0) x-ms-client-request-id: - - 7edb5678-d9a9-11e9-a113-001a7dda7113 + - aecbacc2-f054-11e9-9e7c-2816a845e8c6 x-ms-date: - - Wed, 18 Sep 2019 00:16:01 GMT + - Wed, 16 Oct 2019 20:36:51 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -78,24 +74,24 @@ interactions: : '0' ? !!python/object/new:multidict._istr.istr - Date - : Wed, 18 Sep 2019 00:16:01 GMT + : Wed, 16 Oct 2019 20:36:50 GMT ? !!python/object/new:multidict._istr.istr - Etag - : '"0x8D73BCD630322D1"' + : '"0x8D75278926B8F45"' ? !!python/object/new:multidict._istr.istr - Last-Modified - : Wed, 18 Sep 2019 00:16:01 GMT + : Wed, 16 Oct 2019 20:36:50 GMT ? !!python/object/new:multidict._istr.istr - Server : Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: Directory - x-ms-file-change-time: '2019-09-18T00:16:01.1698897Z' - x-ms-file-creation-time: '2019-09-18T00:16:01.1698897Z' + x-ms-file-change-time: '2019-10-16T20:36:50.2290245Z' + x-ms-file-creation-time: '2019-10-16T20:36:50.2290245Z' x-ms-file-id: '13835128424026341376' - x-ms-file-last-write-time: '2019-09-18T00:16:01.1698897Z' + x-ms-file-last-write-time: '2019-10-16T20:36:50.2290245Z' x-ms-file-parent-id: '0' - x-ms-file-permission-key: 17913408918638655783*10394889115079208622 - x-ms-request-id: 81c5ad46-a01a-0073-6ab6-6d0b67000000 + x-ms-file-permission-key: 17360570244679638438*10967959146200238639 + x-ms-request-id: ed75c1f2-301a-0009-3061-847e8e000000 x-ms-request-server-encrypted: 'true' x-ms-version: '2019-02-02' status: @@ -105,7 +101,7 @@ interactions: state: !!python/tuple - !!python/object/new:urllib.parse.SplitResult - https - - emilydevtest.file.core.windows.net + - amqptest.file.core.windows.net - /utshare48a0210b/utdir48a0210b - restype=directory - '' @@ -113,15 +109,13 @@ interactions: body: null headers: User-Agent: - - azsdk-python-storage-file/12.0.0b3 Python/3.7.3 (Windows-10-10.0.18362-SP0) - content-type: - - application/xml; charset=utf-8 + - azsdk-python-storage-file/12.0.0b4 Python/3.7.3 (Windows-10-10.0.17763-SP0) x-ms-client-request-id: - - 7ee3bf66-d9a9-11e9-b261-001a7dda7113 + - aeed775e-f054-11e9-b3d8-2816a845e8c6 x-ms-content-length: - '65541' x-ms-date: - - Wed, 18 Sep 2019 00:16:01 GMT + - Wed, 16 Oct 2019 20:36:51 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -145,24 +139,24 @@ interactions: : '0' ? !!python/object/new:multidict._istr.istr - Date - : Wed, 18 Sep 2019 00:16:00 GMT + : Wed, 16 Oct 2019 20:36:49 GMT ? !!python/object/new:multidict._istr.istr - Etag - : '"0x8D73BCD6318ABE4"' + : '"0x8D752789293429F"' ? !!python/object/new:multidict._istr.istr - Last-Modified - : Wed, 18 Sep 2019 00:16:01 GMT + : Wed, 16 Oct 2019 20:36:50 GMT ? !!python/object/new:multidict._istr.istr - Server : Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: Archive - x-ms-file-change-time: '2019-09-18T00:16:01.3110244Z' - x-ms-file-creation-time: '2019-09-18T00:16:01.3110244Z' + x-ms-file-change-time: '2019-10-16T20:36:50.4892063Z' + x-ms-file-creation-time: '2019-10-16T20:36:50.4892063Z' x-ms-file-id: '13835093239654252544' - x-ms-file-last-write-time: '2019-09-18T00:16:01.3110244Z' + x-ms-file-last-write-time: '2019-10-16T20:36:50.4892063Z' x-ms-file-parent-id: '13835128424026341376' - x-ms-file-permission-key: 4099112195243312672*10394889115079208622 - x-ms-request-id: 814afbe0-501a-0058-4bb6-6d8bab000000 + x-ms-file-permission-key: 3501246319223038625*10967959146200238639 + x-ms-request-id: 94d6f91d-f01a-001f-7961-84bf10000000 x-ms-request-server-encrypted: 'true' x-ms-version: '2019-02-02' status: @@ -172,7 +166,7 @@ interactions: state: !!python/tuple - !!python/object/new:urllib.parse.SplitResult - https - - emilydevtest.file.core.windows.net + - amqptest.file.core.windows.net - /utshare48a0210b/utdir48a0210b/bytefile48a0210b - '' - '' @@ -1334,11 +1328,11 @@ interactions: Content-Type: - application/octet-stream User-Agent: - - azsdk-python-storage-file/12.0.0b3 Python/3.7.3 (Windows-10-10.0.18362-SP0) + - azsdk-python-storage-file/12.0.0b4 Python/3.7.3 (Windows-10-10.0.17763-SP0) x-ms-client-request-id: - - 7ef51efe-d9a9-11e9-9e0a-001a7dda7113 + - af0a8674-f054-11e9-83ee-2816a845e8c6 x-ms-date: - - Wed, 18 Sep 2019 00:16:01 GMT + - Wed, 16 Oct 2019 20:36:51 GMT x-ms-range: - bytes=0-65540 x-ms-version: @@ -1359,17 +1353,17 @@ interactions: : VDslmd4PxCb6sl/qFeIHNw== ? !!python/object/new:multidict._istr.istr - Date - : Wed, 18 Sep 2019 00:16:01 GMT + : Wed, 16 Oct 2019 20:36:49 GMT ? !!python/object/new:multidict._istr.istr - Etag - : '"0x8D73BCD632000AD"' + : '"0x8D7527892A85504"' ? !!python/object/new:multidict._istr.istr - Last-Modified - : Wed, 18 Sep 2019 00:16:01 GMT + : Wed, 16 Oct 2019 20:36:50 GMT ? !!python/object/new:multidict._istr.istr - Server : Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 - x-ms-request-id: 814afbe1-501a-0058-4cb6-6d8bab000000 + x-ms-request-id: 94d6f920-f01a-001f-7a61-84bf10000000 x-ms-request-server-encrypted: 'true' x-ms-version: '2019-02-02' status: @@ -1379,7 +1373,7 @@ interactions: state: !!python/tuple - !!python/object/new:urllib.parse.SplitResult - https - - emilydevtest.file.core.windows.net + - amqptest.file.core.windows.net - /utshare48a0210b/utdir48a0210b/bytefile48a0210b - comp=range - '' @@ -1387,15 +1381,13 @@ interactions: body: null headers: User-Agent: - - azsdk-python-storage-file/12.0.0b3 Python/3.7.3 (Windows-10-10.0.18362-SP0) - content-type: - - application/xml; charset=utf-8 + - azsdk-python-storage-file/12.0.0b4 Python/3.7.3 (Windows-10-10.0.17763-SP0) x-ms-client-request-id: - - 7f08c164-d9a9-11e9-beb8-001a7dda7113 + - af21f610-f054-11e9-af2c-2816a845e8c6 x-ms-content-length: - '1024' x-ms-date: - - Wed, 18 Sep 2019 00:16:01 GMT + - Wed, 16 Oct 2019 20:36:51 GMT x-ms-file-attributes: - none x-ms-file-creation-time: @@ -1419,24 +1411,24 @@ interactions: : '0' ? !!python/object/new:multidict._istr.istr - Date - : Wed, 18 Sep 2019 00:16:00 GMT + : Wed, 16 Oct 2019 20:36:49 GMT ? !!python/object/new:multidict._istr.istr - Etag - : '"0x8D73BCD633562A2"' + : '"0x8D7527892C817B2"' ? !!python/object/new:multidict._istr.istr - Last-Modified - : Wed, 18 Sep 2019 00:16:01 GMT + : Wed, 16 Oct 2019 20:36:50 GMT ? !!python/object/new:multidict._istr.istr - Server : Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 x-ms-file-attributes: Archive - x-ms-file-change-time: '2019-09-18T00:16:01.4992034Z' - x-ms-file-creation-time: '2019-09-18T00:16:01.4992034Z' + x-ms-file-change-time: '2019-10-16T20:36:50.8354482Z' + x-ms-file-creation-time: '2019-10-16T20:36:50.8354482Z' x-ms-file-id: '13835163608398430208' - x-ms-file-last-write-time: '2019-09-18T00:16:01.4992034Z' + x-ms-file-last-write-time: '2019-10-16T20:36:50.8354482Z' x-ms-file-parent-id: '13835128424026341376' - x-ms-file-permission-key: 4099112195243312672*10394889115079208622 - x-ms-request-id: d6a5a6fb-501a-00e1-70b6-6d8fb1000000 + x-ms-file-permission-key: 3501246319223038625*10967959146200238639 + x-ms-request-id: b4c21ebd-b01a-005c-6461-8495f9000000 x-ms-request-server-encrypted: 'true' x-ms-version: '2019-02-02' status: @@ -1446,7 +1438,7 @@ interactions: state: !!python/tuple - !!python/object/new:urllib.parse.SplitResult - https - - emilydevtest.file.core.windows.net + - amqptest.file.core.windows.net - /utshare48a0210b/utdir48a0210b/file48a0210b - '' - '' @@ -1476,11 +1468,11 @@ interactions: Content-Type: - application/octet-stream User-Agent: - - azsdk-python-storage-file/12.0.0b3 Python/3.7.3 (Windows-10-10.0.18362-SP0) + - azsdk-python-storage-file/12.0.0b4 Python/3.7.3 (Windows-10-10.0.17763-SP0) x-ms-client-request-id: - - 7f1255b0-d9a9-11e9-9a23-001a7dda7113 + - af3ee018-f054-11e9-bce7-2816a845e8c6 x-ms-date: - - Wed, 18 Sep 2019 00:16:01 GMT + - Wed, 16 Oct 2019 20:36:51 GMT x-ms-range: - bytes=0-1023 x-ms-version: @@ -1501,17 +1493,17 @@ interactions: : OTuddbrh+8UM18ydBXSoZw== ? !!python/object/new:multidict._istr.istr - Date - : Wed, 18 Sep 2019 00:16:00 GMT + : Wed, 16 Oct 2019 20:36:49 GMT ? !!python/object/new:multidict._istr.istr - Etag - : '"0x8D73BCD63398253"' + : '"0x8D7527892CFBA30"' ? !!python/object/new:multidict._istr.istr - Last-Modified - : Wed, 18 Sep 2019 00:16:01 GMT + : Wed, 16 Oct 2019 20:36:50 GMT ? !!python/object/new:multidict._istr.istr - Server : Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 - x-ms-request-id: d6a5a6fd-501a-00e1-71b6-6d8fb1000000 + x-ms-request-id: b4c21ebf-b01a-005c-6561-8495f9000000 x-ms-request-server-encrypted: 'true' x-ms-version: '2019-02-02' status: @@ -1521,7 +1513,7 @@ interactions: state: !!python/tuple - !!python/object/new:urllib.parse.SplitResult - https - - emilydevtest.file.core.windows.net + - amqptest.file.core.windows.net - /utshare48a0210b/utdir48a0210b/file48a0210b - comp=range - '' @@ -1531,15 +1523,13 @@ interactions: Accept: - application/xml User-Agent: - - azsdk-python-storage-file/12.0.0b3 Python/3.7.3 (Windows-10-10.0.18362-SP0) - content-type: - - application/xml; charset=utf-8 + - azsdk-python-storage-file/12.0.0b4 Python/3.7.3 (Windows-10-10.0.17763-SP0) x-ms-client-request-id: - - 7f151df8-d9a9-11e9-a058-001a7dda7113 + - af462e1e-f054-11e9-b0d2-2816a845e8c6 x-ms-date: - - Wed, 18 Sep 2019 00:16:01 GMT + - Wed, 16 Oct 2019 20:36:52 GMT x-ms-range: - - bytes=1-32768 + - bytes=4-32771 x-ms-version: - '2019-02-02' method: GET @@ -1547,57 +1537,62 @@ interactions: response: body: string: !!binary | - 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 headers: ? !!python/object/new:multidict._istr.istr - Accept-Ranges : bytes ? !!python/object/new:multidict._istr.istr - Content-Length - : '1023' + : '1020' ? !!python/object/new:multidict._istr.istr - Content-Range - : bytes 1-1023/1024 + : bytes 4-1023/1024 ? !!python/object/new:multidict._istr.istr - Content-Type - : application/xml; charset=utf-8 + : application/octet-stream ? !!python/object/new:multidict._istr.istr - Date - : Wed, 18 Sep 2019 00:16:00 GMT + : Wed, 16 Oct 2019 20:36:50 GMT ? !!python/object/new:multidict._istr.istr - Etag - : '"0x8D73BCD63398253"' + : '"0x8D7527892CFBA30"' ? !!python/object/new:multidict._istr.istr - Last-Modified - : Wed, 18 Sep 2019 00:16:01 GMT + : Wed, 16 Oct 2019 20:36:50 GMT ? !!python/object/new:multidict._istr.istr - Server : Windows-Azure-File/1.0 Microsoft-HTTPAPI/2.0 + ? !!python/object/new:multidict._istr.istr + - Vary + : Origin x-ms-file-attributes: Archive - x-ms-file-change-time: '2019-09-18T00:16:01.4992034Z' - x-ms-file-creation-time: '2019-09-18T00:16:01.4992034Z' + x-ms-file-change-time: '2019-10-16T20:36:50.8354482Z' + x-ms-file-creation-time: '2019-10-16T20:36:50.8354482Z' x-ms-file-id: '13835163608398430208' - x-ms-file-last-write-time: '2019-09-18T00:16:01.4992034Z' + x-ms-file-last-write-time: '2019-10-16T20:36:50.8354482Z' x-ms-file-parent-id: '13835128424026341376' - x-ms-file-permission-key: 4099112195243312672*10394889115079208622 - x-ms-request-id: d6a5a6fe-501a-00e1-72b6-6d8fb1000000 + x-ms-file-permission-key: 3501246319223038625*10967959146200238639 + x-ms-lease-state: available + x-ms-lease-status: unlocked + x-ms-request-id: b4c21ec2-b01a-005c-6661-8495f9000000 x-ms-server-encrypted: 'true' x-ms-type: File x-ms-version: '2019-02-02' @@ -1608,7 +1603,7 @@ interactions: state: !!python/tuple - !!python/object/new:urllib.parse.SplitResult - https - - emilydevtest.file.core.windows.net + - amqptest.file.core.windows.net - /utshare48a0210b/utdir48a0210b/file48a0210b - '' - '' From 54c9c70f1426ec69cd7aa82205bcdddc1c8a97b6 Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Thu, 17 Oct 2019 08:56:18 -0700 Subject: [PATCH 7/8] comments address --- .../azure/storage/file/aio/file_client_async.py | 11 ++++++----- .../azure/storage/file/file_client.py | 13 +++++++------ 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/sdk/storage/azure-storage-file/azure/storage/file/aio/file_client_async.py b/sdk/storage/azure-storage-file/azure/storage/file/aio/file_client_async.py index 484f8f742874..116aae0ae716 100644 --- a/sdk/storage/azure-storage-file/azure/storage/file/aio/file_client_async.py +++ b/sdk/storage/azure-storage-file/azure/storage/file/aio/file_client_async.py @@ -469,13 +469,14 @@ async def download_file( raise ValueError("Encryption not supported.") if length is not None and offset is None: raise ValueError("Offset value must not be None if length is set.") + range_end = None if length is not None: - length = offset + length - 1 # Service actually uses an end-range inclusive index + range_end = offset + length - 1 # Service actually uses an end-range inclusive index downloader = StorageStreamDownloader( client=self._client.file, config=self._config, offset=offset, - length=length, + length=range_end, validate_content=validate_content, encryption_options=None, cls=deserialize_file_stream, @@ -797,9 +798,9 @@ async def clear_range( # type: ignore raise ValueError("Unsupported method for encryption.") if offset is None or offset % 512 != 0: - raise ValueError("offset must be an integer that aligns with 512 file size") - if length is None or length % 512 != 511: - raise ValueError("length must be an integer that aligns with 512 file size") + raise ValueError("offset must be an integer that aligns with 512 bytes file size") + if length is None or length % 512 != 0: + raise ValueError("length must be an integer that aligns with 512 bytes file size") end_range = length + offset - 1 # Reformat to an inclusive range index content_range = "bytes={0}-{1}".format(offset, end_range) try: diff --git a/sdk/storage/azure-storage-file/azure/storage/file/file_client.py b/sdk/storage/azure-storage-file/azure/storage/file/file_client.py index 7ed2986e5850..e6d3f46d2ecd 100644 --- a/sdk/storage/azure-storage-file/azure/storage/file/file_client.py +++ b/sdk/storage/azure-storage-file/azure/storage/file/file_client.py @@ -687,13 +687,14 @@ def download_file( raise ValueError("Encryption not supported.") if length is not None and offset is None: raise ValueError("Offset value must not be None if length is set.") + range_end = None if length is not None: - length = offset + length - 1 # Service actually uses an end-range inclusive index + range_end = offset + length - 1 # Service actually uses an end-range inclusive index return StorageStreamDownloader( client=self._client.file, config=self._config, offset=offset, - length=length, + length=range_end, validate_content=validate_content, encryption_options=None, extra_properties={ @@ -926,7 +927,7 @@ def _upload_range_from_url_options(source_url, # type: str # Format range end_range = offset + length - 1 destination_range = 'bytes={0}-{1}'.format(offset, end_range) - source_range = 'bytes={0}-{1}'.format(source_offset, source_offset + length - 1) # should subtract 1 here? + source_range = 'bytes={0}-{1}'.format(source_offset, source_offset + length - 1) options = { 'copy_source': source_url, @@ -1047,9 +1048,9 @@ def clear_range( # type: ignore raise ValueError("Unsupported method for encryption.") if offset is None or offset % 512 != 0: - raise ValueError("offset must be an integer that aligns with 512 file size") - if length is None or length % 512 != 511: - raise ValueError("length must be an integer that aligns with 512 file size") + raise ValueError("offset must be an integer that aligns with 512 bytes file size") + if length is None or length % 512 != 0: + raise ValueError("length must be an integer that aligns with 512 bytes file size") end_range = length + offset - 1 # Reformat to an inclusive range index content_range = 'bytes={0}-{1}'.format(offset, end_range) try: From e82f978a04a019c8a746acad266f0d7132b6a490 Mon Sep 17 00:00:00 2001 From: Rakshith Bhyravabhotla Date: Thu, 17 Oct 2019 10:07:14 -0700 Subject: [PATCH 8/8] ops --- sdk/storage/azure-storage-file/tests/test_file.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/storage/azure-storage-file/tests/test_file.py b/sdk/storage/azure-storage-file/tests/test_file.py index 8325a4fd7cfc..59122131db93 100644 --- a/sdk/storage/azure-storage-file/tests/test_file.py +++ b/sdk/storage/azure-storage-file/tests/test_file.py @@ -263,7 +263,7 @@ def test_create_file_with_metadata(self): def test_create_file_when_file_permission_is_too_long(self): file_client = self._get_file_client() - permission = str(self.get_random_bytes(8 * 1024)) + permission = str(self.get_random_bytes(8 * 1024 + 1)) with self.assertRaises(ValueError): file_client.create_file(1024, file_permission=permission)