def test_azure_named_key_credential():
    cred = AzureNamedKeyCredential("sample_name", "samplekey")

    assert cred.named_key.name == "sample_name"
    assert cred.named_key.key == "samplekey"
    assert isinstance(cred.named_key, tuple)

    cred.update("newname", "newkey")
    assert cred.named_key.name == "newname"
    assert cred.named_key.key == "newkey"
    assert isinstance(cred.named_key, tuple)
Example #2
0
    async def test_new_invalid_key(self, tables_storage_account_name, tables_primary_storage_account_key):
        invalid_key = tables_primary_storage_account_key.named_key.key[0:-6] + "==" # cut off a bit from the end to invalidate
        tables_primary_storage_account_key = AzureNamedKeyCredential(tables_storage_account_name, invalid_key)
        credential = AzureNamedKeyCredential(name=tables_storage_account_name, key=tables_primary_storage_account_key.named_key.key)
        self.ts = TableServiceClient(self.account_url(tables_storage_account_name, "table"), credential=credential)
        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 = [('create', entity)]
        with pytest.raises(ClientAuthenticationError):
            resp = await self.table.submit_transaction(batch)
    async def wrapper(*args, **kwargs):
        key = kwargs.pop("tables_primary_storage_account_key")
        name = kwargs.pop("tables_storage_account_name")
        key = AzureNamedKeyCredential(key=key, name=name)

        kwargs["tables_primary_storage_account_key"] = key
        kwargs["tables_storage_account_name"] = name

        trimmed_kwargs = {k: v for k, v in kwargs.items()}
        trim_kwargs_from_test_function(func, trimmed_kwargs)

        EXPONENTIAL_BACKOFF = 1.5
        RETRY_COUNT = 0

        try:
            return await func(*args, **trimmed_kwargs)
        except HttpResponseError as exc:
            if exc.status_code != 429:
                raise
            print("Retrying: {} {}".format(RETRY_COUNT, EXPONENTIAL_BACKOFF))
            while RETRY_COUNT < 6:
                if is_live():
                    time.sleep(EXPONENTIAL_BACKOFF)
                try:
                    return await func(*args, **trimmed_kwargs)
                except HttpResponseError as exc:
                    print("Retrying: {} {}".format(RETRY_COUNT, EXPONENTIAL_BACKOFF))
                    EXPONENTIAL_BACKOFF **= 2
                    RETRY_COUNT += 1
                    if exc.status_code != 429 or RETRY_COUNT >= 6:
                        raise
Example #4
0
    async def delete_entity(self):
        from azure.data.tables.aio import TableClient
        from azure.core.exceptions import ResourceNotFoundError, ResourceExistsError
        from azure.core.credentials import AzureNamedKeyCredential

        credential = AzureNamedKeyCredential(self.account_name,
                                             self.access_key)
        table_client = TableClient(account_url=self.account_url,
                                   credential=credential,
                                   table_name=self.table_name)

        # [START delete_entity]
        async with table_client:
            try:
                resp = await table_client.create_entity(entity=self.entity)
            except ResourceExistsError:
                print("Entity already exists!")

            try:
                await table_client.delete_entity(
                    row_key=self.entity["RowKey"],
                    partition_key=self.entity["PartitionKey"])
                print("Successfully deleted!")
            except ResourceNotFoundError:
                print("Entity does not exists")
    def delete_entity(self):
        from azure.data.tables import TableClient
        from azure.core.exceptions import ResourceNotFoundError, ResourceExistsError
        from azure.core.credentials import AzureNamedKeyCredential

        credential = AzureNamedKeyCredential(self.account_name,
                                             self.access_key)
        with TableClient(account_url=self.account_url,
                         credential=credential,
                         table_name=self.table_name) as table_client:

            # Create entity to delete (to showcase etag)
            try:
                resp = table_client.create_entity(entity=self.entity)
            except ResourceExistsError:
                print("Entity already exists!")

            # [START delete_entity]
            try:
                table_client.delete_entity(
                    row_key=self.entity["RowKey"],
                    partition_key=self.entity["PartitionKey"])
                print("Successfully deleted!")
            except ResourceNotFoundError:
                print("Entity does not exists")
Example #6
0
class TestTablesUnitTest(AsyncTableTestCase):
    tables_storage_account_name = "fake_storage_account"
    tables_primary_storage_account_key = "fakeXMZjnGsZGvd4bVr3Il5SeHA"
    credential = AzureNamedKeyCredential(
        name=tables_storage_account_name,
        key=tables_primary_storage_account_key)

    @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.credential)

        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.credential)
        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.credential)
        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)

    def test_azurite_url(self):
        account_url = "https://127.0.0.1:10002/my_account"
        tsc = TableServiceClient(account_url, credential=self.credential)

        assert tsc.account_name == "my_account"
        assert tsc.url == "https://127.0.0.1:10002/my_account"
        assert tsc._location_mode == "primary"
        assert tsc.credential.named_key.key == self.credential.named_key.key
        assert tsc.credential.named_key.name == self.credential.named_key.name
    def authentication_by_shared_access_signature(self):
        # Instantiate a TableServiceClient using a connection string

        # [START auth_from_sas]
        from azure.data.tables import TableServiceClient
        from azure.core.credentials import AzureNamedKeyCredential, AzureSasCredential

        # Create a SAS token to use for authentication of a client
        from azure.data.tables import generate_account_sas, ResourceTypes, AccountSasPermissions

        print("Account name: {}".format(self.account_name))
        credential = AzureNamedKeyCredential(self.account_name,
                                             self.access_key)
        sas_token = generate_account_sas(
            credential,
            resource_types=ResourceTypes(service=True),
            permission=AccountSasPermissions(read=True),
            expiry=datetime.utcnow() + timedelta(hours=1),
        )

        with TableServiceClient(endpoint=self.endpoint,
                                credential=AzureSasCredential(
                                    sas_token)) as token_auth_table_service:
            properties = token_auth_table_service.get_service_properties()
            print("Shared Access Signature: {}".format(properties))
Example #8
0
def cf_table_service(cli_ctx, kwargs):
    from azure.data.tables._table_service_client import TableServiceClient
    client_kwargs = prepare_client_kwargs_track2(cli_ctx)
    client_kwargs = _config_location_mode(kwargs, client_kwargs)
    connection_string = kwargs.pop('connection_string', None)
    account_name = kwargs.pop('account_name', None)
    account_url = kwargs.pop('account_url', None)
    account_key = kwargs.pop('account_key', None)
    token_credential = kwargs.pop('token_credential', None)
    sas_token = kwargs.pop('sas_token', None)

    if connection_string:
        return TableServiceClient.from_connection_string(
            conn_str=connection_string, **client_kwargs)
    if not account_url:
        account_url = get_account_url(cli_ctx,
                                      account_name=account_name,
                                      service='table')
    if account_key:
        from azure.core.credentials import AzureNamedKeyCredential
        credential = AzureNamedKeyCredential(name=account_name,
                                             key=account_key)
    elif sas_token:
        from azure.core.credentials import AzureSasCredential
        credential = AzureSasCredential(signature=sas_token)
    else:
        credential = token_credential

    return TableServiceClient(endpoint=account_url,
                              credential=credential,
                              **client_kwargs)
    def generate_sas_token(self):
        fake_key = 'a' * 30 + 'b' * 30

        return '?' + generate_account_sas(
            credential=AzureNamedKeyCredential(name="fakename", key=fake_key),
            resource_types=ResourceTypes(object=True),
            permission=AccountSasPermissions(read=True, list=True),
            start=datetime.now() - timedelta(hours=24),
            expiry=datetime.now() + timedelta(days=8))
