def test_service_client_api_version_property(self): service_client = BlobServiceClient( "https://foo.blob.core.windows.net/account", credential="fake_key") self.assertEqual(service_client.api_version, self.api_version_2) self.assertEqual(service_client._client._config.version, self.api_version_2) with pytest.raises(AttributeError): service_client.api_version = "foo" service_client = BlobServiceClient( "https://foo.blob.core.windows.net/account", credential="fake_key", api_version=self.api_version_1) self.assertEqual(service_client.api_version, self.api_version_1) self.assertEqual(service_client._client._config.version, self.api_version_1) container_client = service_client.get_container_client("foo") self.assertEqual(container_client.api_version, self.api_version_1) self.assertEqual(container_client._client._config.version, self.api_version_1) blob_client = service_client.get_blob_client("foo", "bar") self.assertEqual(blob_client.api_version, self.api_version_1) self.assertEqual(blob_client._client._config.version, self.api_version_1)
async def test_set_static_webprops_no_impact_other_props( self, resource_group, location, storage_account, storage_account_key): bsc = BlobServiceClient(self.account_url(storage_account, "blob"), credential=storage_account_key, transport=AiohttpTestTransport()) cors_rule1 = CorsRule(['www.xyz.com'], ['GET']) allowed_origins = ['www.xyz.com', "www.ab.com", "www.bc.com"] allowed_methods = ['GET', 'PUT'] max_age_in_seconds = 500 exposed_headers = [ "x-ms-meta-data*", "x-ms-meta-source*", "x-ms-meta-abc", "x-ms-meta-bcd" ] allowed_headers = [ "x-ms-meta-data*", "x-ms-meta-target*", "x-ms-meta-xyz", "x-ms-meta-foo" ] cors_rule2 = CorsRule(allowed_origins, allowed_methods, max_age_in_seconds=max_age_in_seconds, exposed_headers=exposed_headers, allowed_headers=allowed_headers) cors = [cors_rule1, cors_rule2] # Act await bsc.set_service_properties(cors=cors) # Assert cors is updated received_props = await bsc.get_service_properties() self._assert_cors_equal(received_props['cors'], cors) bsc = BlobServiceClient(self.account_url(storage_account, "blob"), credential=storage_account_key, transport=AiohttpTestTransport()) static_website = StaticWebsite( enabled=True, index_document="index.html", error_document404_path="errors/error/404error.html") # Act to set static website await bsc.set_service_properties(static_website=static_website) # Assert static website was updated was cors was unchanged received_props = await bsc.get_service_properties() self._assert_static_website_equal(received_props['static_website'], static_website) self._assert_cors_equal(received_props['cors'], cors)
async def test_retry_put_block_with_seekable_stream_async(self, resource_group, location, storage_account, storage_account_key): pytest.skip("Aiohttp closes stream after request - cannot rewind.") # Arrange bsc = BlobServiceClient(self.account_url(storage_account.name, "blob"), credential=storage_account_key, retry_policy=self.retry, transport=AiohttpTestTransport()) await self._setup(bsc) blob_name = self.get_resource_name('blob') data = self.get_random_bytes(PUT_BLOCK_SIZE) data_stream = BytesIO(data) # rig the response so that it fails for a single time responder = ResponseCallback(status=201, new_status=408) # Act blob = bsc.get_blob_client(self.container_name, blob_name) await blob.stage_block(1, data_stream, raw_response_hook=responder.override_first_status) # Assert _, uncommitted_blocks = await blob.get_block_list( block_list_type="uncommitted", raw_response_hook=responder.override_first_status) self.assertEqual(len(uncommitted_blocks), 1) self.assertEqual(uncommitted_blocks[0].size, PUT_BLOCK_SIZE) # Commit block and verify content await blob.commit_block_list(['1'], raw_response_hook=responder.override_first_status) # Assert content = await (await blob.download_blob()).readall() self.assertEqual(content, data)
async def _test_user_agent_custom_async(self): custom_app = "TestApp/v1.0" service = BlobServiceClient(self._get_account_url(), credential=self.account_key, user_agent=custom_app, transport=AiohttpTestTransport()) def callback(response): self.assertTrue('User-Agent' in response.http_request.headers) self.assertEqual( response.http_request.headers['User-Agent'], "TestApp/v1.0 azsdk-python-storage-blob/{} Python/{} ({})". format(VERSION, platform.python_version(), platform.platform())) await service.get_service_properties(raw_response_hook=callback) def callback(response): self.assertTrue('User-Agent' in response.http_request.headers) self.assertEqual( response.http_request.headers['User-Agent'], "TestApp/v2.0 azsdk-python-storage-blob/{} Python/{} ({})". format(VERSION, platform.python_version(), platform.platform())) await service.get_service_properties(raw_response_hook=callback, user_agent="TestApp/v2.0")
async def test_retry_put_block_with_non_seekable_stream_async(self, storage_account_name, storage_account_key): # Arrange bsc = BlobServiceClient(self.account_url(storage_account_name, "blob"), credential=storage_account_key, retry_policy=self.retry, transport=AiohttpTestTransport()) await self._setup(bsc) blob_name = self.get_resource_name('blob') data = self.get_random_bytes(PUT_BLOCK_SIZE) data_stream = self.NonSeekableStream(BytesIO(data)) # rig the response so that it fails for a single time responder = ResponseCallback(status=201, new_status=408) # Act blob = bsc.get_blob_client(self.container_name, blob_name) # Note: put_block transforms non-seekable streams into byte arrays before handing it off to the executor await blob.stage_block(1, data_stream, raw_response_hook=responder.override_first_status) # Assert _, uncommitted_blocks = await blob.get_block_list( block_list_type="uncommitted", raw_response_hook=responder.override_first_status) self.assertEqual(len(uncommitted_blocks), 1) self.assertEqual(uncommitted_blocks[0].size, PUT_BLOCK_SIZE) # Commit block and verify content await blob.commit_block_list(['1'], raw_response_hook=responder.override_first_status) # Assert content = await (await blob.download_blob()).readall() self.assertEqual(content, data)
async def test_list_blobs(self, resource_group, location, storage_account, storage_account_key): # Arrange bsc = BlobServiceClient(self.account_url(storage_account, "blob"), credential=storage_account_key, connection_data_block_size=1024, max_single_put_size=1024, min_large_block_upload_threshold=1024, max_block_size=1024, max_page_size=1024) await self._setup(bsc) blob_client, _ = await self._create_block_blob( bsc, blob_name="blockblob", data=b'AAABBBCCC', encryption_scope=TEST_ENCRYPTION_KEY_SCOPE) await self._create_append_blob( bsc, encryption_scope=TEST_ENCRYPTION_KEY_SCOPE) container_client = bsc.get_container_client(self.container_name) generator = container_client.list_blobs(include="metadata") async for blob in generator: self.assertIsNotNone(blob) # Assert: every listed blob has encryption_scope self.assertEqual(blob.encryption_scope, TEST_ENCRYPTION_KEY_SCOPE) self._teardown(bsc)
def setUp(self): super(BlobStorageAccountTestAsync, self).setUp() url = self._get_account_url() credential = self._get_shared_key_credential() self.bsc = BlobServiceClient(url, credential=credential, transport=AiohttpTestTransport()) self.container_name = self.get_resource_name('utcontainer')
async def test_set_static_web_props_missing_field(self, storage_account_name, storage_account_key): # Case1: Arrange both missing bsc = BlobServiceClient(self.account_url(storage_account_name, "blob"), credential=storage_account_key, transport=AiohttpTestTransport()) static_website = StaticWebsite(enabled=True) # Act await bsc.set_service_properties(static_website=static_website) # Assert received_props = await bsc.get_service_properties() self._assert_static_website_equal(received_props['static_website'], static_website) # Case2: Arrange index document missing static_website = StaticWebsite(enabled=True, error_document404_path="errors/error/404error.html") # Act await bsc.set_service_properties(static_website=static_website) # Assert received_props = await bsc.get_service_properties() self._assert_static_website_equal(received_props['static_website'], static_website) # Case3: Arrange error document missing static_website = StaticWebsite(enabled=True, index_document="index.html") # Act await bsc.set_service_properties(static_website=static_website) # Assert received_props = await bsc.get_service_properties() self._assert_static_website_equal(received_props['static_website'], static_website)
async def startup_event(): """ Async function which is run on FastAPI startup. Put your bootup code here. """ logging.basicConfig(level=logging.INFO) # Silence the somewhat verbose Azure libs... logging.getLogger("azure.core.pipeline.policies").setLevel(logging.WARNING) account = os.getenv('AZURE_ACCOUNT') key = os.getenv('AZURE_KEY') logging.info(f'Using storage account: "{account}"') if key: logging.info('Storage key is set') else: raise ValueError('Environment variable AZURE_KEY is not set') blob_service_client = BlobServiceClient(account_url=await get_service_url(account), credential=key) logging.info( f'Connected to Azure Blob Service version {blob_service_client.api_version}' ) # This forces some talk on the wire to verify that we can talk to the Azure API. runtime_config["client"] = blob_service_client logging.info('Probing storage layer.') try: await blob_service_client.get_account_information() await register_status(STATUS_OK, 'OK') except ServiceRequestError as exception: await register_status(STATUS_ERROR, exception) logging.error( f"Something went wrong when talking to Azure: {exception}")
async def test_standard_blob_tier_set_tier_api(self, storage_account_name, storage_account_key): bsc = BlobServiceClient(self.account_url(storage_account_name, "blob"), credential=storage_account_key, transport=AiohttpTestTransport()) await self._setup(bsc) tiers = [StandardBlobTier.Archive, StandardBlobTier.Cool, StandardBlobTier.Hot] for tier in tiers: blob_name = self.get_resource_name(tier.value) blob = bsc.get_blob_client(self.container_name, blob_name) await blob.upload_blob(b'hello world') blob_ref = await blob.get_blob_properties() self.assertIsNotNone(blob_ref.blob_tier) self.assertTrue(blob_ref.blob_tier_inferred) self.assertIsNone(blob_ref.blob_tier_change_time) # Act await blob.set_standard_blob_tier(tier) # Assert blob_ref2 = await blob.get_blob_properties() self.assertEqual(tier, blob_ref2.blob_tier) self.assertFalse(blob_ref2.blob_tier_inferred) self.assertIsNotNone(blob_ref2.blob_tier_change_time) await blob.delete_blob()
async def return_gallery_blobs(start=0, limit=None): blob_service_client = BlobServiceClient( account_url=f"https://{os.getenv('AZURE_STORAGE_ACCOUNT')}.blob.core.windows.net/", credential=os.getenv("AZURE_STORAGE_KEY"), ) container_client = blob_service_client.get_container_client( os.getenv("AZURE_STORAGE_VIDEO_CONTAINER") ) blobs_list = [] async for blob in container_client.list_blobs( # pylint: disable=E1133 include=["metadata"] ): metadata = blob.metadata created_at = blob.creation_time blobs_list.append( { "uuid": metadata["uuid"], "image_url": f"/get_thumbnail?video_uuid={metadata['uuid']}", "uploader_username": metadata["uploader_username"], "uploader_id": metadata["uploader_id"], "title": metadata["title"], "badge": metadata["badge"], "elapsed_time": date_funcs.elapsed_time_str(created_at), } ) await container_client.close() await blob_service_client.close() return blobs_list
async def test_create_container_with_default_cpk_n(self, resource_group, location, storage_account, storage_account_key): # Arrange bsc = BlobServiceClient( self.account_url(storage_account, "blob"), credential=storage_account_key, connection_data_block_size=1024, max_single_put_size=1024, min_large_block_upload_threshold=1024, max_block_size=1024, max_page_size=1024) container_client = await bsc.create_container( 'asynccpkcontainer', container_encryption_scope=TEST_CONTAINER_ENCRYPTION_KEY_SCOPE) container_props = await container_client.get_container_properties() self.assertEqual( container_props.encryption_scope.default_encryption_scope, TEST_CONTAINER_ENCRYPTION_KEY_SCOPE.default_encryption_scope) self.assertEqual(container_props.encryption_scope.prevent_encryption_scope_override, False) async for container in bsc.list_containers(name_starts_with='asynccpkcontainer'): self.assertEqual( container_props.encryption_scope.default_encryption_scope, TEST_CONTAINER_ENCRYPTION_KEY_SCOPE.default_encryption_scope) self.assertEqual(container_props.encryption_scope.prevent_encryption_scope_override, False) blob_client = container_client.get_blob_client("appendblob") # providing encryption scope when upload the blob resp = await blob_client.upload_blob(b'aaaa', BlobType.AppendBlob, encryption_scope=TEST_ENCRYPTION_KEY_SCOPE) # Use the provided encryption scope on the blob self.assertEqual(resp['encryption_scope'], TEST_ENCRYPTION_KEY_SCOPE) await container_client.delete_container()
async def test_create_page_blob_with_chunks(self, resource_group, location, storage_account, storage_account_key): # test chunking functionality by reducing the size of each chunk, # otherwise the tests would take too long to execute bsc = BlobServiceClient( self.account_url(storage_account, "blob"), storage_account_key, max_single_put_size=1024, min_large_block_upload_threshold=1024, max_block_size=1024, max_page_size=1024, transport=AiohttpTestTransport(connection_data_block_size=1024)) await self._setup(bsc) # Act blob_client = bsc.get_blob_client(self.container_name, self._get_blob_reference()) page_blob_prop = await blob_client.upload_blob(self.byte_data, blob_type=BlobType.PageBlob, max_concurrency=2, encryption_scope=TEST_ENCRYPTION_KEY_SCOPE) # Assert self.assertIsNotNone(page_blob_prop['etag']) self.assertIsNotNone(page_blob_prop['last_modified']) self.assertTrue(page_blob_prop['request_server_encrypted']) self.assertEqual(page_blob_prop['encryption_scope'], TEST_ENCRYPTION_KEY_SCOPE) # Act get the blob content blob = await blob_client.download_blob() # Assert content was retrieved with the cpk self.assertEqual(await blob.readall(), self.byte_data) self.assertEqual(blob.properties.encryption_scope, TEST_ENCRYPTION_KEY_SCOPE)
async def test_append_block(self, resource_group, location, storage_account, storage_account_key): # Arrange # test chunking functionality by reducing the size of each chunk, # otherwise the tests would take too long to execute bsc = BlobServiceClient( self.account_url(storage_account, "blob"), storage_account_key, max_single_put_size=1024, min_large_block_upload_threshold=1024, max_block_size=1024, max_page_size=1024, transport=AiohttpTestTransport(connection_data_block_size=1024)) await self._setup(bsc) blob_client = await self._create_append_blob(bsc, encryption_scope=TEST_ENCRYPTION_KEY_SCOPE) # Act for content in [b'AAA', b'BBB', b'CCC']: append_blob_prop = await blob_client.append_block(content, encryption_scope=TEST_ENCRYPTION_KEY_SCOPE) # Assert self.assertIsNotNone(append_blob_prop['etag']) self.assertIsNotNone(append_blob_prop['last_modified']) self.assertTrue(append_blob_prop['request_server_encrypted']) self.assertEqual(append_blob_prop['encryption_scope'], TEST_ENCRYPTION_KEY_SCOPE) # Act get the blob content blob = await blob_client.download_blob() # Assert content was retrieved with the cpk self.assertEqual(await blob.readall(), b'AAABBBCCC') self.assertEqual(blob.properties.encryption_scope, TEST_ENCRYPTION_KEY_SCOPE)
async def test_create_block_blob_with_single_chunk(self, resource_group, location, storage_account, storage_account_key): # Act # test chunking functionality by reducing the size of each chunk, # otherwise the tests would take too long to execute bsc = BlobServiceClient( self.account_url(storage_account, "blob"), storage_account_key, max_single_put_size=1024, min_large_block_upload_threshold=1024, max_block_size=1024, max_page_size=1024, transport=AiohttpTestTransport(connection_data_block_size=1024)) await self._setup(bsc) data = b'AAABBBCCC' # create_blob_from_bytes forces the in-memory chunks to be used blob_client, upload_response = await self._create_block_blob(bsc, data=data, encryption_scope=TEST_ENCRYPTION_KEY_SCOPE) # Assert self.assertIsNotNone(upload_response['etag']) self.assertIsNotNone(upload_response['last_modified']) self.assertTrue(upload_response['request_server_encrypted']) self.assertEqual(upload_response['encryption_scope'], TEST_ENCRYPTION_KEY_SCOPE) # Act get the blob content blob = await blob_client.download_blob() # Assert content was retrieved with the cpk self.assertEqual(await blob.readall(), data) self.assertEqual(blob.properties.etag, upload_response['etag']) self.assertEqual(blob.properties.last_modified, upload_response['last_modified']) self.assertEqual(blob.properties.encryption_scope, TEST_ENCRYPTION_KEY_SCOPE)
async def test_ors_source(self, resource_group, location, storage_account, storage_account_key): # Arrange bsc = BlobServiceClient( self.account_url(storage_account, "blob"), credential=storage_account_key, transport=AiohttpTestTransport(connection_data_block_size=1024)) blob = bsc.get_blob_client(container=self.SRC_CONTAINER, blob=self.BLOB_NAME) # Act props = await blob.get_blob_properties() # Assert self.assertIsInstance(props, BlobProperties) self.assertIsNotNone(props.object_replication_source_properties) for replication_policy in props.object_replication_source_properties: self.assertNotEqual(replication_policy.policy_id, '') self.assertIsNotNone(replication_policy.rules) for rule in replication_policy.rules: self.assertNotEqual(rule.rule_id, '') self.assertIsNotNone(rule.status) self.assertNotEqual(rule.status, '') # Check that the download function gives back the same result stream = await blob.download_blob() self.assertEqual(stream.properties.object_replication_source_properties, props.object_replication_source_properties)
async def test_create_append_blob_with_chunks(self, resource_group, location, storage_account, storage_account_key): # Arrange # test chunking functionality by reducing the size of each chunk, # otherwise the tests would take too long to execute bsc = BlobServiceClient( self._account_url(storage_account.name), storage_account_key, max_single_put_size=1024, min_large_block_upload_threshold=1024, max_block_size=1024, max_page_size=1024, transport=AiohttpTestTransport(connection_data_block_size=1024)) await self._setup(bsc) blob_client = await self._create_append_blob(bsc, cpk=TEST_ENCRYPTION_KEY) # Act append_blob_prop = await blob_client.upload_blob(self.byte_data, blob_type=BlobType.AppendBlob, cpk=TEST_ENCRYPTION_KEY) # Assert self.assertIsNotNone(append_blob_prop['etag']) self.assertIsNotNone(append_blob_prop['last_modified']) self.assertTrue(append_blob_prop['request_server_encrypted']) self.assertEqual(append_blob_prop['encryption_key_sha256'], TEST_ENCRYPTION_KEY.key_hash) # Act get the blob content without cpk should fail with self.assertRaises(HttpResponseError): await blob_client.download_blob() # Act get the blob content blob = await blob_client.download_blob(cpk=TEST_ENCRYPTION_KEY) # Assert content was retrieved with the cpk self.assertEqual(await blob.readall(), self.byte_data) self.assertEqual(blob.properties.encryption_key_sha256, TEST_ENCRYPTION_KEY.key_hash)
async def test_user_agent_custom_async(self, storage_account_name, storage_account_key): custom_app = "TestApp/v1.0" service = BlobServiceClient(self.account_url(storage_account_name, "blob"), credential=storage_account_key, user_agent=custom_app) def callback(response): self.assertTrue('User-Agent' in response.http_request.headers) assert ("TestApp/v1.0 azsdk-python-storage-blob/{} Python/{} ({})". format(VERSION, platform.python_version(), platform.platform()) ) in response.http_request.headers['User-Agent'] await service.get_service_properties(raw_response_hook=callback) def callback(response): self.assertTrue('User-Agent' in response.http_request.headers) assert ( "TestApp/v2.0 TestApp/v1.0 azsdk-python-storage-blob/{} Python/{} ({})" .format(VERSION, platform.python_version(), platform.platform()) ) in response.http_request.headers['User-Agent'] await service.get_service_properties(raw_response_hook=callback, user_agent="TestApp/v2.0")
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, transport=AiohttpTestTransport()) 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) # generate a SAS so that it is accessible with a URL sas_token = blob.generate_shared_access_signature( permission=BlobSasPermissions(read=True), expiry=datetime.utcnow() + timedelta(hours=1), ) self.source_blob_url = BlobClient.from_blob_url(blob.url, credential=sas_token).url
async def test_retry_put_block_with_non_seekable_stream_fail_async( self, resource_group, location, storage_account, storage_account_key): if not self.is_live: pytest.skip("live only") # Arrange bsc = BlobServiceClient(self._account_url(storage_account.name), credential=storage_account_key, retry_policy=self.retry, transport=AiohttpTestTransport()) await self._setup(bsc) blob_name = self.get_resource_name('blob') data = self.get_random_bytes(PUT_BLOCK_SIZE) data_stream = self.NonSeekableStream(BytesIO(data)) # rig the response so that it fails for a single time responder = ResponseCallback(status=201, new_status=408) # Act blob = bsc.get_blob_client(self.container_name, blob_name) with self.assertRaises(HttpResponseError) as error: await blob.stage_block( 1, data_stream, length=PUT_BLOCK_SIZE, raw_response_hook=responder.override_first_status) # Assert self.assertEqual(error.exception.response.status_code, 408)
def setUp(self): super(StorageCPKAsyncTest, self).setUp() url = self._get_account_url() # test chunking functionality by reducing the size of each chunk, # otherwise the tests would take too long to execute self.bsc = BlobServiceClient( url, credential=self.settings.STORAGE_ACCOUNT_KEY, connection_data_block_size=1024, max_single_put_size=1024, min_large_block_upload_threshold=1024, max_block_size=1024, max_page_size=1024, transport=AiohttpTestTransport()) self.config = self.bsc._config self.container_name = self.get_resource_name('utcontainer') # prep some test data so that they can be used in upload tests self.byte_data = self.get_random_bytes(64 * 1024) if not self.is_playback(): loop = asyncio.get_event_loop() try: loop.run_until_complete( self.bsc.create_container(self.container_name)) except: pass
async def test_snapshot_blob(self, resource_group, location, storage_account, storage_account_key): # Arrange # test chunking functionality by reducing the size of each chunk, # otherwise the tests would take too long to execute bsc = BlobServiceClient( self.account_url(storage_account, "blob"), storage_account_key, max_single_put_size=1024, min_large_block_upload_threshold=1024, max_block_size=1024, max_page_size=1024, transport=AiohttpTestTransport(connection_data_block_size=1024)) await self._setup(bsc) blob_client, _ = await self._create_block_blob( bsc, data=b'AAABBBCCC', encryption_scope=TEST_ENCRYPTION_KEY_SCOPE) # Act without cpk should not work with self.assertRaises(HttpResponseError): await blob_client.create_snapshot() # Act with cpk should work blob_snapshot = await blob_client.create_snapshot( encryption_scope=TEST_ENCRYPTION_KEY_SCOPE) # Assert self.assertIsNotNone(blob_snapshot)
async def test_logging_request_and_response_body(self, storage_account_name, storage_account_key): bsc = BlobServiceClient(self.account_url(storage_account_name, "blob"), storage_account_key, transport=AiohttpTestTransport(), logging_enable=True) await self._setup(bsc) # Arrange container = bsc.get_container_client(self.container_name) request_body = 'testloggingbody' blob_name = self.get_resource_name("testloggingblob") blob_client = container.get_blob_client(blob_name) await blob_client.upload_blob(request_body, overwrite=True) # Act with LogCaptured(self) as log_captured: await blob_client.download_blob() log_as_str = log_captured.getvalue() self.assertFalse(request_body in log_as_str) with LogCaptured(self) as log_captured: await blob_client.upload_blob(request_body, overwrite=True, logging_body=True) log_as_str = log_captured.getvalue() self.assertTrue(request_body in log_as_str) self.assertEqual(log_as_str.count(request_body), 1)
async def test_create_block_blob_with_chunks(self, resource_group, location, storage_account, storage_account_key): # parallel operation # Arrange bsc = BlobServiceClient( self.account_url(storage_account, "blob"), storage_account_key, max_single_put_size=1024, min_large_block_upload_threshold=1024, max_block_size=1024, max_page_size=1024, transport=AiohttpTestTransport(connection_data_block_size=1024)) await self._setup(bsc) # to force the in-memory chunks to be used self.config.use_byte_buffer = True # Act # create_blob_from_bytes forces the in-memory chunks to be used blob_client, upload_response = await self._create_block_blob(bsc, data=self.byte_data, encryption_scope=TEST_ENCRYPTION_KEY_SCOPE, max_concurrency=2) # Assert self.assertIsNotNone(upload_response['etag']) self.assertIsNotNone(upload_response['last_modified']) self.assertTrue(upload_response['request_server_encrypted']) self.assertEqual(upload_response['encryption_scope'], TEST_ENCRYPTION_KEY_SCOPE) # Act get the blob content blob = await blob_client.download_blob() # Assert content was retrieved with the cpk self.assertEqual(await blob.readall(), self.byte_data) self.assertEqual(blob.properties.etag, upload_response['etag']) self.assertEqual(blob.properties.last_modified, upload_response['last_modified']) self.assertEqual(blob.properties.encryption_scope, TEST_ENCRYPTION_KEY_SCOPE)
async def test_sas_signature_is_scrubbed_off(self, storage_account_name, storage_account_key): # Test can only run live bsc = BlobServiceClient(self.account_url(storage_account_name, "blob"), storage_account_key) await self._setup(bsc) # Arrange container = bsc.get_container_client(self.container_name) token = generate_container_sas( container.account_name, container.container_name, account_key=container.credential.account_key, permission=ContainerSasPermissions(read=True), expiry=datetime.utcnow() + timedelta(hours=1), ) # parse out the signed signature token_components = parse_qs(token) signed_signature = quote( token_components[QueryStringConstants.SIGNED_SIGNATURE][0]) sas_service = ContainerClient.from_container_url(container.url, credential=token) # Act with LogCaptured(self) as log_captured: await sas_service.get_account_information(logging_enable=True) log_as_str = log_captured.getvalue() # Assert # make sure the query parameter 'sig' is logged, but its value is not self.assertTrue( QueryStringConstants.SIGNED_SIGNATURE in log_as_str) self.assertFalse(signed_signature in log_as_str)
async def test_set_cors(self, resource_group, location, storage_account, storage_account_key): bsc = BlobServiceClient(self.account_url(storage_account, "blob"), credential=storage_account_key, transport=AiohttpTestTransport()) cors_rule1 = CorsRule(['www.xyz.com'], ['GET']) allowed_origins = ['www.xyz.com', "www.ab.com", "www.bc.com"] allowed_methods = ['GET', 'PUT'] max_age_in_seconds = 500 exposed_headers = [ "x-ms-meta-data*", "x-ms-meta-source*", "x-ms-meta-abc", "x-ms-meta-bcd" ] allowed_headers = [ "x-ms-meta-data*", "x-ms-meta-target*", "x-ms-meta-xyz", "x-ms-meta-foo" ] cors_rule2 = CorsRule(allowed_origins, allowed_methods, max_age_in_seconds=max_age_in_seconds, exposed_headers=exposed_headers, allowed_headers=allowed_headers) cors = [cors_rule1, cors_rule2] # Act await bsc.set_service_properties(cors=cors) # Assert received_props = await bsc.get_service_properties() self._assert_cors_equal(received_props['cors'], cors)
async def test_append_block_from_url(self, storage_account_name, storage_account_key): # Arrange # test chunking functionality by reducing the size of each chunk, # otherwise the tests would take too long to execute bsc = BlobServiceClient( self.account_url(storage_account_name, "blob"), storage_account_key, max_single_put_size=1024, min_large_block_upload_threshold=1024, max_block_size=1024, max_page_size=1024, transport=AiohttpTestTransport(connection_data_block_size=1024)) await self._setup(bsc) source_blob_name = self.get_resource_name("sourceblob") self.config.use_byte_buffer = True # chunk upload source_blob_client, _ = await self._create_block_blob( bsc, blob_name=source_blob_name, data=self.byte_data) source_blob_sas = generate_blob_sas( source_blob_client.account_name, source_blob_client.container_name, source_blob_client.blob_name, snapshot=source_blob_client.snapshot, account_key=source_blob_client.credential.account_key, permission=BlobSasPermissions(read=True), expiry=datetime.utcnow() + timedelta(hours=1)) source_blob_url = source_blob_client.url + "?" + source_blob_sas self.config.use_byte_buffer = False destination_blob_client = await self._create_append_blob( bsc, cpk=TEST_ENCRYPTION_KEY) # Act append_blob_prop = await destination_blob_client.append_block_from_url( source_blob_url, source_offset=0, source_length=4 * 1024, cpk=TEST_ENCRYPTION_KEY) # Assert self.assertIsNotNone(append_blob_prop['etag']) self.assertIsNotNone(append_blob_prop['last_modified']) # TODO: verify that the swagger is correct, header wasn't added for the response # self.assertTrue(append_blob_prop['request_server_encrypted']) self.assertEqual(append_blob_prop['encryption_key_sha256'], TEST_ENCRYPTION_KEY.key_hash) # Act get the blob content without cpk should fail with self.assertRaises(HttpResponseError): await destination_blob_client.download_blob() # Act get the blob content blob = await destination_blob_client.download_blob( cpk=TEST_ENCRYPTION_KEY) # Assert content was retrieved with the cpk self.assertEqual(await blob.readall(), self.byte_data[0:4 * 1024]) self.assertEqual(blob.properties.encryption_key_sha256, TEST_ENCRYPTION_KEY.key_hash)
async def test_retention_too_long(self, storage_account_name, storage_account_key): bsc = BlobServiceClient(self.account_url(storage_account_name, "blob"), credential=storage_account_key, transport=AiohttpTestTransport()) minute_metrics = Metrics(enabled=True, include_apis=True, retention_policy=RetentionPolicy(enabled=True, days=366)) # Assert with self.assertRaises(HttpResponseError): await bsc.set_service_properties(None, None, minute_metrics)
async def test_user_agent_default_async(self, resource_group, location, storage_account, storage_account_key): service = BlobServiceClient(self.account_url(storage_account, "blob"), credential=storage_account_key, transport=AiohttpTestTransport()) def callback(response): self.assertTrue('User-Agent' in response.http_request.headers) assert "azsdk-python-storage-blob/{}".format(VERSION) in response.http_request.headers['User-Agent'] await service.get_service_properties(raw_response_hook=callback)
async def test_empty_set_service_properties_exception( self, resource_group, location, storage_account, storage_account_key): bsc = BlobServiceClient(self.account_url(storage_account, "blob"), credential=storage_account_key, transport=AiohttpTestTransport()) with self.assertRaises(ValueError): await bsc.set_service_properties()