async def test_client_register_calls_polling_machine_register_with_payload_and_callback( self, mocker, mock_polling_machine): # Override callback to pass successful result def register_complete_success_callback(payload, callback): callback(result=create_success_result()) mocker.patch.object(mock_polling_machine, "register", side_effect=register_complete_success_callback) mqtt_provisioning_pipeline = mocker.MagicMock() mock_polling_machine_init = mocker.patch( "azure.iot.device.provisioning.aio.async_provisioning_device_client.PollingMachine" ) mock_polling_machine_init.return_value = mock_polling_machine user_payload = "petrificus totalus" client = ProvisioningDeviceClient(mqtt_provisioning_pipeline) client.provisioning_payload = user_payload result = await client.register() assert mock_polling_machine.register.call_count == 1 assert mock_polling_machine.register.call_args[1][ "payload"] == user_payload assert callable(mock_polling_machine.register.call_args[1]["callback"]) assert result is not None assert result.registration_state == fake_registration_state assert result.status == fake_status assert result.registration_state == fake_registration_state assert result.registration_state.device_id == fake_device_id assert result.registration_state.assigned_hub == fake_assigned_hub
async def test_get_payload(self, mocker, mock_polling_machine, payload_input): mqtt_provisioning_pipeline = mocker.MagicMock() mock_polling_machine_init = mocker.patch( "azure.iot.device.provisioning.provisioning_device_client.PollingMachine" ) mock_polling_machine_init.return_value = mock_polling_machine client = ProvisioningDeviceClient(mqtt_provisioning_pipeline) client.provisioning_payload = payload_input assert client.provisioning_payload == payload_input
async def test_client_creation(self, mocker, mock_pipeline_init): spy_client_init = mocker.spy(ProvisioningDeviceClient, "__init__") ProvisioningDeviceClient.create_from_symmetric_key( provisioning_host=fake_provisioning_host, registration_id=fake_registration_id, id_scope=fake_id_scope, symmetric_key=fake_symmetric_key, ) assert spy_client_init.call_count == 1 assert spy_client_init.call_args == mocker.call( mocker.ANY, mock_pipeline_init.return_value)
async def test_client_creation(self, mocker, mock_pipeline_init, x509): spy_client_init = mocker.spy(ProvisioningDeviceClient, "__init__") ProvisioningDeviceClient.create_from_x509_certificate( provisioning_host=fake_provisioning_host, registration_id=fake_registration_id, id_scope=fake_id_scope, x509=x509, ) assert spy_client_init.call_count == 1 assert spy_client_init.call_args == mocker.call( mocker.ANY, mock_pipeline_init.return_value)
async def test_waits_for_pipeline_op_completion_on_failure( self, mocker, provisioning_pipeline, registration_result): # fail result registration_result._status = "not assigned" # Set up mocks cb_mock_register = mocker.MagicMock() cb_mock_shutdown = mocker.MagicMock() cb_mock_register.completion.return_value = await create_completed_future( registration_result) cb_mock_shutdown.completion.return_value = await create_completed_future( None) mocker.patch.object(async_adapter, "AwaitableCallback").side_effect = [ cb_mock_register, cb_mock_shutdown, ] # Run test client = ProvisioningDeviceClient(provisioning_pipeline) await client.register() # Calls made as expected assert provisioning_pipeline.register.call_count == 1 assert provisioning_pipeline.shutdown.call_count == 0 # Callbacks sent to pipeline as expected assert provisioning_pipeline.register.call_args == mocker.call( payload=mocker.ANY, callback=cb_mock_register) # Callback completions were waited upon as expected assert cb_mock_register.completion.call_count == 1 assert cb_mock_shutdown.completion.call_count == 0
async def test_raises_error_on_shutdown_pipeline_op_error( self, mocker, pipeline_error, client_error, provisioning_pipeline, registration_result): # success result is required to trigger shutdown registration_result._status = "assigned" error = pipeline_error() def register_complete_success_callback(payload, callback): callback(result=registration_result) def shutdown_failure_callback(callback): callback(result=None, error=error) mocker.patch.object(provisioning_pipeline, "register", side_effect=register_complete_success_callback) mocker.patch.object(provisioning_pipeline, "shutdown", side_effect=shutdown_failure_callback) client = ProvisioningDeviceClient(provisioning_pipeline) with pytest.raises(client_error) as e_info: await client.register() assert e_info.value.__cause__ is error assert provisioning_pipeline.register.call_count == 1
async def test_create_from_x509_cert(self, mocker, protocol, mock_transport): client = ProvisioningDeviceClient.create_from_x509_certificate( fake_provisioning_host, fake_registration_id, fake_id_scope, fake_x509()) assert isinstance(client, ProvisioningDeviceClient) assert client._provisioning_pipeline is not None
async def test_security_client(self, mocker): spy_sec_client = mocker.spy(security, "SymmetricKeySecurityClient") ProvisioningDeviceClient.create_from_symmetric_key( provisioning_host=fake_provisioning_host, registration_id=fake_registration_id, id_scope=fake_id_scope, symmetric_key=fake_symmetric_key, ) assert spy_sec_client.call_count == 1 assert spy_sec_client.call_args == mocker.call( provisioning_host=fake_provisioning_host, registration_id=fake_registration_id, id_scope=fake_id_scope, symmetric_key=fake_symmetric_key, )
async def test_returns_client(self, mocker): client = ProvisioningDeviceClient.create_from_symmetric_key( provisioning_host=fake_provisioning_host, registration_id=fake_registration_id, id_scope=fake_id_scope, symmetric_key=fake_symmetric_key, ) assert isinstance(client, ProvisioningDeviceClient)
async def test_security_client(self, mocker, x509): spy_sec_client = mocker.spy(security, "X509SecurityClient") ProvisioningDeviceClient.create_from_x509_certificate( provisioning_host=fake_provisioning_host, registration_id=fake_registration_id, id_scope=fake_id_scope, x509=x509, ) assert spy_sec_client.call_count == 1 assert spy_sec_client.call_args == mocker.call( provisioning_host=fake_provisioning_host, registration_id=fake_registration_id, id_scope=fake_id_scope, x509=x509, )
async def test_returns_client(self, mocker, x509): client = ProvisioningDeviceClient.create_from_x509_certificate( provisioning_host=fake_provisioning_host, registration_id=fake_registration_id, id_scope=fake_id_scope, x509=x509, ) assert isinstance(client, ProvisioningDeviceClient)
async def test_create_from_x509_cert(self, mocker, protocol): patch_set_x509_client = mocker.patch.object( pipeline_ops_provisioning, "SetX509SecurityClientOperation") client = ProvisioningDeviceClient.create_from_x509_certificate( fake_provisioning_host, fake_registration_id, fake_id_scope, fake_x509()) assert isinstance(client, ProvisioningDeviceClient) assert patch_set_x509_client.call_count == 1 assert client._provisioning_pipeline is not None
async def test_pipeline(self, mocker, mock_pipeline_init, x509): # Note that the details of how the pipeline config is set up are covered in the # SharedClientCreateMethodUserOptionTests mock_pipeline_config = mocker.patch.object( pipeline, "ProvisioningPipelineConfig").return_value mock_sec_client = mocker.patch.object( security, "X509SecurityClient").return_value ProvisioningDeviceClient.create_from_x509_certificate( provisioning_host=fake_provisioning_host, registration_id=fake_registration_id, id_scope=fake_id_scope, x509=x509, ) assert mock_pipeline_init.call_count == 1 assert mock_pipeline_init.call_args == mocker.call( mock_sec_client, mock_pipeline_config)
async def test_create_from_symmetric_key(self, mocker, protocol): patch_set_sym_client = mocker.patch.object( pipeline_ops_provisioning, "SetSymmetricKeySecurityClientOperation" ) client = ProvisioningDeviceClient.create_from_symmetric_key( fake_provisioning_host, fake_symmetric_key, fake_registration_id, fake_id_scope ) assert isinstance(client, ProvisioningDeviceClient) assert patch_set_sym_client.call_count == 1 assert client._provisioning_pipeline is not None
async def test_waits_for_pipeline_op_completion(self, mocker, provisioning_pipeline): cb_mock = mocker.patch.object(async_adapter, "AwaitableCallback").return_value cb_mock.completion.return_value = await create_completed_future( create_success_result()) provisioning_pipeline.responses_enabled.__getitem__.return_value = True client = ProvisioningDeviceClient(provisioning_pipeline) client._provisioning_payload = "payload" await client.register() # Assert callback is sent to pipeline assert provisioning_pipeline.register.call_args[1][ "payload"] == "payload" assert provisioning_pipeline.register.call_args[1][ "callback"] is cb_mock # Assert callback completion is waited upon assert cb_mock.completion.call_count == 1
async def test_register_calls_pipeline_register( self, provisioning_pipeline, mocker, registration_result ): def register_complete_success_callback(payload, callback): callback(result=registration_result) mocker.patch.object( provisioning_pipeline, "register", side_effect=register_complete_success_callback ) client = ProvisioningDeviceClient(provisioning_pipeline) await client.register() assert provisioning_pipeline.register.call_count == 1
async def test_client_cancel_calls_polling_machine_cancel_with_callback( self, mocker, mock_polling_machine): mqtt_provisioning_pipeline = mocker.MagicMock() mock_polling_machine_init = mocker.patch( "azure.iot.device.provisioning.aio.async_provisioning_device_client.PollingMachine" ) mock_polling_machine_init.return_value = mock_polling_machine client = ProvisioningDeviceClient(mqtt_provisioning_pipeline) await client.cancel() assert mock_polling_machine.cancel.call_count == 1 assert callable(mock_polling_machine.cancel.call_args[1]["callback"])
async def test_verifies_registration_result_returned( self, mocker, provisioning_pipeline, registration_result): result = registration_result def register_complete_success_callback(payload, callback): callback(result=result) mocker.patch.object(provisioning_pipeline, "register", side_effect=register_complete_success_callback) client = ProvisioningDeviceClient(provisioning_pipeline) result_returned = await client.register() assert result_returned == result
async def test_no_shutdown_upon_fail(self, mocker, provisioning_pipeline, registration_result): # fail result registration_result._status = "not assigned" def register_complete_fail_callback(payload, callback): callback(result=registration_result) mocker.patch.object( provisioning_pipeline, "register", side_effect=register_complete_fail_callback ) client = ProvisioningDeviceClient(provisioning_pipeline) await client.register() assert provisioning_pipeline.shutdown.call_count == 0
async def test_raises_error_on_register_pipeline_op_error( self, mocker, client_error, pipeline_error, provisioning_pipeline): error = pipeline_error() def register_complete_failure_callback(payload, callback): callback(result=None, error=error) mocker.patch.object(provisioning_pipeline, "register", side_effect=register_complete_failure_callback) client = ProvisioningDeviceClient(provisioning_pipeline) with pytest.raises(client_error) as e_info: await client.register() assert e_info.value.__cause__ is error assert provisioning_pipeline.register.call_count == 1
async def test_enables_provisioning_only_if_not_already_enabled( self, mocker, provisioning_pipeline, registration_result): # Override callback to pass successful result def register_complete_success_callback(payload, callback): callback(result=registration_result) mocker.patch.object(provisioning_pipeline, "register", side_effect=register_complete_success_callback) provisioning_pipeline.responses_enabled.__getitem__.return_value = False client = ProvisioningDeviceClient(provisioning_pipeline) await client.register() assert provisioning_pipeline.enable_responses.call_count == 1 provisioning_pipeline.enable_responses.reset_mock() provisioning_pipeline.responses_enabled.__getitem__.return_value = True await client.register() assert provisioning_pipeline.enable_responses.call_count == 0
async def test_client_register_failure_calls_polling_machine_register_with_callback( self, mocker, mock_polling_machine): # Override callback to pass successful result def register_complete_failure_callback(callback): callback(result=None, error=create_error()) mocker.patch.object(mock_polling_machine, "register", side_effect=register_complete_failure_callback) mqtt_provisioning_pipeline = mocker.MagicMock() mock_polling_machine_init = mocker.patch( "azure.iot.device.provisioning.aio.async_provisioning_device_client.PollingMachine" ) mock_polling_machine_init.return_value = mock_polling_machine client = ProvisioningDeviceClient(mqtt_provisioning_pipeline) result = await client.register() assert mock_polling_machine.register.call_count == 1 assert callable(mock_polling_machine.register.call_args[1]["callback"]) assert result is None
async def test_get_payload(self, mocker, payload_input): provisioning_pipeline = mocker.MagicMock() client = ProvisioningDeviceClient(provisioning_pipeline) client.provisioning_payload = payload_input assert client.provisioning_payload == payload_input
async def test_create_from_symmetric_key(self, mocker, protocol): client = ProvisioningDeviceClient.create_from_symmetric_key( fake_provisioning_host, fake_symmetric_key, fake_registration_id, fake_id_scope) assert isinstance(client, ProvisioningDeviceClient) assert client._provisioning_pipeline is not None
async def test_payload(self, provisioning_pipeline): client = ProvisioningDeviceClient(provisioning_pipeline) assert client._provisioning_payload is None
async def test_sets_provisioning_pipeline(self, provisioning_pipeline): client = ProvisioningDeviceClient(provisioning_pipeline) assert client._provisioning_pipeline is provisioning_pipeline
def client(self, provisioning_pipeline): return ProvisioningDeviceClient(provisioning_pipeline)