Example #10
0
    def create_table_service_client(self):
        # Instantiate a TableServiceClient using a shared access key
        # [START create_table_service_client]
        from azure.data.tables import TableServiceClient
        from azure.core.credentials import AzureNamedKeyCredential

        credential = AzureNamedKeyCredential(self.account_name, self.access_key)
        with TableServiceClient(endpoint=self.endpoint, credential=credential) as table_service:
            properties = table_service.get_service_properties()
            print("Properties: {}".format(properties))
Example #11
0
 def authentication_by_shared_key(self):
     # Instantiate a TableServiceClient using a shared access key
     # [START auth_from_shared_key]
     from azure.data.tables import TableServiceClient
     from azure.core.credentials import AzureNamedKeyCredential
     credential = AzureNamedKeyCredential(self.account_name,
                                          self.access_key)
     with TableServiceClient(account_url=self.account_url,
                             credential=credential) as table_service:
         properties = table_service.get_service_properties()
         print("Shared Key: {}".format(properties))
Example #12
0
    def test_create_client_for_cosmos_emulator(self):
        emulator_credential = AzureNamedKeyCredential(
            'localhost', self.tables_primary_cosmos_account_key)
        emulator_connstr = "DefaultEndpointsProtocol=http;AccountName=localhost;AccountKey={};TableEndpoint=http://localhost:8902/;".format(
            self.tables_primary_cosmos_account_key)

        client = TableServiceClient.from_connection_string(emulator_connstr)
        assert client.url == "http://localhost:8902"
        assert client.account_name == 'localhost'
        assert client.credential.named_key.name == 'localhost'
        assert client.credential.named_key.key == self.tables_primary_cosmos_account_key
        assert client._cosmos_endpoint
        assert client.scheme == 'http'

        client = TableServiceClient("http://localhost:8902/",
                                    credential=emulator_credential)
        assert client.url == "http://localhost:8902"
        assert client.account_name == 'localhost'
        assert client.credential.named_key.name == 'localhost'
        assert client.credential.named_key.key == self.tables_primary_cosmos_account_key
        assert client._cosmos_endpoint
        assert client.scheme == 'http'

        table = TableClient.from_connection_string(emulator_connstr,
                                                   'tablename')
        assert table.url == "http://localhost:8902"
        assert table.account_name == 'localhost'
        assert table.table_name == 'tablename'
        assert table.credential.named_key.name == 'localhost'
        assert table.credential.named_key.key == self.tables_primary_cosmos_account_key
        assert table._cosmos_endpoint
        assert table.scheme == 'http'

        table = TableClient("http://localhost:8902/",
                            "tablename",
                            credential=emulator_credential)
        assert table.url == "http://localhost:8902"
        assert table.account_name == 'localhost'
        assert table.table_name == 'tablename'
        assert table.credential.named_key.name == 'localhost'
        assert table.credential.named_key.key == self.tables_primary_cosmos_account_key
        assert table._cosmos_endpoint
        assert table.scheme == 'http'

        table = TableClient.from_table_url(
            "http://localhost:8902/Tables('tablename')",
            credential=emulator_credential)
        assert table.url == "http://localhost:8902"
        assert table.account_name == 'localhost'
        assert table.table_name == 'tablename'
        assert table.credential.named_key.name == 'localhost'
        assert table.credential.named_key.key == self.tables_primary_cosmos_account_key
        assert table._cosmos_endpoint
        assert table.scheme == 'http'
    async def wrapper(*args, **kwargs):
        key = kwargs.pop("tables_primary_cosmos_account_key")
        name = kwargs.pop("tables_cosmos_account_name")
        key = AzureNamedKeyCredential(key=key, name=name)

        kwargs["tables_primary_cosmos_account_key"] = key
        kwargs["tables_cosmos_account_name"] = name

        trimmed_kwargs = {k: v for k, v in kwargs.items()}
        trim_kwargs_from_test_function(func, trimmed_kwargs)

        return await func(*args, **trimmed_kwargs)
Example #14
0
    async def test_client_named_key_credential_async(self,
                                   servicebus_queue,
                                   servicebus_namespace,
                                   servicebus_namespace_key_name,
                                   servicebus_namespace_primary_key,
                                   servicebus_namespace_connection_string,
                                   **kwargs):
        hostname = "{}.servicebus.windows.net".format(servicebus_namespace.name)
        credential = AzureNamedKeyCredential(servicebus_namespace_key_name, servicebus_namespace_primary_key)

        client = ServiceBusClient(hostname, credential)
        async with client:
            async with client.get_queue_sender(servicebus_queue.name) as sender:
                await sender.send_messages(ServiceBusMessage("foo"))
        
        credential.update("foo", "bar")
        with pytest.raises(Exception):
            async with client:
                async with client.get_queue_sender(servicebus_queue.name) as sender:
                    await sender.send_messages(ServiceBusMessage("foo"))

        # update back to the right key again
        credential.update(servicebus_namespace_key_name, servicebus_namespace_primary_key)
        async with client:
            async with client.get_queue_sender(servicebus_queue.name) as sender:
                await sender.send_messages(ServiceBusMessage("foo"))
def test_azure_named_key_credential_raises():
    with pytest.raises(TypeError, match="Both name and key must be strings."):
        cred = AzureNamedKeyCredential("sample_name", 123345)

    cred = AzureNamedKeyCredential("sample_name", "samplekey")
    assert cred.named_key.name == "sample_name"
    assert cred.named_key.key == "samplekey"

    with pytest.raises(TypeError, match="Both name and key must be strings."):
        cred.update(1234, "newkey")
class TestTablesUnitTest(TableTestCase):
    tables_storage_account_name = "fake_storage_account"
    tables_primary_storage_account_key = "fakeXMZjnGsZGvd4bVr3Il5SeHA"
    credential = AzureNamedKeyCredential(
        name=tables_storage_account_name,
        key=tables_primary_storage_account_key)

    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.credential)

        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.credential)
        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.credential)
        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)
class TestTableUnitTest(AsyncTableTestCase):
    tables_cosmos_account_name = "fake_storage_account"
    tables_primary_cosmos_account_key = "fakeXMZjnGsZGvd4bVr3Il5SeHA"
    credential = AzureNamedKeyCredential(name=tables_cosmos_account_name,
                                         key=tables_primary_cosmos_account_key)

    @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.credential)
        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.credential)
        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.credential)
        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)
