From 33d5bfd5310aecae40ad44702d5148af6c7161cd Mon Sep 17 00:00:00 2001 From: Bill Peck Date: Mon, 24 Jun 2024 14:36:45 -0400 Subject: [PATCH] uamqp is no longer supported The uamqp package is no longer being maitained and fails to build on arm architectures. --- setup.py | 1 - src/azure/iot/hub/constant.py | 2 +- src/azure/iot/hub/iothub_amqp_client.py | 115 -------- src/azure/iot/hub/iothub_registry_manager.py | 29 -- tests/test_iothub_amqp_client.py | 287 ------------------- tests/test_iothub_registry_manager.py | 86 ------ 6 files changed, 1 insertion(+), 519 deletions(-) delete mode 100644 src/azure/iot/hub/iothub_amqp_client.py delete mode 100644 tests/test_iothub_amqp_client.py diff --git a/setup.py b/setup.py index cd0559c..034e98a 100644 --- a/setup.py +++ b/setup.py @@ -77,7 +77,6 @@ install_requires=[ "msrest>=0.6.21,<1.0.0", # NOTE: Python 2.7, 3.5 support dropped >= 1.4.0 - "uamqp>=1.2.14,<2.0.0", "azure-core>=1.10.0,<2.0.0", ], python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4", diff --git a/src/azure/iot/hub/constant.py b/src/azure/iot/hub/constant.py index fe88db4..00ce90b 100644 --- a/src/azure/iot/hub/constant.py +++ b/src/azure/iot/hub/constant.py @@ -6,4 +6,4 @@ """This module defines constants for use across the azure-iot-hub package """ -VERSION = "2.6.1" +VERSION = "2.7.0" diff --git a/src/azure/iot/hub/iothub_amqp_client.py b/src/azure/iot/hub/iothub_amqp_client.py deleted file mode 100644 index cd85b25..0000000 --- a/src/azure/iot/hub/iothub_amqp_client.py +++ /dev/null @@ -1,115 +0,0 @@ -# ------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- - -import base64 -import time -import hashlib -import hmac -from uuid import uuid4 -import six.moves.urllib as urllib -from azure.core.credentials import AccessToken -import uamqp - - -default_sas_expiry = 3600 - - -class IoTHubAmqpClientBase: - def disconnect_sync(self): - """ - Disconnect the Amqp client. - """ - if self.amqp_client: - self.amqp_client.close() - self.amqp_client = None - - def send_message_to_device(self, device_id, message, app_props): - """Send a message to the specified deivce. - - :param str device_id: The name (Id) of the device. - :param str message: The message that is to be delivered to the device. - :param dict app_props: Application and system properties for the message - - :raises: Exception if the Send command is not able to send the message - """ - msg_content = message - msg_props = uamqp.message.MessageProperties() - msg_props.message_id = str(uuid4()) - msg_props.to = "/devices/{}/messages/devicebound".format(device_id) - - app_properties = {} - - # loop through all properties and pull out the custom - # properties - for prop_key, prop_value in app_props.items(): - if prop_key == "contentType": - msg_props.content_type = prop_value - elif prop_key == "contentEncoding": - msg_props.content_encoding = prop_value - elif prop_key == "correlationId": - msg_props.correlation_id = prop_value - elif prop_key == "expiryTimeUtc": - msg_props.absolute_expiry_time = prop_value - elif prop_key == "messageId": - msg_props.message_id = prop_value - else: - app_properties[prop_key] = prop_value - - message = uamqp.Message( - msg_content, properties=msg_props, application_properties=app_properties - ) - self.amqp_client.queue_message(message) - results = self.amqp_client.send_all_messages(close_on_done=False) - if uamqp.constants.MessageState.SendFailed in results: - raise Exception("C2D message send failure") - - -class IoTHubAmqpClientSharedAccessKeyAuth(IoTHubAmqpClientBase): - def __init__(self, hostname, shared_access_key_name, shared_access_key): - def get_token(): - expiry = int(time.time() + default_sas_expiry) - sas = base64.b64decode(shared_access_key) - string_to_sign = (hostname + "\n" + str(expiry)).encode("utf-8") - signed_hmac_sha256 = hmac.HMAC(sas, string_to_sign, hashlib.sha256) - signature = urllib.parse.quote(base64.b64encode(signed_hmac_sha256.digest())) - return AccessToken( - "SharedAccessSignature sr={}&sig={}&se={}&skn={}".format( - hostname, signature, expiry, shared_access_key_name - ), - expiry, - ) - - auth = uamqp.authentication.JWTTokenAuth( - audience="https://" + hostname, - uri="https://" + hostname, - get_token=get_token, - token_type=b"servicebus.windows.net:sastoken", - ) - auth.update_token() - self.amqp_client = uamqp.SendClient( - target="amqps://" + hostname + "/messages/devicebound", - auth=auth, - keep_alive_interval=120, - ) - - -class IoTHubAmqpClientTokenAuth(IoTHubAmqpClientBase): - def __init__( - self, hostname, token_credential, token_scope="https://iothubs.azure.net/.default" - ): - def get_token(): - result = token_credential.get_token(token_scope) - return AccessToken("Bearer " + result.token, result.expires_on) - - auth = uamqp.authentication.JWTTokenAuth( - audience=token_scope, - uri="https://" + hostname, - get_token=get_token, - token_type=b"bearer", - ) - auth.update_token() - target = "amqps://" + hostname + "/messages/devicebound" - self.amqp_client = uamqp.SendClient(target=target, auth=auth, keep_alive_interval=120) diff --git a/src/azure/iot/hub/iothub_registry_manager.py b/src/azure/iot/hub/iothub_registry_manager.py index 7fc5b07..ea03df7 100644 --- a/src/azure/iot/hub/iothub_registry_manager.py +++ b/src/azure/iot/hub/iothub_registry_manager.py @@ -3,7 +3,6 @@ # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- -from . import iothub_amqp_client from .auth import ConnectionStringAuthentication, AzureIdentityCredentialAdapter from .protocol.iot_hub_gateway_service_ap_is import IotHubGatewayServiceAPIs as protocol_client from .protocol.models import ( @@ -69,24 +68,15 @@ def __init__(self, connection_string=None, host=None, token_credential=None): :returns: Instance of the IoTHubRegistryManager object. :rtype: :class:`azure.iot.hub.IoTHubRegistryManager` """ - self.amqp_svc_client = None if connection_string is not None: conn_string_auth = ConnectionStringAuthentication(connection_string) self.protocol = protocol_client( conn_string_auth, "https://" + conn_string_auth["HostName"] ) - self.amqp_svc_client = iothub_amqp_client.IoTHubAmqpClientSharedAccessKeyAuth( - conn_string_auth["HostName"], - conn_string_auth["SharedAccessKeyName"], - conn_string_auth["SharedAccessKey"], - ) else: self.protocol = protocol_client( AzureIdentityCredentialAdapter(token_credential), "https://" + host ) - self.amqp_svc_client = iothub_amqp_client.IoTHubAmqpClientTokenAuth( - host, token_credential - ) @classmethod def from_connection_string(cls, connection_string): @@ -119,13 +109,6 @@ def from_token_credential(cls, url, token_credential): """ return cls(host=url, token_credential=token_credential) - def __del__(self): - """ - Deinitializer for a Registry Manager Service client. - """ - if self.amqp_svc_client is not None: - self.amqp_svc_client.disconnect_sync() - def create_device_with_sas( self, device_id, @@ -914,15 +897,3 @@ def invoke_device_module_method(self, device_id, module_id, direct_method_reques direct_method_request.payload = "" return self.protocol.modules.invoke_method(device_id, module_id, direct_method_request) - - def send_c2d_message(self, device_id, message, properties={}): - """Send a C2D message to a IoTHub Device. - - :param str device_id: The name (Id) of the device. - :param str message: The message that is to be delivered to the device. - :param dict properties: The properties to be send with the message. Can contain - application properties and system properties - - :raises: Exception if the Send command is not able to send the message - """ - self.amqp_svc_client.send_message_to_device(device_id, message, properties) diff --git a/tests/test_iothub_amqp_client.py b/tests/test_iothub_amqp_client.py deleted file mode 100644 index 273e9d9..0000000 --- a/tests/test_iothub_amqp_client.py +++ /dev/null @@ -1,287 +0,0 @@ -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for -# license information. -# -------------------------------------------------------------------------- - -import base64 -import hashlib -import pytest -import uamqp -import hmac -from azure.core.credentials import AccessToken -from azure.iot.hub.iothub_amqp_client import ( - IoTHubAmqpClientSharedAccessKeyAuth, - IoTHubAmqpClientTokenAuth, -) - -"""---Constants---""" -fake_device_id = "device_id" -fake_message = "fake_message" -fake_app_prop = {"fake_prop1": "fake_value1"} -fake_sys_prop = { - "contentType": "value1", - "contentEncoding": "value2", - "correlationId": "value3", - "expiryTimeUtc": 1584727659, - "messageId": 42, -} -fake_hostname = "hostname.mytest.net" -fake_shared_access_key_name = "test_key_name" -fake_shared_access_key = "Zm9vYmFy" -fake_token_scope = "https://token.net/.default" -fake_token = "fasdjkhg" -fake_token_expiry = 1584727659 - - -@pytest.fixture(autouse=True) -def mock_uamqp_SendClient(mocker): - mock_uamqp_SendClient = mocker.patch.object(uamqp, "SendClient") - return mock_uamqp_SendClient - - -class SharedIotHubAmqpClientSendMessageToDeviceTests(object): - @pytest.mark.it("Sends messages with application properties using the uamqp SendClient") - def test_send_message_to_device_app_prop(self, client, mocker, mock_uamqp_SendClient): - client.send_message_to_device(fake_device_id, fake_message, fake_app_prop) - amqp_client_obj = mock_uamqp_SendClient.return_value - - # Message was queued - assert amqp_client_obj.queue_message.call_count == 1 - msg_obj = amqp_client_obj.queue_message.call_args[0][0] - # Message was configured with properties and destination - assert str(msg_obj) == fake_message - assert msg_obj.properties.to == bytes( - str("/devices/" + fake_device_id + "/messages/devicebound").encode("utf-8") - ) - assert msg_obj.application_properties == fake_app_prop - # Message was sent - assert amqp_client_obj.send_all_messages.call_count == 1 - assert amqp_client_obj.send_all_messages.call_args == mocker.call(close_on_done=False) - - @pytest.mark.it("Sends messages with system properties using the uamqp SendClient") - def test_send_message_to_device_sys_prop(self, client, mocker, mock_uamqp_SendClient): - client.send_message_to_device(fake_device_id, fake_message, fake_sys_prop) - amqp_client_obj = mock_uamqp_SendClient.return_value - - # Message was queued - assert amqp_client_obj.queue_message.call_count == 1 - msg_obj = amqp_client_obj.queue_message.call_args[0][0] - # Message was configured with properties and destination - assert str(msg_obj) == fake_message - assert msg_obj.properties.to == bytes( - str("/devices/" + fake_device_id + "/messages/devicebound").encode("utf-8") - ) - assert msg_obj.application_properties == {} - assert msg_obj.properties.content_type == bytes( - str(fake_sys_prop["contentType"]).encode("utf-8") - ) - assert msg_obj.properties.content_encoding == bytes( - str(fake_sys_prop["contentEncoding"]).encode("utf-8") - ) - assert msg_obj.properties.correlation_id == bytes( - str(fake_sys_prop["correlationId"]).encode("utf-8") - ) - assert msg_obj.properties.absolute_expiry_time == fake_sys_prop["expiryTimeUtc"] - assert msg_obj.properties.message_id == fake_sys_prop["messageId"] - # Message was sent - assert amqp_client_obj.send_all_messages.call_count == 1 - assert amqp_client_obj.send_all_messages.call_args == mocker.call(close_on_done=False) - - @pytest.mark.it("Raises an Exception if send_all_messages fails") - def test_raise_exception_on_send_fail(self, client, mocker, mock_uamqp_SendClient): - amqp_client_obj = mock_uamqp_SendClient.return_value - mocker.patch.object( - amqp_client_obj, "send_all_messages", {uamqp.constants.MessageState.SendFailed} - ) - with pytest.raises(Exception): - client.send_message_to_device(fake_device_id, fake_message, fake_app_prop) - - -class SharedIotHubAmqpClientDisconnectSyncTests(object): - @pytest.mark.it( - "Calls close() on the uamqp SendClient and removes it when disconnect_sync() is called" - ) - def test_disconnect_sync(self, client, mock_uamqp_SendClient): - assert client.amqp_client is not None - amqp_client_obj = mock_uamqp_SendClient.return_value - - client.disconnect_sync() - - assert amqp_client_obj.close.call_count == 1 - assert client.amqp_client is None - - -############################################# -# IoTHubAmqpClientSharedAccessKeyAuth Tests # -############################################# - - -class IoTHubAmqpClientSharedAccessKeyAuthTestConfig(object): - @pytest.fixture - def client(self): - return IoTHubAmqpClientSharedAccessKeyAuth( - hostname=fake_hostname, - shared_access_key_name=fake_shared_access_key_name, - shared_access_key=fake_shared_access_key, - ) - - -@pytest.mark.describe("IoTHubAmqpClientSharedAccessKeyAuth - Instantiation") -class TestIoTHubAmqpClientSharedAccessKeyAuthInstantiation( - IoTHubAmqpClientSharedAccessKeyAuthTestConfig -): - @pytest.mark.it( - "Creates a JWTTokenAuth instance with the correct parameters and uses it to create an AMQP SendClient" - ) - def test_create_JWTTokenAuth_with_sas_token(self, mocker, mock_uamqp_SendClient): - amqp_token_init_mock = mocker.patch.object(uamqp.authentication, "JWTTokenAuth") - amqp_token_mock = amqp_token_init_mock.return_value - - IoTHubAmqpClientSharedAccessKeyAuth( - fake_hostname, fake_shared_access_key_name, fake_shared_access_key - ) - - # JWTTokenAuth creation - assert amqp_token_init_mock.call_count == 1 - assert amqp_token_init_mock.call_args[1]["uri"] == "https://" + fake_hostname - assert amqp_token_init_mock.call_args[1]["audience"] == "https://" + fake_hostname - assert amqp_token_init_mock.call_args[1]["token_type"] == b"servicebus.windows.net:sastoken" - assert amqp_token_mock.update_token.call_count == 1 - - # AMQP SendClient is created - assert mock_uamqp_SendClient.call_count == 1 - expected_target = "amqps://" + fake_hostname + "/messages/devicebound" - assert mock_uamqp_SendClient.call_args == mocker.call( - target=expected_target, auth=amqp_token_mock, keep_alive_interval=120 - ) - - @pytest.mark.it("Creates an HMAC to generate a shared access signature") - def test_creates_hmac(self, mocker): - hmac_mock = mocker.patch.object(hmac, "HMAC") - hmac_digest_mock = hmac_mock.return_value.digest - hmac_digest_mock.return_value = b"\xd2\x06\xf7\x12\xf1\xe9\x95$\x90\xfd\x12\x9a\xb1\xbe\xb4\xf8\xf3\xc4\x1ap\x8a\xab'\x8a.D\xfb\x84\x96\xca\xf3z" - - IoTHubAmqpClientSharedAccessKeyAuth( - fake_hostname, fake_shared_access_key_name, fake_shared_access_key - ) - - assert hmac_mock.call_count == 1 - assert hmac_mock.call_args == mocker.call( - base64.b64decode(fake_shared_access_key + "="), mocker.ANY, hashlib.sha256 - ) - - assert hmac_digest_mock.call_count == 1 - - -@pytest.mark.describe("IoTHubAmqpClientSharedAccessKeyAuth - .send_message_to_device()") -class TestIoTHubAmqpClientSharedAccessKeyAuthSendMessageToDevice( - IoTHubAmqpClientSharedAccessKeyAuthTestConfig, SharedIotHubAmqpClientSendMessageToDeviceTests -): - pass - - -@pytest.mark.describe("IoTHubAmqpClientSharedAccessKeyAuth - .disconnect_sync()") -class TestIoTHubAmqpClientSharedAccessKeyAuthDisconnectSync( - IoTHubAmqpClientSharedAccessKeyAuthTestConfig, SharedIotHubAmqpClientDisconnectSyncTests -): - pass - - -################################### -# IoTHubAmqpClientTokenAuth Tests # -################################### - - -class IoTHubAmqpClientTokenAuthTestConfig(object): - @pytest.fixture - def mock_azure_identity_TokenCredential(self, mocker): - mock = mocker.MagicMock() - mock.get_token.return_value = AccessToken(fake_token, fake_token_expiry) - return mock - - @pytest.fixture - def client(self, mock_azure_identity_TokenCredential): - return IoTHubAmqpClientTokenAuth( - hostname=fake_hostname, - token_credential=mock_azure_identity_TokenCredential, - token_scope=fake_token_scope, - ) - - -@pytest.mark.describe("IoTHubAmqpClientTokenAuth - Instantiation") -class TestIotHubAmqpClientTokenAuthInstantiation(IoTHubAmqpClientTokenAuthTestConfig): - @pytest.mark.it( - "Creates a JWTTokenAuth instance with the correct parameters and uses it to create an AMQP SendClient when a token scope is specified" - ) - def test_create_JWTTokenAuth_with_bearer_token_custom_scope( - self, mocker, mock_azure_identity_TokenCredential, mock_uamqp_SendClient - ): - amqp_token_init_mock = mocker.patch.object(uamqp.authentication, "JWTTokenAuth") - amqp_token_mock = amqp_token_init_mock.return_value - - IoTHubAmqpClientTokenAuth( - fake_hostname, mock_azure_identity_TokenCredential, token_scope=fake_token_scope - ) - - # JWTTokenAuth Creation - assert amqp_token_init_mock.call_count == 1 - assert amqp_token_init_mock.call_args[1]["uri"] == "https://" + fake_hostname - assert amqp_token_init_mock.call_args[1]["audience"] == fake_token_scope - assert amqp_token_init_mock.call_args[1]["token_type"] == b"bearer" - assert amqp_token_mock.update_token.call_count == 1 - - # AMQP SendClient is created - assert mock_uamqp_SendClient.call_count == 1 - expected_target = "amqps://" + fake_hostname + "/messages/devicebound" - assert mock_uamqp_SendClient.call_args == mocker.call( - target=expected_target, auth=amqp_token_mock, keep_alive_interval=120 - ) - - @pytest.mark.it( - "Creates a JWTTokenAuth instance with the correct parameters and uses it to create an AMQP SendClient if no token scope is provided (uses the default scope of 'https://iothubs.azure.net/.default')" - ) - def test_create_JWTTokenAuth_with_bearer_token_default_scope( - self, mocker, mock_azure_identity_TokenCredential, mock_uamqp_SendClient - ): - amqp_token_init_mock = mocker.patch.object(uamqp.authentication, "JWTTokenAuth") - amqp_token_mock = amqp_token_init_mock.return_value - - IoTHubAmqpClientTokenAuth(fake_hostname, mock_azure_identity_TokenCredential) - - # JWTTokenAuth Creation - assert amqp_token_init_mock.call_count == 1 - assert amqp_token_init_mock.call_args[1]["uri"] == "https://" + fake_hostname - assert amqp_token_init_mock.call_args[1]["audience"] == "https://iothubs.azure.net/.default" - assert amqp_token_init_mock.call_args[1]["token_type"] == b"bearer" - assert amqp_token_mock.update_token.call_count == 1 - - # AMQP SendClient is created - assert mock_uamqp_SendClient.call_count == 1 - expected_target = "amqps://" + fake_hostname + "/messages/devicebound" - assert mock_uamqp_SendClient.call_args == mocker.call( - target=expected_target, auth=amqp_token_mock, keep_alive_interval=120 - ) - - @pytest.mark.it( - "Retrieves the token from the azure-identity TokenCredential using the specified token scope" - ) - def test_retrieve_token_from_azure_identity(self, mock_azure_identity_TokenCredential): - IoTHubAmqpClientTokenAuth( - fake_hostname, mock_azure_identity_TokenCredential, fake_token_scope - ) - mock_azure_identity_TokenCredential.get_token.assert_called_once_with(fake_token_scope) - - -@pytest.mark.describe("IoTHubAmqpClientTokenAuth - .send_message_to_device()") -class TestIoTHubAmqpClientTokenAuthSendMessageToDevice( - IoTHubAmqpClientTokenAuthTestConfig, SharedIotHubAmqpClientSendMessageToDeviceTests -): - pass - - -@pytest.mark.describe("IoTHubAmqpClientTokenAuth - .disconnect_sync()") -class TestIoTHubAmqpClientTokenAuthDisconnectSync( - IoTHubAmqpClientTokenAuthTestConfig, SharedIotHubAmqpClientDisconnectSyncTests -): - pass diff --git a/tests/test_iothub_registry_manager.py b/tests/test_iothub_registry_manager.py index ee3abd5..ad63ed3 100644 --- a/tests/test_iothub_registry_manager.py +++ b/tests/test_iothub_registry_manager.py @@ -7,7 +7,6 @@ import pytest from azure.iot.hub.protocol.models import AuthenticationMechanism, DeviceCapabilities from azure.iot.hub.iothub_registry_manager import IoTHubRegistryManager -from azure.iot.hub import iothub_amqp_client from azure.iot.hub.protocol.iot_hub_gateway_service_ap_is import IotHubGatewayServiceAPIs """---Constants---""" @@ -60,7 +59,6 @@ class Fake_direct_method_request_with_payload_none: fake_direct_method_request_with_payload_none = Fake_direct_method_request_with_payload_none() -fake_message_to_send = "fake_message_to_send" """----Shared fixtures----""" @@ -127,15 +125,6 @@ def mock_module_constructor(mocker): return mocker.patch("azure.iot.hub.iothub_registry_manager.Module") -@pytest.fixture(scope="function") -def mock_uamqp_send_message_to_device(mocker): - mock_uamqp_send = mocker.patch.object( - iothub_amqp_client.IoTHubAmqpClientSharedAccessKeyAuth, - "send_message_to_device", - ) - return mock_uamqp_send - - @pytest.mark.describe("IoTHubRegistryManager - .from_connection_string()") class TestFromConnectionString: @pytest.mark.parametrize( @@ -160,26 +149,6 @@ class TestFromConnectionString: ), ], ) - @pytest.mark.it( - "Creates an instance of IotHubGatewayServiceAPIs and IoTHubAmqpClientSharedAccessKeyAuth with the correct arguments" - ) - def test_connection_string_auth(self, mocker, connection_string): - amqp_client_init_mock = mocker.patch.object( - iothub_amqp_client, "IoTHubAmqpClientSharedAccessKeyAuth" - ) - - client = IoTHubRegistryManager.from_connection_string(connection_string=connection_string) - - assert repr(client.protocol.config.credentials) == connection_string - assert ( - client.protocol.config.base_url - == "https://" + client.protocol.config.credentials["HostName"] - ) - assert amqp_client_init_mock.call_args == mocker.call( - client.protocol.config.credentials["HostName"], - client.protocol.config.credentials["SharedAccessKeyName"], - client.protocol.config.credentials["SharedAccessKey"], - ) @pytest.mark.it("Sets the protocol attribute") def test_instantiates_auth_and_protocol_attributes(self, iothub_registry_manager): @@ -227,29 +196,6 @@ def test_instantiates_with_connection_string_no_shared_access_key(self): IoTHubRegistryManager.from_connection_string(connection_string) -@pytest.mark.describe("IoTHubRegistryManager - .from_token_credential()") -class TestFromTokenCredential: - @pytest.mark.it( - "Creates an instance of IotHubGatewayServiceAPIs and IoTHubAmqpClientTokenAuth with the correct arguments" - ) - def test_token_credential_auth(self, mocker): - mock_azure_identity_TokenCredential = mocker.MagicMock() - amqp_client_init_mock = mocker.patch.object(iothub_amqp_client, "IoTHubAmqpClientTokenAuth") - - client = IoTHubRegistryManager.from_token_credential( - fake_hostname, mock_azure_identity_TokenCredential - ) - - assert ( - client.protocol.config.credentials._policy._credential - == mock_azure_identity_TokenCredential - ) - assert client.protocol.config.base_url == "https://" + fake_hostname - assert amqp_client_init_mock.call_args == mocker.call( - fake_hostname, mock_azure_identity_TokenCredential - ) - - @pytest.mark.describe("IoTHubRegistryManager - .create_device_with_sas()") class TestCreateDeviceWithSymmetricKey(object): @@ -1365,35 +1311,3 @@ def test_invoke_device_module_method_payload_none( assert mock_modules_operations.invoke_method.call_args == mocker.call( fake_device_id, fake_module_id, fake_direct_method_request_with_payload_none ) - - -@pytest.mark.describe("IoTHubRegistryManager - .send_c2d_message()") -class TestSendC2dMessage(object): - @pytest.mark.it("Test send c2d message") - def test_send_c2d_message( - self, mocker, mock_uamqp_send_message_to_device, iothub_registry_manager - ): - - iothub_registry_manager.send_c2d_message(fake_device_id, fake_message_to_send) - - assert mock_uamqp_send_message_to_device.call_count == 1 - assert mock_uamqp_send_message_to_device.call_args == mocker.call( - fake_device_id, fake_message_to_send, {} - ) - - -@pytest.mark.describe("IoTHubRegistryManager - .send_c2d_message() with properties") -class TestSendC2dMessageWithProperties(object): - @pytest.mark.it("Test send c2d message with properties") - def test_send_c2d_message_with_properties( - self, mocker, mock_uamqp_send_message_to_device, iothub_registry_manager - ): - - iothub_registry_manager.send_c2d_message( - fake_device_id, fake_message_to_send, fake_properties - ) - - assert mock_uamqp_send_message_to_device.call_count == 1 - assert mock_uamqp_send_message_to_device.call_args == mocker.call( - fake_device_id, fake_message_to_send, fake_properties - )