From 22d11cc39c9d11dd3f107b01d5eeaeeb98133adb Mon Sep 17 00:00:00 2001 From: Abhipsa Misra Date: Wed, 17 Mar 2021 20:35:59 -0700 Subject: [PATCH 1/7] feat(all): Add support for .NET 5.0 --- e2e/test/E2ETests.csproj | 4 +-- .../E2ETestsSetup/e2eTestsSetup.ps1 | 32 ++++++++++++------- .../E2ETestsSetup/test-resources.bicep | 4 +-- .../E2ETestsSetup/test-resources.json | 11 +++++-- .../src/Microsoft.Azure.Devices.Client.csproj | 13 ++++++-- ...icrosoft.Azure.Devices.Client.Tests.csproj | 4 +-- .../src/Microsoft.Azure.Devices.csproj | 5 +-- .../Microsoft.Azure.Devices.Tests.csproj | 4 +-- ...t.Azure.Devices.Provisioning.Client.csproj | 2 +- ...e.Devices.Provisioning.Client.Tests.csproj | 2 +- ....Azure.Devices.Provisioning.Service.csproj | 3 +- ....Devices.Provisioning.Service.Tests.csproj | 2 +- ...Devices.Provisioning.Transport.Amqp.csproj | 2 +- ...s.Provisioning.Transport.Amqp.Tests.csproj | 2 +- ...Devices.Provisioning.Transport.Http.csproj | 5 ++- ...s.Provisioning.Transport.Http.Tests.csproj | 2 +- ...Devices.Provisioning.Transport.Mqtt.csproj | 2 +- ...s.Provisioning.Transport.Mqtt.Tests.csproj | 2 +- .../SecurityProviderTpmSimulator.csproj | 3 +- ...e.Devices.Provisioning.Security.Tpm.csproj | 2 +- ...ces.Provisioning.Security.Tpm.Tests.csproj | 2 +- .../src/Microsoft.Azure.Devices.Shared.csproj | 4 +-- ...icrosoft.Azure.Devices.Shared.Tests.csproj | 4 +-- .../TLS protocol tests.csproj | 4 +-- vsts/test-release-nuget.yaml | 8 +++-- vsts/vsts.yaml | 12 ++++--- 26 files changed, 90 insertions(+), 50 deletions(-) diff --git a/e2e/test/E2ETests.csproj b/e2e/test/E2ETests.csproj index 3684595457..aa044fca40 100644 --- a/e2e/test/E2ETests.csproj +++ b/e2e/test/E2ETests.csproj @@ -1,7 +1,7 @@  - netcoreapp3.1;netcoreapp2.1.18;net472;net451 - netcoreapp3.1;netcoreapp2.1.18 + net5.0;netcoreapp3.1;netcoreapp2.1.18;net472;net451 + net5.0;netcoreapp3.1;netcoreapp2.1.18 8.0 true false diff --git a/e2e/test/prerequisites/E2ETestsSetup/e2eTestsSetup.ps1 b/e2e/test/prerequisites/E2ETestsSetup/e2eTestsSetup.ps1 index 1e4dedb8cc..3f94fe89fa 100644 --- a/e2e/test/prerequisites/E2ETestsSetup/e2eTestsSetup.ps1 +++ b/e2e/test/prerequisites/E2ETestsSetup/e2eTestsSetup.ps1 @@ -13,7 +13,7 @@ param( [Parameter(Mandatory)] [string] $GroupCertificatePassword, - # Set this to true on the first execution to get everything installed in poweshell. Does not need to be run everytime. + # Set this to true on the first execution to get everything installed in powershell. Does not need to be run everytime. [Parameter()] [bool] $InstallDependencies = $true ) @@ -110,9 +110,10 @@ if (-not $isAdmin) ################################################################################################# $Region = $Region.Replace(' ', '') -$appRegistrationName = $ResourceGroup +$logAnalyticsAppRegnName = "$ResourceGroup-LogAnalyticsAadApp" $uploadCertificateName = "group1-certificate" $hubUploadCertificateName = "rootCA" +$certificateHashAlgorithm = "SHA256" ################################################################################################# @@ -142,7 +143,7 @@ $keyVaultName = "env-$ResourceGroup-kv" $keyVaultName = [regex]::Replace($keyVaultName, "[^a-zA-Z0-9-]", "") if (-not ($keyVaultName -match "^[a-zA-Z][a-zA-Z0-9-]{1,22}[a-zA-Z0-9]$")) { - throw "Key vault name derrived from resource group has illegal characters: $storageAccountName" + throw "Key vault name derrived from resource group has illegal characters: $keyVaultName" } ######################################################################################################## @@ -186,6 +187,7 @@ $rootCACert = New-SelfSignedCertificate ` -DnsName "$rootCommonName" ` -KeyUsage CertSign ` -TextExtension @("2.5.29.19={text}ca=TRUE&pathlength=12") ` + -HashAlgorithm "$certificateHashAlgorithm" ` -CertStoreLocation "Cert:\LocalMachine\My" ` -NotAfter (Get-Date).AddYears(2) @@ -193,6 +195,7 @@ $intermediateCert1 = New-SelfSignedCertificate ` -DnsName "$intermediateCert1CommonName" ` -KeyUsage CertSign ` -TextExtension @("2.5.29.19={text}ca=TRUE&pathlength=12") ` + -HashAlgorithm "$certificateHashAlgorithm" ` -CertStoreLocation "Cert:\LocalMachine\My" ` -NotAfter (Get-Date).AddYears(2) ` -Signer $rootCACert @@ -201,6 +204,7 @@ $intermediateCert2 = New-SelfSignedCertificate ` -DnsName "$intermediateCert2CommonName" ` -KeyUsage CertSign ` -TextExtension @("2.5.29.19={text}ca=TRUE&pathlength=12") ` + -HashAlgorithm "$certificateHashAlgorithm" ` -CertStoreLocation "Cert:\LocalMachine\My" ` -NotAfter (Get-Date).AddYears(2) ` -Signer $intermediateCert1 @@ -222,6 +226,7 @@ $groupDeviceCert = New-SelfSignedCertificate ` -DnsName "$groupCertCommonName" ` -KeySpec Signature ` -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.2") ` + -HashAlgorithm "$certificateHashAlgorithm" ` -CertStoreLocation "Cert:\LocalMachine\My" ` -NotAfter (Get-Date).AddYears(2) ` -Signer $intermediateCert2 @@ -234,6 +239,7 @@ $individualDeviceCert = New-SelfSignedCertificate ` -DnsName "$deviceCertCommonName" ` -KeySpec Signature ` -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.2") ` + -HashAlgorithm "$certificateHashAlgorithm" ` -CertStoreLocation "Cert:\LocalMachine\My" ` -NotAfter (Get-Date).AddYears(2) @@ -246,6 +252,7 @@ $iotHubCert = New-SelfSignedCertificate ` -DnsName "$iotHubCertCommonName" ` -KeySpec Signature ` -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.2") ` + -HashAlgorithm "$certificateHashAlgorithm" ` -CertStoreLocation "Cert:\LocalMachine\My" ` -NotAfter (Get-Date).AddYears(2) @@ -254,6 +261,7 @@ $iotHubChainDeviceCert = New-SelfSignedCertificate ` -DnsName "$iotHubCertChainDeviceCommonName" ` -KeySpec Signature ` -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.2") ` + -HashAlgorithm "$certificateHashAlgorithm" ` -CertStoreLocation "Cert:\LocalMachine\My" ` -NotAfter (Get-Date).AddYears(2) ` -Signer $intermediateCert2 @@ -317,12 +325,12 @@ if ($InstallDependencies) # Configure an AAD app and create self signed certs and get the bytes to generate more content info. ################################################################################################################################################# -$appId = az ad app list --show-mine --query "[?displayName=='$appRegistrationName'].appId" --output tsv +$appId = az ad app list --show-mine --query "[?displayName=='$logAnalyticsAppRegnName'].appId" --output tsv if (-not $appId) { - Write-Host "`nCreating App Registration $appRegistrationName" - $appId = az ad app create --display-name $appRegistrationName --reply-urls https://api.loganalytics.io/ --available-to-other-tenants false --query 'appId' --output tsv - Write-Host "`nApplication $appRegistrationName with Id $appId was created successfully." + Write-Host "`nCreating App Registration $logAnalyticsAppRegnName" + $appId = az ad app create --display-name $logAnalyticsAppRegnName --reply-urls https://api.loganalytics.io/ --available-to-other-tenants false --query 'appId' --output tsv + Write-Host "`nApplication $logAnalyticsAppRegnName with Id $appId was created successfully." } $spExists = az ad sp list --show-mine --query "[?appId=='$appId'].appId" --output tsv @@ -442,7 +450,8 @@ if ($isVerified -eq 'false') "-DnsName" = $requestedCommonName; "-CertStoreLocation" = "cert:\LocalMachine\My"; "-NotAfter" = (get-date).AddYears(2); - "-TextExtension" = @("2.5.29.37={text}1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.1", "2.5.29.19={text}ca=FALSE&pathlength=0"); + "-TextExtension" = @("2.5.29.37={text}1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.1", "2.5.29.19={text}ca=FALSE&pathlength=0"); + "-HashAlgorithm" = $certificateHashAlgorithm; "-Signer" = $rootCACert; } $verificationCert = New-SelfSignedCertificate @verificationCertArgs @@ -455,7 +464,7 @@ if ($isVerified -eq 'false') # Create device in IoTHub that uses a certificate signed by intermediate certificate ################################################################################################################################## -$iotHubCertChainDevice = az iot hub device-identity list -g $ResourceGroup --hub-name $iotHubName-hub --query "[?deviceId=='$iotHubCertChainDeviceCommonName'].deviceId" --output tsv +$iotHubCertChainDevice = az iot hub device-identity list -g $ResourceGroup --hub-name $iotHubName --query "[?deviceId=='$iotHubCertChainDeviceCommonName'].deviceId" --output tsv if (-not $iotHubCertChainDevice) { @@ -488,7 +497,8 @@ if ($isVerified -eq 'false') "-DnsName" = $requestedCommonName; "-CertStoreLocation" = "cert:\LocalMachine\My"; "-NotAfter" = (get-date).AddYears(2); - "-TextExtension" = @("2.5.29.37={text}1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.1", "2.5.29.19={text}ca=FALSE&pathlength=0"); + "-TextExtension" = @("2.5.29.37={text}1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.1", "2.5.29.19={text}ca=FALSE&pathlength=0"); + "-HashAlgorithm" = $certificateHashAlgorithm; "-Signer" = $rootCACert; } $verificationCert = New-SelfSignedCertificate @verificationCertArgs @@ -557,7 +567,7 @@ while (++$tries -le 10) Write-Host "`nCreating a self-signed certificate and placing it in $ResourceGroup" az ad app credential reset --id $appId --create-cert --keyvault $keyVaultName --cert $ResourceGroup --output none -Write-Host "`nSuccessfully created a self signed certificate for your application $appRegistrationName in $keyVaultName key vault with cert name $ResourceGroup"; +Write-Host "`nSuccessfully created a self signed certificate for your application $logAnalyticsAppRegnName in $keyVaultName key vault with cert name $ResourceGroup"; Write-Host "`nFetching the certificate binary" $selfSignedCerts = "$PSScriptRoot\selfSignedCerts" diff --git a/e2e/test/prerequisites/E2ETestsSetup/test-resources.bicep b/e2e/test/prerequisites/E2ETestsSetup/test-resources.bicep index ffb3a2c8cf..69f2757b59 100644 --- a/e2e/test/prerequisites/E2ETestsSetup/test-resources.bicep +++ b/e2e/test/prerequisites/E2ETestsSetup/test-resources.bicep @@ -229,7 +229,7 @@ resource iotHub 'Microsoft.Devices/IotHubs@2020-01-01' = { eventHubEndpoints: { events: { retentionTimeInDays: 1 - partitionCount: 10 + partitionCount: 4 } } cloudToDevice: { @@ -260,7 +260,7 @@ resource iotHub 'Microsoft.Devices/IotHubs@2020-01-01' = { sku: { name: 'S1' tier: 'Standard' - capacity: 1 + capacity: 3 } dependsOn: [ container diff --git a/e2e/test/prerequisites/E2ETestsSetup/test-resources.json b/e2e/test/prerequisites/E2ETestsSetup/test-resources.json index 2e76516351..45eaac495f 100644 --- a/e2e/test/prerequisites/E2ETestsSetup/test-resources.json +++ b/e2e/test/prerequisites/E2ETestsSetup/test-resources.json @@ -250,7 +250,7 @@ "eventHubEndpoints": { "events": { "retentionTimeInDays": 1, - "partitionCount": 10 + "partitionCount": 4 } }, "cloudToDevice": { @@ -281,7 +281,7 @@ "sku": { "name": "S1", "tier": "Standard", - "capacity": 1 + "capacity": 3 }, "dependsOn": [ "[resourceId('Microsoft.Storage/storageAccounts/blobServices/containers', split(format('{0}/{1}', format('{0}/{1}', parameters('StorageAccountName'), parameters('BlobServiceName')), parameters('ContainerName')), '/')[0], split(format('{0}/{1}', format('{0}/{1}', parameters('StorageAccountName'), parameters('BlobServiceName')), parameters('ContainerName')), '/')[1], split(format('{0}/{1}', format('{0}/{1}', parameters('StorageAccountName'), parameters('BlobServiceName')), parameters('ContainerName')), '/')[2])]", @@ -498,5 +498,12 @@ "type": "string", "value": "[reference(resourceId('Microsoft.Insights/components', parameters('ApplicationInsightsName')), '2015-05-01').InstrumentationKey]" } + }, + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.3.1.62928", + "templateHash": "5703369743693135956" + } } } \ No newline at end of file diff --git a/iothub/device/src/Microsoft.Azure.Devices.Client.csproj b/iothub/device/src/Microsoft.Azure.Devices.Client.csproj index f5574ac86e..be9a98d602 100644 --- a/iothub/device/src/Microsoft.Azure.Devices.Client.csproj +++ b/iothub/device/src/Microsoft.Azure.Devices.Client.csproj @@ -1,7 +1,7 @@  - netstandard2.1;netstandard2.0;net472;net451 - netstandard2.1;netstandard2.0 + net5.0;netstandard2.1;netstandard2.0;net472;net451 + net5.0;netstandard2.1;netstandard2.0 8.0 true @@ -60,6 +60,15 @@ Common + + Common + + + Common + + + Common + diff --git a/iothub/device/tests/Microsoft.Azure.Devices.Client.Tests.csproj b/iothub/device/tests/Microsoft.Azure.Devices.Client.Tests.csproj index 3928ef3cfa..7006e6b8e0 100644 --- a/iothub/device/tests/Microsoft.Azure.Devices.Client.Tests.csproj +++ b/iothub/device/tests/Microsoft.Azure.Devices.Client.Tests.csproj @@ -1,7 +1,7 @@  - netcoreapp3.1;netcoreapp2.1.18;net472;net451 - netcoreapp3.1;netcoreapp2.1.18 + net5.0;netcoreapp3.1;netcoreapp2.1.18;net472;net451 + net5.0;netcoreapp3.1;netcoreapp2.1.18 8.0 False diff --git a/iothub/service/src/Microsoft.Azure.Devices.csproj b/iothub/service/src/Microsoft.Azure.Devices.csproj index 98827e5733..10fada0923 100644 --- a/iothub/service/src/Microsoft.Azure.Devices.csproj +++ b/iothub/service/src/Microsoft.Azure.Devices.csproj @@ -1,7 +1,7 @@  - netstandard2.1;netstandard2.0;net472;net451 - netstandard2.1;netstandard2.0 + net5.0;netstandard2.1;netstandard2.0;net472;net451 + net5.0;netstandard2.1;netstandard2.0 8.0 true @@ -116,6 +116,7 @@ Common\Utils.cs + diff --git a/iothub/service/tests/Microsoft.Azure.Devices.Tests.csproj b/iothub/service/tests/Microsoft.Azure.Devices.Tests.csproj index 75461e56c3..8b572f5ee9 100644 --- a/iothub/service/tests/Microsoft.Azure.Devices.Tests.csproj +++ b/iothub/service/tests/Microsoft.Azure.Devices.Tests.csproj @@ -1,8 +1,8 @@  - netcoreapp3.1;netcoreapp2.1.18;net472;net451 - netcoreapp3.1;netcoreapp2.1.18 + net5.0;netcoreapp3.1;netcoreapp2.1.18;net472;net451 + net5.0;netcoreapp3.1;netcoreapp2.1.18 False 8.0 diff --git a/provisioning/device/src/Microsoft.Azure.Devices.Provisioning.Client.csproj b/provisioning/device/src/Microsoft.Azure.Devices.Provisioning.Client.csproj index 2df6da50c0..22120ac89b 100644 --- a/provisioning/device/src/Microsoft.Azure.Devices.Provisioning.Client.csproj +++ b/provisioning/device/src/Microsoft.Azure.Devices.Provisioning.Client.csproj @@ -1,6 +1,6 @@ - netstandard2.1;netstandard2.0 + net5.0;netstandard2.1;netstandard2.0 8.0 true true diff --git a/provisioning/device/tests/Microsoft.Azure.Devices.Provisioning.Client.Tests.csproj b/provisioning/device/tests/Microsoft.Azure.Devices.Provisioning.Client.Tests.csproj index 2dea5afdb2..94f283b06e 100644 --- a/provisioning/device/tests/Microsoft.Azure.Devices.Provisioning.Client.Tests.csproj +++ b/provisioning/device/tests/Microsoft.Azure.Devices.Provisioning.Client.Tests.csproj @@ -1,7 +1,7 @@  - netcoreapp3.1;netcoreapp2.1.18 + net5.0;netcoreapp3.1;netcoreapp2.1.18 8.0 False diff --git a/provisioning/service/src/Microsoft.Azure.Devices.Provisioning.Service.csproj b/provisioning/service/src/Microsoft.Azure.Devices.Provisioning.Service.csproj index 2e071576c1..dae501a22e 100644 --- a/provisioning/service/src/Microsoft.Azure.Devices.Provisioning.Service.csproj +++ b/provisioning/service/src/Microsoft.Azure.Devices.Provisioning.Service.csproj @@ -1,7 +1,7 @@ - netstandard2.1;netstandard2.0 + net5.0;netstandard2.1;netstandard2.0 8.0 true true @@ -50,6 +50,7 @@ + diff --git a/provisioning/service/tests/Microsoft.Azure.Devices.Provisioning.Service.Tests.csproj b/provisioning/service/tests/Microsoft.Azure.Devices.Provisioning.Service.Tests.csproj index 34927fc0bf..178c417cd0 100644 --- a/provisioning/service/tests/Microsoft.Azure.Devices.Provisioning.Service.Tests.csproj +++ b/provisioning/service/tests/Microsoft.Azure.Devices.Provisioning.Service.Tests.csproj @@ -1,7 +1,7 @@  - netcoreapp3.1;netcoreapp2.1.18 + net5.0;netcoreapp3.1;netcoreapp2.1.18 False 8.0 diff --git a/provisioning/transport/amqp/src/Microsoft.Azure.Devices.Provisioning.Transport.Amqp.csproj b/provisioning/transport/amqp/src/Microsoft.Azure.Devices.Provisioning.Transport.Amqp.csproj index 07c252e6df..0e6701a411 100644 --- a/provisioning/transport/amqp/src/Microsoft.Azure.Devices.Provisioning.Transport.Amqp.csproj +++ b/provisioning/transport/amqp/src/Microsoft.Azure.Devices.Provisioning.Transport.Amqp.csproj @@ -1,7 +1,7 @@ - netstandard2.1;netstandard2.0 + net5.0;netstandard2.1;netstandard2.0 8.0 true Microsoft.Azure.Devices.Provisioning.Client.Transport diff --git a/provisioning/transport/amqp/tests/Microsoft.Azure.Devices.Provisioning.Transport.Amqp.Tests.csproj b/provisioning/transport/amqp/tests/Microsoft.Azure.Devices.Provisioning.Transport.Amqp.Tests.csproj index a16273abb1..16d9df9666 100644 --- a/provisioning/transport/amqp/tests/Microsoft.Azure.Devices.Provisioning.Transport.Amqp.Tests.csproj +++ b/provisioning/transport/amqp/tests/Microsoft.Azure.Devices.Provisioning.Transport.Amqp.Tests.csproj @@ -1,7 +1,7 @@  - netcoreapp3.1;netcoreapp2.1.18 + net5.0;netcoreapp3.1;netcoreapp2.1.18 False 8.0 diff --git a/provisioning/transport/http/src/Microsoft.Azure.Devices.Provisioning.Transport.Http.csproj b/provisioning/transport/http/src/Microsoft.Azure.Devices.Provisioning.Transport.Http.csproj index 34e52daf1e..15a7eee417 100644 --- a/provisioning/transport/http/src/Microsoft.Azure.Devices.Provisioning.Transport.Http.csproj +++ b/provisioning/transport/http/src/Microsoft.Azure.Devices.Provisioning.Transport.Http.csproj @@ -1,7 +1,7 @@ - netstandard2.1;netstandard2.0 + net5.0;netstandard2.1;netstandard2.0 8.0 true Microsoft.Azure.Devices.Provisioning.Client.Transport @@ -83,6 +83,9 @@ Generated\Models\DeviceRegistration.cs + + Common + diff --git a/provisioning/transport/http/tests/Microsoft.Azure.Devices.Provisioning.Transport.Http.Tests.csproj b/provisioning/transport/http/tests/Microsoft.Azure.Devices.Provisioning.Transport.Http.Tests.csproj index df36da49dd..5dca5a9d01 100644 --- a/provisioning/transport/http/tests/Microsoft.Azure.Devices.Provisioning.Transport.Http.Tests.csproj +++ b/provisioning/transport/http/tests/Microsoft.Azure.Devices.Provisioning.Transport.Http.Tests.csproj @@ -1,7 +1,7 @@  - netcoreapp3.1;netcoreapp2.1.18 + net5.0;netcoreapp3.1;netcoreapp2.1.18 False 8.0 diff --git a/provisioning/transport/mqtt/src/Microsoft.Azure.Devices.Provisioning.Transport.Mqtt.csproj b/provisioning/transport/mqtt/src/Microsoft.Azure.Devices.Provisioning.Transport.Mqtt.csproj index f06ab5f483..4a73bb88ae 100644 --- a/provisioning/transport/mqtt/src/Microsoft.Azure.Devices.Provisioning.Transport.Mqtt.csproj +++ b/provisioning/transport/mqtt/src/Microsoft.Azure.Devices.Provisioning.Transport.Mqtt.csproj @@ -1,7 +1,7 @@ - netstandard2.1;netstandard2.0 + net5.0;netstandard2.1;netstandard2.0 8.0 true Microsoft.Azure.Devices.Provisioning.Client.Transport diff --git a/provisioning/transport/mqtt/tests/Microsoft.Azure.Devices.Provisioning.Transport.Mqtt.Tests.csproj b/provisioning/transport/mqtt/tests/Microsoft.Azure.Devices.Provisioning.Transport.Mqtt.Tests.csproj index 01ba2ddb59..ca2c8374e4 100644 --- a/provisioning/transport/mqtt/tests/Microsoft.Azure.Devices.Provisioning.Transport.Mqtt.Tests.csproj +++ b/provisioning/transport/mqtt/tests/Microsoft.Azure.Devices.Provisioning.Transport.Mqtt.Tests.csproj @@ -1,7 +1,7 @@  - netcoreapp3.1;netcoreapp2.1.18 + net5.0;netcoreapp3.1;netcoreapp2.1.18 False 8.0 diff --git a/security/tpm/samples/SecurityProviderTpmSimulator/SecurityProviderTpmSimulator.csproj b/security/tpm/samples/SecurityProviderTpmSimulator/SecurityProviderTpmSimulator.csproj index eae5928360..c838395cb4 100644 --- a/security/tpm/samples/SecurityProviderTpmSimulator/SecurityProviderTpmSimulator.csproj +++ b/security/tpm/samples/SecurityProviderTpmSimulator/SecurityProviderTpmSimulator.csproj @@ -1,7 +1,8 @@ - netstandard2.0 + net5.0;netstandard2.1;netstandard2.0 + 8.0 true Microsoft.Azure.Devices.Provisioning.Security diff --git a/security/tpm/src/Microsoft.Azure.Devices.Provisioning.Security.Tpm.csproj b/security/tpm/src/Microsoft.Azure.Devices.Provisioning.Security.Tpm.csproj index c46bd334ec..0600f7a479 100644 --- a/security/tpm/src/Microsoft.Azure.Devices.Provisioning.Security.Tpm.csproj +++ b/security/tpm/src/Microsoft.Azure.Devices.Provisioning.Security.Tpm.csproj @@ -1,7 +1,7 @@ - netstandard2.1;netstandard2.0 + net5.0;netstandard2.1;netstandard2.0 8.0 true true diff --git a/security/tpm/tests/Microsoft.Azure.Devices.Provisioning.Security.Tpm.Tests.csproj b/security/tpm/tests/Microsoft.Azure.Devices.Provisioning.Security.Tpm.Tests.csproj index 283baacb03..93a1fdd96e 100644 --- a/security/tpm/tests/Microsoft.Azure.Devices.Provisioning.Security.Tpm.Tests.csproj +++ b/security/tpm/tests/Microsoft.Azure.Devices.Provisioning.Security.Tpm.Tests.csproj @@ -1,7 +1,7 @@  - netcoreapp3.1;netcoreapp2.1.18 + net5.0;netcoreapp3.1;netcoreapp2.1.18 False 8.0 diff --git a/shared/src/Microsoft.Azure.Devices.Shared.csproj b/shared/src/Microsoft.Azure.Devices.Shared.csproj index 2d5cd6eda1..ccc3042b2d 100644 --- a/shared/src/Microsoft.Azure.Devices.Shared.csproj +++ b/shared/src/Microsoft.Azure.Devices.Shared.csproj @@ -1,7 +1,7 @@ - netstandard2.1;netstandard2.0;net472;net451 - netstandard2.1;netstandard2.0 + net5.0;netstandard2.1;netstandard2.0;net472;net451 + net5.0;netstandard2.1;netstandard2.0 8.0 true true diff --git a/shared/tests/Microsoft.Azure.Devices.Shared.Tests.csproj b/shared/tests/Microsoft.Azure.Devices.Shared.Tests.csproj index e96e79c80a..3635d21a6a 100644 --- a/shared/tests/Microsoft.Azure.Devices.Shared.Tests.csproj +++ b/shared/tests/Microsoft.Azure.Devices.Shared.Tests.csproj @@ -1,8 +1,8 @@  Microsoft.Azure.Devices.Shared.Tests - netcoreapp3.1;netcoreapp2.1.18;net472;net451 - netcoreapp3.1;netcoreapp2.1.18 + net5.0;netcoreapp3.1;netcoreapp2.1.18;net472;net451 + net5.0;netcoreapp3.1;netcoreapp2.1.18 False diff --git a/tools/TLS Protocols Tests/TLS protocol tests.csproj b/tools/TLS Protocols Tests/TLS protocol tests.csproj index c7da7b5c5f..04388616aa 100644 --- a/tools/TLS Protocols Tests/TLS protocol tests.csproj +++ b/tools/TLS Protocols Tests/TLS protocol tests.csproj @@ -2,8 +2,8 @@ Exe - netcoreapp2.1;net451 - netcoreapp2.1 + net5.0;netcoreapp2.1;net451 + net5.0;netcoreapp2.1 TlsProtocolTests TlsProtocolTests false diff --git a/vsts/test-release-nuget.yaml b/vsts/test-release-nuget.yaml index 80345c4b9c..6f79fa8280 100644 --- a/vsts/test-release-nuget.yaml +++ b/vsts/test-release-nuget.yaml @@ -11,6 +11,8 @@ jobs: # Change maxParallel to 1 make builds run in serial rather than in parallel maxParallel: 100 matrix: + .Net 5.0: + FRAMEWORK: net5.0 .Net Core 3.1: FRAMEWORK: netcoreapp3.1 .Net Core 2.1.18: @@ -18,7 +20,7 @@ jobs: condition: succeeded() pool: - name: Hosted Ubuntu 1604 + vmImage: ubuntu-20.04 steps: - task: DownloadBuildArtifacts@0 inputs: @@ -125,6 +127,8 @@ jobs: # Change maxParallel to 1 make builds run in serial rather than in parallel maxParallel: 100 matrix: + .Net 5.0: + FRAMEWORK: net5.0 .Net Core 3.1: FRAMEWORK: netcoreapp3.1 .Net Core 2.1.18: @@ -136,7 +140,7 @@ jobs: condition: succeeded() pool: - name: Hosted VS2017 + vmImage: windows-2019 steps: - task: DownloadBuildArtifacts@0 inputs: diff --git a/vsts/vsts.yaml b/vsts/vsts.yaml index d4d8b1d7c6..df4b7df2ee 100644 --- a/vsts/vsts.yaml +++ b/vsts/vsts.yaml @@ -25,6 +25,8 @@ jobs: # Change maxParallel to 1 make builds run in serial rather than in parallel maxParallel: 100 matrix: + .Net 5.0: + FRAMEWORK: net5.0 .Net Core 3.1: FRAMEWORK: netcoreapp3.1 .Net Core 2.1.18: @@ -32,7 +34,7 @@ jobs: condition: succeeded() pool: - name: Hosted Ubuntu 1604 + vmImage: ubuntu-20.04 steps: - task: Docker@1 displayName: "Start TPM Simulator" @@ -127,6 +129,8 @@ jobs: # Change maxParallel to 1 make builds run in serial rather than in parallel maxParallel: 100 matrix: + .Net 5.0: + FRAMEWORK: net5.0 .Net Core 3.1: FRAMEWORK: netcoreapp3.1 .Net Core 2.1.18: @@ -138,10 +142,10 @@ jobs: condition: succeeded() pool: - name: Hosted VS2017 + vmImage: windows-2019 steps: - script: | - call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Enterprise\\Common7\\Tools\\VsDevCmd.bat" + call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\Common7\\Tools\\VsDevCmd.bat" sn -Vr *,31bf3856ad364e35 displayName: "Disable strong name validation" @@ -233,7 +237,7 @@ jobs: condition: succeeded() pool: - name: Hosted VS2017 + vmImage: windows-latest steps: - script: | rem Run dotnet first experience. From e84af40c39c7509a8c7c8cf7717b7f287dc7a73d Mon Sep 17 00:00:00 2001 From: Abhipsa Misra Date: Wed, 17 Mar 2021 20:52:02 -0700 Subject: [PATCH 2/7] refactor(all): Update APIs to follow .NET 5.0 patterns --- common/src/HttpContentExtensions.cs | 54 +++++++++++ common/src/HttpMessageHelper.cs | 51 ++++++++++ common/src/StreamExtensions.cs | 21 ++++ common/src/TaskCompletionSource.cs | 34 +++++++ common/src/service/HttpClientHelper.cs | 64 +++---------- ...DeviceAuthenticationWithX509Certificate.cs | 6 +- .../Transport/HttpUdsMessageHandler.cs | 9 +- .../src/Transport/AmqpIoT/AmqpIoTConnector.cs | 7 +- .../device/src/Transport/HttpClientHelper.cs | 5 +- .../src/Transport/HttpTransportHandler.cs | 2 +- .../src/Transport/Mqtt/MqttIotHubAdapter.cs | 13 ++- .../Transport/Mqtt/MqttTransportHandler.cs | 11 ++- .../src/Transport/Mqtt/SimpleWorkQueue.cs | 11 ++- ...RetryDelegatingHandlerImplicitOpenTests.cs | 6 +- .../service/src/Contract/ContractApiHttp.cs | 2 +- .../Config/X509CertificateWithInfoTests.cs | 10 +- .../tests/Config/X509CertificatesTests.cs | 22 ++--- .../ProvisioningErrorDetailsAmqpTests.cs | 96 +++++++++++-------- .../http/src/Generated/RuntimeRegistration.cs | 15 +-- .../transport/http/src/TPM/TpmCredentials.cs | 6 ++ .../http/src/TPM/TpmDelegatingHandler.cs | 13 +-- .../SecurityProviderTpmSimulator.cs | 23 +++-- 22 files changed, 317 insertions(+), 164 deletions(-) create mode 100644 common/src/HttpContentExtensions.cs create mode 100644 common/src/HttpMessageHelper.cs create mode 100644 common/src/StreamExtensions.cs create mode 100644 common/src/TaskCompletionSource.cs diff --git a/common/src/HttpContentExtensions.cs b/common/src/HttpContentExtensions.cs new file mode 100644 index 0000000000..dac9a9e050 --- /dev/null +++ b/common/src/HttpContentExtensions.cs @@ -0,0 +1,54 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.IO; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +namespace Microsoft.Azure.Devices.Shared +{ + internal static class HttpContentExtensions + { + internal static async Task CopyToStreamAsync(this HttpContent content, Stream stream, CancellationToken cancellationToken) + { +#if NET5_0 + await content.CopyToAsync(stream, cancellationToken).ConfigureAwait(false); +#else + _ = cancellationToken; + await content.CopyToAsync(stream).ConfigureAwait(false); +#endif + } + + internal static Task ReadHttpContentAsStream(this HttpContent httpContent, CancellationToken cancellationToken) + { +#if NET5_0 + return httpContent.ReadAsStreamAsync(cancellationToken); +#else + _ = cancellationToken; + return httpContent.ReadAsStreamAsync(); +#endif + } + + internal static Task ReadHttpContentAsByteArrayAsync(this HttpContent content, CancellationToken cancellationToken) + { +#if NET5_0 + return content.ReadAsByteArrayAsync(cancellationToken); +#else + _ = cancellationToken; + return content.ReadAsByteArrayAsync(); +#endif + } + + internal static Task ReadHttpContentAsStringAsync(this HttpContent content, CancellationToken cancellationToken) + { +#if NET5_0 + return content.ReadAsStringAsync(cancellationToken); +#else + _ = cancellationToken; + return content.ReadAsStringAsync(); +#endif + } + + } +} \ No newline at end of file diff --git a/common/src/HttpMessageHelper.cs b/common/src/HttpMessageHelper.cs new file mode 100644 index 0000000000..0fe47b0972 --- /dev/null +++ b/common/src/HttpMessageHelper.cs @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Net.Http; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Newtonsoft.Json; + +#if NET451 +using System.Net.Http.Formatting; +#endif + +namespace Microsoft.Azure.Devices.Shared +{ + internal static class HttpMessageHelper + { +#if !NET451 + private const string ApplicationJson = "application/json"; +#endif + +#if NET451 + private static readonly JsonMediaTypeFormatter s_jsonFormatter = new JsonMediaTypeFormatter(); +#endif + + internal static void SetHttpRequestMessageContent(HttpRequestMessage requestMessage, T entity) + { +#if NET451 + requestMessage.Content = new ObjectContent(entity, s_jsonFormatter); +#else + string str = JsonConvert.SerializeObject(entity); + requestMessage.Content = new StringContent(str, Encoding.UTF8, ApplicationJson); +#endif + } + + internal static async Task ReadHttpResponseMessageContentAsync(HttpResponseMessage message, CancellationToken token) + { +#if NET451 + T entity = await message.Content.ReadAsAsync(token).ConfigureAwait(false); +#elif NET5_0 + string str = await message.Content.ReadAsStringAsync(token).ConfigureAwait(false); + T entity = JsonConvert.DeserializeObject(str); +#else + _ = token; + string str = await message.Content.ReadAsStringAsync().ConfigureAwait(false); + T entity = JsonConvert.DeserializeObject(str); +#endif + return entity; + } + } +} \ No newline at end of file diff --git a/common/src/StreamExtensions.cs b/common/src/StreamExtensions.cs new file mode 100644 index 0000000000..1e73a4bfea --- /dev/null +++ b/common/src/StreamExtensions.cs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.IO; +using System.Threading; +using System.Threading.Tasks; + +namespace Microsoft.Azure.Devices.Shared +{ + internal static class StreamExtensions + { + internal static async Task WriteToStreamAsync(this Stream stream, byte[] requestBytes, CancellationToken cancellationToken) + { +#if NET451 || NET472 || NETSTANDARD2_0 + await stream.WriteAsync(requestBytes, 0, requestBytes.Length, cancellationToken).ConfigureAwait(false); +#else + await stream.WriteAsync(requestBytes, cancellationToken).ConfigureAwait(false); +#endif + } + } +} \ No newline at end of file diff --git a/common/src/TaskCompletionSource.cs b/common/src/TaskCompletionSource.cs new file mode 100644 index 0000000000..0091e9c42f --- /dev/null +++ b/common/src/TaskCompletionSource.cs @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Threading.Tasks; + +namespace Microsoft.Azure.Devices.Shared +{ + internal sealed class TaskCompletionSource : TaskCompletionSource + { + public static readonly TaskCompletionSource Void = CreateVoidTcs(); + + public TaskCompletionSource(object state) + : base(state) + { + } + + public TaskCompletionSource() + { + } + + public bool TrySetResult() => TrySetResult(0); + + public void SetResult() => SetResult(0); + + public override string ToString() => "TaskCompletionSource[status: " + Task.Status.ToString() + "]"; + + static TaskCompletionSource CreateVoidTcs() + { + var tcs = new TaskCompletionSource(); + tcs.TrySetResult(); + return tcs; + } + } +} \ No newline at end of file diff --git a/common/src/service/HttpClientHelper.cs b/common/src/service/HttpClientHelper.cs index c48fa5fa33..f04d56129e 100644 --- a/common/src/service/HttpClientHelper.cs +++ b/common/src/service/HttpClientHelper.cs @@ -10,7 +10,6 @@ using System.Net; using System.Net.Http; using System.Net.Http.Headers; -using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.Azure.Devices.Common; @@ -19,19 +18,13 @@ using Microsoft.Azure.Devices.Shared; using Newtonsoft.Json; -#if NET451 -using System.Net.Http.Formatting; -#endif +using static Microsoft.Azure.Devices.Shared.HttpMessageHelper; namespace Microsoft.Azure.Devices { internal sealed class HttpClientHelper : IHttpClientHelper { private const string ApplicationJson = "application/json"; - -#if NET451 - static readonly JsonMediaTypeFormatter JsonFormatter = new JsonMediaTypeFormatter(); -#endif private readonly Uri _baseAddress; private readonly IAuthorizationHeaderProvider _authenticationHeaderProvider; private readonly IReadOnlyDictionary>> _defaultErrorMapping; @@ -201,12 +194,8 @@ await ExecuteAsync( (requestMsg, token) => { InsertEtag(requestMsg, entity, operationType); -#if NET451 - requestMsg.Content = new ObjectContent(entity, JsonFormatter); -#else - string str = JsonConvert.SerializeObject(entity); - requestMsg.Content = new StringContent(str, Encoding.UTF8, ApplicationJson); -#endif + SetHttpRequestMessageContent(requestMsg, entity); + return Task.FromResult(0); }, async (httpClient, token) => result = await ReadResponseMessageAsync(httpClient, token).ConfigureAwait(false), @@ -230,12 +219,7 @@ await ExecuteAsync( new Uri(_baseAddress, requestUri), (requestMsg, token) => { -#if NET451 - requestMsg.Content = new ObjectContent(entity, JsonFormatter); -#else - string str = JsonConvert.SerializeObject(entity); - requestMsg.Content = new StringContent(str, System.Text.Encoding.UTF8, ApplicationJson); -#endif + SetHttpRequestMessageContent(requestMsg, entity); return Task.FromResult(0); }, async (httpClient, token) => result = await ReadResponseMessageAsync(httpClient, token).ConfigureAwait(false), @@ -259,12 +243,8 @@ await ExecuteAsync( (requestMsg, token) => { InsertEtag(requestMsg, etag, operationType); -#if NET451 - requestMsg.Content = new ObjectContent(entity, JsonFormatter); -#else - string str = Newtonsoft.Json.JsonConvert.SerializeObject(entity); - requestMsg.Content = new StringContent(str, System.Text.Encoding.UTF8, ApplicationJson); -#endif + SetHttpRequestMessageContent(requestMsg, entity); + return Task.FromResult(0); }, null, @@ -289,12 +269,8 @@ await ExecuteAsync( { // TODO: skintali: Use string etag when service side changes are ready InsertEtag(requestMsg, etag, operationType); -#if NET451 - requestMsg.Content = new ObjectContent(entity, JsonFormatter); -#else - string str = JsonConvert.SerializeObject(entity); - requestMsg.Content = new StringContent(str, Encoding.UTF8, ApplicationJson); -#endif + SetHttpRequestMessageContent(requestMsg, entity); + return Task.FromResult(0); }, async (httpClient, token) => result = await ReadResponseMessageAsync(httpClient, token).ConfigureAwait(false), @@ -313,12 +289,8 @@ await ExecuteAsync( (requestMsg, token) => { InsertEtag(requestMsg, etag, PutOperationType.UpdateEntity); -#if NET451 - requestMsg.Content = new ObjectContent(entity, JsonFormatter); -#else - string str = JsonConvert.SerializeObject(entity); - requestMsg.Content = new StringContent(str, Encoding.UTF8, ApplicationJson); -#endif + SetHttpRequestMessageContent(requestMsg, entity); + return Task.FromResult(0); }, null, @@ -339,12 +311,8 @@ await ExecuteAsync( (requestMsg, token) => { InsertEtag(requestMsg, etag, putOperationType); -#if NET451 - requestMsg.Content = new ObjectContent(entity, JsonFormatter); -#else - string str = JsonConvert.SerializeObject(entity); - requestMsg.Content = new StringContent(str, System.Text.Encoding.UTF8, ApplicationJson); -#endif + SetHttpRequestMessageContent(requestMsg, entity); + return Task.FromResult(0); }, async (httpClient, token) => result = await ReadResponseMessageAsync(httpClient, token).ConfigureAwait(false), @@ -361,12 +329,8 @@ private static async Task ReadResponseMessageAsync(HttpResponseMessage mes return (T)(object)message; } -#if NET451 - T entity = await message.Content.ReadAsAsync(token).ConfigureAwait(false); -#else - string str = await message.Content.ReadAsStringAsync().ConfigureAwait(false); - T entity = JsonConvert.DeserializeObject(str); -#endif + T entity = await ReadHttpResponseMessageContentAsync(message, token).ConfigureAwait(false); + // Etag in the header is considered authoritative var eTagHolder = entity as IETagHolder; if (eTagHolder != null) diff --git a/iothub/device/src/DeviceAuthenticationWithX509Certificate.cs b/iothub/device/src/DeviceAuthenticationWithX509Certificate.cs index b8e62fb24b..6b3074e0d4 100644 --- a/iothub/device/src/DeviceAuthenticationWithX509Certificate.cs +++ b/iothub/device/src/DeviceAuthenticationWithX509Certificate.cs @@ -82,14 +82,10 @@ private void SetDeviceId(string deviceId) } /// - /// Dispose the X509 certificate associated with this authentication method. + /// The managed resource should be disposed by the user. /// public void Dispose() { -#if !NET451 - Certificate?.Dispose(); - Certificate = null; -#endif } } } diff --git a/iothub/device/src/ModernDotNet/HsmAuthentication/Transport/HttpUdsMessageHandler.cs b/iothub/device/src/ModernDotNet/HsmAuthentication/Transport/HttpUdsMessageHandler.cs index b72c87d203..66a0ea0372 100644 --- a/iothub/device/src/ModernDotNet/HsmAuthentication/Transport/HttpUdsMessageHandler.cs +++ b/iothub/device/src/ModernDotNet/HsmAuthentication/Transport/HttpUdsMessageHandler.cs @@ -6,6 +6,7 @@ using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; +using Microsoft.Azure.Devices.Shared; namespace Microsoft.Azure.Devices.Client.HsmAuthentication.Transport { @@ -25,15 +26,11 @@ protected override async Task SendAsync(HttpRequestMessage using var stream = new HttpBufferedStream(new NetworkStream(socket, true)); byte[] requestBytes = HttpRequestResponseSerializer.SerializeRequest(request); + await stream.WriteToStreamAsync(requestBytes, cancellationToken).ConfigureAwait(false); -#if NET451 || NET472 || NETSTANDARD2_0 - await stream.WriteAsync(requestBytes, 0, requestBytes.Length, cancellationToken).ConfigureAwait(false); -#else - await stream.WriteAsync(requestBytes, cancellationToken).ConfigureAwait(false); -#endif if (request.Content != null) { - await request.Content.CopyToAsync(stream).ConfigureAwait(false); + await request.Content.CopyToStreamAsync(stream, cancellationToken).ConfigureAwait(false); } HttpResponseMessage response = await HttpRequestResponseSerializer.DeserializeResponseAsync(stream, cancellationToken).ConfigureAwait(false); diff --git a/iothub/device/src/Transport/AmqpIoT/AmqpIoTConnector.cs b/iothub/device/src/Transport/AmqpIoT/AmqpIoTConnector.cs index 805d85af42..21d22c1a0c 100644 --- a/iothub/device/src/Transport/AmqpIoT/AmqpIoTConnector.cs +++ b/iothub/device/src/Transport/AmqpIoT/AmqpIoTConnector.cs @@ -49,14 +49,9 @@ public async Task OpenConnectionAsync(TimeSpan timeout) MaxFrameSize = AmqpConstants.DefaultMaxFrameSize, ContainerId = CommonResources.GetNewStringGuid(), HostName = _hostName, + IdleTimeOut = Convert.ToUInt32(_amqpTransportSettings.IdleTimeout.TotalMilliseconds), }; - TimeSpan idleTimeout = _amqpTransportSettings.IdleTimeout; - if (idleTimeout != null) - { - amqpConnectionSettings.IdleTimeOut = Convert.ToUInt32(idleTimeout.TotalMilliseconds); - } - _amqpIotTransport = new AmqpIoTTransport(amqpSettings, _amqpTransportSettings, _hostName, s_disableServerCertificateValidation); TransportBase transportBase = await _amqpIotTransport.InitializeAsync(timeout).ConfigureAwait(false); diff --git a/iothub/device/src/Transport/HttpClientHelper.cs b/iothub/device/src/Transport/HttpClientHelper.cs index 24c17cb92d..883d2c202f 100644 --- a/iothub/device/src/Transport/HttpClientHelper.cs +++ b/iothub/device/src/Transport/HttpClientHelper.cs @@ -562,12 +562,13 @@ private static StringContent CreateContent(T entity) private static async Task ReadAsAsync(HttpContent content, CancellationToken token) { token.ThrowIfCancellationRequested(); - using Stream stream = await content.ReadAsStreamAsync().ConfigureAwait(false); + + using Stream stream = await content.ReadHttpContentAsStream(token).ConfigureAwait(false); using var reader = new StreamReader(stream); using var jsonReader = new JsonTextReader(reader); return new JsonSerializer().Deserialize(jsonReader); } #endif - } + } } diff --git a/iothub/device/src/Transport/HttpTransportHandler.cs b/iothub/device/src/Transport/HttpTransportHandler.cs index 2e3aff7f23..73c55bb5f7 100644 --- a/iothub/device/src/Transport/HttpTransportHandler.cs +++ b/iothub/device/src/Transport/HttpTransportHandler.cs @@ -277,7 +277,7 @@ public override async Task ReceiveAsync(CancellationToken cancellationT return null; } - byte[] byteContent = await responseMessage.Content.ReadAsByteArrayAsync().ConfigureAwait(false); + byte[] byteContent = await responseMessage.Content.ReadHttpContentAsByteArrayAsync(cancellationToken).ConfigureAwait(false); Message message = byteContent != null ? new Message(byteContent) diff --git a/iothub/device/src/Transport/Mqtt/MqttIotHubAdapter.cs b/iothub/device/src/Transport/Mqtt/MqttIotHubAdapter.cs index 1494122e0e..9782a26f25 100644 --- a/iothub/device/src/Transport/Mqtt/MqttIotHubAdapter.cs +++ b/iothub/device/src/Transport/Mqtt/MqttIotHubAdapter.cs @@ -14,7 +14,6 @@ using System.Threading.Tasks; using DotNetty.Buffers; using DotNetty.Codecs.Mqtt.Packets; -using DotNetty.Common.Concurrency; using DotNetty.Handlers.Tls; using DotNetty.Transport.Channels; using Microsoft.Azure.Devices.Client.Common; @@ -22,6 +21,12 @@ using Microsoft.Azure.Devices.Client.Extensions; using Microsoft.Azure.Devices.Shared; +#if NET5_0 +using TaskCompletionSource = System.Threading.Tasks.TaskCompletionSource; +#else +using TaskCompletionSource = Microsoft.Azure.Devices.Shared.TaskCompletionSource; +#endif + namespace Microsoft.Azure.Devices.Client.Transport.Mqtt { // @@ -639,7 +644,7 @@ private void ProcessSubAck(IChannelHandlerContext context, SubAckPacket packet) if (_subscribeCompletions.TryRemove(packet.PacketId, out TaskCompletionSource task)) { - task.TryComplete(); + task.TrySetResult(); } if (Logging.IsEnabled) @@ -680,7 +685,7 @@ private void ProcessUnsubAck(IChannelHandlerContext context, UnsubAckPacket pack if (_unsubscribeCompletions.TryRemove(packet.PacketId, out TaskCompletionSource task)) { - task.TryComplete(); + task.TrySetResult(); } if (Logging.IsEnabled) @@ -858,7 +863,7 @@ private async Task SendMessageAsync(IChannelHandlerContext context, Message mess } PublishPacket packet = await ComposePublishPacketAsync(context, message, qos, topicName).ConfigureAwait(true); - var publishCompletion = new TaskCompletionSource(); + var publishCompletion = new DotNetty.Common.Concurrency.TaskCompletionSource(); var workItem = new PublishWorkItem { Completion = publishCompletion, diff --git a/iothub/device/src/Transport/Mqtt/MqttTransportHandler.cs b/iothub/device/src/Transport/Mqtt/MqttTransportHandler.cs index caaf8959c4..4676114371 100644 --- a/iothub/device/src/Transport/Mqtt/MqttTransportHandler.cs +++ b/iothub/device/src/Transport/Mqtt/MqttTransportHandler.cs @@ -21,7 +21,6 @@ using DotNetty.Buffers; using DotNetty.Codecs.Mqtt; using DotNetty.Codecs.Mqtt.Packets; -using DotNetty.Common.Concurrency; using DotNetty.Handlers.Logging; using DotNetty.Handlers.Tls; using DotNetty.Transport.Bootstrapping; @@ -33,6 +32,12 @@ using Microsoft.Azure.Devices.Shared; using Newtonsoft.Json; +#if NET5_0 +using TaskCompletionSource = System.Threading.Tasks.TaskCompletionSource; +#else +using TaskCompletionSource = Microsoft.Azure.Devices.Shared.TaskCompletionSource; +#endif + namespace Microsoft.Azure.Devices.Client.Transport.Mqtt { // @@ -509,7 +514,7 @@ public void OnConnected() { if (TryStateTransition(TransportState.Opening, TransportState.Open)) { - _connectCompletion.TryComplete(); + _connectCompletion.TrySetResult(); } } @@ -1080,7 +1085,7 @@ await _channel .ConfigureAwait(true); if (TryStateTransition(TransportState.Subscribing, TransportState.Receiving) - && _subscribeCompletionSource.TryComplete()) + && _subscribeCompletionSource.TrySetResult()) { return; } diff --git a/iothub/device/src/Transport/Mqtt/SimpleWorkQueue.cs b/iothub/device/src/Transport/Mqtt/SimpleWorkQueue.cs index 46548e68b3..85d9713a2d 100644 --- a/iothub/device/src/Transport/Mqtt/SimpleWorkQueue.cs +++ b/iothub/device/src/Transport/Mqtt/SimpleWorkQueue.cs @@ -5,10 +5,15 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using DotNetty.Common.Concurrency; using DotNetty.Common.Utilities; using DotNetty.Transport.Channels; +#if NET5_0 +using TaskCompletionSource = System.Threading.Tasks.TaskCompletionSource; +#else +using TaskCompletionSource = Microsoft.Azure.Devices.Shared.TaskCompletionSource; +#endif + namespace Microsoft.Azure.Devices.Client.Transport.Mqtt { /// @@ -76,7 +81,7 @@ public void Complete() switch (State) { case States.Idle: - _completionSource.TryComplete(); + _completionSource.TrySetResult(); break; case States.Processing: @@ -155,7 +160,7 @@ private async void StartWorkQueueProcessingAsync(IChannelHandlerContext context) case States.FinalProcessing: case States.Aborted: - _completionSource.TryComplete(); + _completionSource.TrySetResult(); break; default: diff --git a/iothub/device/tests/RetryDelegatingHandlerImplicitOpenTests.cs b/iothub/device/tests/RetryDelegatingHandlerImplicitOpenTests.cs index e1e23885ba..c972f740d3 100644 --- a/iothub/device/tests/RetryDelegatingHandlerImplicitOpenTests.cs +++ b/iothub/device/tests/RetryDelegatingHandlerImplicitOpenTests.cs @@ -99,7 +99,7 @@ public async Task Retry_CloseAsyncSuccessDisposesHandler_Throws() public async Task OpenAsyncTwoCallersOnlyOneOpenCalled() { var contextMock = Substitute.For(); - var tcs = new TaskCompletionSource(); + var tcs = new TaskCompletionSource(); var innerHandlerMock = Substitute.For(); int callCounter = 0; innerHandlerMock.OpenAsync(Arg.Any()).Returns(t => @@ -113,7 +113,7 @@ public async Task OpenAsyncTwoCallersOnlyOneOpenCalled() var cancellationToken = new CancellationToken(); Task firstOpen = sut.OpenAsync(cancellationToken); Task secondOpen = sut.OpenAsync(cancellationToken); - tcs.Complete(); + tcs.SetResult(0); await Task.WhenAll(firstOpen, secondOpen).ConfigureAwait(false); Assert.AreEqual(1, callCounter); @@ -151,7 +151,7 @@ public async Task OpenAsyncInnerFailedSutIsOpenAndCanBeReopen() public async Task OpenAsyncInnerCancelledSutIsOpenAndCanBeReopen() { var contextMock = Substitute.For(); - var tcs = new TaskCompletionSource(); + var tcs = new TaskCompletionSource(); tcs.SetCanceled(); var innerHandlerMock = Substitute.For(); innerHandlerMock.OpenAsync(Arg.Any()).Returns(tcs.Task); diff --git a/provisioning/service/src/Contract/ContractApiHttp.cs b/provisioning/service/src/Contract/ContractApiHttp.cs index d467032462..37b79a2595 100644 --- a/provisioning/service/src/Contract/ContractApiHttp.cs +++ b/provisioning/service/src/Contract/ContractApiHttp.cs @@ -123,7 +123,7 @@ public async Task RequestAsync( } response = new ContractApiResponse( - await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false), + await httpResponse.Content.ReadHttpContentAsStringAsync(cancellationToken).ConfigureAwait(false), httpResponse.StatusCode, httpResponse.Headers.ToDictionary(x => x.Key, x => x.Value.FirstOrDefault()), httpResponse.ReasonPhrase); diff --git a/provisioning/service/tests/Config/X509CertificateWithInfoTests.cs b/provisioning/service/tests/Config/X509CertificateWithInfoTests.cs index 9e4a006952..3878712051 100644 --- a/provisioning/service/tests/Config/X509CertificateWithInfoTests.cs +++ b/provisioning/service/tests/Config/X509CertificateWithInfoTests.cs @@ -76,7 +76,7 @@ public void X509CertificateWithInfoConstructorThrowsOnNullX509Certificate() { // arrange X509Certificate2 certificateNull = null; - var certificateEmpty = new X509Certificate2(); + using var certificateEmpty = new X509Certificate2(); string certificateString = null; string certificateStringEmpty = ""; string certificateStringInvalid = @@ -109,10 +109,10 @@ public void X509CertificateWithInfoConstructorThrowsOnNullX509Certificate() public void X509CertificateWithInfoConstructorSucceedOnValidX509Certificate() { // arrange - X509Certificate2 certificate = new X509Certificate2(System.Text.Encoding.ASCII.GetBytes(PUBLIC_KEY_CERTIFICATE)); + using var certificate = new X509Certificate2(System.Text.Encoding.ASCII.GetBytes(PUBLIC_KEY_CERTIFICATE)); // act - X509CertificateWithInfo x509CertificateWithInfo = new X509CertificateWithInfo(certificate); + var x509CertificateWithInfo = new X509CertificateWithInfo(certificate); // assert Assert.AreEqual(PUBLIC_KEY_CERTIFICATE_STRING, x509CertificateWithInfo.Certificate); @@ -126,7 +126,7 @@ public void X509CertificateWithInfoConstructorSucceedOnValidX509CertificateStrin string certificate = PUBLIC_KEY_CERTIFICATE; // act - X509CertificateWithInfo x509CertificateWithInfo = new X509CertificateWithInfo(certificate); + var x509CertificateWithInfo = new X509CertificateWithInfo(certificate); // assert Assert.AreEqual(PUBLIC_KEY_CERTIFICATE, x509CertificateWithInfo.Certificate); @@ -143,7 +143,7 @@ public void X509CertificateWithInfoSucceedOnJsonWithInfo() string json = makeJson(SUBJECT_NAME, SHA1THUMBPRINT, SHA256THUMBPRINT, ISSUER_NAME, NOT_BEFORE_UTC_STRING, NOT_AFTER_UTC_STRING, SERIAL_NUMBER, VERSION); // act - X509CertificateWithInfo x509CertificateWithInfo = Newtonsoft.Json.JsonConvert.DeserializeObject(json); + var x509CertificateWithInfo = Newtonsoft.Json.JsonConvert.DeserializeObject(json); // assert Assert.IsNotNull(x509CertificateWithInfo.Info); diff --git a/provisioning/service/tests/Config/X509CertificatesTests.cs b/provisioning/service/tests/Config/X509CertificatesTests.cs index 3075797cf6..3dc2f23a16 100644 --- a/provisioning/service/tests/Config/X509CertificatesTests.cs +++ b/provisioning/service/tests/Config/X509CertificatesTests.cs @@ -17,9 +17,7 @@ public class X509CertificatesTests private const string SHA256THUMBPRINT = "validEnrollmentGroupId"; private const string ISSUER_NAME = "CN=ROOT_00000000-0000-0000-0000-000000000000, OU=Azure IoT, O=MSFT, C=US"; private const string NOT_BEFORE_UTC_STRING = "2017-11-14T12:34:18.123Z"; - private DateTime NOT_BEFORE_UTC = new DateTime(2017, 11, 14, 12, 34, 18, 123, DateTimeKind.Utc); private const string NOT_AFTER_UTC_STRING = "2017-11-14T12:34:18.321Z"; - private DateTime NOT_AFTER_UTC = new DateTime(2017, 11, 14, 12, 34, 18, 321, DateTimeKind.Utc); private const string SERIAL_NUMBER = "000000000000000000"; private const int VERSION = 3; @@ -64,10 +62,10 @@ private string MakeCertInfoJson( public void X509CertificatesSucceedOnValidPrimaryX509Certificate() { // arrange - X509Certificate2 primary = new X509Certificate2(System.Text.Encoding.ASCII.GetBytes(PUBLIC_KEY_CERTIFICATE_STRING)); + using var primary = new X509Certificate2(System.Text.Encoding.ASCII.GetBytes(PUBLIC_KEY_CERTIFICATE_STRING)); // act - X509Certificates x509Certificates = new X509Certificates(primary); + var x509Certificates = new X509Certificates(primary); // assert Assert.IsNotNull(x509Certificates.Primary); @@ -78,11 +76,11 @@ public void X509CertificatesSucceedOnValidPrimaryX509Certificate() public void X509CertificatesSucceedOnValidPrimaryAndSecondaryX509Certificate() { // arrange - X509Certificate2 primary = new X509Certificate2(System.Text.Encoding.ASCII.GetBytes(PUBLIC_KEY_CERTIFICATE_STRING)); - X509Certificate2 secondary = new X509Certificate2(System.Text.Encoding.ASCII.GetBytes(PUBLIC_KEY_CERTIFICATE_STRING)); + using var primary = new X509Certificate2(System.Text.Encoding.ASCII.GetBytes(PUBLIC_KEY_CERTIFICATE_STRING)); + using var secondary = new X509Certificate2(System.Text.Encoding.ASCII.GetBytes(PUBLIC_KEY_CERTIFICATE_STRING)); // act - X509Certificates x509Certificates = new X509Certificates(primary, secondary); + var x509Certificates = new X509Certificates(primary, secondary); // assert Assert.IsNotNull(x509Certificates.Primary); @@ -96,7 +94,7 @@ public void X509CertificatesSucceedOnValidPrimaryString() string primary = PUBLIC_KEY_CERTIFICATE_STRING; // act - X509Certificates x509Certificates = new X509Certificates(primary); + var x509Certificates = new X509Certificates(primary); // assert Assert.IsNotNull(x509Certificates.Primary); @@ -111,7 +109,7 @@ public void X509CertificatesSucceedOnValidPrimaryAndSecondaryX509CertificateWith string secondary = PUBLIC_KEY_CERTIFICATE_STRING; // act - X509Certificates x509Certificates = new X509Certificates(primary, secondary); + var x509Certificates = new X509Certificates(primary, secondary); // assert Assert.IsNotNull(x509Certificates.Primary); @@ -129,7 +127,7 @@ public void X509CertificatesSucceedOnJsonWithPrimaryCertificate() "}"; // act - X509Certificates x509Certificates = Newtonsoft.Json.JsonConvert.DeserializeObject(json); + var x509Certificates = JsonConvert.DeserializeObject(json); // assert Assert.IsNotNull(x509Certificates.Primary); @@ -150,7 +148,7 @@ public void X509CertificatesSucceedOnJsonWithPrimaryAndSecondaryCertificate() "}"; // act - X509Certificates x509Certificates = Newtonsoft.Json.JsonConvert.DeserializeObject(json); + var x509Certificates = JsonConvert.DeserializeObject(json); // assert Assert.IsNotNull(x509Certificates.Primary); @@ -194,7 +192,7 @@ public void X509CertificatesThrowsOnJsonWithoutPrimaryCertificate() "}"; // act - assert - TestAssert.Throws(() => Newtonsoft.Json.JsonConvert.DeserializeObject(json)); + TestAssert.Throws(() => JsonConvert.DeserializeObject(json)); } } } diff --git a/provisioning/transport/amqp/tests/ProvisioningErrorDetailsAmqpTests.cs b/provisioning/transport/amqp/tests/ProvisioningErrorDetailsAmqpTests.cs index 7fafca76bf..355029977a 100644 --- a/provisioning/transport/amqp/tests/ProvisioningErrorDetailsAmqpTests.cs +++ b/provisioning/transport/amqp/tests/ProvisioningErrorDetailsAmqpTests.cs @@ -1,14 +1,12 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using System; using Microsoft.Azure.Amqp; using Microsoft.Azure.Amqp.Encoding; using Microsoft.Azure.Amqp.Framing; using Microsoft.Azure.Devices.Provisioning.Client.Transport; using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; -using System.Collections.Generic; -using System.Text; namespace Microsoft.Azure.Devices.Provisioning.Transport.Amqp.UnitTests { @@ -16,18 +14,22 @@ namespace Microsoft.Azure.Devices.Provisioning.Transport.Amqp.UnitTests [TestCategory("Unit")] public class ProvisioningErrorDetailsAmqpTests { - private static TimeSpan defaultInterval = TimeSpan.FromSeconds(2); + private static readonly TimeSpan s_defaultInterval = TimeSpan.FromSeconds(2); [TestMethod] public void GetRetryFromRejectedSuccess() { int expectedSeconds = 32; - Rejected Rejected = new Rejected(); - Rejected.Error = new Error(); - Rejected.Error.Info = new Fields(); - Rejected.Error.Info.Add(new AmqpSymbol("Retry-After"), expectedSeconds); + var rejected = new Rejected + { + Error = new Error() + }; + rejected.Error.Info = new Fields + { + { new AmqpSymbol("Retry-After"), expectedSeconds } + }; - TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromRejection(Rejected, defaultInterval); + TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromRejection(rejected, s_defaultInterval); Assert.IsNotNull(actual); Assert.AreEqual(actual?.Seconds, expectedSeconds); @@ -37,40 +39,50 @@ public void GetRetryFromRejectedSuccess() public void GetRetryFromRejectedFallsBackToDefaultIfNegativeRetryAfterProvided() { int expectedSeconds = -1; - Rejected rejected = new Rejected(); - rejected.Error = new Error(); - rejected.Error.Info = new Fields(); - rejected.Error.Info.Add(new Azure.Amqp.Encoding.AmqpSymbol("Retry-After"), expectedSeconds); + var rejected = new Rejected + { + Error = new Error() + }; + rejected.Error.Info = new Fields + { + { new AmqpSymbol("Retry-After"), expectedSeconds } + }; - TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromRejection(rejected, defaultInterval); + TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromRejection(rejected, s_defaultInterval); Assert.IsNotNull(actual); - Assert.AreEqual(actual?.Seconds, defaultInterval.Seconds); + Assert.AreEqual(actual?.Seconds, s_defaultInterval.Seconds); } [TestMethod] public void GetRetryFromRejectedFallsBackToDefaultIfRetryAfterProvidedIs0() { int expectedSeconds = 0; - Rejected rejected = new Rejected(); - rejected.Error = new Error(); - rejected.Error.Info = new Fields(); - rejected.Error.Info.Add(new Azure.Amqp.Encoding.AmqpSymbol("Retry-After"), expectedSeconds); + var rejected = new Rejected + { + Error = new Error() + }; + rejected.Error.Info = new Fields + { + { new AmqpSymbol("Retry-After"), expectedSeconds } + }; - TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromRejection(rejected, defaultInterval); + TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromRejection(rejected, s_defaultInterval); Assert.IsNotNull(actual); - Assert.AreEqual(actual?.Seconds, defaultInterval.Seconds); + Assert.AreEqual(actual?.Seconds, s_defaultInterval.Seconds); } [TestMethod] public void GetRetryFromRejectedReturnsNullIfNoErrorInfoEntries() { - Rejected rejected = new Rejected(); - rejected.Error = new Error(); + var rejected = new Rejected + { + Error = new Error() + }; rejected.Error.Info = new Fields(); - TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromRejection(rejected, defaultInterval); + TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromRejection(rejected, s_defaultInterval); Assert.IsNull(actual); } @@ -78,10 +90,12 @@ public void GetRetryFromRejectedReturnsNullIfNoErrorInfoEntries() [TestMethod] public void GetRetryFromRejectedReturnsNullIfNoErrorInfo() { - Rejected rejected = new Rejected(); - rejected.Error = new Error(); + var rejected = new Rejected + { + Error = new Error() + }; - TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromRejection(rejected, defaultInterval); + TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromRejection(rejected, s_defaultInterval); Assert.IsNull(actual); } @@ -89,9 +103,9 @@ public void GetRetryFromRejectedReturnsNullIfNoErrorInfo() [TestMethod] public void GetRetryFromRejectedReturnsNullIfNoError() { - Rejected rejected = new Rejected(); + var rejected = new Rejected(); - TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromRejection(rejected, defaultInterval); + TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromRejection(rejected, s_defaultInterval); Assert.IsNull(actual); } @@ -100,10 +114,10 @@ public void GetRetryFromRejectedReturnsNullIfNoError() public void GetRetryAfterFromApplicationPropertiesSuccess() { int expectedRetryAfter = 42; - AmqpMessage amqpResponse = AmqpMessage.Create(); + using var amqpResponse = AmqpMessage.Create(); amqpResponse.ApplicationProperties = new ApplicationProperties(); amqpResponse.ApplicationProperties.Map.Add(new MapKey("Retry-After"), expectedRetryAfter); - TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromApplicationProperties(amqpResponse, defaultInterval); + TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromApplicationProperties(amqpResponse, s_defaultInterval); Assert.IsNotNull(actual); Assert.AreEqual(expectedRetryAfter, actual?.Seconds); } @@ -112,40 +126,40 @@ public void GetRetryAfterFromApplicationPropertiesSuccess() public void GetRetryAfterFromApplicationPropertiesReturnsDefaultIfRetryAfterValueIsNegative() { int expectedRetryAfter = -1; - AmqpMessage amqpResponse = AmqpMessage.Create(); + using var amqpResponse = AmqpMessage.Create(); amqpResponse.ApplicationProperties = new ApplicationProperties(); amqpResponse.ApplicationProperties.Map.Add(new MapKey("Retry-After"), expectedRetryAfter); - TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromApplicationProperties(amqpResponse, defaultInterval); + TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromApplicationProperties(amqpResponse, s_defaultInterval); Assert.IsNotNull(actual); - Assert.AreEqual(defaultInterval.Seconds, actual?.Seconds); + Assert.AreEqual(s_defaultInterval.Seconds, actual?.Seconds); } [TestMethod] public void GetRetryAfterFromApplicationPropertiesReturnsDefaultIfRetryAfterValueIsZero() { int expectedRetryAfter = 0; - AmqpMessage amqpResponse = AmqpMessage.Create(); + using var amqpResponse = AmqpMessage.Create(); amqpResponse.ApplicationProperties = new ApplicationProperties(); amqpResponse.ApplicationProperties.Map.Add(new MapKey("Retry-After"), expectedRetryAfter); - TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromApplicationProperties(amqpResponse, defaultInterval); + TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromApplicationProperties(amqpResponse, s_defaultInterval); Assert.IsNotNull(actual); - Assert.AreEqual(defaultInterval.Seconds, actual?.Seconds); + Assert.AreEqual(s_defaultInterval.Seconds, actual?.Seconds); } [TestMethod] public void GetRetryAfterFromApplicationPropertiesReturnsNullIfNoRetryAfterApplicationProperty() { - AmqpMessage amqpResponse = AmqpMessage.Create(); + using var amqpResponse = AmqpMessage.Create(); amqpResponse.ApplicationProperties = new ApplicationProperties(); - TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromApplicationProperties(amqpResponse, defaultInterval); + TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromApplicationProperties(amqpResponse, s_defaultInterval); Assert.IsNull(actual); } [TestMethod] public void GetRetryAfterFromApplicationPropertiesReturnsNullIfNoApplicationProperties() { - AmqpMessage amqpResponse = AmqpMessage.Create(); - TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromApplicationProperties(amqpResponse, defaultInterval); + using var amqpResponse = AmqpMessage.Create(); + TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromApplicationProperties(amqpResponse, s_defaultInterval); Assert.IsNull(actual); } } diff --git a/provisioning/transport/http/src/Generated/RuntimeRegistration.cs b/provisioning/transport/http/src/Generated/RuntimeRegistration.cs index cb159c2c58..954f915718 100644 --- a/provisioning/transport/http/src/Generated/RuntimeRegistration.cs +++ b/provisioning/transport/http/src/Generated/RuntimeRegistration.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using Microsoft.Azure.Devices.Provisioning.Client.Transport.Models; +using Microsoft.Azure.Devices.Shared; using Microsoft.Rest; using Microsoft.Rest.Serialization; using Newtonsoft.Json; @@ -170,7 +171,7 @@ public async Task> OperationS var ex = new HttpOperationException(string.Format(CultureInfo.InvariantCulture, "Operation returned an invalid status code '{0}'", _statusCode)); if (_httpResponse.Content != null) { - _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + _responseContent = await _httpResponse.Content.ReadHttpContentAsStringAsync(cancellationToken).ConfigureAwait(false); } else { @@ -198,7 +199,7 @@ public async Task> OperationS // Deserialize Response if ((int)_statusCode == 200) { - _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + _responseContent = await _httpResponse.Content.ReadHttpContentAsStringAsync(cancellationToken).ConfigureAwait(false); try { _result.Body = SafeJsonConvert.DeserializeObject(_responseContent, Client.DeserializationSettings); @@ -216,7 +217,7 @@ public async Task> OperationS // Deserialize Response if ((int)_statusCode == 202) { - _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + _responseContent = await _httpResponse.Content.ReadHttpContentAsStringAsync(cancellationToken).ConfigureAwait(false); try { _result.Body = SafeJsonConvert.DeserializeObject(_responseContent, Client.DeserializationSettings); @@ -364,7 +365,7 @@ public async Task> OperationS var ex = new HttpOperationException(string.Format(CultureInfo.InvariantCulture, "Operation returned an invalid status code '{0}'", _statusCode)); if (_httpResponse.Content != null) { - _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + _responseContent = await _httpResponse.Content.ReadHttpContentAsStringAsync(cancellationToken).ConfigureAwait(false); } else { @@ -392,7 +393,7 @@ public async Task> OperationS // Deserialize Response if ((int)_statusCode == 200) { - _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + _responseContent = await _httpResponse.Content.ReadHttpContentAsStringAsync(cancellationToken).ConfigureAwait(false); try { _result.Body = SafeJsonConvert.DeserializeObject(_responseContent, Client.DeserializationSettings); @@ -558,7 +559,7 @@ public async Task> RegisterDe var ex = new HttpOperationException(string.Format(CultureInfo.InvariantCulture, "Operation returned an invalid status code '{0}'", _statusCode)); if (_httpResponse.Content != null) { - _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + _responseContent = await _httpResponse.Content.ReadHttpContentAsStringAsync(cancellationToken).ConfigureAwait(false); } else { @@ -586,7 +587,7 @@ public async Task> RegisterDe // Deserialize Response if ((int)_statusCode == 202) { - _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + _responseContent = await _httpResponse.Content.ReadHttpContentAsStringAsync(cancellationToken).ConfigureAwait(false); try { _result.Body = SafeJsonConvert.DeserializeObject(_responseContent, Client.DeserializationSettings); diff --git a/provisioning/transport/http/src/TPM/TpmCredentials.cs b/provisioning/transport/http/src/TPM/TpmCredentials.cs index 9ea5530de4..ea5e8ab97a 100644 --- a/provisioning/transport/http/src/TPM/TpmCredentials.cs +++ b/provisioning/transport/http/src/TPM/TpmCredentials.cs @@ -33,7 +33,13 @@ public override Task ProcessHttpRequestAsync(HttpRequestMessage request, Cancell SetAuthorizationHeader(request, _sasToken); }; +#if NET5_0 + HttpRequestOptions requestOptions = request.Options; + var requestOptionsKey = new HttpRequestOptionsKey>(TpmDelegatingHandler.ProvisioningHeaderName); + requestOptions.Set(requestOptionsKey, action); +#else request.Properties.Add(TpmDelegatingHandler.ProvisioningHeaderName, action); +#endif } else { diff --git a/provisioning/transport/http/src/TPM/TpmDelegatingHandler.cs b/provisioning/transport/http/src/TPM/TpmDelegatingHandler.cs index bb82a85a57..008351673e 100644 --- a/provisioning/transport/http/src/TPM/TpmDelegatingHandler.cs +++ b/provisioning/transport/http/src/TPM/TpmDelegatingHandler.cs @@ -1,16 +1,13 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using Microsoft.Azure.Devices.Shared; -using Newtonsoft.Json; using System; -using System.Collections.Generic; -using System.Globalization; using System.Net; using System.Net.Http; -using System.Text; using System.Threading; using System.Threading.Tasks; +using Microsoft.Azure.Devices.Shared; +using Newtonsoft.Json; namespace Microsoft.Azure.Devices.Provisioning.Client.Transport { @@ -37,12 +34,16 @@ protected override async Task SendAsync( if(response.StatusCode == HttpStatusCode.Unauthorized) { +#if NET5_0 + if (request.Options.TryGetValue(new HttpRequestOptionsKey(ProvisioningHeaderName), out object result)) +#else if (request.Properties.TryGetValue(ProvisioningHeaderName, out object result)) +#endif { if (result is Action setSasToken) { string target = GetTarget(request.RequestUri.LocalPath); - string responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false); + string responseContent = await response.Content.ReadHttpContentAsStringAsync(cancellationToken).ConfigureAwait(false); TpmChallenge challenge = JsonConvert.DeserializeObject(responseContent); string sasToken = ProvisioningSasBuilder.ExtractServiceAuthKey( diff --git a/security/tpm/samples/SecurityProviderTpmSimulator/SecurityProviderTpmSimulator.cs b/security/tpm/samples/SecurityProviderTpmSimulator/SecurityProviderTpmSimulator.cs index 21b6e37238..7ae1568000 100644 --- a/security/tpm/samples/SecurityProviderTpmSimulator/SecurityProviderTpmSimulator.cs +++ b/security/tpm/samples/SecurityProviderTpmSimulator/SecurityProviderTpmSimulator.cs @@ -23,21 +23,22 @@ public class SecurityProviderTpmSimulator : SecurityProviderTpm private const int SimulatorPort = 2321; private const int TcpTpmDeviceTimeoutSeconds = 30; + private TcpTpmDevice _tpmDevice; private SecurityProviderTpmHsm _innerClient; public SecurityProviderTpmSimulator(string registrationId) : base(registrationId) { - var tpmDevice = new TcpTpmDevice(SimulatorAddress, SimulatorPort); - tpmDevice.Connect(); - tpmDevice.SetSocketTimeout(TcpTpmDeviceTimeoutSeconds); - tpmDevice.PowerCycle(); + _tpmDevice = new TcpTpmDevice(SimulatorAddress, SimulatorPort); + _tpmDevice.Connect(); + _tpmDevice.SetSocketTimeout(TcpTpmDeviceTimeoutSeconds); + _tpmDevice.PowerCycle(); - using (var tpm2 = new Tpm2(tpmDevice)) + using (var tpm2 = new Tpm2(_tpmDevice)) { tpm2.Startup(Su.Clear); } - _innerClient = new SecurityProviderTpmHsm(GetRegistrationID(), tpmDevice); + _innerClient = new SecurityProviderTpmHsm(GetRegistrationID(), _tpmDevice); } public override void ActivateIdentityKey(byte[] encryptedKey) @@ -62,7 +63,7 @@ public override byte[] Sign(byte[] data) public static void StopSimulatorProcess() { - foreach (var process in Process.GetProcessesByName(Path.GetFileNameWithoutExtension(SimulatorExeName))) + foreach (Process process in Process.GetProcessesByName(Path.GetFileNameWithoutExtension(SimulatorExeName))) { try { @@ -106,7 +107,7 @@ public static void StartSimulatorProcess() throw new InvalidOperationException($"TPM Simulator not found : {SimulatorExeName}"); } - var simulatorProcess = new Process + using var simulatorProcess = new Process { StartInfo = { @@ -123,7 +124,11 @@ protected override void Dispose(bool disposing) { if (disposing) { - _innerClient.Dispose(); + _innerClient?.Dispose(); + _innerClient = null; + + _tpmDevice?.Dispose(); + _tpmDevice = null; } } } From 04d77f99e51577974a51d49e4b6cb69f5919fb4f Mon Sep 17 00:00:00 2001 From: Abhipsa Misra Date: Wed, 17 Mar 2021 20:58:25 -0700 Subject: [PATCH 3/7] refactor(e2e-tests): Update E2E tests to follow .NET 5.0 patterns --- e2e/test/E2EMsTestBase.cs | 4 - e2e/test/Helpers/CustomWebProxy.cs | 2 +- e2e/test/Helpers/StorageContainer.cs | 2 +- e2e/test/Helpers/TestDevice.cs | 35 +++- e2e/test/Helpers/TestDeviceCallbackHandler.cs | 4 +- e2e/test/Helpers/TestModule.cs | 2 +- e2e/test/Helpers/logging/LoggedTestMethod.cs | 2 +- e2e/test/Helpers/logging/TestLogger.cs | 6 +- e2e/test/Helpers/templates/FaultInjection.cs | 17 +- .../FaultInjectionPoolingOverAmqp.cs | 16 +- e2e/test/Helpers/templates/PoolingOverAmqp.cs | 16 +- .../ConnectionStatusChangeHandlerTests.cs | 2 +- .../DeviceClientX509AuthenticationE2ETests.cs | 112 +++++++------ e2e/test/iothub/DeviceTokenRefreshE2ETests.cs | 155 +++++++++--------- e2e/test/iothub/FileUploadE2ETests.cs | 91 ++++++---- .../iothub/FileUploadFaultInjectionTests.cs | 5 +- e2e/test/iothub/NoRetryE2ETests.cs | 4 +- ...eSecurityCenterForIoTLogAnalyticsClient.cs | 10 +- ...rityCenterForIoTSecurityMessageE2ETests.cs | 6 +- ...ssageReceiveFaultInjectionPoolAmqpTests.cs | 18 +- ....MessageSendFaultInjectionPoolAmqpTests.cs | 8 +- .../messaging/MessageFeedbackE2ETests.cs | 2 +- .../messaging/MessageReceiveE2ETests.cs | 20 +-- .../iothub/messaging/MessageSendE2ETests.cs | 8 +- ...Tests.MethodFaultInjectionPoolAmqpTests.cs | 27 +-- e2e/test/iothub/method/MethodE2ETests.cs | 8 +- .../iothub/service/BulkOperationsE2ETests.cs | 4 +- .../service/DigitalTwinClientE2ETests.cs | 4 +- .../IoTHubCertificateValidationE2ETest.cs | 16 +- .../service/IoTHubServiceProxyE2ETests.cs | 2 +- e2e/test/iothub/service/PnpServiceTests.cs | 12 +- .../iothub/service/RegistryManagerE2ETests.cs | 14 +- .../RegistryManagerExportDevicesTests.cs | 2 +- .../RegistryManagerImportDevicesTests.cs | 4 +- .../iothub/service/ServiceClientE2ETests.cs | 27 +-- ...qpTests.TwinFaultInjectionPoolAmqpTests.cs | 31 +--- e2e/test/iothub/twin/TwinE2ETests.cs | 18 +- .../iothub/twin/TwinFaultInjectionTests.cs | 2 +- ...rovisioningCertificateValidationE2ETest.cs | 7 +- e2e/test/provisioning/ProvisioningE2ETests.cs | 78 +++++---- .../ProvisioningServiceClientE2ETests.cs | 8 +- .../provisioning/ReprovisioningE2ETests.cs | 94 +++++++---- 42 files changed, 488 insertions(+), 417 deletions(-) diff --git a/e2e/test/E2EMsTestBase.cs b/e2e/test/E2EMsTestBase.cs index 9a06aef960..9d33d823c5 100644 --- a/e2e/test/E2EMsTestBase.cs +++ b/e2e/test/E2EMsTestBase.cs @@ -5,10 +5,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.Tracing; -using System.Linq; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Runtime.Versioning; using System.Threading.Tasks; using Microsoft.ApplicationInsights.DataContracts; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/e2e/test/Helpers/CustomWebProxy.cs b/e2e/test/Helpers/CustomWebProxy.cs index bf242d94d7..b0aea21bf2 100644 --- a/e2e/test/Helpers/CustomWebProxy.cs +++ b/e2e/test/Helpers/CustomWebProxy.cs @@ -10,7 +10,7 @@ namespace Microsoft.Azure.Devices.E2ETests.Helpers public class CustomWebProxy : IWebProxy { private readonly MsTestLogger _logger; - private long _counter = 0; + private long _counter; public CustomWebProxy(MsTestLogger logger) { diff --git a/e2e/test/Helpers/StorageContainer.cs b/e2e/test/Helpers/StorageContainer.cs index 94bb4cfcfe..e92fdfebc0 100644 --- a/e2e/test/Helpers/StorageContainer.cs +++ b/e2e/test/Helpers/StorageContainer.cs @@ -14,7 +14,7 @@ namespace Microsoft.Azure.Devices.E2ETests.Helpers /// public class StorageContainer : IDisposable { - private bool _disposed = false; + private bool _disposed; public string ContainerName { get; } public Uri Uri { get; private set; } diff --git a/e2e/test/Helpers/TestDevice.cs b/e2e/test/Helpers/TestDevice.cs index b558adad20..a46954ec7e 100644 --- a/e2e/test/Helpers/TestDevice.cs +++ b/e2e/test/Helpers/TestDevice.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; +using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; using Microsoft.Azure.Devices.Client; @@ -21,11 +22,13 @@ public enum ConnectionStringAuthScope Device } - public class TestDevice + public class TestDevice : IDisposable { private const int DelayAfterDeviceCreationSeconds = 0; private static readonly SemaphoreSlim s_semaphore = new SemaphoreSlim(1, 1); + private X509Certificate2 _authCertificate; + private static MsTestLogger _logger; private TestDevice(Device device, Client.IAuthenticationMethod authenticationMethod) @@ -69,6 +72,8 @@ private static async Task CreateDeviceAsync(TestDeviceType type, str Client.IAuthenticationMethod auth = null; var requestDevice = new Device(deviceName); + X509Certificate2 authCertificate = null; + if (type == TestDeviceType.X509) { requestDevice.Authentication = new AuthenticationMechanism @@ -79,7 +84,10 @@ private static async Task CreateDeviceAsync(TestDeviceType type, str } }; - auth = new DeviceAuthenticationWithX509Certificate(deviceName, Configuration.IoTHub.GetCertificateWithPrivateKey()); + authCertificate = Configuration.IoTHub.GetCertificateWithPrivateKey(); +#pragma warning disable CA2000 // Dispose objects before losing scope - auth is disposed when TestDevice is disposed. + auth = new DeviceAuthenticationWithX509Certificate(deviceName, authCertificate); +#pragma warning restore CA2000 // Dispose objects before losing scope - auth is disposed when TestDevice is disposed. } Device device = await rm.AddDeviceAsync(requestDevice).ConfigureAwait(false); @@ -89,7 +97,10 @@ private static async Task CreateDeviceAsync(TestDeviceType type, str await rm.CloseAsync().ConfigureAwait(false); - return new TestDevice(device, auth); + return new TestDevice(device, auth) + { + _authCertificate = authCertificate, + }; } /// @@ -170,5 +181,23 @@ public async Task RemoveDeviceAsync() using var rm = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); await rm.RemoveDeviceAsync(Id).ConfigureAwait(false); } + + public void Dispose() + { +#if !NET451 + // Ideally we wouldn't be disposing the X509 Certificates here, but rather delegate that to whoever was creating the TestDevice. + // For the design that our test suite follows, it is ok to dispose the X509 certificate here since it won't be referenced by anyone else + // within the scope of the test using this TestDevice. + _authCertificate?.Dispose(); + _authCertificate = null; +#endif + + if (AuthenticationMethod is DeviceAuthenticationWithX509Certificate x509Auth) + { + x509Auth?.Dispose(); + x509Auth = null; + } + + } } } diff --git a/e2e/test/Helpers/TestDeviceCallbackHandler.cs b/e2e/test/Helpers/TestDeviceCallbackHandler.cs index e2b075f91b..3392bedac6 100644 --- a/e2e/test/Helpers/TestDeviceCallbackHandler.cs +++ b/e2e/test/Helpers/TestDeviceCallbackHandler.cs @@ -23,11 +23,11 @@ public class TestDeviceCallbackHandler : IDisposable private readonly SemaphoreSlim _twinCallbackSemaphore = new SemaphoreSlim(0, 1); private ExceptionDispatchInfo _twinExceptionDispatch; - private string _expectedTwinPropertyValue = null; + private string _expectedTwinPropertyValue; private readonly SemaphoreSlim _receivedMessageCallbackSemaphore = new SemaphoreSlim(0, 1); private ExceptionDispatchInfo _receiveMessageExceptionDispatch; - private Message _expectedMessageSentByService = null; + private Message _expectedMessageSentByService; public TestDeviceCallbackHandler(DeviceClient deviceClient, TestDevice testDevice, MsTestLogger logger) { diff --git a/e2e/test/Helpers/TestModule.cs b/e2e/test/Helpers/TestModule.cs index 72a0caaa2f..d5747dbcc1 100644 --- a/e2e/test/Helpers/TestModule.cs +++ b/e2e/test/Helpers/TestModule.cs @@ -23,7 +23,7 @@ private TestModule(Module module) /// public static async Task GetTestModuleAsync(string deviceNamePrefix, string moduleNamePrefix, MsTestLogger logger) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(logger, deviceNamePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(logger, deviceNamePrefix).ConfigureAwait(false); string deviceName = testDevice.Id; string moduleName = "E2E_" + moduleNamePrefix + Guid.NewGuid(); diff --git a/e2e/test/Helpers/logging/LoggedTestMethod.cs b/e2e/test/Helpers/logging/LoggedTestMethod.cs index 8f3cba3b3c..d23438164f 100644 --- a/e2e/test/Helpers/logging/LoggedTestMethod.cs +++ b/e2e/test/Helpers/logging/LoggedTestMethod.cs @@ -19,7 +19,7 @@ public class LoggedTestMethod : TestMethodAttribute public override TestResult[] Execute(ITestMethod testMethod) { TestResult[] results = base.Execute(testMethod); - var testFailureReason = results.First().TestFailureException?.Message; + string testFailureReason = results.First().TestFailureException?.Message; // Log only if there is an exception in the test run. if (!string.IsNullOrWhiteSpace(testFailureReason)) diff --git a/e2e/test/Helpers/logging/TestLogger.cs b/e2e/test/Helpers/logging/TestLogger.cs index e447c7f7d8..81f061d53b 100644 --- a/e2e/test/Helpers/logging/TestLogger.cs +++ b/e2e/test/Helpers/logging/TestLogger.cs @@ -23,9 +23,9 @@ public class TestLogger public const string Service = "IotHub"; // Client to log to application insights. - private TelemetryClient _telemetryClient; + private readonly TelemetryClient _telemetryClient; - private IDictionary _commonProperties; + private readonly IDictionary _commonProperties; private TestLogger() { @@ -35,7 +35,7 @@ private TestLogger() string intrumentationKey = Environment.GetEnvironmentVariable("E2E_IKEY"); if (!string.IsNullOrWhiteSpace(intrumentationKey)) { - var config = new TelemetryConfiguration + using var config = new TelemetryConfiguration { InstrumentationKey = intrumentationKey, }; diff --git a/e2e/test/Helpers/templates/FaultInjection.cs b/e2e/test/Helpers/templates/FaultInjection.cs index 43436c15fc..ea48313a9e 100644 --- a/e2e/test/Helpers/templates/FaultInjection.cs +++ b/e2e/test/Helpers/templates/FaultInjection.cs @@ -93,14 +93,13 @@ public static async Task ActivateFaultInjectionAsync(Client.TransportType transp deviceClient.OperationTimeoutInMilliseconds = (uint)delayInSec.TotalMilliseconds; } - await deviceClient - .SendEventAsync( - ComposeErrorInjectionProperties( - faultType, - reason, - delayInSec, - durationInSec)) - .ConfigureAwait(false); + using Client.Message faultInjectionMessage = ComposeErrorInjectionProperties( + faultType, + reason, + delayInSec, + durationInSec); + + await deviceClient.SendEventAsync(faultInjectionMessage).ConfigureAwait(false); } catch (IotHubCommunicationException ex) { @@ -144,7 +143,7 @@ public static async Task TestErrorInjectionAsync( Func cleanupOperation, MsTestLogger logger) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(logger, devicePrefix, type).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(logger, devicePrefix, type).ConfigureAwait(false); ITransportSettings transportSettings = CreateTransportSettingsFromName(transport, proxyAddress); DeviceClient deviceClient = testDevice.CreateDeviceClient(new ITransportSettings[] { transportSettings }); diff --git a/e2e/test/Helpers/templates/FaultInjectionPoolingOverAmqp.cs b/e2e/test/Helpers/templates/FaultInjectionPoolingOverAmqp.cs index d1dbb5fce2..b62bac69a1 100644 --- a/e2e/test/Helpers/templates/FaultInjectionPoolingOverAmqp.cs +++ b/e2e/test/Helpers/templates/FaultInjectionPoolingOverAmqp.cs @@ -26,7 +26,7 @@ public static async Task TestFaultInjectionPoolAmqpAsync( TimeSpan durationInSec, Func initOperation, Func testOperation, - Func, Task> cleanupOperation, + Func, List, Task> cleanupOperation, ConnectionStringAuthScope authScope, MsTestLogger logger) { @@ -43,11 +43,11 @@ public static async Task TestFaultInjectionPoolAmqpAsync( } }; - IList testDevices = new List(); - IList deviceClients = new List(); - IList testDeviceCallbackHandlers = new List(); - IList amqpConnectionStatuses = new List(); - IList operations = new List(); + var testDevices = new List(); + var deviceClients = new List(); + var testDeviceCallbackHandlers = new List(); + var amqpConnectionStatuses = new List(); + var operations = new List(); // Arrange // Initialize the test device client instances @@ -94,7 +94,7 @@ public static async Task TestFaultInjectionPoolAmqpAsync( watch.Start(); logger.Trace($"{nameof(FaultInjectionPoolingOverAmqp)}: {testDevices[0].Id} Requesting fault injection type={faultType} reason={reason}, delay={delayInSec}s, duration={durationInSec}s"); - var faultInjectionMessage = FaultInjection.ComposeErrorInjectionProperties(faultType, reason, delayInSec, durationInSec); + using Client.Message faultInjectionMessage = FaultInjection.ComposeErrorInjectionProperties(faultType, reason, delayInSec, durationInSec); await deviceClients[0].SendEventAsync(faultInjectionMessage).ConfigureAwait(false); logger.Trace($"{nameof(FaultInjection)}: Waiting for fault injection to be active: {delayInSec} seconds."); @@ -205,7 +205,7 @@ public static async Task TestFaultInjectionPoolAmqpAsync( finally { // Close the service-side components and dispose the device client instances. - await cleanupOperation(deviceClients).ConfigureAwait(false); + await cleanupOperation(deviceClients, testDeviceCallbackHandlers).ConfigureAwait(false); watch.Stop(); diff --git a/e2e/test/Helpers/templates/PoolingOverAmqp.cs b/e2e/test/Helpers/templates/PoolingOverAmqp.cs index 070e52eec8..e6b281f5cb 100644 --- a/e2e/test/Helpers/templates/PoolingOverAmqp.cs +++ b/e2e/test/Helpers/templates/PoolingOverAmqp.cs @@ -47,11 +47,11 @@ public static async Task TestPoolAmqpAsync( int currentSuccessRate = 0; bool reRunTest = false; - IList testDevices = new List(); - IList deviceClients = new List(); - IList testDeviceCallbackHandlers = new List(); - IList amqpConnectionStatuses = new List(); - IList operations = new List(); + var testDevices = new List(); + var deviceClients = new List(); + var testDeviceCallbackHandlers = new List(); + var amqpConnectionStatuses = new List(); + var operations = new List(); do { @@ -135,10 +135,8 @@ public static async Task TestPoolAmqpAsync( await cleanupOperation().ConfigureAwait(false); } - foreach (DeviceClient deviceClient in deviceClients) - { - deviceClient.Dispose(); - } + deviceClients.ForEach(deviceClient => deviceClient.Dispose()); + testDeviceCallbackHandlers.ForEach(testDeviceCallbackHandler => testDeviceCallbackHandler.Dispose()); // Clean up the local lists testDevices.Clear(); diff --git a/e2e/test/iothub/ConnectionStatusChangeHandlerTests.cs b/e2e/test/iothub/ConnectionStatusChangeHandlerTests.cs index e9ecabd8d5..bad5d65bf8 100644 --- a/e2e/test/iothub/ConnectionStatusChangeHandlerTests.cs +++ b/e2e/test/iothub/ConnectionStatusChangeHandlerTests.cs @@ -106,7 +106,7 @@ await this.ModuleClient_Gives_ConnectionStatus_DeviceDisabled_Base( private async Task DeviceClient_Gives_ConnectionStatus_DeviceDisabled_Base( Client.TransportType protocol, Func registryManagerOperation) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix + $"_{Guid.NewGuid()}").ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix + $"_{Guid.NewGuid()}").ConfigureAwait(false); string deviceConnectionString = testDevice.ConnectionString; var config = new Configuration.IoTHub.DeviceConnectionStringParser(deviceConnectionString); diff --git a/e2e/test/iothub/DeviceClientX509AuthenticationE2ETests.cs b/e2e/test/iothub/DeviceClientX509AuthenticationE2ETests.cs index 95a2f10b5d..feb2c44604 100644 --- a/e2e/test/iothub/DeviceClientX509AuthenticationE2ETests.cs +++ b/e2e/test/iothub/DeviceClientX509AuthenticationE2ETests.cs @@ -24,6 +24,8 @@ namespace Microsoft.Azure.Devices.E2ETests public class DeviceClientX509AuthenticationE2ETests : E2EMsTestBase { private static readonly string s_devicePrefix = $"{nameof(DeviceClientX509AuthenticationE2ETests)}_"; + private static X509Certificate2 s_selfSignedCertificateWithPrivateKey = Configuration.IoTHub.GetCertificateWithPrivateKey(); + private static X509Certificate2 s_chainCertificateWithPrivateKey = Configuration.IoTHub.GetChainDeviceCertificateWithPrivateKey(); private readonly string _hostName; public DeviceClientX509AuthenticationE2ETests() @@ -147,13 +149,15 @@ public async Task X509_Enable_CertificateRevocationCheck_Amqp_WebSocket() public async Task X509_Cert_Chain_Install_Test_MQTT_TCP() { // arrange - var chainCerts = new X509Certificate2Collection(); - chainCerts.Add(Configuration.IoTHub.GetRootCACertificate()); - chainCerts.Add(Configuration.IoTHub.GetIntermediate1Certificate()); - chainCerts.Add(Configuration.IoTHub.GetIntermediate2Certificate()); - var auth = new DeviceAuthenticationWithX509Certificate( + var chainCerts = new X509Certificate2Collection + { + Configuration.IoTHub.GetRootCACertificate(), + Configuration.IoTHub.GetIntermediate1Certificate(), + Configuration.IoTHub.GetIntermediate2Certificate() + }; + using var auth = new DeviceAuthenticationWithX509Certificate( Configuration.IoTHub.X509ChainDeviceName, - Configuration.IoTHub.GetChainDeviceCertificateWithPrivateKey(), + s_chainCertificateWithPrivateKey, chainCerts); using var deviceClient = DeviceClient.Create( _hostName, @@ -172,13 +176,15 @@ public async Task X509_Cert_Chain_Install_Test_MQTT_TCP() public async Task X509_Cert_Chain_Install_Test_AMQP_TCP() { // arrange - var chainCerts = new X509Certificate2Collection(); - chainCerts.Add(Configuration.IoTHub.GetRootCACertificate()); - chainCerts.Add(Configuration.IoTHub.GetIntermediate1Certificate()); - chainCerts.Add(Configuration.IoTHub.GetIntermediate2Certificate()); - var auth = new DeviceAuthenticationWithX509Certificate( + var chainCerts = new X509Certificate2Collection + { + Configuration.IoTHub.GetRootCACertificate(), + Configuration.IoTHub.GetIntermediate1Certificate(), + Configuration.IoTHub.GetIntermediate2Certificate() + }; + using var auth = new DeviceAuthenticationWithX509Certificate( Configuration.IoTHub.X509ChainDeviceName, - Configuration.IoTHub.GetChainDeviceCertificateWithPrivateKey(), + s_chainCertificateWithPrivateKey, chainCerts); using var deviceClient = DeviceClient.Create( _hostName, @@ -217,14 +223,12 @@ private void ValidateCertsAreInstalled(X509Certificate2Collection certificates) private async Task SendMessageTest(ITransportSettings transportSetting) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, TestDeviceType.X509).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, TestDeviceType.X509).ConfigureAwait(false); - using (DeviceClient deviceClient = testDevice.CreateDeviceClient(new[] { transportSetting })) - { - await deviceClient.OpenAsync().ConfigureAwait(false); - await MessageSendE2ETests.SendSingleMessageAsync(deviceClient, testDevice.Id, Logger).ConfigureAwait(false); - await deviceClient.CloseAsync().ConfigureAwait(false); - } + using DeviceClient deviceClient = testDevice.CreateDeviceClient(new[] { transportSetting }); + await deviceClient.OpenAsync().ConfigureAwait(false); + await MessageSendE2ETests.SendSingleMessageAsync(deviceClient, testDevice.Id, Logger).ConfigureAwait(false); + await deviceClient.CloseAsync().ConfigureAwait(false); } private ITransportSettings CreateHttpTransportSettingWithCertificateRevocationCheck() @@ -247,8 +251,32 @@ private ITransportSettings CreateAmqpTransportSettingWithCertificateRevocationCh private async Task X509InvalidDeviceIdOpenAsyncTest(Client.TransportType transportType) { - var deviceClient = CreateDeviceClientWithInvalidId(transportType); - using (deviceClient) + string deviceName = $"DEVICE_NOT_EXIST_{Guid.NewGuid()}"; + using var auth = new DeviceAuthenticationWithX509Certificate(deviceName, s_selfSignedCertificateWithPrivateKey); + using var deviceClient = DeviceClient.Create(_hostName, auth, transportType); + + try + { + await deviceClient.OpenAsync().ConfigureAwait(false); + Assert.Fail("Should throw UnauthorizedException but didn't."); + } + catch (UnauthorizedException) + { + // It should always throw UnauthorizedException + } + + // Check TCP connection to verify there is no connection leak + // netstat -na | find "[Your Hub IP]" | find "ESTABLISHED" + await Task.Delay(TimeSpan.FromSeconds(10)).ConfigureAwait(false); + } + + private async Task X509InvalidDeviceIdOpenAsyncTwiceTest(Client.TransportType transportType) + { + string deviceName = $"DEVICE_NOT_EXIST_{Guid.NewGuid()}"; + using var auth = new DeviceAuthenticationWithX509Certificate(deviceName, s_selfSignedCertificateWithPrivateKey); + using var deviceClient = DeviceClient.Create(_hostName, auth, transportType); + + for (int i = 0; i < 2; i++) { try { @@ -259,42 +287,24 @@ private async Task X509InvalidDeviceIdOpenAsyncTest(Client.TransportType transpo { // It should always throw UnauthorizedException } - - // Check TCP connection to verify there is no connection leak - // netstat -na | find "[Your Hub IP]" | find "ESTABLISHED" - await Task.Delay(TimeSpan.FromSeconds(10)).ConfigureAwait(false); } + + // Check TCP connection to verify there is no connection leak + // netstat -na | find "[Your Hub IP]" | find "ESTABLISHED" + await Task.Delay(TimeSpan.FromSeconds(10)).ConfigureAwait(false); } - private async Task X509InvalidDeviceIdOpenAsyncTwiceTest(Client.TransportType transportType) + [ClassCleanup] + public static void ClassCleanup() { - var deviceClient = CreateDeviceClientWithInvalidId(transportType); - using (deviceClient) - { - for (int i = 0; i < 2; i++) - { - try - { - await deviceClient.OpenAsync().ConfigureAwait(false); - Assert.Fail("Should throw UnauthorizedException but didn't."); - } - catch (UnauthorizedException) - { - // It should always throw UnauthorizedException - } - } +#if !NET451 + s_selfSignedCertificateWithPrivateKey?.Dispose(); + s_selfSignedCertificateWithPrivateKey = null; - // Check TCP connection to verify there is no connection leak - // netstat -na | find "[Your Hub IP]" | find "ESTABLISHED" - await Task.Delay(TimeSpan.FromSeconds(10)).ConfigureAwait(false); - } + s_chainCertificateWithPrivateKey?.Dispose(); + s_chainCertificateWithPrivateKey = null; +#endif } - private DeviceClient CreateDeviceClientWithInvalidId(Client.TransportType transportType) - { - string deviceName = $"DEVICE_NOT_EXIST_{Guid.NewGuid()}"; - var auth = new DeviceAuthenticationWithX509Certificate(deviceName, Configuration.IoTHub.GetCertificateWithPrivateKey()); - return DeviceClient.Create(_hostName, auth, transportType); - } } } diff --git a/e2e/test/iothub/DeviceTokenRefreshE2ETests.cs b/e2e/test/iothub/DeviceTokenRefreshE2ETests.cs index 9e5e69688a..88428e8697 100644 --- a/e2e/test/iothub/DeviceTokenRefreshE2ETests.cs +++ b/e2e/test/iothub/DeviceTokenRefreshE2ETests.cs @@ -28,7 +28,7 @@ public class DeviceTokenRefreshE2ETests : E2EMsTestBase [ExpectedException(typeof(DeviceNotFoundException))] public async Task DeviceClient_Not_Exist_AMQP() { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); var config = new Configuration.IoTHub.DeviceConnectionStringParser(testDevice.ConnectionString); using (DeviceClient deviceClient = DeviceClient.CreateFromConnectionString($"HostName={config.IoTHub};DeviceId=device_id_not_exist;SharedAccessKey={config.SharedAccessKey}", Client.TransportType.Amqp_Tcp_Only)) @@ -41,7 +41,7 @@ public async Task DeviceClient_Not_Exist_AMQP() [ExpectedException(typeof(UnauthorizedException))] public async Task DeviceClient_Bad_Credentials_AMQP() { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); var config = new Configuration.IoTHub.DeviceConnectionStringParser(testDevice.ConnectionString); string invalidKey = Convert.ToBase64String(Encoding.UTF8.GetBytes("invalid_key")); @@ -78,7 +78,7 @@ public async Task DeviceClient_TokenIsRefreshed_Ok_Mqtt() [LoggedTestMethod] public async Task DeviceClient_TokenConnectionDoubleRelease_Ok() { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); string deviceConnectionString = testDevice.ConnectionString; @@ -87,37 +87,38 @@ public async Task DeviceClient_TokenConnectionDoubleRelease_Ok() string deviceId = config.DeviceID; string key = config.SharedAccessKey; - SharedAccessSignatureBuilder builder = new SharedAccessSignatureBuilder() + var builder = new SharedAccessSignatureBuilder() { Key = key, TimeToLive = new TimeSpan(0, 10, 0), Target = $"{iotHub}/devices/{WebUtility.UrlEncode(deviceId)}", }; - DeviceAuthenticationWithToken auth = new DeviceAuthenticationWithToken(deviceId, builder.ToSignature()); + var auth = new DeviceAuthenticationWithToken(deviceId, builder.ToSignature()); - using (DeviceClient deviceClient = DeviceClient.Create(iotHub, auth, Client.TransportType.Amqp_Tcp_Only)) - { - Logger.Trace($"{deviceId}: Created {nameof(DeviceClient)} ID={TestLogger.IdOf(deviceClient)}"); + using var deviceClient = DeviceClient.Create(iotHub, auth, Client.TransportType.Amqp_Tcp_Only); + Logger.Trace($"{deviceId}: Created {nameof(DeviceClient)} ID={TestLogger.IdOf(deviceClient)}"); - Logger.Trace($"{deviceId}: DeviceClient OpenAsync."); - await deviceClient.OpenAsync().ConfigureAwait(false); - Logger.Trace($"{deviceId}: DeviceClient SendEventAsync."); - await deviceClient.SendEventAsync(new Client.Message(Encoding.UTF8.GetBytes("TestMessage"))).ConfigureAwait(false); - Logger.Trace($"{deviceId}: DeviceClient CloseAsync."); - await deviceClient.CloseAsync().ConfigureAwait(false); // First release - } // Second release + Logger.Trace($"{deviceId}: DeviceClient OpenAsync."); + await deviceClient.OpenAsync().ConfigureAwait(false); + + Logger.Trace($"{deviceId}: DeviceClient SendEventAsync."); + using var testMessage = new Client.Message(Encoding.UTF8.GetBytes("TestMessage")); + await deviceClient.SendEventAsync(testMessage).ConfigureAwait(false); + + Logger.Trace($"{deviceId}: DeviceClient CloseAsync."); + await deviceClient.CloseAsync().ConfigureAwait(false); } private async Task DeviceClient_TokenIsRefreshed_Internal(Client.TransportType transport, int ttl = 20) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); int buffer = 50; Device device = testDevice.Device; - SemaphoreSlim deviceDisconnected = new SemaphoreSlim(0); + using var deviceDisconnected = new SemaphoreSlim(0); - var refresher = new TestTokenRefresher( + using var refresher = new TestTokenRefresher( device.Id, device.Authentication.SymmetricKey.PrimaryKey, ttl, @@ -125,77 +126,73 @@ private async Task DeviceClient_TokenIsRefreshed_Internal(Client.TransportType t transport, Logger); - using (DeviceClient deviceClient = DeviceClient.Create(testDevice.IoTHubHostName, refresher, transport)) - { - Logger.Trace($"Created {nameof(DeviceClient)} ID={TestLogger.IdOf(deviceClient)}"); + using var deviceClient = DeviceClient.Create(testDevice.IoTHubHostName, refresher, transport); + Logger.Trace($"Created {nameof(DeviceClient)} ID={TestLogger.IdOf(deviceClient)}"); - if (transport == Client.TransportType.Mqtt) + if (transport == Client.TransportType.Mqtt) + { + deviceClient.SetConnectionStatusChangesHandler((ConnectionStatus status, ConnectionStatusChangeReason reason) => { - deviceClient.SetConnectionStatusChangesHandler((ConnectionStatus status, ConnectionStatusChangeReason reason) => + Logger.Trace($"{nameof(ConnectionStatusChangesHandler)}: {status}; {reason}"); + if (status == ConnectionStatus.Disconnected_Retrying || status == ConnectionStatus.Disconnected) { - Logger.Trace($"{nameof(ConnectionStatusChangesHandler)}: {status}; {reason}"); - if (status == ConnectionStatus.Disconnected_Retrying || status == ConnectionStatus.Disconnected) - { - deviceDisconnected.Release(); - } - }); - } + deviceDisconnected.Release(); + } + }); + } - var message = new Client.Message(Encoding.UTF8.GetBytes("Hello")); + using var message = new Client.Message(Encoding.UTF8.GetBytes("Hello")); - using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(ttl * 10))) - { - try - { - // Create the first Token. - Logger.Trace($"[{DateTime.UtcNow}] OpenAsync"); - await deviceClient.OpenAsync(cts.Token).ConfigureAwait(false); + using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(ttl * 10)); + try + { + // Create the first Token. + Logger.Trace($"[{DateTime.UtcNow}] OpenAsync"); + await deviceClient.OpenAsync(cts.Token).ConfigureAwait(false); - Logger.Trace($"[{DateTime.UtcNow}] SendEventAsync (1)"); - await deviceClient.SendEventAsync(message, cts.Token).ConfigureAwait(false); - await refresher.WaitForTokenRefreshAsync(cts.Token).ConfigureAwait(false); - } - catch (OperationCanceledException ex) - { - Assert.Fail($"{TestLogger.IdOf(deviceClient)} did not get the initial token. {ex}"); - throw; - } + Logger.Trace($"[{DateTime.UtcNow}] SendEventAsync (1)"); + await deviceClient.SendEventAsync(message, cts.Token).ConfigureAwait(false); + await refresher.WaitForTokenRefreshAsync(cts.Token).ConfigureAwait(false); + } + catch (OperationCanceledException ex) + { + Assert.Fail($"{TestLogger.IdOf(deviceClient)} did not get the initial token. {ex}"); + throw; + } - // Wait for the Token to expire. - if (transport == Client.TransportType.Http1) - { - float waitTime = (float)ttl * ((float)buffer / 100) + 1; - Logger.Trace($"[{DateTime.UtcNow}] Waiting {waitTime} seconds."); - await Task.Delay(TimeSpan.FromSeconds(waitTime)).ConfigureAwait(false); - } - else if (transport == Client.TransportType.Mqtt) - { - Logger.Trace($"[{DateTime.UtcNow}] Waiting for device disconnect."); - await deviceDisconnected.WaitAsync(cts.Token).ConfigureAwait(false); - } + // Wait for the Token to expire. + if (transport == Client.TransportType.Http1) + { + float waitTime = (float)ttl * ((float)buffer / 100) + 1; + Logger.Trace($"[{DateTime.UtcNow}] Waiting {waitTime} seconds."); + await Task.Delay(TimeSpan.FromSeconds(waitTime)).ConfigureAwait(false); + } + else if (transport == Client.TransportType.Mqtt) + { + Logger.Trace($"[{DateTime.UtcNow}] Waiting for device disconnect."); + await deviceDisconnected.WaitAsync(cts.Token).ConfigureAwait(false); + } - try - { - Logger.Trace($"[{DateTime.UtcNow}] SendEventAsync (2)"); - await deviceClient.SendEventAsync(message, cts.Token).ConfigureAwait(false); - await refresher.WaitForTokenRefreshAsync(cts.Token).ConfigureAwait(false); - } - catch (OperationCanceledException ex) - { - Assert.Fail($"{TestLogger.IdOf(deviceClient)} did not refresh token after {refresher.DetectedRefreshInterval}. {ex}"); - throw; - } + try + { + Logger.Trace($"[{DateTime.UtcNow}] SendEventAsync (2)"); + await deviceClient.SendEventAsync(message, cts.Token).ConfigureAwait(false); + await refresher.WaitForTokenRefreshAsync(cts.Token).ConfigureAwait(false); + } + catch (OperationCanceledException ex) + { + Assert.Fail($"{TestLogger.IdOf(deviceClient)} did not refresh token after {refresher.DetectedRefreshInterval}. {ex}"); + throw; + } - // Ensure that the token was refreshed. - Logger.Trace($"[{DateTime.UtcNow}] Token was refreshed after {refresher.DetectedRefreshInterval} (ttl = {ttl} seconds)."); - Assert.IsTrue( - refresher.DetectedRefreshInterval.TotalSeconds < (float)ttl * (1 + (float)buffer / 100), // Wait for more than what we expect. - $"Token was refreshed after {refresher.DetectedRefreshInterval} although ttl={ttl} seconds."); + // Ensure that the token was refreshed. + Logger.Trace($"[{DateTime.UtcNow}] Token was refreshed after {refresher.DetectedRefreshInterval} (ttl = {ttl} seconds)."); + Assert.IsTrue( + refresher.DetectedRefreshInterval.TotalSeconds < (float)ttl * (1 + (float)buffer / 100), // Wait for more than what we expect. + $"Token was refreshed after {refresher.DetectedRefreshInterval} although ttl={ttl} seconds."); - Logger.Trace($"[{DateTime.UtcNow}] CloseAsync"); - await deviceClient.CloseAsync().ConfigureAwait(false); - } - } + Logger.Trace($"[{DateTime.UtcNow}] CloseAsync"); + await deviceClient.CloseAsync().ConfigureAwait(false); } private class TestTokenRefresher : DeviceAuthenticationWithTokenRefresh diff --git a/e2e/test/iothub/FileUploadE2ETests.cs b/e2e/test/iothub/FileUploadE2ETests.cs index 968ebb2ca4..7cbd4d6352 100644 --- a/e2e/test/iothub/FileUploadE2ETests.cs +++ b/e2e/test/iothub/FileUploadE2ETests.cs @@ -92,7 +92,7 @@ public async Task FileUpload_SmallFile_Http_GranularSteps_x509() using var fileStreamSource = new FileStream(filename, FileMode.Open, FileAccess.Read); var fileUploadTransportSettings = new Http1TransportSettings(); - await UploadFileGranularAsync(fileStreamSource, filename, fileUploadTransportSettings, x509auth: true).ConfigureAwait(false); + await UploadFileGranularAsync(fileStreamSource, filename, fileUploadTransportSettings, useX509auth: true).ConfigureAwait(false); } [LoggedTestMethod] @@ -109,12 +109,12 @@ public async Task FileUpload_SmallFile_Http_GranularSteps_Proxy() await UploadFileGranularAsync(fileStreamSource, filename, fileUploadTransportSettings).ConfigureAwait(false); } - private async Task UploadFileGranularAsync(Stream source, string filename, Http1TransportSettings fileUploadTransportSettings, bool x509auth = false) + private async Task UploadFileGranularAsync(Stream source, string filename, Http1TransportSettings fileUploadTransportSettings, bool useX509auth = false) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync( + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync( Logger, _devicePrefix, - x509auth ? TestDeviceType.X509 : TestDeviceType.Sasl).ConfigureAwait(false); + useX509auth ? TestDeviceType.X509 : TestDeviceType.Sasl).ConfigureAwait(false); DeviceClient deviceClient; var clientOptions = new ClientOptions() @@ -122,16 +122,17 @@ private async Task UploadFileGranularAsync(Stream source, string filename, Http1 FileUploadTransportSettings = fileUploadTransportSettings }; - if (x509auth) + X509Certificate2 cert = null; + DeviceAuthenticationWithX509Certificate x509Auth = null; + if (useX509auth) { - X509Certificate2 cert = Configuration.IoTHub.GetCertificateWithPrivateKey(); - - var auth = new DeviceAuthenticationWithX509Certificate(testDevice.Id, cert); + cert = Configuration.IoTHub.GetCertificateWithPrivateKey(); + x509Auth = new DeviceAuthenticationWithX509Certificate(testDevice.Id, cert); // The X509 certificate being used for device authentication needs to be set into FileUploadTransportSettings as well, // so that the HttpClient created for file upload operation has access to those certificates. clientOptions.FileUploadTransportSettings.ClientCertificate = cert; - deviceClient = DeviceClient.Create(testDevice.IoTHubHostName, auth, Client.TransportType.Http1, clientOptions); + deviceClient = DeviceClient.Create(testDevice.IoTHubHostName, x509Auth, Client.TransportType.Http1, clientOptions); } else { @@ -143,36 +144,47 @@ private async Task UploadFileGranularAsync(Stream source, string filename, Http1 BlobName = filename }; - FileUploadSasUriResponse fileUploadSasUriResponse = await deviceClient.GetFileUploadSasUriAsync(fileUploadSasUriRequest).ConfigureAwait(false); + using (deviceClient) + { + FileUploadSasUriResponse fileUploadSasUriResponse = await deviceClient.GetFileUploadSasUriAsync(fileUploadSasUriRequest).ConfigureAwait(false); - var blob = new CloudBlockBlob(fileUploadSasUriResponse.GetBlobUri()); - Task uploadTask = blob.UploadFromStreamAsync(source); - await uploadTask.ConfigureAwait(false); + var blob = new CloudBlockBlob(fileUploadSasUriResponse.GetBlobUri()); + Task uploadTask = blob.UploadFromStreamAsync(source); + await uploadTask.ConfigureAwait(false); - var notification = new FileUploadCompletionNotification - { - CorrelationId = fileUploadSasUriResponse.CorrelationId, - IsSuccess = uploadTask.IsCompleted + var notification = new FileUploadCompletionNotification + { + CorrelationId = fileUploadSasUriResponse.CorrelationId, + IsSuccess = uploadTask.IsCompleted + }; + + await deviceClient.CompleteFileUploadAsync(notification).ConfigureAwait(false); }; - await deviceClient.CompleteFileUploadAsync(notification).ConfigureAwait(false); + x509Auth?.Dispose(); + +#if !NET451 + cert?.Dispose(); +#endif } [Obsolete] - private async Task UploadFileAsync(Client.TransportType transport, string filename, bool x509auth = false) + private async Task UploadFileAsync(Client.TransportType transport, string filename, bool useX509auth = false) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync( + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync( Logger, _devicePrefix, - x509auth ? TestDeviceType.X509 : TestDeviceType.Sasl).ConfigureAwait(false); + useX509auth ? TestDeviceType.X509 : TestDeviceType.Sasl).ConfigureAwait(false); DeviceClient deviceClient; - if (x509auth) + X509Certificate2 cert = null; + DeviceAuthenticationWithX509Certificate x509Auth = null; + if (useX509auth) { - X509Certificate2 cert = Configuration.IoTHub.GetCertificateWithPrivateKey(); + cert = Configuration.IoTHub.GetCertificateWithPrivateKey(); - var auth = new DeviceAuthenticationWithX509Certificate(testDevice.Id, cert); - deviceClient = DeviceClient.Create(testDevice.IoTHubHostName, auth, transport); + x509Auth = new DeviceAuthenticationWithX509Certificate(testDevice.Id, cert); + deviceClient = DeviceClient.Create(testDevice.IoTHubHostName, x509Auth, transport); } else { @@ -189,22 +201,29 @@ private async Task UploadFileAsync(Client.TransportType transport, string filena await deviceClient.CloseAsync().ConfigureAwait(false); } + + x509Auth?.Dispose(); + +#if !NET451 + cert?.Dispose(); +#endif } - private async Task GetSasUriAsync(Client.TransportType transport, string blobName, bool x509auth = false) + private async Task GetSasUriAsync(Client.TransportType transport, string blobName, bool useX509auth = false) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync( + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync( Logger, _devicePrefix, - x509auth ? TestDeviceType.X509 : TestDeviceType.Sasl).ConfigureAwait(false); + useX509auth ? TestDeviceType.X509 : TestDeviceType.Sasl).ConfigureAwait(false); DeviceClient deviceClient; - if (x509auth) + X509Certificate2 cert = null; + DeviceAuthenticationWithX509Certificate x509Auth = null; + if (useX509auth) { - X509Certificate2 cert = Configuration.IoTHub.GetCertificateWithPrivateKey(); - - var auth = new DeviceAuthenticationWithX509Certificate(testDevice.Id, cert); - deviceClient = DeviceClient.Create(testDevice.IoTHubHostName, auth, transport); + cert = Configuration.IoTHub.GetCertificateWithPrivateKey(); + x509Auth = new DeviceAuthenticationWithX509Certificate(testDevice.Id, cert); + deviceClient = DeviceClient.Create(testDevice.IoTHubHostName, x509Auth, transport); } else { @@ -216,6 +235,12 @@ private async Task GetSasUriAsync(Client.TransportType transport, string blobNam FileUploadSasUriResponse sasUriResponse = await deviceClient.GetFileUploadSasUriAsync(new FileUploadSasUriRequest { BlobName = blobName }); await deviceClient.CloseAsync().ConfigureAwait(false); } + + x509Auth?.Dispose(); + +#if !NET451 + cert?.Dispose(); +#endif } private static async Task GetTestFileNameAsync(int fileSize) diff --git a/e2e/test/iothub/FileUploadFaultInjectionTests.cs b/e2e/test/iothub/FileUploadFaultInjectionTests.cs index a729c445e1..35a20bfaf0 100644 --- a/e2e/test/iothub/FileUploadFaultInjectionTests.cs +++ b/e2e/test/iothub/FileUploadFaultInjectionTests.cs @@ -85,7 +85,7 @@ private async Task UploadFileDisconnectTransport( TimeSpan durationInSec = default, TimeSpan retryDurationInMilliSec = default) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); @@ -119,7 +119,8 @@ private static async Task SendErrorInjectionMessageAsync( { try { - await deviceClient.SendEventAsync(FaultInjection.ComposeErrorInjectionProperties(faultType, reason, delayInSec, durationInSec)).ConfigureAwait(false); + using Client.Message faultInjectionMessage = FaultInjection.ComposeErrorInjectionProperties(faultType, reason, delayInSec, durationInSec); + await deviceClient.SendEventAsync(faultInjectionMessage).ConfigureAwait(false); } catch { diff --git a/e2e/test/iothub/NoRetryE2ETests.cs b/e2e/test/iothub/NoRetryE2ETests.cs index 9d1e3ba519..f705b701ae 100644 --- a/e2e/test/iothub/NoRetryE2ETests.cs +++ b/e2e/test/iothub/NoRetryE2ETests.cs @@ -24,7 +24,7 @@ public class NoRetryE2ETests : E2EMsTestBase [TestCategory("FaultInjection")] public async Task FaultInjection_NoRetry_NoRecovery_OpenAsync() { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix, TestDeviceType.Sasl).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix, TestDeviceType.Sasl).ConfigureAwait(false); using DeviceClient deviceClient = testDevice.CreateDeviceClient(Client.TransportType.Amqp_Tcp_Only); Logger.Trace($"{nameof(FaultInjection_NoRetry_NoRecovery_OpenAsync)}: deviceId={testDevice.Id}"); @@ -83,7 +83,7 @@ await FaultInjection [LoggedTestMethod] public async Task DuplicateDevice_NoRetry_NoPingpong_OpenAsync() { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix, TestDeviceType.Sasl).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix, TestDeviceType.Sasl).ConfigureAwait(false); Logger.Trace($"{nameof(DuplicateDevice_NoRetry_NoPingpong_OpenAsync)}: 2 device client instances with the same deviceId={testDevice.Id}."); diff --git a/e2e/test/iothub/messaging/AzureSecurityCenterForIoTLogAnalyticsClient.cs b/e2e/test/iothub/messaging/AzureSecurityCenterForIoTLogAnalyticsClient.cs index 05bb91e98e..241367f71f 100644 --- a/e2e/test/iothub/messaging/AzureSecurityCenterForIoTLogAnalyticsClient.cs +++ b/e2e/test/iothub/messaging/AzureSecurityCenterForIoTLogAnalyticsClient.cs @@ -49,6 +49,8 @@ public class AzureSecurityCenterForIoTLogAnalyticsClient : IDisposable private readonly AuthenticationContext _authenticationContext; private readonly IClientAssertionCertificate _certificateAssertion; + private readonly X509Certificate2 _authCertificate; + //These are used in NET451 instead of OperationalInsights SDK private readonly HttpClient _client; @@ -65,8 +67,8 @@ private AzureSecurityCenterForIoTLogAnalyticsClient() _queryUri = string.Format(CultureInfo.InvariantCulture, QueryUriTemplate, LogAnalyticsApiVersion, _workspaceId); string authority = string.Format(CultureInfo.InvariantCulture, AuthenticationAuthorityTemplate, _aadTenant); _authenticationContext = new AuthenticationContext(authority); - var cert = new X509Certificate2(Convert.FromBase64String(_appCertificate)); - _certificateAssertion = new ClientAssertionCertificate(_appId, cert); + _authCertificate = new X509Certificate2(Convert.FromBase64String(_appCertificate)); + _certificateAssertion = new ClientAssertionCertificate(_appId, _authCertificate); } public async Task IsRawEventExist(string deviceId, string eventId) @@ -137,6 +139,10 @@ protected virtual void Dispose(bool disposing) if (disposing) { _client?.Dispose(); + +#if !NET451 + _authCertificate?.Dispose(); +#endif } } } diff --git a/e2e/test/iothub/messaging/AzureSecurityCenterForIoTSecurityMessageE2ETests.cs b/e2e/test/iothub/messaging/AzureSecurityCenterForIoTSecurityMessageE2ETests.cs index a6c2aa0282..dbe1105982 100644 --- a/e2e/test/iothub/messaging/AzureSecurityCenterForIoTSecurityMessageE2ETests.cs +++ b/e2e/test/iothub/messaging/AzureSecurityCenterForIoTSecurityMessageE2ETests.cs @@ -125,7 +125,7 @@ private JObject ComposeAzureSecurityCenterForIoTSecurityMessagePayload(string ev private async Task TestSecurityMessageAsync(Client.TransportType transport) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); using DeviceClient deviceClient = testDevice.CreateDeviceClient(transport); try @@ -162,7 +162,7 @@ private async Task SendSingleSecurityMessageAsync( { await deviceClient.OpenAsync().ConfigureAwait(false); - Client.Message testMessage = ComposeD2CSecurityTestMessage(out string eventId, out string payload, out string p1Value); + using Client.Message testMessage = ComposeD2CSecurityTestMessage(out string eventId, out string payload, out string p1Value); await deviceClient.SendEventAsync(testMessage).ConfigureAwait(false); await ValidateEventAsync(deviceId, eventId, logAnalticsTestClient).ConfigureAwait(false); @@ -174,7 +174,7 @@ private async Task SendSingleSecurityMessageModuleAsync( AzureSecurityCenterForIoTLogAnalyticsClient logAnalticsTestClient) { await moduleClient.OpenAsync().ConfigureAwait(false); - Client.Message testMessage = ComposeD2CSecurityTestMessage(out string eventId, out _, out _); + using Client.Message testMessage = ComposeD2CSecurityTestMessage(out string eventId, out _, out _); await moduleClient.SendEventAsync(testMessage).ConfigureAwait(false); await ValidateEventAsync(deviceId, eventId, logAnalticsTestClient).ConfigureAwait(false); diff --git a/e2e/test/iothub/messaging/FaultInjectionPoolAmqpTests.MessageReceiveFaultInjectionPoolAmqpTests.cs b/e2e/test/iothub/messaging/FaultInjectionPoolAmqpTests.MessageReceiveFaultInjectionPoolAmqpTests.cs index ebe911e96a..cbf307526a 100644 --- a/e2e/test/iothub/messaging/FaultInjectionPoolAmqpTests.MessageReceiveFaultInjectionPoolAmqpTests.cs +++ b/e2e/test/iothub/messaging/FaultInjectionPoolAmqpTests.MessageReceiveFaultInjectionPoolAmqpTests.cs @@ -895,7 +895,7 @@ private async Task ReceiveMessageRecoveryPoolOverAmqpAsync( string proxyAddress = null) { // Initialize the service client - var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); async Task TestOperationAsync(DeviceClient deviceClient, TestDevice testDevice, TestDeviceCallbackHandler _) { @@ -911,16 +911,14 @@ await MessageReceiveE2ETests.VerifyReceivedC2DMessageAsync(transport, deviceClie .ConfigureAwait(false); } - async Task CleanupOperationAsync(IList deviceClients) + async Task CleanupOperationAsync(List deviceClients, List testDeviceCallbackHandlers) { await serviceClient.CloseAsync() .ConfigureAwait(false); serviceClient.Dispose(); - foreach (DeviceClient deviceClient in deviceClients) - { - deviceClient.Dispose(); - } + deviceClients.ForEach(deviceClient => deviceClient.Dispose()); + testDeviceCallbackHandlers.ForEach(testDeviceCallbackHandler => testDeviceCallbackHandler.Dispose()); } await FaultInjectionPoolingOverAmqp @@ -977,15 +975,13 @@ async Task TestOperationAsync(DeviceClient deviceClient, TestDevice testDevice, receivedMessage.Should().BeNull(); } - async Task CleanupOperationAsync(IList deviceClients) + async Task CleanupOperationAsync(List deviceClients, List testDeviceCallbackHandlers) { await serviceClient.CloseAsync().ConfigureAwait(false); serviceClient.Dispose(); - foreach (DeviceClient deviceClient in deviceClients) - { - deviceClient.Dispose(); - } + deviceClients.ForEach(deviceClient => deviceClient.Dispose()); + testDeviceCallbackHandlers.ForEach(testDeviceCallbackHandler => testDeviceCallbackHandler.Dispose()); } await FaultInjectionPoolingOverAmqp diff --git a/e2e/test/iothub/messaging/FaultInjectionPoolAmqpTests.MessageSendFaultInjectionPoolAmqpTests.cs b/e2e/test/iothub/messaging/FaultInjectionPoolAmqpTests.MessageSendFaultInjectionPoolAmqpTests.cs index 58e8801f79..de86d5dd88 100644 --- a/e2e/test/iothub/messaging/FaultInjectionPoolAmqpTests.MessageSendFaultInjectionPoolAmqpTests.cs +++ b/e2e/test/iothub/messaging/FaultInjectionPoolAmqpTests.MessageSendFaultInjectionPoolAmqpTests.cs @@ -892,13 +892,9 @@ async Task TestOperationAsync(DeviceClient deviceClient, TestDevice testDevice, await deviceClient.SendEventAsync(testMessage).ConfigureAwait(false); } - Task CleanupOperationAsync(IList deviceClients) + Task CleanupOperationAsync(List deviceClients, List _) { - foreach (DeviceClient deviceClient in deviceClients) - { - deviceClient.Dispose(); - } - + deviceClients.ForEach(deviceClient => deviceClient.Dispose()); return Task.FromResult(0); } diff --git a/e2e/test/iothub/messaging/MessageFeedbackE2ETests.cs b/e2e/test/iothub/messaging/MessageFeedbackE2ETests.cs index 7968b17d46..1ef202f21d 100644 --- a/e2e/test/iothub/messaging/MessageFeedbackE2ETests.cs +++ b/e2e/test/iothub/messaging/MessageFeedbackE2ETests.cs @@ -31,7 +31,7 @@ public async Task Message_CompleteMixOrder_AMQP() private static async Task CompleteMessageMixOrder(TestDeviceType type, Client.TransportType transport, MsTestLogger logger) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(logger, s_devicePrefix, type).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(logger, s_devicePrefix, type).ConfigureAwait(false); using (DeviceClient deviceClient = testDevice.CreateDeviceClient(transport)) using (ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString)) { diff --git a/e2e/test/iothub/messaging/MessageReceiveE2ETests.cs b/e2e/test/iothub/messaging/MessageReceiveE2ETests.cs index 006c5676d8..482b7598ee 100644 --- a/e2e/test/iothub/messaging/MessageReceiveE2ETests.cs +++ b/e2e/test/iothub/messaging/MessageReceiveE2ETests.cs @@ -562,7 +562,7 @@ public static async Task VerifyReceivedC2dMessageWithCancellationTokenAsync(Clie private async Task ReceiveMessageInOperationTimeoutAsync(TestDeviceType type, Client.TransportType transport) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false); using DeviceClient deviceClient = testDevice.CreateDeviceClient(transport); Logger.Trace($"{nameof(ReceiveMessageInOperationTimeoutAsync)} - calling OpenAsync() for transport={transport}"); @@ -598,7 +598,7 @@ private async Task ReceiveMessageInOperationTimeoutAsync(TestDeviceType type, Cl private async Task ReceiveSingleMessageAsync(TestDeviceType type, Client.TransportType transport) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false); using DeviceClient deviceClient = testDevice.CreateDeviceClient(transport); using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); @@ -629,7 +629,7 @@ private async Task ReceiveSingleMessageAsync(TestDeviceType type, Client.Transpo private async Task ReceiveSingleMessageWithCancellationTokenAsync(TestDeviceType type, Client.TransportType transport) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false); using DeviceClient deviceClient = testDevice.CreateDeviceClient(transport); using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); @@ -693,7 +693,7 @@ private static async Task ReceiveMessageWithoutTimeoutCheckAsync(DeviceClient dc private async Task ReceiveSingleMessageUsingCallbackAsync(TestDeviceType type, Client.TransportType transport) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false); using DeviceClient deviceClient = testDevice.CreateDeviceClient(transport); using var testDeviceCallbackHandler = new TestDeviceCallbackHandler(deviceClient, testDevice, Logger); @@ -720,7 +720,7 @@ await Task private async Task ReceiveMessageUsingCallbackAndUnsubscribeAsync(TestDeviceType type, Client.TransportType transport) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false); using DeviceClient deviceClient = testDevice.CreateDeviceClient(transport); using var testDeviceCallbackHandler = new TestDeviceCallbackHandler(deviceClient, testDevice, Logger); @@ -796,10 +796,10 @@ private async Task ReceiveMessageUsingCallbackAndUnsubscribeAsync(TestDeviceType private async Task ReceiveMessageUsingCallbackUpdateHandlerAsync(TestDeviceType type, Client.TransportType transport) { - var firstHandlerSemaphore = new SemaphoreSlim(0, 1); - var secondHandlerSemaphore = new SemaphoreSlim(0, 1); + using var firstHandlerSemaphore = new SemaphoreSlim(0, 1); + using var secondHandlerSemaphore = new SemaphoreSlim(0, 1); - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false); using DeviceClient deviceClient = testDevice.CreateDeviceClient(transport); using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); @@ -856,7 +856,7 @@ await Task private async Task ReceiveMessagesSentBeforeSubscriptionAsync(TestDeviceType type, Client.TransportType transport) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false); DeviceClient deviceClient = testDevice.CreateDeviceClient(transport); var testDeviceCallbackHandler = new TestDeviceCallbackHandler(deviceClient, testDevice, Logger); @@ -899,7 +899,7 @@ private async Task ReceiveMessagesSentBeforeSubscriptionAsync(TestDeviceType typ private async Task DoNotReceiveMessagesSentBeforeSubscriptionAsync(TestDeviceType type, ITransportSettings[] settings) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false); DeviceClient deviceClient = testDevice.CreateDeviceClient(settings); var testDeviceCallbackHandler = new TestDeviceCallbackHandler(deviceClient, testDevice, Logger); diff --git a/e2e/test/iothub/messaging/MessageSendE2ETests.cs b/e2e/test/iothub/messaging/MessageSendE2ETests.cs index 6415c03e85..cf9fec5e0a 100644 --- a/e2e/test/iothub/messaging/MessageSendE2ETests.cs +++ b/e2e/test/iothub/messaging/MessageSendE2ETests.cs @@ -212,7 +212,7 @@ public async Task X509_DeviceSendBatchMessages_Http() [ExpectedException(typeof(MessageTooLargeException))] public async Task Message_ClientThrowsForMqttTopicNameTooLong() { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); using DeviceClient deviceClient = testDevice.CreateDeviceClient(Client.TransportType.Mqtt); await deviceClient.OpenAsync().ConfigureAwait(false); @@ -247,7 +247,7 @@ public async Task Message_DeviceSendSingleLargeMessageAsync(TestDeviceType testD private async Task SendSingleMessage(TestDeviceType type, Client.TransportType transport, int messageSize = 0) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix, type).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix, type).ConfigureAwait(false); using DeviceClient deviceClient = testDevice.CreateDeviceClient(transport); await deviceClient.OpenAsync().ConfigureAwait(false); @@ -257,7 +257,7 @@ private async Task SendSingleMessage(TestDeviceType type, Client.TransportType t private async Task SendBatchMessages(TestDeviceType type, Client.TransportType transport) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix, type).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix, type).ConfigureAwait(false); using DeviceClient deviceClient = testDevice.CreateDeviceClient(transport); await deviceClient.OpenAsync().ConfigureAwait(false); @@ -267,7 +267,7 @@ private async Task SendBatchMessages(TestDeviceType type, Client.TransportType t private async Task SendSingleMessage(TestDeviceType type, ITransportSettings[] transportSettings, int messageSize = 0) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix, type).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix, type).ConfigureAwait(false); using DeviceClient deviceClient = testDevice.CreateDeviceClient(transportSettings); await deviceClient.OpenAsync().ConfigureAwait(false); diff --git a/e2e/test/iothub/method/FaultInjectionPoolAmqpTests.MethodFaultInjectionPoolAmqpTests.cs b/e2e/test/iothub/method/FaultInjectionPoolAmqpTests.MethodFaultInjectionPoolAmqpTests.cs index 28179e035d..3e23e4c797 100644 --- a/e2e/test/iothub/method/FaultInjectionPoolAmqpTests.MethodFaultInjectionPoolAmqpTests.cs +++ b/e2e/test/iothub/method/FaultInjectionPoolAmqpTests.MethodFaultInjectionPoolAmqpTests.cs @@ -735,22 +735,16 @@ private async Task SendMethodAndRespondRecoveryPoolOverAmqpAsync( ConnectionStringAuthScope authScope = ConnectionStringAuthScope.Device, string proxyAddress = null) { - var testDevicesWithCallbackHandler = new Dictionary(); - - async Task InitOperationAsync(DeviceClient deviceClient, TestDevice testDevice, TestDeviceCallbackHandler _) + async Task InitOperationAsync(DeviceClient deviceClient, TestDevice testDevice, TestDeviceCallbackHandler testDeviceCallbackHandler) { - var testDeviceCallbackHandler = new TestDeviceCallbackHandler(deviceClient, testDevice, Logger); - testDevicesWithCallbackHandler.Add(testDevice.Id, testDeviceCallbackHandler); - Logger.Trace($"{nameof(MethodE2EPoolAmqpTests)}: Setting method callback handler for device {testDevice.Id}"); await testDeviceCallbackHandler .SetDeviceReceiveMethodAsync(MethodName, MethodE2ETests.DeviceResponseJson, MethodE2ETests.ServiceRequestJson) .ConfigureAwait(false); } - async Task TestOperationAsync(DeviceClient deviceClient, TestDevice testDevice, TestDeviceCallbackHandler _) + async Task TestOperationAsync(DeviceClient deviceClient, TestDevice testDevice, TestDeviceCallbackHandler testDeviceCallbackHandler) { - TestDeviceCallbackHandler testDeviceCallbackHandler = testDevicesWithCallbackHandler[testDevice.Id]; using var cts = new CancellationTokenSource(FaultInjection.RecoveryTime); Logger.Trace($"{nameof(MethodE2EPoolAmqpTests)}: Preparing to receive method for device {testDevice.Id}"); @@ -766,20 +760,11 @@ async Task TestOperationAsync(DeviceClient deviceClient, TestDevice testDevice, await Task.WhenAll(serviceSendTask, methodReceivedTask).ConfigureAwait(false); } - async Task CleanupOperationAsync(IList deviceClients) + async Task CleanupOperationAsync(List deviceClients, List testDeviceCallbackHandlers) { - foreach (DeviceClient deviceClient in deviceClients) - { - deviceClient.Dispose(); - } - - foreach (KeyValuePair entry in testDevicesWithCallbackHandler) - { - TestDeviceCallbackHandler testDeviceCallbackHandler = entry.Value; - testDeviceCallbackHandler?.Dispose(); - } - - testDevicesWithCallbackHandler.Clear(); + deviceClients.ForEach(deviceClient => deviceClient.Dispose()); + testDeviceCallbackHandlers.ForEach(testDeviceCallbackHandler => testDeviceCallbackHandler.Dispose()); + await Task.FromResult(false).ConfigureAwait(false); } diff --git a/e2e/test/iothub/method/MethodE2ETests.cs b/e2e/test/iothub/method/MethodE2ETests.cs index 8a5ab15554..46418418a7 100644 --- a/e2e/test/iothub/method/MethodE2ETests.cs +++ b/e2e/test/iothub/method/MethodE2ETests.cs @@ -224,7 +224,7 @@ public async Task Method_ModuleReceivesMethodAndResponseWithDefaultMethodHandler public async Task Method_ServiceInvokeDeviceMethodWithUnknownModuleThrows() { // setup - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, "ModuleNotFoundTest").ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, "ModuleNotFoundTest").ConfigureAwait(false); using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); var methodInvocation = new CloudToDeviceMethod("SetTelemetryInterval"); methodInvocation.SetPayloadJson("10"); @@ -271,7 +271,7 @@ await serviceClient.InvokeDeviceMethodAsync( catch (Exception ex) { if (!(ex is DeviceNotFoundException)) - throw ex; + throw; } finally { @@ -503,7 +503,7 @@ await moduleClient.SetMethodDefaultHandlerAsync( private async Task SendMethodAndUnsubscribeAsync(Client.TransportType transport, Func> subscribeAndUnsubscribeMethod, TimeSpan responseTimeout = default, ServiceClientTransportSettings serviceClientTransportSettings = default) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); await subscribeAndUnsubscribeMethod(deviceClient, MethodName, Logger).ConfigureAwait(false); @@ -515,7 +515,7 @@ private async Task SendMethodAndUnsubscribeAsync(Client.TransportType transport, private async Task SendMethodAndRespondAsync(Client.TransportType transport, Func> setDeviceReceiveMethod, TimeSpan responseTimeout = default, ServiceClientTransportSettings serviceClientTransportSettings = default) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); Task methodReceivedTask = await setDeviceReceiveMethod(deviceClient, MethodName, Logger).ConfigureAwait(false); diff --git a/e2e/test/iothub/service/BulkOperationsE2ETests.cs b/e2e/test/iothub/service/BulkOperationsE2ETests.cs index 97880bb878..451c992b56 100644 --- a/e2e/test/iothub/service/BulkOperationsE2ETests.cs +++ b/e2e/test/iothub/service/BulkOperationsE2ETests.cs @@ -24,7 +24,7 @@ public async Task BulkOperations_UpdateTwins2Device_Ok() var tagName = Guid.NewGuid().ToString(); var tagValue = Guid.NewGuid().ToString(); - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); Twin twin = await registryManager.GetTwinAsync(testDevice.Id).ConfigureAwait(false); @@ -51,7 +51,7 @@ public async Task BulkOperations_UpdateTwins2DevicePatch_Ok() var tagName = Guid.NewGuid().ToString(); var tagValue = Guid.NewGuid().ToString(); - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); Twin twin = new Twin(); diff --git a/e2e/test/iothub/service/DigitalTwinClientE2ETests.cs b/e2e/test/iothub/service/DigitalTwinClientE2ETests.cs index 4d8aee5168..a76bceac00 100644 --- a/e2e/test/iothub/service/DigitalTwinClientE2ETests.cs +++ b/e2e/test/iothub/service/DigitalTwinClientE2ETests.cs @@ -31,7 +31,7 @@ public class DigitalTwinClientE2ETests : E2EMsTestBase public async Task DigitalTwinWithOnlyRootComponentOperationsAsync() { // Create a new test device instance. - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); string deviceId = testDevice.Id; try @@ -103,7 +103,7 @@ await deviceClient.SetMethodHandlerAsync(commandName, public async Task DigitalTwinWithComponentOperationsAsync() { // Create a new test device instance. - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); string deviceId = testDevice.Id; try diff --git a/e2e/test/iothub/service/IoTHubCertificateValidationE2ETest.cs b/e2e/test/iothub/service/IoTHubCertificateValidationE2ETest.cs index 4ba550d855..b0e8f1c40b 100644 --- a/e2e/test/iothub/service/IoTHubCertificateValidationE2ETest.cs +++ b/e2e/test/iothub/service/IoTHubCertificateValidationE2ETest.cs @@ -18,9 +18,9 @@ public class IoTHubCertificateValidationE2ETest : E2EMsTestBase [LoggedTestMethod] public async Task RegistryManager_QueryDevicesInvalidServiceCertificateHttp_Fails() { - var rm = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionStringInvalidServiceCertificate); + using var rm = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionStringInvalidServiceCertificate); IQuery query = rm.CreateQuery("select * from devices"); - var exception = await Assert.ThrowsExceptionAsync( + IotHubCommunicationException exception = await Assert.ThrowsExceptionAsync( () => query.GetNextAsTwinAsync()).ConfigureAwait(false); #if NET451 || NET472 @@ -50,18 +50,19 @@ public async Task ServiceClient_SendMessageToDeviceInvalidServiceCertificateAmqp private static async Task TestServiceClientInvalidServiceCertificate(TransportType transport) { - var service = ServiceClient.CreateFromConnectionString( + using var service = ServiceClient.CreateFromConnectionString( Configuration.IoTHub.ConnectionStringInvalidServiceCertificate, transport); - await service.SendAsync("testDevice1", new Message()).ConfigureAwait(false); + using var testMessage = new Message(); + await service.SendAsync("testDevice1", testMessage).ConfigureAwait(false); } [LoggedTestMethod] public async Task JobClient_ScheduleTwinUpdateInvalidServiceCertificateHttp_Fails() { - var job = JobClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionStringInvalidServiceCertificate); + using var jobClient = JobClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionStringInvalidServiceCertificate); var exception = await Assert.ThrowsExceptionAsync( - () => job.ScheduleTwinUpdateAsync( + () => jobClient.ScheduleTwinUpdateAsync( "testDevice", "DeviceId IN ['testDevice']", new Shared.Twin(), @@ -132,7 +133,8 @@ private static async Task TestDeviceClientInvalidServiceCertificate(Client.Trans Configuration.IoTHub.DeviceConnectionStringInvalidServiceCertificate, transport)) { - await deviceClient.SendEventAsync(new Client.Message()).ConfigureAwait(false); + using var testMessage = new Client.Message(); + await deviceClient.SendEventAsync(testMessage).ConfigureAwait(false); await deviceClient.CloseAsync().ConfigureAwait(false); } } diff --git a/e2e/test/iothub/service/IoTHubServiceProxyE2ETests.cs b/e2e/test/iothub/service/IoTHubServiceProxyE2ETests.cs index da10526a10..867ba646f8 100644 --- a/e2e/test/iothub/service/IoTHubServiceProxyE2ETests.cs +++ b/e2e/test/iothub/service/IoTHubServiceProxyE2ETests.cs @@ -57,7 +57,7 @@ public async Task JobClient_ScheduleAndRunTwinJob_WithProxy() private async Task SendSingleMessageService(ServiceClientTransportSettings transportSettings) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); using (DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString)) using (ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(s_connectionString, TransportType.Amqp, transportSettings)) { diff --git a/e2e/test/iothub/service/PnpServiceTests.cs b/e2e/test/iothub/service/PnpServiceTests.cs index ad84bb3eed..a8f942ed19 100644 --- a/e2e/test/iothub/service/PnpServiceTests.cs +++ b/e2e/test/iothub/service/PnpServiceTests.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; using System.Collections.Generic; +using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading.Tasks; using FluentAssertions; @@ -31,7 +32,7 @@ public async Task DeviceTwin_Contains_ModelId() // Setup // Create a device. - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); // Send model ID with MQTT connect packet to make the device plug and play. var options = new ClientOptions { @@ -59,14 +60,15 @@ public async Task DeviceTwin_Contains_ModelId_X509() // Setup // Create a device. - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix, TestDeviceType.X509).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix, TestDeviceType.X509).ConfigureAwait(false); // Send model ID with MQTT connect packet to make the device plug and play. var options = new ClientOptions { ModelId = TestModelId, }; string hostName = HostNameHelper.GetHostName(Configuration.IoTHub.ConnectionString); - var auth = new DeviceAuthenticationWithX509Certificate(testDevice.Id, Configuration.IoTHub.GetCertificateWithPrivateKey()); + X509Certificate2 authCertificate = Configuration.IoTHub.GetCertificateWithPrivateKey(); + using var auth = new DeviceAuthenticationWithX509Certificate(testDevice.Id, authCertificate); using var deviceClient = DeviceClient.Create(hostName, auth, Client.TransportType.Mqtt_Tcp_Only, options); await deviceClient.OpenAsync().ConfigureAwait(false); @@ -81,6 +83,10 @@ public async Task DeviceTwin_Contains_ModelId_X509() // Cleanup await registryManager.RemoveDeviceAsync(testDevice.Id).ConfigureAwait(false); + +#if !NET451 + authCertificate?.Dispose(); +#endif } [TestMethod] diff --git a/e2e/test/iothub/service/RegistryManagerE2ETests.cs b/e2e/test/iothub/service/RegistryManagerE2ETests.cs index 5872b42aab..2499a1aeef 100644 --- a/e2e/test/iothub/service/RegistryManagerE2ETests.cs +++ b/e2e/test/iothub/service/RegistryManagerE2ETests.cs @@ -28,7 +28,7 @@ public class RegistryManagerE2ETests : E2EMsTestBase public async Task RegistryManager_BadProxy_ThrowsException() { // arrange - var registryManager = RegistryManager.CreateFromConnectionString( + using var registryManager = RegistryManager.CreateFromConnectionString( Configuration.IoTHub.ConnectionString, new HttpTransportSettings { @@ -42,7 +42,7 @@ public async Task RegistryManager_BadProxy_ThrowsException() [LoggedTestMethod] public async Task RegistryManager_AddAndRemoveDeviceWithScope() { - var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); string deviceId = _devicePrefix + Guid.NewGuid(); @@ -98,7 +98,7 @@ public async Task RegistryManager_BulkLifecycle() devices.Add(new Device(_devicePrefix + Guid.NewGuid())); } - var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); // Test that you can create devices in bulk var bulkAddResult = await registryManager.AddDevices2Async(devices).ConfigureAwait(false); @@ -214,7 +214,7 @@ public async Task ModulesClient_GetModulesOnDevice() } Device device = null; - RegistryManager client = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using RegistryManager client = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); try { @@ -257,7 +257,7 @@ public async Task ModulesClient_IdentityLifecycle() string testDeviceId = $"IdentityLifecycleDevice{Guid.NewGuid()}"; string testModuleId = $"IdentityLifecycleModule{Guid.NewGuid()}"; - RegistryManager client = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using RegistryManager client = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); try { @@ -300,8 +300,8 @@ public async Task ModulesClient_IdentityLifecycle() [LoggedTestMethod] public async Task ModulesClient_DeviceTwinLifecycle() { - RegistryManager client = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); - var module = await TestModule.GetTestModuleAsync(_devicePrefix, _modulePrefix, Logger).ConfigureAwait(false); + using RegistryManager client = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + TestModule module = await TestModule.GetTestModuleAsync(_devicePrefix, _modulePrefix, Logger).ConfigureAwait(false); try { diff --git a/e2e/test/iothub/service/RegistryManagerExportDevicesTests.cs b/e2e/test/iothub/service/RegistryManagerExportDevicesTests.cs index 211cb7c791..be2887ea4c 100644 --- a/e2e/test/iothub/service/RegistryManagerExportDevicesTests.cs +++ b/e2e/test/iothub/service/RegistryManagerExportDevicesTests.cs @@ -54,7 +54,7 @@ public async Task RegistryManager_ExportDevices(StorageAuthenticationType storag StorageContainer storageContainer = null; string deviceId = $"{nameof(RegistryManager_ExportDevices)}-{StorageContainer.GetRandomSuffix(4)}"; - var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); Logger.Trace($"Using deviceId {deviceId}"); diff --git a/e2e/test/iothub/service/RegistryManagerImportDevicesTests.cs b/e2e/test/iothub/service/RegistryManagerImportDevicesTests.cs index d47f7aa44a..8fc44d2b65 100644 --- a/e2e/test/iothub/service/RegistryManagerImportDevicesTests.cs +++ b/e2e/test/iothub/service/RegistryManagerImportDevicesTests.cs @@ -48,7 +48,7 @@ public async Task RegistryManager_ImportDevices(StorageAuthenticationType storag StorageContainer storageContainer = null; string deviceId = $"{nameof(RegistryManager_ImportDevices)}-{StorageContainer.GetRandomSuffix(4)}"; - var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); Logger.Trace($"Using deviceId {deviceId}"); @@ -64,7 +64,7 @@ public async Task RegistryManager_ImportDevices(StorageAuthenticationType storag ? storageContainer.SasUri : storageContainer.Uri; - Stream devicesFile = ImportExportDevicesHelpers.BuildDevicesStream( + using Stream devicesFile = ImportExportDevicesHelpers.BuildDevicesStream( new List { new ExportImportDevice( diff --git a/e2e/test/iothub/service/ServiceClientE2ETests.cs b/e2e/test/iothub/service/ServiceClientE2ETests.cs index e9af1c4eb3..d336f3199c 100644 --- a/e2e/test/iothub/service/ServiceClientE2ETests.cs +++ b/e2e/test/iothub/service/ServiceClientE2ETests.cs @@ -47,7 +47,7 @@ private async Task DefaultTimeout() private async Task TestTimeout(TimeSpan? timeout) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); using var sender = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); Stopwatch sw = new Stopwatch(); @@ -56,7 +56,8 @@ private async Task TestTimeout(TimeSpan? timeout) Logger.Trace($"Testing ServiceClient SendAsync() timeout in ticks={timeout?.Ticks}"); try { - await sender.SendAsync(testDevice.Id, new Message(Encoding.ASCII.GetBytes("Dummy Message")), timeout).ConfigureAwait(false); + using var testMessage = new Message(Encoding.ASCII.GetBytes("Test Message")); + await sender.SendAsync(testDevice.Id, testMessage, timeout).ConfigureAwait(false); } finally { @@ -71,12 +72,12 @@ private async Task TestTimeout(TimeSpan? timeout) public async Task ServiceClient_SendsMessage(TransportType transportType) { // arrange - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); using var sender = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString, transportType); string messageId = Guid.NewGuid().ToString(); // act and expect no exception - var message = new Message + using var message = new Message { MessageId = messageId, }; @@ -90,13 +91,13 @@ public async Task ServiceClient_SendsMessage(TransportType transportType) public async Task MessageIdDefaultNotSet_SendEventDoesNotSetMessageId() { // arrange - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); using var sender = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); string messageId = Guid.NewGuid().ToString(); // act - var messageWithoutId = new Message(); - var messageWithId = new Message + using var messageWithoutId = new Message(); + using var messageWithId = new Message { MessageId = messageId, }; @@ -115,7 +116,7 @@ public async Task MessageIdDefaultNotSet_SendEventDoesNotSetMessageId() public async Task MessageIdDefaultSetToNull_SendEventDoesNotSetMessageId() { // arrange - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); var options = new ServiceClientOptions { SdkAssignsMessageId = Shared.SdkAssignsMessageId.Never, @@ -124,8 +125,8 @@ public async Task MessageIdDefaultSetToNull_SendEventDoesNotSetMessageId() string messageId = Guid.NewGuid().ToString(); // act - var messageWithoutId = new Message(); - var messageWithId = new Message + using var messageWithoutId = new Message(); + using var messageWithId = new Message { MessageId = messageId, }; @@ -144,7 +145,7 @@ public async Task MessageIdDefaultSetToNull_SendEventDoesNotSetMessageId() public async Task MessageIdDefaultSetToGuid_SendEventSetMessageIdIfNotSet() { // arrange - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); var options = new ServiceClientOptions { SdkAssignsMessageId = Shared.SdkAssignsMessageId.WhenUnset, @@ -153,8 +154,8 @@ public async Task MessageIdDefaultSetToGuid_SendEventSetMessageIdIfNotSet() string messageId = Guid.NewGuid().ToString(); // act - var messageWithoutId = new Message(); - var messageWithId = new Message + using var messageWithoutId = new Message(); + using var messageWithId = new Message { MessageId = messageId, }; diff --git a/e2e/test/iothub/twin/FaultInjectionPoolAmqpTests.TwinFaultInjectionPoolAmqpTests.cs b/e2e/test/iothub/twin/FaultInjectionPoolAmqpTests.TwinFaultInjectionPoolAmqpTests.cs index 9dc7ca5968..53736ec57c 100644 --- a/e2e/test/iothub/twin/FaultInjectionPoolAmqpTests.TwinFaultInjectionPoolAmqpTests.cs +++ b/e2e/test/iothub/twin/FaultInjectionPoolAmqpTests.TwinFaultInjectionPoolAmqpTests.cs @@ -1439,12 +1439,9 @@ async Task TestOperationAsync(DeviceClient deviceClient, TestDevice testDevice, await TwinE2ETests.Twin_DeviceSetsReportedPropertyAndGetsItBackAsync(deviceClient, testDevice.Id, Guid.NewGuid().ToString(), Logger).ConfigureAwait(false); } - async Task CleanupOperationAsync(IList deviceClients) + async Task CleanupOperationAsync(List deviceClients, List _) { - foreach (DeviceClient deviceClient in deviceClients) - { - deviceClient.Dispose(); - } + deviceClients.ForEach(deviceClient => deviceClient.Dispose()); await Task.FromResult(false).ConfigureAwait(false); } @@ -1481,13 +1478,9 @@ private async Task Twin_DeviceDesiredPropertyUpdateRecoveryPoolOverAmqp( string proxyAddress = null) { var twinPropertyMap = new Dictionary>(); - var testDevicesWithCallbackHandler = new Dictionary(); - async Task InitOperationAsync(DeviceClient deviceClient, TestDevice testDevice, TestDeviceCallbackHandler _) + async Task InitOperationAsync(DeviceClient deviceClient, TestDevice testDevice, TestDeviceCallbackHandler testDeviceCallbackHandler) { - var testDeviceCallbackHandler = new TestDeviceCallbackHandler(deviceClient, testDevice, Logger); - testDevicesWithCallbackHandler.Add(testDevice.Id, testDeviceCallbackHandler); - var propName = Guid.NewGuid().ToString(); var propValue = Guid.NewGuid().ToString(); twinPropertyMap.Add(testDevice.Id, new List { propName, propValue }); @@ -1497,9 +1490,8 @@ async Task InitOperationAsync(DeviceClient deviceClient, TestDevice testDevice, await testDeviceCallbackHandler.SetTwinPropertyUpdateCallbackHandlerAsync(propName).ConfigureAwait(false); } - async Task TestOperationAsync(DeviceClient deviceClient, TestDevice testDevice, TestDeviceCallbackHandler _) + async Task TestOperationAsync(DeviceClient deviceClient, TestDevice testDevice, TestDeviceCallbackHandler testDeviceCallbackHandler) { - TestDeviceCallbackHandler testDeviceCallbackHandler = testDevicesWithCallbackHandler[testDevice.Id]; using var cts = new CancellationTokenSource(FaultInjection.RecoveryTime); List twinProperties = twinPropertyMap[testDevice.Id]; @@ -1515,21 +1507,12 @@ async Task TestOperationAsync(DeviceClient deviceClient, TestDevice testDevice, await Task.WhenAll(serviceSendTask, twinReceivedTask).ConfigureAwait(false); } - async Task CleanupOperationAsync(IList deviceClients) + async Task CleanupOperationAsync(List deviceClients, List testDeviceCallbackHandlers) { - foreach (DeviceClient deviceClient in deviceClients) - { - deviceClient.Dispose(); - } - - foreach (KeyValuePair entry in testDevicesWithCallbackHandler) - { - TestDeviceCallbackHandler testDeviceCallbackHandler = entry.Value; - testDeviceCallbackHandler?.Dispose(); - } + deviceClients.ForEach(deviceClient => deviceClient.Dispose()); + testDeviceCallbackHandlers.ForEach(testDeviceCallbackHandler => testDeviceCallbackHandler.Dispose()); twinPropertyMap.Clear(); - testDevicesWithCallbackHandler.Clear(); await Task.FromResult(false).ConfigureAwait(false); } diff --git a/e2e/test/iothub/twin/TwinE2ETests.cs b/e2e/test/iothub/twin/TwinE2ETests.cs index bdea63b787..e1d6eb6920 100644 --- a/e2e/test/iothub/twin/TwinE2ETests.cs +++ b/e2e/test/iothub/twin/TwinE2ETests.cs @@ -391,7 +391,7 @@ public async Task Twin_ClientSetsReportedPropertyWithoutDesiredPropertyCallback( { // arrange - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transportType); await Twin_DeviceSetsReportedPropertyAndGetsItBackAsync(deviceClient, testDevice.Id, Guid.NewGuid().ToString(), Logger).ConfigureAwait(false); @@ -417,7 +417,7 @@ public async Task Twin_ClientSetsReportedPropertyWithoutDesiredPropertyCallback( private async Task Twin_DeviceSetsReportedPropertyAndGetsItBackSingleDeviceAsync(Client.TransportType transport) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); await Twin_DeviceSetsReportedPropertyAndGetsItBackAsync(deviceClient, testDevice.Id, Guid.NewGuid().ToString(), Logger).ConfigureAwait(false); @@ -425,7 +425,7 @@ private async Task Twin_DeviceSetsReportedPropertyAndGetsItBackSingleDeviceAsync private async Task Twin_DeviceSetsReportedPropertyArrayAndGetsItBackSingleDeviceAsync(Client.TransportType transport) { - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); await Twin_DeviceSetsReportedPropertyAndGetsItBackAsync(deviceClient, testDevice.Id, s_listOfPropertyValues, Logger).ConfigureAwait(false); @@ -538,7 +538,7 @@ private async Task Twin_ServiceSetsDesiredPropertyAndDeviceUnsubscribes(Client.T Logger.Trace($"{nameof(Twin_ServiceSetsDesiredPropertyAndDeviceReceivesEventAsync)}: name={propName}, value={propValue}"); - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); // Set a callback @@ -573,7 +573,7 @@ private async Task Twin_ServiceSetsDesiredPropertyAndDeviceReceivesEventAsync(Cl Logger.Trace($"{nameof(Twin_ServiceSetsDesiredPropertyAndDeviceReceivesEventAsync)}: name={propName}, value={propValue}"); - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); Task updateReceivedTask = await setTwinPropertyUpdateCallbackAsync(deviceClient, propName, propValue, Logger).ConfigureAwait(false); @@ -601,7 +601,7 @@ private async Task Twin_ServiceSetsDesiredPropertyAndDeviceReceivesItOnNextGetAs var propName = Guid.NewGuid().ToString(); var propValue = Guid.NewGuid().ToString(); - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); @@ -621,7 +621,7 @@ private async Task Twin_DeviceSetsReportedPropertyAndServiceReceivesItAsync(Clie var propName = Guid.NewGuid().ToString(); var propValue = Guid.NewGuid().ToString(); - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); @@ -642,7 +642,7 @@ private async Task Twin_ServiceDoesNotCreateNullPropertyInCollectionAsync(Client var propName2 = Guid.NewGuid().ToString(); var propEmptyValue = "{}"; - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); @@ -693,7 +693,7 @@ private async Task Twin_ClientHandlesRejectionInvalidPropertyNameAsync(Client.Tr var propName1 = "$" + Guid.NewGuid().ToString(); var propName2 = Guid.NewGuid().ToString(); - TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); + using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); diff --git a/e2e/test/iothub/twin/TwinFaultInjectionTests.cs b/e2e/test/iothub/twin/TwinFaultInjectionTests.cs index 688303f08d..1bc1233da9 100644 --- a/e2e/test/iothub/twin/TwinFaultInjectionTests.cs +++ b/e2e/test/iothub/twin/TwinFaultInjectionTests.cs @@ -273,7 +273,7 @@ private async Task Twin_DeviceDesiredPropertyUpdateRecoveryAsync( string proxyAddress = null) { TestDeviceCallbackHandler testDeviceCallbackHandler = null; - var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); using var cts = new CancellationTokenSource(FaultInjection.RecoveryTime); var propName = Guid.NewGuid().ToString(); diff --git a/e2e/test/provisioning/ProvisioningCertificateValidationE2ETest.cs b/e2e/test/provisioning/ProvisioningCertificateValidationE2ETest.cs index ba2c52a6b4..113ea4be75 100644 --- a/e2e/test/provisioning/ProvisioningCertificateValidationE2ETest.cs +++ b/e2e/test/provisioning/ProvisioningCertificateValidationE2ETest.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Security.Authentication; +using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; using Microsoft.Azure.Devices.Provisioning.Client; using Microsoft.Azure.Devices.Provisioning.Client.Transport; @@ -96,9 +97,9 @@ public async Task ProvisioningDeviceClient_RegisterAsyncInvalidServiceCertificat private static async Task TestInvalidServiceCertificate(ProvisioningTransportHandler transport) { - using var security = - new SecurityProviderX509Certificate(Configuration.Provisioning.GetIndividualEnrollmentCertificate()); - ProvisioningDeviceClient provisioningDeviceClient = ProvisioningDeviceClient.Create( + using X509Certificate2 cert = Configuration.Provisioning.GetIndividualEnrollmentCertificate(); + using var security = new SecurityProviderX509Certificate(cert); + var provisioningDeviceClient = ProvisioningDeviceClient.Create( Configuration.Provisioning.GlobalDeviceEndpointInvalidServiceCertificate, "0ne00000001", security, diff --git a/e2e/test/provisioning/ProvisioningE2ETests.cs b/e2e/test/provisioning/ProvisioningE2ETests.cs index 68947e2a49..0ece38ae22 100644 --- a/e2e/test/provisioning/ProvisioningE2ETests.cs +++ b/e2e/test/provisioning/ProvisioningE2ETests.cs @@ -10,6 +10,7 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.Azure.Devices.Client; +using Microsoft.Azure.Devices.E2ETests.Helpers; using Microsoft.Azure.Devices.Provisioning.Client; using Microsoft.Azure.Devices.Provisioning.Client.Transport; using Microsoft.Azure.Devices.Provisioning.Security.Samples; @@ -33,6 +34,8 @@ public class ProvisioningE2ETests : E2EMsTestBase private const string InvalidGlobalAddress = "httpbin.org"; private static readonly string s_globalDeviceEndpoint = Configuration.Provisioning.GlobalDeviceEndpoint; private static readonly string s_proxyServerAddress = Configuration.IoTHub.ProxyServerAddress; + private static readonly X509Certificate2 s_individualEnrollmentCertificate = Configuration.Provisioning.GetIndividualEnrollmentCertificate(); + private static readonly X509Certificate2 s_groupEnrollmentCertificate = Configuration.Provisioning.GetGroupEnrollmentCertificate(); private readonly string _idPrefix = $"e2e-{nameof(ProvisioningE2ETests).ToLower()}-"; private readonly VerboseTestLogger _verboseLog = VerboseTestLogger.GetInstance(); @@ -530,14 +533,23 @@ private async Task ProvisioningDeviceClientValidRegistrationIdRegisterOkAsync( ValidateDeviceRegistrationResult(false, result); +#pragma warning disable CA2000 // Dispose objects before losing scope + // The certificate instance referenced in the DeviceAuthenticationWithX509Certificate instance is common for all tests in this class. It is disposed during class cleanup. Client.IAuthenticationMethod auth = CreateAuthenticationMethodFromSecurityProvider(security, result.DeviceId); +#pragma warning restore CA2000 // Dispose objects before losing scope await ConfirmRegisteredDeviceWorksAsync(result, auth, transportType, false).ConfigureAwait(false); await ConfirmExpectedDeviceCapabilitiesAsync(result, auth, deviceCapabilities).ConfigureAwait(false); if (attestationType != AttestationMechanismType.X509) //x509 enrollments are hardcoded, should never be deleted { - await DeleteCreatedEnrollmentAsync(enrollmentType, CreateProvisioningService(proxyServerAddress), security, groupId).ConfigureAwait(false); + using ProvisioningServiceClient dpsServiceClient = CreateProvisioningService(proxyServerAddress); + await DeleteCreatedEnrollmentAsync(enrollmentType, dpsServiceClient, security, groupId).ConfigureAwait(false); + } + + if (auth is IDisposable disposableAuth) + { + disposableAuth?.Dispose(); } } @@ -550,7 +562,7 @@ private async Task ProvisioningDeviceClientProvisioningFlowCustomAllocationAlloc string expectedDestinationHub, string proxyServerAddress = null) { - ProvisioningServiceClient provisioningServiceClient = CreateProvisioningService(s_proxyServerAddress); + using ProvisioningServiceClient provisioningServiceClient = CreateProvisioningService(s_proxyServerAddress); string groupId = _idPrefix + AttestationTypeToString(attestationType) + "-" + Guid.NewGuid(); var customAllocationDefinition = new CustomAllocationDefinition @@ -856,15 +868,16 @@ public static ProvisioningTransportHandler CreateTransportHandlerFromName(Client /// /// Attempt to create device client instance from provided arguments, ensure that it can open a /// connection, ensure that it can send telemetry, and (optionally) send a reported property update - /// + /// CreateSecurityProviderFromNameAsync(Attesta { _verboseLog.WriteLine($"{nameof(CreateSecurityProviderFromNameAsync)}({attestationType})"); - var provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); + using var provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); switch (attestationType) { case AttestationMechanismType.Tpm: string registrationId = AttestationTypeToString(attestationType) + "-registration-id-" + Guid.NewGuid(); var tpmSim = new SecurityProviderTpmSimulator(registrationId); - string base64Ek = Convert.ToBase64String(tpmSim.GetEndorsementKey()); - var provisioningService = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); - Logger.Trace($"Getting enrollment: RegistrationID = {registrationId}"); - IndividualEnrollment individualEnrollment = new IndividualEnrollment(registrationId, new TpmAttestation(base64Ek)) { AllocationPolicy = allocationPolicy, ReprovisionPolicy = reprovisionPolicy, IotHubs = iothubs, CustomAllocationDefinition = customAllocationDefinition, Capabilities = capabilities }; - IndividualEnrollment enrollment = await provisioningService.CreateOrUpdateIndividualEnrollmentAsync(individualEnrollment).ConfigureAwait(false); + var individualEnrollment = new IndividualEnrollment(registrationId, new TpmAttestation(base64Ek)) { AllocationPolicy = allocationPolicy, ReprovisionPolicy = reprovisionPolicy, IotHubs = iothubs, CustomAllocationDefinition = customAllocationDefinition, Capabilities = capabilities }; + IndividualEnrollment enrollment = await provisioningServiceClient.CreateOrUpdateIndividualEnrollmentAsync(individualEnrollment).ConfigureAwait(false); var attestation = new TpmAttestation(base64Ek); enrollment.Attestation = attestation; Logger.Trace($"Updating enrollment: RegistrationID = {registrationId} EK = '{base64Ek}'"); - await provisioningService.CreateOrUpdateIndividualEnrollmentAsync(enrollment).ConfigureAwait(false); - + await provisioningServiceClient.CreateOrUpdateIndividualEnrollmentAsync(enrollment).ConfigureAwait(false); return tpmSim; case AttestationMechanismType.X509: @@ -922,11 +931,11 @@ private async Task CreateSecurityProviderFromNameAsync(Attesta switch (enrollmentType) { case EnrollmentType.Individual: - certificate = Configuration.Provisioning.GetIndividualEnrollmentCertificate(); + certificate = s_individualEnrollmentCertificate; break; case EnrollmentType.Group: - certificate = Configuration.Provisioning.GetGroupEnrollmentCertificate(); + certificate = s_groupEnrollmentCertificate; collection = Configuration.Provisioning.GetGroupEnrollmentChain(); break; @@ -979,26 +988,26 @@ private Client.IAuthenticationMethod CreateAuthenticationMethodFromSecurityProvi { _verboseLog.WriteLine($"{nameof(CreateAuthenticationMethodFromSecurityProvider)}({deviceId})"); - if (provisioningSecurity is SecurityProviderTpm) + Client.IAuthenticationMethod auth; + if (provisioningSecurity is SecurityProviderTpm tpmSecurity) + { + auth = new DeviceAuthenticationWithTpm(deviceId, tpmSecurity); + } + else if (provisioningSecurity is SecurityProviderX509 x509Security) { - var security = (SecurityProviderTpm)provisioningSecurity; - var auth = new DeviceAuthenticationWithTpm(deviceId, security); - return auth; + X509Certificate2 cert = x509Security.GetAuthenticationCertificate(); + auth = new DeviceAuthenticationWithX509Certificate(deviceId, cert); } - else if (provisioningSecurity is SecurityProviderX509) + else if (provisioningSecurity is SecurityProviderSymmetricKey symmetricKeySecurity) { - var security = (SecurityProviderX509)provisioningSecurity; - X509Certificate2 cert = security.GetAuthenticationCertificate(); - return new DeviceAuthenticationWithX509Certificate(deviceId, cert); + auth = new DeviceAuthenticationWithRegistrySymmetricKey(deviceId, symmetricKeySecurity.GetPrimaryKey()); } - else if (provisioningSecurity is SecurityProviderSymmetricKey) + else { - var security = (SecurityProviderSymmetricKey)provisioningSecurity; - var auth = new DeviceAuthenticationWithRegistrySymmetricKey(deviceId, security.GetPrimaryKey()); - return auth; + throw new NotSupportedException($"Unknown provisioningSecurity type."); } - throw new NotSupportedException($"Unknown provisioningSecurity type."); + return auth; } /// @@ -1081,5 +1090,14 @@ public static bool ImplementsWebProxy(Client.TransportType transportProtocol) throw new NotSupportedException($"Unknown transport: '{transportProtocol}'."); } + + [ClassCleanup] + public static void CleanupCertificates() + { +#if !NET451 + s_individualEnrollmentCertificate?.Dispose(); + s_groupEnrollmentCertificate?.Dispose(); +#endif + } } } diff --git a/e2e/test/provisioning/ProvisioningServiceClientE2ETests.cs b/e2e/test/provisioning/ProvisioningServiceClientE2ETests.cs index 6ec0b7eca2..31c38a8439 100644 --- a/e2e/test/provisioning/ProvisioningServiceClientE2ETests.cs +++ b/e2e/test/provisioning/ProvisioningServiceClientE2ETests.cs @@ -114,7 +114,7 @@ public async Task ProvisioningServiceClient_GetEnrollmentGroupAttestation_Symmet public async Task ProvisioningServiceClient_GetIndividualEnrollmentAttestation(AttestationMechanismType attestationType) { - ProvisioningServiceClient provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); + using var provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); IndividualEnrollment individualEnrollment = await CreateIndividualEnrollment(provisioningServiceClient, attestationType, null, AllocationPolicy.Static, null, null, null); AttestationMechanism attestationMechanism = await provisioningServiceClient.GetIndividualEnrollmentAttestationAsync(individualEnrollment.RegistrationId); @@ -144,7 +144,7 @@ public async Task ProvisioningServiceClient_GetIndividualEnrollmentAttestation(A public async Task ProvisioningServiceClient_GetEnrollmentGroupAttestation(AttestationMechanismType attestationType) { - ProvisioningServiceClient provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); + using ProvisioningServiceClient provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); string groupId = AttestationTypeToString(attestationType) + "-" + Guid.NewGuid(); EnrollmentGroup enrollmentGroup = await CreateEnrollmentGroup(provisioningServiceClient, attestationType, groupId, null, AllocationPolicy.Static, null, null, null); @@ -174,7 +174,7 @@ public async Task ProvisioningServiceClient_GetEnrollmentGroupAttestation(Attest /// If the query succeeded, otherwise this method will throw private async Task ProvisioningServiceClient_IndividualEnrollments_Query_Ok(string proxyServerAddress) { - ProvisioningServiceClient provisioningServiceClient = CreateProvisioningService(proxyServerAddress); + using ProvisioningServiceClient provisioningServiceClient = CreateProvisioningService(proxyServerAddress); var querySpecification = new QuerySpecification("SELECT * FROM enrollments"); using (Query query = provisioningServiceClient.CreateIndividualEnrollmentQuery(querySpecification)) { @@ -268,7 +268,7 @@ public static async Task CreateIndividualEnrollment(Provis using (var tpmSim = new SecurityProviderTpmSimulator(registrationId)) { string base64Ek = Convert.ToBase64String(tpmSim.GetEndorsementKey()); - var provisioningService = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); + using var provisioningService = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); individualEnrollment = new IndividualEnrollment(registrationId, new TpmAttestation(base64Ek)) { Capabilities = capabilities, diff --git a/e2e/test/provisioning/ReprovisioningE2ETests.cs b/e2e/test/provisioning/ReprovisioningE2ETests.cs index 60247d4123..4cee98cf37 100644 --- a/e2e/test/provisioning/ReprovisioningE2ETests.cs +++ b/e2e/test/provisioning/ReprovisioningE2ETests.cs @@ -30,11 +30,11 @@ public class ReprovisioningE2ETests : E2EMsTestBase private const int PassingTimeoutMiliseconds = 10 * 60 * 1000; private static readonly string s_globalDeviceEndpoint = Configuration.Provisioning.GlobalDeviceEndpoint; private static string s_proxyServerAddress = Configuration.IoTHub.ProxyServerAddress; - private readonly string _devicePrefix = $"E2E_{nameof(ProvisioningE2ETests)}_"; + private static readonly X509Certificate2 s_individualEnrollmentCertificate = Configuration.Provisioning.GetIndividualEnrollmentCertificate(); + private static readonly X509Certificate2 s_groupEnrollmentCertificate = Configuration.Provisioning.GetGroupEnrollmentCertificate(); -#pragma warning disable CA1823 + private readonly string _devicePrefix = $"E2E_{nameof(ProvisioningE2ETests)}_"; private readonly VerboseTestLogger _verboseLog = VerboseTestLogger.GetInstance(); -#pragma warning restore CA1823 [LoggedTestMethod] public async Task ProvisioningDeviceClient_ReprovisionedDeviceResetsTwin_MqttWs_SymmetricKey_RegisterOk_Individual() @@ -259,7 +259,7 @@ public async Task ProvisioningDeviceClient_ReprovisioningFlow( ICollection iotHubsToReprovisionTo, string proxyServerAddress = null) { - ProvisioningServiceClient provisioningServiceClient = CreateProvisioningService(s_proxyServerAddress); + using ProvisioningServiceClient provisioningServiceClient = CreateProvisioningService(s_proxyServerAddress); string groupId = _devicePrefix + AttestationTypeToString(attestationType) + "-" + Guid.NewGuid(); bool twinOperationsAllowed = transportProtocol != Client.TransportType.Http1; @@ -276,12 +276,12 @@ public async Task ProvisioningDeviceClient_ReprovisioningFlow( .ConfigureAwait(false); //Check basic provisioning - if (ProvisioningE2ETests.ImplementsWebProxy(transportProtocol) && setCustomProxy) + if (ImplementsWebProxy(transportProtocol) && setCustomProxy) { transport.Proxy = (proxyServerAddress != null) ? new WebProxy(s_proxyServerAddress) : null; } - ProvisioningDeviceClient provClient = ProvisioningDeviceClient.Create( + var provClient = ProvisioningDeviceClient.Create( s_globalDeviceEndpoint, Configuration.Provisioning.IdScope, security, @@ -289,7 +289,12 @@ public async Task ProvisioningDeviceClient_ReprovisioningFlow( using var cts = new CancellationTokenSource(PassingTimeoutMiliseconds); DeviceRegistrationResult result = await provClient.RegisterAsync(cts.Token).ConfigureAwait(false); ValidateDeviceRegistrationResult(result); + +#pragma warning disable CA2000 // Dispose objects before losing scope + // The certificate instance referenced in the DeviceAuthenticationWithX509Certificate instance is common for all tests in this class. It is disposed during class cleanup. Client.IAuthenticationMethod auth = CreateAuthenticationMethodFromSecurityProvider(security, result.DeviceId); +#pragma warning restore CA2000 // Dispose objects before losing scope + await ConfirmRegisteredDeviceWorks(result, auth, transportProtocol, twinOperationsAllowed).ConfigureAwait(false); //Check reprovisioning @@ -300,7 +305,12 @@ public async Task ProvisioningDeviceClient_ReprovisioningFlow( if (attestationType != AttestationMechanismType.X509) //x509 enrollments are hardcoded, should never be deleted { - await ProvisioningE2ETests.DeleteCreatedEnrollmentAsync(enrollmentType, provisioningServiceClient, security, groupId).ConfigureAwait(false); + await DeleteCreatedEnrollmentAsync(enrollmentType, provisioningServiceClient, security, groupId).ConfigureAwait(false); + } + + if (auth is IDisposable disposableAuth) + { + disposableAuth?.Dispose(); } } @@ -315,8 +325,9 @@ private async Task ConfirmRegisteredDeviceWorks(DeviceRegistrationResult result, Logger.Trace("DeviceClient OpenAsync."); await iotClient.OpenAsync().ConfigureAwait(false); Logger.Trace("DeviceClient SendEventAsync."); - await iotClient.SendEventAsync( - new Client.Message(Encoding.UTF8.GetBytes("TestMessage"))).ConfigureAwait(false); + + using var message = new Client.Message(Encoding.UTF8.GetBytes("TestMessage")); + await iotClient.SendEventAsync(message).ConfigureAwait(false); if (sendReportedPropertiesUpdate) { @@ -348,7 +359,7 @@ private async Task CreateSecurityProviderFromName(AttestationM { _verboseLog.WriteLine($"{nameof(CreateSecurityProviderFromName)}({attestationType})"); - var provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); + using var provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); switch (attestationType) { @@ -358,15 +369,16 @@ private async Task CreateSecurityProviderFromName(AttestationM string base64Ek = Convert.ToBase64String(tpmSim.GetEndorsementKey()); - var provisioningService = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); - - Logger.Trace($"Getting enrollment: RegistrationID = {registrationId}"); - IndividualEnrollment individualEnrollment = new IndividualEnrollment(registrationId, new TpmAttestation(base64Ek)) { AllocationPolicy = allocationPolicy, ReprovisionPolicy = reprovisionPolicy, IotHubs = iothubs, CustomAllocationDefinition = customAllocationDefinition, Capabilities = capabilities }; - IndividualEnrollment enrollment = await provisioningService.CreateOrUpdateIndividualEnrollmentAsync(individualEnrollment).ConfigureAwait(false); - var attestation = new TpmAttestation(base64Ek); - enrollment.Attestation = attestation; - Logger.Trace($"Updating enrollment: RegistrationID = {registrationId} EK = '{base64Ek}'"); - await provisioningService.CreateOrUpdateIndividualEnrollmentAsync(enrollment).ConfigureAwait(false); + using (var provisioningService = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString)) + { + Logger.Trace($"Getting enrollment: RegistrationID = {registrationId}"); + var individualEnrollment = new IndividualEnrollment(registrationId, new TpmAttestation(base64Ek)) { AllocationPolicy = allocationPolicy, ReprovisionPolicy = reprovisionPolicy, IotHubs = iothubs, CustomAllocationDefinition = customAllocationDefinition, Capabilities = capabilities }; + IndividualEnrollment enrollment = await provisioningService.CreateOrUpdateIndividualEnrollmentAsync(individualEnrollment).ConfigureAwait(false); + var attestation = new TpmAttestation(base64Ek); + enrollment.Attestation = attestation; + Logger.Trace($"Updating enrollment: RegistrationID = {registrationId} EK = '{base64Ek}'"); + await provisioningService.CreateOrUpdateIndividualEnrollmentAsync(enrollment).ConfigureAwait(false); + } return tpmSim; @@ -377,11 +389,11 @@ private async Task CreateSecurityProviderFromName(AttestationM switch (enrollmentType) { case EnrollmentType.Individual: - certificate = Configuration.Provisioning.GetIndividualEnrollmentCertificate(); + certificate = s_individualEnrollmentCertificate; break; case EnrollmentType.Group: - certificate = Configuration.Provisioning.GetGroupEnrollmentCertificate(); + certificate = s_groupEnrollmentCertificate; collection = Configuration.Provisioning.GetGroupEnrollmentChain(); break; @@ -434,26 +446,26 @@ private Client.IAuthenticationMethod CreateAuthenticationMethodFromSecurityProvi { _verboseLog.WriteLine($"{nameof(CreateAuthenticationMethodFromSecurityProvider)}({deviceId})"); - if (provisioningSecurity is SecurityProviderTpm) + Client.IAuthenticationMethod auth; + if (provisioningSecurity is SecurityProviderTpm tpmSecurity) { - var security = (SecurityProviderTpm)provisioningSecurity; - var auth = new DeviceAuthenticationWithTpm(deviceId, security); - return auth; + auth = new DeviceAuthenticationWithTpm(deviceId, tpmSecurity); } - else if (provisioningSecurity is SecurityProviderX509) + else if (provisioningSecurity is SecurityProviderX509 x509Security) { - var security = (SecurityProviderX509)provisioningSecurity; - X509Certificate2 cert = security.GetAuthenticationCertificate(); - return new DeviceAuthenticationWithX509Certificate(deviceId, cert); + X509Certificate2 cert = x509Security.GetAuthenticationCertificate(); + auth = new DeviceAuthenticationWithX509Certificate(deviceId, cert); } - else if (provisioningSecurity is SecurityProviderSymmetricKey) + else if (provisioningSecurity is SecurityProviderSymmetricKey symmetricKeySecurity) + { + auth = new DeviceAuthenticationWithRegistrySymmetricKey(deviceId, symmetricKeySecurity.GetPrimaryKey()); + } + else { - var security = (SecurityProviderSymmetricKey)provisioningSecurity; - var auth = new DeviceAuthenticationWithRegistrySymmetricKey(deviceId, security.GetPrimaryKey()); - return auth; + throw new NotSupportedException($"Unknown provisioningSecurity type."); } - throw new NotSupportedException($"Unknown provisioningSecurity type."); + return auth; } /// @@ -518,8 +530,9 @@ private async Task ConfirmDeviceWorksAfterReprovisioning(DeviceRegistrationResul Logger.Trace("DeviceClient OpenAsync."); await iotClient.OpenAsync().ConfigureAwait(false); Logger.Trace("DeviceClient SendEventAsync."); - await iotClient.SendEventAsync( - new Client.Message(Encoding.UTF8.GetBytes("TestMessage"))).ConfigureAwait(false); + + using var testMessage = new Client.Message(Encoding.UTF8.GetBytes("TestMessage")); + await iotClient.SendEventAsync(testMessage).ConfigureAwait(false); //twin can be configured to revert back to default twin when provisioned, or to keep twin // from previous hub's records. @@ -549,5 +562,14 @@ await iotClient.SendEventAsync( await iotClient.CloseAsync().ConfigureAwait(false); } } + + [ClassCleanup] + public static void CleanupCertificates() + { +#if !NET451 + s_individualEnrollmentCertificate?.Dispose(); + s_groupEnrollmentCertificate?.Dispose(); +#endif + } } } From 3a5f7364b837b5d1fac5a907410f67087b59d11e Mon Sep 17 00:00:00 2001 From: Abhipsa Misra Date: Wed, 17 Mar 2021 21:04:00 -0700 Subject: [PATCH 4/7] refactor(all): Simplify disposal of IDisposable X509Certificate --- common/src/HttpContentExtensions.cs | 11 ++++ common/src/HttpMessageHelper.cs | 26 ++------- common/src/StreamExtensions.cs | 3 ++ common/src/TaskCompletionSource.cs | 29 ++++------ common/src/service/HttpClientHelper.cs | 7 ++- e2e/test/Helpers/TestDevice.cs | 16 +++--- .../DeviceClientX509AuthenticationE2ETests.cs | 24 +++++---- e2e/test/iothub/DeviceTokenRefreshE2ETests.cs | 4 +- e2e/test/iothub/FileUploadE2ETests.cs | 45 ++++++++-------- .../iothub/FileUploadFaultInjectionTests.cs | 2 +- ...eSecurityCenterForIoTLogAnalyticsClient.cs | 8 +-- ...ssageReceiveFaultInjectionPoolAmqpTests.cs | 2 +- .../messaging/MessageReceiveE2ETests.cs | 14 ++--- e2e/test/iothub/method/MethodE2ETests.cs | 10 ++-- .../iothub/service/BulkOperationsE2ETests.cs | 8 +-- .../IoTHubCertificateValidationE2ETest.cs | 6 +-- e2e/test/iothub/service/PnpServiceTests.cs | 21 ++++---- .../iothub/service/RegistryManagerE2ETests.cs | 53 +++++++++---------- .../RegistryManagerExportDevicesTests.cs | 2 +- .../RegistryManagerImportDevicesTests.cs | 2 +- .../iothub/service/ServiceClientE2ETests.cs | 8 +-- e2e/test/iothub/twin/TwinE2ETests.cs | 28 +++++----- .../iothub/twin/TwinFaultInjectionTests.cs | 4 +- .../E2ETestsSetup/e2eTestsSetup.ps1 | 24 ++++++++- .../E2ETestsSetup/test-resources.bicep | 9 +++- .../E2ETestsSetup/test-resources.json | 11 +++- ...rovisioningCertificateValidationE2ETest.cs | 4 +- e2e/test/provisioning/ProvisioningE2ETests.cs | 16 +++--- .../ProvisioningServiceClientE2ETests.cs | 4 +- .../provisioning/ReprovisioningE2ETests.cs | 12 ++--- ...DeviceAuthenticationWithX509Certificate.cs | 2 + .../src/Transport/Mqtt/MqttIotHubAdapter.cs | 6 +-- .../src/Transport/Mqtt/PublishWorkItem.cs | 11 ++-- .../src/Microsoft.Azure.Devices.csproj | 1 + .../ProvisioningErrorDetailsAmqpTests.cs | 10 ++-- readme.md | 1 + vsts/test-release-nuget.yaml | 2 +- 37 files changed, 244 insertions(+), 202 deletions(-) diff --git a/common/src/HttpContentExtensions.cs b/common/src/HttpContentExtensions.cs index dac9a9e050..e5d1329ed6 100644 --- a/common/src/HttpContentExtensions.cs +++ b/common/src/HttpContentExtensions.cs @@ -8,6 +8,9 @@ namespace Microsoft.Azure.Devices.Shared { + /// + /// Extensions added to simplify the usage of APIs based on the .NET implementation used. + /// internal static class HttpContentExtensions { internal static async Task CopyToStreamAsync(this HttpContent content, Stream stream, CancellationToken cancellationToken) @@ -15,7 +18,9 @@ internal static async Task CopyToStreamAsync(this HttpContent content, Stream st #if NET5_0 await content.CopyToAsync(stream, cancellationToken).ConfigureAwait(false); #else + // .NET implementations < .NET 5.0 do not support CancellationTokens for HttpContent APIs, so we will discard it. _ = cancellationToken; + await content.CopyToAsync(stream).ConfigureAwait(false); #endif } @@ -25,7 +30,9 @@ internal static Task ReadHttpContentAsStream(this HttpContent httpConten #if NET5_0 return httpContent.ReadAsStreamAsync(cancellationToken); #else + // .NET implementations < .NET 5.0 do not support CancellationTokens for HttpContent APIs, so we will discard it. _ = cancellationToken; + return httpContent.ReadAsStreamAsync(); #endif } @@ -35,7 +42,9 @@ internal static Task ReadHttpContentAsByteArrayAsync(this HttpContent co #if NET5_0 return content.ReadAsByteArrayAsync(cancellationToken); #else + // .NET implementations < .NET 5.0 do not support CancellationTokens for HttpContent APIs, so we will discard it. _ = cancellationToken; + return content.ReadAsByteArrayAsync(); #endif } @@ -45,7 +54,9 @@ internal static Task ReadHttpContentAsStringAsync(this HttpContent conte #if NET5_0 return content.ReadAsStringAsync(cancellationToken); #else + // .NET implementations < .NET 5.0 do not support CancellationTokens for HttpContent APIs, so we will discard it. _ = cancellationToken; + return content.ReadAsStringAsync(); #endif } diff --git a/common/src/HttpMessageHelper.cs b/common/src/HttpMessageHelper.cs index 0fe47b0972..eae670e207 100644 --- a/common/src/HttpMessageHelper.cs +++ b/common/src/HttpMessageHelper.cs @@ -3,8 +3,6 @@ using System.Net.Http; using System.Text; -using System.Threading; -using System.Threading.Tasks; using Newtonsoft.Json; #if NET451 @@ -13,14 +11,15 @@ namespace Microsoft.Azure.Devices.Shared { + /// + /// A helper class to simplify operations with Http messages based on the .NET implementation used. + /// internal static class HttpMessageHelper { -#if !NET451 - private const string ApplicationJson = "application/json"; -#endif - #if NET451 private static readonly JsonMediaTypeFormatter s_jsonFormatter = new JsonMediaTypeFormatter(); +#else + private const string ApplicationJson = "application/json"; #endif internal static void SetHttpRequestMessageContent(HttpRequestMessage requestMessage, T entity) @@ -32,20 +31,5 @@ internal static void SetHttpRequestMessageContent(HttpRequestMessage requestM requestMessage.Content = new StringContent(str, Encoding.UTF8, ApplicationJson); #endif } - - internal static async Task ReadHttpResponseMessageContentAsync(HttpResponseMessage message, CancellationToken token) - { -#if NET451 - T entity = await message.Content.ReadAsAsync(token).ConfigureAwait(false); -#elif NET5_0 - string str = await message.Content.ReadAsStringAsync(token).ConfigureAwait(false); - T entity = JsonConvert.DeserializeObject(str); -#else - _ = token; - string str = await message.Content.ReadAsStringAsync().ConfigureAwait(false); - T entity = JsonConvert.DeserializeObject(str); -#endif - return entity; - } } } \ No newline at end of file diff --git a/common/src/StreamExtensions.cs b/common/src/StreamExtensions.cs index 1e73a4bfea..af353bad64 100644 --- a/common/src/StreamExtensions.cs +++ b/common/src/StreamExtensions.cs @@ -7,6 +7,9 @@ namespace Microsoft.Azure.Devices.Shared { + /// + /// Extensions added to simplify the usage of APIs based on the .NET implementation used. + /// internal static class StreamExtensions { internal static async Task WriteToStreamAsync(this Stream stream, byte[] requestBytes, CancellationToken cancellationToken) diff --git a/common/src/TaskCompletionSource.cs b/common/src/TaskCompletionSource.cs index 0091e9c42f..73ca5ca5ce 100644 --- a/common/src/TaskCompletionSource.cs +++ b/common/src/TaskCompletionSource.cs @@ -5,30 +5,23 @@ namespace Microsoft.Azure.Devices.Shared { - internal sealed class TaskCompletionSource : TaskCompletionSource + /// + /// A implementation that returns a when completed. + /// + /// + /// Represents the producer side of a unbound to a delegate, providing access to the consumer side through the property. + /// This is used for .NET implementations lower than .NET 5.0, which lack a native implementation of the non-generic TaskCompletionSource. + /// + internal sealed class TaskCompletionSource : TaskCompletionSource { - public static readonly TaskCompletionSource Void = CreateVoidTcs(); - - public TaskCompletionSource(object state) - : base(state) - { - } - public TaskCompletionSource() { } - public bool TrySetResult() => TrySetResult(0); + public bool TrySetResult() => TrySetResult(true); - public void SetResult() => SetResult(0); + public void SetResult() => SetResult(true); - public override string ToString() => "TaskCompletionSource[status: " + Task.Status.ToString() + "]"; - - static TaskCompletionSource CreateVoidTcs() - { - var tcs = new TaskCompletionSource(); - tcs.TrySetResult(); - return tcs; - } + public override string ToString() => $"TaskCompletionSource[status: {Task.Status}]"; } } \ No newline at end of file diff --git a/common/src/service/HttpClientHelper.cs b/common/src/service/HttpClientHelper.cs index f04d56129e..0f03df2311 100644 --- a/common/src/service/HttpClientHelper.cs +++ b/common/src/service/HttpClientHelper.cs @@ -329,7 +329,12 @@ private static async Task ReadResponseMessageAsync(HttpResponseMessage mes return (T)(object)message; } - T entity = await ReadHttpResponseMessageContentAsync(message, token).ConfigureAwait(false); +#if NET451 + T entity = await message.Content.ReadAsAsync(token).ConfigureAwait(false); +#else + string str = await message.Content.ReadHttpContentAsStringAsync(token).ConfigureAwait(false); + T entity = JsonConvert.DeserializeObject(str); +#endif // Etag in the header is considered authoritative var eTagHolder = entity as IETagHolder; diff --git a/e2e/test/Helpers/TestDevice.cs b/e2e/test/Helpers/TestDevice.cs index a46954ec7e..4c5a8c64e3 100644 --- a/e2e/test/Helpers/TestDevice.cs +++ b/e2e/test/Helpers/TestDevice.cs @@ -66,7 +66,7 @@ private static async Task CreateDeviceAsync(TestDeviceType type, str string deviceName = "E2E_" + prefix + Guid.NewGuid(); // Delete existing devices named this way and create a new one. - using var rm = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using RegistryManager rm = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); _logger.Trace($"{nameof(GetTestDeviceAsync)}: Creating device {deviceName} with type {type}."); Client.IAuthenticationMethod auth = null; @@ -184,20 +184,22 @@ public async Task RemoveDeviceAsync() public void Dispose() { -#if !NET451 - // Ideally we wouldn't be disposing the X509 Certificates here, but rather delegate that to whoever was creating the TestDevice. + // X509Certificate needs to be disposed for implementations !NET451 (NET451 doesn't implement X509Certificates as IDisposable). + + // Normally we wouldn't be disposing the X509 Certificates here, but rather delegate that to whoever was creating the TestDevice. // For the design that our test suite follows, it is ok to dispose the X509 certificate here since it won't be referenced by anyone else // within the scope of the test using this TestDevice. - _authCertificate?.Dispose(); + if (_authCertificate is IDisposable disposableCert) + { + disposableCert?.Dispose(); + } _authCertificate = null; -#endif if (AuthenticationMethod is DeviceAuthenticationWithX509Certificate x509Auth) { x509Auth?.Dispose(); - x509Auth = null; } - + AuthenticationMethod = null; } } } diff --git a/e2e/test/iothub/DeviceClientX509AuthenticationE2ETests.cs b/e2e/test/iothub/DeviceClientX509AuthenticationE2ETests.cs index feb2c44604..12f6f7c148 100644 --- a/e2e/test/iothub/DeviceClientX509AuthenticationE2ETests.cs +++ b/e2e/test/iothub/DeviceClientX509AuthenticationE2ETests.cs @@ -159,7 +159,7 @@ public async Task X509_Cert_Chain_Install_Test_MQTT_TCP() Configuration.IoTHub.X509ChainDeviceName, s_chainCertificateWithPrivateKey, chainCerts); - using var deviceClient = DeviceClient.Create( + using DeviceClient deviceClient = DeviceClient.Create( _hostName, auth, DeviceTransportType.Mqtt_Tcp_Only); @@ -186,7 +186,7 @@ public async Task X509_Cert_Chain_Install_Test_AMQP_TCP() Configuration.IoTHub.X509ChainDeviceName, s_chainCertificateWithPrivateKey, chainCerts); - using var deviceClient = DeviceClient.Create( + using DeviceClient deviceClient = DeviceClient.Create( _hostName, auth, DeviceTransportType.Amqp_Tcp_Only); @@ -253,7 +253,7 @@ private async Task X509InvalidDeviceIdOpenAsyncTest(Client.TransportType transpo { string deviceName = $"DEVICE_NOT_EXIST_{Guid.NewGuid()}"; using var auth = new DeviceAuthenticationWithX509Certificate(deviceName, s_selfSignedCertificateWithPrivateKey); - using var deviceClient = DeviceClient.Create(_hostName, auth, transportType); + using DeviceClient deviceClient = DeviceClient.Create(_hostName, auth, transportType); try { @@ -274,7 +274,7 @@ private async Task X509InvalidDeviceIdOpenAsyncTwiceTest(Client.TransportType tr { string deviceName = $"DEVICE_NOT_EXIST_{Guid.NewGuid()}"; using var auth = new DeviceAuthenticationWithX509Certificate(deviceName, s_selfSignedCertificateWithPrivateKey); - using var deviceClient = DeviceClient.Create(_hostName, auth, transportType); + using DeviceClient deviceClient = DeviceClient.Create(_hostName, auth, transportType); for (int i = 0; i < 2; i++) { @@ -297,14 +297,20 @@ private async Task X509InvalidDeviceIdOpenAsyncTwiceTest(Client.TransportType tr [ClassCleanup] public static void ClassCleanup() { -#if !NET451 - s_selfSignedCertificateWithPrivateKey?.Dispose(); + // X509Certificate needs to be disposed for implementations !NET451 (NET451 doesn't implement X509Certificates as IDisposable). + if (s_selfSignedCertificateWithPrivateKey is IDisposable disposableSelfSignedCertificate) + { + disposableSelfSignedCertificate?.Dispose(); + } s_selfSignedCertificateWithPrivateKey = null; - s_chainCertificateWithPrivateKey?.Dispose(); + // X509Certificate needs to be disposed for implementations !NET451 (NET451 doesn't implement X509Certificates as IDisposable). + if (s_chainCertificateWithPrivateKey is IDisposable disposableChainedCertificate) + { + disposableChainedCertificate?.Dispose(); + + } s_chainCertificateWithPrivateKey = null; -#endif } - } } diff --git a/e2e/test/iothub/DeviceTokenRefreshE2ETests.cs b/e2e/test/iothub/DeviceTokenRefreshE2ETests.cs index 88428e8697..149dce35e0 100644 --- a/e2e/test/iothub/DeviceTokenRefreshE2ETests.cs +++ b/e2e/test/iothub/DeviceTokenRefreshE2ETests.cs @@ -96,7 +96,7 @@ public async Task DeviceClient_TokenConnectionDoubleRelease_Ok() var auth = new DeviceAuthenticationWithToken(deviceId, builder.ToSignature()); - using var deviceClient = DeviceClient.Create(iotHub, auth, Client.TransportType.Amqp_Tcp_Only); + using DeviceClient deviceClient = DeviceClient.Create(iotHub, auth, Client.TransportType.Amqp_Tcp_Only); Logger.Trace($"{deviceId}: Created {nameof(DeviceClient)} ID={TestLogger.IdOf(deviceClient)}"); Logger.Trace($"{deviceId}: DeviceClient OpenAsync."); @@ -126,7 +126,7 @@ private async Task DeviceClient_TokenIsRefreshed_Internal(Client.TransportType t transport, Logger); - using var deviceClient = DeviceClient.Create(testDevice.IoTHubHostName, refresher, transport); + using DeviceClient deviceClient = DeviceClient.Create(testDevice.IoTHubHostName, refresher, transport); Logger.Trace($"Created {nameof(DeviceClient)} ID={TestLogger.IdOf(deviceClient)}"); if (transport == Client.TransportType.Mqtt) diff --git a/e2e/test/iothub/FileUploadE2ETests.cs b/e2e/test/iothub/FileUploadE2ETests.cs index 7cbd4d6352..238781c406 100644 --- a/e2e/test/iothub/FileUploadE2ETests.cs +++ b/e2e/test/iothub/FileUploadE2ETests.cs @@ -20,9 +20,10 @@ namespace Microsoft.Azure.Devices.E2ETests [TestCategory("IoTHub")] public class FileUploadE2ETests : E2EMsTestBase { - private readonly string _devicePrefix = $"{nameof(FileUploadE2ETests)}_"; private const int FileSizeSmall = 10 * 1024; private const int FileSizeBig = 5120 * 1024; + private readonly string _devicePrefix = $"{nameof(FileUploadE2ETests)}_"; + private static readonly X509Certificate2 s_selfSignedCertificate = Configuration.IoTHub.GetCertificateWithPrivateKey(); [LoggedTestMethod] [TestCategory("LongRunning")] @@ -126,7 +127,7 @@ private async Task UploadFileGranularAsync(Stream source, string filename, Http1 DeviceAuthenticationWithX509Certificate x509Auth = null; if (useX509auth) { - cert = Configuration.IoTHub.GetCertificateWithPrivateKey(); + cert = s_selfSignedCertificate; x509Auth = new DeviceAuthenticationWithX509Certificate(testDevice.Id, cert); // The X509 certificate being used for device authentication needs to be set into FileUploadTransportSettings as well, @@ -159,13 +160,9 @@ private async Task UploadFileGranularAsync(Stream source, string filename, Http1 }; await deviceClient.CompleteFileUploadAsync(notification).ConfigureAwait(false); - }; + } x509Auth?.Dispose(); - -#if !NET451 - cert?.Dispose(); -#endif } [Obsolete] @@ -181,9 +178,9 @@ private async Task UploadFileAsync(Client.TransportType transport, string filena DeviceAuthenticationWithX509Certificate x509Auth = null; if (useX509auth) { - cert = Configuration.IoTHub.GetCertificateWithPrivateKey(); - + cert = s_selfSignedCertificate; x509Auth = new DeviceAuthenticationWithX509Certificate(testDevice.Id, cert); + deviceClient = DeviceClient.Create(testDevice.IoTHubHostName, x509Auth, transport); } else @@ -193,20 +190,15 @@ private async Task UploadFileAsync(Client.TransportType transport, string filena using (deviceClient) { - using (var fileStreamSource = new FileStream(filename, FileMode.Open, FileAccess.Read)) - { - // UploadToBlobAsync is obsolete, added [Obsolete] attribute to suppress CS0618 message - await deviceClient.UploadToBlobAsync(filename, fileStreamSource).ConfigureAwait(false); - } + using var fileStreamSource = new FileStream(filename, FileMode.Open, FileAccess.Read); + + // UploadToBlobAsync is obsolete, added [Obsolete] attribute to suppress CS0618 message + await deviceClient.UploadToBlobAsync(filename, fileStreamSource).ConfigureAwait(false); await deviceClient.CloseAsync().ConfigureAwait(false); } x509Auth?.Dispose(); - -#if !NET451 - cert?.Dispose(); -#endif } private async Task GetSasUriAsync(Client.TransportType transport, string blobName, bool useX509auth = false) @@ -221,8 +213,9 @@ private async Task GetSasUriAsync(Client.TransportType transport, string blobNam DeviceAuthenticationWithX509Certificate x509Auth = null; if (useX509auth) { - cert = Configuration.IoTHub.GetCertificateWithPrivateKey(); + cert = s_selfSignedCertificate; x509Auth = new DeviceAuthenticationWithX509Certificate(testDevice.Id, cert); + deviceClient = DeviceClient.Create(testDevice.IoTHubHostName, x509Auth, transport); } else @@ -237,10 +230,6 @@ private async Task GetSasUriAsync(Client.TransportType transport, string blobNam } x509Auth?.Dispose(); - -#if !NET451 - cert?.Dispose(); -#endif } private static async Task GetTestFileNameAsync(int fileSize) @@ -260,5 +249,15 @@ private static async Task GetTestFileNameAsync(int fileSize) return filePath; } + + [ClassCleanup] + public static void CleanupCertificates() + { + // X509Certificate needs to be disposed for implementations !NET451 (NET451 doesn't implement X509Certificates as IDisposable). + if (s_selfSignedCertificate is IDisposable disposableCertificate) + { + disposableCertificate?.Dispose(); + } + } } } diff --git a/e2e/test/iothub/FileUploadFaultInjectionTests.cs b/e2e/test/iothub/FileUploadFaultInjectionTests.cs index 35a20bfaf0..8e261f4312 100644 --- a/e2e/test/iothub/FileUploadFaultInjectionTests.cs +++ b/e2e/test/iothub/FileUploadFaultInjectionTests.cs @@ -87,7 +87,7 @@ private async Task UploadFileDisconnectTransport( { using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); - using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); + using DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); TimeSpan operationTimeout = retryDurationInMilliSec == TimeSpan.Zero ? FaultInjection.RecoveryTime : retryDurationInMilliSec; deviceClient.OperationTimeoutInMilliseconds = (uint)operationTimeout.TotalMilliseconds; diff --git a/e2e/test/iothub/messaging/AzureSecurityCenterForIoTLogAnalyticsClient.cs b/e2e/test/iothub/messaging/AzureSecurityCenterForIoTLogAnalyticsClient.cs index 241367f71f..b3e50baac8 100644 --- a/e2e/test/iothub/messaging/AzureSecurityCenterForIoTLogAnalyticsClient.cs +++ b/e2e/test/iothub/messaging/AzureSecurityCenterForIoTLogAnalyticsClient.cs @@ -140,9 +140,11 @@ protected virtual void Dispose(bool disposing) { _client?.Dispose(); -#if !NET451 - _authCertificate?.Dispose(); -#endif + // X509Certificate needs to be disposed for implementations !NET451 (NET451 doesn't implement X509Certificates as IDisposable). + if (_authCertificate is IDisposable disposableCert) + { + disposableCert?.Dispose(); + } } } } diff --git a/e2e/test/iothub/messaging/FaultInjectionPoolAmqpTests.MessageReceiveFaultInjectionPoolAmqpTests.cs b/e2e/test/iothub/messaging/FaultInjectionPoolAmqpTests.MessageReceiveFaultInjectionPoolAmqpTests.cs index cbf307526a..ae029a5dab 100644 --- a/e2e/test/iothub/messaging/FaultInjectionPoolAmqpTests.MessageReceiveFaultInjectionPoolAmqpTests.cs +++ b/e2e/test/iothub/messaging/FaultInjectionPoolAmqpTests.MessageReceiveFaultInjectionPoolAmqpTests.cs @@ -953,7 +953,7 @@ private async Task ReceiveMessageUsingCallbackRecoveryPoolOverAmqpAsync( string proxyAddress = null) { // Initialize the service client - var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); async Task InitOperationAsync(DeviceClient deviceClient, TestDevice testDevice, TestDeviceCallbackHandler testDeviceCallbackHandler) { diff --git a/e2e/test/iothub/messaging/MessageReceiveE2ETests.cs b/e2e/test/iothub/messaging/MessageReceiveE2ETests.cs index 482b7598ee..52d8892ecd 100644 --- a/e2e/test/iothub/messaging/MessageReceiveE2ETests.cs +++ b/e2e/test/iothub/messaging/MessageReceiveE2ETests.cs @@ -600,7 +600,7 @@ private async Task ReceiveSingleMessageAsync(TestDeviceType type, Client.Transpo { using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false); using DeviceClient deviceClient = testDevice.CreateDeviceClient(transport); - using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); await deviceClient.OpenAsync().ConfigureAwait(false); await serviceClient.OpenAsync().ConfigureAwait(false); @@ -631,7 +631,7 @@ private async Task ReceiveSingleMessageWithCancellationTokenAsync(TestDeviceType { using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false); using DeviceClient deviceClient = testDevice.CreateDeviceClient(transport); - using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); await deviceClient.OpenAsync().ConfigureAwait(false); await serviceClient.OpenAsync().ConfigureAwait(false); @@ -697,7 +697,7 @@ private async Task ReceiveSingleMessageUsingCallbackAsync(TestDeviceType type, C using DeviceClient deviceClient = testDevice.CreateDeviceClient(transport); using var testDeviceCallbackHandler = new TestDeviceCallbackHandler(deviceClient, testDevice, Logger); - using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); (Message msg, string payload, string p1Value) = ComposeC2dTestMessage(Logger); using (msg) @@ -724,7 +724,7 @@ private async Task ReceiveMessageUsingCallbackAndUnsubscribeAsync(TestDeviceType using DeviceClient deviceClient = testDevice.CreateDeviceClient(transport); using var testDeviceCallbackHandler = new TestDeviceCallbackHandler(deviceClient, testDevice, Logger); - using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); // For Mqtt - we will need to subscribe to the Mqtt receive telemetry topic // before the device can begin receiving c2d messages. @@ -801,7 +801,7 @@ private async Task ReceiveMessageUsingCallbackUpdateHandlerAsync(TestDeviceType using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, s_devicePrefix, type).ConfigureAwait(false); using DeviceClient deviceClient = testDevice.CreateDeviceClient(transport); - using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); // Set the first C2D message handler. await deviceClient.SetReceiveMessageHandlerAsync( @@ -860,7 +860,7 @@ private async Task ReceiveMessagesSentBeforeSubscriptionAsync(TestDeviceType typ DeviceClient deviceClient = testDevice.CreateDeviceClient(transport); var testDeviceCallbackHandler = new TestDeviceCallbackHandler(deviceClient, testDevice, Logger); - using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); (Message msg, string payload, string p1Value) = ComposeC2dTestMessage(Logger); @@ -903,7 +903,7 @@ private async Task DoNotReceiveMessagesSentBeforeSubscriptionAsync(TestDeviceTyp DeviceClient deviceClient = testDevice.CreateDeviceClient(settings); var testDeviceCallbackHandler = new TestDeviceCallbackHandler(deviceClient, testDevice, Logger); - using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); (Message msg, string payload, string p1Value) = ComposeC2dTestMessage(Logger); diff --git a/e2e/test/iothub/method/MethodE2ETests.cs b/e2e/test/iothub/method/MethodE2ETests.cs index 46418418a7..d0247400d4 100644 --- a/e2e/test/iothub/method/MethodE2ETests.cs +++ b/e2e/test/iothub/method/MethodE2ETests.cs @@ -151,7 +151,7 @@ public async Task Method_ServiceSendsMethodThroughProxyWithCustomTimeout() public async Task Method_ServiceInvokeDeviceMethodWithUnknownDeviceThrows() { // setup - using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); var methodInvocation = new CloudToDeviceMethod("SetTelemetryInterval"); methodInvocation.SetPayloadJson("10"); @@ -225,7 +225,7 @@ public async Task Method_ServiceInvokeDeviceMethodWithUnknownModuleThrows() { // setup using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, "ModuleNotFoundTest").ConfigureAwait(false); - using var serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); var methodInvocation = new CloudToDeviceMethod("SetTelemetryInterval"); methodInvocation.SetPayloadJson("10"); @@ -504,7 +504,7 @@ await moduleClient.SetMethodDefaultHandlerAsync( private async Task SendMethodAndUnsubscribeAsync(Client.TransportType transport, Func> subscribeAndUnsubscribeMethod, TimeSpan responseTimeout = default, ServiceClientTransportSettings serviceClientTransportSettings = default) { using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); - using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); + using DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); await subscribeAndUnsubscribeMethod(deviceClient, MethodName, Logger).ConfigureAwait(false); @@ -516,7 +516,7 @@ private async Task SendMethodAndUnsubscribeAsync(Client.TransportType transport, private async Task SendMethodAndRespondAsync(Client.TransportType transport, Func> setDeviceReceiveMethod, TimeSpan responseTimeout = default, ServiceClientTransportSettings serviceClientTransportSettings = default) { using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); - using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); + using DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); Task methodReceivedTask = await setDeviceReceiveMethod(deviceClient, MethodName, Logger).ConfigureAwait(false); @@ -532,7 +532,7 @@ await Task private async Task SendMethodAndRespondAsync(Client.TransportType transport, Func> setDeviceReceiveMethod, TimeSpan responseTimeout = default, ServiceClientTransportSettings serviceClientTransportSettings = default) { TestModule testModule = await TestModule.GetTestModuleAsync(_devicePrefix, _modulePrefix, Logger).ConfigureAwait(false); - using var moduleClient = ModuleClient.CreateFromConnectionString(testModule.ConnectionString, transport); + using ModuleClient moduleClient = ModuleClient.CreateFromConnectionString(testModule.ConnectionString, transport); Task methodReceivedTask = await setDeviceReceiveMethod(moduleClient, MethodName, Logger).ConfigureAwait(false); diff --git a/e2e/test/iothub/service/BulkOperationsE2ETests.cs b/e2e/test/iothub/service/BulkOperationsE2ETests.cs index 451c992b56..dc3d518229 100644 --- a/e2e/test/iothub/service/BulkOperationsE2ETests.cs +++ b/e2e/test/iothub/service/BulkOperationsE2ETests.cs @@ -25,7 +25,7 @@ public async Task BulkOperations_UpdateTwins2Device_Ok() var tagValue = Guid.NewGuid().ToString(); using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); Twin twin = await registryManager.GetTwinAsync(testDevice.Id).ConfigureAwait(false); @@ -52,7 +52,7 @@ public async Task BulkOperations_UpdateTwins2DevicePatch_Ok() var tagValue = Guid.NewGuid().ToString(); using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); Twin twin = new Twin(); twin.DeviceId = testDevice.Id; @@ -79,7 +79,7 @@ public async Task BulkOperations_UpdateTwins2Module_Ok() var tagValue = Guid.NewGuid().ToString(); TestModule testModule = await TestModule.GetTestModuleAsync(DevicePrefix, ModulePrefix, Logger).ConfigureAwait(false); - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); Twin twin = await registryManager.GetTwinAsync(testModule.DeviceId, testModule.Id).ConfigureAwait(false); @@ -108,7 +108,7 @@ public async Task BulkOperations_UpdateTwins2ModulePatch_Ok() TestModule testModule = await TestModule.GetTestModuleAsync(DevicePrefix, ModulePrefix, Logger).ConfigureAwait(false); - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); var twin = new Twin(); twin.DeviceId = testModule.DeviceId; twin.ModuleId = testModule.Id; diff --git a/e2e/test/iothub/service/IoTHubCertificateValidationE2ETest.cs b/e2e/test/iothub/service/IoTHubCertificateValidationE2ETest.cs index b0e8f1c40b..dbe4ad2fa2 100644 --- a/e2e/test/iothub/service/IoTHubCertificateValidationE2ETest.cs +++ b/e2e/test/iothub/service/IoTHubCertificateValidationE2ETest.cs @@ -18,7 +18,7 @@ public class IoTHubCertificateValidationE2ETest : E2EMsTestBase [LoggedTestMethod] public async Task RegistryManager_QueryDevicesInvalidServiceCertificateHttp_Fails() { - using var rm = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionStringInvalidServiceCertificate); + using RegistryManager rm = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionStringInvalidServiceCertificate); IQuery query = rm.CreateQuery("select * from devices"); IotHubCommunicationException exception = await Assert.ThrowsExceptionAsync( () => query.GetNextAsTwinAsync()).ConfigureAwait(false); @@ -50,7 +50,7 @@ public async Task ServiceClient_SendMessageToDeviceInvalidServiceCertificateAmqp private static async Task TestServiceClientInvalidServiceCertificate(TransportType transport) { - using var service = ServiceClient.CreateFromConnectionString( + using ServiceClient service = ServiceClient.CreateFromConnectionString( Configuration.IoTHub.ConnectionStringInvalidServiceCertificate, transport); using var testMessage = new Message(); @@ -60,7 +60,7 @@ private static async Task TestServiceClientInvalidServiceCertificate(TransportTy [LoggedTestMethod] public async Task JobClient_ScheduleTwinUpdateInvalidServiceCertificateHttp_Fails() { - using var jobClient = JobClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionStringInvalidServiceCertificate); + using JobClient jobClient = JobClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionStringInvalidServiceCertificate); var exception = await Assert.ThrowsExceptionAsync( () => jobClient.ScheduleTwinUpdateAsync( "testDevice", diff --git a/e2e/test/iothub/service/PnpServiceTests.cs b/e2e/test/iothub/service/PnpServiceTests.cs index a8f942ed19..c2026ed853 100644 --- a/e2e/test/iothub/service/PnpServiceTests.cs +++ b/e2e/test/iothub/service/PnpServiceTests.cs @@ -38,13 +38,13 @@ public async Task DeviceTwin_Contains_ModelId() { ModelId = TestModelId, }; - using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, Client.TransportType.Mqtt_Tcp_Only, options); + using DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, Client.TransportType.Mqtt_Tcp_Only, options); await deviceClient.OpenAsync().ConfigureAwait(false); // Act // Get device twin. - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); Twin twin = await registryManager.GetTwinAsync(testDevice.Device.Id).ConfigureAwait(false); // Assert @@ -69,13 +69,13 @@ public async Task DeviceTwin_Contains_ModelId_X509() string hostName = HostNameHelper.GetHostName(Configuration.IoTHub.ConnectionString); X509Certificate2 authCertificate = Configuration.IoTHub.GetCertificateWithPrivateKey(); using var auth = new DeviceAuthenticationWithX509Certificate(testDevice.Id, authCertificate); - using var deviceClient = DeviceClient.Create(hostName, auth, Client.TransportType.Mqtt_Tcp_Only, options); + using DeviceClient deviceClient = DeviceClient.Create(hostName, auth, Client.TransportType.Mqtt_Tcp_Only, options); await deviceClient.OpenAsync().ConfigureAwait(false); // Act // Get device twin. - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); Twin twin = await registryManager.GetTwinAsync(testDevice.Device.Id).ConfigureAwait(false); // Assert @@ -84,9 +84,12 @@ public async Task DeviceTwin_Contains_ModelId_X509() // Cleanup await registryManager.RemoveDeviceAsync(testDevice.Id).ConfigureAwait(false); -#if !NET451 - authCertificate?.Dispose(); -#endif + // X509Certificate needs to be disposed for implementations !NET451 (NET451 doesn't implement X509Certificates as IDisposable). + if (authCertificate is IDisposable disposableCert) + { + disposableCert?.Dispose(); + } + authCertificate = null; } [TestMethod] @@ -101,13 +104,13 @@ public async Task ModuleTwin_Contains_ModelId() { ModelId = TestModelId, }; - using var moduleClient = ModuleClient.CreateFromConnectionString(testModule.ConnectionString, Client.TransportType.Mqtt_Tcp_Only, options); + using ModuleClient moduleClient = ModuleClient.CreateFromConnectionString(testModule.ConnectionString, Client.TransportType.Mqtt_Tcp_Only, options); await moduleClient.OpenAsync().ConfigureAwait(false); // Act // Get module twin. - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); Twin twin = await registryManager.GetTwinAsync(testModule.DeviceId, testModule.Id).ConfigureAwait(false); // Assert diff --git a/e2e/test/iothub/service/RegistryManagerE2ETests.cs b/e2e/test/iothub/service/RegistryManagerE2ETests.cs index 2499a1aeef..d7a7f00289 100644 --- a/e2e/test/iothub/service/RegistryManagerE2ETests.cs +++ b/e2e/test/iothub/service/RegistryManagerE2ETests.cs @@ -7,7 +7,6 @@ using System.Net; using System.Threading.Tasks; using FluentAssertions; -using Microsoft.Azure.Devices.Common.Exceptions; using Microsoft.Azure.Devices.E2ETests.Helpers; using Microsoft.Azure.Devices.Shared; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -28,7 +27,7 @@ public class RegistryManagerE2ETests : E2EMsTestBase public async Task RegistryManager_BadProxy_ThrowsException() { // arrange - using var registryManager = RegistryManager.CreateFromConnectionString( + using RegistryManager registryManager = RegistryManager.CreateFromConnectionString( Configuration.IoTHub.ConnectionString, new HttpTransportSettings { @@ -42,7 +41,7 @@ public async Task RegistryManager_BadProxy_ThrowsException() [LoggedTestMethod] public async Task RegistryManager_AddAndRemoveDeviceWithScope() { - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); string deviceId = _devicePrefix + Guid.NewGuid(); @@ -67,41 +66,39 @@ public async Task RegistryManager_AddDeviceWithTwinWithDeviceCapabilities() { string deviceId = _devicePrefix + Guid.NewGuid(); - using (var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString)) + using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + var twin = new Twin { - var twin = new Twin - { - Tags = new TwinCollection(@"{ companyId: 1234 }"), - }; + Tags = new TwinCollection(@"{ companyId: 1234 }"), + }; - var iotEdgeDevice = new Device(deviceId) - { - Capabilities = new DeviceCapabilities { IotEdge = true } - }; + var iotEdgeDevice = new Device(deviceId) + { + Capabilities = new DeviceCapabilities { IotEdge = true } + }; - await registryManager.AddDeviceWithTwinAsync(iotEdgeDevice, twin).ConfigureAwait(false); + await registryManager.AddDeviceWithTwinAsync(iotEdgeDevice, twin).ConfigureAwait(false); - Device actual = await registryManager.GetDeviceAsync(deviceId).ConfigureAwait(false); - await registryManager.RemoveDeviceAsync(deviceId).ConfigureAwait(false); + Device actual = await registryManager.GetDeviceAsync(deviceId).ConfigureAwait(false); + await registryManager.RemoveDeviceAsync(deviceId).ConfigureAwait(false); - Assert.IsTrue(actual.Capabilities.IotEdge); - } + Assert.IsTrue(actual.Capabilities.IotEdge); } [LoggedTestMethod] public async Task RegistryManager_BulkLifecycle() { int bulkCount = 50; - List devices = new List(); + var devices = new List(); for (int i = 0; i < bulkCount; i++) { devices.Add(new Device(_devicePrefix + Guid.NewGuid())); } - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); // Test that you can create devices in bulk - var bulkAddResult = await registryManager.AddDevices2Async(devices).ConfigureAwait(false); + BulkRegistryOperationResult bulkAddResult = await registryManager.AddDevices2Async(devices).ConfigureAwait(false); Assert.IsTrue(bulkAddResult.IsSuccessful); foreach (Device device in devices) @@ -110,7 +107,7 @@ public async Task RegistryManager_BulkLifecycle() Assert.IsNotNull(await registryManager.GetDeviceAsync(device.Id).ConfigureAwait(false)); } - List twins = new List(); + var twins = new List(); string expectedProperty = "someNewProperty"; string expectedPropertyValue = "someNewPropertyValue"; foreach (Device device in devices) @@ -131,7 +128,7 @@ public async Task RegistryManager_BulkLifecycle() } // Test that you can delete device identities in bulk - var bulkDeleteResult = await registryManager.RemoveDevices2Async(devices, true, default).ConfigureAwait(false); + BulkRegistryOperationResult bulkDeleteResult = await registryManager.RemoveDevices2Async(devices, true, default).ConfigureAwait(false); Assert.IsTrue(bulkDeleteResult.IsSuccessful); @@ -151,18 +148,16 @@ public async Task RegistryManager_AddDeviceWithProxy() Proxy = new WebProxy(Configuration.IoTHub.ProxyServerAddress) }; - using (var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString, transportSettings)) - { - var device = new Device(deviceId); - await registryManager.AddDeviceAsync(device).ConfigureAwait(false); - } + using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString, transportSettings); + var device = new Device(deviceId); + await registryManager.AddDeviceAsync(device).ConfigureAwait(false); } [LoggedTestMethod] public async Task RegistryManager_Query_Works() { // arrange - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); string deviceId = $"{_devicePrefix}{Guid.NewGuid()}"; try @@ -182,7 +177,7 @@ public async Task RegistryManager_Query_Works() twins = await query.GetNextAsTwinAsync().ConfigureAwait(false); - if (twins.Count() > 0) + if (twins.Any()) { break; } diff --git a/e2e/test/iothub/service/RegistryManagerExportDevicesTests.cs b/e2e/test/iothub/service/RegistryManagerExportDevicesTests.cs index be2887ea4c..c30fd3c716 100644 --- a/e2e/test/iothub/service/RegistryManagerExportDevicesTests.cs +++ b/e2e/test/iothub/service/RegistryManagerExportDevicesTests.cs @@ -54,7 +54,7 @@ public async Task RegistryManager_ExportDevices(StorageAuthenticationType storag StorageContainer storageContainer = null; string deviceId = $"{nameof(RegistryManager_ExportDevices)}-{StorageContainer.GetRandomSuffix(4)}"; - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); Logger.Trace($"Using deviceId {deviceId}"); diff --git a/e2e/test/iothub/service/RegistryManagerImportDevicesTests.cs b/e2e/test/iothub/service/RegistryManagerImportDevicesTests.cs index 8fc44d2b65..98ab463950 100644 --- a/e2e/test/iothub/service/RegistryManagerImportDevicesTests.cs +++ b/e2e/test/iothub/service/RegistryManagerImportDevicesTests.cs @@ -48,7 +48,7 @@ public async Task RegistryManager_ImportDevices(StorageAuthenticationType storag StorageContainer storageContainer = null; string deviceId = $"{nameof(RegistryManager_ImportDevices)}-{StorageContainer.GetRandomSuffix(4)}"; - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); Logger.Trace($"Using deviceId {deviceId}"); diff --git a/e2e/test/iothub/service/ServiceClientE2ETests.cs b/e2e/test/iothub/service/ServiceClientE2ETests.cs index d336f3199c..efdc065733 100644 --- a/e2e/test/iothub/service/ServiceClientE2ETests.cs +++ b/e2e/test/iothub/service/ServiceClientE2ETests.cs @@ -73,7 +73,7 @@ public async Task ServiceClient_SendsMessage(TransportType transportType) { // arrange using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); - using var sender = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString, transportType); + using ServiceClient sender = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString, transportType); string messageId = Guid.NewGuid().ToString(); // act and expect no exception @@ -92,7 +92,7 @@ public async Task MessageIdDefaultNotSet_SendEventDoesNotSetMessageId() { // arrange using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, DevicePrefix).ConfigureAwait(false); - using var sender = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using ServiceClient sender = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); string messageId = Guid.NewGuid().ToString(); // act @@ -121,7 +121,7 @@ public async Task MessageIdDefaultSetToNull_SendEventDoesNotSetMessageId() { SdkAssignsMessageId = Shared.SdkAssignsMessageId.Never, }; - using var sender = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString, options); + using ServiceClient sender = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString, options); string messageId = Guid.NewGuid().ToString(); // act @@ -150,7 +150,7 @@ public async Task MessageIdDefaultSetToGuid_SendEventSetMessageIdIfNotSet() { SdkAssignsMessageId = Shared.SdkAssignsMessageId.WhenUnset, }; - using var sender = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString, options); + using ServiceClient sender = ServiceClient.CreateFromConnectionString(Configuration.IoTHub.ConnectionString, options); string messageId = Guid.NewGuid().ToString(); // act diff --git a/e2e/test/iothub/twin/TwinE2ETests.cs b/e2e/test/iothub/twin/TwinE2ETests.cs index e1d6eb6920..3856362d09 100644 --- a/e2e/test/iothub/twin/TwinE2ETests.cs +++ b/e2e/test/iothub/twin/TwinE2ETests.cs @@ -392,7 +392,7 @@ public async Task Twin_ClientSetsReportedPropertyWithoutDesiredPropertyCallback( // arrange using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); - using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transportType); + using DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transportType); await Twin_DeviceSetsReportedPropertyAndGetsItBackAsync(deviceClient, testDevice.Id, Guid.NewGuid().ToString(), Logger).ConfigureAwait(false); @@ -418,7 +418,7 @@ public async Task Twin_ClientSetsReportedPropertyWithoutDesiredPropertyCallback( private async Task Twin_DeviceSetsReportedPropertyAndGetsItBackSingleDeviceAsync(Client.TransportType transport) { using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); - using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); + using DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); await Twin_DeviceSetsReportedPropertyAndGetsItBackAsync(deviceClient, testDevice.Id, Guid.NewGuid().ToString(), Logger).ConfigureAwait(false); } @@ -426,7 +426,7 @@ private async Task Twin_DeviceSetsReportedPropertyAndGetsItBackSingleDeviceAsync private async Task Twin_DeviceSetsReportedPropertyArrayAndGetsItBackSingleDeviceAsync(Client.TransportType transport) { using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); - using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); + using DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); await Twin_DeviceSetsReportedPropertyAndGetsItBackAsync(deviceClient, testDevice.Id, s_listOfPropertyValues, Logger).ConfigureAwait(false); } @@ -523,7 +523,7 @@ await deviceClient public static async Task RegistryManagerUpdateDesiredPropertyAsync(string deviceId, string propName, object propValue) { - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); var twinPatch = new Twin(); twinPatch.Properties.Desired[propName] = propValue; @@ -539,7 +539,7 @@ private async Task Twin_ServiceSetsDesiredPropertyAndDeviceUnsubscribes(Client.T Logger.Trace($"{nameof(Twin_ServiceSetsDesiredPropertyAndDeviceReceivesEventAsync)}: name={propName}, value={propValue}"); using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); - using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); + using DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); // Set a callback await deviceClient. @@ -574,7 +574,7 @@ private async Task Twin_ServiceSetsDesiredPropertyAndDeviceReceivesEventAsync(Cl Logger.Trace($"{nameof(Twin_ServiceSetsDesiredPropertyAndDeviceReceivesEventAsync)}: name={propName}, value={propValue}"); using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); - using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); + using DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); Task updateReceivedTask = await setTwinPropertyUpdateCallbackAsync(deviceClient, propName, propValue, Logger).ConfigureAwait(false); @@ -602,8 +602,8 @@ private async Task Twin_ServiceSetsDesiredPropertyAndDeviceReceivesItOnNextGetAs var propValue = Guid.NewGuid().ToString(); using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); - using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); + using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); var twinPatch = new Twin(); twinPatch.Properties.Desired[propName] = propValue; @@ -622,8 +622,8 @@ private async Task Twin_DeviceSetsReportedPropertyAndServiceReceivesItAsync(Clie var propValue = Guid.NewGuid().ToString(); using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); - using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); + using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); var patch = new TwinCollection(); patch[propName] = propValue; @@ -643,8 +643,8 @@ private async Task Twin_ServiceDoesNotCreateNullPropertyInCollectionAsync(Client var propEmptyValue = "{}"; using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); - using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); + using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); await deviceClient .UpdateReportedPropertiesAsync( @@ -694,8 +694,8 @@ private async Task Twin_ClientHandlesRejectionInvalidPropertyNameAsync(Client.Tr var propName2 = Guid.NewGuid().ToString(); using TestDevice testDevice = await TestDevice.GetTestDeviceAsync(Logger, _devicePrefix).ConfigureAwait(false); - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); - using var deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); + using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(testDevice.ConnectionString, transport); var exceptionThrown = false; try diff --git a/e2e/test/iothub/twin/TwinFaultInjectionTests.cs b/e2e/test/iothub/twin/TwinFaultInjectionTests.cs index 1bc1233da9..4cd53e1a79 100644 --- a/e2e/test/iothub/twin/TwinFaultInjectionTests.cs +++ b/e2e/test/iothub/twin/TwinFaultInjectionTests.cs @@ -256,7 +256,7 @@ await FaultInjection private async Task RegistryManagerUpdateDesiredPropertyAsync(string deviceId, string propName, string propValue) { - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); var twinPatch = new Twin(); twinPatch.Properties.Desired[propName] = propValue; @@ -273,7 +273,7 @@ private async Task Twin_DeviceDesiredPropertyUpdateRecoveryAsync( string proxyAddress = null) { TestDeviceCallbackHandler testDeviceCallbackHandler = null; - using var registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); + using RegistryManager registryManager = RegistryManager.CreateFromConnectionString(Configuration.IoTHub.ConnectionString); using var cts = new CancellationTokenSource(FaultInjection.RecoveryTime); var propName = Guid.NewGuid().ToString(); diff --git a/e2e/test/prerequisites/E2ETestsSetup/e2eTestsSetup.ps1 b/e2e/test/prerequisites/E2ETestsSetup/e2eTestsSetup.ps1 index 3f94fe89fa..54606109c6 100644 --- a/e2e/test/prerequisites/E2ETestsSetup/e2eTestsSetup.ps1 +++ b/e2e/test/prerequisites/E2ETestsSetup/e2eTestsSetup.ps1 @@ -15,7 +15,12 @@ param( # Set this to true on the first execution to get everything installed in powershell. Does not need to be run everytime. [Parameter()] - [bool] $InstallDependencies = $true + [bool] $InstallDependencies = $true, + + # Set this to true if you are generating resources for the DevOps test pipeline. + # This will create resources capable of handling the test pipeline traffic, which is greater than what you would generally require for local testing. + [Parameter()] + [bool] $GenerateResourcesForDevOpsPipeline = $false ) $startTime = (Get-Date) @@ -113,8 +118,21 @@ $Region = $Region.Replace(' ', '') $logAnalyticsAppRegnName = "$ResourceGroup-LogAnalyticsAadApp" $uploadCertificateName = "group1-certificate" $hubUploadCertificateName = "rootCA" +$iothubUnitsToBeCreated = 1 + + +# OpenSSL has dropped support for SHA1 signed certificates in ubuntu 20.04, so our test resources will use SHA256 signed certificates instead. $certificateHashAlgorithm = "SHA256" +################################################################################################# +# Make any special modifications required to generate resources for the DevOps test pipeline +################################################################################################# + +if ($GenerateResourcesForDevOpsPipeline) +{ + $iothubUnitsToBeCreated = 3 +} + ################################################################################################# # Get Function App contents to pass to deployment @@ -388,7 +406,9 @@ az deployment group create ` StorageAccountName=$storageAccountName ` KeyVaultName=$keyVaultName ` DpsCustomAllocatorRunCsxContent=$dpsCustomAllocatorRunCsxContent ` - DpsCustomAllocatorProjContent=$dpsCustomAllocatorProjContent + DpsCustomAllocatorProjContent=$dpsCustomAllocatorProjContent ` + HubUnitsCount=$iothubUnitsToBeCreated + if ($LastExitCode -ne 0) { diff --git a/e2e/test/prerequisites/E2ETestsSetup/test-resources.bicep b/e2e/test/prerequisites/E2ETestsSetup/test-resources.bicep index 69f2757b59..eda7ee93da 100644 --- a/e2e/test/prerequisites/E2ETestsSetup/test-resources.bicep +++ b/e2e/test/prerequisites/E2ETestsSetup/test-resources.bicep @@ -44,6 +44,13 @@ param HubName string { } } +param HubUnitsCount int { + default: 1 + metadata: { + description: 'The number of IoT Hub units to be deployed.' + } +} + param ConsumerGroupName string { default: 'e2e-tests' metadata: { @@ -260,7 +267,7 @@ resource iotHub 'Microsoft.Devices/IotHubs@2020-01-01' = { sku: { name: 'S1' tier: 'Standard' - capacity: 3 + capacity: HubUnitsCount } dependsOn: [ container diff --git a/e2e/test/prerequisites/E2ETestsSetup/test-resources.json b/e2e/test/prerequisites/E2ETestsSetup/test-resources.json index 45eaac495f..56483d482a 100644 --- a/e2e/test/prerequisites/E2ETestsSetup/test-resources.json +++ b/e2e/test/prerequisites/E2ETestsSetup/test-resources.json @@ -50,6 +50,13 @@ }, "defaultValue": "[format('{0}-hub', resourceGroup().name)]" }, + "HubUnitsCount": { + "type": "int", + "metadata": { + "description": "The number of IoT Hub units to be deployed." + }, + "defaultValue": 1 + }, "ConsumerGroupName": { "type": "string", "metadata": { @@ -281,7 +288,7 @@ "sku": { "name": "S1", "tier": "Standard", - "capacity": 3 + "capacity": "[parameters('HubUnitsCount')]" }, "dependsOn": [ "[resourceId('Microsoft.Storage/storageAccounts/blobServices/containers', split(format('{0}/{1}', format('{0}/{1}', parameters('StorageAccountName'), parameters('BlobServiceName')), parameters('ContainerName')), '/')[0], split(format('{0}/{1}', format('{0}/{1}', parameters('StorageAccountName'), parameters('BlobServiceName')), parameters('ContainerName')), '/')[1], split(format('{0}/{1}', format('{0}/{1}', parameters('StorageAccountName'), parameters('BlobServiceName')), parameters('ContainerName')), '/')[2])]", @@ -503,7 +510,7 @@ "_generator": { "name": "bicep", "version": "0.3.1.62928", - "templateHash": "5703369743693135956" + "templateHash": "7317588320467693544" } } } \ No newline at end of file diff --git a/e2e/test/provisioning/ProvisioningCertificateValidationE2ETest.cs b/e2e/test/provisioning/ProvisioningCertificateValidationE2ETest.cs index 113ea4be75..1f5086d978 100644 --- a/e2e/test/provisioning/ProvisioningCertificateValidationE2ETest.cs +++ b/e2e/test/provisioning/ProvisioningCertificateValidationE2ETest.cs @@ -19,7 +19,7 @@ public class ProvisioningCertificateValidationE2ETest : E2EMsTestBase [LoggedTestMethod] public async Task ProvisioningServiceClient_QueryInvalidServiceCertificateHttp_Fails() { - using var provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString( + using ProvisioningServiceClient provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString( Configuration.Provisioning.ConnectionStringInvalidServiceCertificate); Query q = provisioningServiceClient.CreateEnrollmentGroupQuery( new QuerySpecification("SELECT * FROM enrollmentGroups")); @@ -99,7 +99,7 @@ private static async Task TestInvalidServiceCertificate(ProvisioningTransportHan { using X509Certificate2 cert = Configuration.Provisioning.GetIndividualEnrollmentCertificate(); using var security = new SecurityProviderX509Certificate(cert); - var provisioningDeviceClient = ProvisioningDeviceClient.Create( + ProvisioningDeviceClient provisioningDeviceClient = ProvisioningDeviceClient.Create( Configuration.Provisioning.GlobalDeviceEndpointInvalidServiceCertificate, "0ne00000001", security, diff --git a/e2e/test/provisioning/ProvisioningE2ETests.cs b/e2e/test/provisioning/ProvisioningE2ETests.cs index 0ece38ae22..1b55ccad36 100644 --- a/e2e/test/provisioning/ProvisioningE2ETests.cs +++ b/e2e/test/provisioning/ProvisioningE2ETests.cs @@ -375,7 +375,7 @@ private async Task ProvisioningDeviceClientCustomAllocationPolicyAsync( bool setCustomProxy, string customServerProxy = null) { - var closeHostName = IotHubConnectionStringBuilder.Create(Configuration.IoTHub.ConnectionString).HostName; + string closeHostName = IotHubConnectionStringBuilder.Create(Configuration.IoTHub.ConnectionString).HostName; ICollection iotHubsToProvisionTo = new List() { closeHostName, Configuration.Provisioning.FarAwayIotHubHostName }; string expectedDestinationHub = ""; @@ -501,7 +501,7 @@ private async Task ProvisioningDeviceClientValidRegistrationIdRegisterOkAsync( transport.Proxy = (proxyServerAddress != null) ? new WebProxy(s_proxyServerAddress) : null; } - var provClient = ProvisioningDeviceClient.Create( + ProvisioningDeviceClient provClient = ProvisioningDeviceClient.Create( s_globalDeviceEndpoint, Configuration.Provisioning.IdScope, security, @@ -588,7 +588,7 @@ private async Task ProvisioningDeviceClientProvisioningFlowCustomAllocationAlloc transport.Proxy = (proxyServerAddress != null) ? new WebProxy(s_proxyServerAddress) : null; } - var provClient = ProvisioningDeviceClient.Create( + ProvisioningDeviceClient provClient = ProvisioningDeviceClient.Create( s_globalDeviceEndpoint, Configuration.Provisioning.IdScope, security, @@ -655,7 +655,7 @@ public async Task ProvisioningDeviceClient_InvalidRegistrationId_TpmRegister_Fai { using ProvisioningTransportHandler transport = CreateTransportHandlerFromName(transportProtocol); using SecurityProvider security = new SecurityProviderTpmSimulator("invalidregistrationid"); - var provClient = ProvisioningDeviceClient.Create( + ProvisioningDeviceClient provClient = ProvisioningDeviceClient.Create( s_globalDeviceEndpoint, Configuration.Provisioning.IdScope, security, @@ -895,9 +895,9 @@ private async Task ConfirmExpectedDeviceCapabilitiesAsync(DeviceRegistrationResu if (capabilities != null && capabilities.IotEdge) { //If device is edge device, it should be able to connect to iot hub as its edgehub module identity - var connectionStringBuilder = Client.IotHubConnectionStringBuilder.Create(result.AssignedHub, auth); + Client.IotHubConnectionStringBuilder connectionStringBuilder = Client.IotHubConnectionStringBuilder.Create(result.AssignedHub, auth); string edgehubConnectionString = connectionStringBuilder.ToString() + ";ModuleId=$edgeHub"; - using var moduleClient = ModuleClient.CreateFromConnectionString(edgehubConnectionString); + using ModuleClient moduleClient = ModuleClient.CreateFromConnectionString(edgehubConnectionString); await moduleClient.OpenAsync().ConfigureAwait(false); } } @@ -906,7 +906,7 @@ private async Task CreateSecurityProviderFromNameAsync(Attesta { _verboseLog.WriteLine($"{nameof(CreateSecurityProviderFromNameAsync)}({attestationType})"); - using var provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); + using ProvisioningServiceClient provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); switch (attestationType) { @@ -1094,10 +1094,8 @@ public static bool ImplementsWebProxy(Client.TransportType transportProtocol) [ClassCleanup] public static void CleanupCertificates() { -#if !NET451 s_individualEnrollmentCertificate?.Dispose(); s_groupEnrollmentCertificate?.Dispose(); -#endif } } } diff --git a/e2e/test/provisioning/ProvisioningServiceClientE2ETests.cs b/e2e/test/provisioning/ProvisioningServiceClientE2ETests.cs index 31c38a8439..484339064e 100644 --- a/e2e/test/provisioning/ProvisioningServiceClientE2ETests.cs +++ b/e2e/test/provisioning/ProvisioningServiceClientE2ETests.cs @@ -114,7 +114,7 @@ public async Task ProvisioningServiceClient_GetEnrollmentGroupAttestation_Symmet public async Task ProvisioningServiceClient_GetIndividualEnrollmentAttestation(AttestationMechanismType attestationType) { - using var provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); + using ProvisioningServiceClient provisioningServiceClient = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); IndividualEnrollment individualEnrollment = await CreateIndividualEnrollment(provisioningServiceClient, attestationType, null, AllocationPolicy.Static, null, null, null); AttestationMechanism attestationMechanism = await provisioningServiceClient.GetIndividualEnrollmentAttestationAsync(individualEnrollment.RegistrationId); @@ -268,7 +268,7 @@ public static async Task CreateIndividualEnrollment(Provis using (var tpmSim = new SecurityProviderTpmSimulator(registrationId)) { string base64Ek = Convert.ToBase64String(tpmSim.GetEndorsementKey()); - using var provisioningService = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); + using ProvisioningServiceClient provisioningService = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString); individualEnrollment = new IndividualEnrollment(registrationId, new TpmAttestation(base64Ek)) { Capabilities = capabilities, diff --git a/e2e/test/provisioning/ReprovisioningE2ETests.cs b/e2e/test/provisioning/ReprovisioningE2ETests.cs index 4cee98cf37..11802a6bb0 100644 --- a/e2e/test/provisioning/ReprovisioningE2ETests.cs +++ b/e2e/test/provisioning/ReprovisioningE2ETests.cs @@ -211,7 +211,7 @@ public async Task ProvisioningDeviceClient_ReprovisioningBlockingWorks_MqttWs_Sy /// private async Task ProvisioningDeviceClient_ReprovisioningFlow_ResetTwin(Client.TransportType transportProtocol, AttestationMechanismType attestationType, EnrollmentType enrollmentType, bool setCustomProxy, string customServerProxy = null) { - var connectionString = IotHubConnectionStringBuilder.Create(Configuration.IoTHub.ConnectionString); + IotHubConnectionStringBuilder connectionString = IotHubConnectionStringBuilder.Create(Configuration.IoTHub.ConnectionString); ICollection iotHubsToStartAt = new List() { Configuration.Provisioning.FarAwayIotHubHostName }; ICollection iotHubsToReprovisionTo = new List() { connectionString.HostName }; await ProvisioningDeviceClient_ReprovisioningFlow(transportProtocol, attestationType, enrollmentType, setCustomProxy, new ReprovisionPolicy { MigrateDeviceData = false, UpdateHubAssignment = true }, AllocationPolicy.Hashed, null, iotHubsToStartAt, iotHubsToReprovisionTo, customServerProxy).ConfigureAwait(false); @@ -223,7 +223,7 @@ private async Task ProvisioningDeviceClient_ReprovisioningFlow_ResetTwin(Client. /// private async Task ProvisioningDeviceClient_ReprovisioningFlow_KeepTwin(Client.TransportType transportProtocol, AttestationMechanismType attestationType, EnrollmentType enrollmentType, bool setCustomProxy, string customServerProxy = null) { - var connectionString = IotHubConnectionStringBuilder.Create(Configuration.IoTHub.ConnectionString); + IotHubConnectionStringBuilder connectionString = IotHubConnectionStringBuilder.Create(Configuration.IoTHub.ConnectionString); ICollection iotHubsToStartAt = new List() { Configuration.Provisioning.FarAwayIotHubHostName }; ICollection iotHubsToReprovisionTo = new List() { connectionString.HostName }; await ProvisioningDeviceClient_ReprovisioningFlow(transportProtocol, attestationType, enrollmentType, setCustomProxy, new ReprovisionPolicy { MigrateDeviceData = true, UpdateHubAssignment = true }, AllocationPolicy.Hashed, null, iotHubsToStartAt, iotHubsToReprovisionTo, customServerProxy).ConfigureAwait(false); @@ -234,7 +234,7 @@ private async Task ProvisioningDeviceClient_ReprovisioningFlow_KeepTwin(Client.T /// private async Task ProvisioningDeviceClient_ReprovisioningFlow_DoNotReprovision(Client.TransportType transportProtocol, AttestationMechanismType attestationType, EnrollmentType enrollmentType, bool setCustomProxy, string customServerProxy = null) { - var connectionString = IotHubConnectionStringBuilder.Create(Configuration.IoTHub.ConnectionString); + IotHubConnectionStringBuilder connectionString = IotHubConnectionStringBuilder.Create(Configuration.IoTHub.ConnectionString); ICollection iotHubsToStartAt = new List() { Configuration.Provisioning.FarAwayIotHubHostName }; ICollection iotHubsToReprovisionTo = new List() { connectionString.HostName }; await ProvisioningDeviceClient_ReprovisioningFlow(transportProtocol, attestationType, enrollmentType, setCustomProxy, new ReprovisionPolicy { MigrateDeviceData = false, UpdateHubAssignment = false }, AllocationPolicy.Hashed, null, iotHubsToStartAt, iotHubsToReprovisionTo, customServerProxy).ConfigureAwait(false); @@ -281,7 +281,7 @@ public async Task ProvisioningDeviceClient_ReprovisioningFlow( transport.Proxy = (proxyServerAddress != null) ? new WebProxy(s_proxyServerAddress) : null; } - var provClient = ProvisioningDeviceClient.Create( + ProvisioningDeviceClient provClient = ProvisioningDeviceClient.Create( s_globalDeviceEndpoint, Configuration.Provisioning.IdScope, security, @@ -369,7 +369,7 @@ private async Task CreateSecurityProviderFromName(AttestationM string base64Ek = Convert.ToBase64String(tpmSim.GetEndorsementKey()); - using (var provisioningService = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString)) + using (ProvisioningServiceClient provisioningService = ProvisioningServiceClient.CreateFromConnectionString(Configuration.Provisioning.ConnectionString)) { Logger.Trace($"Getting enrollment: RegistrationID = {registrationId}"); var individualEnrollment = new IndividualEnrollment(registrationId, new TpmAttestation(base64Ek)) { AllocationPolicy = allocationPolicy, ReprovisionPolicy = reprovisionPolicy, IotHubs = iothubs, CustomAllocationDefinition = customAllocationDefinition, Capabilities = capabilities }; @@ -566,10 +566,8 @@ private async Task ConfirmDeviceWorksAfterReprovisioning(DeviceRegistrationResul [ClassCleanup] public static void CleanupCertificates() { -#if !NET451 s_individualEnrollmentCertificate?.Dispose(); s_groupEnrollmentCertificate?.Dispose(); -#endif } } } diff --git a/iothub/device/src/DeviceAuthenticationWithX509Certificate.cs b/iothub/device/src/DeviceAuthenticationWithX509Certificate.cs index 6b3074e0d4..7d38987b4d 100644 --- a/iothub/device/src/DeviceAuthenticationWithX509Certificate.cs +++ b/iothub/device/src/DeviceAuthenticationWithX509Certificate.cs @@ -83,6 +83,8 @@ private void SetDeviceId(string deviceId) /// /// The managed resource should be disposed by the user. + /// This library intentionally does not dispose it here since the user might want to + /// reuse the certificate instance elsewhere for some other operation. /// public void Dispose() { diff --git a/iothub/device/src/Transport/Mqtt/MqttIotHubAdapter.cs b/iothub/device/src/Transport/Mqtt/MqttIotHubAdapter.cs index 9782a26f25..41facd0dcd 100644 --- a/iothub/device/src/Transport/Mqtt/MqttIotHubAdapter.cs +++ b/iothub/device/src/Transport/Mqtt/MqttIotHubAdapter.cs @@ -799,7 +799,7 @@ private Task ProcessAckAsync(IChannelHandlerContext context, PublishWorkItem pub if (Logging.IsEnabled) Logging.Enter(this, context.Name, publish?.Value, nameof(ProcessAckAsync)); - publish.Completion.Complete(); + publish.Completion.SetResult(); if (Logging.IsEnabled) Logging.Exit(this, context.Name, publish?.Value, nameof(ProcessAckAsync)); @@ -863,7 +863,7 @@ private async Task SendMessageAsync(IChannelHandlerContext context, Message mess } PublishPacket packet = await ComposePublishPacketAsync(context, message, qos, topicName).ConfigureAwait(true); - var publishCompletion = new DotNetty.Common.Concurrency.TaskCompletionSource(); + var publishCompletion = new TaskCompletionSource(); var workItem = new PublishWorkItem { Completion = publishCompletion, @@ -941,7 +941,7 @@ private async Task SendMessageToServerAsync(IChannelHandlerContext context, Publ await WriteMessageAsync(context, publish.Value, s_shutdownOnWriteErrorHandler).ConfigureAwait(true); if (publish.Value.QualityOfService == QualityOfService.AtMostOnce) { - publish.Completion.TryComplete(); + publish.Completion.TrySetResult(); } } catch (Exception ex) diff --git a/iothub/device/src/Transport/Mqtt/PublishWorkItem.cs b/iothub/device/src/Transport/Mqtt/PublishWorkItem.cs index 38290ff525..7415d78182 100644 --- a/iothub/device/src/Transport/Mqtt/PublishWorkItem.cs +++ b/iothub/device/src/Transport/Mqtt/PublishWorkItem.cs @@ -3,7 +3,12 @@ using System; using DotNetty.Codecs.Mqtt.Packets; -using DotNetty.Common.Concurrency; + +#if NET5_0 +using TaskCompletionSource = System.Threading.Tasks.TaskCompletionSource; +#else +using TaskCompletionSource = Microsoft.Azure.Devices.Shared.TaskCompletionSource; +#endif namespace Microsoft.Azure.Devices.Client.Transport.Mqtt { @@ -15,12 +20,12 @@ internal sealed class PublishWorkItem : ReferenceCountedObjectContainer + diff --git a/provisioning/transport/amqp/tests/ProvisioningErrorDetailsAmqpTests.cs b/provisioning/transport/amqp/tests/ProvisioningErrorDetailsAmqpTests.cs index 355029977a..ba0a6e39fc 100644 --- a/provisioning/transport/amqp/tests/ProvisioningErrorDetailsAmqpTests.cs +++ b/provisioning/transport/amqp/tests/ProvisioningErrorDetailsAmqpTests.cs @@ -114,7 +114,7 @@ public void GetRetryFromRejectedReturnsNullIfNoError() public void GetRetryAfterFromApplicationPropertiesSuccess() { int expectedRetryAfter = 42; - using var amqpResponse = AmqpMessage.Create(); + using AmqpMessage amqpResponse = AmqpMessage.Create(); amqpResponse.ApplicationProperties = new ApplicationProperties(); amqpResponse.ApplicationProperties.Map.Add(new MapKey("Retry-After"), expectedRetryAfter); TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromApplicationProperties(amqpResponse, s_defaultInterval); @@ -126,7 +126,7 @@ public void GetRetryAfterFromApplicationPropertiesSuccess() public void GetRetryAfterFromApplicationPropertiesReturnsDefaultIfRetryAfterValueIsNegative() { int expectedRetryAfter = -1; - using var amqpResponse = AmqpMessage.Create(); + using AmqpMessage amqpResponse = AmqpMessage.Create(); amqpResponse.ApplicationProperties = new ApplicationProperties(); amqpResponse.ApplicationProperties.Map.Add(new MapKey("Retry-After"), expectedRetryAfter); TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromApplicationProperties(amqpResponse, s_defaultInterval); @@ -138,7 +138,7 @@ public void GetRetryAfterFromApplicationPropertiesReturnsDefaultIfRetryAfterValu public void GetRetryAfterFromApplicationPropertiesReturnsDefaultIfRetryAfterValueIsZero() { int expectedRetryAfter = 0; - using var amqpResponse = AmqpMessage.Create(); + using AmqpMessage amqpResponse = AmqpMessage.Create(); amqpResponse.ApplicationProperties = new ApplicationProperties(); amqpResponse.ApplicationProperties.Map.Add(new MapKey("Retry-After"), expectedRetryAfter); TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromApplicationProperties(amqpResponse, s_defaultInterval); @@ -149,7 +149,7 @@ public void GetRetryAfterFromApplicationPropertiesReturnsDefaultIfRetryAfterValu [TestMethod] public void GetRetryAfterFromApplicationPropertiesReturnsNullIfNoRetryAfterApplicationProperty() { - using var amqpResponse = AmqpMessage.Create(); + using AmqpMessage amqpResponse = AmqpMessage.Create(); amqpResponse.ApplicationProperties = new ApplicationProperties(); TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromApplicationProperties(amqpResponse, s_defaultInterval); Assert.IsNull(actual); @@ -158,7 +158,7 @@ public void GetRetryAfterFromApplicationPropertiesReturnsNullIfNoRetryAfterAppli [TestMethod] public void GetRetryAfterFromApplicationPropertiesReturnsNullIfNoApplicationProperties() { - using var amqpResponse = AmqpMessage.Create(); + using AmqpMessage amqpResponse = AmqpMessage.Create(); TimeSpan? actual = ProvisioningErrorDetailsAmqp.GetRetryAfterFromApplicationProperties(amqpResponse, s_defaultInterval); Assert.IsNull(actual); } diff --git a/readme.md b/readme.md index b4b0f7ea56..6a72be7caf 100644 --- a/readme.md +++ b/readme.md @@ -68,6 +68,7 @@ If you would like to build or change the SDK source code, please follow the [dev The IoT Hub device SDK for .NET can be used with a broad range of OS platforms and devices, mainly modern versions Windows and Linux. The NuGet packages provide support for the following .NET flavors: +- .NET 5.0 - .NET Standard 2.1 - .NET Standard 2.0 - .NET Framework 4.7.2 (IoT Hub SDKs only) diff --git a/vsts/test-release-nuget.yaml b/vsts/test-release-nuget.yaml index 6f79fa8280..334775e669 100644 --- a/vsts/test-release-nuget.yaml +++ b/vsts/test-release-nuget.yaml @@ -160,7 +160,7 @@ jobs: OverWrite: true - script: | - call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Enterprise\\Common7\\Tools\\VsDevCmd.bat" + call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\Common7\\Tools\\VsDevCmd.bat" sn -Vr *,31bf3856ad364e35 displayName: 'Disable strong name validation' From f4fb4168cfdbaff985c3a0fa1637d51904df1b34 Mon Sep 17 00:00:00 2001 From: Abhipsa Misra Date: Mon, 22 Mar 2021 16:10:36 -0700 Subject: [PATCH 5/7] fix(vsts): Update the location for log analytics workspace resource --- .../prerequisites/E2ETestsSetup/test-resources.bicep | 11 +++++++++-- .../prerequisites/E2ETestsSetup/test-resources.json | 11 +++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/e2e/test/prerequisites/E2ETestsSetup/test-resources.bicep b/e2e/test/prerequisites/E2ETestsSetup/test-resources.bicep index eda7ee93da..1220a744d9 100644 --- a/e2e/test/prerequisites/E2ETestsSetup/test-resources.bicep +++ b/e2e/test/prerequisites/E2ETestsSetup/test-resources.bicep @@ -1,7 +1,7 @@ param ApplicationInsightsName string { default: '${resourceGroup().name}-ai' metadata: { - description: 'The name of application insights.' + description: 'The name of application insights.' } } @@ -92,6 +92,13 @@ param OperationalInsightsName string { } } +param OperationInsightsLocation string { + default: 'eastus' + metadata: { + description: 'The location for Microsoft.OperationalInsights/workspaces.' + } +} + param SecuritySolutionName string { default: '${resourceGroup().name}-ss' metadata: { @@ -314,7 +321,7 @@ resource provisioningService 'Microsoft.Devices/provisioningServices@2017-11-15' resource operationalInsightsWorkspaces 'Microsoft.OperationalInsights/workspaces@2017-03-15-preview' = { name: OperationalInsightsName - location: resourceGroup().location + location: OperationInsightsLocation properties: { } } diff --git a/e2e/test/prerequisites/E2ETestsSetup/test-resources.json b/e2e/test/prerequisites/E2ETestsSetup/test-resources.json index 56483d482a..cc437d8d45 100644 --- a/e2e/test/prerequisites/E2ETestsSetup/test-resources.json +++ b/e2e/test/prerequisites/E2ETestsSetup/test-resources.json @@ -98,6 +98,13 @@ }, "defaultValue": "[format('{0}-oi', resourceGroup().name)]" }, + "OperationInsightsLocation": { + "type": "string", + "metadata": { + "description": "The location for Microsoft.OperationalInsights/workspaces." + }, + "defaultValue": "eastus" + }, "SecuritySolutionName": { "type": "string", "metadata": { @@ -345,7 +352,7 @@ "type": "Microsoft.OperationalInsights/workspaces", "apiVersion": "2017-03-15-preview", "name": "[parameters('OperationalInsightsName')]", - "location": "[resourceGroup().location]", + "location": "[parameters('OperationInsightsLocation')]", "properties": {} }, { @@ -510,7 +517,7 @@ "_generator": { "name": "bicep", "version": "0.3.1.62928", - "templateHash": "7317588320467693544" + "templateHash": "9993199802379393341" } } } \ No newline at end of file From 8bc97021e89c099d9807a4d7089a04438ee41c3d Mon Sep 17 00:00:00 2001 From: Abhipsa Misra Date: Mon, 19 Apr 2021 12:06:49 -0700 Subject: [PATCH 6/7] refactor(e2e-tests): Dispose IDisposable types --- e2e/test/iothub/DeviceTokenRefreshE2ETests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/e2e/test/iothub/DeviceTokenRefreshE2ETests.cs b/e2e/test/iothub/DeviceTokenRefreshE2ETests.cs index 1e6cb47ed8..2cbc998a37 100644 --- a/e2e/test/iothub/DeviceTokenRefreshE2ETests.cs +++ b/e2e/test/iothub/DeviceTokenRefreshE2ETests.cs @@ -110,7 +110,7 @@ public async Task DeviceClient_TokenConnectionDoubleRelease_Ok() await deviceClient.CloseAsync().ConfigureAwait(false); } - // The easiest way to test that sas tokens expire with custom expiration time via the CreateFromConnectionString flow is + // The easiest way to test that sas tokens expire with custom expiration time via the CreateFromConnectionString flow is // by initializing a DeviceClient instance over Mqtt (since sas token expiration over Mqtt is accompanied by a disconnect). [LoggedTestMethod] [TestCategory("LongRunning")] @@ -146,7 +146,7 @@ public async Task DeviceClient_CreateFromConnectionString_TokenIsRefreshed_Mqtt( }); deviceClient.OperationTimeoutInMilliseconds = (uint)operationTimeoutInMilliseconds; - var message = new Client.Message(Encoding.UTF8.GetBytes("Hello")); + using var message = new Client.Message(Encoding.UTF8.GetBytes("Hello")); Logger.Trace($"[{testDevice.Id}]: SendEventAsync (1)"); await deviceClient.SendEventAsync(message).ConfigureAwait(false); From 4964f3a96b90b02d2b12251e8a3f0a69b0c1b3d9 Mon Sep 17 00:00:00 2001 From: Abhipsa Misra Date: Mon, 17 May 2021 19:24:23 -0700 Subject: [PATCH 7/7] fix(e2e-tests): Dispose IDisposable types created - hmac --- e2e/test/config/Configuration.IoTHub.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/test/config/Configuration.IoTHub.cs b/e2e/test/config/Configuration.IoTHub.cs index 88565486c4..0d5e4ffbec 100644 --- a/e2e/test/config/Configuration.IoTHub.cs +++ b/e2e/test/config/Configuration.IoTHub.cs @@ -119,7 +119,7 @@ private static string GenerateSasToken(string resourceUri, string sharedAccessKe string stringToSign = WebUtility.UrlEncode(resourceUri) + "\n" + expiry; - HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(sharedAccessKey)); + using var hmac = new HMACSHA256(Convert.FromBase64String(sharedAccessKey)); string signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign))); // SharedAccessSignature sr=ENCODED(dh://myiothub.azure-devices.net/a/b/c?myvalue1=a)&sig=&se=[&skn=]