Skip to content

Commit

Permalink
Remove redundant tests and wait for device to be disconnected (#5244)
Browse files Browse the repository at this point in the history
* Remove redundant tests and wait for device to be connected/disconnected
  • Loading branch information
ancaantochi authored Jul 15, 2021
1 parent 39bd6dc commit 221048a
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down

0 comments on commit 221048a

Please sign in to comment.