зеркало из https://github.com/Azure/iotedge.git
Adding E2E Test for Twin Operations. (#754)
* Adding E2E Test for Twin Operations. * Fixing StyleCop Issues. * Addressing Code Review Comments. * Fixing Code Style. * Adressing more code review comments. * Passing Code Style.
This commit is contained in:
Родитель
6f7c6cdbff
Коммит
5bbcec092a
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"moduleId" : "tempSensor",
|
||||
"properties" : {
|
||||
"desired" : {
|
||||
"SendInterval": 42,
|
||||
"SendData": true,
|
||||
"OtherType" : "test"
|
||||
},
|
||||
"reported" : {
|
||||
"SendInterval": 42,
|
||||
"SendData": true
|
||||
}
|
||||
}
|
||||
}
|
|
@ -114,6 +114,9 @@ Defaults:
|
|||
[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;
|
||||
|
||||
|
@ -197,6 +200,8 @@ Defaults:
|
|||
|
||||
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(
|
||||
|
@ -213,6 +218,7 @@ Defaults:
|
|||
this.NoVerify,
|
||||
this.VerifyDataFromModule,
|
||||
deployment,
|
||||
twinTest,
|
||||
this.DeviceCaCert,
|
||||
this.DeviceCaPk,
|
||||
this.DeviceCaCerts,
|
||||
|
|
|
@ -27,13 +27,14 @@ namespace IotEdgeQuickstart
|
|||
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;
|
||||
|
@ -67,6 +68,7 @@ namespace IotEdgeQuickstart
|
|||
if (!this.noVerify)
|
||||
{
|
||||
await this.VerifyDataOnIoTHub(this.verifyDataFromModule);
|
||||
await this.VerifyTwinAsync();
|
||||
}
|
||||
|
||||
if (this.leaveRunning == LeaveRunning.Core)
|
||||
|
|
|
@ -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;
|
||||
|
@ -21,6 +22,8 @@ namespace IotEdgeQuickstart.Details
|
|||
{
|
||||
public readonly Option<string> DeploymentFileName;
|
||||
|
||||
public readonly Option<string> TwinTestFileName;
|
||||
|
||||
const string DeployJson = @"
|
||||
{
|
||||
""modulesContent"": {
|
||||
|
@ -138,6 +141,7 @@ namespace IotEdgeQuickstart.Details
|
|||
string deviceId,
|
||||
string hostname,
|
||||
Option<string> deploymentFileName,
|
||||
Option<string> twinTestFileName,
|
||||
string deviceCaCert,
|
||||
string deviceCaPk,
|
||||
string deviceCaCerts,
|
||||
|
@ -172,6 +176,7 @@ namespace IotEdgeQuickstart.Details
|
|||
this.deviceId = deviceId;
|
||||
this.hostname = hostname;
|
||||
this.DeploymentFileName = deploymentFileName;
|
||||
this.TwinTestFileName = twinTestFileName;
|
||||
this.deviceCaCert = deviceCaCert;
|
||||
this.deviceCaPk = deviceCaPk;
|
||||
this.deviceCaCerts = deviceCaCerts;
|
||||
|
@ -334,6 +339,46 @@ namespace IotEdgeQuickstart.Details
|
|||
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();
|
||||
|
|
|
@ -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; }
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче