From dbbe0daf6e6ae40d216d51a4c4bd8a38b5b2856f Mon Sep 17 00:00:00 2001 From: Azad Abbasi Date: Tue, 16 Jun 2020 10:59:52 -0700 Subject: [PATCH 1/4] feat(tests): Make sure we can run tests. --- .../src/IoTHubServiceClient.cs | 12 ++--- .../tests/DevicesClientTests.cs | 48 +++++++++++++++++++ .../tests/TestSettings.cs | 18 ++++++- 3 files changed, 71 insertions(+), 7 deletions(-) create mode 100644 sdk/iot/Azure.Iot.Hub.Service/tests/DevicesClientTests.cs diff --git a/sdk/iot/Azure.Iot.Hub.Service/src/IoTHubServiceClient.cs b/sdk/iot/Azure.Iot.Hub.Service/src/IoTHubServiceClient.cs index ef1e1f52dee1..2ca72c074771 100644 --- a/sdk/iot/Azure.Iot.Hub.Service/src/IoTHubServiceClient.cs +++ b/sdk/iot/Azure.Iot.Hub.Service/src/IoTHubServiceClient.cs @@ -23,32 +23,32 @@ public class IoTHubServiceClient /// /// place holder for Devices /// - public DevicesClient Devices { get; private set; } + public virtual DevicesClient Devices { get; private set; } /// /// place holder for Modules /// - public ModulesClient Modules { get; private set; } + public virtual ModulesClient Modules { get; private set; } /// /// place holder for Statistics /// - public StatisticsClient Statistics { get; private set; } + public virtual StatisticsClient Statistics { get; private set; } /// /// place holder for Messages /// - public CloudToDeviceMessagesClient Messages { get; private set; } + public virtual CloudToDeviceMessagesClient Messages { get; private set; } /// /// place holder for Files /// - public FilesClient Files { get; private set; } + public virtual FilesClient Files { get; private set; } /// /// place holder for Jobs /// - public JobsClient Jobs { get; private set; } + public virtual JobsClient Jobs { get; private set; } /// /// Initializes a new instance of the class. diff --git a/sdk/iot/Azure.Iot.Hub.Service/tests/DevicesClientTests.cs b/sdk/iot/Azure.Iot.Hub.Service/tests/DevicesClientTests.cs new file mode 100644 index 000000000000..050676646d88 --- /dev/null +++ b/sdk/iot/Azure.Iot.Hub.Service/tests/DevicesClientTests.cs @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System.Net; +using System.Threading.Tasks; +using FluentAssertions; +using NUnit.Framework; + +namespace Azure.Iot.Hub.Service.Tests +{ + public class DevicesClientTests : E2eTestBase + { + public DevicesClientTests(bool isAsync) + : base(isAsync) + { + } + + [Test] + public async Task Devices_Lifecycle() + { + // TODO: This is just a verification that tests run and it requires the tester to complete this test however they see fit. + string testDeviceName = GetRandom(); + + IoTHubServiceClient client = GetClient(); + + try + { + await client.Devices.GetIdentityAsync(testDeviceName).ConfigureAwait(false); + } + catch (RequestFailedException ex) when (ex.Status == (int)HttpStatusCode.NotFound) + { + // If the Device doesn't exist, we will create it. + await client.Devices.CreateOrUpdateIdentityAsync( + new Models.DeviceIdentity + { + DeviceId = testDeviceName + }).ConfigureAwait(false); + } + + // Perform another GET. We expect the device to exist. + Response response = await client.Devices.GetIdentityAsync(testDeviceName).ConfigureAwait(false); + response.GetRawResponse().Status.Should().Be(200); + + // Delete the device at the end. + await client.Devices.DeleteIdentityAsync(response.Value, IfMatchPrecondition.UnconditionalIfMatch).ConfigureAwait(false); + } + } +} diff --git a/sdk/iot/Azure.Iot.Hub.Service/tests/TestSettings.cs b/sdk/iot/Azure.Iot.Hub.Service/tests/TestSettings.cs index 753d80a04bf0..d5df972dccff 100644 --- a/sdk/iot/Azure.Iot.Hub.Service/tests/TestSettings.cs +++ b/sdk/iot/Azure.Iot.Hub.Service/tests/TestSettings.cs @@ -19,7 +19,7 @@ public class TestSettings // These environment variables are required to be set to run tests against the CI pipeline. // If these environment variables exist in the environment, their values will replace (supersede) config.json values. - private static readonly string s_iotHubConnectionString = $"{IotHubServiceEnvironmentVariablesPrefix}_CONNECTION_STRING"; + private static readonly string s_iotHubConnectionString = $"{IotHubServiceEnvironmentVariablesPrefix}_HUB_CONNECTION_STRING"; private static readonly string s_iotHubServiceTestMode = $"AZURE_IOT_TEST_MODE"; @@ -81,6 +81,22 @@ static TestSettings() // These environment variables are required to be set to run tests against the CI pipeline. private static void OverrideFromEnvVariables() { + string iotHubConnectionString = Environment.GetEnvironmentVariable(s_iotHubConnectionString); + if (!string.IsNullOrWhiteSpace(iotHubConnectionString)) + { + Instance.IotHubConnectionString = iotHubConnectionString; + } + + string testMode = Environment.GetEnvironmentVariable(s_iotHubServiceTestMode); + if (!string.IsNullOrWhiteSpace(testMode)) + { + // Enum.Parse(value) cannot be used in net461 so using the type casting syntax. + Instance.TestMode = (RecordedTestMode)Enum.Parse(typeof(RecordedTestMode), testMode); + } + else + { + Environment.SetEnvironmentVariable(s_iotHubServiceTestMode, Instance.TestMode.ToString()); + } } } } From c0c72d5efedb268a626ded76134dfca0cf337fee Mon Sep 17 00:00:00 2001 From: Azad Abbasi Date: Tue, 16 Jun 2020 11:12:54 -0700 Subject: [PATCH 2/4] Update setup.ps1 --- sdk/iot/Azure.Iot.Hub.Service/tests/prerequisites/setup.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/iot/Azure.Iot.Hub.Service/tests/prerequisites/setup.ps1 b/sdk/iot/Azure.Iot.Hub.Service/tests/prerequisites/setup.ps1 index e331d2ad6fd2..1ee60bc4e45b 100644 --- a/sdk/iot/Azure.Iot.Hub.Service/tests/prerequisites/setup.ps1 +++ b/sdk/iot/Azure.Iot.Hub.Service/tests/prerequisites/setup.ps1 @@ -77,7 +77,7 @@ if (-not $sp) } # Get test application OID from the service principal -$applicationOId = az ad sp show --id $sp --query "objectId" --output tsv +$applicationOId = az ad sp show --id $appId --query "objectId" --output tsv $rgExists = az group exists --name $ResourceGroup if ($rgExists -eq "False") From 24a0f24b84fd9334467758f04dc71d59063b57d0 Mon Sep 17 00:00:00 2001 From: Azad Abbasi Date: Tue, 16 Jun 2020 11:45:52 -0700 Subject: [PATCH 3/4] Update DevicesClientTests.cs --- .../tests/DevicesClientTests.cs | 52 +++++++++++++------ 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/sdk/iot/Azure.Iot.Hub.Service/tests/DevicesClientTests.cs b/sdk/iot/Azure.Iot.Hub.Service/tests/DevicesClientTests.cs index 050676646d88..fadc5796620f 100644 --- a/sdk/iot/Azure.Iot.Hub.Service/tests/DevicesClientTests.cs +++ b/sdk/iot/Azure.Iot.Hub.Service/tests/DevicesClientTests.cs @@ -1,8 +1,10 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using System; using System.Net; using System.Threading.Tasks; +using Azure.Iot.Hub.Service.Models; using FluentAssertions; using NUnit.Framework; @@ -16,33 +18,51 @@ public DevicesClientTests(bool isAsync) } [Test] + [Category("Live")] public async Task Devices_Lifecycle() { // TODO: This is just a verification that tests run and it requires the tester to complete this test however they see fit. - string testDeviceName = GetRandom(); + string testDeviceName = $"testDevice{GetRandom()}"; - IoTHubServiceClient client = GetClient(); + DeviceIdentity device = null; + IoTHubServiceClient client = GetClient(); try { - await client.Devices.GetIdentityAsync(testDeviceName).ConfigureAwait(false); + try + { + device = (await client.Devices.GetIdentityAsync(testDeviceName).ConfigureAwait(false)).Value; + } + catch (RequestFailedException ex) when (ex.Status == (int)HttpStatusCode.NotFound) + { + // If the Device doesn't exist, we will create it. + device = (await client.Devices.CreateOrUpdateIdentityAsync( + new Models.DeviceIdentity + { + DeviceId = testDeviceName + }).ConfigureAwait(false)).Value; + } + + // Perform another GET. We expect the device to exist. + Response response = await client.Devices.GetIdentityAsync(testDeviceName).ConfigureAwait(false); + device = response.Value; + response.GetRawResponse().Status.Should().Be(200); } - catch (RequestFailedException ex) when (ex.Status == (int)HttpStatusCode.NotFound) + finally { - // If the Device doesn't exist, we will create it. - await client.Devices.CreateOrUpdateIdentityAsync( - new Models.DeviceIdentity + // cleanup + try + { + if (device != null) + { + await client.Devices.DeleteIdentityAsync(device, IfMatchPrecondition.UnconditionalIfMatch).ConfigureAwait(false); + } + } + catch (Exception ex) { - DeviceId = testDeviceName - }).ConfigureAwait(false); + Assert.Fail($"Test clean up failed: {ex.Message}"); + } } - - // Perform another GET. We expect the device to exist. - Response response = await client.Devices.GetIdentityAsync(testDeviceName).ConfigureAwait(false); - response.GetRawResponse().Status.Should().Be(200); - - // Delete the device at the end. - await client.Devices.DeleteIdentityAsync(response.Value, IfMatchPrecondition.UnconditionalIfMatch).ConfigureAwait(false); } } } From bf43f99a49b3e8d0878d5d5be5d6c6265cac2771 Mon Sep 17 00:00:00 2001 From: Azad Abbasi Date: Tue, 16 Jun 2020 12:37:59 -0700 Subject: [PATCH 4/4] Generate code --- .../api/Azure.Iot.Hub.Service.netstandard2.0.cs | 12 ++++++------ .../tests/UpdateSessionRecords.ps1 | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) create mode 100644 sdk/iot/Azure.Iot.Hub.Service/tests/UpdateSessionRecords.ps1 diff --git a/sdk/iot/Azure.Iot.Hub.Service/api/Azure.Iot.Hub.Service.netstandard2.0.cs b/sdk/iot/Azure.Iot.Hub.Service/api/Azure.Iot.Hub.Service.netstandard2.0.cs index e7f94731e4d7..91aaec80d0d3 100644 --- a/sdk/iot/Azure.Iot.Hub.Service/api/Azure.Iot.Hub.Service.netstandard2.0.cs +++ b/sdk/iot/Azure.Iot.Hub.Service/api/Azure.Iot.Hub.Service.netstandard2.0.cs @@ -54,12 +54,12 @@ public IoTHubServiceClient(string connectionString) { } public IoTHubServiceClient(string connectionString, Azure.Iot.Hub.Service.IoTHubServiceClientOptions options) { } public IoTHubServiceClient(System.Uri endpoint, Azure.Core.TokenCredential credential) { } public IoTHubServiceClient(System.Uri endpoint, Azure.Core.TokenCredential credential, Azure.Iot.Hub.Service.IoTHubServiceClientOptions options) { } - public Azure.Iot.Hub.Service.DevicesClient Devices { get { throw null; } } - public Azure.Iot.Hub.Service.FilesClient Files { get { throw null; } } - public Azure.Iot.Hub.Service.JobsClient Jobs { get { throw null; } } - public Azure.Iot.Hub.Service.CloudToDeviceMessagesClient Messages { get { throw null; } } - public Azure.Iot.Hub.Service.ModulesClient Modules { get { throw null; } } - public Azure.Iot.Hub.Service.StatisticsClient Statistics { get { throw null; } } + public virtual Azure.Iot.Hub.Service.DevicesClient Devices { get { throw null; } } + public virtual Azure.Iot.Hub.Service.FilesClient Files { get { throw null; } } + public virtual Azure.Iot.Hub.Service.JobsClient Jobs { get { throw null; } } + public virtual Azure.Iot.Hub.Service.CloudToDeviceMessagesClient Messages { get { throw null; } } + public virtual Azure.Iot.Hub.Service.ModulesClient Modules { get { throw null; } } + public virtual Azure.Iot.Hub.Service.StatisticsClient Statistics { get { throw null; } } } public partial class IoTHubServiceClientOptions : Azure.Core.ClientOptions { diff --git a/sdk/iot/Azure.Iot.Hub.Service/tests/UpdateSessionRecords.ps1 b/sdk/iot/Azure.Iot.Hub.Service/tests/UpdateSessionRecords.ps1 new file mode 100644 index 000000000000..23c2c8b715ab --- /dev/null +++ b/sdk/iot/Azure.Iot.Hub.Service/tests/UpdateSessionRecords.ps1 @@ -0,0 +1 @@ +dotnet msbuild /t:UpdateSessionRecords \ No newline at end of file