Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
8f85d8c
Updated blobs shared code
annatisch Jul 19, 2019
a3aff08
Started blob refactor
annatisch Jul 19, 2019
90b9640
Refactoring upload
annatisch Jul 22, 2019
6d33776
Merge remote-tracking branch 'upstream/storage-preview2'
annatisch Jul 22, 2019
de42b24
Updated shared code
annatisch Jul 22, 2019
d8ec863
Started fixing tests
annatisch Jul 22, 2019
8d9bd39
Merge remote-tracking branch 'upstream/storage-preview2'
annatisch Jul 22, 2019
3a231d8
Refactored sync blobs
annatisch Jul 23, 2019
d527688
Added blob async APIs
annatisch Jul 24, 2019
76b9e3c
Some fixes
annatisch Jul 24, 2019
9a8fb9d
Append blob async tests
annatisch Jul 24, 2019
900e07b
blob access async tests
annatisch Jul 24, 2019
c8668c9
Blob client async tests
annatisch Jul 24, 2019
05b9020
encryption async tests
annatisch Jul 24, 2019
bee7e3f
Patch for azure core exception
annatisch Jul 24, 2019
dda031b
blob retry async
annatisch Jul 24, 2019
99bc35d
Retry async tests
annatisch Jul 24, 2019
4fd5b84
Get blob async tests
annatisch Jul 25, 2019
1eb8192
Bug fix for clear page operation
annatisch Jul 25, 2019
24dd430
More async tests + upload fix
annatisch Jul 26, 2019
30cbc1b
Merged from preview 2
annatisch Jul 26, 2019
076d062
Merged blobs
annatisch Jul 26, 2019
fa808bb
Updated Files shared code
annatisch Jul 26, 2019
38f6fc5
Updated queue shared code
annatisch Jul 26, 2019
e6d9544
Merge from upstream
annatisch Jul 26, 2019
704d8bb
async tests pass except 2 common blob tests
kristapratico Jul 26, 2019
9bcd94a
adds async paging to blobs and some async tests (not all pass)
kristapratico Jul 29, 2019
8a6df99
Merge pull request #2 from annatisch/async-blob-tests
kristapratico Jul 29, 2019
d28961c
initial commit
rakshith91 Jul 30, 2019
375323e
block_blob_tests
rakshith91 Jul 30, 2019
35261e9
page blob tests
rakshith91 Jul 30, 2019
0b5eaed
Merge pull request #3 from annatisch/async_tests
Jul 30, 2019
bdd8396
Merge branch 'storage-preview2' into master
kristapratico Jul 31, 2019
37fb8e3
fix for special chars, some tests, and recordings
kristapratico Jul 31, 2019
4bcbca7
add to shared storage and fix import
kristapratico Jul 31, 2019
a984b39
adding more tests/recordings
kristapratico Jul 31, 2019
90a7c61
more tests/recordings
kristapratico Aug 1, 2019
36155a8
Merge pull request #4 from annatisch/async-blob-tests
kristapratico Aug 1, 2019
5fb77f5
rerecord tests, fix imports
kristapratico Aug 1, 2019
e97af55
Merge pull request #5 from annatisch/async-blob-tests
kristapratico Aug 1, 2019
4687f62
fix import again
kristapratico Aug 1, 2019
7552cdb
Merge pull request #6 from annatisch/async-blob-tests
kristapratico Aug 1, 2019
753006e
blacklist azure-servicemanagement-legacy
kristapratico Aug 1, 2019
748237e
Merge pull request #7 from annatisch/async-blob-tests
kristapratico Aug 1, 2019
dfabb8b
get CI to run
kristapratico Aug 1, 2019
0ad6851
Merge pull request #8 from annatisch/async-blob-tests
kristapratico Aug 1, 2019
634a74a
rerecord all async tests
kristapratico Aug 2, 2019
2848c33
Merge pull request #9 from annatisch/async-blob-tests
kristapratico Aug 2, 2019
c607dde
testing
kristapratico Aug 2, 2019
b3b67fc
Merge pull request #10 from annatisch/async-blob-tests
kristapratico Aug 2, 2019
4df2eef
add variable indirection for storage live tests. this is a temporary …
danieljurek Aug 2, 2019
615fc42
newline
danieljurek Aug 2, 2019
f51dfb4
Merge pull request #11 from danieljurek/async-blob-tests
kristapratico Aug 2, 2019
7edbc6e
print envar
kristapratico Aug 2, 2019
ace7ea7
Merge pull request #12 from annatisch/async-blob-tests
kristapratico Aug 2, 2019
85490ca
remove testing
kristapratico Aug 3, 2019
d48e917
Merge pull request #13 from annatisch/async-blob-tests
kristapratico Aug 3, 2019
20adbbc
adjust pypy testing
kristapratico Aug 3, 2019
2b1a0ae
Merge pull request #14 from annatisch/async-blob-tests
kristapratico Aug 3, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
More async tests + upload fix
  • Loading branch information
