Skip to content

Commit

Permalink
Merge pull request #378 from zezha-msft/0.37.1
Browse files Browse the repository at this point in the history
0.37.1 for blob and common
  • Loading branch information
zezha-msft authored Nov 3, 2017
2 parents 6b1b520 + 524a2e7 commit ff62441
Show file tree
Hide file tree
Showing 543 changed files with 27,263 additions and 27,078 deletions.
3 changes: 2 additions & 1 deletion azure-storage-blob/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

> See [BreakingChanges](BreakingChanges.md) for a detailed list of API breaks.
## Version XX.XX.XX:
## Version 0.37.1:

- Enabling MD5 validation no longer uses the memory-efficient algorithm for large block blobs, since computing the MD5 hash requires reading the entire block into memory.
- Fixed a bug in the _SubStream class which was at risk of causing data corruption when using the memory-efficient algorithm for large block blobs.
- Support for AccessTierChangeTime to get the last time a tier was modified on an individual blob.
2 changes: 1 addition & 1 deletion azure-storage-blob/azure/storage/blob/_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# --------------------------------------------------------------------------

__author__ = 'Microsoft Corp. <[email protected]>'
__version__ = '0.37.0'
__version__ = '0.37.1'

# x-ms-version for storage service.
X_MS_VERSION = '2017-04-17'
Expand Down
6 changes: 5 additions & 1 deletion azure-storage-blob/azure/storage/blob/_deserialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,9 @@ def _convert_xml_to_containers(response):
'CopyCompletionTime': ('copy', 'completion_time', _to_str),
'CopyStatusDescription': ('copy', 'status_description', _to_str),
'AccessTier': (None, 'blob_tier', _to_str),
'ArchiveStatus': (None, 'rehydration_status', _to_str)
'AccessTierChangeTime': (None, 'blob_tier_change_time', parser.parse),
'AccessTierInferred': (None, 'blob_tier_inferred', _bool),
'ArchiveStatus': (None, 'rehydration_status', _to_str),
}


