diff --git a/eng/tools/azure-sdk-tools/azpysdk/samples.py b/eng/tools/azure-sdk-tools/azpysdk/samples.py index 0ebf1f056725..a7f7b83e229e 100644 --- a/eng/tools/azure-sdk-tools/azpysdk/samples.py +++ b/eng/tools/azure-sdk-tools/azpysdk/samples.py @@ -158,6 +158,9 @@ "blob_samples_container_access_policy_async.py", "blob_samples_client_side_encryption_keyvault.py", ], + "azure-messaging-webpubsubservice": [ + "integration_sample.py", + ], } diff --git a/sdk/webpubsub/azure-messaging-webpubsubclient/dev_requirements.txt b/sdk/webpubsub/azure-messaging-webpubsubclient/dev_requirements.txt index 4c9ec1f26d4f..65083eeb5eab 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubclient/dev_requirements.txt +++ b/sdk/webpubsub/azure-messaging-webpubsubclient/dev_requirements.txt @@ -1,6 +1,6 @@ -e ../../../eng/tools/azure-sdk-tools ../../core/azure-core ../../identity/azure-identity -azure-messaging-webpubsubservice==1.1.0b1 +../azure-messaging-webpubsubservice psutil aiohttp>=3.9.3 diff --git a/sdk/webpubsub/azure-messaging-webpubsubclient/samples/hello_world.py b/sdk/webpubsub/azure-messaging-webpubsubclient/samples/hello_world.py index 371c77b21091..249c9ef8e53e 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubclient/samples/hello_world.py +++ b/sdk/webpubsub/azure-messaging-webpubsubclient/samples/hello_world.py @@ -6,6 +6,7 @@ import os from azure.messaging.webpubsubclient import WebPubSubClient, WebPubSubClientCredential from azure.messaging.webpubsubservice import WebPubSubServiceClient +from azure.identity import DefaultAzureCredential from azure.messaging.webpubsubclient.models import ( OnConnectedArgs, OnGroupDataMessageArgs, @@ -37,8 +38,8 @@ def on_group_message(msg: OnGroupDataMessageArgs): def main(): - service_client = WebPubSubServiceClient.from_connection_string( # type: ignore - connection_string=os.getenv("WEBPUBSUB_CONNECTION_STRING", ""), hub="hub" + service_client = WebPubSubServiceClient( + endpoint=os.getenv("WEBPUBSUB_ENDPOINT", ""), hub="hub", credential=DefaultAzureCredential() ) client = WebPubSubClient( credential=WebPubSubClientCredential( diff --git a/sdk/webpubsub/azure-messaging-webpubsubclient/samples/hello_world_async.py b/sdk/webpubsub/azure-messaging-webpubsubclient/samples/hello_world_async.py index 77ee5c11d275..900a8e49d1c9 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubclient/samples/hello_world_async.py +++ b/sdk/webpubsub/azure-messaging-webpubsubclient/samples/hello_world_async.py @@ -7,6 +7,7 @@ import asyncio from azure.messaging.webpubsubclient.aio import WebPubSubClient, WebPubSubClientCredential from azure.messaging.webpubsubservice.aio import WebPubSubServiceClient +from azure.identity.aio import DefaultAzureCredential from azure.messaging.webpubsubclient.models import ( OnConnectedArgs, OnGroupDataMessageArgs, @@ -38,8 +39,9 @@ async def on_group_message(msg: OnGroupDataMessageArgs): async def main(): - service_client = WebPubSubServiceClient.from_connection_string( # type: ignore - connection_string=os.getenv("WEBPUBSUB_CONNECTION_STRING", ""), hub="hub" + credential = DefaultAzureCredential() + service_client = WebPubSubServiceClient( + endpoint=os.getenv("WEBPUBSUB_ENDPOINT", ""), hub="hub", credential=credential ) async def client_access_url_provider(): return (await service_client.get_client_access_token( diff --git a/sdk/webpubsub/azure-messaging-webpubsubclient/samples/hello_world_exceptions.py b/sdk/webpubsub/azure-messaging-webpubsubclient/samples/hello_world_exceptions.py index b9ca3cf3d648..778640e45b83 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubclient/samples/hello_world_exceptions.py +++ b/sdk/webpubsub/azure-messaging-webpubsubclient/samples/hello_world_exceptions.py @@ -7,6 +7,7 @@ import logging from azure.messaging.webpubsubclient import WebPubSubClient, WebPubSubClientCredential from azure.messaging.webpubsubservice import WebPubSubServiceClient +from azure.identity import DefaultAzureCredential from azure.messaging.webpubsubclient.models import OpenClientError, SendMessageError from dotenv import load_dotenv @@ -17,8 +18,8 @@ # The following code is to show how to handle exceptions in WebPubSubClient, and it # may not run directly def main(): - service_client = WebPubSubServiceClient.from_connection_string( # type: ignore - connection_string=os.getenv("WEBPUBSUB_CONNECTION_STRING", ""), hub="hub" + service_client = WebPubSubServiceClient( + endpoint=os.getenv("WEBPUBSUB_ENDPOINT", ""), hub="hub", credential=DefaultAzureCredential() ) client = WebPubSubClient( credential=WebPubSubClientCredential( diff --git a/sdk/webpubsub/azure-messaging-webpubsubclient/samples/send_compare_between_async_sync.py b/sdk/webpubsub/azure-messaging-webpubsubclient/samples/send_compare_between_async_sync.py index b8a2dd32f043..d681640af789 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubclient/samples/send_compare_between_async_sync.py +++ b/sdk/webpubsub/azure-messaging-webpubsubclient/samples/send_compare_between_async_sync.py @@ -13,6 +13,8 @@ from azure.messaging.webpubsubclient import WebPubSubClient as Client from azure.messaging.webpubsubclient import WebPubSubClientCredential from azure.messaging.webpubsubclient.models import WebPubSubDataType +from azure.identity import DefaultAzureCredential +from azure.identity.aio import DefaultAzureCredential as AsyncDefaultAzureCredential from dotenv import load_dotenv load_dotenv() @@ -23,16 +25,17 @@ def client_access_url_provider(): - service_client = WebPubSubServiceClient.from_connection_string( # type: ignore - connection_string=os.getenv("WEBPUBSUB_CONNECTION_STRING", ""), hub="hub" + service_client = WebPubSubServiceClient( + endpoint=os.getenv("WEBPUBSUB_ENDPOINT", ""), hub="hub", credential=DefaultAzureCredential() ) return service_client.get_client_access_token( roles=["webpubsub.joinLeaveGroup", "webpubsub.sendToGroup"] )["url"] async def client_access_url_provider_async(): - service_client_async = WebPubSubServiceClientAsync.from_connection_string( # type: ignore - connection_string=os.getenv("WEBPUBSUB_CONNECTION_STRING", ""), hub="hub" + credential = AsyncDefaultAzureCredential() + service_client_async = WebPubSubServiceClientAsync( + endpoint=os.getenv("WEBPUBSUB_ENDPOINT", ""), hub="hub", credential=credential ) return (await service_client_async.get_client_access_token( roles=["webpubsub.joinLeaveGroup", "webpubsub.sendToGroup"] @@ -81,7 +84,7 @@ async def send_async() -> None: if __name__ == "__main__": send() - asyncio.get_event_loop().run_until_complete(send_async()) + asyncio.run(send_async()) print( f"it takes {TIME_COST} seconds to send {MESSAGE_COUNT} messages with Sync API" ) diff --git a/sdk/webpubsub/azure-messaging-webpubsubclient/tests/conftest.py b/sdk/webpubsub/azure-messaging-webpubsubclient/tests/conftest.py index 9cc88c245ac6..fc3b351ea3ee 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubclient/tests/conftest.py +++ b/sdk/webpubsub/azure-messaging-webpubsubclient/tests/conftest.py @@ -24,16 +24,29 @@ # # -------------------------------------------------------------------------- import os +import re import pytest from dotenv import load_dotenv from devtools_testutils import test_proxy, add_general_regex_sanitizer +from testcase import TEST_RESULT +from testcase_async import TEST_RESULT_ASYNC load_dotenv() + +@pytest.fixture(autouse=True) +def clear_test_results(): + TEST_RESULT.clear() + TEST_RESULT_ASYNC.clear() + yield + TEST_RESULT.clear() + TEST_RESULT_ASYNC.clear() + + @pytest.fixture(scope="session", autouse=True) def add_sanitizers(test_proxy): - connection_string = os.environ.get("WEBPUBSUBCLIENT_CONNECTION_STRING", "WEBPUBSUBCLIENT_CONNECTION_STRING") + endpoint = os.environ.get("WEBPUBSUBCLIENT_ENDPOINT", "WEBPUBSUBCLIENT_ENDPOINT") add_general_regex_sanitizer( - regex=connection_string, - value="Endpoint=https://myservice.webpubsub.azure.com;AccessKey=aaaaaaaaaaaaa;Version=1.0;", + regex=re.escape(endpoint), + value="https://myservice.webpubsub.azure.com", ) diff --git a/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_auto_connect.py b/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_auto_connect.py index 180e011e8280..7d1942e42247 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_auto_connect.py +++ b/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_auto_connect.py @@ -4,10 +4,9 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # ------------------------------------------------------------------------- -import time import pytest from devtools_testutils import recorded_by_proxy -from testcase import WebpubsubClientTest, WebpubsubClientPowerShellPreparer, TEST_RESULT, on_group_message +from testcase import WebpubsubClientTest, WebpubsubClientPowerShellPreparer, TEST_RESULT from azure.messaging.webpubsubclient.models import WebPubSubProtocolType @@ -16,9 +15,9 @@ class TestWebpubsubClientAutoConnect(WebpubsubClientTest): # auto_connect will be triggered if connection is dropped by accident and we disable recovery @WebpubsubClientPowerShellPreparer() @recorded_by_proxy - def test_auto_connect(self, webpubsubclient_connection_string): + def test_auto_connect(self, webpubsubclient_endpoint): client = self.create_client( - connection_string=webpubsubclient_connection_string, + endpoint=webpubsubclient_endpoint, protocol_type=WebPubSubProtocolType.JSON, message_retry_total=10, reconnect_retry_total=10, @@ -26,16 +25,16 @@ def test_auto_connect(self, webpubsubclient_connection_string): reconnect_retry_backoff_factor=0.1, ) name = "test_auto_connect" + connected_event, _, message_event = self.setup_events(client) with client: - time.sleep(0.001) # wait for connection_id to be updated + assert connected_event.wait(timeout=30), "Timed out waiting for initial connection" conn_id0 = client._connection_id - group_name = name - client.subscribe("group-message", on_group_message) - client.join_group(group_name) + client.join_group(name) + connected_event.clear() # reset for reconnection detection client._ws.sock.close(1001) # close the connection to trigger auto connect - time.sleep(3) # wait for reconnect - client.send_to_group(group_name, name, "text") - time.sleep(1) # wait for on_group_message to be called + # wait for reconnect + assert connected_event.wait(timeout=30), "Timed out waiting for reconnection" + self.retry_send_until_message(client, name, name, message_event, retries=10) conn_id1 = client._connection_id assert conn_id0 is not None assert conn_id1 is not None diff --git a/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_auto_connect_async.py b/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_auto_connect_async.py index 2b43c979289e..6158be968d6e 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_auto_connect_async.py +++ b/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_auto_connect_async.py @@ -7,7 +7,7 @@ import asyncio import pytest from devtools_testutils.aio import recorded_by_proxy_async -from testcase_async import WebpubsubClientTestAsync, TEST_RESULT_ASYNC, on_group_message +from testcase_async import WebpubsubClientTestAsync, TEST_RESULT_ASYNC from testcase import WebpubsubClientPowerShellPreparer from azure.messaging.webpubsubclient.models import WebPubSubProtocolType @@ -16,9 +16,9 @@ class TestWebpubsubClientAutoConnectAsync(WebpubsubClientTestAsync): # auto_connect will be triggered if connection is dropped by accident and we disable recovery @WebpubsubClientPowerShellPreparer() @recorded_by_proxy_async - async def test_auto_connect_async(self, webpubsubclient_connection_string): + async def test_auto_connect_async(self, webpubsubclient_endpoint): client = await self.create_client( - connection_string=webpubsubclient_connection_string, + endpoint=webpubsubclient_endpoint, protocol_type=WebPubSubProtocolType.JSON, message_retry_total=10, reconnect_retry_total=10, @@ -26,18 +26,16 @@ async def test_auto_connect_async(self, webpubsubclient_connection_string): reconnect_retry_backoff_factor=0.1, ) name = "test_auto_connect_async" + connected_event, _, message_event = await self.setup_events(client) async with client: - await asyncio.sleep(0.001) # wait for connection_id to be updated + await asyncio.wait_for(connected_event.wait(), timeout=30) conn_id0 = client._connection_id - group_name = name - await client.subscribe("group-message", on_group_message) - await client.join_group(group_name) - await client._ws.sock.close( - code=1001 - ) # close the connection to trigger auto connect - await asyncio.sleep(3) # wait for reconnect - await client.send_to_group(group_name, name, "text") - await asyncio.sleep(1) # wait for on_group_message to be called + await client.join_group(name) + connected_event.clear() # reset for reconnection detection + await client._ws.sock.close(code=1001) # close the connection to trigger auto connect + # wait for reconnect + await asyncio.wait_for(connected_event.wait(), timeout=30) + await self.retry_send_until_message(client, name, name, message_event, retries=10) conn_id1 = client._connection_id assert conn_id0 is not None assert conn_id1 is not None diff --git a/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_no_recovery_no_connect.py b/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_no_recovery_no_connect.py index 2f5614277ee2..10b1821562d8 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_no_recovery_no_connect.py +++ b/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_no_recovery_no_connect.py @@ -25,21 +25,22 @@ class TestWebpubsubClientNoRecoveryNoReconnect(WebpubsubClientTest): # disable recovery and auto reconnect @WebpubsubClientPowerShellPreparer() @recorded_by_proxy - def test_disable_recovery_and_autoconnect(self, webpubsubclient_connection_string): + def test_disable_recovery_and_autoconnect(self, webpubsubclient_endpoint): client = self.create_client( - connection_string=webpubsubclient_connection_string, + endpoint=webpubsubclient_endpoint, reconnect_retry_total=0, protocol_type=WebPubSubProtocolType.JSON, ) name = "test_disable_recovery_and_autoconnect" with client: group_name = name - client.subscribe("group-message", on_group_message) + _, disconnected_event, _ = self.setup_events(client) client.join_group(group_name) client._ws.sock.close(1001) # close connection + assert disconnected_event.wait(timeout=30), "Timed out waiting for disconnection" with pytest.raises(SendMessageError): client.send_to_group(group_name, name, "text") - time.sleep(1) # wait for on_group_message to be called + time.sleep(3) # wait to confirm message was NOT received assert name not in TEST_RESULT @@ -47,10 +48,10 @@ def test_disable_recovery_and_autoconnect(self, webpubsubclient_connection_strin @WebpubsubClientPowerShellPreparer() @recorded_by_proxy def test_disable_recovery_and_autoconnect_send_concurrently( - self, webpubsubclient_connection_string + self, webpubsubclient_endpoint ): client = self.create_client( - connection_string=webpubsubclient_connection_string, + endpoint=webpubsubclient_endpoint, reconnect_retry_total=0, message_retry_total=3, protocol_type=WebPubSubProtocolType.JSON, @@ -58,7 +59,11 @@ def test_disable_recovery_and_autoconnect_send_concurrently( with client: group_name = "test_disable_recovery_and_autoconnect_send_concurrently" + _, disconnected_event, _ = self.setup_events(client) client.join_group(group_name) + client._ws.sock.close(1001) # close connection + assert disconnected_event.wait(timeout=30), "Timed out waiting for disconnection" + assert not client.is_connected() def send(idx): client.send_to_group(group_name, f"hello_{idx}", "text") @@ -68,10 +73,7 @@ def send(idx): t = SafeThread(target=send, args=(i,)) t.start() all_threads.append(t) - if i == 50: - client._ws.sock.close(1001) # close connection - for i, t in enumerate(all_threads): - if i > 50: - with pytest.raises(Exception): - t.join() + for t in all_threads: + with pytest.raises(SendMessageError): + t.join() diff --git a/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_no_recovery_no_connect_async.py b/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_no_recovery_no_connect_async.py index 4175598fa2ae..9fed3de74f86 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_no_recovery_no_connect_async.py +++ b/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_no_recovery_no_connect_async.py @@ -20,21 +20,22 @@ class TestWebpubsubClientNoRecoveryNoReconnectAsync(WebpubsubClientTestAsync): # disable recovery and auto reconnect @WebpubsubClientPowerShellPreparer() @recorded_by_proxy_async - async def test_disable_recovery_and_autoconnect_async(self, webpubsubclient_connection_string): + async def test_disable_recovery_and_autoconnect_async(self, webpubsubclient_endpoint): client = await self.create_client( - connection_string=webpubsubclient_connection_string, + endpoint=webpubsubclient_endpoint, reconnect_retry_total=0, protocol_type=WebPubSubProtocolType.JSON, ) name = "test_disable_recovery_and_autoconnect_async" async with client: group_name = name - await client.subscribe("group-message", on_group_message) + _, disconnected_event, _ = await self.setup_events(client) await client.join_group(group_name) await client._ws.session.close() # close connection + await asyncio.wait_for(disconnected_event.wait(), timeout=30) with pytest.raises(SendMessageError): await client.send_to_group(group_name, name, "text") - await asyncio.sleep(1) # wait for on_group_message to be called + await asyncio.sleep(3) # wait to confirm message was NOT received assert name not in TEST_RESULT_ASYNC @@ -42,10 +43,10 @@ async def test_disable_recovery_and_autoconnect_async(self, webpubsubclient_conn @WebpubsubClientPowerShellPreparer() @recorded_by_proxy_async async def test_disable_recovery_and_autoconnect_send_concurrently_async( - self, webpubsubclient_connection_string + self, webpubsubclient_endpoint ): client = await self.create_client( - connection_string=webpubsubclient_connection_string, + endpoint=webpubsubclient_endpoint, reconnect_retry_total=0, message_retry_total=3, protocol_type=WebPubSubProtocolType.JSON, @@ -53,10 +54,13 @@ async def test_disable_recovery_and_autoconnect_send_concurrently_async( async with client: group_name = "test_disable_recovery_and_autoconnect_send_concurrently_async" + _, disconnected_event, _ = await self.setup_events(client) await client.join_group(group_name) - count = 10 - tasks = [client.send_to_group(group_name, "hello", "text") for _ in range(10)] await client._ws.session.close() # close connection + await asyncio.wait_for(disconnected_event.wait(), timeout=30) + assert not client.is_connected() + + tasks = [client.send_to_group(group_name, "hello", "text") for _ in range(10)] for task in asyncio.as_completed(tasks): with pytest.raises(SendMessageError): await task diff --git a/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_recovery.py b/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_recovery.py index f6abea8cecf9..9ccaf053bb7d 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_recovery.py +++ b/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_recovery.py @@ -4,10 +4,9 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # ------------------------------------------------------------------------- -import time import pytest from devtools_testutils import recorded_by_proxy -from testcase import WebpubsubClientTest, WebpubsubClientPowerShellPreparer, TEST_RESULT, on_group_message +from testcase import WebpubsubClientTest, WebpubsubClientPowerShellPreparer, TEST_RESULT @pytest.mark.live_test_only @@ -15,19 +14,17 @@ class TestWebpubsubClientRecovery(WebpubsubClientTest): # recovery will be triggered if connection is dropped by accident @WebpubsubClientPowerShellPreparer() @recorded_by_proxy - def test_recovery(self, webpubsubclient_connection_string): - client = self.create_client(connection_string=webpubsubclient_connection_string, message_retry_total=10) + def test_recovery(self, webpubsubclient_endpoint): + client = self.create_client(endpoint=webpubsubclient_endpoint, message_retry_total=10) name = "test_recovery" + connected_event, _, message_event = self.setup_events(client) with client: - time.sleep(0.001) # wait for connection_id to be updated + assert connected_event.wait(timeout=30), "Timed out waiting for connection" conn_id0 = client._connection_id - group_name = name - client.subscribe("group-message", on_group_message) - client.join_group(group_name) + client.join_group(name) client._ws.sock.close(1001) # close connection to trigger recovery - client.send_to_group(group_name, name, "text") + self.retry_send_until_message(client, name, name, message_event) conn_id1 = client._connection_id - time.sleep(1) # wait for on_group_message to be called assert name in TEST_RESULT assert conn_id0 is not None diff --git a/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_recovery_async.py b/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_recovery_async.py index 591096e09e6c..218b612f8f9c 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_recovery_async.py +++ b/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_recovery_async.py @@ -8,7 +8,7 @@ import pytest from devtools_testutils.aio import recorded_by_proxy_async from testcase import WebpubsubClientPowerShellPreparer -from testcase_async import WebpubsubClientTestAsync, TEST_RESULT_ASYNC, on_group_message +from testcase_async import WebpubsubClientTestAsync, TEST_RESULT_ASYNC @pytest.mark.live_test_only @@ -16,19 +16,17 @@ class TestWebpubsubClientRecoveryAsync(WebpubsubClientTestAsync): # recovery will be triggered if connection is dropped by accident @WebpubsubClientPowerShellPreparer() @recorded_by_proxy_async - async def test_recovery_async(self, webpubsubclient_connection_string): - client = await self.create_client(connection_string=webpubsubclient_connection_string, message_retry_total=10) + async def test_recovery_async(self, webpubsubclient_endpoint): + client = await self.create_client(endpoint=webpubsubclient_endpoint, message_retry_total=10) name = "test_recovery_async" + connected_event, _, message_event = await self.setup_events(client) async with client: - await asyncio.sleep(0.001) # wait for connection_id to be updated + await asyncio.wait_for(connected_event.wait(), timeout=30) conn_id0 = client._connection_id - group_name = name - await client.subscribe("group-message", on_group_message) - await client.join_group(group_name) + await client.join_group(name) await client._ws.session.close() # close connection to trigger recovery - await client.send_to_group(group_name, name, "text") + await self.retry_send_until_message(client, name, name, message_event) conn_id1 = client._connection_id - await asyncio.sleep(1) # wait for on_group_message to be called assert name in TEST_RESULT_ASYNC assert conn_id0 is not None diff --git a/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_send_concurrently.py b/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_send_concurrently.py index f4f3ea9ad0df..ed5a688d62a5 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_send_concurrently.py +++ b/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_send_concurrently.py @@ -13,9 +13,11 @@ class TestWebpubsubClientSendConcurrently(WebpubsubClientTest): @WebpubsubClientPowerShellPreparer() @recorded_by_proxy - def test_send_concurrently(self, webpubsubclient_connection_string): - client = self.create_client(connection_string=webpubsubclient_connection_string) + def test_send_concurrently(self, webpubsubclient_endpoint): + client = self.create_client(endpoint=webpubsubclient_endpoint) + connected_event, _, _ = self.setup_events(client) with client: + assert connected_event.wait(timeout=30), "Timed out waiting for connection" group_name = "test_send_concurrently" client.join_group(group_name) diff --git a/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_send_concurrently_async.py b/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_send_concurrently_async.py index 905ac3df8b4d..dedc96e76de2 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_send_concurrently_async.py +++ b/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_send_concurrently_async.py @@ -15,9 +15,11 @@ class TestWebpubsubClientSendConcurrentlyAsync(WebpubsubClientTestAsync): @WebpubsubClientPowerShellPreparer() @recorded_by_proxy_async - async def test_send_concurrently_async(self, webpubsubclient_connection_string): - client = await self.create_client(connection_string=webpubsubclient_connection_string) + async def test_send_concurrently_async(self, webpubsubclient_endpoint): + client = await self.create_client(endpoint=webpubsubclient_endpoint) + connected_event, _, _ = await self.setup_events(client) async with client: + await asyncio.wait_for(connected_event.wait(), timeout=30) group_name = "test_send_concurrently_async" await client.join_group(group_name) await asyncio.gather(*[client.send_to_group(group_name, f"hello_{idx}", "text") for idx in range(100)]) diff --git a/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_smoke.py b/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_smoke.py index 94effcff964f..da0b3c842a72 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_smoke.py +++ b/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_smoke.py @@ -6,14 +6,15 @@ # ------------------------------------------------------------------------- from typing import List, Any import time +import threading import pytest from devtools_testutils import recorded_by_proxy from testcase import ( WebpubsubClientTest, WebpubsubClientPowerShellPreparer, - on_group_message, TEST_RESULT, ) +from azure.messaging.webpubsubclient import WebPubSubClient, WebPubSubClientCredential from azure.messaging.webpubsubclient.models import ( OnGroupDataMessageArgs, OpenClientError, @@ -25,12 +26,20 @@ class TestWebpubsubClientSmoke(WebpubsubClientTest): @WebpubsubClientPowerShellPreparer() @recorded_by_proxy - def test_call_back_deadlock(self, webpubsubclient_connection_string): - client = self.create_client(connection_string=webpubsubclient_connection_string) + def test_call_back_deadlock(self, webpubsubclient_endpoint): + client = self.create_client(endpoint=webpubsubclient_endpoint) group_name = "test_call_back_deadlock" + callback_completed = threading.Event() + callback_count = 0 + callback_count_lock = threading.Lock() def on_group_message(msg: OnGroupDataMessageArgs): + nonlocal callback_count client.send_to_group(group_name, msg.data, "text", no_echo=True) + with callback_count_lock: + callback_count += 1 + if callback_count >= 3: + callback_completed.set() with client: client.join_group(group_name) @@ -38,48 +47,73 @@ def on_group_message(msg: OnGroupDataMessageArgs): client.send_to_group(group_name, "hello test_call_back_deadlock1", "text") client.send_to_group(group_name, "hello test_call_back_deadlock2", "text") client.send_to_group(group_name, "hello test_call_back_deadlock3", "text") - # sleep to make sure the callback has enough time to execute before close - time.sleep(1) + assert callback_completed.wait(timeout=30), "Timed out waiting for callbacks to finish" @WebpubsubClientPowerShellPreparer() @recorded_by_proxy - def test_context_manager(self, webpubsubclient_connection_string): - client = self.create_client(connection_string=webpubsubclient_connection_string) + def test_context_manager(self, webpubsubclient_endpoint): + client = self.create_client(endpoint=webpubsubclient_endpoint) + _, _, message_event = self.setup_events(client) with client: group_name = "test_context_manager" client.join_group(group_name) client.send_to_group(group_name, "test_context_manager", "text") - time.sleep(2.0) + assert message_event.wait(timeout=30), "Timed out waiting for context manager message" assert client._sequence_id.sequence_id > 0 # test on_stop @WebpubsubClientPowerShellPreparer() @recorded_by_proxy - def test_on_stop(self, webpubsubclient_connection_string): - client = self.create_client(connection_string=webpubsubclient_connection_string) + def test_on_stop(self, webpubsubclient_endpoint): + client = self.create_client(endpoint=webpubsubclient_endpoint) + connected_event, disconnected_event, _ = self.setup_events(client) + reopen_error = None + reopen_complete = threading.Event() def on_stop(): - client.open() + nonlocal reopen_error + try: + # close() can race with immediate reopen, so retry briefly before failing. + for _ in range(10): + try: + client.open() + break + except OpenClientError: + time.sleep(1) + else: + raise RuntimeError("Failed to reopen client in stopped callback") + + if not connected_event.wait(timeout=30): + raise RuntimeError("Timed out waiting for client to reconnect in stopped callback") + assert client.is_connected() + except Exception as e: + reopen_error = e + finally: + reopen_complete.set() with client: # open client again after close client.subscribe("stopped", on_stop) - time.sleep(0.1) + assert connected_event.wait(timeout=30), "Timed out waiting for initial connection" assert client.is_connected() + connected_event.clear() client.close() - time.sleep(1.0) - assert client.is_connected() + # wait for on_stop callback to finish reopening + if not reopen_complete.wait(timeout=60): + pytest.fail("on_stop callback failed to complete within 60 seconds") + assert reopen_error is None, f"on_stop callback failed: {reopen_error}" # remove stopped event and close again client.unsubscribe("stopped", on_stop) + disconnected_event.clear() client.close() - time.sleep(1.0) + assert disconnected_event.wait(timeout=30), "Timed out waiting for client to disconnect" assert not client.is_connected() @WebpubsubClientPowerShellPreparer() @recorded_by_proxy - def test_duplicated_start(self, webpubsubclient_connection_string): - client = self.create_client(connection_string=webpubsubclient_connection_string) + def test_duplicated_start(self, webpubsubclient_endpoint): + client = self.create_client(endpoint=webpubsubclient_endpoint) with pytest.raises(OpenClientError): with client: client.open() @@ -87,16 +121,16 @@ def test_duplicated_start(self, webpubsubclient_connection_string): @WebpubsubClientPowerShellPreparer() @recorded_by_proxy - def test_duplicated_stop(self, webpubsubclient_connection_string): - client = self.create_client(connection_string=webpubsubclient_connection_string) + def test_duplicated_stop(self, webpubsubclient_endpoint): + client = self.create_client(endpoint=webpubsubclient_endpoint) with client: client.close() assert not client.is_connected() @WebpubsubClientPowerShellPreparer() @recorded_by_proxy - def test_send_event(self, webpubsubclient_connection_string): - client = self.create_client(connection_string=webpubsubclient_connection_string, message_retry_total=0) + def test_send_event(self, webpubsubclient_endpoint): + client = self.create_client(endpoint=webpubsubclient_endpoint, message_retry_total=0) with client: # please register event handler in azure portal before run this test try: @@ -106,22 +140,28 @@ def test_send_event(self, webpubsubclient_connection_string): @WebpubsubClientPowerShellPreparer() @recorded_by_proxy - def test_rejoin_group(self, webpubsubclient_connection_string): + def test_rejoin_group(self, webpubsubclient_endpoint): def _test(enable_auto_rejoin, test_group_name, assert_func): client = self.create_client( - connection_string=webpubsubclient_connection_string, + endpoint=webpubsubclient_endpoint, auto_rejoin_groups=enable_auto_rejoin, + message_retry_total=10, ) - group_name = test_group_name - client.subscribe("group-message", on_group_message) + connected_event, _, message_event = self.setup_events(client) with client: - client.join_group(group_name) + client.join_group(test_group_name) + connected_event.clear() + message_event.clear() with client: - time.sleep(1) # make sure rejoin group is called - client.send_to_group(group_name, group_name, "text") - time.sleep(1) # wait for on_group_message to be called - assert assert_func(test_group_name) + assert connected_event.wait(timeout=30), "Timed out waiting for connection" + if enable_auto_rejoin: + self.retry_send_until_message(client, test_group_name, test_group_name, message_event) + else: + client.send_to_group(test_group_name, test_group_name, "text") + # wait for on_group_message callback to fire + message_event.wait(timeout=10) + assert assert_func(test_group_name) _test( enable_auto_rejoin=True, @@ -137,8 +177,10 @@ def _test(enable_auto_rejoin, test_group_name, assert_func): @WebpubsubClientPowerShellPreparer() @recorded_by_proxy def test_open_client_error(self): - client = self.create_client( - connection_string="Endpoint=https://myservice.webpubsub.azure.com;AccessKey=aaaaaaaaaaaaa;Version=1.0;", + client = WebPubSubClient( + credential=WebPubSubClientCredential( + lambda: "wss://myservice.webpubsub.azure.com/client/hubs/Hub" + ), ) start_time = time.time() with pytest.raises(OpenClientError) as err: diff --git a/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_smoke_async.py b/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_smoke_async.py index cea2929c9fe7..dd31e14c3659 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_smoke_async.py +++ b/sdk/webpubsub/azure-messaging-webpubsubclient/tests/test_smoke_async.py @@ -11,9 +11,9 @@ from testcase import WebpubsubClientPowerShellPreparer from testcase_async import ( WebpubsubClientTestAsync, - on_group_message, TEST_RESULT_ASYNC, ) +from azure.messaging.webpubsubclient.aio import WebPubSubClient as AsyncWebPubSubClient, WebPubSubClientCredential as AsyncWebPubSubClientCredential from azure.messaging.webpubsubclient.models import ( OnGroupDataMessageArgs, OpenClientError, @@ -25,12 +25,18 @@ class TestWebpubsubClientSmokeAsync(WebpubsubClientTestAsync): @WebpubsubClientPowerShellPreparer() @recorded_by_proxy_async - async def test_call_back_deadlock_async(self, webpubsubclient_connection_string): - client = await self.create_client(connection_string=webpubsubclient_connection_string) + async def test_call_back_deadlock_async(self, webpubsubclient_endpoint): + client = await self.create_client(endpoint=webpubsubclient_endpoint) group_name = "test_call_back_deadlock_async" + callback_completed = asyncio.Event() + callback_count = 0 async def on_group_message(msg: OnGroupDataMessageArgs): + nonlocal callback_count await client.send_to_group(group_name, msg.data, "text", no_echo=True) + callback_count += 1 + if callback_count >= 3: + callback_completed.set() async with client: await client.join_group(group_name) @@ -38,48 +44,69 @@ async def on_group_message(msg: OnGroupDataMessageArgs): await client.send_to_group(group_name, "hello test_call_back_deadlock1", "text") await client.send_to_group(group_name, "hello test_call_back_deadlock2", "text") await client.send_to_group(group_name, "hello test_call_back_deadlock3", "text") - # sleep to make sure the callback has enough time to execute before close - await asyncio.sleep(1) + await asyncio.wait_for(callback_completed.wait(), timeout=30) @WebpubsubClientPowerShellPreparer() @recorded_by_proxy_async - async def test_context_manager_async(self, webpubsubclient_connection_string): - client = await self.create_client(connection_string=webpubsubclient_connection_string) + async def test_context_manager_async(self, webpubsubclient_endpoint): + client = await self.create_client(endpoint=webpubsubclient_endpoint) + _, _, message_event = await self.setup_events(client) async with client: group_name = "test_context_manager_async" await client.join_group(group_name) await client.send_to_group(group_name, "test_context_manager", "text") - await asyncio.sleep(2.0) + await asyncio.wait_for(message_event.wait(), timeout=30) assert client._sequence_id.sequence_id > 0 # test on_stop @WebpubsubClientPowerShellPreparer() @recorded_by_proxy_async - async def test_on_stop_async(self, webpubsubclient_connection_string): - client = await self.create_client(connection_string=webpubsubclient_connection_string) + async def test_on_stop_async(self, webpubsubclient_endpoint): + client = await self.create_client(endpoint=webpubsubclient_endpoint) + connected_event, disconnected_event, _ = await self.setup_events(client) + reopen_error = None + reopen_complete = asyncio.Event() async def on_stop(): - await client.open() + nonlocal reopen_error + try: + # close() can race with immediate reopen, so retry briefly before failing. + for _ in range(10): + try: + await client.open() + break + except OpenClientError: + await asyncio.sleep(1) + else: + raise RuntimeError("Failed to reopen client in stopped callback") + + await asyncio.wait_for(connected_event.wait(), timeout=30) + assert client.is_connected() + except Exception as e: + reopen_error = e + finally: + reopen_complete.set() async with client: # open client again after close await client.subscribe("stopped", on_stop) - await asyncio.sleep(0.1) + await asyncio.wait_for(connected_event.wait(), timeout=30) assert client.is_connected() + connected_event.clear() await client.close() - await asyncio.sleep(1.0) - assert client.is_connected() + # wait for on_stop callback to finish reopening + await asyncio.wait_for(reopen_complete.wait(), timeout=60) + assert reopen_error is None, f"on_stop callback failed: {reopen_error}" # remove stopped event and close again await client.unsubscribe("stopped", on_stop) await client.close() - await asyncio.sleep(1.0) assert not client.is_connected() @WebpubsubClientPowerShellPreparer() @recorded_by_proxy_async - async def test_duplicated_start_async(self, webpubsubclient_connection_string): - client = await self.create_client(connection_string=webpubsubclient_connection_string) + async def test_duplicated_start_async(self, webpubsubclient_endpoint): + client = await self.create_client(endpoint=webpubsubclient_endpoint) with pytest.raises(OpenClientError): async with client: await client.open() @@ -87,16 +114,16 @@ async def test_duplicated_start_async(self, webpubsubclient_connection_string): @WebpubsubClientPowerShellPreparer() @recorded_by_proxy_async - async def test_duplicated_stop_async(self, webpubsubclient_connection_string): - client = await self.create_client(connection_string=webpubsubclient_connection_string) + async def test_duplicated_stop_async(self, webpubsubclient_endpoint): + client = await self.create_client(endpoint=webpubsubclient_endpoint) async with client: await client.close() assert not client.is_connected() @WebpubsubClientPowerShellPreparer() @recorded_by_proxy_async - async def test_send_event_async(self, webpubsubclient_connection_string): - client = await self.create_client(connection_string=webpubsubclient_connection_string, message_retry_total=0) + async def test_send_event_async(self, webpubsubclient_endpoint): + client = await self.create_client(endpoint=webpubsubclient_endpoint, message_retry_total=0) async with client: # please register event handler in azure portal before run this test try: @@ -106,21 +133,29 @@ async def test_send_event_async(self, webpubsubclient_connection_string): @WebpubsubClientPowerShellPreparer() @recorded_by_proxy_async - async def test_rejoin_group_async(self, webpubsubclient_connection_string): + async def test_rejoin_group_async(self, webpubsubclient_endpoint): async def _test(enable_auto_rejoin, test_group_name, assert_func): client = await self.create_client( - connection_string=webpubsubclient_connection_string, + endpoint=webpubsubclient_endpoint, auto_rejoin_groups=enable_auto_rejoin, ) - group_name = test_group_name - await client.subscribe("group-message", on_group_message) + connected_event, _, message_event = await self.setup_events(client) async with client: - await client.join_group(group_name) + await client.join_group(test_group_name) + connected_event.clear() + message_event.clear() async with client: - await asyncio.sleep(1) # make sure rejoin group is called - await client.send_to_group(group_name, group_name, "text") - await asyncio.sleep(1) # wait for on_group_message to be called + await asyncio.wait_for(connected_event.wait(), timeout=30) + if enable_auto_rejoin: + await self.retry_send_until_message(client, test_group_name, test_group_name, message_event) + else: + await client.send_to_group(test_group_name, test_group_name, "text") + # wait for on_group_message callback to fire + try: + await asyncio.wait_for(message_event.wait(), timeout=10) + except asyncio.TimeoutError: + pass assert assert_func(test_group_name) await _test( @@ -137,8 +172,11 @@ async def _test(enable_auto_rejoin, test_group_name, assert_func): @WebpubsubClientPowerShellPreparer() @recorded_by_proxy_async async def test_open_client_error_async(self): - client = await self.create_client( - connection_string="Endpoint=https://myservice.webpubsub.azure.com;AccessKey=aaaaaaaaaaaaa;Version=1.0;", + async def _fake_url_provider(): + return "wss://myservice.webpubsub.azure.com/client/hubs/Hub" + + client = AsyncWebPubSubClient( + credential=AsyncWebPubSubClientCredential(_fake_url_provider), ) start_time = time.time() with pytest.raises(OpenClientError) as err: diff --git a/sdk/webpubsub/azure-messaging-webpubsubclient/tests/testcase.py b/sdk/webpubsub/azure-messaging-webpubsubclient/tests/testcase.py index 77f69f2e6d24..db014a195692 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubclient/tests/testcase.py +++ b/sdk/webpubsub/azure-messaging-webpubsubclient/tests/testcase.py @@ -6,32 +6,74 @@ # -------------------------------------------------------------------------- from typing import List import functools +import time import threading from devtools_testutils import AzureRecordedTestCase, PowerShellPreparer from azure.messaging.webpubsubclient import WebPubSubClient, WebPubSubClientCredential -from azure.messaging.webpubsubclient.models import OnGroupDataMessageArgs +from azure.messaging.webpubsubclient.models import OnGroupDataMessageArgs, SendMessageError from azure.messaging.webpubsubservice import WebPubSubServiceClient class WebpubsubClientTest(AzureRecordedTestCase): def create_client( self, - connection_string, + endpoint, hub: str = "Hub", roles: List[str] = ["webpubsub.joinLeaveGroup", "webpubsub.sendToGroup"], **kwargs, ): - service_client = WebPubSubServiceClient.from_connection_string(connection_string, hub) + credential = self.get_credential(WebPubSubServiceClient) + service_client = self.create_client_from_credential( + WebPubSubServiceClient, + credential=credential, + endpoint=endpoint, + hub=hub, + ) return WebPubSubClient( credential=WebPubSubClientCredential(lambda: service_client.get_client_access_token(roles=roles)["url"]), **kwargs, ) + @staticmethod + def setup_events(client): + """Subscribe connected/disconnected/group-message events and return their wait handles.""" + connected_event = threading.Event() + disconnected_event = threading.Event() + message_event = threading.Event() + + def _on_connected(*args, **kwargs): + connected_event.set() + + def _on_disconnected(*args, **kwargs): + disconnected_event.set() + + def _on_group_message(msg): + on_group_message(msg) + message_event.set() + + client.subscribe("connected", _on_connected) + client.subscribe("disconnected", _on_disconnected) + client.subscribe("group-message", _on_group_message) + return connected_event, disconnected_event, message_event + + @staticmethod + def retry_send_until_message(client, group_name, data, message_event, retries=30): + """Retry send_to_group until message_event fires, handling SendMessageError from rejoin lag.""" + for _ in range(retries): + try: + client.send_to_group(group_name, data, "text") + except SendMessageError: + time.sleep(1) + continue + if message_event.wait(timeout=2): + return + message_event.wait(timeout=2) + WebpubsubClientPowerShellPreparer = functools.partial( PowerShellPreparer, "webpubsubclient", - webpubsubclient_connection_string="Endpoint=https://myservice.webpubsub.azure.com;AccessKey=aaaaaaaaaaaaa;Version=1.0;", + webpubsubclient_endpoint="https://myservice.webpubsub.azure.com", ) TEST_RESULT = set() diff --git a/sdk/webpubsub/azure-messaging-webpubsubclient/tests/testcase_async.py b/sdk/webpubsub/azure-messaging-webpubsubclient/tests/testcase_async.py index c9836ccc2f5a..29af098eaf0c 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubclient/tests/testcase_async.py +++ b/sdk/webpubsub/azure-messaging-webpubsubclient/tests/testcase_async.py @@ -5,28 +5,77 @@ # license information. # -------------------------------------------------------------------------- from typing import List +import asyncio from devtools_testutils import AzureRecordedTestCase, PowerShellPreparer from azure.messaging.webpubsubclient.aio import WebPubSubClient, WebPubSubClientCredential -from azure.messaging.webpubsubclient.models import OnGroupDataMessageArgs +from azure.messaging.webpubsubclient.models import OnGroupDataMessageArgs, SendMessageError from azure.messaging.webpubsubservice.aio import WebPubSubServiceClient class WebpubsubClientTestAsync(AzureRecordedTestCase): async def create_client( self, - connection_string, + endpoint, hub: str = "Hub", roles: List[str] = ["webpubsub.joinLeaveGroup", "webpubsub.sendToGroup"], **kwargs, ): - service_client = WebPubSubServiceClient.from_connection_string(connection_string, hub) + credential = self.get_credential(WebPubSubServiceClient, is_async=True) async def client_access_url_provider(): - return (await service_client.get_client_access_token(roles=roles))["url"] + async with self.create_client_from_credential( + WebPubSubServiceClient, + credential=credential, + endpoint=endpoint, + hub=hub, + ) as service_client: + return (await service_client.get_client_access_token(roles=roles))["url"] return WebPubSubClient( credential=WebPubSubClientCredential(client_access_url_provider), **kwargs, ) + @staticmethod + async def setup_events(client): + """Subscribe connected/disconnected/group-message events and return their wait handles.""" + connected_event = asyncio.Event() + disconnected_event = asyncio.Event() + message_event = asyncio.Event() + + async def _on_connected(*args, **kwargs): + connected_event.set() + + async def _on_disconnected(*args, **kwargs): + disconnected_event.set() + + async def _on_group_message(msg): + await on_group_message(msg) + message_event.set() + + await client.subscribe("connected", _on_connected) + await client.subscribe("disconnected", _on_disconnected) + await client.subscribe("group-message", _on_group_message) + return connected_event, disconnected_event, message_event + + @staticmethod + async def retry_send_until_message(client, group_name, data, message_event, retries=30): + """Retry send_to_group until message_event fires, handling SendMessageError from rejoin lag.""" + for _ in range(retries): + try: + await client.send_to_group(group_name, data, "text") + except SendMessageError: + await asyncio.sleep(1) + continue + try: + await asyncio.wait_for(message_event.wait(), timeout=2) + return + except asyncio.TimeoutError: + pass + try: + await asyncio.wait_for(message_event.wait(), timeout=2) + except asyncio.TimeoutError: + pass + + TEST_RESULT_ASYNC = set() async def on_group_message(msg: OnGroupDataMessageArgs): diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/assets.json b/sdk/webpubsub/azure-messaging-webpubsubservice/assets.json index f0e9d9f02012..9d7bf5ac45a4 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/assets.json +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "python", "TagPrefix": "python/webpubsub/azure-messaging-webpubsubservice", - "Tag": "python/webpubsub/azure-messaging-webpubsubservice_447df314c8" + "Tag": "python/webpubsub/azure-messaging-webpubsubservice_752b7f1c61" } diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/get_client_access_token.py b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/get_client_access_token.py index a90cdd1b954c..573d07a91aeb 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/get_client_access_token.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/get_client_access_token.py @@ -35,26 +35,18 @@ LOG = logging.getLogger() # Set the values of the client ID, tenant ID, and client secret of the AAD application as environment variables: -# AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET, WEBPUBSUB_ENDPOINT, WEBPUBSUB_CONNECTION_STRING +# AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET, WEBPUBSUB_ENDPOINT try: endpoint = os.environ["WEBPUBSUB_ENDPOINT"] - connection_string = os.environ["WEBPUBSUB_CONNECTION_STRING"] except KeyError: LOG.error( - "Missing environment variable 'WEBPUBSUB_ENDPOINT' or 'WEBPUBSUB_CONNECTION_STRING' - please set if before running the example" + "Missing environment variable 'WEBPUBSUB_ENDPOINT' - please set it before running the example" ) exit() # Build a client through AAD -client_aad = WebPubSubServiceClient(endpoint=endpoint, hub="hub", credential=DefaultAzureCredential()) +client = WebPubSubServiceClient(endpoint=endpoint, hub="hub", credential=DefaultAzureCredential()) # Build authentication token -token_aad = client_aad.get_client_access_token() -print("token by AAD: {}".format(token_aad)) - -# Build a client through connection string -client_key = WebPubSubServiceClient.from_connection_string(connection_string, hub="hub") - -# Build authentication token -token_key = client_key.get_client_access_token() -print("token by access key: {}".format(token_key)) +token = client.get_client_access_token() +print("token by AAD: {}".format(token)) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/get_client_access_token_async.py b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/get_client_access_token_async.py index 0d032ea1f3df..2a1bb796f283 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/get_client_access_token_async.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/get_client_access_token_async.py @@ -38,28 +38,21 @@ async def main(): # Set the values of the client ID, tenant ID, and client secret of the AAD application as environment variables: - # AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET, WEBPUBSUB_ENDPOINT, WEBPUBSUB_CONNECTION_STRING + # AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET, WEBPUBSUB_ENDPOINT try: endpoint = os.environ["WEBPUBSUB_ENDPOINT"] - connection_string = os.environ["WEBPUBSUB_CONNECTION_STRING"] except KeyError: LOG.error( - "Missing environment variable 'WEBPUBSUB_ENDPOINT' or 'WEBPUBSUB_CONNECTION_STRING' - please set if before running the example" + "Missing environment variable 'WEBPUBSUB_ENDPOINT' - please set it before running the example" ) exit() # Build a client through AAD(async) async with DefaultAzureCredential() as credential: - async with WebPubSubServiceClientAsync(endpoint=endpoint, hub="hub", credential=credential) as client_aad_async: + async with WebPubSubServiceClientAsync(endpoint=endpoint, hub="hub", credential=credential) as client: # Build authentication token(async) - token_aad_async = await client_aad_async.get_client_access_token() - print("token by AAD(async): {}".format(token_aad_async)) - - # Build a client through connection string(async) - async with WebPubSubServiceClientAsync.from_connection_string(connection_string, hub="hub") as client_key_async: - # Build authentication token(async) - token_key_async = await client_key_async.get_client_access_token() - print("token by access key(async): {}".format(token_key_async)) + token = await client.get_client_access_token() + print("token by AAD(async): {}".format(token)) if __name__ == "__main__": diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/integration_sample.py b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/integration_sample.py index 44c1d80bfaa7..aeec6a8baf04 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/integration_sample.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/integration_sample.py @@ -12,6 +12,7 @@ from websocket import WebSocketApp from typing import List, Optional from azure.messaging.webpubsubservice import WebPubSubServiceClient +from azure.identity import DefaultAzureCredential logging.basicConfig(level=logging.DEBUG) LOG = logging.getLogger() @@ -62,10 +63,10 @@ def client_number(self): return len(self.clients) -def test_overall_integration(webpubsub_connection_string: str): - # build a service client from the connection string. - service = WebPubSubServiceClient.from_connection_string( - webpubsub_connection_string, hub="hub", logging_enable=False +def test_overall_integration(endpoint: str): + # build a service client through AAD. + service = WebPubSubServiceClient( + endpoint=endpoint, hub="hub", credential=DefaultAzureCredential(), logging_enable=False ) # build multiple websocket clients connected to the Web PubSub service @@ -114,11 +115,11 @@ def test_overall_integration(webpubsub_connection_string: str): if __name__ == "__main__": try: - connection_string = os.environ["WEBPUBSUB_CONNECTION_STRING"] + endpoint = os.environ["WEBPUBSUB_ENDPOINT"] except KeyError: LOG.error( - "Missing environment variable 'WEBPUBSUB_CONNECTION_STRING' - please set if before running the example" + "Missing environment variable 'WEBPUBSUB_ENDPOINT' - please set it before running the example" ) exit() - test_overall_integration(connection_string) + test_overall_integration(endpoint) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad.py b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad.py index 59e01d85bd32..4bd171ff6cbc 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad.py @@ -40,7 +40,7 @@ try: endpoint = os.environ["WEBPUBSUB_ENDPOINT"] except KeyError: - LOG.error("Missing environment variable 'WEBPUBSUB_ENDPOINT' - please set if before running the example") + LOG.error("Missing environment variable 'WEBPUBSUB_ENDPOINT' - please set it before running the example") exit() # Build a client through AAD diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad_apim_proxy.py b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad_apim_proxy.py index 876404e0a58a..7eac3bee49f4 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad_apim_proxy.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_aad_apim_proxy.py @@ -43,7 +43,7 @@ reverse_proxy_endpoint = os.environ["WEBPUBSUB_REVERSE_PROXY_ENDPOINT"] except KeyError: LOG.error( - "Missing environment variable 'WEBPUBSUB_ENDPOINT' or 'WEBPUBSUB_REVERSE_PROXY_ENDPOINT' - please set if before running the example" + "Missing environment variable 'WEBPUBSUB_ENDPOINT' or 'WEBPUBSUB_REVERSE_PROXY_ENDPOINT' - please set it before running the example" ) exit() diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_connection_string.py b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_connection_string.py index 69a2ca9a4bd8..48c7b8946d2f 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_connection_string.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_connection_string.py @@ -29,20 +29,21 @@ import os from azure.messaging.webpubsubservice import WebPubSubServiceClient +from azure.identity import DefaultAzureCredential from azure.core.exceptions import HttpResponseError logging.basicConfig(level=logging.DEBUG) LOG = logging.getLogger() try: - connection_string = os.environ["WEBPUBSUB_CONNECTION_STRING"] + endpoint = os.environ["WEBPUBSUB_ENDPOINT"] except KeyError: - LOG.error("Missing environment variable 'WEBPUBSUB_CONNECTION_STRING' - please set if before running the example") + LOG.error("Missing environment variable 'WEBPUBSUB_ENDPOINT' - please set it before running the example") exit() -# Build a client from the connection string. And for this example, we have enabled debug +# Build a client through AAD. And for this example, we have enabled debug # tracing. For production code, this should be turned off. -client = WebPubSubServiceClient.from_connection_string(connection_string, hub="hub", logging_enable=True) +client = WebPubSubServiceClient(endpoint=endpoint, hub="hub", credential=DefaultAzureCredential(), logging_enable=True) try: # Raise an exception if the service rejected the call diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_connection_string_apim_proxy.py b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_connection_string_apim_proxy.py index f8aaaf4e84ac..f26900f99772 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_connection_string_apim_proxy.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/samples/send_messages_connection_string_apim_proxy.py @@ -30,25 +30,26 @@ import os from azure.messaging.webpubsubservice import WebPubSubServiceClient +from azure.identity import DefaultAzureCredential from azure.core.exceptions import HttpResponseError logging.basicConfig(level=logging.DEBUG) LOG = logging.getLogger() try: - connection_string = os.environ["WEBPUBSUB_CONNECTION_STRING"] + endpoint = os.environ["WEBPUBSUB_ENDPOINT"] reverse_proxy_endpoint = os.environ["WEBPUBSUB_REVERSE_PROXY_ENDPOINT"] except KeyError: LOG.error( - "Missing environment variable 'WEBPUBSUB_CONNECTION_STRING' or 'WEBPUBSUB_REVERSE_PROXY_ENDPOINT' - please set if before running the example" + "Missing environment variable 'WEBPUBSUB_ENDPOINT' or 'WEBPUBSUB_REVERSE_PROXY_ENDPOINT' - please set it before running the example" ) exit() -# Build a client from the connection string. And for this example, we have enabled debug +# Build a client through AAD. And for this example, we have enabled debug # tracing. For production code, this should be turned off. # If you want to know more about the effect of `reverse_proxy_endpoint`, please reference: https://github.com/Azure/azure-webpubsub/issues/194 -client = WebPubSubServiceClient.from_connection_string( - connection_string, hub="hub", logging_enable=True, reverse_proxy_endpoint=reverse_proxy_endpoint +client = WebPubSubServiceClient( + endpoint=endpoint, hub="hub", credential=DefaultAzureCredential(), logging_enable=True, reverse_proxy_endpoint=reverse_proxy_endpoint ) try: diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_generated_api_coverage.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_generated_api_coverage.py index ad56d2c4b68b..184a1134584f 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_generated_api_coverage.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_generated_api_coverage.py @@ -20,8 +20,8 @@ class TestGeneratedApiCoverage(WebpubsubTest): @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_get_service_status(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_get_service_status(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") assert client.get_service_status() @WebpubsubPowerShellPreparer() @@ -39,28 +39,28 @@ def test_generate_client_token(self, webpubsub_endpoint, **kwargs): @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_close_all_connections(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_close_all_connections(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") client.close_all_connections(excluded=["fake-conn-1", "fake-conn-2"], reason="test") @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_add_connections_to_groups(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_add_connections_to_groups(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") client.add_connections_to_groups(groups_to_add={"filter": "userId eq 'nobody'", "groups": ["group1", "group2"]}) @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_remove_connections_from_groups(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_remove_connections_from_groups(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") client.remove_connections_from_groups( groups_to_remove={"filter": "userId eq 'nobody'", "groups": ["group1", "group2"]} ) @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_send_to_all_json(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_send_to_all_json(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") client.send_to_all( message={"hello": "world"}, content_type="application/json", @@ -70,20 +70,20 @@ def test_send_to_all_json(self, webpubsub_connection_string): @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_send_to_all_text(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_send_to_all_text(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") client.send_to_all(message="hello", content_type="text/plain") @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_send_to_all_binary(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_send_to_all_binary(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") client.send_to_all(message=b"hello", content_type="application/octet-stream") @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_send_to_group_json(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_send_to_group_json(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") client.send_to_group( group="group1", message={"hello": "world"}, @@ -94,20 +94,20 @@ def test_send_to_group_json(self, webpubsub_connection_string): @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_send_to_group_text(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_send_to_group_text(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") client.send_to_group(group="group1", message="hello", content_type="text/plain") @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_send_to_group_binary(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_send_to_group_binary(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") client.send_to_group(group="group1", message=b"hello", content_type="application/octet-stream") @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_send_to_user_json(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_send_to_user_json(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") client.send_to_user( user_id="user1", message={"hello": "world"}, @@ -117,20 +117,20 @@ def test_send_to_user_json(self, webpubsub_connection_string): @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_send_to_user_text(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_send_to_user_text(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") client.send_to_user(user_id="user1", message="hello", content_type="text/plain") @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_send_to_user_binary(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_send_to_user_binary(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") client.send_to_user(user_id="user1", message=b"hello", content_type="application/octet-stream") @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_send_to_connection_with_fake_connection_id(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_send_to_connection_with_fake_connection_id(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") client.send_to_connection( connection_id="fake-connection-id", message={"hello": "world"}, @@ -139,117 +139,117 @@ def test_send_to_connection_with_fake_connection_id(self, webpubsub_connection_s @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_close_connection_with_fake_connection_id(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_close_connection_with_fake_connection_id(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") client.close_connection(connection_id="fake-connection-id", reason="test") @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_add_connection_to_group_not_found(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_add_connection_to_group_not_found(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") with pytest.raises(ResourceNotFoundError): client.add_connection_to_group(group="group1", connection_id="fake-connection-id") @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_grant_permission_not_found(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_grant_permission_not_found(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") with pytest.raises(ResourceNotFoundError): client.grant_permission(permission="sendToGroup", connection_id="fake-connection-id", target_name="group1") @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_revoke_permission_with_fake_connection_id(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_revoke_permission_with_fake_connection_id(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") client.revoke_permission(permission="sendToGroup", connection_id="fake-connection-id", target_name="group1") @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_add_user_to_group_not_found(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_add_user_to_group_not_found(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") with pytest.raises(ResourceNotFoundError): client.add_user_to_group(group="group1", user_id="fake-user") @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_connection_exists(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_connection_exists(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") assert not client.connection_exists(connection_id="fake-connection-id") @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_user_exists(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_user_exists(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") assert not client.user_exists(user_id="fake-user") @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_group_exists(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_group_exists(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") assert not client.group_exists(group="fake-group") @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_check_permission(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_check_permission(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") assert not client.check_permission( permission="sendToGroup", connection_id="fake-connection-id", target_name="group1" ) @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_has_permission(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_has_permission(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") assert not client.has_permission( permission="sendToGroup", connection_id="fake-connection-id", target_name="group1" ) @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_remove_connection_from_all_groups(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_remove_connection_from_all_groups(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") client.remove_connection_from_all_groups(connection_id="fake-connection-id") @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_remove_user_from_all_groups(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_remove_user_from_all_groups(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") client.remove_user_from_all_groups(user_id="fake-user") @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_close_group_connections(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_close_group_connections(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") client.close_group_connections(group="group1", excluded=["fake-conn-1", "fake-conn-2"], reason="test") @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_close_user_connections(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_close_user_connections(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") client.close_user_connections(user_id="user1", excluded=["fake-conn-1", "fake-conn-2"], reason="test") @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_remove_user_from_group(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_remove_user_from_group(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") client.remove_user_from_group(group="group1", user_id="fake-user") @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_list_connections_in_group(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_list_connections_in_group(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") result = list(client.list_connections_in_group(group="group1", top=10)) assert isinstance(result, list) @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_list_connections(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_list_connections(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") result = list(client.list_connections(group="group1", top=10)) assert isinstance(result, list) @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_remove_connection_from_group(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + def test_remove_connection_from_group(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") client.remove_connection_from_group(group="group1", connection_id="fake-connection-id") diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_generated_api_coverage_async.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_generated_api_coverage_async.py index d9f24744d820..a41138d65efc 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_generated_api_coverage_async.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_generated_api_coverage_async.py @@ -21,8 +21,8 @@ class TestGeneratedApiCoverageAsync(WebpubsubAsyncTest): @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_get_service_status(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_get_service_status(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") assert await client.get_service_status() @WebpubsubPowerShellPreparer() @@ -40,30 +40,30 @@ async def test_generate_client_token(self, webpubsub_endpoint, **kwargs): @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_close_all_connections(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_close_all_connections(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") await client.close_all_connections(excluded=["fake-conn-1", "fake-conn-2"], reason="test") @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_add_connections_to_groups(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_add_connections_to_groups(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") await client.add_connections_to_groups( groups_to_add={"filter": "userId eq 'nobody'", "groups": ["group1", "group2"]} ) @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_remove_connections_from_groups(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_remove_connections_from_groups(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") await client.remove_connections_from_groups( groups_to_remove={"filter": "userId eq 'nobody'", "groups": ["group1", "group2"]} ) @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_send_to_all_json(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_send_to_all_json(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") await client.send_to_all( message={"hello": "world"}, content_type="application/json", @@ -73,20 +73,20 @@ async def test_send_to_all_json(self, webpubsub_connection_string): @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_send_to_all_text(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_send_to_all_text(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") await client.send_to_all(message="hello", content_type="text/plain") @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_send_to_all_binary(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_send_to_all_binary(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") await client.send_to_all(message=b"hello", content_type="application/octet-stream") @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_send_to_group_json(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_send_to_group_json(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") await client.send_to_group( group="group1", message={"hello": "world"}, @@ -97,20 +97,20 @@ async def test_send_to_group_json(self, webpubsub_connection_string): @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_send_to_group_text(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_send_to_group_text(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") await client.send_to_group(group="group1", message="hello", content_type="text/plain") @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_send_to_group_binary(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_send_to_group_binary(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") await client.send_to_group(group="group1", message=b"hello", content_type="application/octet-stream") @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_send_to_user_json(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_send_to_user_json(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") await client.send_to_user( user_id="user1", message={"hello": "world"}, @@ -120,20 +120,20 @@ async def test_send_to_user_json(self, webpubsub_connection_string): @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_send_to_user_text(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_send_to_user_text(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") await client.send_to_user(user_id="user1", message="hello", content_type="text/plain") @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_send_to_user_binary(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_send_to_user_binary(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") await client.send_to_user(user_id="user1", message=b"hello", content_type="application/octet-stream") @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_send_to_connection_with_fake_connection_id(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_send_to_connection_with_fake_connection_id(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") await client.send_to_connection( connection_id="fake-connection-id", message={"hello": "world"}, @@ -142,21 +142,21 @@ async def test_send_to_connection_with_fake_connection_id(self, webpubsub_connec @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_close_connection_with_fake_connection_id(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_close_connection_with_fake_connection_id(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") await client.close_connection(connection_id="fake-connection-id", reason="test") @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_add_connection_to_group_not_found(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_add_connection_to_group_not_found(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") with pytest.raises(ResourceNotFoundError): await client.add_connection_to_group(group="group1", connection_id="fake-connection-id") @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_grant_permission_not_found(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_grant_permission_not_found(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") with pytest.raises(ResourceNotFoundError): await client.grant_permission( permission="sendToGroup", connection_id="fake-connection-id", target_name="group1" @@ -164,99 +164,99 @@ async def test_grant_permission_not_found(self, webpubsub_connection_string): @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_revoke_permission_with_fake_connection_id(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_revoke_permission_with_fake_connection_id(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") await client.revoke_permission( permission="sendToGroup", connection_id="fake-connection-id", target_name="group1" ) @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_add_user_to_group_not_found(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_add_user_to_group_not_found(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") with pytest.raises(ResourceNotFoundError): await client.add_user_to_group(group="group1", user_id="fake-user") @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_connection_exists(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_connection_exists(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") assert not await client.connection_exists(connection_id="fake-connection-id") @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_user_exists(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_user_exists(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") assert not await client.user_exists(user_id="fake-user") @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_group_exists(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_group_exists(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") assert not await client.group_exists(group="fake-group") @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_check_permission(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_check_permission(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") assert not await client.check_permission( permission="sendToGroup", connection_id="fake-connection-id", target_name="group1" ) @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_has_permission(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_has_permission(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") assert not await client.has_permission( permission="sendToGroup", connection_id="fake-connection-id", target_name="group1" ) @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_remove_connection_from_all_groups(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_remove_connection_from_all_groups(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") await client.remove_connection_from_all_groups(connection_id="fake-connection-id") @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_remove_user_from_all_groups(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_remove_user_from_all_groups(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") await client.remove_user_from_all_groups(user_id="fake-user") @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_close_group_connections(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_close_group_connections(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") await client.close_group_connections(group="group1", excluded=["fake-conn-1", "fake-conn-2"], reason="test") @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_close_user_connections(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_close_user_connections(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") await client.close_user_connections(user_id="user1", excluded=["fake-conn-1", "fake-conn-2"], reason="test") @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_remove_user_from_group(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_remove_user_from_group(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") await client.remove_user_from_group(group="group1", user_id="fake-user") @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_list_connections_in_group(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_list_connections_in_group(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") result = [member async for member in client.list_connections_in_group(group="group1", top=10)] assert isinstance(result, list) @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_list_connections(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_list_connections(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") result = [member async for member in client.list_connections(group="group1", top=10)] assert isinstance(result, list) @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_remove_connection_from_group(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="apicoverage") + async def test_remove_connection_from_group(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="apicoverage") await client.remove_connection_from_group(group="group1", connection_id="fake-connection-id") diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_list_connections.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_list_connections.py index 64b28c84df4d..f900f2d4eabf 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_list_connections.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_list_connections.py @@ -5,6 +5,7 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # ------------------------------------------------------------------------- +import asyncio from websockets import connect as ws_connect from testcase import WebpubsubTest, WebpubsubPowerShellPreparer from devtools_testutils import recorded_by_proxy, set_custom_default_matcher @@ -22,7 +23,7 @@ def test_list_connections(self, **kwargs): asyncio.run(self._test_list_connections_impl(**kwargs)) async def _test_list_connections_impl(self, **kwargs): - webpubsub_connection_string = kwargs.get("webpubsub_connection_string") + webpubsub_endpoint = kwargs.get("webpubsub_endpoint") # Test cases with different pagination scenarios test_cases = [ {"total_connection_count": 6, "max_count_to_list": 6, "expected_total_count": 6, "expected_page_count": 1}, @@ -37,7 +38,7 @@ async def _test_list_connections_impl(self, **kwargs): ] for test_case in test_cases: - client = self.create_client(connection_string=webpubsub_connection_string, hub="test_list_connections") + client = self.create_client(endpoint=webpubsub_endpoint, hub="test_list_connections") group_name = "group1" ws_clients = [] @@ -50,6 +51,7 @@ async def _test_list_connections_impl(self, **kwargs): for _ in range(test_case["total_connection_count"]): ws = await ws_connect(client_url) ws_clients.append(ws) + await asyncio.sleep(3) # wait for server to register connections # List connections with pagination actual_page_count = 0 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_list_connections_async.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_list_connections_async.py index b36442647607..19358346116a 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_list_connections_async.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_list_connections_async.py @@ -4,6 +4,7 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # ------------------------------------------------------------------------- +import asyncio import pytest from websockets import connect as ws_connect from testcase import WebpubsubPowerShellPreparer @@ -17,7 +18,7 @@ class TestListConnectionsAsync(WebpubsubAsyncTest): @WebpubsubPowerShellPreparer() @recorded_by_proxy_async async def test_list_connections(self, **kwargs): - webpubsub_connection_string = kwargs.get("webpubsub_connection_string") + webpubsub_endpoint = kwargs.get("webpubsub_endpoint") # Test cases with different pagination scenarios test_cases = [ {"total_connection_count": 6, "max_count_to_list": 6, "expected_total_count": 6, "expected_page_count": 1}, @@ -32,7 +33,7 @@ async def test_list_connections(self, **kwargs): ] for test_case in test_cases: - client = self.create_client(connection_string=webpubsub_connection_string, hub="test_list_connections") + client = self.create_client(endpoint=webpubsub_endpoint, hub="test_list_connections") async with client: group_name = "group1" ws_clients = [] @@ -46,6 +47,7 @@ async def test_list_connections(self, **kwargs): for _ in range(test_case["total_connection_count"]): ws = await ws_connect(client_url) ws_clients.append(ws) + await asyncio.sleep(3) # wait for server to register connections # List connections with pagination actual_page_count = 0 diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_live_api_coverage.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_live_api_coverage.py index 2540e9a29658..7afc3d29ac56 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_live_api_coverage.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_live_api_coverage.py @@ -17,7 +17,7 @@ @pytest.mark.live_test_only class TestLiveApiCoverage(WebpubsubTest): def _find_connection_id(self, client, group_name, user_id): - for _ in range(10): + for _ in range(30): members = list(client.list_connections(group=group_name, top=20)) for member in members: if member.user_id == user_id and member.connection_id: @@ -25,13 +25,20 @@ def _find_connection_id(self, client, group_name, user_id): time.sleep(1) return None + def _wait_for_connection_removed(self, client, connection_id): + for _ in range(30): + if not client.connection_exists(connection_id=connection_id): + return + time.sleep(1) + pytest.fail(f"Timed out waiting for connection {connection_id} to be removed") + @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_live_api_coverage_all_apis_and_parameters(self, webpubsub_endpoint, webpubsub_connection_string): + def test_live_api_coverage_all_apis_and_parameters(self, webpubsub_endpoint, webpubsub_socketio_endpoint): if not getattr(self, "is_live", False): pytest.skip("Live WebSocket coverage test is skipped in playback mode") - client = self.create_client(connection_string=webpubsub_connection_string, hub="hub") + client = self.create_client(endpoint=webpubsub_endpoint, hub="hub") aad_client = self.create_client(endpoint=webpubsub_endpoint, hub="hub") user_id = "live-user-1" @@ -55,7 +62,8 @@ def test_live_api_coverage_all_apis_and_parameters(self, webpubsub_endpoint, web assert "webpubsub.joinLeaveGroup" in decoded["role"] assert group_1 in decoded["webpubsub.group"] - socketio_token = client.get_client_access_token(user_id=user_id, groups=[group_1], client_protocol="SocketIO") + socketio_client = self.create_client(endpoint=webpubsub_socketio_endpoint, hub="hub") + socketio_token = socketio_client.get_client_access_token(user_id=user_id, groups=[group_1], client_protocol="SocketIO") assert socketio_token["token"] generated_token = aad_client.generate_client_token( @@ -69,7 +77,7 @@ def test_live_api_coverage_all_apis_and_parameters(self, webpubsub_endpoint, web ws = None try: - ws = ws_connect(access_token["url"]) + ws = ws_connect(access_token["url"], open_timeout=30) assert client.get_service_status() @@ -164,31 +172,36 @@ def test_live_api_coverage_all_apis_and_parameters(self, webpubsub_endpoint, web # close_group_connections (connection auto-joins group_1 via token) ws.close() - ws = ws_connect(access_token["url"]) + self._wait_for_connection_removed(client, connection_id) + ws = ws_connect(access_token["url"], open_timeout=30) conn = self._find_connection_id(client, group_1, user_id) assert conn is not None client.close_group_connections(group=group_1, reason="live-coverage") + self._wait_for_connection_removed(client, conn) assert not client.connection_exists(connection_id=conn) # close_user_connections - ws = ws_connect(access_token["url"]) + ws = ws_connect(access_token["url"], open_timeout=30) conn = self._find_connection_id(client, group_1, user_id) assert conn is not None client.close_user_connections(user_id=user_id, reason="live-coverage") + self._wait_for_connection_removed(client, conn) assert not client.connection_exists(connection_id=conn) # close_connection - ws = ws_connect(access_token["url"]) + ws = ws_connect(access_token["url"], open_timeout=30) conn = self._find_connection_id(client, group_1, user_id) assert conn is not None client.close_connection(connection_id=conn, reason="live-coverage") + self._wait_for_connection_removed(client, conn) assert not client.connection_exists(connection_id=conn) # close_all_connections - ws = ws_connect(access_token["url"]) + ws = ws_connect(access_token["url"], open_timeout=30) conn = self._find_connection_id(client, group_1, user_id) assert conn is not None client.close_all_connections(reason="live-coverage") + self._wait_for_connection_removed(client, conn) assert not client.connection_exists(connection_id=conn) ws = None diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_live_api_coverage_async.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_live_api_coverage_async.py index 978de6645cd6..92d0125850df 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_live_api_coverage_async.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_live_api_coverage_async.py @@ -19,7 +19,7 @@ @pytest.mark.asyncio class TestLiveApiCoverageAsync(WebpubsubAsyncTest): async def _find_connection_id(self, client, group_name, user_id): - for _ in range(10): + for _ in range(30): members = [member async for member in client.list_connections(group=group_name, top=20)] for member in members: if member.user_id == user_id and member.connection_id: @@ -27,15 +27,22 @@ async def _find_connection_id(self, client, group_name, user_id): await asyncio.sleep(1) return None + async def _wait_for_connection_removed(self, client, connection_id): + for _ in range(30): + if not await client.connection_exists(connection_id=connection_id): + return + await asyncio.sleep(1) + pytest.fail(f"Timed out waiting for connection {connection_id} to be removed") + @WebpubsubPowerShellPreparer() @recorded_by_proxy_async async def test_live_api_coverage_all_apis_and_parameters_async( - self, webpubsub_endpoint, webpubsub_connection_string + self, webpubsub_endpoint, webpubsub_socketio_endpoint ): if not getattr(self, "is_live", False): pytest.skip("Live WebSocket coverage test is skipped in playback mode") - client = self.create_client(connection_string=webpubsub_connection_string, hub="hub") + client = self.create_client(endpoint=webpubsub_endpoint, hub="hub") aad_client = self.create_client(endpoint=webpubsub_endpoint, hub="hub") user_id = "live-user-1" @@ -60,11 +67,13 @@ async def test_live_api_coverage_all_apis_and_parameters_async( assert "webpubsub.joinLeaveGroup" in decoded["role"] assert group_1 in decoded["webpubsub.group"] - socketio_token = await client.get_client_access_token( - user_id=user_id, - groups=[group_1], - client_protocol="SocketIO", - ) + socketio_client = self.create_client(endpoint=webpubsub_socketio_endpoint, hub="hub") + async with socketio_client: + socketio_token = await socketio_client.get_client_access_token( + user_id=user_id, + groups=[group_1], + client_protocol="SocketIO", + ) assert socketio_token["token"] generated_token = await aad_client.generate_client_token( @@ -193,31 +202,36 @@ async def test_live_api_coverage_all_apis_and_parameters_async( # close_group_connections (connection auto-joins group_1 via token) await ws.close() - ws = await ws_connect(access_token["url"]) + await self._wait_for_connection_removed(client, connection_id) + ws = await ws_connect(access_token["url"], open_timeout=30) conn = await self._find_connection_id(client, group_1, user_id) assert conn is not None await client.close_group_connections(group=group_1, reason="live-coverage") + await self._wait_for_connection_removed(client, conn) assert not await client.connection_exists(connection_id=conn) # close_user_connections - ws = await ws_connect(access_token["url"]) + ws = await ws_connect(access_token["url"], open_timeout=30) conn = await self._find_connection_id(client, group_1, user_id) assert conn is not None await client.close_user_connections(user_id=user_id, reason="live-coverage") + await self._wait_for_connection_removed(client, conn) assert not await client.connection_exists(connection_id=conn) # close_connection - ws = await ws_connect(access_token["url"]) + ws = await ws_connect(access_token["url"], open_timeout=30) conn = await self._find_connection_id(client, group_1, user_id) assert conn is not None await client.close_connection(connection_id=conn, reason="live-coverage") + await self._wait_for_connection_removed(client, conn) assert not await client.connection_exists(connection_id=conn) # close_all_connections - ws = await ws_connect(access_token["url"]) + ws = await ws_connect(access_token["url"], open_timeout=30) conn = await self._find_connection_id(client, group_1, user_id) assert conn is not None await client.close_all_connections(reason="live-coverage") + await self._wait_for_connection_removed(client, conn) assert not await client.connection_exists(connection_id=conn) ws = None diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_reverse_proxy.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_reverse_proxy.py index e373804ba7a3..f68d9a89faad 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_reverse_proxy.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_reverse_proxy.py @@ -53,9 +53,9 @@ def _callback(pipeline_request): @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_reverse_proxy_call(self, webpubsub_connection_string, webpubsub_reverse_proxy_endpoint): + def test_reverse_proxy_call(self, webpubsub_endpoint, webpubsub_reverse_proxy_endpoint): client = self.create_client( - connection_string=webpubsub_connection_string, + endpoint=webpubsub_endpoint, hub="hub", logging_enable=True, reverse_proxy_endpoint=webpubsub_reverse_proxy_endpoint, diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_reverse_proxy_async.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_reverse_proxy_async.py index 7ef02f256ecc..b65c6791b97f 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_reverse_proxy_async.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_reverse_proxy_async.py @@ -59,9 +59,9 @@ def _callback(pipeline_request): @pytest.mark.asyncio @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_reverse_proxy_call(self, webpubsub_connection_string, webpubsub_reverse_proxy_endpoint): + async def test_reverse_proxy_call(self, webpubsub_endpoint, webpubsub_reverse_proxy_endpoint): client = self.create_client( - connection_string=webpubsub_connection_string, + endpoint=webpubsub_endpoint, hub="hub", logging_enable=True, reverse_proxy_endpoint=webpubsub_reverse_proxy_endpoint, diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py index e876bb201947..fd733a26fd4d 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke.py @@ -70,43 +70,43 @@ def test_get_client_access_token(self, webpubsub_endpoint): @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_hello_world_with_connection_string(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="hub") + def test_hello_world(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="hub") client.send_to_all(message="Hello, World!", content_type="text/plain") @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_hello_world_with_connection_string_json(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="hub") + def test_hello_world_json(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="hub") client.send_to_all(message={"hello": "world!"}) @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_hello_world_with_connection_string_binary(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="hub") + def test_hello_world_binary(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="hub") client.send_to_all(message=b"Hello, World!", content_type="application/octet-stream") @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_no_users_groups(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="hub") + def test_no_users_groups(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="hub") assert not client.user_exists(user_id="fake user") assert not client.group_exists(group="fake group") @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_remove_connection_from_all_groups(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="hub") + def test_remove_connection_from_all_groups(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="hub") client.remove_connection_from_all_groups(connection_id="fake connection id") @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_send_with_filter(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="hub") + def test_send_with_filter(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="hub") client.send_to_all(message={"hello": "world!"}, filter="userId ne 'user1'", content_type="text/plain") @WebpubsubPowerShellPreparer() @recorded_by_proxy - def test_get_client_access_key_with_groups(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="hub") + def test_get_client_access_key_with_groups(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="hub") client.get_client_access_token(user_id="user1", groups=["groups1"]) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke_async.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke_async.py index 84e70c05a288..7ee810cd1d73 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke_async.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/test_smoke_async.py @@ -38,43 +38,43 @@ async def test_get_client_access_token(self, webpubsub_endpoint): @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_hello_world_with_connection_string(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="hub") + async def test_hello_world(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="hub") await client.send_to_all(message="Hello, World!", content_type="text/plain") @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_hello_world_with_connection_string_json(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="hub") + async def test_hello_world_json(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="hub") await client.send_to_all(message={"hello": "world!"}) @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_hello_world_with_connection_string_binary(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="hub") + async def test_hello_world_binary(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="hub") await client.send_to_all(message=b"Hello, World!", content_type="application/octet-stream") @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_no_users_groups(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="hub") + async def test_no_users_groups(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="hub") assert not await client.user_exists(user_id="fake user") assert not await client.group_exists(group="fake group") @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_remove_connection_from_all_groups(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="hub") + async def test_remove_connection_from_all_groups(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="hub") await client.remove_connection_from_all_groups(connection_id="fake connection id") @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_send_with_filter(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="hub") + async def test_send_with_filter(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="hub") await client.send_to_all(message={"hello": "world!"}, filter="userId ne 'user1'", content_type="text/plain") @WebpubsubPowerShellPreparer() @recorded_by_proxy_async - async def test_get_client_access_key_with_groups(self, webpubsub_connection_string): - client = self.create_client(connection_string=webpubsub_connection_string, hub="hub") + async def test_get_client_access_key_with_groups(self, webpubsub_endpoint): + client = self.create_client(endpoint=webpubsub_endpoint, hub="hub") await client.get_client_access_token(user_id="user1", groups=["groups1"]) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/testcase.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/testcase.py index 4a319cf1dbd8..a21176bd3770 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/testcase.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/testcase.py @@ -11,8 +11,6 @@ class WebpubsubTest(AzureRecordedTestCase): def create_client(self, endpoint=None, hub=None, reverse_proxy_endpoint=None, **kwargs): - if kwargs.get("connection_string"): - return WebPubSubServiceClient.from_connection_string(kwargs.pop("connection_string"), hub, **kwargs) credential = self.get_credential(WebPubSubServiceClient) return self.create_client_from_credential( WebPubSubServiceClient, @@ -28,5 +26,5 @@ def create_client(self, endpoint=None, hub=None, reverse_proxy_endpoint=None, ** "webpubsub", webpubsub_endpoint="https://myservice.webpubsub.azure.com", webpubsub_reverse_proxy_endpoint="https://myservice.webpubsub.azure.com", - webpubsub_connection_string="Endpoint=https://myservice.webpubsub.azure.com;AccessKey=aaaaaaaaaaaaa;Version=1.0;", + webpubsub_socketio_endpoint="https://myservice-socketio.webpubsub.azure.com", ) diff --git a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/testcase_async.py b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/testcase_async.py index 538211460604..6d65abb16482 100644 --- a/sdk/webpubsub/azure-messaging-webpubsubservice/tests/testcase_async.py +++ b/sdk/webpubsub/azure-messaging-webpubsubservice/tests/testcase_async.py @@ -10,8 +10,6 @@ class WebpubsubAsyncTest(AzureRecordedTestCase): def create_client(self, endpoint=None, hub=None, reverse_proxy_endpoint=None, **kwargs): - if kwargs.get("connection_string"): - return WebPubSubServiceClient.from_connection_string(kwargs.pop("connection_string"), hub, **kwargs) credential = self.get_credential(WebPubSubServiceClient, is_async=True) return self.create_client_from_credential( WebPubSubServiceClient, diff --git a/sdk/webpubsub/azure-mgmt-webpubsub/dev_requirements.txt b/sdk/webpubsub/azure-mgmt-webpubsub/dev_requirements.txt index 21cc05c69feb..a248c967d56c 100644 --- a/sdk/webpubsub/azure-mgmt-webpubsub/dev_requirements.txt +++ b/sdk/webpubsub/azure-mgmt-webpubsub/dev_requirements.txt @@ -1,3 +1,4 @@ -e ../../../eng/tools/azure-sdk-tools ../../identity/azure-identity +../../resources/azure-mgmt-resource aiohttp \ No newline at end of file diff --git a/sdk/webpubsub/test-resources.bicep b/sdk/webpubsub/test-resources.bicep new file mode 100644 index 000000000000..abcc8c7762d5 --- /dev/null +++ b/sdk/webpubsub/test-resources.bicep @@ -0,0 +1,68 @@ +param baseName string = resourceGroup().name +param testApplicationOid string +param location string = resourceGroup().location +param supportsSafeSecretStandard bool = false + +var webpubsubName = 'e2e-${baseName}' +var socketioName = 'e2e-socketio-${baseName}' +// Web PubSub Service Owner +var ownerRoleId = '12cf5a90-567b-43ae-8102-96cf46c7d9b4' + +resource webPubSubSocketIO 'Microsoft.SignalRService/webPubSub@2024-10-01-preview' = { + name: socketioName + location: location + kind: 'SocketIO' + sku: { + name: 'Standard_S1' + tier: 'Standard' + capacity: 1 + } + properties: { + tls: { + clientCertEnabled: false + } + disableLocalAuth: supportsSafeSecretStandard + } +} + +resource webPubSub 'Microsoft.SignalRService/webPubSub@2024-10-01-preview' = { + name: webpubsubName + location: location + kind: 'WebPubSub' + sku: { + name: 'Standard_S1' + tier: 'Standard' + capacity: 1 + } + properties: { + tls: { + clientCertEnabled: false + } + disableLocalAuth: supportsSafeSecretStandard + } +} + +resource ownerRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid('ownerRoleId', webPubSub.id, testApplicationOid) + scope: webPubSub + properties: { + roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', ownerRoleId) + principalId: testApplicationOid + } +} + +resource socketIOOwnerRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid('ownerRoleId', webPubSubSocketIO.id, testApplicationOid) + scope: webPubSubSocketIO + properties: { + roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', ownerRoleId) + principalId: testApplicationOid + } +} + +output AZURE_SUBSCRIPTION_ID string = subscription().subscriptionId +output AZURE_RESOURCE_GROUP string = resourceGroup().name +output WEBPUBSUB_ENDPOINT string = 'https://${webPubSub.properties.hostName}' +output WEBPUBSUB_REVERSE_PROXY_ENDPOINT string = 'https://${webPubSub.properties.hostName}' +output WEBPUBSUBCLIENT_ENDPOINT string = 'https://${webPubSub.properties.hostName}' +output WEBPUBSUB_SOCKETIO_ENDPOINT string = 'https://${webPubSubSocketIO.properties.hostName}' diff --git a/sdk/webpubsub/tests.yml b/sdk/webpubsub/tests.yml index e0c2f37352d1..7a03ef94410d 100644 --- a/sdk/webpubsub/tests.yml +++ b/sdk/webpubsub/tests.yml @@ -8,8 +8,4 @@ extends: MatrixReplace: - TestSamples=.*/true EnvVars: - WEBPUBSUB_REVERSE_PROXY_ENDPOINT: $(webpubsub-reverse-proxy-endpoint) - WEBPUBSUB_ENDPOINT: $(webpubsub-endpoint) - WEBPUBSUB_CONNECTION_STRING: $(webpubsub-connection-string) - TEST_MODE: "RunLiveNoRecord" # use when allowing preparers to create the rgs for you AZURE_TEST_RUN_LIVE: "true" # use when utilizing the New-TestResources Script