annatisch committed Jul 26, 2019
commit 24dd4303cd625640f57e8f371a5ae4f3b95cb73c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import asyncio
from asyncio import Lock
from itertools import islice
import threading

from math import ceil

Expand Down Expand Up @@ -137,7 +138,7 @@ def __init__(self, service, total_size, chunk_size, stream, parallel, encryptor=

# Stream management
self.stream_start = stream.tell() if parallel else None
self.stream_lock = Lock() if parallel else None
self.stream_lock = threading.Lock() if parallel else None

# Progress feedback
self.progress_total = 0
Expand Down Expand Up @@ -232,7 +233,7 @@ async def _upload_substream_block(self, block_id, block_stream):
raise NotImplementedError("Must be implemented by child class.")

async def _upload_substream_block_with_progress(self, block_id, block_stream):
range_id = self._upload_substream_block(block_id, block_stream)
range_id = await self._upload_substream_block(block_id, block_stream)
await self._update_progress(len(block_stream))
return range_id

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
# -------------------------------------------------------------------------
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: confusing file name

# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# --------------------------------------------------------------------------
import pytest
import asyncio

from datetime import datetime, timedelta
from azure.core import HttpResponseError
from azure.storage.blob.aio import (
BlobServiceClient,
ContainerClient,
BlobClient,
StorageErrorCode,
BlobPermissions
)
from azure.storage.blob._shared.policies import StorageContentValidation
from testcase import (
StorageTestCase,
record,
TestMode
)

# ------------------------------------------------------------------------------
SOURCE_BLOB_SIZE = 8 * 1024


# ------------------------------------------------------------------------------

class StorageBlockBlobTestAsync(StorageTestCase):

def setUp(self):
super(StorageBlockBlobTestAsync, self).setUp()
url = self._get_account_url()
credential = self._get_shared_key_credential()

# test chunking functionality by reducing the size of each chunk,
# otherwise the tests would take too long to execute
self.bsc = BlobServiceClient(
url,
credential=credential,
connection_data_block_size=4 * 1024,
max_single_put_size=32 * 1024,
max_block_size=4 * 1024)
self.config = self.bsc._config
self.container_name = self.get_resource_name('utcontainer')

# create source blob to be copied from
self.source_blob_name = self.get_resource_name('srcblob')
self.source_blob_data = self.get_random_bytes(SOURCE_BLOB_SIZE)

blob = self.bsc.get_blob_client(self.container_name, self.source_blob_name)
if not self.is_playback():
self.bsc.create_container(self.container_name)
blob.upload_blob(self.source_blob_data)

# generate a SAS so that it is accessible with a URL
sas_token = blob.generate_shared_access_signature(
permission=BlobPermissions.READ,
expiry=datetime.utcnow() + timedelta(hours=1),
)
self.source_blob_url = BlobClient(blob.url, credential=sas_token).url

def tearDown(self):
if not self.is_playback():
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(self.bsc.delete_container(self.container_name))
except:
pass

return super(StorageBlockBlobTestAsync, self).tearDown()

async def _setup(self):
blob = self.bsc.get_blob_client(self.container_name, self.source_blob_name)
if not self.is_playback():
try:
await self.bsc.create_container(self.container_name)
except:
pass
await blob.upload_blob(self.source_blob_data, overwrite=True)

# generate a SAS so that it is accessible with a URL
sas_token = blob.generate_shared_access_signature(
permission=BlobPermissions.READ,
expiry=datetime.utcnow() + timedelta(hours=1),
)
self.source_blob_url = BlobClient(blob.url, credential=sas_token).url

async def _test_put_block_from_url_and_commit_async(self):
# Arrange
await self._setup()
dest_blob_name = self.get_resource_name('destblob')
dest_blob = self.bsc.get_blob_client(self.container_name, dest_blob_name)

# Act part 1: make put block from url calls
futures = [
dest_blob.stage_block_from_url(
block_id=1,
source_url=self.source_blob_url,
source_offset=0,
source_length=4 * 1024 - 1),
dest_blob.stage_block_from_url(
block_id=2,
source_url=self.source_blob_url,
source_offset=4 * 1024,
source_length=8 * 1024)]
await asyncio.gather(*futures)

# Assert blocks
committed, uncommitted = await dest_blob.get_block_list('all')
self.assertEqual(len(uncommitted), 2)
self.assertEqual(len(committed), 0)

# Act part 2: commit the blocks
await dest_blob.commit_block_list(['1', '2'])

# Assert destination blob has right content
content = await (await dest_blob.download_blob()).content_as_bytes()
self.assertEqual(content, self.source_blob_data)

def test_put_block_from_url_and_commit_async(self):
if TestMode.need_recording_file(self.test_mode):
return
loop = asyncio.get_event_loop()
loop.run_until_complete(self._test_put_block_from_url_and_commit_async())

async def _test_put_block_from_url_and_validate_content_md5_async(self):
# Arrange
await self._setup()
dest_blob_name = self.get_resource_name('destblob')
dest_blob = self.bsc.get_blob_client(self.container_name, dest_blob_name)
src_md5 = StorageContentValidation.get_content_md5(self.source_blob_data)

# Act part 1: put block from url with md5 validation
await dest_blob.stage_block_from_url(
block_id=1,
source_url=self.source_blob_url,
source_content_md5=src_md5,
source_offset=0,
source_length=8 * 1024)

# Assert block was staged
committed, uncommitted = await dest_blob.get_block_list('all')
self.assertEqual(len(uncommitted), 1)
self.assertEqual(len(committed), 0)

# Act part 2: put block from url with wrong md5
fake_md5 = StorageContentValidation.get_content_md5(b"POTATO")
with self.assertRaises(HttpResponseError) as error:
await dest_blob.stage_block_from_url(
block_id=2,
source_url=self.source_blob_url,
source_content_md5=fake_md5,
source_offset=0,
source_length=8 * 1024)
self.assertEqual(error.exception.error_code, StorageErrorCode.md5_mismatch)

# Assert block was not staged
committed, uncommitted = await dest_blob.get_block_list('all')
self.assertEqual(len(uncommitted), 1)
self.assertEqual(len(committed), 0)

def test_put_block_from_url_and_validate_content_md5_async(self):
if TestMode.need_recording_file(self.test_mode):
return
loop = asyncio.get_event_loop()
loop.run_until_complete(self._test_put_block_from_url_and_validate_content_md5_async())

async def _test_copy_blob_sync_async(self):
# Arrange
await self._setup()
dest_blob_name = self.get_resource_name('destblob')
dest_blob = self.bsc.get_blob_client(self.container_name, dest_blob_name)

# Act
copy_props = await dest_blob.start_copy_from_url(self.source_blob_url, requires_sync=True)

# Assert
self.assertIsNotNone(copy_props)
self.assertIsNotNone(copy_props['copy_id'])
self.assertEqual('success', copy_props['copy_status'])

# Verify content
content = await (await dest_blob.download_blob()).content_as_bytes()
self.assertEqual(self.source_blob_data, content)

def test_copy_blob_sync_async(self):
if TestMode.need_recording_file(self.test_mode):
return
loop = asyncio.get_event_loop()
loop.run_until_complete(self._test_copy_blob_sync_async())
Loading