From 221048a9c4278338077f406bd785438b4e174099 Mon Sep 17 00:00:00 2001 From: Anca Antochi Date: Thu, 15 Jul 2021 13:18:55 -0700 Subject: [PATCH] Remove redundant tests and wait for device to be disconnected (#5244) * Remove redundant tests and wait for device to be connected/disconnected --- .../Cloud2DeviceTest.cs | 87 +++++++++---------- .../TwinDiffE2ETest.cs | 20 +++++ 2 files changed, 60 insertions(+), 47 deletions(-) diff --git a/edge-hub/core/test/Microsoft.Azure.Devices.Edge.Hub.E2E.Test/Cloud2DeviceTest.cs b/edge-hub/core/test/Microsoft.Azure.Devices.Edge.Hub.E2E.Test/Cloud2DeviceTest.cs index 30d26bde131..8af1891d103 100644 --- a/edge-hub/core/test/Microsoft.Azure.Devices.Edge.Hub.E2E.Test/Cloud2DeviceTest.cs +++ b/edge-hub/core/test/Microsoft.Azure.Devices.Edge.Hub.E2E.Test/Cloud2DeviceTest.cs @@ -5,6 +5,7 @@ namespace Microsoft.Azure.Devices.Edge.Hub.E2E.Test using System.Collections.Generic; using System.Linq; using System.Text; + using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; using Microsoft.Azure.Devices.Client; @@ -63,49 +64,6 @@ public async void Receive_C2D_SingleMessage_ShouldSucceed(TransportType transpor [Fact] [TestPriority(102)] - public async void Receive_C2D_OfflineSingleMessage_ShouldSucceed() - { - // Arrange - string iotHubConnectionString = await SecretsHelper.GetSecretFromConfigKey("iotHubConnStrKey"); - string edgeDeviceId = ConnectionStringHelper.GetDeviceId(ConfigHelper.TestConfig[Service.Constants.ConfigKey.IotHubConnectionString]); - RegistryManager rm = RegistryManager.CreateFromConnectionString(iotHubConnectionString); - var edgeDevice = await rm.GetDeviceAsync(edgeDeviceId); - (string deviceName, string deviceConnectionString) = await RegistryManagerHelper.CreateDevice(DeviceNamePrefix, iotHubConnectionString, rm, scope: edgeDevice.Scope); - - ServiceClient serviceClient = null; - DeviceClient deviceClient = null; - try - { - serviceClient = ServiceClient.CreateFromConnectionString(iotHubConnectionString); - await serviceClient.OpenAsync(); - - ITransportSettings[] settings = this.GetTransportSettings(); - deviceClient = DeviceClient.CreateFromConnectionString(deviceConnectionString, settings); - // Dummy ReceiveAsync to ensure mqtt subscription registration before SendAsync() is called on service client. - await deviceClient.ReceiveAsync(TimeSpan.FromSeconds(1)); - await deviceClient.CloseAsync(); - // wait for the connection to be closed on the Edge side - await Task.Delay(TimeSpan.FromSeconds(20)); - - // Act - // Send message before device is listening - Message message = this.CreateMessage(out string payload); - await serviceClient.SendAsync(deviceName, message); - - deviceClient = DeviceClient.CreateFromConnectionString(deviceConnectionString, settings); - await deviceClient.OpenAsync(); - - // Assert - await this.VerifyReceivedC2DMessage(deviceClient, payload, message.Properties[MessagePropertyName]); - } - finally - { - await this.Cleanup(deviceClient, serviceClient, rm, deviceName); - } - } - - [Fact] - [TestPriority(103)] public async void Receive_C2D_SingleMessage_AfterOfflineMessage_ShouldSucceed() { // Arrange @@ -127,9 +85,14 @@ public async void Receive_C2D_SingleMessage_AfterOfflineMessage_ShouldSucceed() deviceClient = DeviceClient.CreateFromConnectionString(deviceConnectionString, settings); // Dummy ReceiveAsync to ensure mqtt subscription registration before SendAsync() is called on service client. await deviceClient.ReceiveAsync(TimeSpan.FromSeconds(1)); + + var device = await rm.GetDeviceAsync(deviceName); + // Wait for device to be connected to cloud + await this.WaitForDeviceConnectionStateTimeoutAfter(rm, deviceName, DeviceConnectionState.Connected, TimeSpan.FromSeconds(60)); await deviceClient.CloseAsync(); - // wait for the connection to be closed on the Edge side - await Task.Delay(TimeSpan.FromSeconds(30)); + + // Wait for the connection to be closed on the Edge side by checking device connection state + await this.WaitForDeviceConnectionStateTimeoutAfter(rm, deviceName, DeviceConnectionState.Disconnected, TimeSpan.FromSeconds(60)); // Act // Send message before device is listening @@ -156,7 +119,7 @@ public async void Receive_C2D_SingleMessage_AfterOfflineMessage_ShouldSucceed() } [Fact] - [TestPriority(104)] + [TestPriority(103)] public async void Receive_C2D_NotSubscribed_OfflineSingleMessage_ShouldThrow() { // Arrange @@ -204,6 +167,29 @@ ITransportSettings[] GetTransportSettings(TransportType transportType = Transpor return settings; } + async Task WaitForDeviceConnectionStateTimeoutAfter(RegistryManager rm, string deviceName, DeviceConnectionState state, TimeSpan timespan) + { + Task timerTask = Task.Delay(timespan); + CancellationTokenSource cts = new CancellationTokenSource(); + + Task completedTask = await Task.WhenAny(this.WaitForDeviceConnectionState(rm, deviceName, state, cts.Token), timerTask); + if (completedTask == timerTask) + { + cts.Cancel(); + throw new TimeoutException(string.Format("Wait for device to be in {0} state timed out", state)); + } + } + + async Task WaitForDeviceConnectionState(RegistryManager rm, string deviceName, DeviceConnectionState state, CancellationToken cancellationToken) + { + var device = await rm.GetDeviceAsync(deviceName); + while (device.ConnectionState != state && !cancellationToken.IsCancellationRequested) + { + device = await rm.GetDeviceAsync(deviceName); + await Task.Delay(TimeSpan.FromSeconds(5)); + } + } + Message CreateMessage(out string payload) { payload = Guid.NewGuid().ToString(); @@ -247,7 +233,14 @@ async Task Cleanup(DeviceClient deviceClient, ServiceClient serviceClient, Regis { if (deviceClient != null) { - await deviceClient.CloseAsync(); + try + { + await deviceClient.CloseAsync(); + } + catch + { + // ignore + } } if (serviceClient != null) diff --git a/edge-hub/core/test/Microsoft.Azure.Devices.Edge.Hub.E2E.Test/TwinDiffE2ETest.cs b/edge-hub/core/test/Microsoft.Azure.Devices.Edge.Hub.E2E.Test/TwinDiffE2ETest.cs index d4f5075a897..bc241ff3f30 100644 --- a/edge-hub/core/test/Microsoft.Azure.Devices.Edge.Hub.E2E.Test/TwinDiffE2ETest.cs +++ b/edge-hub/core/test/Microsoft.Azure.Devices.Edge.Hub.E2E.Test/TwinDiffE2ETest.cs @@ -377,6 +377,26 @@ await this.RunTestCase( } } + for (int i = 0; i < 5; i++) + { + try + { + var device = await rm.GetDeviceAsync(deviceName); + if (device.ConnectionState != DeviceConnectionState.Connected) + throw new Exception("Device not connected to cloud"); + break; + } + catch (Exception) + { + if (i == 4) + { + throw; + } + + await Task.Delay(TimeSpan.FromSeconds(5)); + } + } + return (deviceClient, deviceName); }