Example #18
0
def parse_connection_str(conn_str, credential, keyword_args):
    conn_settings = parse_connection_string(conn_str)
    primary = None
    secondary = None
    if not credential:
        try:
            credential = AzureNamedKeyCredential(
                name=conn_settings["accountname"],
                key=conn_settings["accountkey"])
        except KeyError:
            credential = conn_settings.get("sharedaccesssignature", None)
            if not credential:
                raise ValueError(
                    "Connection string missing required connection details.")
            credential = AzureSasCredential(credential)
    primary = conn_settings.get("tableendpoint")
    secondary = conn_settings.get("tablesecondaryendpoint")
    if not primary:
        if secondary:
            raise ValueError(
                "Connection string specifies only secondary endpoint.")
        try:
            primary = "{}://{}.table.{}".format(
                conn_settings["defaultendpointsprotocol"],
                conn_settings["accountname"],
                conn_settings["endpointsuffix"],
            )
            secondary = "{}-secondary.table.{}".format(
                conn_settings["accountname"], conn_settings["endpointsuffix"])
        except KeyError:
            pass

    if not primary:
        try:
            primary = "https://{}.table.{}".format(
                conn_settings["accountname"],
                conn_settings.get("endpointsuffix", SERVICE_HOST_BASE),
            )
        except KeyError:
            raise ValueError(
                "Connection string missing required connection details.")

    if "secondary_hostname" not in keyword_args:
        keyword_args["secondary_hostname"] = secondary

    return primary, credential
Example #19
0
def test_client_azure_named_key_credential(live_eventhub):
    credential = AzureNamedKeyCredential(live_eventhub['key_name'],
                                         live_eventhub['access_key'])
    consumer_client = EventHubConsumerClient(
        fully_qualified_namespace=live_eventhub['hostname'],
        eventhub_name=live_eventhub['event_hub'],
        consumer_group='$default',
        credential=credential,
        user_agent='customized information')

    assert consumer_client.get_eventhub_properties() is not None

    credential.update("foo", "bar")

    with pytest.raises(Exception):
        consumer_client.get_eventhub_properties()

    credential.update(live_eventhub['key_name'], live_eventhub['access_key'])
    assert consumer_client.get_eventhub_properties() is not None
Example #20
0
    def test_create_client_for_azurite(self):
        azurite_credential = AzureNamedKeyCredential("myaccount", self.tables_primary_storage_account_key)
        http_connstr = "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey={};TableEndpoint=http://127.0.0.1:10002/devstoreaccount1;".format(
            self.tables_primary_storage_account_key
        )
        https_connstr = "DefaultEndpointsProtocol=https;AccountName=devstoreaccount1;AccountKey={};TableEndpoint=https://127.0.0.1:10002/devstoreaccount1;".format(
            self.tables_primary_storage_account_key
        )
        account_url = "https://127.0.0.1:10002/myaccount"
        client = TableServiceClient(account_url, credential=azurite_credential)
        assert client.account_name == "myaccount"
        assert client.url == "https://127.0.0.1:10002/myaccount"
        assert client._location_mode == "primary"
        assert client._secondary_endpoint == "https://127.0.0.1:10002/myaccount-secondary"
        assert client.credential.named_key.key == azurite_credential.named_key.key
        assert client.credential.named_key.name == azurite_credential.named_key.name
        assert not client._cosmos_endpoint

        client = TableServiceClient.from_connection_string(http_connstr)
        assert client.account_name == "devstoreaccount1"
        assert client.url == "http://127.0.0.1:10002/devstoreaccount1"
        assert client._location_mode == "primary"
        assert client._secondary_endpoint == "http://127.0.0.1:10002/devstoreaccount1-secondary"
        assert client.credential.named_key.key == self.tables_primary_storage_account_key
        assert client.credential.named_key.name == "devstoreaccount1"
        assert not client._cosmos_endpoint

        client = TableServiceClient.from_connection_string(https_connstr)
        assert client.account_name == "devstoreaccount1"
        assert client.url == "https://127.0.0.1:10002/devstoreaccount1"
        assert client._location_mode == "primary"
        assert client._secondary_endpoint == "https://127.0.0.1:10002/devstoreaccount1-secondary"
        assert client.credential.named_key.key == self.tables_primary_storage_account_key
        assert client.credential.named_key.name == "devstoreaccount1"
        assert not client._cosmos_endpoint

        table = TableClient(account_url, "tablename", credential=azurite_credential)
        assert table.account_name == "myaccount"
        assert table.table_name == "tablename"
        assert table.url == "https://127.0.0.1:10002/myaccount"
        assert table._location_mode == "primary"
        assert table._secondary_endpoint == "https://127.0.0.1:10002/myaccount-secondary"
        assert table.credential.named_key.key == azurite_credential.named_key.key
        assert table.credential.named_key.name == azurite_credential.named_key.name
        assert not table._cosmos_endpoint

        table = TableClient.from_connection_string(http_connstr, "tablename")
        assert table.account_name == "devstoreaccount1"
        assert table.table_name == "tablename"
        assert table.url == "http://127.0.0.1:10002/devstoreaccount1"
        assert table._location_mode == "primary"
        assert table._secondary_endpoint == "http://127.0.0.1:10002/devstoreaccount1-secondary"
        assert table.credential.named_key.key == self.tables_primary_storage_account_key
        assert table.credential.named_key.name == "devstoreaccount1"
        assert not table._cosmos_endpoint

        table = TableClient.from_connection_string(https_connstr, "tablename")
        assert table.account_name == "devstoreaccount1"
        assert table.table_name == "tablename"
        assert table.url == "https://127.0.0.1:10002/devstoreaccount1"
        assert table._location_mode == "primary"
        assert table._secondary_endpoint == "https://127.0.0.1:10002/devstoreaccount1-secondary"
        assert table.credential.named_key.key == self.tables_primary_storage_account_key
        assert table.credential.named_key.name == "devstoreaccount1"
        assert not table._cosmos_endpoint

        table_url = "https://127.0.0.1:10002/myaccount/Tables('tablename')"
        table = TableClient.from_table_url(table_url, azurite_credential)
        assert table.account_name == "myaccount"
        assert table.table_name == "tablename"
        assert table.url == "https://127.0.0.1:10002/myaccount"
        assert table._location_mode == "primary"
        assert table._secondary_endpoint == "https://127.0.0.1:10002/myaccount-secondary"
        assert table.credential.named_key.key == azurite_credential.named_key.key
        assert table.credential.named_key.name == azurite_credential.named_key.name
        assert not table._cosmos_endpoint
