private async Task SendMethodAndRespondRecovery(Client.TransportType transport, string faultType, string reason, int delayInSec) { Tuple <string, string> deviceInfo = TestUtil.CreateDevice(DevicePrefix, hostName, registryManager); var assertResult = new TaskCompletionSource <Tuple <bool, bool> >(); DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(deviceInfo.Item2, transport); await deviceClient.SetMethodHandlerAsync(MethodName, (request, context) => { assertResult.SetResult(new Tuple <bool, bool>(request.Name.Equals(MethodName), request.DataAsJson.Equals(ServiceRequestJson))); return(Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(DeviceResponseJson), 200))); }, null); await ServiceSendMethodAndVerifyResponse(deviceInfo.Item1, MethodName, DeviceResponseJson, ServiceRequestJson, assertResult); // send error command await deviceClient.SendEventAsync(TestUtil.ComposeErrorInjectionProperties(faultType, reason, delayInSec)); // allow time for connection recovery await Task.Delay(TimeSpan.FromSeconds(3)); assertResult = new TaskCompletionSource <Tuple <bool, bool> >(); await ServiceSendMethodAndVerifyResponse(deviceInfo.Item1, MethodName, DeviceResponseJson, ServiceRequestJson, assertResult); await deviceClient.CloseAsync(); TestUtil.RemoveDevice(deviceInfo.Item1, registryManager); }
private async Task SendMessageThrottledForHttp() { await sequentialTestSemaphore.WaitAsync(); Tuple <string, string> deviceInfo = TestUtil.CreateDevice(DevicePrefix, hostName, registryManager); EventHubClient eventHubClient; EventHubReceiver eventHubReceiver = CreateEventHubReceiver(deviceInfo.Item1, out eventHubClient); var deviceClient = DeviceClient.CreateFromConnectionString(deviceInfo.Item2, Client.TransportType.Http1); deviceClient.OperationTimeoutInMilliseconds = (uint)TestUtil.ShortRetryInMilliSec; await deviceClient.OpenAsync(); string payload, p1Value; Client.Message testMessage = ComposeD2CTestMessage(out payload, out p1Value); await deviceClient.SendEventAsync(testMessage); var events = await eventHubReceiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(5)); VerifyTestMessage(events, deviceInfo.Item1, payload, p1Value); // Implementation of error injection of throttling on http is that it will throttle the // fault injection message itself only. The duration of fault has no effect on http throttle. // Client is supposed to retry sending the throttling fault message until operation timeout. await deviceClient.SendEventAsync(TestUtil.ComposeErrorInjectionProperties(TestUtil.FaultType_Throttle, TestUtil.FaultCloseReason_Boom, TestUtil.DefaultDelayInSec, TestUtil.DefaultDurationInSec)); sequentialTestSemaphore.Release(1); }
private async Task SendMethodAndRespondRecovery(Client.TransportType transport, string faultType, string reason, int delayInSec) { Tuple <string, string> deviceInfo = TestUtil.CreateDevice("E2E_Method_CSharp_", hostName, registryManager); string deviceResponseJson = "{\"name\":\"e2e_test\"}"; string serviceRequestJson = "{\"a\":123}"; string methodName = "MethodE2ETest"; var assertResult = new TaskCompletionSource <Tuple <bool, bool> >(); DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(deviceInfo.Item2, transport); await deviceClient.SetMethodHandlerAsync(methodName, (request, context) => { assertResult.SetResult(new Tuple <bool, bool>(request.Name.Equals(methodName), request.DataAsJson.Equals(serviceRequestJson))); return(Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(deviceResponseJson), 200))); }, null); await ServiceSendMethodAndVerifyResponse(deviceInfo.Item1, methodName, deviceResponseJson, serviceRequestJson, assertResult); // send error command await deviceClient.SendEventAsync(TestUtil.ComposeErrorInjectionProperties(faultType, reason, delayInSec)); Debug.WriteLine("Drop command sent from device client."); // allow time for connection recovery await Task.Delay(TimeSpan.FromSeconds(3)); assertResult = new TaskCompletionSource <Tuple <bool, bool> >(); await ServiceSendMethodAndVerifyResponse(deviceInfo.Item1, methodName, deviceResponseJson, serviceRequestJson, assertResult); await deviceClient.CloseAsync(); TestUtil.RemoveDevice(deviceInfo.Item1, registryManager); }
private async Task SendMessageRecovery(Client.TransportType transport, string faultType, string reason, int delayInSec, int durationInSec = 0, int retryDurationInMilliSec = 240000) { await sequentialTestSemaphore.WaitAsync(); Tuple <string, string> deviceInfo = TestUtil.CreateDevice(DevicePrefix, hostName, registryManager); EventHubClient eventHubClient; EventHubReceiver eventHubReceiver = CreateEventHubReceiver(deviceInfo.Item1, out eventHubClient); var deviceClient = DeviceClient.CreateFromConnectionString(deviceInfo.Item2, transport); deviceClient.OperationTimeoutInMilliseconds = (uint)retryDurationInMilliSec; await deviceClient.OpenAsync(); string payload, p1Value; Client.Message testMessage = ComposeD2CTestMessage(out payload, out p1Value); await deviceClient.SendEventAsync(testMessage); bool isReceived = false; Stopwatch sw = new Stopwatch(); sw.Start(); while (!isReceived && sw.Elapsed.Minutes < 1) { var events = await eventHubReceiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(5)); isReceived = VerifyTestMessage(events, deviceInfo.Item1, payload, p1Value); } sw.Stop(); // send error command and clear eventHubReceiver of the fault injection message await deviceClient.SendEventAsync(TestUtil.ComposeErrorInjectionProperties(faultType, reason, delayInSec, durationInSec)); await eventHubReceiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(5)); Thread.Sleep(1000); testMessage = ComposeD2CTestMessage(out payload, out p1Value); await deviceClient.SendEventAsync(testMessage); sw.Reset(); sw.Start(); while (!isReceived && sw.Elapsed.Minutes < 1) { var events = await eventHubReceiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(5)); isReceived = VerifyTestMessage(events, deviceInfo.Item1, payload, p1Value); } sw.Stop(); await deviceClient.CloseAsync(); await eventHubClient.CloseAsync(); TestUtil.RemoveDevice(deviceInfo.Item1, registryManager); sequentialTestSemaphore.Release(1); }
private async Task _Twin_DeviceReportedPropertiesRecovery(Client.TransportType transport, string faultType, string reason, int delayInSec) { var propName = Guid.NewGuid().ToString(); var propValue1 = Guid.NewGuid().ToString(); Tuple<string, string> deviceInfo = TestUtil.CreateDevice(DevicePrefix, hostName, registryManager); var deviceClient = DeviceClient.CreateFromConnectionString(deviceInfo.Item2, transport); TwinCollection props = new TwinCollection(); props[propName] = propValue1; await deviceClient.UpdateReportedPropertiesAsync(props); var deviceTwin = await deviceClient.GetTwinAsync(); Assert.AreEqual<String>(deviceTwin.Properties.Reported[propName].ToString(), propValue1); // send error command await deviceClient.SendEventAsync(TestUtil.ComposeErrorInjectionProperties(faultType, reason, delayInSec)); Thread.Sleep(1000); deviceTwin = await deviceClient.GetTwinAsync(); Assert.AreEqual<String>(deviceTwin.Properties.Reported[propName].ToString(), propValue1); var propValue2 = Guid.NewGuid().ToString(); props[propName] = propValue2; await deviceClient.UpdateReportedPropertiesAsync(props); deviceTwin = await deviceClient.GetTwinAsync(); Assert.AreEqual<String>(deviceTwin.Properties.Reported[propName].ToString(), propValue2); await deviceClient.CloseAsync(); TestUtil.RemoveDevice(deviceInfo.Item1, registryManager); }
private async Task _Twin_DeviceDesiredPropertyUpdateRecovery(Client.TransportType transport, string faultType, string reason, int delayInSec) { var tcs = new TaskCompletionSource <bool>(); var propName = Guid.NewGuid().ToString(); var propValue = Guid.NewGuid().ToString(); Tuple <string, string> deviceInfo = TestUtil.CreateDevice(DevicePrefix, hostName, registryManager); var deviceClient = DeviceClient.CreateFromConnectionString(deviceInfo.Item2, transport); await deviceClient.OpenAsync(); await deviceClient.SetDesiredPropertyUpdateCallbackAsync((patch, context) => { return(Task.Run(() => { try { Assert.AreEqual(patch[propName].ToString(), propValue); } catch (Exception e) { tcs.SetException(e); } finally { tcs.SetResult(true); } })); }, null); var twinPatch = new Twin(); twinPatch.Properties.Desired[propName] = propValue; await registryManager.UpdateTwinAsync(deviceInfo.Item1, twinPatch, "*"); await tcs.Task; // send error command await deviceClient.SendEventAsync(TestUtil.ComposeErrorInjectionProperties(faultType, reason, delayInSec)); await Task.Delay(TimeSpan.FromSeconds(3)); tcs = new TaskCompletionSource <bool>(); twinPatch = new Twin(); twinPatch.Properties.Desired[propName] = propValue; await registryManager.UpdateTwinAsync(deviceInfo.Item1, twinPatch, "*"); await tcs.Task; await deviceClient.CloseAsync(); TestUtil.RemoveDevice(deviceInfo.Item1, registryManager); }
internal async Task SendMessageThrottledForHttp() { // TODO: Update Jenkins Config if (Configuration.IoTHub.EventHubString.IsNullOrWhiteSpace()) { return; } await sequentialTestSemaphore.WaitAsync(); Tuple <string, string> deviceInfo = TestUtil.CreateDevice(DevicePrefix, hostName, registryManager); EventHubClient eventHubClient; PartitionReceiver eventHubReceiver = await CreateEventHubReceiver(deviceInfo.Item1); var deviceClient = DeviceClient.CreateFromConnectionString(deviceInfo.Item2, Client.TransportType.Http1); try { deviceClient.OperationTimeoutInMilliseconds = (uint)TestUtil.ShortRetryInMilliSec; await deviceClient.OpenAsync(); string payload, p1Value; Client.Message testMessage = ComposeD2CTestMessage(out payload, out p1Value); await deviceClient.SendEventAsync(testMessage); bool isReceived = false; Stopwatch sw = new Stopwatch(); sw.Start(); while (!isReceived && sw.Elapsed.Minutes < 1) { var events = await eventHubReceiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(5)); isReceived = VerifyTestMessage(events, deviceInfo.Item1, payload, p1Value); } sw.Stop(); // Implementation of error injection of throttling on http is that it will throttle the // fault injection message itself only. The duration of fault has no effect on http throttle. // Client is supposed to retry sending the throttling fault message until operation timeout. await deviceClient.SendEventAsync(TestUtil.ComposeErrorInjectionProperties(TestUtil.FaultType_Throttle, TestUtil.FaultCloseReason_Boom, TestUtil.DefaultDelayInSec, TestUtil.DefaultDurationInSec)); } finally { await deviceClient.CloseAsync(); await eventHubReceiver.CloseAsync(); sequentialTestSemaphore.Release(1); } }
private async Task ReceiveMessageRecovery(Client.TransportType transport, string faultType, string reason, int delayInSec) { await sequentialTestSemaphore.WaitAsync(); Tuple <string, string> deviceInfo = TestUtil.CreateDevice(DevicePrefix, hostName, registryManager); ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(hubConnectionString); var deviceClient = DeviceClient.CreateFromConnectionString(deviceInfo.Item2, transport); try { await deviceClient.OpenAsync(); 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(2)); } string payload, messageId, p1Value; await serviceClient.OpenAsync(); await serviceClient.SendAsync(deviceInfo.Item1, ComposeC2DTestMessage(out payload, out messageId, out p1Value)); await VerifyReceivedC2DMessage(transport, deviceClient, payload, p1Value); // send error command await deviceClient.SendEventAsync( TestUtil.ComposeErrorInjectionProperties(faultType, reason, delayInSec)); await Task.Delay(1000); await serviceClient.SendAsync(deviceInfo.Item1, ComposeC2DTestMessage(out payload, out messageId, out p1Value)); await VerifyReceivedC2DMessage(transport, deviceClient, payload, p1Value); } finally { await deviceClient.CloseAsync(); await serviceClient.CloseAsync(); await TestUtil.RemoveDeviceAsync(deviceInfo.Item1, registryManager); sequentialTestSemaphore.Release(1); } }
private async Task SendMessageRecovery(Client.TransportType transport, string faultType, string reason, int delayInSec, int durationInSec = 0) { await sequentialTestSemaphore.WaitAsync(); Tuple <string, string> deviceInfo = TestUtil.CreateDevice(DevicePrefix, hostName, registryManager); EventHubClient eventHubClient; EventHubReceiver eventHubReceiver = CreateEventHubReceiver(deviceInfo.Item1, out eventHubClient); var deviceClient = DeviceClient.CreateFromConnectionString(deviceInfo.Item2, transport); await deviceClient.OpenAsync(); string payload, p1Value; Client.Message testMessage = ComposeD2CTestMessage(out payload, out p1Value); await deviceClient.SendEventAsync(testMessage); var events = await eventHubReceiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(5)); VerifyTestMessage(events, deviceInfo.Item1, payload, p1Value); // send error command and clear eventHubReceiver of the fault injection message await deviceClient.SendEventAsync(TestUtil.ComposeErrorInjectionProperties(faultType, reason, delayInSec, durationInSec)); await eventHubReceiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(5)); Thread.Sleep(1000); testMessage = ComposeD2CTestMessage(out payload, out p1Value); await deviceClient.SendEventAsync(testMessage); events = await eventHubReceiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(5)); VerifyTestMessage(events, deviceInfo.Item1, payload, p1Value); await deviceClient.CloseAsync(); await eventHubClient.CloseAsync(); TestUtil.RemoveDevice(deviceInfo.Item1, registryManager); sequentialTestSemaphore.Release(1); }
async Task uploadFileDisconnectTransport(Client.TransportType transport, string filename, string faultType, string reason, int delayInSec, int durationInSec = 0, int retryDurationInMilliSec = 24000) { Tuple <string, string> deviceInfo = TestUtil.CreateDevice(DevicePrefix, hostName, registryManager); DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(deviceInfo.Item2, transport); deviceClient.OperationTimeoutInMilliseconds = (uint)retryDurationInMilliSec; Task fileuploadTask; Task <FileNotification> verifyTask; using (FileStream fileStreamSource = new FileStream(filename, FileMode.Open, FileAccess.Read)) { verifyTask = VerifyFileNotification(deviceInfo); fileuploadTask = deviceClient.UploadToBlobAsync(filename, fileStreamSource); try { await deviceClient.SendEventAsync(TestUtil.ComposeErrorInjectionProperties(faultType, reason, delayInSec, durationInSec)).ConfigureAwait(false); } catch (Exception) { // catch and ignore exceptions resulted from error injection and continue to // check result of the file upload status } await Task.WhenAll(fileuploadTask, verifyTask).ConfigureAwait(false); } FileNotification fileNotification = await verifyTask.ConfigureAwait(false); Assert.IsNotNull(fileNotification, "FileNotification is not received."); Assert.AreEqual(deviceInfo.Item1 + "/" + filename, fileNotification.BlobName, "Uploaded file name mismatch in notifications"); Assert.AreEqual(new FileInfo(filename).Length, fileNotification.BlobSizeInBytes, "Uploaded file size mismatch in notifications"); Assert.IsFalse(string.IsNullOrEmpty(fileNotification.BlobUri), "File notification blob uri is null or empty"); await deviceClient.CloseAsync().ConfigureAwait(false); await TestUtil.RemoveDeviceAsync(deviceInfo.Item1, registryManager).ConfigureAwait(false); }
private async Task SendMethodAndRespondRecovery(Client.TransportType transport, string faultType, string reason, int delayInSec) { Tuple <string, string> deviceInfo = TestUtil.CreateDevice(DevicePrefix, hostName, registryManager); var assertResult = new TaskCompletionSource <Tuple <bool, bool> >(); DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(deviceInfo.Item2, transport); ConnectionStatus? lastConnectionStatus = null; ConnectionStatusChangeReason?lastConnectionStatusChangeReason = null; int setConnectionStatusChangesHandlerCount = 0; bool assertStatusChange = false; deviceClient.SetConnectionStatusChangesHandler((status, statusChangeReason) => { if (assertStatusChange) { if (setConnectionStatusChangesHandlerCount == 0) { Assert.AreEqual(ConnectionStatus.Disconnected_Retrying, status); Assert.AreEqual(ConnectionStatusChangeReason.No_Network, statusChangeReason); } else { Assert.AreEqual(ConnectionStatus.Connected, status); Assert.AreEqual(ConnectionStatusChangeReason.Connection_Ok, statusChangeReason); } } lastConnectionStatus = status; lastConnectionStatusChangeReason = statusChangeReason; setConnectionStatusChangesHandlerCount++; }); await deviceClient.SetMethodHandlerAsync(MethodName, (request, context) => { assertResult.SetResult(new Tuple <bool, bool>(request.Name.Equals(MethodName), request.DataAsJson.Equals(ServiceRequestJson))); return(Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(DeviceResponseJson), 200))); }, null); if (transport != Client.TransportType.Http1) { Assert.AreEqual(1, setConnectionStatusChangesHandlerCount); Assert.AreEqual(ConnectionStatus.Connected, lastConnectionStatus); Assert.AreEqual(ConnectionStatusChangeReason.Connection_Ok, lastConnectionStatusChangeReason); } await ServiceSendMethodAndVerifyResponse(deviceInfo.Item1, MethodName, DeviceResponseJson, ServiceRequestJson, assertResult); // allow time for connection recovery setConnectionStatusChangesHandlerCount = 0; assertStatusChange = true; // send error command await deviceClient.SendEventAsync(TestUtil.ComposeErrorInjectionProperties(faultType, reason, delayInSec)); Stopwatch sw = new Stopwatch(); sw.Start(); while (sw.Elapsed.Minutes < 3 && setConnectionStatusChangesHandlerCount < 2) { await Task.Delay(1000); } assertResult = new TaskCompletionSource <Tuple <bool, bool> >(); await ServiceSendMethodAndVerifyResponse(deviceInfo.Item1, MethodName, DeviceResponseJson, ServiceRequestJson, assertResult); setConnectionStatusChangesHandlerCount = 0; assertStatusChange = false; await deviceClient.SetMethodHandlerAsync(MethodName, null, null); if (transport != Client.TransportType.Http1) { Assert.AreEqual(1, setConnectionStatusChangesHandlerCount); Assert.AreEqual(ConnectionStatus.Disabled, lastConnectionStatus); Assert.AreEqual(ConnectionStatusChangeReason.Client_Close, lastConnectionStatusChangeReason); } TestUtil.RemoveDevice(deviceInfo.Item1, registryManager); }
private async Task SendMessageRecovery(Client.TransportType transport, string faultType, string reason, int delayInSec, int durationInSec = 0, int retryDurationInMilliSec = 240000) { await sequentialTestSemaphore.WaitAsync(); Tuple <string, string> deviceInfo = TestUtil.CreateDevice(DevicePrefix, hostName, registryManager); var deviceClient = DeviceClient.CreateFromConnectionString(deviceInfo.Item2, transport); EventHubClient eventHubClient; EventHubReceiver eventHubReceiver = CreateEventHubReceiver(deviceInfo.Item1, out eventHubClient); try { deviceClient.OperationTimeoutInMilliseconds = (uint)retryDurationInMilliSec; ConnectionStatus? lastConnectionStatus = null; ConnectionStatusChangeReason?lastConnectionStatusChangeReason = null; int setConnectionStatusChangesHandlerCount = 0; deviceClient.SetConnectionStatusChangesHandler((status, statusChangeReason) => { lastConnectionStatus = status; lastConnectionStatusChangeReason = statusChangeReason; setConnectionStatusChangesHandlerCount++; }); await deviceClient.OpenAsync(); if (transport != Client.TransportType.Http1) { Assert.AreEqual(1, setConnectionStatusChangesHandlerCount); Assert.AreEqual(ConnectionStatus.Connected, lastConnectionStatus); Assert.AreEqual(ConnectionStatusChangeReason.Connection_Ok, lastConnectionStatusChangeReason); } string payload, p1Value; Client.Message testMessage = ComposeD2CTestMessage(out payload, out p1Value); await deviceClient.SendEventAsync(testMessage); bool isReceived = false; Stopwatch sw = new Stopwatch(); sw.Start(); while (!isReceived && sw.Elapsed.Minutes < 1) { var events = await eventHubReceiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(5)); isReceived = VerifyTestMessage(events, deviceInfo.Item1, payload, p1Value); } sw.Stop(); // send error command and clear eventHubReceiver of the fault injection message await deviceClient.SendEventAsync(TestUtil.ComposeErrorInjectionProperties(faultType, reason, delayInSec, durationInSec)); await eventHubReceiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(5)); Thread.Sleep(1000); testMessage = ComposeD2CTestMessage(out payload, out p1Value); await deviceClient.SendEventAsync(testMessage); sw.Reset(); sw.Start(); while (!isReceived && sw.Elapsed.Minutes < 1) { var events = await eventHubReceiver.ReceiveAsync(int.MaxValue, TimeSpan.FromSeconds(5)); isReceived = VerifyTestMessage(events, deviceInfo.Item1, payload, p1Value); } sw.Stop(); await deviceClient.CloseAsync(); if (transport != Client.TransportType.Http1) { Assert.AreEqual(2, setConnectionStatusChangesHandlerCount); Assert.AreEqual(ConnectionStatus.Disabled, lastConnectionStatus); Assert.AreEqual(ConnectionStatusChangeReason.Client_Close, lastConnectionStatusChangeReason); } } finally { await deviceClient.CloseAsync(); await eventHubReceiver.CloseAsync(); await eventHubClient.CloseAsync(); TestUtil.RemoveDevice(deviceInfo.Item1, registryManager); sequentialTestSemaphore.Release(1); } }
private async Task Twin_DeviceDesiredPropertyUpdateRecovery(Client.TransportType transport, string faultType, string reason, int delayInSec) { var tcs = new TaskCompletionSource <bool>(); var propName = Guid.NewGuid().ToString(); var propValue = Guid.NewGuid().ToString(); Tuple <string, string> deviceInfo = TestUtil.CreateDevice(DevicePrefix, hostName, registryManager); var deviceClient = DeviceClient.CreateFromConnectionString(deviceInfo.Item2, transport); ConnectionStatus? lastConnectionStatus = null; ConnectionStatusChangeReason?lastConnectionStatusChangeReason = null; int setConnectionStatusChangesHandlerCount = 0; var tcsConnected = new TaskCompletionSource <bool>(); var tcsDisconnected = new TaskCompletionSource <bool>(); deviceClient.SetConnectionStatusChangesHandler((status, statusChangeReason) => { if (status == ConnectionStatus.Disconnected_Retrying) { tcsDisconnected.TrySetResult(true); Assert.AreEqual(ConnectionStatusChangeReason.No_Network, statusChangeReason); } else if (status == ConnectionStatus.Connected) { tcsConnected.TrySetResult(true); } lastConnectionStatus = status; lastConnectionStatusChangeReason = statusChangeReason; setConnectionStatusChangesHandlerCount++; }); await deviceClient.SetDesiredPropertyUpdateCallbackAsync((patch, context) => { return(Task.Run(() => { try { Assert.AreEqual(patch[propName].ToString(), propValue); } catch (Exception e) { tcs.SetException(e); } finally { tcs.SetResult(true); } })); }, null).ConfigureAwait(false); // assert on successfuly connection await Task.WhenAny( Task.Run(async() => { await Task.Delay(1000).ConfigureAwait(false); }), tcsConnected.Task).ConfigureAwait(false); Assert.IsTrue(tcsConnected.Task.IsCompleted, "Initial connection failed"); if (transport != Client.TransportType.Http1) { Assert.AreEqual(1, setConnectionStatusChangesHandlerCount); Assert.AreEqual(ConnectionStatus.Connected, lastConnectionStatus); Assert.AreEqual(ConnectionStatusChangeReason.Connection_Ok, lastConnectionStatusChangeReason); } var twinPatch = new Twin(); twinPatch.Properties.Desired[propName] = propValue; await registryManager.UpdateTwinAsync(deviceInfo.Item1, twinPatch, "*").ConfigureAwait(false); await tcs.Task.ConfigureAwait(false); // send error command await deviceClient.SendEventAsync(TestUtil.ComposeErrorInjectionProperties(faultType, reason, delayInSec)).ConfigureAwait(false); // reset ConnectionStatusChangesHandler data setConnectionStatusChangesHandlerCount = 0; tcsConnected = new TaskCompletionSource <bool>(); tcsDisconnected = new TaskCompletionSource <bool>(); // wait for disconnection await Task.WhenAny( Task.Run(async() => { await Task.Delay(TimeSpan.FromSeconds(10)).ConfigureAwait(false); }), tcsDisconnected.Task).ConfigureAwait(false); Assert.IsTrue(tcsDisconnected.Task.IsCompleted, "Error injection did not interrupt the device"); // allow max 30s for connection recovery await Task.WhenAny( Task.Run(async() => { await Task.Delay(TimeSpan.FromSeconds(10)).ConfigureAwait(false); return(Task.FromResult(true)); }), tcsConnected.Task).ConfigureAwait(false); Assert.IsTrue(tcsConnected.Task.IsCompleted, "Recovery connection failed"); tcs = new TaskCompletionSource <bool>(); twinPatch = new Twin(); twinPatch.Properties.Desired[propName] = propValue; await registryManager.UpdateTwinAsync(deviceInfo.Item1, twinPatch, "*").ConfigureAwait(false); await tcs.Task.ConfigureAwait(false); await deviceClient.CloseAsync().ConfigureAwait(false); await TestUtil.RemoveDeviceAsync(deviceInfo.Item1, registryManager).ConfigureAwait(false); }
private async Task SendMethodAndRespondRecovery(Client.TransportType transport, string faultType, string reason, int delayInSec) { Tuple <string, string> deviceInfo = TestUtil.CreateDevice(DevicePrefix, hostName, registryManager); var assertResult = new TaskCompletionSource <Tuple <bool, bool> >(); DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(deviceInfo.Item2, transport); ConnectionStatus? lastConnectionStatus = null; ConnectionStatusChangeReason?lastConnectionStatusChangeReason = null; int setConnectionStatusChangesHandlerCount = 0; var tcsConnected = new TaskCompletionSource <bool>(); var tcsDisconnected = new TaskCompletionSource <bool>(); deviceClient.SetConnectionStatusChangesHandler((status, statusChangeReason) => { Debug.WriteLine("Connection Changed to {0} because {1}", status, statusChangeReason); if (status == ConnectionStatus.Disconnected_Retrying) { tcsDisconnected.TrySetResult(true); Assert.AreEqual(ConnectionStatusChangeReason.No_Network, statusChangeReason); } else if (status == ConnectionStatus.Connected) { tcsConnected.TrySetResult(true); } lastConnectionStatus = status; lastConnectionStatusChangeReason = statusChangeReason; setConnectionStatusChangesHandlerCount++; }); await deviceClient.SetMethodHandlerAsync(MethodName, (request, context) => { assertResult.TrySetResult(new Tuple <bool, bool>(request.Name.Equals(MethodName), request.DataAsJson.Equals(ServiceRequestJson))); return(Task.FromResult(new MethodResponse(Encoding.UTF8.GetBytes(DeviceResponseJson), 200))); }, null); // assert on successfuly connection await Task.WhenAny( Task.Run(async() => { await Task.Delay(1000); }), tcsConnected.Task); Assert.IsTrue(tcsConnected.Task.IsCompleted, "Initial connection failed"); if (transport != Client.TransportType.Http1) { Assert.AreEqual(1, setConnectionStatusChangesHandlerCount); Assert.AreEqual(ConnectionStatus.Connected, lastConnectionStatus); Assert.AreEqual(ConnectionStatusChangeReason.Connection_Ok, lastConnectionStatusChangeReason); } // check on normal operation await ServiceSendMethodAndVerifyResponse(deviceInfo.Item1, MethodName, DeviceResponseJson, ServiceRequestJson, assertResult); // reset ConnectionStatusChangesHandler data setConnectionStatusChangesHandlerCount = 0; tcsConnected = new TaskCompletionSource <bool>(); tcsDisconnected = new TaskCompletionSource <bool>(); // send error command await deviceClient.SendEventAsync(TestUtil.ComposeErrorInjectionProperties(faultType, reason, delayInSec)); // wait for disconnection await Task.WhenAny( Task.Run(async() => { await Task.Delay(TimeSpan.FromSeconds(10)); }), tcsDisconnected.Task); Assert.IsTrue(tcsDisconnected.Task.IsCompleted, "Error injection did not interrupt the device"); // allow max 3 minutes for connection recovery await Task.WhenAny( Task.Run(async() => { ////////////////////////change it to 30 await Task.Delay(TimeSpan.FromSeconds(10)); return(Task.FromResult(true)); }), tcsConnected.Task); Assert.IsTrue(tcsConnected.Task.IsCompleted, "Recovery connection failed"); assertResult = new TaskCompletionSource <Tuple <bool, bool> >(); await ServiceSendMethodAndVerifyResponse(deviceInfo.Item1, MethodName, DeviceResponseJson, ServiceRequestJson, assertResult); setConnectionStatusChangesHandlerCount = 0; //remove and CloseAsync await deviceClient.SetMethodHandlerAsync(MethodName, null, null); if (transport != Client.TransportType.Http1) { Assert.AreEqual(1, setConnectionStatusChangesHandlerCount); Assert.AreEqual(ConnectionStatus.Disabled, lastConnectionStatus); Assert.AreEqual(ConnectionStatusChangeReason.Client_Close, lastConnectionStatusChangeReason); } TestUtil.RemoveDevice(deviceInfo.Item1, registryManager); }
async Task uploadFileDisconnectTransport(Client.TransportType transport, string filename, string faultType, string reason, int delayInSec, int durationInSec = 0, int retryDurationInMilliSec = 24000) { Tuple <string, string> deviceInfo = TestUtil.CreateDevice(DevicePrefix, hostName, registryManager); DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(deviceInfo.Item2, transport); deviceClient.OperationTimeoutInMilliseconds = (uint)retryDurationInMilliSec; Task fileuploadTask; using (FileStream fileStreamSource = new FileStream(filename, FileMode.Open, FileAccess.Read)) { fileuploadTask = deviceClient.UploadToBlobAsync(filename, fileStreamSource); // send error command after 400ms to allow time for the actual fileupload operation to start await Task.Delay(400); try { await deviceClient.SendEventAsync(TestUtil.ComposeErrorInjectionProperties(faultType, reason, delayInSec, durationInSec)); } catch (Exception) { // catch and ignore exceptions resulted from error injection and continue to // check result of the file upload status } await fileuploadTask; } ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(hubConnectionString); FileNotificationReceiver <FileNotification> fileNotificationReceiver = serviceClient.GetFileNotificationReceiver(); FileNotification fileNotification; while (true) { // Receive the file notification from queue fileNotification = await fileNotificationReceiver.ReceiveAsync(TimeSpan.FromSeconds(20)); Assert.IsNotNull(fileNotification); await fileNotificationReceiver.CompleteAsync(fileNotification); if (deviceInfo.Item1 == fileNotification.DeviceId) { break; } } Assert.AreEqual(deviceInfo.Item1 + "/" + filename, fileNotification.BlobName, "Uploaded file name mismatch in notifications"); Assert.AreEqual(new FileInfo(filename).Length, fileNotification.BlobSizeInBytes, "Uploaded file size mismatch in notifications"); Assert.IsFalse(string.IsNullOrEmpty(fileNotification.BlobUri), "File notification blob uri is null or empty"); await deviceClient.CloseAsync(); await serviceClient.CloseAsync(); TestUtil.RemoveDevice(deviceInfo.Item1, registryManager); }