Expand Down Expand Up @@ -281,6 +283,8 @@ def _convert_xml_to_blob_list(response):
<CopyCompletionTime>datetime</CopyCompletionTime>
<CopyStatusDescription>error string</CopyStatusDescription>
<AccessTier>P4 | P6 | P10 | P20 | P30 | P40 | P50 | P60 | Archive | Cool | Hot</AccessTier>
<AccessTierChangeTime>date-time-value</AccessTierChangeTime>
<AccessTierInferred>true</AccessTierInferred>
</Properties>
<Metadata>
<Name>value</Name>
Expand Down
15 changes: 15 additions & 0 deletions azure-storage-blob/azure/storage/blob/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,18 @@ class BlobProperties(object):
Stores all the content settings for the blob.
:ivar ~azure.storage.blob.models.LeaseProperties lease:
Stores all the lease information for the blob.
:ivar StandardBlobTier blob_tier:
Indicates the access tier of the blob. The hot tier is optimized
for storing data that is accessed frequently. The cool storage tier
is optimized for storing data that is infrequently accessed and stored
for at least a month. The archive tier is optimized for storing
data that is rarely accessed and stored for at least six months
with flexible latency requirements.
:ivar datetime blob_tier_change_time:
Indicates when the access tier was last changed.
:ivar bool blob_tier_inferred:
Indicates whether the access tier was inferred by the service.
If false, it indicates that the tier was set explicitly.
'''

def __init__(self):
Expand All @@ -129,6 +141,9 @@ def __init__(self):
self.copy = CopyProperties()
self.content_settings = ContentSettings()
self.lease = LeaseProperties()
self.blob_tier = None
self.blob_tier_change_time = None
self.blob_tier_inferred = False


class ContentSettings(object):
Expand Down
4 changes: 2 additions & 2 deletions azure-storage-blob/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@

setup(
name='azure-storage-blob',
version='0.37.0',
version='0.37.1',
description='Microsoft Azure Storage Blob Client Library for Python',
long_description=open('README.rst', 'r').read(),
license='Apache License 2.0',
Expand All @@ -86,7 +86,7 @@
'cryptography',
'python-dateutil',
'requests',
'azure-storage-common>=0.37.0,<0.38.0'
'azure-storage-common>=0.37.1,<0.38.0'
] + (['futures'] if sys.version_info < (3, 0) else []),
cmdclass=cmdclass
)
2 changes: 1 addition & 1 deletion azure-storage-common/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

> See [BreakingChanges](BreakingChanges.md) for a detailed list of API breaks.
## Version XX.XX.XX:
## Version 0.37.1:
- Fixed the return type of __add__ and __or__ methods on the AccountPermissions class
- Added the captured exception to retry_context, in case the user wants more info in retry_callback or implement their own retry class.
- Added random jitters to retry intervals, in order to avoid multiple retries to happen at the exact same time
Expand Down
2 changes: 1 addition & 1 deletion azure-storage-common/azure/storage/common/_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import platform

__author__ = 'Microsoft Corp. <[email protected]>'
__version__ = '0.37.0'
__version__ = '0.37.1'

# UserAgent string sample: 'Azure-Storage/0.37.0-0.38.0 (Python CPython 3.4.2; Windows 8)'
# First version(0.37.0) is the common package, and the second version(0.38.0) is the service package
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ def _get_download_size(start_range, end_range, resource_size):
'x-ms-blob-sequence-number': (None, 'page_blob_sequence_number', _int_to_str),
'x-ms-blob-committed-block-count': (None, 'append_blob_committed_block_count', _int_to_str),
'x-ms-access-tier': (None, 'blob_tier', _to_str),
'x-ms-access-tier-change-time': (None, 'blob_tier_change_time', parser.parse),
'x-ms-access-tier-inferred': (None, 'blob_tier_inferred', _bool),
'x-ms-archive-status': (None, 'rehydration_status', _to_str),
'x-ms-share-quota': (None, 'quota', _int_to_str),
Expand Down
2 changes: 1 addition & 1 deletion azure-storage-common/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@

setup(
name='azure-storage-common',
version='0.37.0',
version='0.37.1',
description='Microsoft Azure Storage Common Client Library for Python',
long_description=open('README.rst', 'r').read(),
license='Apache License 2.0',
Expand Down
4 changes: 2 additions & 2 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@
# built documents.
#
# The short X.Y version.
version = '0.37.0'
version = '0.37.1'
# The full version, including alpha/beta/rc tags.
release = '0.37.0'
release = '0.37.1'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
31 changes: 25 additions & 6 deletions tests/blob/test_blob_storage_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,29 @@ def test_standard_blob_tier_set_tier_api(self):
blob_name = self._get_blob_reference()
data = b'hello world'
self.bs.create_blob_from_bytes(self.container_name, blob_name, data)

blob_ref = self.bs.get_blob_properties(self.container_name, blob_name)
self.assertIsNotNone(blob_ref.properties.blob_tier)
self.assertTrue(blob_ref.properties.blob_tier_inferred)
self.assertIsNone(blob_ref.properties.blob_tier_change_time)

blobs = list(self.bs.list_blobs(self.container_name))

# Assert
self.assertIsNotNone(blobs)
self.assertGreaterEqual(len(blobs), 1)
self.assertIsNotNone(blobs[0])
self.assertNamedItemInContainer(blobs, blob_name)
self.assertIsNotNone(blobs[0].properties.blob_tier)
self.assertTrue(blobs[0].properties.blob_tier_inferred)
self.assertIsNone(blobs[0].properties.blob_tier_change_time)

self.bs.set_standard_blob_tier(self.container_name, blob_name, tier)

blob_ref2 = self.bs.get_blob_properties(self.container_name, blob_name)
self.assertEqual(tier, blob_ref2.properties.blob_tier)
self.assertFalse(hasattr(blob_ref2.properties, 'blob_tier_inferred'))
self.assertFalse(blob_ref2.properties.blob_tier_inferred)
self.assertIsNotNone(blob_ref2.properties.blob_tier_change_time)

blobs = list(self.bs.list_blobs(self.container_name))

Expand All @@ -89,7 +107,8 @@ def test_standard_blob_tier_set_tier_api(self):
self.assertIsNotNone(blobs[0])
self.assertNamedItemInContainer(blobs, blob_name)
self.assertEqual(blobs[0].properties.blob_tier, tier)
self.assertFalse(hasattr(blobs[0].properties, 'blob_tier_inferred'))
self.assertFalse(blobs[0].properties.blob_tier_inferred)
self.assertIsNotNone(blobs[0].properties.blob_tier_change_time)

self.bs.delete_blob(self.container_name, blob_name)

Expand All @@ -106,7 +125,7 @@ def test_rehydration_status(self):
blob_ref = self.bs.get_blob_properties(self.container_name, blob_name)
self.assertEqual(StandardBlobTier.Archive, blob_ref.properties.blob_tier)
self.assertEqual("rehydrate-pending-to-cool", blob_ref.properties.rehydration_status)
self.assertFalse(hasattr(blob_ref.properties, 'blob_tier_inferred'))
self.assertFalse(blob_ref.properties.blob_tier_inferred)

blobs = list(self.bs.list_blobs(self.container_name))
self.bs.delete_blob(self.container_name, blob_name)
Expand All @@ -118,7 +137,7 @@ def test_rehydration_status(self):
self.assertNamedItemInContainer(blobs, blob_name)
self.assertEqual(StandardBlobTier.Archive, blobs[0].properties.blob_tier)
self.assertEqual("rehydrate-pending-to-cool", blobs[0].properties.rehydration_status)
self.assertFalse(hasattr(blobs[0].properties, 'blob_tier_inferred'))
self.assertFalse(blobs[0].properties.blob_tier_inferred)

self.bs.create_blob_from_bytes(self.container_name, blob_name2, data)
self.bs.set_standard_blob_tier(self.container_name, blob_name2, StandardBlobTier.Archive)
Expand All @@ -127,7 +146,7 @@ def test_rehydration_status(self):
blob_ref2 = self.bs.get_blob_properties(self.container_name, blob_name2)
self.assertEqual(StandardBlobTier.Archive, blob_ref2.properties.blob_tier)
self.assertEqual("rehydrate-pending-to-hot", blob_ref2.properties.rehydration_status)
self.assertFalse(hasattr(blob_ref2.properties, 'blob_tier_inferred'))
self.assertFalse(blob_ref2.properties.blob_tier_inferred)

blobs = list(self.bs.list_blobs(self.container_name))

Expand All @@ -138,7 +157,7 @@ def test_rehydration_status(self):
self.assertNamedItemInContainer(blobs, blob_name2)
self.assertEqual(StandardBlobTier.Archive, blobs[0].properties.blob_tier)
self.assertEqual("rehydrate-pending-to-hot", blobs[0].properties.rehydration_status)
self.assertFalse(hasattr(blobs[0].properties, 'blob_tier_inferred'))
self.assertFalse(blobs[0].properties.blob_tier_inferred)


# ------------------------------------------------------------------------------
Expand Down
25 changes: 17 additions & 8 deletions tests/blob/test_page_blob.py
Original file line number Diff line number Diff line change
Expand Up @@ -748,7 +748,6 @@ def test_create_blob_with_md5_large(self):

# Assert


def test_incremental_copy_blob(self):
# parallel tests introduce random order of requests, can only run live
if TestMode.need_recording_file(self.test_mode):
Expand Down Expand Up @@ -806,7 +805,7 @@ def test_blob_tier_on_create(self):

blob = ps.get_blob_properties(container_name, blob_name)
self.assertEqual(blob.properties.blob_tier, PremiumPageBlobTier.P4)
self.assertFalse(hasattr(blob.properties, 'blob_tier_inferred'))
self.assertFalse(blob.properties.blob_tier_inferred)

# test create_blob_from_bytes API
blob_name2 = self._get_blob_reference()
Expand All @@ -815,7 +814,7 @@ def test_blob_tier_on_create(self):

blob2 = ps.get_blob_properties(container_name, blob_name2)
self.assertEqual(blob2.properties.blob_tier, PremiumPageBlobTier.P6)
self.assertFalse(hasattr(blob.properties, 'blob_tier_inferred'))
self.assertFalse(blob.properties.blob_tier_inferred)

# test create_blob_from_path API
blob_name3 = self._get_blob_reference()
Expand All @@ -825,7 +824,7 @@ def test_blob_tier_on_create(self):

blob3 = ps.get_blob_properties(container_name, blob_name3)
self.assertEqual(blob3.properties.blob_tier, PremiumPageBlobTier.P10)
self.assertFalse(hasattr(blob.properties, 'blob_tier_inferred'))
self.assertFalse(blob.properties.blob_tier_inferred)

# test create_blob_from_stream API
blob_name4 = self._get_blob_reference()
Expand All @@ -834,7 +833,7 @@ def test_blob_tier_on_create(self):

blob4 = ps.get_blob_properties(container_name, blob_name4)
self.assertEqual(blob4.properties.blob_tier, PremiumPageBlobTier.P20)
self.assertFalse(hasattr(blob.properties, 'blob_tier_inferred'))
self.assertFalse(blob.properties.blob_tier_inferred)
finally:
ps.delete_container(container_name)

Expand All @@ -851,12 +850,22 @@ def test_blob_tier_set_tier_api(self):
ps.create_blob(container_name, blob_name, 1024)
blob_ref = ps.get_blob_properties(container_name, blob_name)
self.assertEqual(PremiumPageBlobTier.P10, blob_ref.properties.blob_tier)
self.assertIsNotNone(blob_ref.properties.blob_tier)
self.assertTrue(blob_ref.properties.blob_tier_inferred)

blobs = list(ps.list_blobs(container_name))

# Assert
self.assertIsNotNone(blobs)
self.assertGreaterEqual(len(blobs), 1)
self.assertIsNotNone(blobs[0])
self.assertNamedItemInContainer(blobs, blob_name)

ps.set_premium_page_blob_tier(container_name, blob_name, PremiumPageBlobTier.P50)

blob_ref2 = ps.get_blob_properties(container_name, blob_name)
self.assertEqual(PremiumPageBlobTier.P50, blob_ref2.properties.blob_tier)
self.assertFalse(hasattr(blob_ref2.properties, 'blob_tier_inferred'))
self.assertFalse(blob_ref2.properties.blob_tier_inferred)

blobs = list(ps.list_blobs(container_name))

Expand All @@ -866,7 +875,7 @@ def test_blob_tier_set_tier_api(self):
self.assertIsNotNone(blobs[0])
self.assertNamedItemInContainer(blobs, blob_name)
self.assertEqual(blobs[0].properties.blob_tier, PremiumPageBlobTier.P50)
self.assertFalse(hasattr(blobs[0].properties, 'blob_tier_inferred'))
self.assertFalse(blobs[0].properties.blob_tier_inferred)
finally:
ps.delete_container(container_name)

Expand Down Expand Up @@ -910,7 +919,7 @@ def test_blob_tier_copy_blob(self):

copy_ref2 = ps.get_blob_properties(container_name, 'blob2copy')
self.assertEqual(copy_ref2.properties.blob_tier, PremiumPageBlobTier.P60)
self.assertFalse(hasattr(copy_ref2.properties, 'blob_tier_inferred'))
self.assertFalse(copy_ref2.properties.blob_tier_inferred)

copy3 = ps.copy_blob(container_name, 'blob3copy', source_blob2)
self.assertIsNotNone(copy3)
Expand Down
Loading

0 comments on commit ff62441

Please sign in to comment.