Example #21
0
class TestTableUnitTests(TableTestCase):
    tables_storage_account_name = "fake_storage_account"
    tables_primary_storage_account_key = "fakeXMZjnGsZGvd4bVr3Il5SeHA"
    credential = AzureNamedKeyCredential(name=tables_storage_account_name, key=tables_primary_storage_account_key)

    # --Helpers-----------------------------------------------------------------
    def validate_standard_account_endpoints(self, service, account_name, account_key):
        assert service is not None
        assert service.account_name == account_name
        assert service.credential.named_key.name == account_name
        assert service.credential.named_key.key == 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 --------------------------------------------
    def test_create_service_with_key(self):
        # Arrange

        for client, url in SERVICES.items():
            # Act
            service = client(
                self.account_url(self.tables_storage_account_name, url), credential=self.credential, table_name='foo')

            # Assert
            self.validate_standard_account_endpoints(service, self.tables_storage_account_name, self.tables_primary_storage_account_key)
            assert service.scheme == 'https'

    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(self.tables_storage_account_name, self.tables_primary_storage_account_key), table_name="test")

            # Assert
            self.validate_standard_account_endpoints(service, self.tables_storage_account_name, self.tables_primary_storage_account_key)
            assert service.scheme == 'https'

    def test_create_service_with_sas(self):
        # Arrange
        url = self.account_url(self.tables_storage_account_name, "table")
        suffix = '.table.core.windows.net'
        token = self.generate_sas_token()
        for service_type in SERVICES:
            # Act
            service = service_type(
                self.account_url(self.tables_storage_account_name, "table"), credential=token, 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.url.endswith(token)
            assert service.credential is None

    def test_create_service_china(self):
        # Arrange
        for service_type in SERVICES.items():
            # Act
            url = self.account_url(self.tables_storage_account_name, "table").replace('core.windows.net', 'core.chinacloudapi.cn')
            service = service_type[0](
                url, credential=self.credential, table_name='foo')

            # Assert
            assert service is not None
            assert service.account_name == self.tables_storage_account_name
            assert service.credential.named_key.name == self.tables_storage_account_name
            assert service.credential.named_key.key == self.tables_primary_storage_account_key
            assert service._primary_endpoint.startswith('https://{}.{}.core.chinacloudapi.cn'.format(self.tables_storage_account_name, "table"))

    def test_create_service_protocol(self):
        # Arrange

        for service_type in SERVICES.items():
            # Act
            url = self.account_url(self.tables_storage_account_name, "table").replace('https', 'http')
            service = service_type[0](
                url, credential=self.credential, table_name='foo')

            # Assert
            self.validate_standard_account_endpoints(service, self.tables_storage_account_name, self.tables_primary_storage_account_key)
            assert service.scheme == 'http'

    def test_create_service_empty_key(self):
        # Arrange
        TABLE_SERVICES = [TableServiceClient, TableClient]

        for service_type in TABLE_SERVICES:
            # Act
            with pytest.raises(ValueError) as e:
                test_service = service_type('testaccount', credential='', table_name='foo')

            # test non-string account URL
            with pytest.raises(ValueError):
                test_service = service_type(endpoint=123456, credential=self.credential, table_name='foo')

            assert str(e.value) == "You need to provide either a SAS token or an account shared key to authenticate."

    def test_create_service_with_socket_timeout(self):
        # Arrange

        for service_type in SERVICES.items():
            # Act
            default_service = service_type[0](
                self.account_url(self.tables_storage_account_name, "table"), credential=self.credential, table_name='foo')
            service = service_type[0](
                self.account_url(self.tables_storage_account_name, "table"), credential=self.credential,
                table_name='foo', connection_timeout=22)

            # Assert
            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 == 300

        # Assert Parent transport is shared with child client
        service = TableServiceClient(
            self.account_url(self.tables_storage_account_name, "table"),
            credential=self.credential,
            connection_timeout=22)
        assert service._client._client._pipeline._transport.connection_config.timeout == 22
        table = service.get_table_client('tablename')
        assert table._client._client._pipeline._transport._transport.connection_config.timeout == 22



    # --Connection String Test Cases --------------------------------------------
    def test_create_service_with_connection_string_key(self):
        # Arrange
        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, self.tables_storage_account_name, self.tables_primary_storage_account_key)
            assert service.scheme == 'https'

    def test_create_service_with_connection_string_sas(self):
        # Arrange
        token = self.generate_sas_token()
        conn_string = 'AccountName={};SharedAccessSignature={};'.format(
            self.tables_storage_account_name, token)

        for service_type in SERVICES:
            # Act
            service = service_type.from_connection_string(conn_string, 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 + '.table.core.windows.net')
            assert service.url.endswith(token)
            assert service.credential is None

    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(
            self.tables_storage_account_name, self.tables_primary_storage_account_key)

        for service_type in SERVICES:
            # Act
            service = service_type.from_connection_string(conn_string, 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 + '.table.cosmos.azure.com')
            assert service.credential.named_key.name == self.tables_storage_account_name
            assert service.credential.named_key.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'

    def test_create_service_with_connection_string_endpoint_protocol(self):
        # Arrange
        conn_string = 'AccountName={};AccountKey={};DefaultEndpointsProtocol=http;EndpointSuffix=core.chinacloudapi.cn;'.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
            assert service is not None
            assert service.account_name == self.tables_storage_account_name
            assert service.credential.named_key.name == self.tables_storage_account_name
            assert service.credential.named_key.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'

    def test_create_service_with_connection_string_emulated(self):
        # Arrange
        for service_type in SERVICES.items():
            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")

    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(
                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.credential.named_key.name == self.tables_storage_account_name
            assert service.credential.named_key.key == self.tables_primary_storage_account_key
            assert service._primary_endpoint.startswith('https://www.mydomain.com')

    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(
                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.credential.named_key.name == self.tables_storage_account_name
            assert service.credential.named_key.key == self.tables_primary_storage_account_key
            assert service._primary_endpoint.startswith('https://www.mydomain.com')

    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(
                self.tables_storage_account_name, self.tables_primary_storage_account_key)

            # Act
            service = service_type[0].from_connection_string(
                conn_string, secondary_hostname="www-sec.mydomain.com", table_name="foo")

            # Assert
            assert service is not None
            assert service.credential.named_key.name == self.tables_storage_account_name
            assert service.credential.named_key.key == self.tables_primary_storage_account_key
            assert service._primary_endpoint.startswith('https://www.mydomain.com')

    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(
                self.tables_storage_account_name, self.tables_primary_storage_account_key,
                _CONNECTION_ENDPOINTS_SECONDARY.get(service_type[1]))

            # Act

            # Fails if primary excluded
            with pytest.raises(ValueError):
                service = service_type[0].from_connection_string(conn_string, table_name="foo")

    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(
                self.tables_storage_account_name,
                self.tables_primary_storage_account_key,
                _CONNECTION_ENDPOINTS.get(service_type[1]),
                _CONNECTION_ENDPOINTS_SECONDARY.get(service_type[1]))

            # Act
            service = service_type[0].from_connection_string(conn_string, table_name="foo")

            # Assert
            assert service is not None
            assert service.credential.named_key.name == self.tables_storage_account_name
            assert service.credential.named_key.key == self.tables_primary_storage_account_key
            assert service._primary_endpoint.startswith('https://www.mydomain.com')

    def test_create_service_with_custom_account_endpoint_path(self):
        token = self.generate_sas_token()
        custom_account_url = "http://local-machine:11002/custom/account/path/" + token
        for service_type in SERVICES.items():
            conn_string = 'DefaultEndpointsProtocol=http;AccountName={};AccountKey={};TableEndpoint={};'.format(
                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 == self.tables_storage_account_name
            assert service.credential.named_key.name == self.tables_storage_account_name
            assert service.credential.named_key.key == self.tables_primary_storage_account_key
            assert service._primary_hostname == 'local-machine:11002/custom/account/path'

        service = TableServiceClient(endpoint=custom_account_url)
        assert service.account_name == "custom"
        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')

        service = TableClient(endpoint=custom_account_url, table_name="foo")
        assert service.account_name == "custom"
        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')

        service = TableClient.from_table_url("http://local-machine:11002/custom/account/path/foo" + token)
        assert service.account_name == "custom"
        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')

    def test_create_table_client_with_complete_table_url(self):
        # Arrange
        table_url = self.account_url(self.tables_storage_account_name, "table") + "/foo"
        service = TableClient(table_url, table_name='bar', credential=self.credential)

        # Assert
        assert service.scheme == 'https'
        assert service.table_name == 'bar'
        assert service.account_name == self.tables_storage_account_name

    def test_create_table_client_with_complete_url(self):
        # Arrange
        table_url = "https://{}.table.core.windows.net:443/foo".format(self.tables_storage_account_name)
        service = TableClient(endpoint=table_url, table_name='bar', credential=self.credential)

        # Assert
        assert service.scheme == 'https'
        assert service.table_name == 'bar'
        assert service.account_name == self.tables_storage_account_name

    def test_create_table_client_with_invalid_name(self):
        # Arrange
        table_url = "https://{}.table.core.windows.net:443/foo".format("test")
        invalid_table_name = "my_table"

        # Assert
        with pytest.raises(ValueError) as excinfo:
            service = TableClient(endpoint=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)

    def test_error_with_malformed_conn_str(self):
        # Arrange

        for conn_str in ["", "foobar", "foobar=baz=foo", "foo;bar;baz", "foo=;bar=;", "=", ";", "=;=="]:
            for service_type in SERVICES.items():
                # Act
                with pytest.raises(ValueError) as e:
                    service = service_type[0].from_connection_string(conn_str, table_name="test")

                if conn_str in("", "foobar", "foo;bar;baz", ";", "foo=;bar=;", "=", "=;=="):
                    assert str(e.value) == "Connection string is either blank or malformed."
                elif conn_str in ("foobar=baz=foo"):
                   assert str(e.value) == "Connection string missing required connection details."

    def test_closing_pipeline_client(self):
        # Arrange
        for client, url in SERVICES.items():
            # Act
            service = client(
                self.account_url(self.tables_storage_account_name, "table"), credential=self.credential, table_name='table')

            # Assert
            with service:
                assert hasattr(service, 'close')
                service.close()

    def test_closing_pipeline_client_simple(self):
        # Arrange
        for client, url in SERVICES.items():
            # Act
            service = client(
                self.account_url(self.tables_storage_account_name, "table"), credential=self.credential, 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')

    def test_create_client_with_api_version(self):
        url = self.account_url(self.tables_storage_account_name, "table")
        client = TableServiceClient(url, credential=self.credential)
        assert client._client._config.version == "2019-02-02"
        table = client.get_table_client('tablename')
        assert table._client._config.version == "2019-02-02"

        client = TableServiceClient(url, credential=self.credential, api_version="2019-07-07")
        assert client._client._config.version == "2019-07-07"
        table = client.get_table_client('tablename')
        assert table._client._config.version == "2019-07-07"

        with pytest.raises(ValueError):
            TableServiceClient(url, credential=self.credential, api_version="foo")

    def test_create_client_for_azurite(self):
        azurite_credential = AzureNamedKeyCredential("myaccount", self.tables_primary_storage_account_key)
        http_connstr = "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey={};TableEndpoint=http://127.0.0.1:10002/devstoreaccount1;".format(
            self.tables_primary_storage_account_key
        )
        https_connstr = "DefaultEndpointsProtocol=https;AccountName=devstoreaccount1;AccountKey={};TableEndpoint=https://127.0.0.1:10002/devstoreaccount1;".format(
            self.tables_primary_storage_account_key
        )
        account_url = "https://127.0.0.1:10002/myaccount"
        client = TableServiceClient(account_url, credential=azurite_credential)
        assert client.account_name == "myaccount"
        assert client.url == "https://127.0.0.1:10002/myaccount"
        assert client._location_mode == "primary"
        assert client._secondary_endpoint == "https://127.0.0.1:10002/myaccount-secondary"
        assert client.credential.named_key.key == azurite_credential.named_key.key
        assert client.credential.named_key.name == azurite_credential.named_key.name
        assert not client._cosmos_endpoint

        client = TableServiceClient.from_connection_string(http_connstr)
        assert client.account_name == "devstoreaccount1"
        assert client.url == "http://127.0.0.1:10002/devstoreaccount1"
        assert client._location_mode == "primary"
        assert client._secondary_endpoint == "http://127.0.0.1:10002/devstoreaccount1-secondary"
        assert client.credential.named_key.key == self.tables_primary_storage_account_key
        assert client.credential.named_key.name == "devstoreaccount1"
        assert not client._cosmos_endpoint

        client = TableServiceClient.from_connection_string(https_connstr)
        assert client.account_name == "devstoreaccount1"
        assert client.url == "https://127.0.0.1:10002/devstoreaccount1"
        assert client._location_mode == "primary"
        assert client._secondary_endpoint == "https://127.0.0.1:10002/devstoreaccount1-secondary"
        assert client.credential.named_key.key == self.tables_primary_storage_account_key
        assert client.credential.named_key.name == "devstoreaccount1"
        assert not client._cosmos_endpoint

        table = TableClient(account_url, "tablename", credential=azurite_credential)
        assert table.account_name == "myaccount"
        assert table.table_name == "tablename"
        assert table.url == "https://127.0.0.1:10002/myaccount"
        assert table._location_mode == "primary"
        assert table._secondary_endpoint == "https://127.0.0.1:10002/myaccount-secondary"
        assert table.credential.named_key.key == azurite_credential.named_key.key
        assert table.credential.named_key.name == azurite_credential.named_key.name
        assert not table._cosmos_endpoint

        table = TableClient.from_connection_string(http_connstr, "tablename")
        assert table.account_name == "devstoreaccount1"
        assert table.table_name == "tablename"
        assert table.url == "http://127.0.0.1:10002/devstoreaccount1"
        assert table._location_mode == "primary"
        assert table._secondary_endpoint == "http://127.0.0.1:10002/devstoreaccount1-secondary"
        assert table.credential.named_key.key == self.tables_primary_storage_account_key
        assert table.credential.named_key.name == "devstoreaccount1"
        assert not table._cosmos_endpoint

        table = TableClient.from_connection_string(https_connstr, "tablename")
        assert table.account_name == "devstoreaccount1"
        assert table.table_name == "tablename"
        assert table.url == "https://127.0.0.1:10002/devstoreaccount1"
        assert table._location_mode == "primary"
        assert table._secondary_endpoint == "https://127.0.0.1:10002/devstoreaccount1-secondary"
        assert table.credential.named_key.key == self.tables_primary_storage_account_key
        assert table.credential.named_key.name == "devstoreaccount1"
        assert not table._cosmos_endpoint

        table_url = "https://127.0.0.1:10002/myaccount/Tables('tablename')"
        table = TableClient.from_table_url(table_url, azurite_credential)
        assert table.account_name == "myaccount"
        assert table.table_name == "tablename"
        assert table.url == "https://127.0.0.1:10002/myaccount"
        assert table._location_mode == "primary"
        assert table._secondary_endpoint == "https://127.0.0.1:10002/myaccount-secondary"
        assert table.credential.named_key.key == azurite_credential.named_key.key
        assert table.credential.named_key.name == azurite_credential.named_key.name
        assert not table._cosmos_endpoint
Example #22
0
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
"""
An example to show authentication using AzureNamedKeyCredential.
"""

import os
import asyncio
from azure.core.credentials import AzureNamedKeyCredential
from azure.servicebus.aio import ServiceBusClient
from azure.servicebus import ServiceBusMessage

FULLY_QUALIFIED_NAMESPACE = os.environ['SERVICE_BUS_FULLY_QUALIFIED_NAMESPACE']
QUEUE_NAME = os.environ["SERVICE_BUS_QUEUE_NAME"]
SAS_POLICY = os.environ['SERVICE_BUS_SAS_POLICY']
SERVICEBUS_SAS_KEY = os.environ['SERVICE_BUS_SAS_KEY']

credential = AzureNamedKeyCredential(SAS_POLICY, SERVICEBUS_SAS_KEY)


async def send_message():
    async with ServiceBusClient(FULLY_QUALIFIED_NAMESPACE,
                                credential) as client:
        async with client.get_queue_sender(QUEUE_NAME) as sender:
            await sender.send_messages([ServiceBusMessage("hello")])


asyncio.run(send_message())
Example #23
0
class TestTableClientUnit(TableTestCase):
    tables_cosmos_account_name = "fake_storage_account"
    tables_primary_cosmos_account_key = "fakeXMZjnGsZGvd4bVr3Il5SeHA"
    credential = AzureNamedKeyCredential(name=tables_cosmos_account_name,
                                         key=tables_primary_cosmos_account_key)

    # --Helpers-----------------------------------------------------------------
    def validate_standard_account_endpoints(self, service, account_name,
                                            account_key):
        assert service is not None
        assert service.account_name == account_name
        assert service.credential.named_key.name == account_name
        assert service.credential.named_key.key == account_key
        assert ('{}.{}'.format(account_name, 'table.core.windows.net')
                in service.url) or ('{}.{}'.format(
                    account_name, 'table.cosmos.azure.com') in service.url)

    def _account_url(self, account_name):
        return "https://{}.table.cosmos.azure.com".format(account_name)

    # --Direct Parameters Test Cases --------------------------------------------

    def test_create_service_with_key(self):
        # Arrange
        for client, url in SERVICES.items():
            # Act
            service = client(endpoint=self._account_url(
                self.tables_cosmos_account_name),
                             credential=self.credential,
                             table_name='foo')

            # Assert
            self.validate_standard_account_endpoints(
                service, self.tables_cosmos_account_name,
                self.tables_primary_cosmos_account_key)
            assert service.scheme == 'https'

    def test_create_service_with_connection_string(self):

        for client, url in SERVICES.items():
            # Act
            service = client(endpoint=self._account_url(
                self.tables_cosmos_account_name),
                             credential=self.credential,
                             table_name="test")

            # Assert
            self.validate_standard_account_endpoints(
                service, self.tables_cosmos_account_name,
                self.tables_primary_cosmos_account_key)
            assert service.scheme == 'https'

    def test_create_service_with_sas(self):
        # Arrange
        url = self.account_url(self.tables_cosmos_account_name, "cosmos")
        suffix = '.table.cosmos.azure.com'
        self.sas_token = self.generate_sas_token()
        self.sas_token = AzureSasCredential(self.sas_token)
        for service_type in SERVICES:
            # Act
            service = service_type(endpoint=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 == self.tables_cosmos_account_name
            assert service.url.startswith('https://' +
                                          self.tables_cosmos_account_name +
                                          suffix)
            assert isinstance(service.credential, AzureSasCredential)

    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 = service_type(
                endpoint=self._account_url(self.tables_cosmos_account_name),
                credential=AzureSasCredential("fake_sas_credential"),
                table_name="foo")

            # Assert
            assert service is not None
            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')

    @pytest.mark.skip("HTTP prefix does not raise an error")
    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(self.tables_cosmos_account_name,
                                       "cosmos").replace('https', 'http')
                service = service_type(
                    endpoint=url,
                    credential=AzureSasCredential("fake_sas_credential"),
                    table_name="foo")

    def test_create_service_china(self):
        for service_type in SERVICES.items():
            url = self.account_url(self.tables_cosmos_account_name,
                                   "cosmos").replace('cosmos.azure.com',
                                                     'core.chinacloudapi.cn')
            service = service_type[0](url,
                                      credential=self.credential,
                                      table_name='foo')

            assert service is not None
            assert service.account_name == self.tables_cosmos_account_name
            assert service.credential.named_key.name == self.tables_cosmos_account_name
            assert service.credential.named_key.key == self.tables_primary_cosmos_account_key
            assert service._primary_endpoint.startswith(
                'https://{}.{}.core.chinacloudapi.cn'.format(
                    self.tables_cosmos_account_name, "table"))

    def test_create_service_protocol(self):
        # Arrange
        url = self._account_url(self.tables_cosmos_account_name).replace(
            'https', 'http')
        suffix = '.table.cosmos.azure.com'
        for service_type in SERVICES:
            # Act
            service = service_type(endpoint=url,
                                   credential=self.credential,
                                   table_name="foo")

            # Assert
            self.validate_standard_account_endpoints(
                service, self.tables_cosmos_account_name,
                self.tables_primary_cosmos_account_key)
            assert service.scheme == 'http'

    def test_create_service_empty_key(self):
        # Arrange
        TABLE_SERVICES = [TableServiceClient, TableClient]

        for service_type in TABLE_SERVICES:
            # Act
            with pytest.raises(ValueError) as e:
                test_service = service_type('testaccount',
                                            credential='',
                                            table_name='foo')

            assert str(
                e.value
            ) == "You need to provide either an AzureSasCredential or AzureNamedKeyCredential"

    def test_create_service_with_socket_timeout(self):
        # Arrange

        for service_type in SERVICES.items():
            # Act
            default_service = service_type[0](endpoint=self._account_url(
                self.tables_cosmos_account_name),
                                              credential=self.credential,
                                              table_name="foo")
            service = service_type[0](endpoint=self._account_url(
                self.tables_cosmos_account_name),
                                      credential=self.credential,
                                      table_name="foo",
                                      connection_timeout=22)

            # Assert
            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 == 300

    # --Connection String Test Cases --------------------------------------------
    def test_create_service_with_connection_string_key(self):
        # Arrange
        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, self.tables_cosmos_account_name,
                self.tables_primary_cosmos_account_key)
            assert service.scheme == 'https'

    def test_create_service_with_connection_string_sas(self):
        # Arrange
        self.sas_token = self.generate_sas_token()
        self.sas_token = AzureSasCredential(self.sas_token)
        conn_string = 'AccountName={};SharedAccessSignature={};'.format(
            self.tables_cosmos_account_name, self.sas_token.signature)

        for service_type in SERVICES:
            # Act
            service = service_type.from_connection_string(conn_string,
                                                          table_name='foo')

            # Assert
            assert service is not None
            assert service.url.startswith('https://' +
                                          self.tables_cosmos_account_name +
                                          '.table.core.windows.net')
            assert isinstance(service.credential, AzureSasCredential)

    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(
            self.tables_cosmos_account_name,
            self.tables_primary_cosmos_account_key)

        for service_type in SERVICES:
            # Act
            service = service_type.from_connection_string(conn_string,
                                                          table_name='foo')

            # Assert
            assert service is not None
            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.named_key.name == self.tables_cosmos_account_name
            assert service.credential.named_key.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'

    def test_create_service_with_connection_string_endpoint_protocol(self):
        conn_string = 'AccountName={};AccountKey={};DefaultEndpointsProtocol=http;EndpointSuffix=core.chinacloudapi.cn;'.format(
            self.tables_cosmos_account_name,
            self.tables_primary_cosmos_account_key)

        for service_type in SERVICES.items():
            service = service_type[0].from_connection_string(conn_string,
                                                             table_name="foo")

            assert service is not None
            assert service.account_name == self.tables_cosmos_account_name
            assert service.credential.named_key.name == self.tables_cosmos_account_name
            assert service.credential.named_key.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'

    def test_create_service_with_connection_string_emulated(self):
        # Arrange
        for service_type in SERVICES.items():
            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")

    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(
                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.credential.named_key.name == self.tables_cosmos_account_name
            assert service.credential.named_key.key == self.tables_primary_cosmos_account_key
            assert service._primary_endpoint.startswith(
                'https://www.mydomain.com')
            assert service.scheme == 'https'

    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(
                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.credential.named_key.name == self.tables_cosmos_account_name
            assert service.credential.named_key.key == self.tables_primary_cosmos_account_key
            assert service._primary_endpoint.startswith(
                'https://www.mydomain.com')

    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(
                self.tables_cosmos_account_name,
                self.tables_primary_cosmos_account_key)

            # Act
            service = service_type[0].from_connection_string(
                conn_string,
                secondary_hostname="www-sec.mydomain.com",
                table_name="foo")

            # Assert
            assert service is not None
            assert service.credential.named_key.name == self.tables_cosmos_account_name
            assert service.credential.named_key.key == self.tables_primary_cosmos_account_key
            assert service._primary_endpoint.startswith(
                'https://www.mydomain.com')

    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(
                self.tables_cosmos_account_name,
                self.tables_primary_cosmos_account_key,
                _CONNECTION_ENDPOINTS_SECONDARY.get(service_type[1]))

            # Act

            # Fails if primary excluded
            with pytest.raises(ValueError):
                service = service_type[0].from_connection_string(
                    conn_string, table_name="foo")

    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(
                self.tables_cosmos_account_name,
                self.tables_primary_cosmos_account_key,
                _CONNECTION_ENDPOINTS.get(service_type[1]),
                _CONNECTION_ENDPOINTS_SECONDARY.get(service_type[1]))

            # Act
            service = service_type[0].from_connection_string(conn_string,
                                                             table_name="foo")

            # Assert
            assert service is not None
            assert service.credential.named_key.name == self.tables_cosmos_account_name
            assert service.credential.named_key.key == self.tables_primary_cosmos_account_key
            assert service._primary_endpoint.startswith(
                'https://www.mydomain.com')

    def test_create_service_with_custom_account_endpoint_path(self):
        self.sas_token = AzureSasCredential(self.generate_sas_token())
        custom_account_url = "http://*****:*****@")
        _validate_cosmos_tablename("a" * 254)
        with pytest.raises(ValueError):
            _validate_cosmos_tablename("\\")
        with pytest.raises(ValueError):
            _validate_cosmos_tablename("/")
        with pytest.raises(ValueError):
            _validate_cosmos_tablename("#")
        with pytest.raises(ValueError):
            _validate_cosmos_tablename("?")
        with pytest.raises(ValueError):
            _validate_cosmos_tablename("a ")
        with pytest.raises(ValueError):
            _validate_cosmos_tablename("a" * 255)
import os
import asyncio
import time
from azure.core.credentials import AzureNamedKeyCredential
from azure.eventhub.aio import EventHubProducerClient
from azure.eventhub import EventData

# Target namespace and hub must also be specified.
FULLY_QUALIFIED_NAMESPACE = os.environ['EVENT_HUB_HOSTNAME']
EVENTHUB_NAME = os.environ['EVENT_HUB_NAME']

EVENTHUB_POLICY_NAME = os.environ['EVENT_HUB_SAS_POLICY']
EVENTHUB_KEY = os.environ['EVENT_HUB_SAS_KEY']

credential = AzureNamedKeyCredential(EVENTHUB_POLICY_NAME, EVENTHUB_KEY)

producer_client = EventHubProducerClient(
    fully_qualified_namespace=FULLY_QUALIFIED_NAMESPACE,
    eventhub_name=EVENTHUB_NAME,
    credential=credential,
    logging_enable=True)

start_time = time.time()


async def authenticate_with_named_key():
    async with producer_client:
        event_data_batch = await producer_client.create_batch()
        event_data_batch.add(EventData('Single message'))
        await producer_client.send_batch(event_data_batch)
class TestTableClientUnit(AsyncTableTestCase):
    tables_cosmos_account_name = "fake_storage_account"
    tables_primary_cosmos_account_key = "fakeXMZjnGsZGvd4bVr3Il5SeHA"
    credential = AzureNamedKeyCredential(name=tables_cosmos_account_name,
                                         key=tables_primary_cosmos_account_key)

    # --Helpers-----------------------------------------------------------------
    def validate_standard_account_endpoints(self, service, account_name,
                                            account_key):
        assert service is not None
        assert service.account_name == account_name
        assert service.credential.named_key.name == account_name
        assert service.credential.named_key.key == 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 --------------------------------------------
    @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(self.tables_cosmos_account_name,
                                              url),
                             credential=self.credential,
                             table_name='foo')

            # Assert
            self.validate_standard_account_endpoints(
                service, self.tables_cosmos_account_name,
                self.tables_primary_cosmos_account_key)
            assert service.scheme == 'https'

    @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(self.tables_cosmos_account_name,
                                       self.tables_primary_cosmos_account_key),
                table_name="test")

            # Assert
            self.validate_standard_account_endpoints(
                service, self.tables_cosmos_account_name,
                self.tables_primary_cosmos_account_key)
            assert service.scheme == 'https'

    @pytest.mark.asyncio
    async def test_create_service_with_sas_async(self):
        # Arrange
        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(
                self.tables_cosmos_account_name, "cosmos"),
                                   credential=self.sas_token,
                                   table_name='foo')

            # Assert
            assert service is not None
            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

    @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 == 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')

    @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(self.tables_cosmos_account_name,
                                       "cosmos").replace('https', 'http')
                service_type(url,
                             credential=self.token_credential,
                             table_name='foo')

    @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(self.tables_cosmos_account_name,
                                   "cosmos").replace('cosmos.azure.com',
                                                     'core.chinacloudapi.cn')
            service = service_type[0](url,
                                      credential=self.credential,
                                      table_name='foo')

            # Assert
            assert service is not None
            assert service.account_name == self.tables_cosmos_account_name
            assert service.credential.named_key.name == self.tables_cosmos_account_name
            assert service.credential.named_key.key == self.tables_primary_cosmos_account_key
            assert service._primary_endpoint.startswith(
                'https://{}.{}.core.chinacloudapi.cn'.format(
                    self.tables_cosmos_account_name, "table"))

    @pytest.mark.asyncio
    async def test_create_service_protocol_async(self):
        # Arrange

        for service_type in SERVICES.items():
            # Act
            url = self.account_url(self.tables_cosmos_account_name,
                                   "cosmos").replace('https', 'http')
            service = service_type[0](url,
                                      credential=self.credential,
                                      table_name='foo')

            # Assert
            self.validate_standard_account_endpoints(
                service, self.tables_cosmos_account_name,
                self.tables_primary_cosmos_account_key)
            assert service.scheme == 'http'

    @pytest.mark.asyncio
    async def test_create_service_empty_key_async(self):
        # Arrange
        TABLE_SERVICES = [TableServiceClient, TableClient]

        for service_type in TABLE_SERVICES:
            # Act
            with pytest.raises(ValueError) as e:
                test_service = service_type('testaccount',
                                            credential='',
                                            table_name='foo')

            assert str(
                e.value
            ) == "You need to provide either a SAS token or an account shared key to authenticate."

    @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(
                self.tables_cosmos_account_name, "cosmos"),
                                              credential=self.credential,
                                              table_name='foo')
            service = service_type[0](self.account_url(
                self.tables_cosmos_account_name, "cosmos"),
                                      credential=self.credential,
                                      table_name='foo',
                                      connection_timeout=22)

            # Assert
            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 == 300

    # --Connection String Test Cases --------------------------------------------
    @pytest.mark.asyncio
    async def test_create_service_with_connection_string_key_async(self):
        # Arrange
        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, self.tables_cosmos_account_name,
                self.tables_primary_cosmos_account_key)
            assert service.scheme == 'https'

    @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(
            self.tables_cosmos_account_name, self.sas_token)

        for service_type in SERVICES:
            # Act
            service = service_type.from_connection_string(conn_string,
                                                          table_name='foo')

            # Assert
            assert service is not None
            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

    @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(
            self.tables_cosmos_account_name,
            self.tables_primary_cosmos_account_key)

        for service_type in SERVICES:
            # Act
            service = service_type.from_connection_string(conn_string,
                                                          table_name='foo')

            # Assert
            assert service is not None
            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.named_key.name == self.tables_cosmos_account_name
            assert service.credential.named_key.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.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(
            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
            assert service is not None
            assert service.account_name == self.tables_cosmos_account_name
            assert service.credential.named_key.name == self.tables_cosmos_account_name
            assert service.credential.named_key.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'

    @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(
                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")

    @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(
                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.credential.named_key.name == self.tables_cosmos_account_name
            assert service.credential.named_key.key == self.tables_primary_cosmos_account_key
            assert service._primary_endpoint.startswith(
                'https://www.mydomain.com')

    @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(
                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.credential.named_key.name == self.tables_cosmos_account_name
            assert service.credential.named_key.key == self.tables_primary_cosmos_account_key
            assert service._primary_endpoint.startswith(
                'https://www.mydomain.com')

    @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(
                self.tables_cosmos_account_name,
                self.tables_primary_cosmos_account_key)

            # Act
            service = service_type[0].from_connection_string(
                conn_string,
                secondary_hostname="www-sec.mydomain.com",
                table_name="foo")

            # Assert
            assert service is not None
            assert service.credential.named_key.name == self.tables_cosmos_account_name
            assert service.credential.named_key.key == self.tables_primary_cosmos_account_key
            assert service._primary_endpoint.startswith(
                'https://www.mydomain.com')

    @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(
                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")

    @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(
                self.tables_cosmos_account_name,
                self.tables_primary_cosmos_account_key,
                _CONNECTION_ENDPOINTS.get(service_type[1]),
                _CONNECTION_ENDPOINTS_SECONDARY.get(service_type[1]))

            # Act
            service = service_type[0].from_connection_string(conn_string,
                                                             table_name="foo")

            # Assert
            assert service is not None
            assert service.credential.named_key.name == self.tables_cosmos_account_name
            assert service.credential.named_key.key == self.tables_primary_cosmos_account_key
            assert service._primary_endpoint.startswith(
                'https://www.mydomain.com')

    @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(
                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 == "custom"
            assert service.credential.named_key.name == self.tables_cosmos_account_name
            assert service.credential.named_key.key == self.tables_primary_cosmos_account_key
            assert service._primary_hostname == 'local-machine:11002/custom/account/path'

        service = TableServiceClient(endpoint=custom_account_url)
        assert service.account_name == "custom"
        assert service.credential == None
        assert service._primary_hostname == 'local-machine:11002/custom/account/path'
        # mine doesnt have a question mark at the end
        assert service.url.startswith(
            'http://local-machine:11002/custom/account/path')

        service = TableClient(endpoint=custom_account_url, table_name="foo")
        assert service.account_name == "custom"
        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')

        service = TableClient.from_table_url(
            "http://local-machine:11002/custom/account/path/foo" +
            self.sas_token)
        assert service.account_name == "custom"
        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')

    @pytest.mark.asyncio
    async def test_create_table_client_with_complete_table_url_async(self):
        # Arrange
        table_url = self.account_url(self.tables_cosmos_account_name,
                                     "cosmos") + "/foo"
        service = TableClient(table_url,
                              table_name='bar',
                              credential=self.credential)

        # Assert
        assert service.scheme == 'https'
        assert service.table_name == 'bar'
        assert service.account_name == self.tables_cosmos_account_name

    @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(
            self.tables_cosmos_account_name)
        service = TableClient(table_url,
                              table_name='bar',
                              credential=self.credential)

        # Assert
        assert service.scheme == 'https'
        assert service.table_name == 'bar'
        assert service.account_name == self.tables_cosmos_account_name

    @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")
        invalid_table_name = "my_table"

        # Assert
        with pytest.raises(ValueError) as excinfo:
            service = TableClient(
                endpoint=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)

    @pytest.mark.asyncio
    async def test_error_with_malformed_conn_str_async(self):
        # Arrange

        for conn_str in [
                "", "foobar", "foobar=baz=foo", "foo;bar;baz", "foo=;bar=;",
                "=", ";", "=;=="
        ]:
            for service_type in SERVICES.items():
                # Act
                with pytest.raises(ValueError) as e:
                    service = service_type[0].from_connection_string(
                        conn_str, table_name="test")

                if conn_str in ("", "foobar", "foo;bar;baz", ";", "foo=;bar=;",
                                "=", "=;=="):
                    assert str(
                        e.value
                    ) == "Connection string is either blank or malformed."
                elif conn_str in ("foobar=baz=foo"):
                    assert str(
                        e.value
                    ) == "Connection string missing required connection details."

    @pytest.mark.asyncio
    async def test_closing_pipeline_client_async(self):
        # Arrange
        for client, url in SERVICES.items():
            # Act
            service = client(self.account_url(self.tables_cosmos_account_name,
                                              "cosmos"),
                             credential=self.credential,
                             table_name='table')

            # Assert
            async with service:
                assert hasattr(service, 'close')
                await service.close()

    @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(self.tables_cosmos_account_name,
                                              "cosmos"),
                             credential=self.credential,
                             table_name='table')
            await service.close()