Skip to content

Commit

Permalink
Adding E2E Test for Twin Operations. (#754)
Browse files Browse the repository at this point in the history
* Adding E2E Test for Twin Operations.

* Fixing StyleCop Issues.

* Addressing Code Review Comments.

* Fixing Code Style.

* Adressing more code review comments.

* Passing Code Style.
  • Loading branch information
aribeironovaes authored Jan 29, 2019
1 parent 6f7c6cd commit 5bbcec0
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 1 deletion.
14 changes: 14 additions & 0 deletions e2e_test_files/twin_test_tempSensor.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"moduleId" : "tempSensor",
"properties" : {
"desired" : {
"SendInterval": 42,
"SendData": true,
"OtherType" : "test"
},
"reported" : {
"SendInterval": 42,
"SendData": true
}
}
}
6 changes: 6 additions & 0 deletions smoke/IotEdgeQuickstart/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ class Program
[Option("-l|--deployment <filename>", Description = "Deployment json file")]
public string DeploymentFileName { get; } = Environment.GetEnvironmentVariable("deployment");

[Option("-tw|--twin_test <filename>", Description = "A file with Json content to set desired property and check reported property in a module.")]
public string TwinTestFileName { get; } = null;

[Option("--device_ca_cert", Description = "path to the device ca certificate and its chain")]
public string DeviceCaCert { get; } = string.Empty;

Expand Down Expand Up @@ -197,6 +200,8 @@ async Task<int> OnExecuteAsync()

Option<string> deployment = this.DeploymentFileName != null ? Option.Some(this.DeploymentFileName) : Option.None<string>();

Option<string> twinTest = this.TwinTestFileName != null ? Option.Some(this.TwinTestFileName) : Option.None<string>();

string tag = this.ImageTag ?? "1.0";

var test = new Quickstart(
Expand All @@ -213,6 +218,7 @@ async Task<int> OnExecuteAsync()
this.NoVerify,
this.VerifyDataFromModule,
deployment,
twinTest,
this.DeviceCaCert,
this.DeviceCaPk,
this.DeviceCaCerts,
Expand Down
4 changes: 3 additions & 1 deletion smoke/IotEdgeQuickstart/Quickstart.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@ public Quickstart(
bool noVerify,
string verifyDataFromModule,
Option<string> deploymentFileName,
Option<string> twinTestFileName,
string deviceCaCert,
string deviceCaPk,
string deviceCaCerts,
bool optimizedForPerformance,
LogLevel runtimeLogLevel,
bool cleanUpExistingDeviceOnSuccess)
: base(bootstrapper, credentials, iothubConnectionString, eventhubCompatibleEndpointWithEntityPath, upstreamProtocol, imageTag, deviceId, hostname, deploymentFileName, deviceCaCert, deviceCaPk, deviceCaCerts, optimizedForPerformance, runtimeLogLevel, cleanUpExistingDeviceOnSuccess)
: base(bootstrapper, credentials, iothubConnectionString, eventhubCompatibleEndpointWithEntityPath, upstreamProtocol, imageTag, deviceId, hostname, deploymentFileName, twinTestFileName, deviceCaCert, deviceCaPk, deviceCaCerts, optimizedForPerformance, runtimeLogLevel, cleanUpExistingDeviceOnSuccess)
{
this.leaveRunning = leaveRunning;
this.noDeployment = noDeployment;
Expand Down Expand Up @@ -67,6 +68,7 @@ public async Task RunAsync()
if (!this.noVerify)
{
await this.VerifyDataOnIoTHub(this.verifyDataFromModule);
await this.VerifyTwinAsync();
}

if (this.leaveRunning == LeaveRunning.Core)
Expand Down
45 changes: 45 additions & 0 deletions smoke/IotEdgeQuickstart/details/Details.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ namespace IotEdgeQuickstart.Details
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -21,6 +22,8 @@ public class Details
{
public readonly Option<string> DeploymentFileName;

public readonly Option<string> TwinTestFileName;

const string DeployJson = @"
{
""modulesContent"": {
Expand Down Expand Up @@ -138,6 +141,7 @@ protected Details(
string deviceId,
string hostname,
Option<string> deploymentFileName,
Option<string> twinTestFileName,
string deviceCaCert,
string deviceCaPk,
string deviceCaCerts,
Expand Down Expand Up @@ -172,6 +176,7 @@ protected Details(
this.deviceId = deviceId;
this.hostname = hostname;
this.DeploymentFileName = deploymentFileName;
this.TwinTestFileName = twinTestFileName;
this.deviceCaCert = deviceCaCert;
this.deviceCaPk = deviceCaPk;
this.deviceCaCerts = deviceCaCerts;
Expand Down Expand Up @@ -334,6 +339,46 @@ protected async Task VerifyDataOnIoTHub(string moduleId)
await eventHubClient.CloseAsync();
}

protected async Task VerifyTwinAsync()
{
await this.TwinTestFileName.ForEachAsync(
async fileName =>
{
string twinTestJson = File.ReadAllText(fileName);

var twinTest = JsonConvert.DeserializeObject<TwinTestConfiguration>(twinTestJson);

Twin currentTwin = await this.context.RegistryManager.GetTwinAsync(this.context.Device.Id, twinTest.ModuleId);

if (twinTest.Properties?.Desired?.Count > 0)
{
// Build Patch Object.
string patch = JsonConvert.SerializeObject(twinTest, Formatting.Indented);
await this.context.RegistryManager.UpdateTwinAsync(this.context.Device.Id, twinTest.ModuleId, patch, currentTwin.ETag);
}

if (twinTest.Properties?.Reported?.Count > 0)
{
TimeSpan retryInterval = TimeSpan.FromSeconds(10);
bool IsValid(TwinCollection currentTwinReportedProperty) => twinTest.Properties.Reported.Cast<KeyValuePair<string, object>>().All(p => currentTwinReportedProperty.Cast<KeyValuePair<string, object>>().Contains(p));

using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(20)))
{
async Task<TwinCollection> Func()
{
// Removing reSharper warning for CTS, Code Block will never exit before the delegate code completes because of using.
// ReSharper disable AccessToDisposedClosure
currentTwin = await this.context.RegistryManager.GetTwinAsync(this.context.Device.Id, twinTest.ModuleId, cts.Token);
// ReSharper restore AccessToDisposedClosure
return await Task.FromResult(currentTwin.Properties.Reported);
}

await Retry.Do(Func, IsValid, null, retryInterval, cts.Token);
}
}
});
}

protected Task RemoveTempSensorFromEdgeDevice()
{
(string deployJson, string[] _) = this.DeploymentJson();
Expand Down
16 changes: 16 additions & 0 deletions smoke/IotEdgeQuickstart/details/TwinTestConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) Microsoft. All rights reserved.
namespace IotEdgeQuickstart.Details
{
using System.Collections.Generic;
using Microsoft.Azure.Devices.Shared;
using Newtonsoft.Json;

public class TwinTestConfiguration
{
[JsonProperty(PropertyName = "moduleId")]
public string ModuleId { get; set; }

[JsonProperty(PropertyName = "properties")]
public TwinProperties Properties { get; set; }
}
}

0 comments on commit 5bbcec0

Please sign in to comment.