private async Task ReceiveMessageWithCallbackRecoveryAsync( TestDeviceType type, Client.TransportType transport, string faultType, string reason, TimeSpan delayInSec, string proxyAddress = null) { TestDeviceCallbackHandler testDeviceCallbackHandler = null; using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); async Task InitOperationAsync(DeviceClient deviceClient, TestDevice testDevice) { await serviceClient.OpenAsync().ConfigureAwait(false); testDeviceCallbackHandler = new TestDeviceCallbackHandler(deviceClient, testDevice, Logger); await testDeviceCallbackHandler.SetMessageReceiveCallbackHandlerAsync().ConfigureAwait(false); } async Task TestOperationAsync(DeviceClient deviceClient, TestDevice testDevice) { var timeout = TimeSpan.FromSeconds(20); using var cts = new CancellationTokenSource(timeout); (Message message, string payload, string p1Value) = MessageReceiveE2ETests.ComposeC2dTestMessage(Logger); testDeviceCallbackHandler.ExpectedMessageSentByService = message; await serviceClient.SendAsync(testDevice.Id, message).ConfigureAwait(false); Client.Message receivedMessage = await deviceClient.ReceiveAsync(timeout).ConfigureAwait(false); await testDeviceCallbackHandler.WaitForReceiveMessageCallbackAsync(cts.Token).ConfigureAwait(false); receivedMessage.Should().BeNull(); } Task CleanupOperationAsync() { serviceClient.CloseAsync(); testDeviceCallbackHandler?.Dispose(); return(Task.FromResult(true)); } await FaultInjection .TestErrorInjectionAsync( DevicePrefix, type, transport, proxyAddress, faultType, reason, delayInSec, FaultInjection.DefaultFaultDuration, InitOperationAsync, TestOperationAsync, CleanupOperationAsync, Logger) .ConfigureAwait(false); }
private async Task Twin_DeviceDesiredPropertyUpdateRecoveryAsync( Client.TransportType transport, string faultType, string reason, int delayInSec) { TestDeviceCallbackHandler testDeviceCallbackHandler = null; var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); using var cts = new CancellationTokenSource(FaultInjection.RecoveryTimeMilliseconds); var propName = Guid.NewGuid().ToString(); var props = new TwinCollection(); // Configure the callback and start accepting twin changes. Func <DeviceClient, TestDevice, Task> initOperation = async(deviceClient, testDevice) => { testDeviceCallbackHandler = new TestDeviceCallbackHandler(deviceClient, Logger); await testDeviceCallbackHandler.SetTwinPropertyUpdateCallbackHandlerAsync(propName).ConfigureAwait(false); }; // Change the twin from the service side and verify the device received it. Func <DeviceClient, TestDevice, Task> testOperation = async(deviceClient, testDevice) => { var propValue = Guid.NewGuid().ToString(); testDeviceCallbackHandler.ExpectedTwinPropertyValue = propValue; Logger.Trace($"{nameof(Twin_DeviceDesiredPropertyUpdateRecoveryAsync)}: name={propName}, value={propValue}"); Task serviceSendTask = RegistryManagerUpdateDesiredPropertyAsync(testDevice.Id, propName, propValue); Task twinReceivedTask = testDeviceCallbackHandler.WaitForTwinCallbackAsync(cts.Token); var tasks = new List <Task>() { serviceSendTask, twinReceivedTask }; while (tasks.Count > 0) { Task completedTask = await Task.WhenAny(tasks).ConfigureAwait(false); completedTask.GetAwaiter().GetResult(); tasks.Remove(completedTask); } }; await FaultInjection .TestErrorInjectionAsync( s_devicePrefix, TestDeviceType.Sasl, transport, faultType, reason, delayInSec, FaultInjection.DefaultDurationInSec, initOperation, testOperation, () => { return(Task.FromResult(false)); }, Logger) .ConfigureAwait(false); }
private async Task SendMethodAndRespondRecoveryAsync(Client.TransportType transport, string faultType, string reason, TimeSpan delayInSec, string proxyAddress = null) { TestDeviceCallbackHandler testDeviceCallbackHandler = null; using var cts = new CancellationTokenSource(FaultInjection.RecoveryTime); // Configure the callback and start accepting method calls. async Task InitOperationAsync(DeviceClient deviceClient, TestDevice testDevice) { testDeviceCallbackHandler = new TestDeviceCallbackHandler(deviceClient, testDevice, Logger); await testDeviceCallbackHandler .SetDeviceReceiveMethodAsync(MethodName, DeviceResponseJson, ServiceRequestJson) .ConfigureAwait(false); } // Call the method from the service side and verify the device received the call. async Task TestOperationAsync(DeviceClient deviceClient, TestDevice testDevice) { Task serviceSendTask = ServiceSendMethodAndVerifyResponseAsync(testDevice.Id, MethodName, DeviceResponseJson, ServiceRequestJson); Task methodReceivedTask = testDeviceCallbackHandler.WaitForMethodCallbackAsync(cts.Token); var tasks = new List <Task>() { serviceSendTask, methodReceivedTask }; while (tasks.Count > 0) { Task completedTask = await Task.WhenAny(tasks).ConfigureAwait(false); completedTask.GetAwaiter().GetResult(); tasks.Remove(completedTask); } } // Cleanup references. Task CleanupOperationAsync() { testDeviceCallbackHandler?.Dispose(); return(Task.FromResult(false)); } await FaultInjection .TestErrorInjectionAsync( DevicePrefix, TestDeviceType.Sasl, transport, proxyAddress, faultType, reason, delayInSec, FaultInjection.DefaultFaultDelay, InitOperationAsync, TestOperationAsync, CleanupOperationAsync, Logger) .ConfigureAwait(false); }
private async Task ReceiveMessageRecovery( TestDeviceType type, Client.TransportType transport, string faultType, string reason, TimeSpan delayInSec, string proxyAddress = null) { using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); async Task InitOperationAsync(DeviceClient deviceClient, TestDevice testDevice) { await serviceClient.OpenAsync().ConfigureAwait(false); // For Mqtt - the device needs to have subscribed to the devicebound topic, in order for IoT Hub to deliver messages to the device. // For this reason we will make a "fake" ReceiveAsync() call, which will result in the device subscribing to the c2d topic. // Note: We need this "fake" ReceiveAsync() call even though we (SDK default) CONNECT with a CleanSession flag set to 0. // This is because this test device is newly created, and it has never subscribed to IoT hub c2d topic. // Hence, IoT hub doesn't know about its CleanSession preference yet. if (transport == Client.TransportType.Mqtt_Tcp_Only || transport == Client.TransportType.Mqtt_WebSocket_Only) { await deviceClient.ReceiveAsync(TimeSpan.FromSeconds(5)).ConfigureAwait(false); } } async Task TestOperationAsync(DeviceClient deviceClient, TestDevice testDevice) { (Message message, string payload, string p1Value) = MessageReceiveE2ETests.ComposeC2dTestMessage(Logger); await serviceClient.SendAsync(testDevice.Id, message).ConfigureAwait(false); await MessageReceiveE2ETests.VerifyReceivedC2DMessageAsync(transport, deviceClient, testDevice.Id, message, payload, Logger).ConfigureAwait(false); } Task CleanupOperationAsync() { return(serviceClient.CloseAsync()); } await FaultInjection .TestErrorInjectionAsync( DevicePrefix, type, transport, proxyAddress, faultType, reason, delayInSec, FaultInjection.DefaultFaultDuration, InitOperationAsync, TestOperationAsync, CleanupOperationAsync, Logger) .ConfigureAwait(false); }
private async Task ReceiveMessageRecovery( TestDeviceType type, Client.TransportType transport, string faultType, string reason, int delayInSec, string proxyAddress = null) { using (ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString)) { Func <DeviceClient, TestDevice, Task> init = async(deviceClient, testDevice) => { await serviceClient.OpenAsync().ConfigureAwait(false); if (transport == Client.TransportType.Mqtt_Tcp_Only || transport == Client.TransportType.Mqtt_WebSocket_Only) { // Dummy ReceiveAsync to ensure mqtt subscription registration before SendAsync() is called on service client. await deviceClient.ReceiveAsync(TimeSpan.FromSeconds(5)).ConfigureAwait(false); } }; Func <DeviceClient, TestDevice, Task> testOperation = async(deviceClient, testDevice) => { (Message message, string payload, string p1Value) = MessageReceiveE2ETests.ComposeC2dTestMessage(Logger); await serviceClient.SendAsync(testDevice.Id, message).ConfigureAwait(false); await MessageReceiveE2ETests.VerifyReceivedC2DMessageAsync(transport, deviceClient, testDevice.Id, message, payload, Logger).ConfigureAwait(false); }; Func <Task> cleanupOperation = () => { return(serviceClient.CloseAsync()); }; await FaultInjection.TestErrorInjectionAsync( DevicePrefix, type, transport, proxyAddress, faultType, reason, delayInSec, FaultInjection.DefaultDurationInSec, init, testOperation, cleanupOperation, Logger).ConfigureAwait(false); } }
private async Task SendMethodAndRespondRecoveryAsync(Client.TransportType transport, string faultType, string reason, int delayInSec) { TestDeviceCallbackHandler testDeviceCallbackHandler = null; using var cts = new CancellationTokenSource(FaultInjection.RecoveryTimeMilliseconds); // Configure the callback and start accepting method calls. Func <DeviceClient, TestDevice, Task> initOperation = async(deviceClient, testDevice) => { testDeviceCallbackHandler = new TestDeviceCallbackHandler(deviceClient, Logger); await testDeviceCallbackHandler .SetDeviceReceiveMethodAsync(MethodName, DeviceResponseJson, ServiceRequestJson) .ConfigureAwait(false); }; // Call the method from the service side and verify the device received the call. Func <DeviceClient, TestDevice, Task> testOperation = async(deviceClient, testDevice) => { Task serviceSendTask = ServiceSendMethodAndVerifyResponseAsync(testDevice.Id, MethodName, DeviceResponseJson, ServiceRequestJson); Task methodReceivedTask = testDeviceCallbackHandler.WaitForMethodCallbackAsync(cts.Token); var tasks = new List <Task>() { serviceSendTask, methodReceivedTask }; while (tasks.Count > 0) { Task completedTask = await Task.WhenAny(tasks).ConfigureAwait(false); completedTask.GetAwaiter().GetResult(); tasks.Remove(completedTask); } }; await FaultInjection .TestErrorInjectionAsync( DevicePrefix, TestDeviceType.Sasl, transport, faultType, reason, delayInSec, FaultInjection.DefaultDelayInSec, initOperation, testOperation, () => { return(Task.FromResult <bool>(false)); }, Logger) .ConfigureAwait(false); }
private async Task Twin_DeviceReportedPropertiesRecovery( Client.TransportType transport, string faultType, string reason, int delayInSec, string proxyAddress = null) { var propName = Guid.NewGuid().ToString(); var props = new TwinCollection(); Func <DeviceClient, TestDevice, Task> testOperation = async(deviceClient, testDevice) => { var propValue = Guid.NewGuid().ToString(); props[propName] = propValue; await deviceClient.UpdateReportedPropertiesAsync(props).ConfigureAwait(false); Twin deviceTwin = await deviceClient.GetTwinAsync().ConfigureAwait(false); Assert.IsNotNull(deviceTwin, $"{nameof(deviceTwin)} is null"); Assert.IsNotNull(deviceTwin.Properties, $"{nameof(deviceTwin)}.Properties is null"); Assert.IsNotNull(deviceTwin.Properties.Reported, $"{nameof(deviceTwin)}.Properties.Reported is null"); Assert.IsNotNull(deviceTwin.Properties.Reported[propName], $"{nameof(deviceTwin)}.Properties.Reported[{nameof(propName)}] is null"); Assert.AreEqual <string>(deviceTwin.Properties.Reported[propName].ToString(), propValue); }; await FaultInjection .TestErrorInjectionAsync( s_devicePrefix, TestDeviceType.Sasl, transport, proxyAddress, faultType, reason, delayInSec, FaultInjection.DefaultDurationInSec, (d, t) => { return(Task.FromResult <bool>(false)); }, testOperation, () => { return(Task.FromResult <bool>(false)); }, Logger) .ConfigureAwait(false); }
internal async Task SendMessageRecoveryAsync( TestDeviceType type, Client.TransportType transport, string faultType, string reason, TimeSpan delayInSec, TimeSpan durationInSec = default, TimeSpan retryDurationInMilliSec = default, string proxyAddress = null) { TimeSpan operationTimeoutInMilliSecs = retryDurationInMilliSec == TimeSpan.Zero ? FaultInjection.RecoveryTime : retryDurationInMilliSec; Func <DeviceClient, TestDevice, Task> init = (deviceClient, testDevice) => { deviceClient.OperationTimeoutInMilliseconds = (uint)retryDurationInMilliSec.TotalMilliseconds; return(Task.FromResult(0)); }; Func <DeviceClient, TestDevice, Task> testOperation = async(deviceClient, testDevice) => { (Client.Message testMessage, string payload, string p1Value) = MessageSendE2ETests.ComposeD2cTestMessage(Logger); await deviceClient.SendEventAsync(testMessage).ConfigureAwait(false); }; await FaultInjection .TestErrorInjectionAsync( _devicePrefix, type, transport, proxyAddress, faultType, reason, delayInSec, durationInSec == TimeSpan.Zero?FaultInjection.DefaultFaultDuration : durationInSec, init, testOperation, () => { return(Task.FromResult(false)); }, Logger) .ConfigureAwait(false); }