diff --git a/sdk/tables/azure-data-tables/tests/_shared/asynctestcase.py b/sdk/tables/azure-data-tables/tests/_shared/asynctestcase.py index 69cd33157efe..feabcbe3944b 100644 --- a/sdk/tables/azure-data-tables/tests/_shared/asynctestcase.py +++ b/sdk/tables/azure-data-tables/tests/_shared/asynctestcase.py @@ -9,8 +9,6 @@ from .testcase import TableTestCase -LOGGING_FORMAT = '%(asctime)s %(name)-20s %(levelname)-5s %(message)s' - class AsyncFakeTokenCredential(object): """Protocol for classes able to provide OAuth tokens. :param str scopes: Lets you specify the type of access needed. @@ -23,16 +21,6 @@ async def get_token(self, *args): class AsyncTableTestCase(TableTestCase): - @staticmethod - def generate_oauth_token(self): - if self.is_live: - from azure.identity.aio import ClientSecretCredential - return ClientSecretCredential( - self.get_settings_value("TENANT_ID"), - self.get_settings_value("CLIENT_ID"), - self.get_settings_value("CLIENT_SECRET"), - ) - return self.generate_fake_token() def generate_fake_token(self): return AsyncFakeTokenCredential() diff --git a/sdk/tables/azure-data-tables/tests/_shared/testcase.py b/sdk/tables/azure-data-tables/tests/_shared/testcase.py index 16804952c029..baec5c2ca926 100644 --- a/sdk/tables/azure-data-tables/tests/_shared/testcase.py +++ b/sdk/tables/azure-data-tables/tests/_shared/testcase.py @@ -7,33 +7,21 @@ from __future__ import division from contextlib import contextmanager import os -import time from datetime import datetime, timedelta - -import zlib -import sys import string -import random -import re import logging -from devtools_testutils import AzureTestCase -from azure_devtools.scenario_tests import RecordingProcessor, AzureTestError -try: - from cStringIO import StringIO -except ImportError: - from io import StringIO - -from azure.core.credentials import AccessToken - -from azure.data.tables import generate_account_sas, AccountSasPermissions, ResourceTypes import pytest +from devtools_testutils import AzureTestCase +from azure.core.credentials import AccessToken +from azure.data.tables import generate_account_sas, AccountSasPermissions, ResourceTypes LOGGING_FORMAT = '%(asctime)s %(name)-20s %(levelname)-5s %(message)s' SLEEP_DELAY = 30 + class FakeTokenCredential(object): """Protocol for classes able to provide OAuth tokens. :param str scopes: Lets you specify the type of access needed. @@ -45,28 +33,7 @@ def get_token(self, *args): return self.token -class XMSRequestIDBody(RecordingProcessor): - """This process is used for Storage batch call only, to avoid the echo policy. - """ - def process_response(self, response): - content_type = None - for key, value in response.get('headers', {}).items(): - if key.lower() == 'content-type': - content_type = (value[0] if isinstance(value, list) else value).lower() - break - - if content_type and 'multipart/mixed' in content_type: - response['body']['string'] = re.sub(b"x-ms-client-request-id: [a-f0-9-]+\r\n", b"", response['body']['string']) - - return response - - -class TableTestCase(AzureTestCase): - - def __init__(self, *args, **kwargs): - super(TableTestCase, self).__init__(*args, **kwargs) - self.replay_processors.append(XMSRequestIDBody()) - self._RESOURCE_GROUP = None, +class TableTestCase(object): def connection_string(self, account, key): return "DefaultEndpointsProtocol=https;AccountName=" + account + ";AccountKey=" + str(key) + ";EndpointSuffix=core.windows.net" @@ -90,97 +57,6 @@ def account_url(self, account, endpoint_type): if endpoint_type == "cosmos": return "https://{}.table.cosmos.azure.com".format(account) - - def configure_logging(self): - try: - enable_logging = self.get_settings_value("ENABLE_LOGGING") - except AzureTestError: - enable_logging = True # That's the default value in fake settings - - self.enable_logging() if enable_logging else self.disable_logging() - - def enable_logging(self): - handler = logging.StreamHandler() - handler.setFormatter(logging.Formatter(LOGGING_FORMAT)) - self.logger.handlers = [handler] - self.logger.setLevel(logging.INFO) - self.logger.propagate = True - self.logger.disabled = False - - def disable_logging(self): - self.logger.propagate = False - self.logger.disabled = True - self.logger.handlers = [] - - def sleep(self, seconds): - if self.is_live: - time.sleep(seconds) - - def get_random_bytes(self, size): - # recordings don't like random stuff. making this more - # deterministic. - return b'a'*size - - def get_random_text_data(self, size): - '''Returns random unicode text data exceeding the size threshold for - chunking blob upload.''' - checksum = zlib.adler32(self.qualified_test_name.encode()) & 0xffffffff - rand = random.Random(checksum) - text = u'' - words = [u'hello', u'world', u'python', u'啊齄丂狛狜'] - while (len(text) < size): - index = int(rand.random()*(len(words) - 1)) - text = text + u' ' + words[index] - - return text - - @staticmethod - def _set_test_proxy(service, settings): - if settings.USE_PROXY: - service.set_proxy( - settings.PROXY_HOST, - settings.PROXY_PORT, - settings.PROXY_USER, - settings.PROXY_PASSWORD, - ) - - def assertNamedItemInContainer(self, container, item_name, msg=None): - def _is_string(obj): - if sys.version_info >= (3,): - return isinstance(obj, str) - else: - return isinstance(obj, basestring) - for item in container: - if _is_string(item): - if item == item_name: - return - elif item.name == item_name: - return - elif hasattr(item, 'snapshot') and item.snapshot == item_name: - return - - - standardMsg = '{0} not found in {1}'.format( - repr(item_name), [str(c) for c in container]) - self.fail(self._formatMessage(msg, standardMsg)) - - def assertNamedItemNotInContainer(self, container, item_name, msg=None): - for item in container: - if item.name == item_name: - standardMsg = '{0} unexpectedly found in {1}'.format( - repr(item_name), repr(container)) - self.fail(self._formatMessage(msg, standardMsg)) - - def generate_oauth_token(self): - if self.is_live: - from azure.identity import ClientSecretCredential - return ClientSecretCredential( - self.get_settings_value("TENANT_ID"), - self.get_settings_value("CLIENT_ID"), - self.get_settings_value("CLIENT_SECRET"), - ) - return self.generate_fake_token() - def generate_sas_token(self): fake_key = 'a'*30 + 'b'*30 diff --git a/sdk/tables/azure-data-tables/tests/recordings/test_table_client.test_response_callback.yaml b/sdk/tables/azure-data-tables/tests/recordings/test_table_client.test_response_callback.yaml deleted file mode 100644 index fd9bd5a4d21e..000000000000 --- a/sdk/tables/azure-data-tables/tests/recordings/test_table_client.test_response_callback.yaml +++ /dev/null @@ -1,39 +0,0 @@ -interactions: -- request: - body: null - headers: - Accept: - - application/xml - Accept-Encoding: - - gzip, deflate - Connection: - - keep-alive - Date: - - Wed, 01 Jul 2020 18:18:37 GMT - User-Agent: - - azsdk-python-storage-table/2019-07-07 Python/3.8.3 (Windows-10-10.0.19041-SP0) - x-ms-date: - - Wed, 01 Jul 2020 18:18:37 GMT - x-ms-version: - - '2019-07-07' - method: GET - uri: https://storagename.table.core.windows.net/?restype=service&comp=properties - response: - body: - string: "\uFEFF1.0falsefalsefalsefalse1.0truetruetrue71.0falsefalse" - headers: - content-type: - - application/xml - date: - - Wed, 01 Jul 2020 18:18:35 GMT - server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - transfer-encoding: - - chunked - x-ms-version: - - '2019-07-07' - status: - code: 200 - message: OK -version: 1 diff --git a/sdk/tables/azure-data-tables/tests/recordings/test_table_client.test_service_client_create_table.yaml b/sdk/tables/azure-data-tables/tests/recordings/test_table_client.test_service_client_create_table.yaml deleted file mode 100644 index 2f34fe002e7a..000000000000 --- a/sdk/tables/azure-data-tables/tests/recordings/test_table_client.test_service_client_create_table.yaml +++ /dev/null @@ -1,101 +0,0 @@ -interactions: -- request: - body: '{"TableName": "foo"}' - headers: - Accept: - - application/json;odata=minimalmetadata - Accept-Encoding: - - gzip, deflate - Connection: - - keep-alive - Content-Length: - - '20' - Content-Type: - - application/json;odata=nometadata - DataServiceVersion: - - '3.0' - Date: - - Tue, 25 Aug 2020 20:12:58 GMT - User-Agent: - - azsdk-python-data-tables/2019-07-07 Python/3.8.4 (Windows-10-10.0.19041-SP0) - x-ms-date: - - Tue, 25 Aug 2020 20:12:58 GMT - x-ms-version: - - '2019-07-07' - method: POST - uri: https://storagename.table.core.windows.net/Tables - response: - body: - string: '{"odata.metadata":"https://storagename.table.core.windows.net/$metadata#Tables/@Element","TableName":"foo"}' - headers: - cache-control: - - no-cache - content-type: - - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 - date: - - Tue, 25 Aug 2020 20:12:59 GMT - location: - - https://storagename.table.core.windows.net/Tables('foo') - server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - transfer-encoding: - - chunked - x-content-type-options: - - nosniff - x-ms-version: - - '2019-07-07' - status: - code: 201 - message: Created -- request: - body: '{"PartitionKey": "pk", "RowKey": "rk", "Value": "2", "Value@odata.type": - "Edm.Int64"}' - headers: - Accept: - - application/json;odata=minimalmetadata - Accept-Encoding: - - gzip, deflate - Connection: - - keep-alive - Content-Length: - - '85' - Content-Type: - - application/json;odata=nometadata - DataServiceVersion: - - '3.0' - Date: - - Tue, 25 Aug 2020 20:12:59 GMT - User-Agent: - - azsdk-python-data-tables/2019-07-07 Python/3.8.4 (Windows-10-10.0.19041-SP0) - x-ms-date: - - Tue, 25 Aug 2020 20:12:59 GMT - x-ms-version: - - '2019-07-07' - method: POST - uri: https://storagename.table.core.windows.net/foo - response: - body: - string: '{"odata.metadata":"https://storagename.table.core.windows.net/$metadata#foo/@Element","odata.etag":"W/\"datetime''2020-08-25T20%3A12%3A59.6939685Z''\"","PartitionKey":"pk","RowKey":"rk","Timestamp":"2020-08-25T20:12:59.6939685Z","Value@odata.type":"Edm.Int64","Value":"2"}' - headers: - cache-control: - - no-cache - content-type: - - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 - date: - - Tue, 25 Aug 2020 20:12:59 GMT - etag: - - W/"datetime'2020-08-25T20%3A12%3A59.6939685Z'" - location: - - https://storagename.table.core.windows.net/foo(PartitionKey='pk',RowKey='rk') - server: - - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - transfer-encoding: - - chunked - x-content-type-options: - - nosniff - x-ms-version: - - '2019-07-07' - status: - code: 201 - message: Created -version: 1 diff --git a/sdk/tables/azure-data-tables/tests/recordings/test_table_client.test_user_agent_custom.yaml b/sdk/tables/azure-data-tables/tests/recordings/test_table_client.test_user_agent_custom.yaml index a132cdfc1ba4..052b07dc743b 100644 --- a/sdk/tables/azure-data-tables/tests/recordings/test_table_client.test_user_agent_custom.yaml +++ b/sdk/tables/azure-data-tables/tests/recordings/test_table_client.test_user_agent_custom.yaml @@ -11,25 +11,25 @@ interactions: DataServiceVersion: - '3.0' Date: - - Fri, 18 Dec 2020 17:08:50 GMT + - Wed, 03 Feb 2021 20:56:20 GMT User-Agent: - - TestApp/v1.0 azsdk-python-data-tables/12.0.0b4 Python/3.9.0rc1 (Windows-10-10.0.19041-SP0) + - TestApp/v1.0 azsdk-python-data-tables/12.0.0b5 Python/3.9.0rc1 (Windows-10-10.0.19041-SP0) x-ms-date: - - Fri, 18 Dec 2020 17:08:50 GMT + - Wed, 03 Feb 2021 20:56:20 GMT x-ms-version: - '2019-02-02' method: GET uri: https://fake_table_account.table.core.windows.net/Tables response: body: - string: '{"odata.metadata":"https://fake_table_account.table.core.windows.net/$metadata#Tables","value":[{"TableName":"listtable0cac14c3"},{"TableName":"listtable1cac14c3"},{"TableName":"listtable2cac14c3"},{"TableName":"listtable3cac14c3"}]}' + string: '{"odata.metadata":"https://fake_table_account.table.core.windows.net/$metadata#Tables","value":[]}' headers: cache-control: - no-cache content-type: - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 date: - - Fri, 18 Dec 2020 17:08:50 GMT + - Wed, 03 Feb 2021 20:56:20 GMT server: - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 transfer-encoding: @@ -53,26 +53,26 @@ interactions: DataServiceVersion: - '3.0' Date: - - Fri, 18 Dec 2020 17:08:51 GMT + - Wed, 03 Feb 2021 20:56:21 GMT User-Agent: - - TestApp/v2.0 TestApp/v1.0 azsdk-python-data-tables/12.0.0b4 Python/3.9.0rc1 + - TestApp/v2.0 TestApp/v1.0 azsdk-python-data-tables/12.0.0b5 Python/3.9.0rc1 (Windows-10-10.0.19041-SP0) x-ms-date: - - Fri, 18 Dec 2020 17:08:51 GMT + - Wed, 03 Feb 2021 20:56:21 GMT x-ms-version: - '2019-02-02' method: GET uri: https://fake_table_account.table.core.windows.net/Tables response: body: - string: '{"odata.metadata":"https://fake_table_account.table.core.windows.net/$metadata#Tables","value":[{"TableName":"listtable0cac14c3"},{"TableName":"listtable1cac14c3"},{"TableName":"listtable2cac14c3"},{"TableName":"listtable3cac14c3"}]}' + string: '{"odata.metadata":"https://fake_table_account.table.core.windows.net/$metadata#Tables","value":[]}' headers: cache-control: - no-cache content-type: - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 date: - - Fri, 18 Dec 2020 17:08:51 GMT + - Wed, 03 Feb 2021 20:56:20 GMT server: - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 transfer-encoding: diff --git a/sdk/tables/azure-data-tables/tests/recordings/test_table_client.test_user_agent_default.yaml b/sdk/tables/azure-data-tables/tests/recordings/test_table_client.test_user_agent_default.yaml index 1379bcf2cbe0..9ba5e2cece5b 100644 --- a/sdk/tables/azure-data-tables/tests/recordings/test_table_client.test_user_agent_default.yaml +++ b/sdk/tables/azure-data-tables/tests/recordings/test_table_client.test_user_agent_default.yaml @@ -11,25 +11,25 @@ interactions: DataServiceVersion: - '3.0' Date: - - Fri, 18 Dec 2020 17:08:51 GMT + - Wed, 03 Feb 2021 20:56:21 GMT User-Agent: - - azsdk-python-data-tables/12.0.0b4 Python/3.9.0rc1 (Windows-10-10.0.19041-SP0) + - azsdk-python-data-tables/12.0.0b5 Python/3.9.0rc1 (Windows-10-10.0.19041-SP0) x-ms-date: - - Fri, 18 Dec 2020 17:08:51 GMT + - Wed, 03 Feb 2021 20:56:21 GMT x-ms-version: - '2019-02-02' method: GET uri: https://fake_table_account.table.core.windows.net/Tables response: body: - string: '{"odata.metadata":"https://fake_table_account.table.core.windows.net/$metadata#Tables","value":[{"TableName":"listtable0cac14c3"},{"TableName":"listtable1cac14c3"},{"TableName":"listtable2cac14c3"},{"TableName":"listtable3cac14c3"}]}' + string: '{"odata.metadata":"https://fake_table_account.table.core.windows.net/$metadata#Tables","value":[]}' headers: cache-control: - no-cache content-type: - application/json;odata=minimalmetadata;streaming=true;charset=utf-8 date: - - Fri, 18 Dec 2020 17:08:51 GMT + - Wed, 03 Feb 2021 20:56:21 GMT server: - Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 transfer-encoding: diff --git a/sdk/tables/azure-data-tables/tests/recordings/test_table_client_cosmos.test_user_agent_custom.yaml b/sdk/tables/azure-data-tables/tests/recordings/test_table_client_cosmos.test_user_agent_custom.yaml index 1a7df4ec0508..6c7412bda73c 100644 --- a/sdk/tables/azure-data-tables/tests/recordings/test_table_client_cosmos.test_user_agent_custom.yaml +++ b/sdk/tables/azure-data-tables/tests/recordings/test_table_client_cosmos.test_user_agent_custom.yaml @@ -11,23 +11,60 @@ interactions: DataServiceVersion: - '3.0' Date: - - Fri, 30 Oct 2020 21:53:05 GMT + - Wed, 03 Feb 2021 21:17:55 GMT User-Agent: - - TestApp/v1.0 azsdk-python-data-tables/12.0.0b3 Python/3.9.0rc1 (Windows-10-10.0.19041-SP0) + - TestApp/v1.0 azsdk-python-data-tables/12.0.0b5 Python/3.9.0rc1 (Windows-10-10.0.19041-SP0) x-ms-date: - - Fri, 30 Oct 2020 21:53:05 GMT + - Wed, 03 Feb 2021 21:17:55 GMT x-ms-version: - '2019-02-02' method: GET - uri: https://tablestestcosmosname.table.cosmos.azure.com/Tables + uri: https://fake_cosmos_account.table.cosmos.azure.com/Tables response: body: - string: '' + string: '{"value":[],"odata.metadata":"https://fake_cosmos_account.table.cosmos.azure.com/$metadata#Tables"}' headers: content-type: - application/json;odata=minimalmetadata date: - - Fri, 30 Oct 2020 21:53:06 GMT + - Wed, 03 Feb 2021 21:17:56 GMT + server: + - Microsoft-HTTPAPI/2.0 + transfer-encoding: + - chunked + status: + code: 200 + message: Ok +- request: + body: null + headers: + Accept: + - application/json;odata=minimalmetadata + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + DataServiceVersion: + - '3.0' + Date: + - Wed, 03 Feb 2021 21:17:56 GMT + User-Agent: + - TestApp/v2.0 TestApp/v1.0 azsdk-python-data-tables/12.0.0b5 Python/3.9.0rc1 + (Windows-10-10.0.19041-SP0) + x-ms-date: + - Wed, 03 Feb 2021 21:17:56 GMT + x-ms-version: + - '2019-02-02' + method: GET + uri: https://fake_cosmos_account.table.cosmos.azure.com/Tables + response: + body: + string: '{"value":[],"odata.metadata":"https://fake_cosmos_account.table.cosmos.azure.com/$metadata#Tables"}' + headers: + content-type: + - application/json;odata=minimalmetadata + date: + - Wed, 03 Feb 2021 21:17:56 GMT server: - Microsoft-HTTPAPI/2.0 transfer-encoding: diff --git a/sdk/tables/azure-data-tables/tests/recordings/test_table_client_cosmos.test_user_agent_default.yaml b/sdk/tables/azure-data-tables/tests/recordings/test_table_client_cosmos.test_user_agent_default.yaml index 744f0388ee69..14fe819fa136 100644 --- a/sdk/tables/azure-data-tables/tests/recordings/test_table_client_cosmos.test_user_agent_default.yaml +++ b/sdk/tables/azure-data-tables/tests/recordings/test_table_client_cosmos.test_user_agent_default.yaml @@ -11,23 +11,23 @@ interactions: DataServiceVersion: - '3.0' Date: - - Tue, 22 Dec 2020 18:45:42 GMT + - Wed, 03 Feb 2021 21:18:26 GMT User-Agent: - - azsdk-python-data-tables/12.0.0b4 Python/2.7.18 (Windows-10-10.0.19041) + - azsdk-python-data-tables/12.0.0b5 Python/3.9.0rc1 (Windows-10-10.0.19041-SP0) x-ms-date: - - Tue, 22 Dec 2020 18:45:42 GMT + - Wed, 03 Feb 2021 21:18:26 GMT x-ms-version: - '2019-02-02' method: GET uri: https://fake_cosmos_account.table.cosmos.azure.com/Tables response: body: - string: !!python/unicode '{"value":[],"odata.metadata":"https://fake_cosmos_account.table.cosmos.azure.com/$metadata#Tables"}' + string: '{"value":[],"odata.metadata":"https://fake_cosmos_account.table.cosmos.azure.com/$metadata#Tables"}' headers: content-type: - application/json;odata=minimalmetadata date: - - Tue, 22 Dec 2020 18:45:41 GMT + - Wed, 03 Feb 2021 21:18:27 GMT server: - Microsoft-HTTPAPI/2.0 transfer-encoding: diff --git a/sdk/tables/azure-data-tables/tests/recordings/test_table_service_properties_async.test_set_cors.yaml b/sdk/tables/azure-data-tables/tests/recordings/test_table_service_properties_async.test_set_cors.yaml deleted file mode 100644 index 5f2105c9acc7..000000000000 --- a/sdk/tables/azure-data-tables/tests/recordings/test_table_service_properties_async.test_set_cors.yaml +++ /dev/null @@ -1,37 +0,0 @@ -interactions: -- request: - body: ' - - www.xyz.comGET0www.xyz.com,www.ab.com,www.bc.comGET,PUTx-ms-meta-data*,x-ms-meta-target*,x-ms-meta-xyz,x-ms-meta-foox-ms-meta-data*,x-ms-meta-source*,x-ms-meta-abc,x-ms-meta-bcd500' - headers: - Content-Length: - - '631' - Content-Type: - - application/xml - Date: - - Mon, 10 Aug 2020 16:44:50 GMT - User-Agent: - - azsdk-python-storage-table/12.0.0b1 Python/3.8.4 (Windows-10-10.0.19041-SP0) - x-ms-date: - - Mon, 10 Aug 2020 16:44:50 GMT - x-ms-version: - - 12.0.0b1 - method: PUT - uri: https://storagename.table.core.windows.net/?restype=service&comp=properties - response: - body: - string: "\uFEFF\r\n\r\n - \ InvalidHeaderValue\r\n The value - for one of the HTTP headers is not in the correct format.\nRequestId:16266bd7-7002-006d-3835-6fffef000000\nTime:2020-08-10T16:44:51.9401828Z\r\n" - headers: - content-length: '371' - content-type: application/xml - date: Mon, 10 Aug 2020 16:44:51 GMT - server: Microsoft-HTTPAPI/2.0 - status: - code: 400 - message: The value for one of the HTTP headers is not in the correct format. - url: https://storagename.table.core.windows.net/?restype=service&comp=properties -version: 1 diff --git a/sdk/tables/azure-data-tables/tests/recordings/test_table_service_properties_async.test_set_hour_metrics.yaml b/sdk/tables/azure-data-tables/tests/recordings/test_table_service_properties_async.test_set_hour_metrics.yaml deleted file mode 100644 index 25ff77268b76..000000000000 --- a/sdk/tables/azure-data-tables/tests/recordings/test_table_service_properties_async.test_set_hour_metrics.yaml +++ /dev/null @@ -1,36 +0,0 @@ -interactions: -- request: - body: ' - - 1.0truetruetrue5' - headers: - Content-Length: - - '267' - Content-Type: - - application/xml - Date: - - Mon, 10 Aug 2020 16:44:51 GMT - User-Agent: - - azsdk-python-storage-table/12.0.0b1 Python/3.8.4 (Windows-10-10.0.19041-SP0) - x-ms-date: - - Mon, 10 Aug 2020 16:44:51 GMT - x-ms-version: - - 12.0.0b1 - method: PUT - uri: https://storagename.table.core.windows.net/?restype=service&comp=properties - response: - body: - string: "\uFEFF\r\n\r\n - \ InvalidHeaderValue\r\n The value - for one of the HTTP headers is not in the correct format.\nRequestId:b6f9f451-0002-008c-7d35-6f189a000000\nTime:2020-08-10T16:44:52.2987018Z\r\n" - headers: - content-length: '371' - content-type: application/xml - date: Mon, 10 Aug 2020 16:44:51 GMT - server: Microsoft-HTTPAPI/2.0 - status: - code: 400 - message: The value for one of the HTTP headers is not in the correct format. - url: https://storagename.table.core.windows.net/?restype=service&comp=properties -version: 1 diff --git a/sdk/tables/azure-data-tables/tests/recordings/test_table_service_properties_async.test_set_logging.yaml b/sdk/tables/azure-data-tables/tests/recordings/test_table_service_properties_async.test_set_logging.yaml deleted file mode 100644 index 3b2ea91b04fa..000000000000 --- a/sdk/tables/azure-data-tables/tests/recordings/test_table_service_properties_async.test_set_logging.yaml +++ /dev/null @@ -1,36 +0,0 @@ -interactions: -- request: - body: ' - - 1.0truetruetruetrue5' - headers: - Content-Length: - - '262' - Content-Type: - - application/xml - Date: - - Mon, 10 Aug 2020 16:38:41 GMT - User-Agent: - - azsdk-python-storage-table/12.0.0b1 Python/3.8.4 (Windows-10-10.0.19041-SP0) - x-ms-date: - - Mon, 10 Aug 2020 16:38:41 GMT - x-ms-version: - - 12.0.0b1 - method: PUT - uri: https://storagename.table.core.windows.net/?restype=service&comp=properties - response: - body: - string: "\uFEFF\r\n\r\n - \ InvalidHeaderValue\r\n The value - for one of the HTTP headers is not in the correct format.\nRequestId:617bd8f1-c002-0116-7534-6fd20a000000\nTime:2020-08-10T16:38:42.9984604Z\r\n" - headers: - content-length: '371' - content-type: application/xml - date: Mon, 10 Aug 2020 16:38:42 GMT - server: Microsoft-HTTPAPI/2.0 - status: - code: 400 - message: The value for one of the HTTP headers is not in the correct format. - url: https://storagename.table.core.windows.net/?restype=service&comp=properties -version: 1 diff --git a/sdk/tables/azure-data-tables/tests/recordings/test_table_service_properties_async.test_set_minute_metrics.yaml b/sdk/tables/azure-data-tables/tests/recordings/test_table_service_properties_async.test_set_minute_metrics.yaml deleted file mode 100644 index 0aa821f62161..000000000000 --- a/sdk/tables/azure-data-tables/tests/recordings/test_table_service_properties_async.test_set_minute_metrics.yaml +++ /dev/null @@ -1,36 +0,0 @@ -interactions: -- request: - body: ' - - 1.0truetruetrue5' - headers: - Content-Length: - - '271' - Content-Type: - - application/xml - Date: - - Mon, 10 Aug 2020 16:44:51 GMT - User-Agent: - - azsdk-python-storage-table/12.0.0b1 Python/3.8.4 (Windows-10-10.0.19041-SP0) - x-ms-date: - - Mon, 10 Aug 2020 16:44:51 GMT - x-ms-version: - - 12.0.0b1 - method: PUT - uri: https://storagename.table.core.windows.net/?restype=service&comp=properties - response: - body: - string: "\uFEFF\r\n\r\n - \ InvalidHeaderValue\r\n The value - for one of the HTTP headers is not in the correct format.\nRequestId:3f3ccf8b-8002-005a-2835-6f5340000000\nTime:2020-08-10T16:44:52.6990255Z\r\n" - headers: - content-length: '371' - content-type: application/xml - date: Mon, 10 Aug 2020 16:44:52 GMT - server: Microsoft-HTTPAPI/2.0 - status: - code: 400 - message: The value for one of the HTTP headers is not in the correct format. - url: https://storagename.table.core.windows.net/?restype=service&comp=properties -version: 1 diff --git a/sdk/tables/azure-data-tables/tests/recordings/test_table_service_properties_async.test_table_service_properties.yaml b/sdk/tables/azure-data-tables/tests/recordings/test_table_service_properties_async.test_table_service_properties.yaml deleted file mode 100644 index 81930db36e2b..000000000000 --- a/sdk/tables/azure-data-tables/tests/recordings/test_table_service_properties_async.test_table_service_properties.yaml +++ /dev/null @@ -1,37 +0,0 @@ -interactions: -- request: - body: ' - - 1.0falsefalsefalsefalse1.0falsefalse1.0falsefalse' - headers: - Content-Length: - - '528' - Content-Type: - - application/xml - Date: - - Mon, 10 Aug 2020 16:38:03 GMT - User-Agent: - - azsdk-python-storage-table/12.0.0b1 Python/3.8.4 (Windows-10-10.0.19041-SP0) - x-ms-date: - - Mon, 10 Aug 2020 16:38:03 GMT - x-ms-version: - - 12.0.0b1 - method: PUT - uri: https://storagename.table.core.windows.net/?restype=service&comp=properties - response: - body: - string: "\uFEFF\r\n\r\n - \ InvalidHeaderValue\r\n The value - for one of the HTTP headers is not in the correct format.\nRequestId:66b65521-9002-0082-3734-6ff491000000\nTime:2020-08-10T16:38:05.2926871Z\r\n" - headers: - content-length: '371' - content-type: application/xml - date: Mon, 10 Aug 2020 16:38:04 GMT - server: Microsoft-HTTPAPI/2.0 - status: - code: 400 - message: The value for one of the HTTP headers is not in the correct format. - url: https://storagename.table.core.windows.net/?restype=service&comp=properties -version: 1 diff --git a/sdk/tables/azure-data-tables/tests/recordings/test_table_service_stats_async.test_table_service_stats_f_async.yaml b/sdk/tables/azure-data-tables/tests/recordings/test_table_service_stats_async.test_table_service_stats_f_async.yaml deleted file mode 100644 index 6361e9f6e28b..000000000000 --- a/sdk/tables/azure-data-tables/tests/recordings/test_table_service_stats_async.test_table_service_stats_f_async.yaml +++ /dev/null @@ -1,30 +0,0 @@ -interactions: -- request: - body: null - headers: - Accept: - - application/xml - Date: - - Wed, 16 Sep 2020 21:58:16 GMT - User-Agent: - - azsdk-python-data-tables/12.0.0b2 Python/3.8.4 (Windows-10-10.0.19041-SP0) - x-ms-date: - - Wed, 16 Sep 2020 21:58:16 GMT - x-ms-version: - - '2019-02-02' - method: GET - uri: https://pyacrstoragestorname-secondary.table.core.windows.net/?restype=service&comp=stats - response: - body: - string: "\uFEFFunavailable" - headers: - content-type: application/xml - date: Wed, 16 Sep 2020 21:58:16 GMT - server: Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - transfer-encoding: chunked - x-ms-version: '2019-02-02' - status: - code: 200 - message: OK - url: https://pyacrstoragemxivwppgccaw-secondary.table.core.windows.net/?restype=service&comp=stats -version: 1 diff --git a/sdk/tables/azure-data-tables/tests/recordings/test_table_service_stats_async.test_table_service_stats_when_unavailable_async.yaml b/sdk/tables/azure-data-tables/tests/recordings/test_table_service_stats_async.test_table_service_stats_when_unavailable_async.yaml deleted file mode 100644 index a54e41e0544b..000000000000 --- a/sdk/tables/azure-data-tables/tests/recordings/test_table_service_stats_async.test_table_service_stats_when_unavailable_async.yaml +++ /dev/null @@ -1,30 +0,0 @@ -interactions: -- request: - body: null - headers: - Accept: - - application/xml - Date: - - Wed, 16 Sep 2020 21:58:38 GMT - User-Agent: - - azsdk-python-data-tables/12.0.0b2 Python/3.8.4 (Windows-10-10.0.19041-SP0) - x-ms-date: - - Wed, 16 Sep 2020 21:58:38 GMT - x-ms-version: - - '2019-02-02' - method: GET - uri: https://pyacrstoragestorname-secondary.table.core.windows.net/?restype=service&comp=stats - response: - body: - string: "\uFEFFunavailable" - headers: - content-type: application/xml - date: Wed, 16 Sep 2020 21:58:38 GMT - server: Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 - transfer-encoding: chunked - x-ms-version: '2019-02-02' - status: - code: 200 - message: OK - url: https://pyacrstorage4wq73yk5234v-secondary.table.core.windows.net/?restype=service&comp=stats -version: 1 diff --git a/sdk/tables/azure-data-tables/tests/test_table.py b/sdk/tables/azure-data-tables/tests/test_table.py index 6cfee9a948fa..4ed84978fa91 100644 --- a/sdk/tables/azure-data-tables/tests/test_table.py +++ b/sdk/tables/azure-data-tables/tests/test_table.py @@ -12,6 +12,8 @@ import os from datetime import datetime, timedelta +from devtools_testutils import AzureTestCase + from azure.data.tables import ( ResourceTypes, AccountSasPermissions, @@ -23,10 +25,9 @@ TableAnalyticsLogging, Metrics, TableServiceClient, - TableItem + TableItem, + generate_account_sas ) -from azure.data.tables._authentication import SharedKeyCredentialPolicy -from azure.data.tables._table_shared_access_signature import generate_account_sas from azure.core.pipeline import Pipeline from azure.core.pipeline.policies import ( HeadersPolicy, @@ -47,7 +48,7 @@ # ------------------------------------------------------------------------------ -class StorageTableTest(TableTestCase): +class StorageTableTest(AzureTestCase, TableTestCase): # --Helpers----------------------------------------------------------------- def _get_table_reference(self, prefix=TEST_TABLE_PREFIX): @@ -197,32 +198,6 @@ def test_create_table_if_exists_new_table(self, tables_storage_account_name, tab assert t.table_name == table_name ts.delete_table(table_name) - @TablesPreparer() - def test_create_table_invalid_name(self, tables_storage_account_name, tables_primary_storage_account_key): - # Arrange - account_url = self.account_url(tables_storage_account_name, "table") - ts = self.create_client_from_credential(TableServiceClient, tables_primary_storage_account_key, account_url=account_url) - invalid_table_name = "my_table" - - with pytest.raises(ValueError) as excinfo: - ts.create_table(table_name=invalid_table_name) - - assert "Table names must be alphanumeric, cannot begin with a number, and must be between 3-63 characters long.""" in str( - excinfo) - - @TablesPreparer() - def test_delete_table_invalid_name(self, tables_storage_account_name, tables_primary_storage_account_key): - # Arrange - account_url = self.account_url(tables_storage_account_name, "table") - ts = self.create_client_from_credential(TableServiceClient, tables_primary_storage_account_key, account_url=account_url) - invalid_table_name = "my_table" - - with pytest.raises(ValueError) as excinfo: - ts.create_table(invalid_table_name) - - assert "Table names must be alphanumeric, cannot begin with a number, and must be between 3-63 characters long.""" in str( - excinfo) - @TablesPreparer() def test_query_tables(self, tables_storage_account_name, tables_primary_storage_account_key): # Arrange @@ -354,21 +329,6 @@ def test_delete_table_with_non_existing_table_fail_not_exist(self, tables_storag with pytest.raises(HttpResponseError): ts.delete_table(table_name) - @TablesPreparer() - def test_unicode_create_table_unicode_name(self, tables_storage_account_name, tables_primary_storage_account_key): - # Arrange - account_url = self.account_url(tables_storage_account_name, "table") - ts = self.create_client_from_credential(TableServiceClient, tables_primary_storage_account_key, account_url=account_url) - - table_name = u'啊齄丂狛狜' - - # Act - with pytest.raises(ValueError) as excinfo: - ts.create_table(table_name) - - assert "Table names must be alphanumeric, cannot begin with a number, and must be between 3-63 characters long.""" in str( - excinfo) - @TablesPreparer() def test_get_table_acl(self, tables_storage_account_name, tables_primary_storage_account_key): # Arrange @@ -555,3 +515,46 @@ def test_locale(self, tables_storage_account_name, tables_primary_storage_accoun ts.delete_table(table) locale.setlocale(locale.LC_ALL, init_locale[0] or 'en_US') + + +class TestTablesUnitTest(TableTestCase): + tables_storage_account_name = "fake_storage_account" + tables_primary_storage_account_key = "fakeXMZjnGsZGvd4bVr3Il5SeHA" + + def test_unicode_create_table_unicode_name(self): + # Arrange + account_url = self.account_url(self.tables_storage_account_name, "table") + tsc = TableServiceClient(account_url, credential=self.tables_primary_storage_account_key) + + table_name = u'啊齄丂狛狜' + + # Act + with pytest.raises(ValueError) as excinfo: + tsc.create_table(table_name) + + assert "Table names must be alphanumeric, cannot begin with a number, and must be between 3-63 characters long.""" in str( + excinfo) + + def test_create_table_invalid_name(self): + # Arrange + account_url = self.account_url(self.tables_storage_account_name, "table") + tsc = TableServiceClient(account_url, credential=self.tables_primary_storage_account_key) + invalid_table_name = "my_table" + + with pytest.raises(ValueError) as excinfo: + tsc.create_table(invalid_table_name) + + assert "Table names must be alphanumeric, cannot begin with a number, and must be between 3-63 characters long.""" in str( + excinfo) + + def test_delete_table_invalid_name(self): + # Arrange + account_url = self.account_url(self.tables_storage_account_name, "table") + tsc = TableServiceClient(account_url, credential=self.tables_primary_storage_account_key) + invalid_table_name = "my_table" + + with pytest.raises(ValueError) as excinfo: + tsc.delete_table(invalid_table_name) + + assert "Table names must be alphanumeric, cannot begin with a number, and must be between 3-63 characters long.""" in str( + excinfo) diff --git a/sdk/tables/azure-data-tables/tests/test_table_async.py b/sdk/tables/azure-data-tables/tests/test_table_async.py index 9b9cb9b45ce8..2e9223b40dcc 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_async.py +++ b/sdk/tables/azure-data-tables/tests/test_table_async.py @@ -5,16 +5,18 @@ import pytest +from devtools_testutils import AzureTestCase + from azure.core.exceptions import ResourceNotFoundError, ResourceExistsError from azure.data.tables import ( AccessPolicy, TableSasPermissions, ResourceTypes, AccountSasPermissions, - TableItem + TableItem, + generate_account_sas ) from azure.data.tables.aio import TableServiceClient, TableClient -from azure.data.tables._table_shared_access_signature import generate_account_sas from _shared.asynctestcase import AsyncTableTestCase from preparers import TablesPreparer @@ -24,7 +26,7 @@ # ------------------------------------------------------------------------------ -class TableTestAsync(AsyncTableTestCase): +class TableTestAsync(AzureTestCase, AsyncTableTestCase): # --Helpers----------------------------------------------------------------- def _get_table_reference(self, prefix=TEST_TABLE_PREFIX): table_name = self.get_resource_name(prefix) @@ -112,32 +114,6 @@ async def test_query_tables_per_page(self, tables_storage_account_name, tables_p for i in range(5): await ts.delete_table(table_name + str(i)) - @TablesPreparer() - async def test_create_table_invalid_name(self, tables_storage_account_name, tables_primary_storage_account_key): - # Arrange - account_url = self.account_url(tables_storage_account_name, "table") - ts = self.create_client_from_credential(TableServiceClient, tables_primary_storage_account_key, account_url=account_url) - invalid_table_name = "my_table" - - with pytest.raises(ValueError) as excinfo: - await ts.create_table(table_name=invalid_table_name) - - assert "Table names must be alphanumeric, cannot begin with a number, and must be between 3-63 characters long.""" in str( - excinfo) - - @TablesPreparer() - async def test_delete_table_invalid_name(self, tables_storage_account_name, tables_primary_storage_account_key): - # Arrange - account_url = self.account_url(tables_storage_account_name, "table") - ts = self.create_client_from_credential(TableServiceClient, tables_primary_storage_account_key, account_url=account_url) - invalid_table_name = "my_table" - - with pytest.raises(ValueError) as excinfo: - await ts.create_table(invalid_table_name) - - assert "Table names must be alphanumeric, cannot begin with a number, and must be between 3-63 characters long.""" in str( - excinfo) - @TablesPreparer() async def test_list_tables(self, tables_storage_account_name, tables_primary_storage_account_key): # Arrange @@ -271,21 +247,6 @@ async def test_delete_table_with_non_existing_table_fail_not_exist(self, tables_ # Assert - @TablesPreparer() - async def test_unicode_create_table_unicode_name(self, tables_storage_account_name, tables_primary_storage_account_key): - # Arrange - account_url = self.account_url(tables_storage_account_name, "table") - ts = self.create_client_from_credential(TableServiceClient, tables_primary_storage_account_key, account_url=account_url) - - table_name = u'啊齄丂狛狜' - - # Act - with pytest.raises(ValueError) as excinfo: - await ts.create_table(table_name) - - assert "Table names must be alphanumeric, cannot begin with a number, and must be between 3-63 characters long.""" in str( - excinfo) - @TablesPreparer() async def test_get_table_acl(self, tables_storage_account_name, tables_primary_storage_account_key): # Arrange @@ -461,3 +422,49 @@ async def test_locale(self, tables_storage_account_name, tables_primary_storage_ await ts.delete_table(table) locale.setlocale(locale.LC_ALL, init_locale[0] or 'en_US') + + +class TestTablesUnitTest(AsyncTableTestCase): + tables_storage_account_name = "fake_storage_account" + tables_primary_storage_account_key = "fakeXMZjnGsZGvd4bVr3Il5SeHA" + + @pytest.mark.asyncio + async def test_unicode_create_table_unicode_name(self): + # Arrange + account_url = self.account_url(self.tables_storage_account_name, "table") + tsc = TableServiceClient(account_url, credential=self.tables_primary_storage_account_key) + + table_name = u'啊齄丂狛狜' + + # Act + with pytest.raises(ValueError) as excinfo: + await tsc.create_table(table_name) + + assert "Table names must be alphanumeric, cannot begin with a number, and must be between 3-63 characters long.""" in str( + excinfo) + + @pytest.mark.asyncio + async def test_create_table_invalid_name(self): + # Arrange + account_url = self.account_url(self.tables_storage_account_name, "table") + tsc = TableServiceClient(account_url, credential=self.tables_primary_storage_account_key) + invalid_table_name = "my_table" + + with pytest.raises(ValueError) as excinfo: + await tsc.create_table(table_name=invalid_table_name) + + assert "Table names must be alphanumeric, cannot begin with a number, and must be between 3-63 characters long.""" in str( + excinfo) + + @pytest.mark.asyncio + async def test_delete_table_invalid_name(self): + # Arrange + account_url = self.account_url(self.tables_storage_account_name, "table") + tsc = TableServiceClient(account_url, credential=self.tables_primary_storage_account_key) + invalid_table_name = "my_table" + + with pytest.raises(ValueError) as excinfo: + await tsc.create_table(invalid_table_name) + + assert "Table names must be alphanumeric, cannot begin with a number, and must be between 3-63 characters long.""" in str( + excinfo) diff --git a/sdk/tables/azure-data-tables/tests/test_table_batch.py b/sdk/tables/azure-data-tables/tests/test_table_batch.py index a27a0513c040..87dba13a1a81 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_batch.py +++ b/sdk/tables/azure-data-tables/tests/test_table_batch.py @@ -13,6 +13,8 @@ import sys import uuid +from devtools_testutils import AzureTestCase + from azure.core import MatchConditions from azure.core.exceptions import ( ResourceExistsError, @@ -39,7 +41,7 @@ TEST_TABLE_PREFIX = 'table' #------------------------------------------------------------------------------ -class StorageTableBatchTest(TableTestCase): +class StorageTableBatchTest(AzureTestCase, TableTestCase): def _set_up(self, tables_storage_account_name, tables_primary_storage_account_key): self.ts = TableServiceClient(self.account_url(tables_storage_account_name, "table"), tables_primary_storage_account_key) @@ -169,31 +171,6 @@ def _assert_valid_batch_transaction(self, transaction, length): assert length == len(transaction.results) assert length == len(transaction.requests) - #--Test cases for batch --------------------------------------------- - def test_inferred_types(self): - # Arrange - # Act - entity = TableEntity() - entity.PartitionKey = '003' - entity.RowKey = 'batch_all_operations_together-1' - entity.test = EntityProperty(True) - entity.test2 = EntityProperty(b'abcdef') - entity.test3 = EntityProperty(u'c9da6455-213d-42c9-9a79-3e9149a57833') - entity.test4 = EntityProperty(datetime(1973, 10, 4, tzinfo=tzutc())) - entity.test5 = EntityProperty(u"stringystring") - entity.test6 = EntityProperty(3.14159) - entity.test7 = EntityProperty(100) - entity.test8 = EntityProperty(2 ** 33, EdmType.INT64) - - # Assert - assert entity.test.type == EdmType.BOOLEAN - assert entity.test2.type == EdmType.BINARY - assert entity.test3.type == EdmType.GUID - assert entity.test4.type == EdmType.DATETIME - assert entity.test5.type == EdmType.STRING - assert entity.test6.type == EdmType.DOUBLE - assert entity.test7.type == EdmType.INT32 - assert entity.test8.type == EdmType.INT64 @pytest.mark.skipif(sys.version_info < (3, 0), reason="requires Python3") @TablesPreparer() @@ -873,3 +850,31 @@ def test_new_delete_nonexistent_entity(self, tables_storage_account_name, tables finally: self._tear_down() + +class TestTableUnitTest(TableTestCase): + + #--Test cases for batch --------------------------------------------- + def test_inferred_types(self): + # Arrange + # Act + entity = TableEntity() + entity.PartitionKey = '003' + entity.RowKey = 'batch_all_operations_together-1' + entity.test = EntityProperty(True) + entity.test2 = EntityProperty(b'abcdef') + entity.test3 = EntityProperty(u'c9da6455-213d-42c9-9a79-3e9149a57833') + entity.test4 = EntityProperty(datetime(1973, 10, 4, tzinfo=tzutc())) + entity.test5 = EntityProperty(u"stringystring") + entity.test6 = EntityProperty(3.14159) + entity.test7 = EntityProperty(100) + entity.test8 = EntityProperty(2 ** 33, EdmType.INT64) + + # Assert + assert entity.test.type == EdmType.BOOLEAN + assert entity.test2.type == EdmType.BINARY + assert entity.test3.type == EdmType.GUID + assert entity.test4.type == EdmType.DATETIME + assert entity.test5.type == EdmType.STRING + assert entity.test6.type == EdmType.DOUBLE + assert entity.test7.type == EdmType.INT32 + assert entity.test8.type == EdmType.INT64 \ No newline at end of file diff --git a/sdk/tables/azure-data-tables/tests/test_table_batch_async.py b/sdk/tables/azure-data-tables/tests/test_table_batch_async.py index b6c0f426aa8e..85d85112644c 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_batch_async.py +++ b/sdk/tables/azure-data-tables/tests/test_table_batch_async.py @@ -13,6 +13,8 @@ from dateutil.tz import tzutc import sys +from devtools_testutils import AzureTestCase + from azure.core import MatchConditions from azure.core.exceptions import ( ResourceExistsError, @@ -30,14 +32,14 @@ BatchErrorException ) -from _shared.testcase import TableTestCase +from _shared.asynctestcase import AsyncTableTestCase from preparers import TablesPreparer #------------------------------------------------------------------------------ TEST_TABLE_PREFIX = 'table' #------------------------------------------------------------------------------ -class StorageTableBatchTest(TableTestCase): +class StorageTableBatchTest(AzureTestCase, AsyncTableTestCase): async def _set_up(self, tables_storage_account_name, tables_primary_storage_account_key): self.ts = TableServiceClient(self.account_url(tables_storage_account_name, "table"), tables_primary_storage_account_key) @@ -630,47 +632,6 @@ async def test_batch_all_operations_together_context_manager(self, tables_storag finally: await self._tear_down() - @pytest.mark.skip("Not sure this is how the batching should operate, will consult w/ Anna") - @TablesPreparer() - async def test_batch_reuse(self, tables_storage_account_name, tables_primary_storage_account_key): - # Arrange - await self._set_up(tables_storage_account_name, tables_primary_storage_account_key) - try: - table2 = self._get_table_reference('table2') - table2.create_table() - - # Act - entity = TableEntity() - entity.PartitionKey = '003' - entity.RowKey = 'batch_all_operations_together-1' - entity.test = EntityProperty(True) - entity.test2 = 'value' - entity.test3 = 3 - entity.test4 = EntityProperty(1234567890) - entity.test5 = datetime.utcnow() - - batch = self.table.create_batch() - batch.create_entity(entity) - entity.RowKey = 'batch_all_operations_together-2' - batch.create_entity(entity) - entity.RowKey = 'batch_all_operations_together-3' - batch.create_entity(entity) - entity.RowKey = 'batch_all_operations_together-4' - batch.create_entity(entity) - - await self.table.send_batch(batch) - with pytest.raises(HttpResponseError): - resp = await table2.send_batch(batch) - - # Assert - entities = self.table.query_entities("PartitionKey eq '003'") - length = 0 - async for e in entities: - length += 1 - assert 5 == length - finally: - await self._tear_down() - # @pytest.mark.skip("This does not throw an error, but it should") @TablesPreparer() async def test_batch_same_row_operations_fail(self, tables_storage_account_name, tables_primary_storage_account_key): diff --git a/sdk/tables/azure-data-tables/tests/test_table_batch_cosmos.py b/sdk/tables/azure-data-tables/tests/test_table_batch_cosmos.py index c8e83f68a422..e7ebc9341b67 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_batch_cosmos.py +++ b/sdk/tables/azure-data-tables/tests/test_table_batch_cosmos.py @@ -13,6 +13,8 @@ import pytest +from devtools_testutils import AzureTestCase + from azure.core import MatchConditions from azure.core.exceptions import ( ResourceExistsError, @@ -39,7 +41,7 @@ TEST_TABLE_PREFIX = 'table' #------------------------------------------------------------------------------ -class StorageTableClientTest(TableTestCase): +class StorageTableClientTest(AzureTestCase, TableTestCase): def _set_up(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): self.ts = TableServiceClient(self.account_url(tables_cosmos_account_name, "cosmos"), tables_primary_cosmos_account_key) @@ -155,32 +157,6 @@ def _assert_updated_entity(self, entity): assert entity['_metadata']['etag'] is not None #--Test cases for batch --------------------------------------------- - - def test_inferred_types(self): - # Arrange - # Act - entity = TableEntity() - entity.PartitionKey = '003' - entity.RowKey = 'batch_all_operations_together-1' - entity.test = EntityProperty(True) - entity.test2 = EntityProperty(b'abcdef') - entity.test3 = EntityProperty(u'c9da6455-213d-42c9-9a79-3e9149a57833') - entity.test4 = EntityProperty(datetime(1973, 10, 4, tzinfo=tzutc())) - entity.test5 = EntityProperty(u"stringystring") - entity.test6 = EntityProperty(3.14159) - entity.test7 = EntityProperty(100) - entity.test8 = EntityProperty(10, EdmType.INT64) - - # Assert - assert entity.test.type == EdmType.BOOLEAN - assert entity.test2.type == EdmType.BINARY - assert entity.test3.type == EdmType.GUID - assert entity.test4.type == EdmType.DATETIME - assert entity.test5.type == EdmType.STRING - assert entity.test6.type == EdmType.DOUBLE - assert entity.test7.type == EdmType.INT32 - assert entity.test8.type == EdmType.INT64 - def _assert_valid_batch_transaction(self, transaction, length): assert isinstance(transaction, BatchTransactionResult) assert length == len(transaction.entities) @@ -663,28 +639,6 @@ def test_new_non_existent_table(self, tables_cosmos_account_name, tables_primary finally: self._tear_down() - @pytest.mark.skip("Cannot fake cosmos credential") - @pytest.mark.skipif(sys.version_info < (3, 0), reason="requires Python3") - @CosmosPreparer() - def test_new_invalid_key(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): - # Arrange - invalid_key = tables_primary_cosmos_account_key[0:-6] + "==" # cut off a bit from the end to invalidate - key_list = list(tables_primary_cosmos_account_key) - - key_list[-6:] = list("0000==") - invalid_key = ''.join(key_list) - - self.ts = TableServiceClient(self.account_url(tables_cosmos_account_name, "table"), invalid_key) - self.table_name = self.get_resource_name('uttable') - self.table = self.ts.get_table_client(self.table_name) - - entity = self._create_random_entity_dict('001', 'batch_negative_1') - - batch = self.table.create_batch() - batch.create_entity(entity) - - with pytest.raises(ClientAuthenticationError): - resp = self.table.send_batch(batch) @pytest.mark.skipif(sys.version_info < (3, 0), reason="requires Python3") @CosmosPreparer() diff --git a/sdk/tables/azure-data-tables/tests/test_table_batch_cosmos_async.py b/sdk/tables/azure-data-tables/tests/test_table_batch_cosmos_async.py index d536b7b3fabf..839061bd9f01 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_batch_cosmos_async.py +++ b/sdk/tables/azure-data-tables/tests/test_table_batch_cosmos_async.py @@ -14,6 +14,8 @@ import pytest +from devtools_testutils import AzureTestCase + from azure.core import MatchConditions from azure.core.exceptions import ( ResourceExistsError, @@ -31,14 +33,15 @@ ) from azure.data.tables.aio import TableServiceClient -from _shared.testcase import TableTestCase, SLEEP_DELAY +from _shared.testcase import SLEEP_DELAY +from _shared.asynctestcase import AsyncTableTestCase from preparers import CosmosPreparer #------------------------------------------------------------------------------ TEST_TABLE_PREFIX = 'table' #------------------------------------------------------------------------------ -class StorageTableBatchTest(TableTestCase): +class StorageTableBatchTest(AzureTestCase, AsyncTableTestCase): async def _set_up(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): self.ts = TableServiceClient(self.account_url(tables_cosmos_account_name, "cosmos"), tables_primary_cosmos_account_key) @@ -730,29 +733,6 @@ async def test_new_non_existent_table(self, tables_cosmos_account_name, tables_p finally: await self._tear_down() - @pytest.mark.skip("Cannot fake cosmos credential") - @pytest.mark.skipif(sys.version_info < (3, 0), reason="requires Python3") - @CosmosPreparer() - async def test_new_invalid_key(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): - # Arrange - invalid_key = tables_primary_cosmos_account_key[0:-6] + "==" # cut off a bit from the end to invalidate - key_list = list(tables_primary_cosmos_account_key) - - key_list[-6:] = list("0000==") - invalid_key = ''.join(key_list) - - self.ts = TableServiceClient(self.account_url(tables_cosmos_account_name, "table"), invalid_key) - self.table_name = self.get_resource_name('uttable') - self.table = self.ts.get_table_client(self.table_name) - - entity = self._create_random_entity_dict('001', 'batch_negative_1') - - batch = self.table.create_batch() - batch.create_entity(entity) - - with pytest.raises(ClientAuthenticationError): - resp = await self.table.send_batch(batch) - @pytest.mark.skipif(sys.version_info < (3, 0), reason="requires Python3") @CosmosPreparer() async def test_new_delete_nonexistent_entity(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): diff --git a/sdk/tables/azure-data-tables/tests/test_table_client.py b/sdk/tables/azure-data-tables/tests/test_table_client.py index 494ebde9547c..aaf5a4c00a3b 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_client.py +++ b/sdk/tables/azure-data-tables/tests/test_table_client.py @@ -6,8 +6,10 @@ import pytest import platform +from devtools_testutils import AzureTestCase + from azure.data.tables import TableServiceClient, TableClient -from azure.data.tables._version import VERSION +from azure.data.tables import __version__ as VERSION from azure.core.exceptions import HttpResponseError from _shared.testcase import ( @@ -27,11 +29,66 @@ _CONNECTION_ENDPOINTS_SECONDARY = {'table': 'TableSecondaryEndpoint', 'cosmos': 'TableSecondaryEndpoint'} -class StorageTableClientTest(TableTestCase): - def setUp(self): - super(StorageTableClientTest, self).setUp() - self.sas_token = self.generate_sas_token() - self.token_credential = self.generate_oauth_token() +class TestTableClient(AzureTestCase, TableTestCase): + + @TablesPreparer() + def test_user_agent_custom(self, tables_storage_account_name, tables_primary_storage_account_key): + custom_app = "TestApp/v1.0" + service = TableServiceClient( + self.account_url(tables_storage_account_name, "table"), credential=tables_primary_storage_account_key, user_agent=custom_app) + + def callback(response): + assert 'User-Agent' in response.http_request.headers + assert "TestApp/v1.0 azsdk-python-data-tables/{} Python/{} ({})".format( + VERSION, + platform.python_version(), + platform.platform()) in response.http_request.headers['User-Agent'] + + tables = list(service.list_tables(raw_response_hook=callback)) + assert isinstance(tables, list) + + def callback(response): + assert 'User-Agent' in response.http_request.headers + assert "TestApp/v2.0 TestApp/v1.0 azsdk-python-data-tables/{} Python/{} ({})".format( + VERSION, + platform.python_version(), + platform.platform()) in response.http_request.headers['User-Agent'] + + tables = list(service.list_tables(raw_response_hook=callback, user_agent="TestApp/v2.0")) + assert isinstance(tables, list) + + @TablesPreparer() + def test_user_agent_append(self, tables_storage_account_name, tables_primary_storage_account_key): + service = TableServiceClient(self.account_url(tables_storage_account_name, "table"), credential=tables_primary_storage_account_key) + + def callback(response): + assert 'User-Agent' in response.http_request.headers + assert response.http_request.headers['User-Agent'] == "azsdk-python-data-tables/{} Python/{} ({}) customer_user_agent".format( + VERSION, + platform.python_version(), + platform.platform()) + + custom_headers = {'User-Agent': 'customer_user_agent'} + tables = service.list_tables(raw_response_hook=callback, headers=custom_headers) + + @TablesPreparer() + def test_user_agent_default(self, tables_storage_account_name, tables_primary_storage_account_key): + service = TableServiceClient(self.account_url(tables_storage_account_name, "table"), credential=tables_primary_storage_account_key) + + def callback(response): + assert 'User-Agent' in response.http_request.headers + assert "azsdk-python-data-tables/{} Python/{} ({})".format( + VERSION, + platform.python_version(), + platform.platform()) in response.http_request.headers['User-Agent'] + + tables = list(service.list_tables(raw_response_hook=callback)) + assert isinstance(tables, list) + + +class TestTableUnitTests(TableTestCase): + tables_storage_account_name = "fake_storage_account" + tables_primary_storage_account_key = "fakeXMZjnGsZGvd4bVr3Il5SeHA" # --Helpers----------------------------------------------------------------- def validate_standard_account_endpoints(self, service, account_name, account_key): @@ -42,104 +99,74 @@ def validate_standard_account_endpoints(self, service, account_name, account_key assert ('{}.{}'.format(account_name, 'table.core.windows.net') in service.url) or ('{}.{}'.format(account_name, 'table.cosmos.azure.com') in service.url) # --Direct Parameters Test Cases -------------------------------------------- - @TablesPreparer() - def test_create_service_with_key(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_create_service_with_key(self): # Arrange for client, url in SERVICES.items(): # Act service = client( - self.account_url(tables_storage_account_name, url), credential=tables_primary_storage_account_key, table_name='foo') + self.account_url(self.tables_storage_account_name, url), credential=self.tables_primary_storage_account_key, table_name='foo') # Assert - self.validate_standard_account_endpoints(service, tables_storage_account_name, tables_primary_storage_account_key) + self.validate_standard_account_endpoints(service, self.tables_storage_account_name, self.tables_primary_storage_account_key) assert service.scheme == 'https' - @TablesPreparer() - def test_create_service_with_connection_string(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_create_service_with_connection_string(self): for service_type in SERVICES.items(): # Act service = service_type[0].from_connection_string( - self.connection_string(tables_storage_account_name, tables_primary_storage_account_key), table_name="test") + self.connection_string(self.tables_storage_account_name, self.tables_primary_storage_account_key), table_name="test") # Assert - self.validate_standard_account_endpoints(service, tables_storage_account_name, tables_primary_storage_account_key) + self.validate_standard_account_endpoints(service, self.tables_storage_account_name, self.tables_primary_storage_account_key) assert service.scheme == 'https' - @TablesPreparer() - def test_create_service_with_sas(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_create_service_with_sas(self): # Arrange - url = self.account_url(tables_storage_account_name, "table") + url = self.account_url(self.tables_storage_account_name, "table") suffix = '.table.core.windows.net' for service_type in SERVICES: # Act service = service_type( - self.account_url(tables_storage_account_name, "table"), credential=self.sas_token, table_name='foo') + self.account_url(self.tables_storage_account_name, "table"), credential=self.generate_sas_token(), table_name='foo') # Assert assert service is not None - assert service.account_name == tables_storage_account_name - assert service.url.startswith('https://' + tables_storage_account_name + suffix) - assert service.url.endswith(self.sas_token) + assert service.account_name == self.tables_storage_account_name + assert service.url.startswith('https://' + self.tables_storage_account_name + suffix) + assert service.url.endswith(self.generate_sas_token()) assert service.credential is None - @TablesPreparer() - def test_create_service_with_token(self, tables_storage_account_name, tables_primary_storage_account_key): - url = self.account_url(tables_storage_account_name, "table") - suffix = '.table.core.windows.net' - for service_type in SERVICES: - # Act - service = service_type(url, credential=self.token_credential, table_name='foo') - - # Assert - assert service is not None - assert service.account_name == tables_storage_account_name - assert service.url.startswith('https://' + tables_storage_account_name + suffix) - assert service.credential == self.token_credential - assert not hasattr(service.credential, 'account_key') - assert hasattr(service.credential, 'get_token') - - @TablesPreparer() - def test_create_service_with_token_and_http(self, tables_storage_account_name, tables_primary_storage_account_key): - for service_type in SERVICES: - # Act - with pytest.raises(ValueError): - url = self.account_url(tables_storage_account_name, "table").replace('https', 'http') - service_type(url, credential=self.token_credential, table_name='foo') - - @TablesPreparer() - def test_create_service_china(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_create_service_china(self): # Arrange for service_type in SERVICES.items(): # Act - url = self.account_url(tables_storage_account_name, "table").replace('core.windows.net', 'core.chinacloudapi.cn') + url = self.account_url(self.tables_storage_account_name, "table").replace('core.windows.net', 'core.chinacloudapi.cn') service = service_type[0]( - url, credential=tables_primary_storage_account_key, table_name='foo') + url, credential=self.tables_primary_storage_account_key, table_name='foo') # Assert assert service is not None - assert service.account_name == tables_storage_account_name - assert service.credential.account_name == tables_storage_account_name - assert service.credential.account_key == tables_primary_storage_account_key - assert service._primary_endpoint.startswith('https://{}.{}.core.chinacloudapi.cn'.format(tables_storage_account_name, "table")) + assert service.account_name == self.tables_storage_account_name + assert service.credential.account_name == self.tables_storage_account_name + assert service.credential.account_key == self.tables_primary_storage_account_key + assert service._primary_endpoint.startswith('https://{}.{}.core.chinacloudapi.cn'.format(self.tables_storage_account_name, "table")) - @TablesPreparer() - def test_create_service_protocol(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_create_service_protocol(self): # Arrange for service_type in SERVICES.items(): # Act - url = self.account_url(tables_storage_account_name, "table").replace('https', 'http') + url = self.account_url(self.tables_storage_account_name, "table").replace('https', 'http') service = service_type[0]( - url, credential=tables_primary_storage_account_key, table_name='foo') + url, credential=self.tables_primary_storage_account_key, table_name='foo') # Assert - self.validate_standard_account_endpoints(service, tables_storage_account_name, tables_primary_storage_account_key) + self.validate_standard_account_endpoints(service, self.tables_storage_account_name, self.tables_primary_storage_account_key) assert service.scheme == 'http' - @TablesPreparer() - def test_create_service_empty_key(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_create_service_empty_key(self): # Arrange TABLE_SERVICES = [TableServiceClient, TableClient] @@ -150,45 +177,42 @@ def test_create_service_empty_key(self, tables_storage_account_name, tables_prim # test non-string account URL with pytest.raises(ValueError): - test_service = service_type(account_url=123456, credential=tables_primary_storage_account_key, table_name='foo') + test_service = service_type(account_url=123456, credential=self.tables_primary_storage_account_key, table_name='foo') assert str(e.value) == "You need to provide either a SAS token or an account shared key to authenticate." - @TablesPreparer() - def test_create_service_with_socket_timeout(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_create_service_with_socket_timeout(self): # Arrange for service_type in SERVICES.items(): # Act default_service = service_type[0]( - self.account_url(tables_storage_account_name, "table"), credential=tables_primary_storage_account_key, table_name='foo') + self.account_url(self.tables_storage_account_name, "table"), credential=self.tables_primary_storage_account_key, table_name='foo') service = service_type[0]( - self.account_url(tables_storage_account_name, "table"), credential=tables_primary_storage_account_key, + self.account_url(self.tables_storage_account_name, "table"), credential=self.tables_primary_storage_account_key, table_name='foo', connection_timeout=22) # Assert - self.validate_standard_account_endpoints(service, tables_storage_account_name, tables_primary_storage_account_key) + self.validate_standard_account_endpoints(service, self.tables_storage_account_name, self.tables_primary_storage_account_key) assert service._client._client._pipeline._transport.connection_config.timeout == 22 assert default_service._client._client._pipeline._transport.connection_config.timeout in [20, (20, 2000)] # --Connection String Test Cases -------------------------------------------- - @TablesPreparer() - def test_create_service_with_connection_string_key(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_create_service_with_connection_string_key(self): # Arrange - conn_string = 'AccountName={};AccountKey={};'.format(tables_storage_account_name, tables_primary_storage_account_key) + conn_string = 'AccountName={};AccountKey={};'.format(self.tables_storage_account_name, self.tables_primary_storage_account_key) for service_type in SERVICES.items(): # Act service = service_type[0].from_connection_string(conn_string, table_name='foo') # Assert - self.validate_standard_account_endpoints(service, tables_storage_account_name, tables_primary_storage_account_key) + self.validate_standard_account_endpoints(service, self.tables_storage_account_name, self.tables_primary_storage_account_key) assert service.scheme == 'https' - @TablesPreparer() - def test_create_service_with_connection_string_sas(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_create_service_with_connection_string_sas(self): # Arrange - conn_string = 'AccountName={};SharedAccessSignature={};'.format(tables_storage_account_name, self.sas_token) + conn_string = 'AccountName={};SharedAccessSignature={};'.format(self.tables_storage_account_name, self.generate_sas_token()) for service_type in SERVICES: # Act @@ -196,16 +220,15 @@ def test_create_service_with_connection_string_sas(self, tables_storage_account_ # Assert assert service is not None - assert service.account_name == tables_storage_account_name - assert service.url.startswith('https://' + tables_storage_account_name + '.table.core.windows.net') - assert service.url.endswith(self.sas_token) + assert service.account_name == self.tables_storage_account_name + assert service.url.startswith('https://' + self.tables_storage_account_name + '.table.core.windows.net') + assert service.url.endswith(self.generate_sas_token()) assert service.credential is None - @TablesPreparer() - def test_create_service_with_connection_string_cosmos(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_create_service_with_connection_string_cosmos(self): # Arrange conn_string = 'DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};TableEndpoint=https://{0}.table.cosmos.azure.com:443/;'.format( - tables_storage_account_name, tables_primary_storage_account_key) + self.tables_storage_account_name, self.tables_primary_storage_account_key) for service_type in SERVICES: # Act @@ -213,18 +236,17 @@ def test_create_service_with_connection_string_cosmos(self, tables_storage_accou # Assert assert service is not None - assert service.account_name == tables_storage_account_name - assert service.url.startswith('https://' + tables_storage_account_name + '.table.cosmos.azure.com') - assert service.credential.account_name == tables_storage_account_name - assert service.credential.account_key == tables_primary_storage_account_key - assert service._primary_endpoint.startswith('https://' + tables_storage_account_name + '.table.cosmos.azure.com') + assert service.account_name == self.tables_storage_account_name + assert service.url.startswith('https://' + self.tables_storage_account_name + '.table.cosmos.azure.com') + assert service.credential.account_name == self.tables_storage_account_name + assert service.credential.account_key == self.tables_primary_storage_account_key + assert service._primary_endpoint.startswith('https://' + self.tables_storage_account_name + '.table.cosmos.azure.com') assert service.scheme == 'https' - @TablesPreparer() - def test_create_service_with_connection_string_endpoint_protocol(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_create_service_with_connection_string_endpoint_protocol(self): # Arrange conn_string = 'AccountName={};AccountKey={};DefaultEndpointsProtocol=http;EndpointSuffix=core.chinacloudapi.cn;'.format( - tables_storage_account_name, tables_primary_storage_account_key) + self.tables_storage_account_name, self.tables_primary_storage_account_key) for service_type in SERVICES.items(): # Act @@ -232,62 +254,58 @@ def test_create_service_with_connection_string_endpoint_protocol(self, tables_st # Assert assert service is not None - assert service.account_name == tables_storage_account_name - assert service.credential.account_name == tables_storage_account_name - assert service.credential.account_key == tables_primary_storage_account_key - assert service._primary_endpoint.startswith('http://{}.{}.core.chinacloudapi.cn'.format(tables_storage_account_name, "table")) + assert service.account_name == self.tables_storage_account_name + assert service.credential.account_name == self.tables_storage_account_name + assert service.credential.account_key == self.tables_primary_storage_account_key + assert service._primary_endpoint.startswith('http://{}.{}.core.chinacloudapi.cn'.format(self.tables_storage_account_name, "table")) assert service.scheme == 'http' - @TablesPreparer() - def test_create_service_with_connection_string_emulated(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_create_service_with_connection_string_emulated(self): # Arrange for service_type in SERVICES.items(): - conn_string = 'UseDevelopmentStorage=true;'.format(tables_storage_account_name, tables_primary_storage_account_key) + conn_string = 'UseDevelopmentStorage=true;'.format(self.tables_storage_account_name, self.tables_primary_storage_account_key) # Act with pytest.raises(ValueError): service = service_type[0].from_connection_string(conn_string, table_name="foo") - @TablesPreparer() - def test_create_service_with_connection_string_custom_domain(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_create_service_with_connection_string_custom_domain(self): # Arrange for service_type in SERVICES.items(): conn_string = 'AccountName={};AccountKey={};TableEndpoint=www.mydomain.com;'.format( - tables_storage_account_name, tables_primary_storage_account_key) + self.tables_storage_account_name, self.tables_primary_storage_account_key) # Act service = service_type[0].from_connection_string(conn_string, table_name="foo") # Assert assert service is not None - assert service.account_name == tables_storage_account_name - assert service.credential.account_name == tables_storage_account_name - assert service.credential.account_key == tables_primary_storage_account_key + assert service.account_name == self.tables_storage_account_name + assert service.credential.account_name == self.tables_storage_account_name + assert service.credential.account_key == self.tables_primary_storage_account_key assert service._primary_endpoint.startswith('https://www.mydomain.com') - @TablesPreparer() - def test_create_service_with_conn_str_custom_domain_trailing_slash(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_create_service_with_conn_str_custom_domain_trailing_slash(self): # Arrange for service_type in SERVICES.items(): conn_string = 'AccountName={};AccountKey={};TableEndpoint=www.mydomain.com/;'.format( - tables_storage_account_name, tables_primary_storage_account_key) + self.tables_storage_account_name, self.tables_primary_storage_account_key) # Act service = service_type[0].from_connection_string(conn_string, table_name="foo") # Assert assert service is not None - assert service.account_name == tables_storage_account_name - assert service.credential.account_name == tables_storage_account_name - assert service.credential.account_key == tables_primary_storage_account_key + assert service.account_name == self.tables_storage_account_name + assert service.credential.account_name == self.tables_storage_account_name + assert service.credential.account_key == self.tables_primary_storage_account_key assert service._primary_endpoint.startswith('https://www.mydomain.com') - @TablesPreparer() - def test_create_service_with_conn_str_custom_domain_sec_override(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_create_service_with_conn_str_custom_domain_sec_override(self): # Arrange for service_type in SERVICES.items(): conn_string = 'AccountName={};AccountKey={};TableEndpoint=www.mydomain.com/;'.format( - tables_storage_account_name, tables_primary_storage_account_key) + self.tables_storage_account_name, self.tables_primary_storage_account_key) # Act service = service_type[0].from_connection_string( @@ -295,17 +313,16 @@ def test_create_service_with_conn_str_custom_domain_sec_override(self, tables_st # Assert assert service is not None - assert service.account_name == tables_storage_account_name - assert service.credential.account_name == tables_storage_account_name - assert service.credential.account_key == tables_primary_storage_account_key + assert service.account_name == self.tables_storage_account_name + assert service.credential.account_name == self.tables_storage_account_name + assert service.credential.account_key == self.tables_primary_storage_account_key assert service._primary_endpoint.startswith('https://www.mydomain.com') - @TablesPreparer() - def test_create_service_with_conn_str_fails_if_sec_without_primary(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_create_service_with_conn_str_fails_if_sec_without_primary(self): for service_type in SERVICES.items(): # Arrange conn_string = 'AccountName={};AccountKey={};{}=www.mydomain.com;'.format( - tables_storage_account_name, tables_primary_storage_account_key, + self.tables_storage_account_name, self.tables_primary_storage_account_key, _CONNECTION_ENDPOINTS_SECONDARY.get(service_type[1])) # Act @@ -314,13 +331,12 @@ def test_create_service_with_conn_str_fails_if_sec_without_primary(self, tables_ with pytest.raises(ValueError): service = service_type[0].from_connection_string(conn_string, table_name="foo") - @TablesPreparer() - def test_create_service_with_conn_str_succeeds_if_sec_with_primary(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_create_service_with_conn_str_succeeds_if_sec_with_primary(self): for service_type in SERVICES.items(): # Arrange conn_string = 'AccountName={};AccountKey={};{}=www.mydomain.com;{}=www-sec.mydomain.com;'.format( - tables_storage_account_name, - tables_primary_storage_account_key, + self.tables_storage_account_name, + self.tables_primary_storage_account_key, _CONNECTION_ENDPOINTS.get(service_type[1]), _CONNECTION_ENDPOINTS_SECONDARY.get(service_type[1])) @@ -329,25 +345,24 @@ def test_create_service_with_conn_str_succeeds_if_sec_with_primary(self, tables_ # Assert assert service is not None - assert service.account_name == tables_storage_account_name - assert service.credential.account_name == tables_storage_account_name - assert service.credential.account_key == tables_primary_storage_account_key + assert service.account_name == self.tables_storage_account_name + assert service.credential.account_name == self.tables_storage_account_name + assert service.credential.account_key == self.tables_primary_storage_account_key assert service._primary_endpoint.startswith('https://www.mydomain.com') - @TablesPreparer() - def test_create_service_with_custom_account_endpoint_path(self, tables_storage_account_name, tables_primary_storage_account_key): - custom_account_url = "http://local-machine:11002/custom/account/path/" + self.sas_token + def test_create_service_with_custom_account_endpoint_path(self): + custom_account_url = "http://local-machine:11002/custom/account/path/" + self.generate_sas_token() for service_type in SERVICES.items(): conn_string = 'DefaultEndpointsProtocol=http;AccountName={};AccountKey={};TableEndpoint={};'.format( - tables_storage_account_name, tables_primary_storage_account_key, custom_account_url) + self.tables_storage_account_name, self.tables_primary_storage_account_key, custom_account_url) # Act service = service_type[0].from_connection_string(conn_string, table_name="foo") # Assert - assert service.account_name == tables_storage_account_name - assert service.credential.account_name == tables_storage_account_name - assert service.credential.account_key == tables_primary_storage_account_key + assert service.account_name == self.tables_storage_account_name + assert service.credential.account_name == self.tables_storage_account_name + assert service.credential.account_key == self.tables_primary_storage_account_key assert service._primary_hostname == 'local-machine:11002/custom/account/path' service = TableServiceClient(account_url=custom_account_url) @@ -363,88 +378,32 @@ def test_create_service_with_custom_account_endpoint_path(self, tables_storage_a assert service._primary_hostname == 'local-machine:11002/custom/account/path' assert service.url.startswith('http://local-machine:11002/custom/account/path') - service = TableClient.from_table_url("http://local-machine:11002/custom/account/path/foo" + self.sas_token) + service = TableClient.from_table_url("http://local-machine:11002/custom/account/path/foo" + self.generate_sas_token()) assert service.account_name == None assert service.table_name == "foo" assert service.credential == None assert service._primary_hostname == 'local-machine:11002/custom/account/path' assert service.url.startswith('http://local-machine:11002/custom/account/path') - @TablesPreparer() - def test_user_agent_default(self, tables_storage_account_name, tables_primary_storage_account_key): - service = TableServiceClient(self.account_url(tables_storage_account_name, "table"), credential=tables_primary_storage_account_key) - - def callback(response): - assert 'User-Agent' in response.http_request.headers - assert "azsdk-python-data-tables/{} Python/{} ({})".format( - VERSION, - platform.python_version(), - platform.platform()) in response.http_request.headers['User-Agent'] - - tables = list(service.list_tables(raw_response_hook=callback)) - assert isinstance(tables, list) - - @TablesPreparer() - def test_user_agent_custom(self, tables_storage_account_name, tables_primary_storage_account_key): - custom_app = "TestApp/v1.0" - service = TableServiceClient( - self.account_url(tables_storage_account_name, "table"), credential=tables_primary_storage_account_key, user_agent=custom_app) - - def callback(response): - assert 'User-Agent' in response.http_request.headers - assert "TestApp/v1.0 azsdk-python-data-tables/{} Python/{} ({})".format( - VERSION, - platform.python_version(), - platform.platform()) in response.http_request.headers['User-Agent'] - - tables = list(service.list_tables(raw_response_hook=callback)) - assert isinstance(tables, list) - - def callback(response): - assert 'User-Agent' in response.http_request.headers - assert "TestApp/v2.0 TestApp/v1.0 azsdk-python-data-tables/{} Python/{} ({})".format( - VERSION, - platform.python_version(), - platform.platform()) in response.http_request.headers['User-Agent'] - - tables = list(service.list_tables(raw_response_hook=callback, user_agent="TestApp/v2.0")) - assert isinstance(tables, list) - - @TablesPreparer() - def test_user_agent_append(self, tables_storage_account_name, tables_primary_storage_account_key): - service = TableServiceClient(self.account_url(tables_storage_account_name, "table"), credential=tables_primary_storage_account_key) - - def callback(response): - assert 'User-Agent' in response.http_request.headers - assert response.http_request.headers['User-Agent'] == "azsdk-python-data-tables/{} Python/{} ({}) customer_user_agent".format( - VERSION, - platform.python_version(), - platform.platform()) - - custom_headers = {'User-Agent': 'customer_user_agent'} - tables = service.list_tables(raw_response_hook=callback, headers=custom_headers) - - @TablesPreparer() - def test_create_table_client_with_complete_table_url(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_create_table_client_with_complete_table_url(self): # Arrange - table_url = self.account_url(tables_storage_account_name, "table") + "/foo" - service = TableClient(table_url, table_name='bar', credential=tables_primary_storage_account_key) + table_url = self.account_url(self.tables_storage_account_name, "table") + "/foo" + service = TableClient(table_url, table_name='bar', credential=self.tables_primary_storage_account_key) # Assert assert service.scheme == 'https' assert service.table_name == 'bar' - assert service.account_name == tables_storage_account_name + assert service.account_name == self.tables_storage_account_name - @TablesPreparer() - def test_create_table_client_with_complete_url(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_create_table_client_with_complete_url(self): # Arrange - table_url = "https://{}.table.core.windows.net:443/foo".format(tables_storage_account_name) - service = TableClient(account_url=table_url, table_name='bar', credential=tables_primary_storage_account_key) + table_url = "https://{}.table.core.windows.net:443/foo".format(self.tables_storage_account_name) + service = TableClient(account_url=table_url, table_name='bar', credential=self.tables_primary_storage_account_key) # Assert assert service.scheme == 'https' assert service.table_name == 'bar' - assert service.account_name == tables_storage_account_name + assert service.account_name == self.tables_storage_account_name def test_create_table_client_with_invalid_name(self): # Arrange @@ -453,7 +412,7 @@ def test_create_table_client_with_invalid_name(self): # Assert with pytest.raises(ValueError) as excinfo: - service = TableClient(account_url=table_url, table_name=invalid_table_name, credential="tables_primary_storage_account_key") + service = TableClient(account_url=table_url, table_name=invalid_table_name, credential="self.tables_primary_storage_account_key") assert "Table names must be alphanumeric, cannot begin with a number, and must be between 3-63 characters long." in str(excinfo) @@ -471,24 +430,54 @@ def test_error_with_malformed_conn_str(self): elif conn_str in ("foobar=baz=foo" , "foo=;bar=;", "=", "=;=="): assert str(e.value) == "Connection string missing required connection details." - @TablesPreparer() - def test_closing_pipeline_client(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_closing_pipeline_client(self): # Arrange for client, url in SERVICES.items(): # Act service = client( - self.account_url(tables_storage_account_name, "table"), credential=tables_primary_storage_account_key, table_name='table') + self.account_url(self.tables_storage_account_name, "table"), credential=self.tables_primary_storage_account_key, table_name='table') # Assert with service: assert hasattr(service, 'close') service.close() - @TablesPreparer() - def test_closing_pipeline_client_simple(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_closing_pipeline_client_simple(self): # Arrange for client, url in SERVICES.items(): # Act service = client( - self.account_url(tables_storage_account_name, "table"), credential=tables_primary_storage_account_key, table_name='table') + self.account_url(self.tables_storage_account_name, "table"), credential=self.tables_primary_storage_account_key, table_name='table') service.close() + + def test_create_service_with_token_and_http(self): + for service_type in SERVICES: + + with pytest.raises(ValueError): + url = self.account_url(self.tables_storage_account_name, "table").replace('https', 'http') + service_type(url, credential=self.generate_fake_token(), table_name='foo') + + def test_create_service_with_token(self): + url = self.account_url(self.tables_storage_account_name, "table") + suffix = '.table.core.windows.net' + self.token_credential = self.generate_fake_token() + + service = TableClient(url, credential=self.token_credential, table_name='foo') + + # Assert + assert service is not None + assert service.account_name == self.tables_storage_account_name + assert service.url.startswith('https://' + self.tables_storage_account_name + suffix) + assert service.credential == self.token_credential + assert not hasattr(service.credential, 'account_key') + assert hasattr(service.credential, 'get_token') + + service = TableServiceClient(url, credential=self.token_credential, table_name='foo') + + # Assert + assert service is not None + assert service.account_name == self.tables_storage_account_name + assert service.url.startswith('https://' + self.tables_storage_account_name + suffix) + assert service.credential == self.token_credential + assert not hasattr(service.credential, 'account_key') + assert hasattr(service.credential, 'get_token') diff --git a/sdk/tables/azure-data-tables/tests/test_table_client_async.py b/sdk/tables/azure-data-tables/tests/test_table_client_async.py index 5317a776b6d0..1f1b2431fac5 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_client_async.py +++ b/sdk/tables/azure-data-tables/tests/test_table_client_async.py @@ -6,10 +6,12 @@ import pytest import platform +from devtools_testutils import AzureTestCase + from azure.data.tables.aio import TableServiceClient, TableClient from azure.data.tables._version import VERSION -from _shared.testcase import TableTestCase +from _shared.asynctestcase import AsyncTableTestCase from preparers import TablesPreparer from devtools_testutils import AzureTestCase # ------------------------------------------------------------------------------ @@ -22,11 +24,68 @@ _CONNECTION_ENDPOINTS_SECONDARY = {'table': 'TableSecondaryEndpoint'} -class StorageTableClientTest(TableTestCase): - def setUp(self): - super(StorageTableClientTest, self).setUp() - self.sas_token = self.generate_sas_token() - self.token_credential = self.generate_oauth_token() + +class TestTableClient(AzureTestCase, AsyncTableTestCase): + + @TablesPreparer() + async def test_user_agent_default_async(self, tables_storage_account_name, tables_primary_storage_account_key): + service = TableServiceClient(self.account_url(tables_storage_account_name, "table"), credential=tables_primary_storage_account_key) + + def callback(response): + assert 'User-Agent' in response.http_request.headers + assert response.http_request.headers['User-Agent'] in "azsdk-python-data-tables/{} Python/{} ({})".format( + VERSION, + platform.python_version(), + platform.platform()) + + tables = service.list_tables(raw_response_hook=callback) + assert tables is not None + + @TablesPreparer() + async def test_user_agent_custom_async(self, tables_storage_account_name, tables_primary_storage_account_key): + custom_app = "TestApp/v1.0" + service = TableServiceClient( + self.account_url(tables_storage_account_name, "table"), credential=tables_primary_storage_account_key, user_agent=custom_app) + + def callback(response): + assert 'User-Agent' in response.http_request.headers + assert "TestApp/v1.0 azsdk-python-data-tables/{} Python/{} ({})".format( + VERSION, + platform.python_version(), + platform.platform()) in response.http_request.headers['User-Agent'] + + tables = service.list_tables(raw_response_hook=callback) + assert tables is not None + + def callback(response): + assert 'User-Agent' in response.http_request.headers + assert "TestApp/v2.0 TestApp/v1.0 azsdk-python-data-tables/{} Python/{} ({})".format( + VERSION, + platform.python_version(), + platform.platform()) in response.http_request.headers['User-Agent'] + + tables = service.list_tables(raw_response_hook=callback, user_agent="TestApp/v2.0") + assert tables is not None + + @TablesPreparer() + async def test_user_agent_append(self, tables_storage_account_name, tables_primary_storage_account_key): + # TODO: fix this one + service = TableServiceClient(self.account_url(tables_storage_account_name, "table"), credential=tables_primary_storage_account_key) + + def callback(response): + assert 'User-Agent' in response.http_request.headers + assert response.http_request.headers['User-Agent'] == "azsdk-python-data-tables/{} Python/{} ({}) customer_user_agent".format( + VERSION, + platform.python_version(), + platform.platform()) + + custom_headers = {'User-Agent': 'customer_user_agent'} + tables = service.list_tables(raw_response_hook=callback, headers=custom_headers) + + +class TestTableClientUnit(AsyncTableTestCase): + tables_storage_account_name = "fake_storage_account" + tables_primary_storage_account_key = "fakeXMZjnGsZGvd4bVr3Il5SeHA" # --Helpers----------------------------------------------------------------- def validate_standard_account_endpoints(self, service, account_name, account_key): @@ -37,105 +96,106 @@ def validate_standard_account_endpoints(self, service, account_name, account_key assert ('{}.{}'.format(account_name, 'table.core.windows.net') in service.url) or ('{}.{}'.format(account_name, 'table.cosmos.azure.com') in service.url) # --Direct Parameters Test Cases -------------------------------------------- - @TablesPreparer() - async def test_create_service_with_key_async(self, tables_storage_account_name, tables_primary_storage_account_key): + @pytest.mark.asyncio + async def test_create_service_with_key_async(self): # Arrange for client, url in SERVICES.items(): # Act service = client( - self.account_url(tables_storage_account_name, url), credential=tables_primary_storage_account_key, table_name='foo') + self.account_url(self.tables_storage_account_name, url), credential=self.tables_primary_storage_account_key, table_name='foo') # Assert - self.validate_standard_account_endpoints(service, tables_storage_account_name, tables_primary_storage_account_key) + self.validate_standard_account_endpoints(service, self.tables_storage_account_name, self.tables_primary_storage_account_key) assert service.scheme == 'https' - @TablesPreparer() - async def test_create_service_with_connection_string_async(self, tables_storage_account_name, tables_primary_storage_account_key): + @pytest.mark.asyncio + async def test_create_service_with_connection_string_async(self): for service_type in SERVICES.items(): # Act service = service_type[0].from_connection_string( - self.connection_string(tables_storage_account_name, tables_primary_storage_account_key), table_name="test") + self.connection_string(self.tables_storage_account_name, self.tables_primary_storage_account_key), table_name="test") # Assert - self.validate_standard_account_endpoints(service, tables_storage_account_name, tables_primary_storage_account_key) + self.validate_standard_account_endpoints(service, self.tables_storage_account_name, self.tables_primary_storage_account_key) assert service.scheme == 'https' - @TablesPreparer() - async def test_create_service_with_sas_async(self, tables_storage_account_name, tables_primary_storage_account_key): + @pytest.mark.asyncio + async def test_create_service_with_sas_async(self): # Arrange - url = self.account_url(tables_storage_account_name, "table") + url = self.account_url(self.tables_storage_account_name, "table") suffix = '.table.core.windows.net' for service_type in SERVICES: # Act service = service_type( - self.account_url(tables_storage_account_name, "table"), credential=self.sas_token, table_name='foo') + self.account_url(self.tables_storage_account_name, "table"), credential=self.generate_sas_token(), table_name='foo') # Assert assert service is not None - assert service.account_name == tables_storage_account_name - assert service.url.startswith('https://' + tables_storage_account_name + suffix) - assert service.url.endswith(self.sas_token) + assert service.account_name == self.tables_storage_account_name + assert service.url.startswith('https://' + self.tables_storage_account_name + suffix) + assert service.url.endswith(self.generate_sas_token()) assert service.credential is None - @TablesPreparer() - async def test_create_service_with_token_async(self, tables_storage_account_name, tables_primary_storage_account_key): - url = self.account_url(tables_storage_account_name, "table") + @pytest.mark.asyncio + async def test_create_service_with_token_async(self): + url = self.account_url(self.tables_storage_account_name, "table") suffix = '.table.core.windows.net' + self.token_credential = self.generate_fake_token() for service_type in SERVICES: # Act service = service_type(url, credential=self.token_credential, table_name='foo') # Assert assert service is not None - assert service.account_name == tables_storage_account_name - assert service.url.startswith('https://' + tables_storage_account_name + suffix) - assert service.credential == self.token_credential + assert service.account_name == self.tables_storage_account_name + assert service.url.startswith('https://' + self.tables_storage_account_name + suffix) + assert service.credential == self.token_credential assert not hasattr(service.credential, 'account_key') assert hasattr(service.credential, 'get_token') - @TablesPreparer() - async def test_create_service_with_token_and_http_async(self, tables_storage_account_name, tables_primary_storage_account_key): + @pytest.mark.asyncio + async def test_create_service_with_token_and_http_async(self): for service_type in SERVICES: # Act with pytest.raises(ValueError): - url = self.account_url(tables_storage_account_name, "table").replace('https', 'http') - service_type(url, credential=self.token_credential, table_name='foo') + url = self.account_url(self.tables_storage_account_name, "table").replace('https', 'http') + service_type(url, credential=self.generate_fake_token(), table_name='foo') - @TablesPreparer() - async def test_create_service_china_async(self, tables_storage_account_name, tables_primary_storage_account_key): + @pytest.mark.asyncio + async def test_create_service_china_async(self): # Arrange # TODO: Confirm regional cloud cosmos URLs for service_type in SERVICES.items(): # Act - url = self.account_url(tables_storage_account_name, "table").replace('core.windows.net', 'core.chinacloudapi.cn') + url = self.account_url(self.tables_storage_account_name, "table").replace('core.windows.net', 'core.chinacloudapi.cn') service = service_type[0]( - url, credential=tables_primary_storage_account_key, table_name='foo') + url, credential=self.tables_primary_storage_account_key, table_name='foo') # Assert assert service is not None - assert service.account_name == tables_storage_account_name - assert service.credential.account_name == tables_storage_account_name - assert service.credential.account_key == tables_primary_storage_account_key - assert service._primary_endpoint.startswith('https://{}.{}.core.chinacloudapi.cn'.format(tables_storage_account_name, "table")) + assert service.account_name == self.tables_storage_account_name + assert service.credential.account_name == self.tables_storage_account_name + assert service.credential.account_key == self.tables_primary_storage_account_key + assert service._primary_endpoint.startswith('https://{}.{}.core.chinacloudapi.cn'.format(self.tables_storage_account_name, "table")) - @TablesPreparer() - async def test_create_service_protocol_async(self, tables_storage_account_name, tables_primary_storage_account_key): + @pytest.mark.asyncio + async def test_create_service_protocol_async(self): # Arrange for service_type in SERVICES.items(): # Act - url = self.account_url(tables_storage_account_name, "table").replace('https', 'http') + url = self.account_url(self.tables_storage_account_name, "table").replace('https', 'http') service = service_type[0]( - url, credential=tables_primary_storage_account_key, table_name='foo') + url, credential=self.tables_primary_storage_account_key, table_name='foo') # Assert - self.validate_standard_account_endpoints(service, tables_storage_account_name, tables_primary_storage_account_key) + self.validate_standard_account_endpoints(service, self.tables_storage_account_name, self.tables_primary_storage_account_key) assert service.scheme == 'http' - @TablesPreparer() - async def test_create_service_empty_key_async(self, tables_storage_account_name, tables_primary_storage_account_key): + @pytest.mark.asyncio + async def test_create_service_empty_key_async(self): # Arrange TABLE_SERVICES = [TableServiceClient, TableClient] @@ -146,41 +206,41 @@ async def test_create_service_empty_key_async(self, tables_storage_account_name, assert str(e.value) == "You need to provide either a SAS token or an account shared key to authenticate." - @TablesPreparer() - async def test_create_service_with_socket_timeout_async(self, tables_storage_account_name, tables_primary_storage_account_key): + @pytest.mark.asyncio + async def test_create_service_with_socket_timeout_async(self): # Arrange for service_type in SERVICES.items(): # Act default_service = service_type[0]( - self.account_url(tables_storage_account_name, "table"), credential=tables_primary_storage_account_key, table_name='foo') + self.account_url(self.tables_storage_account_name, "table"), credential=self.tables_primary_storage_account_key, table_name='foo') service = service_type[0]( - self.account_url(tables_storage_account_name, "table"), credential=tables_primary_storage_account_key, + self.account_url(self.tables_storage_account_name, "table"), credential=self.tables_primary_storage_account_key, table_name='foo', connection_timeout=22) # Assert - self.validate_standard_account_endpoints(service, tables_storage_account_name, tables_primary_storage_account_key) + self.validate_standard_account_endpoints(service, self.tables_storage_account_name, self.tables_primary_storage_account_key) assert service._client._client._pipeline._transport.connection_config.timeout == 22 assert default_service._client._client._pipeline._transport.connection_config.timeout in [20, (20, 2000)] # --Connection String Test Cases -------------------------------------------- - @TablesPreparer() - async def test_create_service_with_connection_string_key_async(self, tables_storage_account_name, tables_primary_storage_account_key): + @pytest.mark.asyncio + async def test_create_service_with_connection_string_key_async(self): # Arrange - conn_string = 'AccountName={};AccountKey={};'.format(tables_storage_account_name, tables_primary_storage_account_key) + conn_string = 'AccountName={};AccountKey={};'.format(self.tables_storage_account_name, self.tables_primary_storage_account_key) for service_type in SERVICES.items(): # Act service = service_type[0].from_connection_string(conn_string, table_name='foo') # Assert - self.validate_standard_account_endpoints(service, tables_storage_account_name, tables_primary_storage_account_key) + self.validate_standard_account_endpoints(service, self.tables_storage_account_name, self.tables_primary_storage_account_key) assert service.scheme == 'https' - @TablesPreparer() - async def test_create_service_with_connection_string_sas_async(self, tables_storage_account_name, tables_primary_storage_account_key): + @pytest.mark.asyncio + async def test_create_service_with_connection_string_sas_async(self): # Arrange - conn_string = 'AccountName={};SharedAccessSignature={};'.format(tables_storage_account_name, self.sas_token) + conn_string = 'AccountName={};SharedAccessSignature={};'.format(self.tables_storage_account_name, self.generate_sas_token()) for service_type in SERVICES: # Act @@ -188,16 +248,16 @@ async def test_create_service_with_connection_string_sas_async(self, tables_stor # Assert assert service is not None - assert service.account_name == tables_storage_account_name - assert service.url.startswith('https://' + tables_storage_account_name + '.table.core.windows.net') - assert service.url.endswith(self.sas_token) + assert service.account_name == self.tables_storage_account_name + assert service.url.startswith('https://' + self.tables_storage_account_name + '.table.core.windows.net') + assert service.url.endswith(self.generate_sas_token()) assert service.credential is None - @TablesPreparer() - async def test_create_service_with_connection_string_cosmos_async(self, tables_storage_account_name, tables_primary_storage_account_key): + @pytest.mark.asyncio + async def test_create_service_with_connection_string_cosmos_async(self): # Arrange conn_string = 'DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};TableEndpoint=https://{0}.table.cosmos.azure.com:443/;'.format( - tables_storage_account_name, tables_primary_storage_account_key) + self.tables_storage_account_name, self.tables_primary_storage_account_key) for service_type in SERVICES: # Act @@ -205,18 +265,18 @@ async def test_create_service_with_connection_string_cosmos_async(self, tables_s # Assert assert service is not None - assert service.account_name == tables_storage_account_name - assert service.url.startswith('https://' + tables_storage_account_name + '.table.cosmos.azure.com') - assert service.credential.account_name == tables_storage_account_name - assert service.credential.account_key == tables_primary_storage_account_key - assert service._primary_endpoint.startswith('https://' + tables_storage_account_name + '.table.cosmos.azure.com') + assert service.account_name == self.tables_storage_account_name + assert service.url.startswith('https://' + self.tables_storage_account_name + '.table.cosmos.azure.com') + assert service.credential.account_name == self.tables_storage_account_name + assert service.credential.account_key == self.tables_primary_storage_account_key + assert service._primary_endpoint.startswith('https://' + self.tables_storage_account_name + '.table.cosmos.azure.com') assert service.scheme == 'https' - @TablesPreparer() - async def test_create_service_with_connection_string_endpoint_protocol_async(self, tables_storage_account_name, tables_primary_storage_account_key): + @pytest.mark.asyncio + async def test_create_service_with_connection_string_endpoint_protocol_async(self): # Arrange conn_string = 'AccountName={};AccountKey={};DefaultEndpointsProtocol=http;EndpointSuffix=core.chinacloudapi.cn;'.format( - tables_storage_account_name, tables_primary_storage_account_key) + self.tables_storage_account_name, self.tables_primary_storage_account_key) for service_type in SERVICES.items(): # Act @@ -224,62 +284,62 @@ async def test_create_service_with_connection_string_endpoint_protocol_async(sel # Assert assert service is not None - assert service.account_name == tables_storage_account_name - assert service.credential.account_name == tables_storage_account_name - assert service.credential.account_key == tables_primary_storage_account_key - assert service._primary_endpoint.startswith('http://{}.{}.core.chinacloudapi.cn'.format(tables_storage_account_name, "table")) + assert service.account_name == self.tables_storage_account_name + assert service.credential.account_name == self.tables_storage_account_name + assert service.credential.account_key == self.tables_primary_storage_account_key + assert service._primary_endpoint.startswith('http://{}.{}.core.chinacloudapi.cn'.format(self.tables_storage_account_name, "table")) assert service.scheme == 'http' - @TablesPreparer() - async def test_create_service_with_connection_string_emulated_async(self, tables_storage_account_name, tables_primary_storage_account_key): + @pytest.mark.asyncio + async def test_create_service_with_connection_string_emulated_async(self): # Arrange for service_type in SERVICES.items(): - conn_string = 'UseDevelopmentStorage=true;'.format(tables_storage_account_name, tables_primary_storage_account_key) + conn_string = 'UseDevelopmentStorage=true;'.format(self.tables_storage_account_name, self.tables_primary_storage_account_key) # Act with pytest.raises(ValueError): service = service_type[0].from_connection_string(conn_string, table_name="foo") - @TablesPreparer() - async def test_create_service_with_connection_string_custom_domain_async(self, tables_storage_account_name, tables_primary_storage_account_key): + @pytest.mark.asyncio + async def test_create_service_with_connection_string_custom_domain_async(self): # Arrange for service_type in SERVICES.items(): conn_string = 'AccountName={};AccountKey={};TableEndpoint=www.mydomain.com;'.format( - tables_storage_account_name, tables_primary_storage_account_key) + self.tables_storage_account_name, self.tables_primary_storage_account_key) # Act service = service_type[0].from_connection_string(conn_string, table_name="foo") # Assert assert service is not None - assert service.account_name == tables_storage_account_name - assert service.credential.account_name == tables_storage_account_name - assert service.credential.account_key == tables_primary_storage_account_key + assert service.account_name == self.tables_storage_account_name + assert service.credential.account_name == self.tables_storage_account_name + assert service.credential.account_key == self.tables_primary_storage_account_key assert service._primary_endpoint.startswith('https://www.mydomain.com') - @TablesPreparer() - async def test_create_service_with_conn_str_custom_domain_trailing_slash_async(self, tables_storage_account_name, tables_primary_storage_account_key): + @pytest.mark.asyncio + async def test_create_service_with_conn_str_custom_domain_trailing_slash_async(self): # Arrange for service_type in SERVICES.items(): conn_string = 'AccountName={};AccountKey={};TableEndpoint=www.mydomain.com/;'.format( - tables_storage_account_name, tables_primary_storage_account_key) + self.tables_storage_account_name, self.tables_primary_storage_account_key) # Act service = service_type[0].from_connection_string(conn_string, table_name="foo") # Assert assert service is not None - assert service.account_name == tables_storage_account_name - assert service.credential.account_name == tables_storage_account_name - assert service.credential.account_key == tables_primary_storage_account_key + assert service.account_name == self.tables_storage_account_name + assert service.credential.account_name == self.tables_storage_account_name + assert service.credential.account_key == self.tables_primary_storage_account_key assert service._primary_endpoint.startswith('https://www.mydomain.com') - @TablesPreparer() - async def test_create_service_with_conn_str_custom_domain_sec_override_async(self, tables_storage_account_name, tables_primary_storage_account_key): + @pytest.mark.asyncio + async def test_create_service_with_conn_str_custom_domain_sec_override_async(self): # Arrange for service_type in SERVICES.items(): conn_string = 'AccountName={};AccountKey={};TableEndpoint=www.mydomain.com/;'.format( - tables_storage_account_name, tables_primary_storage_account_key) + self.tables_storage_account_name, self.tables_primary_storage_account_key) # Act service = service_type[0].from_connection_string( @@ -287,30 +347,30 @@ async def test_create_service_with_conn_str_custom_domain_sec_override_async(sel # Assert assert service is not None - assert service.account_name == tables_storage_account_name - assert service.credential.account_name == tables_storage_account_name - assert service.credential.account_key == tables_primary_storage_account_key + assert service.account_name == self.tables_storage_account_name + assert service.credential.account_name == self.tables_storage_account_name + assert service.credential.account_key == self.tables_primary_storage_account_key assert service._primary_endpoint.startswith('https://www.mydomain.com') - @TablesPreparer() - async def test_create_service_with_conn_str_fails_if_sec_without_primary_async(self, tables_storage_account_name, tables_primary_storage_account_key): + @pytest.mark.asyncio + async def test_create_service_with_conn_str_fails_if_sec_without_primary_async(self): for service_type in SERVICES.items(): # Arrange conn_string = 'AccountName={};AccountKey={};{}=www.mydomain.com;'.format( - tables_storage_account_name, tables_primary_storage_account_key, + self.tables_storage_account_name, self.tables_primary_storage_account_key, _CONNECTION_ENDPOINTS_SECONDARY.get(service_type[1])) # Fails if primary excluded with pytest.raises(ValueError): service = service_type[0].from_connection_string(conn_string, table_name="foo") - @TablesPreparer() - async def test_create_service_with_conn_str_succeeds_if_sec_with_primary_async(self, tables_storage_account_name, tables_primary_storage_account_key): + @pytest.mark.asyncio + async def test_create_service_with_conn_str_succeeds_if_sec_with_primary_async(self): for service_type in SERVICES.items(): # Arrange conn_string = 'AccountName={};AccountKey={};{}=www.mydomain.com;{}=www-sec.mydomain.com;'.format( - tables_storage_account_name, - tables_primary_storage_account_key, + self.tables_storage_account_name, + self.tables_primary_storage_account_key, _CONNECTION_ENDPOINTS.get(service_type[1]), _CONNECTION_ENDPOINTS_SECONDARY.get(service_type[1])) @@ -319,25 +379,25 @@ async def test_create_service_with_conn_str_succeeds_if_sec_with_primary_async(s # Assert assert service is not None - assert service.account_name == tables_storage_account_name - assert service.credential.account_name == tables_storage_account_name - assert service.credential.account_key == tables_primary_storage_account_key + assert service.account_name == self.tables_storage_account_name + assert service.credential.account_name == self.tables_storage_account_name + assert service.credential.account_key == self.tables_primary_storage_account_key assert service._primary_endpoint.startswith('https://www.mydomain.com') - @TablesPreparer() - async def test_create_service_with_custom_account_endpoint_path_async(self, tables_storage_account_name, tables_primary_storage_account_key): - custom_account_url = "http://local-machine:11002/custom/account/path/" + self.sas_token + @pytest.mark.asyncio + async def test_create_service_with_custom_account_endpoint_path_async(self): + custom_account_url = "http://local-machine:11002/custom/account/path/" + self.generate_sas_token() for service_type in SERVICES.items(): conn_string = 'DefaultEndpointsProtocol=http;AccountName={};AccountKey={};TableEndpoint={};'.format( - tables_storage_account_name, tables_primary_storage_account_key, custom_account_url) + self.tables_storage_account_name, self.tables_primary_storage_account_key, custom_account_url) # Act service = service_type[0].from_connection_string(conn_string, table_name="foo") # Assert - assert service.account_name == tables_storage_account_name - assert service.credential.account_name == tables_storage_account_name - assert service.credential.account_key == tables_primary_storage_account_key + assert service.account_name == self.tables_storage_account_name + assert service.credential.account_name == self.tables_storage_account_name + assert service.credential.account_key == self.tables_primary_storage_account_key assert service._primary_hostname == 'local-machine:11002/custom/account/path' service = TableServiceClient(account_url=custom_account_url) @@ -353,91 +413,36 @@ async def test_create_service_with_custom_account_endpoint_path_async(self, tabl assert service._primary_hostname == 'local-machine:11002/custom/account/path' assert service.url.startswith('http://local-machine:11002/custom/account/path') - service = TableClient.from_table_url("http://local-machine:11002/custom/account/path/foo" + self.sas_token) + service = TableClient.from_table_url("http://local-machine:11002/custom/account/path/foo" + self.generate_sas_token()) assert service.account_name == None assert service.table_name == "foo" assert service.credential == None assert service._primary_hostname == 'local-machine:11002/custom/account/path' assert service.url.startswith('http://local-machine:11002/custom/account/path') - @TablesPreparer() - async def test_user_agent_default_async(self, tables_storage_account_name, tables_primary_storage_account_key): - service = TableServiceClient(self.account_url(tables_storage_account_name, "table"), credential=tables_primary_storage_account_key) - - def callback(response): - assert 'User-Agent' in response.http_request.headers - assert response.http_request.headers['User-Agent'] in "azsdk-python-data-tables/{} Python/{} ({})".format( - VERSION, - platform.python_version(), - platform.platform()) - - tables = service.list_tables(raw_response_hook=callback) - assert tables is not None - - @TablesPreparer() - async def test_user_agent_custom_async(self, tables_storage_account_name, tables_primary_storage_account_key): - custom_app = "TestApp/v1.0" - service = TableServiceClient( - self.account_url(tables_storage_account_name, "table"), credential=tables_primary_storage_account_key, user_agent=custom_app) - - def callback(response): - assert 'User-Agent' in response.http_request.headers - assert "TestApp/v1.0 azsdk-python-data-tables/{} Python/{} ({})".format( - VERSION, - platform.python_version(), - platform.platform()) in response.http_request.headers['User-Agent'] - - tables = service.list_tables(raw_response_hook=callback) - assert tables is not None - - def callback(response): - assert 'User-Agent' in response.http_request.headers - assert "TestApp/v2.0 TestApp/v1.0 azsdk-python-data-tables/{} Python/{} ({})".format( - VERSION, - platform.python_version(), - platform.platform()) in response.http_request.headers['User-Agent'] - - tables = service.list_tables(raw_response_hook=callback, user_agent="TestApp/v2.0") - assert tables is not None - - @TablesPreparer() - async def test_user_agent_append(self, tables_storage_account_name, tables_primary_storage_account_key): - # TODO: fix this one - service = TableServiceClient(self.account_url(tables_storage_account_name, "table"), credential=tables_primary_storage_account_key) - - def callback(response): - assert 'User-Agent' in response.http_request.headers - assert response.http_request.headers['User-Agent'] == "azsdk-python-data-tables/{} Python/{} ({}) customer_user_agent".format( - VERSION, - platform.python_version(), - platform.platform()) - - custom_headers = {'User-Agent': 'customer_user_agent'} - tables = service.list_tables(raw_response_hook=callback, headers=custom_headers) - - @TablesPreparer() - async def test_create_table_client_with_complete_table_url_async(self, tables_storage_account_name, tables_primary_storage_account_key): + @pytest.mark.asyncio + async def test_create_table_client_with_complete_table_url_async(self): # Arrange - table_url = self.account_url(tables_storage_account_name, "table") + "/foo" - service = TableClient(table_url, table_name='bar', credential=tables_primary_storage_account_key) + table_url = self.account_url(self.tables_storage_account_name, "table") + "/foo" + service = TableClient(table_url, table_name='bar', credential=self.tables_primary_storage_account_key) # Assert assert service.scheme == 'https' assert service.table_name == 'bar' - assert service.account_name == tables_storage_account_name + assert service.account_name == self.tables_storage_account_name - @TablesPreparer() - async def test_create_table_client_with_complete_url_async(self, tables_storage_account_name, tables_primary_storage_account_key): + @pytest.mark.asyncio + async def test_create_table_client_with_complete_url_async(self): # Arrange - table_url = "https://{}.table.core.windows.net:443/foo".format(tables_storage_account_name) - service = TableClient(account_url=table_url, table_name='bar', credential=tables_primary_storage_account_key) + table_url = "https://{}.table.core.windows.net:443/foo".format(self.tables_storage_account_name) + service = TableClient(account_url=table_url, table_name='bar', credential=self.tables_primary_storage_account_key) # Assert assert service.scheme == 'https' assert service.table_name == 'bar' - assert service.account_name == tables_storage_account_name + assert service.account_name == self.tables_storage_account_name - @AzureTestCase.await_prepared_test + @pytest.mark.asyncio async def test_create_table_client_with_invalid_name_async(self): # Arrange table_url = "https://{}.table.core.windows.net:443/foo".format("storage_account_name") @@ -445,11 +450,11 @@ async def test_create_table_client_with_invalid_name_async(self): # Assert with pytest.raises(ValueError) as excinfo: - service = TableClient(account_url=table_url, table_name=invalid_table_name, credential="tables_primary_storage_account_key") + service = TableClient(account_url=table_url, table_name=invalid_table_name, credential="self.tables_primary_storage_account_key") assert "Table names must be alphanumeric, cannot begin with a number, and must be between 3-63 characters long."in str(excinfo) - @AzureTestCase.await_prepared_test + @pytest.mark.asyncio async def test_error_with_malformed_conn_str_async(self): # Arrange @@ -464,24 +469,24 @@ async def test_error_with_malformed_conn_str_async(self): elif conn_str in ("foobar=baz=foo" , "foo=;bar=;", "=", "=;=="): assert str(e.value) == "Connection string missing required connection details." - @TablesPreparer() - async def test_closing_pipeline_client_async(self, tables_storage_account_name, tables_primary_storage_account_key): + @pytest.mark.asyncio + async def test_closing_pipeline_client_async(self): # Arrange for client, url in SERVICES.items(): # Act service = client( - self.account_url(tables_storage_account_name, "table"), credential=tables_primary_storage_account_key, table_name='table') + self.account_url(self.tables_storage_account_name, "table"), credential=self.tables_primary_storage_account_key, table_name='table') # Assert async with service: assert hasattr(service, 'close') await service.close() - @TablesPreparer() - async def test_closing_pipeline_client_simple_async(self, tables_storage_account_name, tables_primary_storage_account_key): + @pytest.mark.asyncio + async def test_closing_pipeline_client_simple_async(self): # Arrange for client, url in SERVICES.items(): # Act service = client( - self.account_url(tables_storage_account_name, "table"), credential=tables_primary_storage_account_key, table_name='table') + self.account_url(self.tables_storage_account_name, "table"), credential=self.tables_primary_storage_account_key, table_name='table') await service.close() diff --git a/sdk/tables/azure-data-tables/tests/test_table_client_cosmos.py b/sdk/tables/azure-data-tables/tests/test_table_client_cosmos.py index 968d0233fa3b..3ee62a23136d 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_client_cosmos.py +++ b/sdk/tables/azure-data-tables/tests/test_table_client_cosmos.py @@ -8,8 +8,10 @@ from time import sleep import sys +from devtools_testutils import AzureTestCase + from azure.data.tables import TableServiceClient, TableClient -from azure.data.tables._version import VERSION +from azure.data.tables import __version__ as VERSION from _shared.testcase import ( TableTestCase, @@ -27,11 +29,80 @@ _CONNECTION_ENDPOINTS_SECONDARY = {'table': 'TableSecondaryEndpoint', 'cosmos': 'TableSecondaryEndpoint'} -class StorageTableClientTest(TableTestCase): - def setUp(self): - super(StorageTableClientTest, self).setUp() - self.sas_token = self.generate_sas_token() - self.token_credential = self.generate_oauth_token() +class TestTableClient(AzureTestCase, TableTestCase): + + @pytest.mark.skipif(sys.version_info < (3, 0), reason="Malformed string") + @CosmosPreparer() + def test_user_agent_default(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + service = TableServiceClient(self.account_url(tables_cosmos_account_name, "cosmos"), credential=tables_primary_cosmos_account_key) + + def callback(response): + assert 'User-Agent' in response.http_request.headers + assert "azsdk-python-data-tables/{} Python/{} ({})".format( + VERSION, + platform.python_version(), + platform.platform()) in response.http_request.headers['User-Agent'] + + tables = list(service.list_tables(raw_response_hook=callback)) + assert isinstance(tables, list) + + if self.is_live: + sleep(SLEEP_DELAY) + + @pytest.mark.skipif(sys.version_info < (3, 0), reason="requires Python3") + @CosmosPreparer() + def test_user_agent_custom(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + custom_app = "TestApp/v1.0" + service = TableServiceClient( + self.account_url(tables_cosmos_account_name, "cosmos"), credential=tables_primary_cosmos_account_key, user_agent=custom_app) + + def callback(response): + assert 'User-Agent' in response.http_request.headers + assert "TestApp/v1.0 azsdk-python-data-tables/{} Python/{} ({})".format( + VERSION, + platform.python_version(), + platform.platform()) in response.http_request.headers['User-Agent'] + + tables = list(service.list_tables(raw_response_hook=callback)) + assert isinstance(tables, list) + + def callback(response): + assert 'User-Agent' in response.http_request.headers + assert "TestApp/v2.0 TestApp/v1.0 azsdk-python-data-tables/{} Python/{} ({})".format( + VERSION, + platform.python_version(), + platform.platform()) in response.http_request.headers['User-Agent'] + + tables = list(service.list_tables(raw_response_hook=callback, user_agent="TestApp/v2.0")) + assert isinstance(tables, list) + + if self.is_live: + sleep(SLEEP_DELAY) + + @CosmosPreparer() + def test_user_agent_append(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + service = self.create_client_from_credential( + TableServiceClient, + account_url=self.account_url(tables_cosmos_account_name, "cosmos"), + credential=tables_primary_cosmos_account_key) + + def callback(response): + assert 'User-Agent' in response.http_request.headers + assert response.http_request.headers['User-Agent'] == "azsdk-python-data-tables/{} Python/{} ({}) customer_user_agent".format( + VERSION, + platform.python_version(), + platform.platform()) + + custom_headers = {'User-Agent': 'customer_user_agent'} + tables = service.list_tables(raw_response_hook=callback, headers=custom_headers) + + if self.is_live: + sleep(SLEEP_DELAY) + + +class TestTableClientUnit(TableTestCase): + tables_cosmos_account_name = "fake_storage_account" + tables_primary_cosmos_account_key = "fakeXMZjnGsZGvd4bVr3Il5SeHA" # --Helpers----------------------------------------------------------------- def validate_standard_account_endpoints(self, service, account_name, account_key): @@ -45,134 +116,117 @@ def _account_url(self, account_name): return "https://{}.table.cosmos.azure.com".format(account_name) # --Direct Parameters Test Cases -------------------------------------------- - @CosmosPreparer() - def test_create_service_with_key(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + + def test_create_service_with_key(self): # Arrange for client, url in SERVICES.items(): # Act - service = self.create_client_from_credential( - client, - account_url=self._account_url(tables_cosmos_account_name), - credential=tables_primary_cosmos_account_key, + service = client( + account_url=self._account_url(self.tables_cosmos_account_name), + credential=self.tables_primary_cosmos_account_key, table_name='foo') # Assert - self.validate_standard_account_endpoints(service, tables_cosmos_account_name, tables_primary_cosmos_account_key) + self.validate_standard_account_endpoints(service, self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key) assert service.scheme == 'https' - @CosmosPreparer() - def test_create_service_with_connection_string(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + + def test_create_service_with_connection_string(self): for client, url in SERVICES.items(): # Act - service = self.create_client_from_credential( - client, - account_url=self._account_url(tables_cosmos_account_name), - credential=tables_primary_cosmos_account_key, + service = client( + account_url=self._account_url(self.tables_cosmos_account_name), + credential=self.tables_primary_cosmos_account_key, table_name="test") # Assert - self.validate_standard_account_endpoints(service, tables_cosmos_account_name, tables_primary_cosmos_account_key) + self.validate_standard_account_endpoints(service, self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key) assert service.scheme == 'https' - if self.is_live: - sleep(SLEEP_DELAY) - @CosmosPreparer() - def test_create_service_with_sas(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + def test_create_service_with_sas(self): # Arrange - url = self.account_url(tables_cosmos_account_name, "cosmos") + url = self.account_url(self.tables_cosmos_account_name, "cosmos") suffix = '.table.cosmos.azure.com' + self.sas_token = self.generate_sas_token() for service_type in SERVICES: # Act - service = self.create_client_from_credential( - service_type, - account_url=self._account_url(tables_cosmos_account_name), + service = service_type( + account_url=self._account_url(self.tables_cosmos_account_name), credential=self.sas_token, table_name="foo") # Assert assert service is not None - assert service.account_name == tables_cosmos_account_name - assert service.url.startswith('https://' + tables_cosmos_account_name + suffix) + assert service.account_name == self.tables_cosmos_account_name + assert service.url.startswith('https://' + self.tables_cosmos_account_name + suffix) assert service.url.endswith(self.sas_token) assert service.credential is None - if self.is_live: - sleep(SLEEP_DELAY) - @CosmosPreparer() - def test_create_service_with_token(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): - url = self.account_url(tables_cosmos_account_name, "cosmos") + def test_create_service_with_token(self): + url = self.account_url(self.tables_cosmos_account_name, "cosmos") suffix = '.table.cosmos.azure.com' for service_type in SERVICES: # Act - service = self.create_client_from_credential( - service_type, - account_url=self._account_url(tables_cosmos_account_name), - credential=tables_primary_cosmos_account_key, + service = service_type( + account_url=self._account_url(self.tables_cosmos_account_name), + credential=self.tables_primary_cosmos_account_key, table_name="foo") # Assert assert service is not None - assert service.account_name == tables_cosmos_account_name - assert service.url.startswith('https://' + tables_cosmos_account_name + suffix) + assert service.account_name == self.tables_cosmos_account_name + assert service.url.startswith('https://' + self.tables_cosmos_account_name + suffix) assert not hasattr(service, 'account_key') - @CosmosPreparer() - def test_create_service_with_token_and_http(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + + def test_create_service_with_token_and_http(self): + self.token_credential = self.generate_fake_token() for service_type in SERVICES: # Act with pytest.raises(ValueError): - url = self.account_url(tables_cosmos_account_name, "cosmos").replace('https', 'http') - service = self.create_client_from_credential( - service_type, + url = self.account_url(self.tables_cosmos_account_name, "cosmos").replace('https', 'http') + service = service_type( account_url=url, credential=self.token_credential, table_name="foo") @pytest.mark.skip("Testing against a different cloud than the one created in powershell script") - @CosmosPreparer() - def test_create_service_china(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + + def test_create_service_china(self): # Arrange # TODO: Confirm regional cloud cosmos URLs for service_type in SERVICES.items(): # Act - url = self.account_url(tables_cosmos_account_name, "cosmos").replace('core.windows.net', 'core.chinacloudapi.cn') + url = self.account_url(self.tables_cosmos_account_name, "cosmos").replace('core.windows.net', 'core.chinacloudapi.cn') if 'cosmos.azure' in url: pytest.skip("Confirm cosmos national cloud URLs") service = service_type[0]( - url, credential=tables_primary_cosmos_account_key, table_name='foo') + url, credential=self.tables_primary_cosmos_account_key, table_name='foo') # Assert assert service is not None - assert service.account_name == tables_cosmos_account_name - assert service.credential.account_name == tables_cosmos_account_name - assert service.credential.account_key == tables_primary_cosmos_account_key - assert service._primary_endpoint.startswith('https://{}.{}.core.chinacloudapi.cn'.format(tables_cosmos_account_name, "table")) + assert service.account_name == self.tables_cosmos_account_name + assert service.credential.account_name == self.tables_cosmos_account_name + assert service.credential.account_key == self.tables_primary_cosmos_account_key + assert service._primary_endpoint.startswith('https://{}.{}.core.chinacloudapi.cn'.format(self.tables_cosmos_account_name, "table")) - if self.is_live: - sleep(SLEEP_DELAY) - - @CosmosPreparer() - def test_create_service_protocol(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + def test_create_service_protocol(self): # Arrange - url = self._account_url(tables_cosmos_account_name).replace('https', 'http') + url = self._account_url(self.tables_cosmos_account_name).replace('https', 'http') suffix = '.table.cosmos.azure.com' for service_type in SERVICES: # Act - service = self.create_client_from_credential( - service_type, + service = service_type( account_url=url, - credential=tables_primary_cosmos_account_key, + credential=self.tables_primary_cosmos_account_key, table_name="foo") # Assert - self.validate_standard_account_endpoints(service, tables_cosmos_account_name, tables_primary_cosmos_account_key) + self.validate_standard_account_endpoints(service, self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key) assert service.scheme == 'http' - if self.is_live: - sleep(SLEEP_DELAY) - @CosmosPreparer() - def test_create_service_empty_key(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + def test_create_service_empty_key(self): # Arrange TABLE_SERVICES = [TableServiceClient, TableClient] @@ -183,51 +237,44 @@ def test_create_service_empty_key(self, tables_cosmos_account_name, tables_prima assert str(e.value) == "You need to provide either a SAS token or an account shared key to authenticate." - if self.is_live: - sleep(SLEEP_DELAY) - - @CosmosPreparer() - def test_create_service_with_socket_timeout(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + def test_create_service_with_socket_timeout(self): # Arrange for service_type in SERVICES.items(): # Act - default_service = self.create_client_from_credential( - service_type[0], - account_url=self._account_url(tables_cosmos_account_name), - credential=tables_primary_cosmos_account_key, + default_service = service_type[0]( + account_url=self._account_url(self.tables_cosmos_account_name), + credential=self.tables_primary_cosmos_account_key, table_name="foo") - service = self.create_client_from_credential( - service_type[0], - account_url=self._account_url(tables_cosmos_account_name), - credential=tables_primary_cosmos_account_key, + service = service_type[0]( + account_url=self._account_url(self.tables_cosmos_account_name), + credential=self.tables_primary_cosmos_account_key, table_name="foo", connection_timeout=22) # Assert - self.validate_standard_account_endpoints(service, tables_cosmos_account_name, tables_primary_cosmos_account_key) + self.validate_standard_account_endpoints(service, self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key) assert service._client._client._pipeline._transport.connection_config.timeout == 22 assert default_service._client._client._pipeline._transport.connection_config.timeout in [20, (20, 2000)] - if self.is_live: - sleep(SLEEP_DELAY) + # --Connection String Test Cases -------------------------------------------- - @CosmosPreparer() - def test_create_service_with_connection_string_key(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + def test_create_service_with_connection_string_key(self): # Arrange - conn_string = 'AccountName={};AccountKey={};'.format(tables_cosmos_account_name, tables_primary_cosmos_account_key) + conn_string = 'AccountName={};AccountKey={};'.format(self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key) for service_type in SERVICES.items(): # Act service = service_type[0].from_connection_string(conn_string, table_name='foo') # Assert - self.validate_standard_account_endpoints(service, tables_cosmos_account_name, tables_primary_cosmos_account_key) + self.validate_standard_account_endpoints(service, self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key) assert service.scheme == 'https' - @CosmosPreparer() - def test_create_service_with_connection_string_sas(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + + def test_create_service_with_connection_string_sas(self): # Arrange - conn_string = 'AccountName={};SharedAccessSignature={};'.format(tables_cosmos_account_name, self.sas_token) + self.sas_token = self.generate_sas_token() + conn_string = 'AccountName={};SharedAccessSignature={};'.format(self.tables_cosmos_account_name, self.sas_token) for service_type in SERVICES: # Act @@ -235,15 +282,15 @@ def test_create_service_with_connection_string_sas(self, tables_cosmos_account_n # Assert assert service is not None - assert service.url.startswith('https://' + tables_cosmos_account_name + '.table.core.windows.net') + assert service.url.startswith('https://' + self.tables_cosmos_account_name + '.table.core.windows.net') assert service.url.endswith(self.sas_token) assert service.credential is None - @CosmosPreparer() - def test_create_service_with_connection_string_cosmos(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + + def test_create_service_with_connection_string_cosmos(self): # Arrange conn_string = 'DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};TableEndpoint=https://{0}.table.cosmos.azure.com:443/;'.format( - tables_cosmos_account_name, tables_primary_cosmos_account_key) + self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key) for service_type in SERVICES: # Act @@ -251,19 +298,19 @@ def test_create_service_with_connection_string_cosmos(self, tables_cosmos_accoun # Assert assert service is not None - assert service.account_name == tables_cosmos_account_name - assert service.url.startswith('https://' + tables_cosmos_account_name + '.table.cosmos.azure.com') - assert service.credential.account_name == tables_cosmos_account_name - assert service.credential.account_key == tables_primary_cosmos_account_key - assert service._primary_endpoint.startswith('https://' + tables_cosmos_account_name + '.table.cosmos.azure.com') + assert service.account_name == self.tables_cosmos_account_name + assert service.url.startswith('https://' + self.tables_cosmos_account_name + '.table.cosmos.azure.com') + assert service.credential.account_name == self.tables_cosmos_account_name + assert service.credential.account_key == self.tables_primary_cosmos_account_key + assert service._primary_endpoint.startswith('https://' + self.tables_cosmos_account_name + '.table.cosmos.azure.com') assert service.scheme == 'https' @pytest.mark.skip("Tests fail with non-standard clouds") - @CosmosPreparer() - def test_create_service_with_connection_string_endpoint_protocol(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + + def test_create_service_with_connection_string_endpoint_protocol(self): # Arrange conn_string = 'AccountName={};AccountKey={};DefaultEndpointsProtocol=http;EndpointSuffix=core.chinacloudapi.cn;'.format( - tables_cosmos_account_name, tables_primary_cosmos_account_key) + self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key) for service_type in SERVICES.items(): # Act @@ -271,64 +318,61 @@ def test_create_service_with_connection_string_endpoint_protocol(self, tables_co # Assert assert service is not None - assert service.account_name == tables_cosmos_account_name - assert service.credential.account_name == tables_cosmos_account_name - assert service.credential.account_key == tables_primary_cosmos_account_key - assert service._primary_endpoint.startswith('http://{}.{}.core.chinacloudapi.cn'.format(tables_cosmos_account_name, "table")) + assert service.account_name == self.tables_cosmos_account_name + assert service.credential.account_name == self.tables_cosmos_account_name + assert service.credential.account_key == self.tables_primary_cosmos_account_key + assert service._primary_endpoint.startswith('http://{}.{}.core.chinacloudapi.cn'.format(self.tables_cosmos_account_name, "table")) assert service.scheme == 'http' - @CosmosPreparer() - def test_create_service_with_connection_string_emulated(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + + def test_create_service_with_connection_string_emulated(self): # Arrange for service_type in SERVICES.items(): - conn_string = 'UseDevelopmentStorage=true;'.format(tables_cosmos_account_name, tables_primary_cosmos_account_key) + conn_string = 'UseDevelopmentStorage=true;'.format(self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key) # Act with pytest.raises(ValueError): service = service_type[0].from_connection_string(conn_string, table_name="foo") - @CosmosPreparer() - def test_create_service_with_connection_string_custom_domain(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + + def test_create_service_with_connection_string_custom_domain(self): # Arrange for service_type in SERVICES.items(): conn_string = 'AccountName={};AccountKey={};TableEndpoint=www.mydomain.com;'.format( - tables_cosmos_account_name, tables_primary_cosmos_account_key) + self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key) # Act service = service_type[0].from_connection_string(conn_string, table_name="foo") # Assert assert service is not None - assert service.account_name == tables_cosmos_account_name - assert service.credential.account_name == tables_cosmos_account_name - assert service.credential.account_key == tables_primary_cosmos_account_key + assert service.account_name == self.tables_cosmos_account_name + assert service.credential.account_name == self.tables_cosmos_account_name + assert service.credential.account_key == self.tables_primary_cosmos_account_key assert service._primary_endpoint.startswith('https://www.mydomain.com') - @CosmosPreparer() - def test_create_service_with_conn_str_custom_domain_trailing_slash(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + + def test_create_service_with_conn_str_custom_domain_trailing_slash(self): # Arrange for service_type in SERVICES.items(): conn_string = 'AccountName={};AccountKey={};TableEndpoint=www.mydomain.com/;'.format( - tables_cosmos_account_name, tables_primary_cosmos_account_key) + self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key) # Act service = service_type[0].from_connection_string(conn_string, table_name="foo") # Assert assert service is not None - assert service.account_name == tables_cosmos_account_name - assert service.credential.account_name == tables_cosmos_account_name - assert service.credential.account_key == tables_primary_cosmos_account_key + assert service.account_name == self.tables_cosmos_account_name + assert service.credential.account_name == self.tables_cosmos_account_name + assert service.credential.account_key == self.tables_primary_cosmos_account_key assert service._primary_endpoint.startswith('https://www.mydomain.com') - if self.is_live: - sleep(SLEEP_DELAY) - @CosmosPreparer() - def test_create_service_with_conn_str_custom_domain_sec_override(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + def test_create_service_with_conn_str_custom_domain_sec_override(self): # Arrange for service_type in SERVICES.items(): conn_string = 'AccountName={};AccountKey={};TableEndpoint=www.mydomain.com/;'.format( - tables_cosmos_account_name, tables_primary_cosmos_account_key) + self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key) # Act service = service_type[0].from_connection_string( @@ -336,19 +380,16 @@ def test_create_service_with_conn_str_custom_domain_sec_override(self, tables_co # Assert assert service is not None - assert service.account_name == tables_cosmos_account_name - assert service.credential.account_name == tables_cosmos_account_name - assert service.credential.account_key == tables_primary_cosmos_account_key + assert service.account_name == self.tables_cosmos_account_name + assert service.credential.account_name == self.tables_cosmos_account_name + assert service.credential.account_key == self.tables_primary_cosmos_account_key assert service._primary_endpoint.startswith('https://www.mydomain.com') - if self.is_live: - sleep(SLEEP_DELAY) - @CosmosPreparer() - def test_create_service_with_conn_str_fails_if_sec_without_primary(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + def test_create_service_with_conn_str_fails_if_sec_without_primary(self): for service_type in SERVICES.items(): # Arrange conn_string = 'AccountName={};AccountKey={};{}=www.mydomain.com;'.format( - tables_cosmos_account_name, tables_primary_cosmos_account_key, + self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key, _CONNECTION_ENDPOINTS_SECONDARY.get(service_type[1])) # Act @@ -357,13 +398,13 @@ def test_create_service_with_conn_str_fails_if_sec_without_primary(self, tables_ with pytest.raises(ValueError): service = service_type[0].from_connection_string(conn_string, table_name="foo") - @CosmosPreparer() - def test_create_service_with_conn_str_succeeds_if_sec_with_primary(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + + def test_create_service_with_conn_str_succeeds_if_sec_with_primary(self): for service_type in SERVICES.items(): # Arrange conn_string = 'AccountName={};AccountKey={};{}=www.mydomain.com;{}=www-sec.mydomain.com;'.format( - tables_cosmos_account_name, - tables_primary_cosmos_account_key, + self.tables_cosmos_account_name, + self.tables_primary_cosmos_account_key, _CONNECTION_ENDPOINTS.get(service_type[1]), _CONNECTION_ENDPOINTS_SECONDARY.get(service_type[1])) @@ -372,27 +413,25 @@ def test_create_service_with_conn_str_succeeds_if_sec_with_primary(self, tables_ # Assert assert service is not None - assert service.account_name == tables_cosmos_account_name - assert service.credential.account_name == tables_cosmos_account_name - assert service.credential.account_key == tables_primary_cosmos_account_key + assert service.account_name == self.tables_cosmos_account_name + assert service.credential.account_name == self.tables_cosmos_account_name + assert service.credential.account_key == self.tables_primary_cosmos_account_key assert service._primary_endpoint.startswith('https://www.mydomain.com') - if self.is_live: - sleep(SLEEP_DELAY) - @CosmosPreparer() - def test_create_service_with_custom_account_endpoint_path(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + def test_create_service_with_custom_account_endpoint_path(self): + self.sas_token = self.generate_sas_token() custom_account_url = "http://local-machine:11002/custom/account/path/" + self.sas_token for service_type in SERVICES.items(): conn_string = 'DefaultEndpointsProtocol=http;AccountName={};AccountKey={};TableEndpoint={};'.format( - tables_cosmos_account_name, tables_primary_cosmos_account_key, custom_account_url) + self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key, custom_account_url) # Act service = service_type[0].from_connection_string(conn_string, table_name="foo") # Assert - assert service.account_name == tables_cosmos_account_name - assert service.credential.account_name == tables_cosmos_account_name - assert service.credential.account_key == tables_primary_cosmos_account_key + assert service.account_name == self.tables_cosmos_account_name + assert service.credential.account_name == self.tables_cosmos_account_name + assert service.credential.account_key == self.tables_primary_cosmos_account_key assert service._primary_hostname == 'local-machine:11002/custom/account/path' service = TableServiceClient(account_url=custom_account_url) @@ -416,106 +455,32 @@ def test_create_service_with_custom_account_endpoint_path(self, tables_cosmos_ac assert service._primary_hostname == 'local-machine:11002/custom/account/path' assert service.url.startswith('http://local-machine:11002/custom/account/path') - if self.is_live: - sleep(SLEEP_DELAY) - - @pytest.mark.skipif(sys.version_info < (3, 0), reason="Malformed string") - @CosmosPreparer() - def test_user_agent_default(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): - service = TableServiceClient(self.account_url(tables_cosmos_account_name, "cosmos"), credential=tables_primary_cosmos_account_key) - - def callback(response): - assert 'User-Agent' in response.http_request.headers - assert "azsdk-python-data-tables/{} Python/{} ({})".format( - VERSION, - platform.python_version(), - platform.platform()) in response.http_request.headers['User-Agent'] - - tables = list(service.list_tables(raw_response_hook=callback)) - assert isinstance(tables, list) - - if self.is_live: - sleep(SLEEP_DELAY) - - @pytest.mark.skip("Tests fail with non-standard clouds") - @CosmosPreparer() - def test_user_agent_custom(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): - custom_app = "TestApp/v1.0" - service = TableServiceClient( - self.account_url(tables_cosmos_account_name, "cosmos"), credential=tables_primary_cosmos_account_key, user_agent=custom_app) - - def callback(response): - assert 'User-Agent' in response.http_request.headers - assert "TestApp/v1.0 azsdk-python-data-tables/{} Python/{} ({})".format( - VERSION, - platform.python_version(), - platform.platform()) in response.http_request.headers['User-Agent'] - - tables = list(service.list_tables(raw_response_hook=callback)) - assert isinstance(tables, list) - - def callback(response): - assert 'User-Agent' in response.http_request.headers - assert "TestApp/v2.0 TestApp/v1.0 azsdk-python-data-tables/{} Python/{} ({})".format( - VERSION, - platform.python_version(), - platform.platform()) in response.http_request.headers['User-Agent'] - - tables = list(service.list_tables(raw_response_hook=callback, user_agent="TestApp/v2.0")) - assert isinstance(tables, list) - - if self.is_live: - sleep(SLEEP_DELAY) - - @CosmosPreparer() - def test_user_agent_append(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): - service = self.create_client_from_credential( - TableServiceClient, - account_url=self._account_url(tables_cosmos_account_name), - credential=tables_primary_cosmos_account_key) - - def callback(response): - assert 'User-Agent' in response.http_request.headers - assert response.http_request.headers['User-Agent'] == "azsdk-python-data-tables/{} Python/{} ({}) customer_user_agent".format( - VERSION, - platform.python_version(), - platform.platform()) - - custom_headers = {'User-Agent': 'customer_user_agent'} - tables = service.list_tables(raw_response_hook=callback, headers=custom_headers) - - if self.is_live: - sleep(SLEEP_DELAY) - - @CosmosPreparer() - def test_create_table_client_with_complete_table_url(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + def test_create_table_client_with_complete_table_url(self): # Arrange - table_url = self._account_url(tables_cosmos_account_name) + "/foo" - service = self.create_client_from_credential( - TableClient, + table_url = self._account_url(self.tables_cosmos_account_name) + "/foo" + service = TableClient( account_url=table_url, - credential=tables_primary_cosmos_account_key, + credential=self.tables_primary_cosmos_account_key, table_name="bar") # Assert assert service.scheme == 'https' assert service.table_name == 'bar' - assert service.account_name == tables_cosmos_account_name + assert service.account_name == self.tables_cosmos_account_name - @CosmosPreparer() - def test_create_table_client_with_complete_url(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + + def test_create_table_client_with_complete_url(self): # Arrange - table_url = "https://{}.table.cosmos.azure.com:443/foo".format(tables_cosmos_account_name) - service = self.create_client_from_credential( - TableClient, + table_url = "https://{}.table.cosmos.azure.com:443/foo".format(self.tables_cosmos_account_name) + service = TableClient( account_url=table_url, - credential=tables_primary_cosmos_account_key, + credential=self.tables_primary_cosmos_account_key, table_name="bar") # Assert assert service.scheme == 'https' assert service.table_name == 'bar' - assert service.account_name == tables_cosmos_account_name + assert service.account_name == self.tables_cosmos_account_name def test_create_table_client_with_invalid_name(self): # Arrange @@ -524,13 +489,10 @@ def test_create_table_client_with_invalid_name(self): # Assert with pytest.raises(ValueError) as excinfo: - service = TableClient(account_url=table_url, table_name=invalid_table_name, credential="tables_primary_cosmos_account_key") + service = TableClient(account_url=table_url, table_name=invalid_table_name, credential="self.tables_primary_cosmos_account_key") assert "Table names must be alphanumeric, cannot begin with a number, and must be between 3-63 characters long." in str(excinfo) - if self.is_live: - sleep(SLEEP_DELAY) - def test_error_with_malformed_conn_str(self): # Arrange @@ -545,18 +507,13 @@ def test_error_with_malformed_conn_str(self): elif conn_str in ("foobar=baz=foo" , "foo=;bar=;", "=", "=;=="): assert str(e.value) == "Connection string missing required connection details." - if self.is_live: - sleep(SLEEP_DELAY) - - @CosmosPreparer() - def test_closing_pipeline_client(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + def test_closing_pipeline_client(self): # Arrange for client, url in SERVICES.items(): # Act - service = self.create_client_from_credential( - client, - account_url=self._account_url(tables_cosmos_account_name), - credential=tables_primary_cosmos_account_key, + service = client( + account_url=self._account_url(self.tables_cosmos_account_name), + credential=self.tables_primary_cosmos_account_key, table_name='table') # Assert @@ -564,15 +521,14 @@ def test_closing_pipeline_client(self, tables_cosmos_account_name, tables_primar assert hasattr(service, 'close') service.close() - @CosmosPreparer() - def test_closing_pipeline_client_simple(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + + def test_closing_pipeline_client_simple(self): # Arrange for client, url in SERVICES.items(): # Act - service = self.create_client_from_credential( - client, - account_url=self._account_url(tables_cosmos_account_name), - credential=tables_primary_cosmos_account_key, + service = client( + account_url=self._account_url(self.tables_cosmos_account_name), + credential=self.tables_primary_cosmos_account_key, table_name='table') service.close() diff --git a/sdk/tables/azure-data-tables/tests/test_table_client_cosmos_async.py b/sdk/tables/azure-data-tables/tests/test_table_client_cosmos_async.py index efe6f5a91cab..4fe6326b433c 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_client_cosmos_async.py +++ b/sdk/tables/azure-data-tables/tests/test_table_client_cosmos_async.py @@ -7,13 +7,13 @@ import platform from time import sleep +from devtools_testutils import AzureTestCase + from azure.data.tables.aio import TableServiceClient, TableClient -from azure.data.tables._version import VERSION +from azure.data.tables import __version__ as VERSION -from _shared.testcase import ( - TableTestCase, - SLEEP_DELAY -) +from _shared.asynctestcase import AsyncTableTestCase +from _shared.testcase import SLEEP_DELAY from preparers import CosmosPreparer from devtools_testutils import AzureTestCase @@ -28,11 +28,66 @@ _CONNECTION_ENDPOINTS_SECONDARY = {'table': 'TableSecondaryEndpoint', 'cosmos': 'TableSecondaryEndpoint'} -class StorageTableClientTest(TableTestCase): - def setUp(self): - super(StorageTableClientTest, self).setUp() - self.sas_token = self.generate_sas_token() - self.token_credential = self.generate_oauth_token() +class TestTableClient(AzureTestCase, AsyncTableTestCase): + + @CosmosPreparer() + async def test_user_agent_default_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + service = TableServiceClient(self.account_url(tables_cosmos_account_name, "cosmos"), credential=tables_primary_cosmos_account_key) + + def callback(response): + assert 'User-Agent' in response.http_request.headers + assert response.http_request.headers['User-Agent'] == "azsdk-python-storage-table/{} Python/{} ({})".format( + VERSION, + platform.python_version(), + platform.platform()) + + tables = service.list_tables(raw_response_hook=callback) + assert tables is not None + + @CosmosPreparer() + async def test_user_agent_custom_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + custom_app = "TestApp/v1.0" + service = TableServiceClient( + self.account_url(tables_cosmos_account_name, "cosmos"), credential=tables_primary_cosmos_account_key, user_agent=custom_app) + + def callback(response): + assert 'User-Agent' in response.http_request.headers + assert "TestApp/v1.0 azsdk-python-storage-table/{} Python/{} ({})".format( + VERSION, + platform.python_version(), + platform.platform()) in response.http_request.headers['User-Agent'] + + tables = service.list_tables(raw_response_hook=callback) + assert tables is not None + + def callback(response): + assert 'User-Agent' in response.http_request.headers + assert "TestApp/v2.0 TestApp/v1.0 azsdk-python-storage-table/{} Python/{} ({})".format( + VERSION, + platform.python_version(), + platform.platform()) in response.http_request.headers['User-Agent'] + + tables = service.list_tables(raw_response_hook=callback, user_agent="TestApp/v2.0") + assert tables is not None + + @CosmosPreparer() + async def test_user_agent_append(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + service = TableServiceClient(self.account_url(tables_cosmos_account_name, "cosmos"), credential=tables_primary_cosmos_account_key) + + def callback(response): + assert 'User-Agent' in response.http_request.headers + assert response.http_request.headers['User-Agent'] == "azsdk-python-storage-tables/{} Python/{} ({}) customer_user_agent".format( + VERSION, + platform.python_version(), + platform.platform()) + + custom_headers = {'User-Agent': 'customer_user_agent'} + tables = service.list_tables(raw_response_hook=callback, headers=custom_headers) + + +class TestTableClientUnit(AsyncTableTestCase): + tables_cosmos_account_name = "fake_storage_account" + tables_primary_cosmos_account_key = "fakeXMZjnGsZGvd4bVr3Il5SeHA" # --Helpers----------------------------------------------------------------- def validate_standard_account_endpoints(self, service, account_name, account_key): @@ -43,116 +98,109 @@ def validate_standard_account_endpoints(self, service, account_name, account_key assert '{}.{}'.format(account_name, 'table.core.windows.net') in service.url or '{}.{}'.format(account_name, 'table.cosmos.azure.com') in service.url # --Direct Parameters Test Cases -------------------------------------------- - - @CosmosPreparer() - async def test_create_service_with_key_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + @pytest.mark.asyncio + async def test_create_service_with_key_async(self): # Arrange for client, url in SERVICES.items(): # Act service = client( - self.account_url(tables_cosmos_account_name, url), credential=tables_primary_cosmos_account_key, table_name='foo') + self.account_url(self.tables_cosmos_account_name, url), credential=self.tables_primary_cosmos_account_key, table_name='foo') # Assert - self.validate_standard_account_endpoints(service, tables_cosmos_account_name, tables_primary_cosmos_account_key) + self.validate_standard_account_endpoints(service, self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key) assert service.scheme == 'https' - if self.is_live: - sleep(SLEEP_DELAY) - - @CosmosPreparer() - async def test_create_service_with_connection_string_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + @pytest.mark.asyncio + async def test_create_service_with_connection_string_async(self): for service_type in SERVICES.items(): # Act service = service_type[0].from_connection_string( - self.connection_string(tables_cosmos_account_name, tables_primary_cosmos_account_key), table_name="test") + self.connection_string(self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key), table_name="test") # Assert - self.validate_standard_account_endpoints(service, tables_cosmos_account_name, tables_primary_cosmos_account_key) + self.validate_standard_account_endpoints(service, self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key) assert service.scheme == 'https' - - @CosmosPreparer() - async def test_create_service_with_sas_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + @pytest.mark.asyncio + async def test_create_service_with_sas_async(self): # Arrange - url = self.account_url(tables_cosmos_account_name, "cosmos") + url = self.account_url(self.tables_cosmos_account_name, "cosmos") suffix = '.table.cosmos.azure.com' + self.sas_token = self.generate_sas_token() for service_type in SERVICES: # Act service = service_type( - self.account_url(tables_cosmos_account_name, "cosmos"), credential=self.sas_token, table_name='foo') + self.account_url(self.tables_cosmos_account_name, "cosmos"), credential=self.sas_token, table_name='foo') # Assert assert service is not None - assert service.account_name == tables_cosmos_account_name - assert service.url.startswith('https://' +tables_cosmos_account_name + suffix) + assert service.account_name == self.tables_cosmos_account_name + assert service.url.startswith('https://' +self.tables_cosmos_account_name + suffix) assert service.url.endswith(self.sas_token) assert service.credential is None - - @CosmosPreparer() - async def test_create_service_with_token_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): - url = self.account_url(tables_cosmos_account_name, "cosmos") + @pytest.mark.asyncio + async def test_create_service_with_token_async(self): + url = self.account_url(self.tables_cosmos_account_name, "cosmos") suffix = '.table.cosmos.azure.com' + self.token_credential = self.generate_fake_token() for service_type in SERVICES: # Act service = service_type(url, credential=self.token_credential, table_name='foo') # Assert assert service is not None - assert service.account_name == tables_cosmos_account_name - assert service.url.startswith('https://' + tables_cosmos_account_name + suffix) + assert service.account_name == self.tables_cosmos_account_name + assert service.url.startswith('https://' + self.tables_cosmos_account_name + suffix) assert service.credential == self.token_credential assert not hasattr(service.credential, 'account_key') assert hasattr(service.credential, 'get_token') - - @CosmosPreparer() - async def test_create_service_with_token_and_http_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + @pytest.mark.asyncio + async def test_create_service_with_token_and_http_async(self): + self.token_credential = self.generate_fake_token() for service_type in SERVICES: # Act with pytest.raises(ValueError): - url = self.account_url(tables_cosmos_account_name, "cosmos").replace('https', 'http') + url = self.account_url(self.tables_cosmos_account_name, "cosmos").replace('https', 'http') service_type(url, credential=self.token_credential, table_name='foo') @pytest.mark.skip("Confirm cosmos national cloud URLs") - - @CosmosPreparer() - async def test_create_service_china_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + @pytest.mark.asyncio + async def test_create_service_china_async(self): # Arrange # TODO: Confirm regional cloud cosmos URLs for service_type in SERVICES.items(): # Act - url = self.account_url(tables_cosmos_account_name, "cosmos").replace('core.windows.net', 'core.chinacloudapi.cn') + url = self.account_url(self.tables_cosmos_account_name, "cosmos").replace('cosmos.azure.com', 'core.chinacloudapi.cn') service = service_type[0]( - url, credential=tables_primary_cosmos_account_key, table_name='foo') + url, credential=self.tables_primary_cosmos_account_key, table_name='foo') # Assert assert service is not None - assert service.account_name == tables_cosmos_account_name - assert service.credential.account_name == tables_cosmos_account_name - assert service.credential.account_key == tables_primary_cosmos_account_key - assert service._primary_endpoint.startswith('https://{}.{}.core.chinacloudapi.cn'.format(tables_cosmos_account_name, "cosmos")) + assert service.account_name == self.tables_cosmos_account_name + assert service.credential.account_name == self.tables_cosmos_account_name + assert service.credential.account_key == self.tables_primary_cosmos_account_key + assert service._primary_endpoint.startswith('https://{}.{}.core.chinacloudapi.cn'.format(self.tables_cosmos_account_name, "cosmos")) - - @CosmosPreparer() - async def test_create_service_protocol_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + @pytest.mark.asyncio + async def test_create_service_protocol_async(self): # Arrange for service_type in SERVICES.items(): # Act - url = self.account_url(tables_cosmos_account_name, "cosmos").replace('https', 'http') + url = self.account_url(self.tables_cosmos_account_name, "cosmos").replace('https', 'http') service = service_type[0]( - url, credential=tables_primary_cosmos_account_key, table_name='foo') + url, credential=self.tables_primary_cosmos_account_key, table_name='foo') # Assert - self.validate_standard_account_endpoints(service, tables_cosmos_account_name, tables_primary_cosmos_account_key) + self.validate_standard_account_endpoints(service, self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key) assert service.scheme == 'http' - - @CosmosPreparer() - async def test_create_service_empty_key_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + @pytest.mark.asyncio + async def test_create_service_empty_key_async(self): # Arrange TABLE_SERVICES = [TableServiceClient, TableClient] @@ -163,45 +211,43 @@ async def test_create_service_empty_key_async(self, tables_cosmos_account_name, assert str(e.value) == "You need to provide either a SAS token or an account shared key to authenticate." - - @CosmosPreparer() - async def test_create_service_with_socket_timeout_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + @pytest.mark.asyncio + async def test_create_service_with_socket_timeout_async(self): # Arrange for service_type in SERVICES.items(): # Act default_service = service_type[0]( - self.account_url(tables_cosmos_account_name, "cosmos"), credential=tables_primary_cosmos_account_key, table_name='foo') + self.account_url(self.tables_cosmos_account_name, "cosmos"), credential=self.tables_primary_cosmos_account_key, table_name='foo') service = service_type[0]( - self.account_url(tables_cosmos_account_name, "cosmos"), credential=tables_primary_cosmos_account_key, + self.account_url(self.tables_cosmos_account_name, "cosmos"), credential=self.tables_primary_cosmos_account_key, table_name='foo', connection_timeout=22) # Assert - self.validate_standard_account_endpoints(service, tables_cosmos_account_name, tables_primary_cosmos_account_key) + self.validate_standard_account_endpoints(service, self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key) assert service._client._client._pipeline._transport.connection_config.timeout == 22 assert default_service._client._client._pipeline._transport.connection_config.timeout in [20, (20, 2000)] # --Connection String Test Cases -------------------------------------------- - - @CosmosPreparer() - async def test_create_service_with_connection_string_key_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + @pytest.mark.asyncio + async def test_create_service_with_connection_string_key_async(self): # Arrange - conn_string = 'AccountName={};AccountKey={};'.format(tables_cosmos_account_name, tables_primary_cosmos_account_key) + conn_string = 'AccountName={};AccountKey={};'.format(self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key) for service_type in SERVICES.items(): # Act service = service_type[0].from_connection_string(conn_string, table_name='foo') # Assert - self.validate_standard_account_endpoints(service, tables_cosmos_account_name, tables_primary_cosmos_account_key) + self.validate_standard_account_endpoints(service, self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key) assert service.scheme == 'https' - @pytest.mark.skip("Error with sas formation") - - @CosmosPreparer() - async def test_create_service_with_connection_string_sas_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + # @pytest.mark.skip("Error with sas formation") + @pytest.mark.asyncio + async def test_create_service_with_connection_string_sas_async(self): + self.sas_token = self.generate_sas_token() # Arrange - conn_string = 'AccountName={};SharedAccessSignature={};'.format(tables_cosmos_account_name, self.sas_token) + conn_string = 'AccountName={};SharedAccessSignature={};'.format(self.tables_cosmos_account_name, self.sas_token) for service_type in SERVICES: # Act @@ -209,17 +255,16 @@ async def test_create_service_with_connection_string_sas_async(self, tables_cosm # Assert assert service is not None - assert service.account_name == tables_cosmos_account_name - assert service.url.startswith('https://' + tables_cosmos_account_name + '.table.core.windows.net') + assert service.account_name == self.tables_cosmos_account_name + assert service.url.startswith('https://' + self.tables_cosmos_account_name + '.table.core.windows.net') assert service.url.endswith(self.sas_token) assert service.credential is None - - @CosmosPreparer() - async def test_create_service_with_connection_string_cosmos_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + @pytest.mark.asyncio + async def test_create_service_with_connection_string_cosmos_async(self): # Arrange conn_string = 'DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1};TableEndpoint=https://{0}.table.cosmos.azure.com:443/;'.format( - tables_cosmos_account_name, tables_primary_cosmos_account_key) + self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key) for service_type in SERVICES: # Act @@ -227,19 +272,18 @@ async def test_create_service_with_connection_string_cosmos_async(self, tables_c # Assert assert service is not None - assert service.account_name == tables_cosmos_account_name - assert service.url.startswith('https://' + tables_cosmos_account_name + '.table.cosmos.azure.com') - assert service.credential.account_name == tables_cosmos_account_name - assert service.credential.account_key == tables_primary_cosmos_account_key - assert service._primary_endpoint.startswith('https://' + tables_cosmos_account_name + '.table.cosmos.azure.com') + assert service.account_name == self.tables_cosmos_account_name + assert service.url.startswith('https://' + self.tables_cosmos_account_name + '.table.cosmos.azure.com') + assert service.credential.account_name == self.tables_cosmos_account_name + assert service.credential.account_key == self.tables_primary_cosmos_account_key + assert service._primary_endpoint.startswith('https://' + self.tables_cosmos_account_name + '.table.cosmos.azure.com') assert service.scheme == 'https' - - @CosmosPreparer() - async def test_create_service_with_connection_string_endpoint_protocol_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + @pytest.mark.asyncio + async def test_create_service_with_connection_string_endpoint_protocol_async(self): # Arrange conn_string = 'AccountName={};AccountKey={};DefaultEndpointsProtocol=http;EndpointSuffix=core.chinacloudapi.cn;'.format( - tables_cosmos_account_name, tables_primary_cosmos_account_key) + self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key) for service_type in SERVICES.items(): # Act @@ -247,66 +291,62 @@ async def test_create_service_with_connection_string_endpoint_protocol_async(sel # Assert assert service is not None - assert service.account_name == tables_cosmos_account_name - assert service.credential.account_name == tables_cosmos_account_name - assert service.credential.account_key == tables_primary_cosmos_account_key - assert service._primary_endpoint.startswith('http://{}.{}.core.chinacloudapi.cn'.format(tables_cosmos_account_name, "table")) + assert service.account_name == self.tables_cosmos_account_name + assert service.credential.account_name == self.tables_cosmos_account_name + assert service.credential.account_key == self.tables_primary_cosmos_account_key + assert service._primary_endpoint.startswith('http://{}.{}.core.chinacloudapi.cn'.format(self.tables_cosmos_account_name, "table")) assert service.scheme == 'http' - - @CosmosPreparer() - async def test_create_service_with_connection_string_emulated_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + @pytest.mark.asyncio + async def test_create_service_with_connection_string_emulated_async(self): # Arrange for service_type in SERVICES.items(): - conn_string = 'UseDevelopmentStorage=true;'.format(tables_cosmos_account_name, tables_primary_cosmos_account_key) + conn_string = 'UseDevelopmentStorage=true;'.format(self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key) # Act with pytest.raises(ValueError): service = service_type[0].from_connection_string(conn_string, table_name="foo") - - @CosmosPreparer() - async def test_create_service_with_connection_string_custom_domain_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + @pytest.mark.asyncio + async def test_create_service_with_connection_string_custom_domain_async(self): # Arrange for service_type in SERVICES.items(): conn_string = 'AccountName={};AccountKey={};TableEndpoint=www.mydomain.com;'.format( - tables_cosmos_account_name, tables_primary_cosmos_account_key) + self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key) # Act service = service_type[0].from_connection_string(conn_string, table_name="foo") # Assert assert service is not None - assert service.account_name == tables_cosmos_account_name - assert service.credential.account_name == tables_cosmos_account_name - assert service.credential.account_key == tables_primary_cosmos_account_key + assert service.account_name == self.tables_cosmos_account_name + assert service.credential.account_name == self.tables_cosmos_account_name + assert service.credential.account_key == self.tables_primary_cosmos_account_key assert service._primary_endpoint.startswith('https://www.mydomain.com') - - @CosmosPreparer() - async def test_create_service_with_conn_str_custom_domain_trailing_slash_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + @pytest.mark.asyncio + async def test_create_service_with_conn_str_custom_domain_trailing_slash_async(self): # Arrange for service_type in SERVICES.items(): conn_string = 'AccountName={};AccountKey={};TableEndpoint=www.mydomain.com/;'.format( - tables_cosmos_account_name, tables_primary_cosmos_account_key) + self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key) # Act service = service_type[0].from_connection_string(conn_string, table_name="foo") # Assert assert service is not None - assert service.account_name == tables_cosmos_account_name - assert service.credential.account_name == tables_cosmos_account_name - assert service.credential.account_key == tables_primary_cosmos_account_key + assert service.account_name == self.tables_cosmos_account_name + assert service.credential.account_name == self.tables_cosmos_account_name + assert service.credential.account_key == self.tables_primary_cosmos_account_key assert service._primary_endpoint.startswith('https://www.mydomain.com') - - @CosmosPreparer() - async def test_create_service_with_conn_str_custom_domain_sec_override_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + @pytest.mark.asyncio + async def test_create_service_with_conn_str_custom_domain_sec_override_async(self): # Arrange for service_type in SERVICES.items(): conn_string = 'AccountName={};AccountKey={};TableEndpoint=www.mydomain.com/;'.format( - tables_cosmos_account_name, tables_primary_cosmos_account_key) + self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key) # Act service = service_type[0].from_connection_string( @@ -314,32 +354,30 @@ async def test_create_service_with_conn_str_custom_domain_sec_override_async(sel # Assert assert service is not None - assert service.account_name == tables_cosmos_account_name - assert service.credential.account_name == tables_cosmos_account_name - assert service.credential.account_key == tables_primary_cosmos_account_key + assert service.account_name == self.tables_cosmos_account_name + assert service.credential.account_name == self.tables_cosmos_account_name + assert service.credential.account_key == self.tables_primary_cosmos_account_key assert service._primary_endpoint.startswith('https://www.mydomain.com') - - @CosmosPreparer() - async def test_create_service_with_conn_str_fails_if_sec_without_primary_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + @pytest.mark.asyncio + async def test_create_service_with_conn_str_fails_if_sec_without_primary_async(self): for service_type in SERVICES.items(): # Arrange conn_string = 'AccountName={};AccountKey={};{}=www.mydomain.com;'.format( - tables_cosmos_account_name, tables_primary_cosmos_account_key, + self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key, _CONNECTION_ENDPOINTS_SECONDARY.get(service_type[1])) # Fails if primary excluded with pytest.raises(ValueError): service = service_type[0].from_connection_string(conn_string, table_name="foo") - - @CosmosPreparer() - async def test_create_service_with_conn_str_succeeds_if_sec_with_primary_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + @pytest.mark.asyncio + async def test_create_service_with_conn_str_succeeds_if_sec_with_primary_async(self): for service_type in SERVICES.items(): # Arrange conn_string = 'AccountName={};AccountKey={};{}=www.mydomain.com;{}=www-sec.mydomain.com;'.format( - tables_cosmos_account_name, - tables_primary_cosmos_account_key, + self.tables_cosmos_account_name, + self.tables_primary_cosmos_account_key, _CONNECTION_ENDPOINTS.get(service_type[1]), _CONNECTION_ENDPOINTS_SECONDARY.get(service_type[1])) @@ -348,26 +386,26 @@ async def test_create_service_with_conn_str_succeeds_if_sec_with_primary_async(s # Assert assert service is not None - assert service.account_name == tables_cosmos_account_name - assert service.credential.account_name == tables_cosmos_account_name - assert service.credential.account_key == tables_primary_cosmos_account_key + assert service.account_name == self.tables_cosmos_account_name + assert service.credential.account_name == self.tables_cosmos_account_name + assert service.credential.account_key == self.tables_primary_cosmos_account_key assert service._primary_endpoint.startswith('https://www.mydomain.com') - - @CosmosPreparer() - async def test_create_service_with_custom_account_endpoint_path_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + @pytest.mark.asyncio + async def test_create_service_with_custom_account_endpoint_path_async(self): + self.sas_token = self.generate_sas_token() custom_account_url = "http://local-machine:11002/custom/account/path/" + self.sas_token for service_type in SERVICES.items(): conn_string = 'DefaultEndpointsProtocol=http;AccountName={};AccountKey={};TableEndpoint={};'.format( - tables_cosmos_account_name, tables_primary_cosmos_account_key, custom_account_url) + self.tables_cosmos_account_name, self.tables_primary_cosmos_account_key, custom_account_url) # Act service = service_type[0].from_connection_string(conn_string, table_name="foo") # Assert - assert service.account_name == tables_cosmos_account_name - assert service.credential.account_name == tables_cosmos_account_name - assert service.credential.account_key == tables_primary_cosmos_account_key + assert service.account_name == self.tables_cosmos_account_name + assert service.credential.account_name == self.tables_cosmos_account_name + assert service.credential.account_key == self.tables_primary_cosmos_account_key assert service._primary_hostname == 'local-machine:11002/custom/account/path' service = TableServiceClient(account_url=custom_account_url) @@ -391,90 +429,30 @@ async def test_create_service_with_custom_account_endpoint_path_async(self, tabl assert service._primary_hostname == 'local-machine:11002/custom/account/path' assert service.url.startswith('http://local-machine:11002/custom/account/path') - - @CosmosPreparer() - async def test_user_agent_default_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): - service = TableServiceClient(self.account_url(tables_cosmos_account_name, "cosmos"), credential=tables_primary_cosmos_account_key) - - def callback(response): - assert 'User-Agent' in response.http_request.headers - assert response.http_request.headers['User-Agent'] == "azsdk-python-storage-table/{} Python/{} ({})".format( - VERSION, - platform.python_version(), - platform.platform()) - - tables = service.list_tables(raw_response_hook=callback) - assert tables is not None - - - @CosmosPreparer() - async def test_user_agent_custom_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): - custom_app = "TestApp/v1.0" - service = TableServiceClient( - self.account_url(tables_cosmos_account_name, "cosmos"), credential=tables_primary_cosmos_account_key, user_agent=custom_app) - - def callback(response): - assert 'User-Agent' in response.http_request.headers - assert "TestApp/v1.0 azsdk-python-storage-table/{} Python/{} ({})".format( - VERSION, - platform.python_version(), - platform.platform()) in response.http_request.headers['User-Agent'] - - tables = service.list_tables(raw_response_hook=callback) - assert tables is not None - - def callback(response): - assert 'User-Agent' in response.http_request.headers - assert "TestApp/v2.0 TestApp/v1.0 azsdk-python-storage-table/{} Python/{} ({})".format( - VERSION, - platform.python_version(), - platform.platform()) in response.http_request.headers['User-Agent'] - - tables = service.list_tables(raw_response_hook=callback, user_agent="TestApp/v2.0") - assert tables is not None - - - @CosmosPreparer() - async def test_user_agent_append(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): - # TODO: fix this one - service = TableServiceClient(self.account_url(tables_cosmos_account_name, "cosmos"), credential=tables_primary_cosmos_account_key) - - def callback(response): - assert 'User-Agent' in response.http_request.headers - assert response.http_request.headers['User-Agent'] == "azsdk-python-storage-tables/{} Python/{} ({}) customer_user_agent".format( - VERSION, - platform.python_version(), - platform.platform()) - - custom_headers = {'User-Agent': 'customer_user_agent'} - tables = service.list_tables(raw_response_hook=callback, headers=custom_headers) - - - @CosmosPreparer() - async def test_create_table_client_with_complete_table_url_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + @pytest.mark.asyncio + async def test_create_table_client_with_complete_table_url_async(self): # Arrange - table_url = self.account_url(tables_cosmos_account_name, "cosmos") + "/foo" - service = TableClient(table_url, table_name='bar', credential=tables_primary_cosmos_account_key) + table_url = self.account_url(self.tables_cosmos_account_name, "cosmos") + "/foo" + service = TableClient(table_url, table_name='bar', credential=self.tables_primary_cosmos_account_key) # Assert assert service.scheme == 'https' assert service.table_name == 'bar' - assert service.account_name == tables_cosmos_account_name - - @pytest.mark.skip("cosmos differential") + assert service.account_name == self.tables_cosmos_account_name - @CosmosPreparer() - async def test_create_table_client_with_complete_url_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + # @pytest.mark.skip("cosmos differential") + @pytest.mark.asyncio + async def test_create_table_client_with_complete_url_async(self): # Arrange - table_url = "https://{}.table.cosmos.azure.com:443/foo".format(tables_cosmos_account_name) - service = TableClient(table_url, table_name='bar', credential=tables_primary_cosmos_account_key) + table_url = "https://{}.table.cosmos.azure.com:443/foo".format(self.tables_cosmos_account_name) + service = TableClient(table_url, table_name='bar', credential=self.tables_primary_cosmos_account_key) # Assert assert service.scheme == 'https' assert service.table_name == 'bar' - assert service.account_name == tables_cosmos_account_name + assert service.account_name == self.tables_cosmos_account_name - @AzureTestCase.await_prepared_test + @pytest.mark.asyncio async def test_create_table_client_with_invalid_name_async(self): # Arrange table_url = "https://{}.table.cosmos.azure.com:443/foo".format("cosmos_account_name") @@ -482,11 +460,11 @@ async def test_create_table_client_with_invalid_name_async(self): # Assert with pytest.raises(ValueError) as excinfo: - service = TableClient(account_url=table_url, table_name=invalid_table_name, credential="tables_primary_cosmos_account_key") + service = TableClient(account_url=table_url, table_name=invalid_table_name, credential="self.tables_primary_cosmos_account_key") assert "Table names must be alphanumeric, cannot begin with a number, and must be between 3-63 characters long.""" in str(excinfo) - @AzureTestCase.await_prepared_test + @pytest.mark.asyncio async def test_error_with_malformed_conn_str_async(self): # Arrange @@ -501,26 +479,24 @@ async def test_error_with_malformed_conn_str_async(self): elif conn_str in ("foobar=baz=foo" , "foo=;bar=;", "=", "=;=="): assert str(e.value) == "Connection string missing required connection details." - - @CosmosPreparer() - async def test_closing_pipeline_client_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + @pytest.mark.asyncio + async def test_closing_pipeline_client_async(self): # Arrange for client, url in SERVICES.items(): # Act service = client( - self.account_url(tables_cosmos_account_name, "cosmos"), credential=tables_primary_cosmos_account_key, table_name='table') + self.account_url(self.tables_cosmos_account_name, "cosmos"), credential=self.tables_primary_cosmos_account_key, table_name='table') # Assert async with service: assert hasattr(service, 'close') await service.close() - - @CosmosPreparer() - async def test_closing_pipeline_client_simple_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): + @pytest.mark.asyncio + async def test_closing_pipeline_client_simple_async(self): # Arrange for client, url in SERVICES.items(): # Act service = client( - self.account_url(tables_cosmos_account_name, "cosmos"), credential=tables_primary_cosmos_account_key, table_name='table') + self.account_url(self.tables_cosmos_account_name, "cosmos"), credential=self.tables_primary_cosmos_account_key, table_name='table') await service.close() diff --git a/sdk/tables/azure-data-tables/tests/test_table_cosmos.py b/sdk/tables/azure-data-tables/tests/test_table_cosmos.py index 6867b6216b42..50f929847ca7 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_cosmos.py +++ b/sdk/tables/azure-data-tables/tests/test_table_cosmos.py @@ -15,6 +15,8 @@ timedelta, ) +from devtools_testutils import AzureTestCase + from azure.core.exceptions import ( HttpResponseError, ResourceNotFoundError, @@ -36,10 +38,9 @@ AccessPolicy, TableAnalyticsLogging, Metrics, - TableServiceClient + TableServiceClient, + generate_account_sas ) -from azure.data.tables._authentication import SharedKeyCredentialPolicy -from azure.data.tables._table_shared_access_signature import generate_account_sas from _shared.testcase import TableTestCase, SLEEP_DELAY from preparers import CosmosPreparer @@ -48,7 +49,7 @@ TEST_TABLE_PREFIX = 'pytablesync' # ------------------------------------------------------------------------------ -class StorageTableTest(TableTestCase): +class StorageTableTest(AzureTestCase, TableTestCase): # --Helpers----------------------------------------------------------------- def _get_table_reference(self, prefix=TEST_TABLE_PREFIX): @@ -173,35 +174,6 @@ def test_query_tables_per_page(self, tables_cosmos_account_name, tables_primary_ if self.is_live: sleep(SLEEP_DELAY) - @CosmosPreparer() - def test_create_table_invalid_name(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): - # Arrange - ts = TableServiceClient(self.account_url(tables_cosmos_account_name, "cosmos"), tables_primary_cosmos_account_key) - invalid_table_name = "my_table" - - with pytest.raises(ValueError) as excinfo: - ts.create_table(table_name=invalid_table_name) - - assert "Table names must be alphanumeric, cannot begin with a number, and must be between 3-63 characters long.""" in str( - excinfo) - - if self.is_live: - sleep(SLEEP_DELAY) - - @CosmosPreparer() - def test_delete_table_invalid_name(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): - # Arrange - ts = TableServiceClient(self.account_url(tables_cosmos_account_name, "cosmos"), tables_primary_cosmos_account_key) - invalid_table_name = "my_table" - - with pytest.raises(ValueError) as excinfo: - ts.create_table(invalid_table_name) - - assert "Table names must be alphanumeric, cannot begin with a number, and must be between 3-63 characters long.""" in str( - excinfo) - - if self.is_live: - sleep(SLEEP_DELAY) @CosmosPreparer() def test_query_tables(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): @@ -330,20 +302,7 @@ def test_delete_table_with_non_existing_table_fail_not_exist(self, tables_cosmos if self.is_live: sleep(SLEEP_DELAY) - @pytest.mark.skip("Cosmos does not support table access policy") - @CosmosPreparer() - def test_unicode_create_table_unicode_name(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): - # Arrange - url = self.account_url(tables_cosmos_account_name, "cosmos") - ts = TableServiceClient(url, tables_primary_cosmos_account_key) - table_name = u'啊齄丂狛狜' - - # Act - with pytest.raises(HttpResponseError): - ts.create_table(table_name) - if self.is_live: - sleep(SLEEP_DELAY) @pytest.mark.skip("Cosmos does not support table access policy") @CosmosPreparer() @@ -539,3 +498,40 @@ def test_locale(self, tables_cosmos_account_name, tables_primary_cosmos_account_ if self.is_live: sleep(SLEEP_DELAY) + + +class TestTableUnitTest(TableTestCase): + tables_cosmos_account_name = "fake_storage_account" + tables_primary_cosmos_account_key = "fakeXMZjnGsZGvd4bVr3Il5SeHA" + + def test_create_table_invalid_name(self): + # Arrange + ts = TableServiceClient(self.account_url(self.tables_cosmos_account_name, "cosmos"), self.tables_primary_cosmos_account_key) + invalid_table_name = "my_table" + + with pytest.raises(ValueError) as excinfo: + ts.create_table(table_name=invalid_table_name) + + assert "Table names must be alphanumeric, cannot begin with a number, and must be between 3-63 characters long.""" in str( + excinfo) + + def test_delete_table_invalid_name(self): + # Arrange + ts = TableServiceClient(self.account_url(self.tables_cosmos_account_name, "cosmos"), self.tables_primary_cosmos_account_key) + invalid_table_name = "my_table" + + with pytest.raises(ValueError) as excinfo: + ts.create_table(invalid_table_name) + + assert "Table names must be alphanumeric, cannot begin with a number, and must be between 3-63 characters long.""" in str( + excinfo) + + def test_unicode_create_table_unicode_name(self): + # Arrange + url = self.account_url(self.tables_cosmos_account_name, "cosmos") + ts = TableServiceClient(url, self.tables_primary_cosmos_account_key) + table_name = u'啊齄丂狛狜' + + # Act + with pytest.raises(ValueError): + ts.create_table(table_name) \ No newline at end of file diff --git a/sdk/tables/azure-data-tables/tests/test_table_cosmos_async.py b/sdk/tables/azure-data-tables/tests/test_table_cosmos_async.py index 65deccdc646e..e0168e2b2ea7 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_cosmos_async.py +++ b/sdk/tables/azure-data-tables/tests/test_table_cosmos_async.py @@ -6,26 +6,27 @@ import pytest -from azure.core.exceptions import ResourceNotFoundError, ResourceExistsError, HttpResponseError -from _shared.asynctestcase import AsyncTableTestCase -from _shared.testcase import SLEEP_DELAY +from devtools_testutils import AzureTestCase +from azure.core.exceptions import ResourceNotFoundError, ResourceExistsError, HttpResponseError from azure.data.tables import ( AccessPolicy, TableSasPermissions, ResourceTypes, - AccountSasPermissions + AccountSasPermissions, + generate_account_sas ) from azure.data.tables.aio import TableServiceClient -from azure.data.tables._table_shared_access_signature import generate_account_sas +from _shared.asynctestcase import AsyncTableTestCase +from _shared.testcase import SLEEP_DELAY from preparers import CosmosPreparer TEST_TABLE_PREFIX = 'pytableasync' # ------------------------------------------------------------------------------ -class TableTestAsync(AsyncTableTestCase): +class TableTestAsync(AzureTestCase, AsyncTableTestCase): # --Helpers----------------------------------------------------------------- def _get_table_reference(self, prefix=TEST_TABLE_PREFIX): table_name = self.get_resource_name(prefix) @@ -118,36 +119,6 @@ async def test_query_tables_per_page(self, tables_cosmos_account_name, tables_pr if self.is_live: sleep(SLEEP_DELAY) - @CosmosPreparer() - async def test_create_table_invalid_name(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): - # Arrange - ts = TableServiceClient(self.account_url(tables_cosmos_account_name, "cosmos"), tables_primary_cosmos_account_key) - invalid_table_name = "my_table" - - with pytest.raises(ValueError) as excinfo: - await ts.create_table(table_name=invalid_table_name) - - assert "Table names must be alphanumeric, cannot begin with a number, and must be between 3-63 characters long.""" in str( - excinfo) - - if self.is_live: - sleep(SLEEP_DELAY) - - @CosmosPreparer() - async def test_delete_table_invalid_name(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): - # Arrange - ts = TableServiceClient(self.account_url(tables_cosmos_account_name, "cosmos"), tables_primary_cosmos_account_key) - invalid_table_name = "my_table" - - with pytest.raises(ValueError) as excinfo: - await ts.create_table(invalid_table_name) - - assert "Table names must be alphanumeric, cannot begin with a number, and must be between 3-63 characters long.""" in str( - excinfo) - - if self.is_live: - sleep(SLEEP_DELAY) - @CosmosPreparer() async def test_list_tables(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): # Arrange @@ -278,23 +249,6 @@ async def test_delete_table_with_non_existing_table_fail_not_exist(self, tables_ if self.is_live: sleep(SLEEP_DELAY) - @CosmosPreparer() - async def test_unicode_create_table_unicode_name(self, tables_cosmos_account_name, - tables_primary_cosmos_account_key): - # Arrange - url = self.account_url(tables_cosmos_account_name, "cosmos") - ts = TableServiceClient(url, tables_primary_cosmos_account_key) - table_name = u'啊齄丂狛狜' - - with pytest.raises(ValueError) as excinfo: - await ts.create_table(table_name=table_name) - - assert "Table names must be alphanumeric, cannot begin with a number, and must be between 3-63 characters long.""" in str( - excinfo) - - if self.is_live: - sleep(SLEEP_DELAY) - @pytest.mark.skip("Cosmos does not support table access policy") @CosmosPreparer() async def test_get_table_acl(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): @@ -492,3 +446,45 @@ async def test_locale(self, tables_cosmos_account_name, tables_primary_cosmos_ac if self.is_live: sleep(SLEEP_DELAY) + + +class TestTableUnitTest(AsyncTableTestCase): + tables_cosmos_account_name = "fake_storage_account" + tables_primary_cosmos_account_key = "fakeXMZjnGsZGvd4bVr3Il5SeHA" + + @pytest.mark.asyncio + async def test_unicode_create_table_unicode_name(self): + # Arrange + url = self.account_url(self.tables_cosmos_account_name, "cosmos") + ts = TableServiceClient(url, self.tables_primary_cosmos_account_key) + table_name = u'啊齄丂狛狜' + + with pytest.raises(ValueError) as excinfo: + await ts.create_table(table_name=table_name) + + assert "Table names must be alphanumeric, cannot begin with a number, and must be between 3-63 characters long.""" in str( + excinfo) + + @pytest.mark.asyncio + async def test_create_table_invalid_name(self): + # Arrange + ts = TableServiceClient(self.account_url(self.tables_cosmos_account_name, "cosmos"), self.tables_primary_cosmos_account_key) + invalid_table_name = "my_table" + + with pytest.raises(ValueError) as excinfo: + await ts.create_table(table_name=invalid_table_name) + + assert "Table names must be alphanumeric, cannot begin with a number, and must be between 3-63 characters long.""" in str( + excinfo) + + @pytest.mark.asyncio + async def test_delete_table_invalid_name(self): + # Arrange + ts = TableServiceClient(self.account_url(self.tables_cosmos_account_name, "cosmos"), self.tables_primary_cosmos_account_key) + invalid_table_name = "my_table" + + with pytest.raises(ValueError) as excinfo: + await ts.create_table(invalid_table_name) + + assert "Table names must be alphanumeric, cannot begin with a number, and must be between 3-63 characters long.""" in str( + excinfo) diff --git a/sdk/tables/azure-data-tables/tests/test_table_entity.py b/sdk/tables/azure-data-tables/tests/test_table_entity.py index 76b737eff18a..605960de62fb 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_entity.py +++ b/sdk/tables/azure-data-tables/tests/test_table_entity.py @@ -14,6 +14,8 @@ from math import isnan import uuid +from devtools_testutils import AzureTestCase + from azure.data.tables import ( TableServiceClient, TableClient, @@ -39,7 +41,7 @@ # ------------------------------------------------------------------------------ -class StorageTableEntityTest(TableTestCase): +class StorageTableEntityTest(AzureTestCase, TableTestCase): def _set_up(self, tables_storage_account_name, tables_primary_storage_account_key, url='table'): self.table_name = self.get_resource_name('uttable') diff --git a/sdk/tables/azure-data-tables/tests/test_table_entity_async.py b/sdk/tables/azure-data-tables/tests/test_table_entity_async.py index 726c74c32cff..6bf4f0f21073 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_entity_async.py +++ b/sdk/tables/azure-data-tables/tests/test_table_entity_async.py @@ -13,24 +13,30 @@ from math import isnan import uuid +from devtools_testutils import AzureTestCase + from azure.core import MatchConditions from azure.core.exceptions import ( HttpResponseError, ResourceNotFoundError, - ResourceExistsError + ResourceExistsError, ) -from azure.data.tables import TableSasPermissions, AccessPolicy, UpdateMode, generate_table_sas -from azure.data.tables._entity import TableEntity, EntityProperty, EdmType +from azure.data.tables import ( + TableSasPermissions, + AccessPolicy, + UpdateMode, + generate_table_sas, + TableEntity, + EntityProperty, + EdmType +) from azure.data.tables.aio import TableServiceClient -from _shared.testcase import TableTestCase +from _shared.asynctestcase import AsyncTableTestCase from preparers import TablesPreparer -# ------------------------------------------------------------------------------ -# TODO: change to `with table_client as client:` to close sessions -# ------------------------------------------------------------------------------ -class StorageTableEntityTest(TableTestCase): +class StorageTableEntityTest(AzureTestCase, AsyncTableTestCase): async def _set_up(self, tables_storage_account_name, tables_primary_storage_account_key): account_url = self.account_url(tables_storage_account_name, "table") diff --git a/sdk/tables/azure-data-tables/tests/test_table_entity_cosmos.py b/sdk/tables/azure-data-tables/tests/test_table_entity_cosmos.py index dfc35086202c..18091aa04b14 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_entity_cosmos.py +++ b/sdk/tables/azure-data-tables/tests/test_table_entity_cosmos.py @@ -15,6 +15,8 @@ from time import sleep import uuid +from devtools_testutils import AzureTestCase + from azure.core import MatchConditions from azure.core.exceptions import ( HttpResponseError, @@ -38,7 +40,7 @@ # ------------------------------------------------------------------------------ -class StorageTableEntityTest(TableTestCase): +class StorageTableEntityTest(AzureTestCase, TableTestCase): def _set_up(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): self.ts = TableServiceClient(self.account_url(tables_cosmos_account_name, "cosmos"), tables_primary_cosmos_account_key) diff --git a/sdk/tables/azure-data-tables/tests/test_table_entity_cosmos_async.py b/sdk/tables/azure-data-tables/tests/test_table_entity_cosmos_async.py index e6f49b7fc79d..7b21757e92e3 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_entity_cosmos_async.py +++ b/sdk/tables/azure-data-tables/tests/test_table_entity_cosmos_async.py @@ -15,6 +15,8 @@ from time import sleep import uuid +from devtools_testutils import AzureTestCase + from azure.data.tables import ( generate_table_sas, TableEntity, @@ -33,13 +35,14 @@ ResourceExistsError, ) -from _shared.testcase import TableTestCase, SLEEP_DELAY +from _shared.asynctestcase import AsyncTableTestCase +from _shared.testcase import SLEEP_DELAY from preparers import CosmosPreparer # ------------------------------------------------------------------------------ # TODO: change to `with table_client as client:` to close sessions # ------------------------------------------------------------------------------ -class StorageTableEntityTest(TableTestCase): +class StorageTableEntityTest(AzureTestCase, AsyncTableTestCase): async def _set_up(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): account_url = self.account_url(tables_cosmos_account_name, "cosmos") diff --git a/sdk/tables/azure-data-tables/tests/test_table_service_properties.py b/sdk/tables/azure-data-tables/tests/test_table_service_properties.py index 595f1e307291..69cf89874978 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_service_properties.py +++ b/sdk/tables/azure-data-tables/tests/test_table_service_properties.py @@ -8,8 +8,15 @@ import time import pytest -from azure.data.tables import TableServiceClient -from azure.data.tables._models import TableAnalyticsLogging, Metrics, RetentionPolicy, CorsRule +from devtools_testutils import AzureTestCase + +from azure.data.tables import ( + TableServiceClient, + TableAnalyticsLogging, + Metrics, + RetentionPolicy, + CorsRule +) from azure.core.exceptions import HttpResponseError from _shared.testcase import TableTestCase @@ -18,7 +25,7 @@ # ------------------------------------------------------------------------------ -class TableServicePropertiesTest(TableTestCase): +class TableServicePropertiesTest(AzureTestCase, TableTestCase): # --Helpers----------------------------------------------------------------- def _assert_properties_default(self, prop): assert prop is not None @@ -193,13 +200,6 @@ def test_set_cors(self, tables_storage_account_name, tables_primary_storage_acco self._assert_cors_equal(received_props['cors'], cors) # --Test cases for errors --------------------------------------- - @TablesPreparer() - def test_retention_no_days(self, tables_storage_account_name, tables_primary_storage_account_key): - # Assert - pytest.raises(ValueError, - RetentionPolicy, - True, None) - @TablesPreparer() def test_too_many_cors_rules(self, tables_storage_account_name, tables_primary_storage_account_key): # Arrange @@ -223,3 +223,11 @@ def test_retention_too_long(self, tables_storage_account_name, tables_primary_st pytest.raises(HttpResponseError, tsc.set_service_properties, None, None, minute_metrics) + + +class TestTableUnitTest(TableTestCase): + def test_retention_no_days(self): + # Assert + pytest.raises(ValueError, + RetentionPolicy, + True, None) diff --git a/sdk/tables/azure-data-tables/tests/test_table_service_properties_async.py b/sdk/tables/azure-data-tables/tests/test_table_service_properties_async.py index ec6d8ae927c3..6faf66eb1999 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_service_properties_async.py +++ b/sdk/tables/azure-data-tables/tests/test_table_service_properties_async.py @@ -8,9 +8,11 @@ import time import pytest +from devtools_testutils import AzureTestCase + from azure.core.exceptions import HttpResponseError -from azure.data.tables._models import TableAnalyticsLogging, Metrics, RetentionPolicy, CorsRule +from azure.data.tables import TableAnalyticsLogging, Metrics, RetentionPolicy, CorsRule from azure.data.tables.aio import TableServiceClient from _shared.testcase import TableTestCase @@ -19,7 +21,7 @@ # ------------------------------------------------------------------------------ -class TableServicePropertiesTest(TableTestCase): +class TableServicePropertiesTest(AzureTestCase, TableTestCase): # --Helpers----------------------------------------------------------------- def _assert_properties_default(self, prop): assert prop is not None @@ -194,13 +196,6 @@ async def test_set_cors_async(self, tables_storage_account_name, tables_primary_ self._assert_cors_equal(received_props['cors'], cors) # --Test cases for errors --------------------------------------- - @TablesPreparer() - async def test_retention_no_days_async(self, tables_storage_account_name, tables_primary_storage_account_key): - # Assert - pytest.raises(ValueError, - RetentionPolicy, - True, None) - @TablesPreparer() async def test_too_many_cors_rules_async(self, tables_storage_account_name, tables_primary_storage_account_key): # Arrange @@ -223,3 +218,13 @@ async def test_retention_too_long_async(self, tables_storage_account_name, table # Assert with pytest.raises(HttpResponseError): await tsc.set_service_properties(None, None, minute_metrics) + + +class TestTableUnitTest(TableTestCase): + + @pytest.mark.asyncio + async def test_retention_no_days_async(self): + # Assert + pytest.raises(ValueError, + RetentionPolicy, + True, None) \ No newline at end of file diff --git a/sdk/tables/azure-data-tables/tests/test_table_service_properties_cosmos.py b/sdk/tables/azure-data-tables/tests/test_table_service_properties_cosmos.py index e807a813f894..139f3c1973a4 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_service_properties_cosmos.py +++ b/sdk/tables/azure-data-tables/tests/test_table_service_properties_cosmos.py @@ -8,16 +8,23 @@ import time import pytest +from devtools_testutils import AzureTestCase + from azure.core.exceptions import HttpResponseError -from azure.data.tables import TableServiceClient -from azure.data.tables._models import TableAnalyticsLogging, Metrics, RetentionPolicy, CorsRule +from azure.data.tables import ( + TableServiceClient, + TableAnalyticsLogging, + Metrics, + RetentionPolicy, + CorsRule +) from _shared.testcase import TableTestCase from preparers import CosmosPreparer # ------------------------------------------------------------------------------ -class TableServicePropertiesTest(TableTestCase): +class TableServicePropertiesTest(AzureTestCase, TableTestCase): # --Helpers----------------------------------------------------------------- def _assert_properties_default(self, prop): assert prop is not None @@ -95,10 +102,10 @@ def _assert_retention_equal(self, ret1, ret2): # --Test cases per service --------------------------------------- @pytest.mark.skip("Cosmos Tables does not yet support service properties") @CosmosPreparer() - def test_table_service_properties(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_table_service_properties(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): # Arrange - url = self.account_url(tables_storage_account_name, "cosmos") - tsc = TableServiceClient(url, tables_primary_storage_account_key) + url = self.account_url(tables_cosmos_account_name, "cosmos") + tsc = TableServiceClient(url, tables_primary_cosmos_account_key) # Act resp = tsc.set_service_properties( analytics_logging=TableAnalyticsLogging(), @@ -115,10 +122,10 @@ def test_table_service_properties(self, tables_storage_account_name, tables_prim # --Test cases per feature --------------------------------------- @pytest.mark.skip("Cosmos Tables does not yet support service properties") @CosmosPreparer() - def test_set_logging(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_set_logging(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): # Arrange - url = self.account_url(tables_storage_account_name, "cosmos") - tsc = TableServiceClient(url, tables_primary_storage_account_key) + url = self.account_url(tables_cosmos_account_name, "cosmos") + tsc = TableServiceClient(url, tables_primary_cosmos_account_key) logging = TableAnalyticsLogging(read=True, write=True, delete=True, retention_policy=RetentionPolicy(enabled=True, days=5)) # Act @@ -132,10 +139,10 @@ def test_set_logging(self, tables_storage_account_name, tables_primary_storage_a @pytest.mark.skip("Cosmos Tables does not yet support service properties") @CosmosPreparer() - def test_set_hour_metrics(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_set_hour_metrics(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): # Arrange - url = self.account_url(tables_storage_account_name, "cosmos") - tsc = TableServiceClient(url, tables_primary_storage_account_key) + url = self.account_url(tables_cosmos_account_name, "cosmos") + tsc = TableServiceClient(url, tables_primary_cosmos_account_key) hour_metrics = Metrics(enabled=True, include_apis=True, retention_policy=RetentionPolicy(enabled=True, days=5)) # Act @@ -149,10 +156,10 @@ def test_set_hour_metrics(self, tables_storage_account_name, tables_primary_stor @pytest.mark.skip("Cosmos Tables does not yet support service properties") @CosmosPreparer() - def test_set_minute_metrics(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_set_minute_metrics(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): # Arrange - url = self.account_url(tables_storage_account_name, "cosmos") - tsc = TableServiceClient(url, tables_primary_storage_account_key) + url = self.account_url(tables_cosmos_account_name, "cosmos") + tsc = TableServiceClient(url, tables_primary_cosmos_account_key) minute_metrics = Metrics(enabled=True, include_apis=True, retention_policy=RetentionPolicy(enabled=True, days=5)) @@ -167,10 +174,10 @@ def test_set_minute_metrics(self, tables_storage_account_name, tables_primary_st @pytest.mark.skip("Cosmos Tables does not yet support service properties") @CosmosPreparer() - def test_set_cors(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_set_cors(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): # Arrange - url = self.account_url(tables_storage_account_name, "cosmos") - tsc = TableServiceClient(url, tables_primary_storage_account_key) + url = self.account_url(tables_cosmos_account_name, "cosmos") + tsc = TableServiceClient(url, tables_primary_cosmos_account_key) cors_rule1 = CorsRule(['www.xyz.com'], ['GET']) allowed_origins = ['www.xyz.com', "www.ab.com", "www.bc.com"] @@ -199,19 +206,9 @@ def test_set_cors(self, tables_storage_account_name, tables_primary_storage_acco # --Test cases for errors --------------------------------------- @pytest.mark.skip("Cosmos Tables does not yet support service properties") @CosmosPreparer() - def test_retention_no_days(self, tables_storage_account_name, tables_primary_storage_account_key): - # Assert - pytest.raises(ValueError, - RetentionPolicy, - True, None) - if self.is_live: - sleep(SLEEP_DELAY) - - @pytest.mark.skip("Cosmos Tables does not yet support service properties") - @CosmosPreparer() - def test_too_many_cors_rules(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_too_many_cors_rules(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): # Arrange - tsc = TableServiceClient(self.account_url(tables_storage_account_name, "cosmos"), tables_primary_storage_account_key) + tsc = TableServiceClient(self.account_url(tables_cosmos_account_name, "cosmos"), tables_primary_cosmos_account_key) cors = [] for i in range(0, 6): cors.append(CorsRule(['www.xyz.com'], ['GET'])) @@ -224,9 +221,9 @@ def test_too_many_cors_rules(self, tables_storage_account_name, tables_primary_s @pytest.mark.skip("Cosmos Tables does not yet support service properties") @CosmosPreparer() - def test_retention_too_long(self, tables_storage_account_name, tables_primary_storage_account_key): + def test_retention_too_long(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): # Arrange - tsc = TableServiceClient(self.account_url(tables_storage_account_name, "cosmos"), tables_primary_storage_account_key) + tsc = TableServiceClient(self.account_url(tables_cosmos_account_name, "cosmos"), tables_primary_cosmos_account_key) minute_metrics = Metrics(enabled=True, include_apis=True, retention_policy=RetentionPolicy(enabled=True, days=366)) @@ -236,3 +233,10 @@ def test_retention_too_long(self, tables_storage_account_name, tables_primary_st None, None, minute_metrics) if self.is_live: sleep(SLEEP_DELAY) + + +class TestTableUnitTest(TableTestCase): + + def test_retention_no_days(self): + # Assert + pytest.raises(ValueError, RetentionPolicy, True, None) diff --git a/sdk/tables/azure-data-tables/tests/test_table_service_properties_cosmos_async.py b/sdk/tables/azure-data-tables/tests/test_table_service_properties_cosmos_async.py index 0c66f575ad39..f5efb87e4522 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_service_properties_cosmos_async.py +++ b/sdk/tables/azure-data-tables/tests/test_table_service_properties_cosmos_async.py @@ -8,15 +8,18 @@ import pytest from time import sleep -from azure.data.tables._models import TableAnalyticsLogging, Metrics, RetentionPolicy, CorsRule +from devtools_testutils import AzureTestCase + +from azure.data.tables import TableAnalyticsLogging, Metrics, RetentionPolicy, CorsRule from azure.data.tables.aio import TableServiceClient from azure.core.exceptions import HttpResponseError -from _shared.testcase import TableTestCase, SLEEP_DELAY +from _shared.testcase import SLEEP_DELAY +from _shared.asynctestcase import AsyncTableTestCase from preparers import CosmosPreparer # ------------------------------------------------------------------------------ -class TableServicePropertiesTest(TableTestCase): +class TableServicePropertiesTest(AzureTestCase, AsyncTableTestCase): # --Helpers----------------------------------------------------------------- def _assert_properties_default(self, prop): assert prop is not None @@ -196,15 +199,6 @@ async def test_set_cors_async(self, tables_cosmos_account_name, tables_primary_c sleep(SLEEP_DELAY) # --Test cases for errors --------------------------------------- - @CosmosPreparer() - async def test_retention_no_days_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): - # Assert - pytest.raises(ValueError, - RetentionPolicy, - True, None) - if self.is_live: - sleep(SLEEP_DELAY) - @CosmosPreparer() async def test_too_many_cors_rules_async(self, tables_cosmos_account_name, tables_primary_cosmos_account_key): # Arrange @@ -231,3 +225,11 @@ async def test_retention_too_long_async(self, tables_cosmos_account_name, tables await tsc.set_service_properties(None, None, minute_metrics) if self.is_live: sleep(SLEEP_DELAY) + + +class TestTableUnitTest(AsyncTableTestCase): + + @pytest.mark.asyncio + async def test_retention_no_days_async(self): + # Assert + pytest.raises(ValueError, RetentionPolicy, True, None) diff --git a/sdk/tables/azure-data-tables/tests/test_table_service_stats.py b/sdk/tables/azure-data-tables/tests/test_table_service_stats.py index 5fc48d82c3ee..765d9ad6ff10 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_service_stats.py +++ b/sdk/tables/azure-data-tables/tests/test_table_service_stats.py @@ -5,6 +5,8 @@ # -------------------------------------------------------------------------- import pytest +from devtools_testutils import AzureTestCase + from azure.data.tables import TableServiceClient from _shared.testcase import TableTestCase from preparers import TablesPreparer @@ -18,7 +20,7 @@ '> ' # --Test Class ----------------------------------------------------------------- -class TableServiceStatsTest(TableTestCase): +class TableServiceStatsTest(AzureTestCase, TableTestCase): # --Helpers----------------------------------------------------------------- def _assert_stats_default(self, stats): assert stats is not None diff --git a/sdk/tables/azure-data-tables/tests/test_table_service_stats_async.py b/sdk/tables/azure-data-tables/tests/test_table_service_stats_async.py index d0f0e74d6fe8..cc2dfd9bdcb5 100644 --- a/sdk/tables/azure-data-tables/tests/test_table_service_stats_async.py +++ b/sdk/tables/azure-data-tables/tests/test_table_service_stats_async.py @@ -5,9 +5,11 @@ # -------------------------------------------------------------------------- import pytest +from devtools_testutils import AzureTestCase + from azure.data.tables.aio import TableServiceClient -from _shared.testcase import TableTestCase +from _shared.asynctestcase import AsyncTableTestCase from preparers import TablesPreparer SERVICE_UNAVAILABLE_RESP_BODY = ' ' # --Test Class ----------------------------------------------------------------- -class TableServiceStatsTest(TableTestCase): +class TableServiceStatsTest(AzureTestCase, AsyncTableTestCase): # --Helpers----------------------------------------------------------------- def _assert_stats_default(self, stats): assert stats is not None diff --git a/tools/azure-sdk-tools/devtools_testutils/azure_testcase.py b/tools/azure-sdk-tools/devtools_testutils/azure_testcase.py index 03fbb51132d3..4b3c7b5f77b8 100644 --- a/tools/azure-sdk-tools/devtools_testutils/azure_testcase.py +++ b/tools/azure-sdk-tools/devtools_testutils/azure_testcase.py @@ -8,6 +8,7 @@ import logging import os.path import sys +import time import zlib try: @@ -343,3 +344,7 @@ def run(test_class_instance, *args, **kwargs): return loop.run_until_complete(test_fn(test_class_instance, **kwargs)) return run + + def sleep(self, seconds): + if self.is_live: + time.sleep(seconds) \ No newline at end of file