diff --git a/README.md b/README.md index 3be6947..7633f08 100644 --- a/README.md +++ b/README.md @@ -577,6 +577,10 @@ The following parameters will be the same for each process in the set: ### Unreleased +* Fixes issue where MsiPackage Integration tests fail to make an HTTPS + connection if Strong Crypto for .NET is not enabled. Fixes + [Issue #142](https://github.com/PowerShell/PSDscResources/issues/142) + ### 2.11.0.0 * Fix Custom DSC Resource Kit PSSA Rule Failures diff --git a/Tests/Integration/MSFT_MsiPackage.EndToEnd.Tests.ps1 b/Tests/Integration/MSFT_MsiPackage.EndToEnd.Tests.ps1 index 5abf0a9..78bc29e 100644 --- a/Tests/Integration/MSFT_MsiPackage.EndToEnd.Tests.ps1 +++ b/Tests/Integration/MSFT_MsiPackage.EndToEnd.Tests.ps1 @@ -13,631 +13,647 @@ if ($PSVersionTable.PSVersion -lt [Version] '5.1') return } -Describe 'MsiPackage End to End Tests' { - BeforeAll { - # Import CommonTestHelper - $testsFolderFilePath = Split-Path $PSScriptRoot -Parent - $testHelperFolderFilePath = Join-Path -Path $testsFolderFilePath -ChildPath 'TestHelpers' - $commonTestHelperFilePath = Join-Path -Path $testHelperFolderFilePath -ChildPath 'CommonTestHelper.psm1' - Import-Module -Name $commonTestHelperFilePath - - $script:testEnvironment = Enter-DscResourceTestEnvironment ` - -DscResourceModuleName 'PSDscResources' ` - -DscResourceName 'MSFT_MsiPackage' ` - -TestType 'Integration' - - # Import MsiPackage resource module for Test-TargetResource - $moduleRootFilePath = Split-Path -Path $testsFolderFilePath -Parent - $dscResourcesFolderFilePath = Join-Path -Path $moduleRootFilePath -ChildPath 'DscResources' - $msiPackageResourceFolderFilePath = Join-Path -Path $dscResourcesFolderFilePath -ChildPath 'MSFT_MsiPackage' - $msiPackageResourceModuleFilePath = Join-Path -Path $msiPackageResourceFolderFilePath -ChildPath 'MSFT_MsiPackage.psm1' - Import-Module -Name $msiPackageResourceModuleFilePath -Force - - # Import the MsiPackage test helper - $packageTestHelperFilePath = Join-Path -Path $testHelperFolderFilePath -ChildPath 'MSFT_MsiPackageResource.TestHelper.psm1' - Import-Module -Name $packageTestHelperFilePath -Force - - # Set up the paths to the test configurations - $script:configurationFilePathNoOptionalParameters = Join-Path -Path $PSScriptRoot -ChildPath 'MSFT_MsiPackage_NoOptionalParameters' - $script:configurationFilePathLogPath = Join-Path -Path $PSScriptRoot -ChildPath 'MSFT_MsiPackage_LogPath' - - <# - This log file is used to log messages from the mock server which is important for debugging since - most of the work of the mock server is done within a separate process. - #> - $script:logFile = Join-Path -Path $PSScriptRoot -ChildPath 'PackageTestLogFile.txt' - $script:environmentInIncorrectStateErrorMessage = 'The current environment is not in the expected state for this test - either something was setup incorrectly on your machine or a previous test failed - results after this may be invalid.' - - $script:msiName = 'DSCSetupProject.msi' - $script:msiLocation = Join-Path -Path $TestDrive -ChildPath $script:msiName - - $script:packageId = '{deadbeef-80c6-41e6-a1b9-8bdb8a05027f}' - - $null = New-TestMsi -DestinationPath $script:msiLocation - - # Clear the log file - 'Beginning integration tests' > $script:logFile - } +# Import CommonTestHelper +$testsFolderFilePath = Split-Path -Path $PSScriptRoot -Parent +$testHelperFolderFilePath = Join-Path -Path $testsFolderFilePath -ChildPath 'TestHelpers' +$commonTestHelperFilePath = Join-Path -Path $testHelperFolderFilePath -ChildPath 'CommonTestHelper.psm1' +Import-Module -Name $commonTestHelperFilePath - AfterAll { - # Remove the test MSI if it is still installed - if (Test-PackageInstalledById -ProductId $script:packageId) - { - $null = Start-Process -FilePath 'msiexec.exe' -ArgumentList @("/x$script:packageId", '/passive') -Wait - $null = Start-Sleep -Seconds 1 - } +try +{ + # Make sure strong crypto is enabled in .NET for HTTPS tests + $originalStrongCryptoSettings = Enable-StrongCryptoForDotNetFour + + Describe 'MsiPackage End to End Tests' { + BeforeAll { + # Import CommonTestHelper + $testsFolderFilePath = Split-Path $PSScriptRoot -Parent + $testHelperFolderFilePath = Join-Path -Path $testsFolderFilePath -ChildPath 'TestHelpers' + $commonTestHelperFilePath = Join-Path -Path $testHelperFolderFilePath -ChildPath 'CommonTestHelper.psm1' + Import-Module -Name $commonTestHelperFilePath + + $script:testEnvironment = Enter-DscResourceTestEnvironment ` + -DscResourceModuleName 'PSDscResources' ` + -DscResourceName 'MSFT_MsiPackage' ` + -TestType 'Integration' + + # Import MsiPackage resource module for Test-TargetResource + $moduleRootFilePath = Split-Path -Path $testsFolderFilePath -Parent + $dscResourcesFolderFilePath = Join-Path -Path $moduleRootFilePath -ChildPath 'DscResources' + $msiPackageResourceFolderFilePath = Join-Path -Path $dscResourcesFolderFilePath -ChildPath 'MSFT_MsiPackage' + $msiPackageResourceModuleFilePath = Join-Path -Path $msiPackageResourceFolderFilePath -ChildPath 'MSFT_MsiPackage.psm1' + Import-Module -Name $msiPackageResourceModuleFilePath -Force + + # Import the MsiPackage test helper + $packageTestHelperFilePath = Join-Path -Path $testHelperFolderFilePath -ChildPath 'MSFT_MsiPackageResource.TestHelper.psm1' + Import-Module -Name $packageTestHelperFilePath -Force + + # Set up the paths to the test configurations + $script:configurationFilePathNoOptionalParameters = Join-Path -Path $PSScriptRoot -ChildPath 'MSFT_MsiPackage_NoOptionalParameters' + $script:configurationFilePathLogPath = Join-Path -Path $PSScriptRoot -ChildPath 'MSFT_MsiPackage_LogPath' - if (Test-PackageInstalledById -ProductId $script:packageId) - { - throw 'Test package could not be uninstalled after running all tests. It may cause errors in subsequent test runs.' - } + <# + This log file is used to log messages from the mock server which is important for debugging since + most of the work of the mock server is done within a separate process. + #> + $script:logFile = Join-Path -Path $PSScriptRoot -ChildPath 'PackageTestLogFile.txt' + $script:environmentInIncorrectStateErrorMessage = 'The current environment is not in the expected state for this test - either something was setup incorrectly on your machine or a previous test failed - results after this may be invalid.' - Exit-DscResourceTestEnvironment -TestEnvironment $script:testEnvironment - } + $script:msiName = 'DSCSetupProject.msi' + $script:msiLocation = Join-Path -Path $TestDrive -ChildPath $script:msiName - Context 'Uninstall package that is already Absent' { - $configurationName = 'RemoveAbsentMsiPackage' + $script:packageId = '{deadbeef-80c6-41e6-a1b9-8bdb8a05027f}' - $msiPackageParameters = @{ - ProductId = $script:packageId - Path = $script:msiLocation - Ensure = 'Absent' - } + $null = New-TestMsi -DestinationPath $script:msiLocation - It 'Should return True from Test-TargetResource with the same parameters before configuration' { - $testTargetResourceInitialResult = MSFT_MsiPackage\Test-TargetResource @msiPackageParameters - $testTargetResourceInitialResult | Should Be $true + # Clear the log file + 'Beginning integration tests' > $script:logFile + } - if ($testTargetResourceInitialResult -ne $true) + AfterAll { + # Remove the test MSI if it is still installed + if (Test-PackageInstalledById -ProductId $script:packageId) { - <# - Not throwing an error here since the tests should still run correctly after this, - we just want to notify the user that the tests aren't necessarily testing what - they should be - #> - Write-Error -Message $script:environmentInIncorrectStateErrorMessage + $null = Start-Process -FilePath 'msiexec.exe' -ArgumentList @("/x$script:packageId", '/passive') -Wait + $null = Start-Sleep -Seconds 1 } - } - It 'Package should not exist on the machine before configuration is run' { - Test-PackageInstalledById -ProductId $script:packageId | Should Be $false - } - - It 'Should compile and run configuration' { - { - . $script:configurationFilePathNoOptionalParameters -ConfigurationName $configurationName - & $configurationName -OutputPath $TestDrive @msiPackageParameters - Start-DscConfiguration -Path $TestDrive -ErrorAction 'Stop' -Wait -Force - } | Should Not Throw - } + if (Test-PackageInstalledById -ProductId $script:packageId) + { + throw 'Test package could not be uninstalled after running all tests. It may cause errors in subsequent test runs.' + } - It 'Should return True from Test-TargetResource with the same parameters after configuration' { - MSFT_MsiPackage\Test-TargetResource @msiPackageParameters | Should Be $true + Exit-DscResourceTestEnvironment -TestEnvironment $script:testEnvironment } - It 'Package should not exist on the machine' { - Test-PackageInstalledById -ProductId $script:packageId | Should Be $false - } - } + Context 'Uninstall package that is already Absent' { + $configurationName = 'RemoveAbsentMsiPackage' - Context 'Install package that is not installed yet' { - $configurationName = 'InstallMsiPackage' + $msiPackageParameters = @{ + ProductId = $script:packageId + Path = $script:msiLocation + Ensure = 'Absent' + } - $msiPackageParameters = @{ - ProductId = $script:packageId - Path = $script:msiLocation - Ensure = 'Present' - } + It 'Should return True from Test-TargetResource with the same parameters before configuration' { + $testTargetResourceInitialResult = MSFT_MsiPackage\Test-TargetResource @msiPackageParameters + $testTargetResourceInitialResult | Should Be $true + + if ($testTargetResourceInitialResult -ne $true) + { + <# + Not throwing an error here since the tests should still run correctly after this, + we just want to notify the user that the tests aren't necessarily testing what + they should be + #> + Write-Error -Message $script:environmentInIncorrectStateErrorMessage + } + } - It 'Should return False from Test-TargetResource with the same parameters before configuration' { - $testTargetResourceInitialResult = MSFT_MsiPackage\Test-TargetResource @msiPackageParameters - $testTargetResourceInitialResult | Should Be $false + It 'Package should not exist on the machine before configuration is run' { + Test-PackageInstalledById -ProductId $script:packageId | Should Be $false + } - if ($testTargetResourceInitialResult -ne $false) - { - <# - Not throwing an error here since the tests should still run correctly after this, - we just want to notify the user that the tests aren't necessarily testing what - they should be - #> - Write-Error -Message $script:environmentInIncorrectStateErrorMessage + It 'Should compile and run configuration' { + { + . $script:configurationFilePathNoOptionalParameters -ConfigurationName $configurationName + & $configurationName -OutputPath $TestDrive @msiPackageParameters + Start-DscConfiguration -Path $TestDrive -ErrorAction 'Stop' -Wait -Force + } | Should Not Throw } - } - It 'Package should not exist on the machine before configuration is run' { - Test-PackageInstalledById -ProductId $script:packageId | Should Be $false - } + It 'Should return True from Test-TargetResource with the same parameters after configuration' { + MSFT_MsiPackage\Test-TargetResource @msiPackageParameters | Should Be $true + } - It 'Should compile and run configuration' { - { - . $script:configurationFilePathNoOptionalParameters -ConfigurationName $configurationName - & $configurationName -OutputPath $TestDrive @msiPackageParameters - Start-DscConfiguration -Path $TestDrive -ErrorAction 'Stop' -Wait -Force - } | Should Not Throw + It 'Package should not exist on the machine' { + Test-PackageInstalledById -ProductId $script:packageId | Should Be $false + } } - It 'Should return True from Test-TargetResource with the same parameters after configuration' { - MSFT_MsiPackage\Test-TargetResource @msiPackageParameters | Should Be $true - } + Context 'Install package that is not installed yet' { + $configurationName = 'InstallMsiPackage' - It 'Package should exist on the machine' { - Test-PackageInstalledById -ProductId $script:packageId | Should Be $true - } - } + $msiPackageParameters = @{ + ProductId = $script:packageId + Path = $script:msiLocation + Ensure = 'Present' + } - Context 'Install package that is already installed' { - $configurationName = 'InstallExistingMsiPackage' + It 'Should return False from Test-TargetResource with the same parameters before configuration' { + $testTargetResourceInitialResult = MSFT_MsiPackage\Test-TargetResource @msiPackageParameters + $testTargetResourceInitialResult | Should Be $false + + if ($testTargetResourceInitialResult -ne $false) + { + <# + Not throwing an error here since the tests should still run correctly after this, + we just want to notify the user that the tests aren't necessarily testing what + they should be + #> + Write-Error -Message $script:environmentInIncorrectStateErrorMessage + } + } - $msiPackageParameters = @{ - ProductId = $script:packageId - Path = $script:msiLocation - Ensure = 'Present' - } + It 'Package should not exist on the machine before configuration is run' { + Test-PackageInstalledById -ProductId $script:packageId | Should Be $false + } - It 'Should return True from Test-TargetResource with the same parameters before configuration' { - $testTargetResourceInitialResult = MSFT_MsiPackage\Test-TargetResource @msiPackageParameters - $testTargetResourceInitialResult | Should Be $true + It 'Should compile and run configuration' { + { + . $script:configurationFilePathNoOptionalParameters -ConfigurationName $configurationName + & $configurationName -OutputPath $TestDrive @msiPackageParameters + Start-DscConfiguration -Path $TestDrive -ErrorAction 'Stop' -Wait -Force + } | Should Not Throw + } - if ($testTargetResourceInitialResult -ne $true) - { - <# - Not throwing an error here since the tests should still run correctly after this, - we just want to notify the user that the tests aren't necessarily testing what - they should be - #> - Write-Error -Message $script:environmentInIncorrectStateErrorMessage + It 'Should return True from Test-TargetResource with the same parameters after configuration' { + MSFT_MsiPackage\Test-TargetResource @msiPackageParameters | Should Be $true } - } - It 'Package should exist on the machine before configuration is run' { - Test-PackageInstalledById -ProductId $script:packageId | Should Be $true + It 'Package should exist on the machine' { + Test-PackageInstalledById -ProductId $script:packageId | Should Be $true + } } - It 'Should compile and run configuration' { - { - . $script:configurationFilePathNoOptionalParameters -ConfigurationName $configurationName - & $configurationName -OutputPath $TestDrive @msiPackageParameters - Start-DscConfiguration -Path $TestDrive -ErrorAction 'Stop' -Wait -Force - } | Should Not Throw - } + Context 'Install package that is already installed' { + $configurationName = 'InstallExistingMsiPackage' - It 'Should return True from Test-TargetResource with the same parameters after configuration' { - MSFT_MsiPackage\Test-TargetResource @msiPackageParameters | Should Be $true - } + $msiPackageParameters = @{ + ProductId = $script:packageId + Path = $script:msiLocation + Ensure = 'Present' + } - It 'Package should exist on the machine' { - Test-PackageInstalledById -ProductId $script:packageId | Should Be $true - } - } + It 'Should return True from Test-TargetResource with the same parameters before configuration' { + $testTargetResourceInitialResult = MSFT_MsiPackage\Test-TargetResource @msiPackageParameters + $testTargetResourceInitialResult | Should Be $true + + if ($testTargetResourceInitialResult -ne $true) + { + <# + Not throwing an error here since the tests should still run correctly after this, + we just want to notify the user that the tests aren't necessarily testing what + they should be + #> + Write-Error -Message $script:environmentInIncorrectStateErrorMessage + } + } - Context 'Uninstall package that is installed' { - $configurationName = 'UninstallExistingMsiPackage' + It 'Package should exist on the machine before configuration is run' { + Test-PackageInstalledById -ProductId $script:packageId | Should Be $true + } - $msiPackageParameters = @{ - ProductId = $script:packageId - Path = $script:msiLocation - Ensure = 'Absent' - } + It 'Should compile and run configuration' { + { + . $script:configurationFilePathNoOptionalParameters -ConfigurationName $configurationName + & $configurationName -OutputPath $TestDrive @msiPackageParameters + Start-DscConfiguration -Path $TestDrive -ErrorAction 'Stop' -Wait -Force + } | Should Not Throw + } - It 'Should return False from Test-TargetResource with the same parameters before configuration' { - $testTargetResourceInitialResult = MSFT_MsiPackage\Test-TargetResource @msiPackageParameters - $testTargetResourceInitialResult | Should Be $false + It 'Should return True from Test-TargetResource with the same parameters after configuration' { + MSFT_MsiPackage\Test-TargetResource @msiPackageParameters | Should Be $true + } - if ($testTargetResourceInitialResult -ne $false) - { - <# - Not throwing an error here since the tests should still run correctly after this, - we just want to notify the user that the tests aren't necessarily testing what - they should be - #> - Write-Error -Message $script:environmentInIncorrectStateErrorMessage + It 'Package should exist on the machine' { + Test-PackageInstalledById -ProductId $script:packageId | Should Be $true } } - It 'Package should exist on the machine before configuration is run' { - Test-PackageInstalledById -ProductId $script:packageId | Should Be $true - } + Context 'Uninstall package that is installed' { + $configurationName = 'UninstallExistingMsiPackage' - It 'Should compile and run configuration' { - { - . $script:configurationFilePathNoOptionalParameters -ConfigurationName $configurationName - & $configurationName -OutputPath $TestDrive @msiPackageParameters - Start-DscConfiguration -Path $TestDrive -ErrorAction 'Stop' -Wait -Force - } | Should Not Throw - } + $msiPackageParameters = @{ + ProductId = $script:packageId + Path = $script:msiLocation + Ensure = 'Absent' + } - It 'Should return True from Test-TargetResource with the same parameters after configuration' { - MSFT_MsiPackage\Test-TargetResource @msiPackageParameters | Should Be $true - } + It 'Should return False from Test-TargetResource with the same parameters before configuration' { + $testTargetResourceInitialResult = MSFT_MsiPackage\Test-TargetResource @msiPackageParameters + $testTargetResourceInitialResult | Should Be $false + + if ($testTargetResourceInitialResult -ne $false) + { + <# + Not throwing an error here since the tests should still run correctly after this, + we just want to notify the user that the tests aren't necessarily testing what + they should be + #> + Write-Error -Message $script:environmentInIncorrectStateErrorMessage + } + } - It 'Package should not exist on the machine' { - Test-PackageInstalledById -ProductId $script:packageId | Should Be $false - } - } + It 'Package should exist on the machine before configuration is run' { + Test-PackageInstalledById -ProductId $script:packageId | Should Be $true + } - Context 'Install package that is not installed and write to specified log file' { - $configurationName = 'InstallWithLogFile' + It 'Should compile and run configuration' { + { + . $script:configurationFilePathNoOptionalParameters -ConfigurationName $configurationName + & $configurationName -OutputPath $TestDrive @msiPackageParameters + Start-DscConfiguration -Path $TestDrive -ErrorAction 'Stop' -Wait -Force + } | Should Not Throw + } - $logPath = Join-Path -Path $TestDrive -ChildPath 'TestMsiLog.txt' + It 'Should return True from Test-TargetResource with the same parameters after configuration' { + MSFT_MsiPackage\Test-TargetResource @msiPackageParameters | Should Be $true + } - if (Test-Path -Path $logPath) - { - Remove-Item -Path $logPath -Force + It 'Package should not exist on the machine' { + Test-PackageInstalledById -ProductId $script:packageId | Should Be $false + } } - $msiPackageParameters = @{ - ProductId = $script:packageId - Path = $script:msiLocation - Ensure = 'Present' - LogPath = $logPath - } + Context 'Install package that is not installed and write to specified log file' { + $configurationName = 'InstallWithLogFile' - It 'Should return False from Test-TargetResource with the same parameters before configuration' { - $testTargetResourceInitialResult = MSFT_MsiPackage\Test-TargetResource @msiPackageParameters - $testTargetResourceInitialResult | Should Be $false + $logPath = Join-Path -Path $TestDrive -ChildPath 'TestMsiLog.txt' - if ($testTargetResourceInitialResult -ne $false) + if (Test-Path -Path $logPath) { - <# - Not throwing an error here since the tests should still run correctly after this, - we just want to notify the user that the tests aren't necessarily testing what - they should be - #> - Write-Error -Message $script:environmentInIncorrectStateErrorMessage + Remove-Item -Path $logPath -Force } - } - - It 'Package should not exist on the machine before configuration is run' { - Test-PackageInstalledById -ProductId $script:packageId | Should Be $false - } - It 'Should compile and run configuration' { - { - . $script:configurationFilePathLogPath -ConfigurationName $configurationName - & $configurationName -OutputPath $TestDrive @msiPackageParameters - Start-DscConfiguration -Path $TestDrive -ErrorAction 'Stop' -Wait -Force - } | Should Not Throw - } + $msiPackageParameters = @{ + ProductId = $script:packageId + Path = $script:msiLocation + Ensure = 'Present' + LogPath = $logPath + } - It 'Should return True from Test-TargetResource with the same parameters after configuration' { - MSFT_MsiPackage\Test-TargetResource @msiPackageParameters | Should Be $true - } + It 'Should return False from Test-TargetResource with the same parameters before configuration' { + $testTargetResourceInitialResult = MSFT_MsiPackage\Test-TargetResource @msiPackageParameters + $testTargetResourceInitialResult | Should Be $false + + if ($testTargetResourceInitialResult -ne $false) + { + <# + Not throwing an error here since the tests should still run correctly after this, + we just want to notify the user that the tests aren't necessarily testing what + they should be + #> + Write-Error -Message $script:environmentInIncorrectStateErrorMessage + } + } - It 'Should have created the log file' { - Test-Path -Path $logPath | Should Be $true - } + It 'Package should not exist on the machine before configuration is run' { + Test-PackageInstalledById -ProductId $script:packageId | Should Be $false + } - It 'Package should exist on the machine' { - Test-PackageInstalledById -ProductId $script:packageId | Should Be $true - } - } + It 'Should compile and run configuration' { + { + . $script:configurationFilePathLogPath -ConfigurationName $configurationName + & $configurationName -OutputPath $TestDrive @msiPackageParameters + Start-DscConfiguration -Path $TestDrive -ErrorAction 'Stop' -Wait -Force + } | Should Not Throw + } - Context 'Uninstall package that is installed and write to specified log file' { - $configurationName = 'InstallWithLogFile' + It 'Should return True from Test-TargetResource with the same parameters after configuration' { + MSFT_MsiPackage\Test-TargetResource @msiPackageParameters | Should Be $true + } - $logPath = Join-Path -Path $TestDrive -ChildPath 'TestMsiLog.txt' + It 'Should have created the log file' { + Test-Path -Path $logPath | Should Be $true + } - if (Test-Path -Path $logPath) - { - Remove-Item -Path $logPath -Force + It 'Package should exist on the machine' { + Test-PackageInstalledById -ProductId $script:packageId | Should Be $true + } } - $msiPackageParameters = @{ - ProductId = $script:packageId - Path = $script:msiLocation - Ensure = 'Absent' - LogPath = $logPath - } + Context 'Uninstall package that is installed and write to specified log file' { + $configurationName = 'InstallWithLogFile' - It 'Should return False from Test-TargetResource with the same parameters before configuration' { - $testTargetResourceInitialResult = MSFT_MsiPackage\Test-TargetResource @msiPackageParameters - $testTargetResourceInitialResult | Should Be $false + $logPath = Join-Path -Path $TestDrive -ChildPath 'TestMsiLog.txt' - if ($testTargetResourceInitialResult -ne $false) + if (Test-Path -Path $logPath) { - <# - Not throwing an error here since the tests should still run correctly after this, - we just want to notify the user that the tests aren't necessarily testing what - they should be - #> - Write-Error -Message $script:environmentInIncorrectStateErrorMessage + Remove-Item -Path $logPath -Force } - } - It 'Package should exist on the machine before configuration is run' { - Test-PackageInstalledById -ProductId $script:packageId | Should Be $true - } + $msiPackageParameters = @{ + ProductId = $script:packageId + Path = $script:msiLocation + Ensure = 'Absent' + LogPath = $logPath + } - It 'Should compile and run configuration' { - { - . $script:configurationFilePathLogPath -ConfigurationName $configurationName - & $configurationName -OutputPath $TestDrive @msiPackageParameters - Start-DscConfiguration -Path $TestDrive -ErrorAction 'Stop' -Wait -Force - } | Should Not Throw - } + It 'Should return False from Test-TargetResource with the same parameters before configuration' { + $testTargetResourceInitialResult = MSFT_MsiPackage\Test-TargetResource @msiPackageParameters + $testTargetResourceInitialResult | Should Be $false + + if ($testTargetResourceInitialResult -ne $false) + { + <# + Not throwing an error here since the tests should still run correctly after this, + we just want to notify the user that the tests aren't necessarily testing what + they should be + #> + Write-Error -Message $script:environmentInIncorrectStateErrorMessage + } + } - It 'Should return True from Test-TargetResource with the same parameters after configuration' { - MSFT_MsiPackage\Test-TargetResource @msiPackageParameters | Should Be $true - } + It 'Package should exist on the machine before configuration is run' { + Test-PackageInstalledById -ProductId $script:packageId | Should Be $true + } + + It 'Should compile and run configuration' { + { + . $script:configurationFilePathLogPath -ConfigurationName $configurationName + & $configurationName -OutputPath $TestDrive @msiPackageParameters + Start-DscConfiguration -Path $TestDrive -ErrorAction 'Stop' -Wait -Force + } | Should Not Throw + } + + It 'Should return True from Test-TargetResource with the same parameters after configuration' { + MSFT_MsiPackage\Test-TargetResource @msiPackageParameters | Should Be $true + } + + It 'Should have created the log file' { + Test-Path -Path $logPath | Should Be $true + } - It 'Should have created the log file' { - Test-Path -Path $logPath | Should Be $true + It 'Package should not exist on the machine' { + Test-PackageInstalledById -ProductId $script:packageId | Should Be $false + } } - It 'Package should not exist on the machine' { - Test-PackageInstalledById -ProductId $script:packageId | Should Be $false - } - } + Context 'Install package from HTTP Url' { + $configurationName = 'UninstallExistingMsiPackageFromHttp' - Context 'Install package from HTTP Url' { - $configurationName = 'UninstallExistingMsiPackageFromHttp' + $baseUrl = 'http://localhost:1242/' + $msiUrl = "$baseUrl" + 'package.msi' - $baseUrl = 'http://localhost:1242/' - $msiUrl = "$baseUrl" + 'package.msi' + $fileServerStarted = $null + $job = $null - $fileServerStarted = $null - $job = $null + $msiPackageParameters = @{ + ProductId = $script:packageId + Path = $msiUrl + Ensure = 'Present' + } - $msiPackageParameters = @{ - ProductId = $script:packageId - Path = $msiUrl - Ensure = 'Present' - } + It 'Should return False from Test-TargetResource with the same parameters before configuration' { + $testTargetResourceInitialResult = MSFT_MsiPackage\Test-TargetResource @msiPackageParameters + $testTargetResourceInitialResult | Should Be $false + + if ($testTargetResourceInitialResult -ne $false) + { + <# + Not throwing an error here since the tests should still run correctly after this, + we just want to notify the user that the tests aren't necessarily testing what + they should be + #> + Write-Error -Message $script:environmentInIncorrectStateErrorMessage + } + } - It 'Should return False from Test-TargetResource with the same parameters before configuration' { - $testTargetResourceInitialResult = MSFT_MsiPackage\Test-TargetResource @msiPackageParameters - $testTargetResourceInitialResult | Should Be $false + It 'Package should not exist on the machine before configuration is run' { + Test-PackageInstalledById -ProductId $script:packageId | Should Be $false + } - if ($testTargetResourceInitialResult -ne $false) + try + { + $serverResult = Start-Server -FilePath $script:msiLocation -LogPath $script:logFile -Https $false + $fileServerStarted = $serverResult.FileServerStarted + $job = $serverResult.Job + + $fileServerStarted.WaitOne(30000) + + It 'Should compile and run configuration' { + { + . $script:configurationFilePathNoOptionalParameters -ConfigurationName $configurationName + & $configurationName -OutputPath $TestDrive @msiPackageParameters + Start-DscConfiguration -Path $TestDrive -ErrorAction 'Stop' -Wait -Force + } | Should Not Throw + } + } + finally { <# - Not throwing an error here since the tests should still run correctly after this, - we just want to notify the user that the tests aren't necessarily testing what - they should be + This must be called after Start-Server to ensure the listening port is closed, + otherwise subsequent tests may fail until the machine is rebooted. #> - Write-Error -Message $script:environmentInIncorrectStateErrorMessage + Stop-Server -FileServerStarted $fileServerStarted -Job $job } - } - It 'Package should not exist on the machine before configuration is run' { - Test-PackageInstalledById -ProductId $script:packageId | Should Be $false - } - - try - { - $serverResult = Start-Server -FilePath $script:msiLocation -LogPath $script:logFile -Https $false - $fileServerStarted = $serverResult.FileServerStarted - $job = $serverResult.Job - - $fileServerStarted.WaitOne(30000) - - It 'Should compile and run configuration' { - { - . $script:configurationFilePathNoOptionalParameters -ConfigurationName $configurationName - & $configurationName -OutputPath $TestDrive @msiPackageParameters - Start-DscConfiguration -Path $TestDrive -ErrorAction 'Stop' -Wait -Force - } | Should Not Throw + It 'Should return True from Test-TargetResource with the same parameters after configuration' { + MSFT_MsiPackage\Test-TargetResource @msiPackageParameters | Should Be $true } - } - finally - { - <# - This must be called after Start-Server to ensure the listening port is closed, - otherwise subsequent tests may fail until the machine is rebooted. - #> - Stop-Server -FileServerStarted $fileServerStarted -Job $job - } - It 'Should return True from Test-TargetResource with the same parameters after configuration' { - MSFT_MsiPackage\Test-TargetResource @msiPackageParameters | Should Be $true - } - - It 'Package should exist on the machine' { - Test-PackageInstalledById -ProductId $script:packageId | Should Be $true + It 'Package should exist on the machine' { + Test-PackageInstalledById -ProductId $script:packageId | Should Be $true + } } - } - Context 'Uninstall Msi package from HTTP Url' { - $configurationName = 'InstallMsiPackageFromHttp' + Context 'Uninstall Msi package from HTTP Url' { + $configurationName = 'InstallMsiPackageFromHttp' - $baseUrl = 'http://localhost:1242/' - $msiUrl = "$baseUrl" + 'package.msi' + $baseUrl = 'http://localhost:1242/' + $msiUrl = "$baseUrl" + 'package.msi' - $fileServerStarted = $null - $job = $null + $fileServerStarted = $null + $job = $null - $msiPackageParameters = @{ - ProductId = $script:packageId - Path = $msiUrl - Ensure = 'Absent' - } + $msiPackageParameters = @{ + ProductId = $script:packageId + Path = $msiUrl + Ensure = 'Absent' + } - It 'Should return False from Test-TargetResource with the same parameters before configuration' { - $testTargetResourceInitialResult = MSFT_MsiPackage\Test-TargetResource @msiPackageParameters - $testTargetResourceInitialResult | Should Be $false + It 'Should return False from Test-TargetResource with the same parameters before configuration' { + $testTargetResourceInitialResult = MSFT_MsiPackage\Test-TargetResource @msiPackageParameters + $testTargetResourceInitialResult | Should Be $false + + if ($testTargetResourceInitialResult -ne $false) + { + <# + Not throwing an error here since the tests should still run correctly after this, + we just want to notify the user that the tests aren't necessarily testing what + they should be + #> + Write-Error -Message $script:environmentInIncorrectStateErrorMessage + } + } - if ($testTargetResourceInitialResult -ne $false) + It 'Package should exist on the machine before configuration is run' { + Test-PackageInstalledById -ProductId $script:packageId | Should Be $true + } + + try + { + $serverResult = Start-Server -FilePath $script:msiLocation -LogPath $script:logFile -Https $false + $fileServerStarted = $serverResult.FileServerStarted + $job = $serverResult.Job + + $fileServerStarted.WaitOne(30000) + + It 'Should compile and run configuration' { + { + . $script:configurationFilePathNoOptionalParameters -ConfigurationName $configurationName + & $configurationName -OutputPath $TestDrive @msiPackageParameters + Start-DscConfiguration -Path $TestDrive -ErrorAction 'Stop' -Wait -Force + } | Should Not Throw + } + } + finally { <# - Not throwing an error here since the tests should still run correctly after this, - we just want to notify the user that the tests aren't necessarily testing what - they should be + This must be called after Start-Server to ensure the listening port is closed, + otherwise subsequent tests may fail until the machine is rebooted. #> - Write-Error -Message $script:environmentInIncorrectStateErrorMessage + Stop-Server -FileServerStarted $fileServerStarted -Job $job } - } - - It 'Package should exist on the machine before configuration is run' { - Test-PackageInstalledById -ProductId $script:packageId | Should Be $true - } - - try - { - $serverResult = Start-Server -FilePath $script:msiLocation -LogPath $script:logFile -Https $false - $fileServerStarted = $serverResult.FileServerStarted - $job = $serverResult.Job - - $fileServerStarted.WaitOne(30000) - It 'Should compile and run configuration' { - { - . $script:configurationFilePathNoOptionalParameters -ConfigurationName $configurationName - & $configurationName -OutputPath $TestDrive @msiPackageParameters - Start-DscConfiguration -Path $TestDrive -ErrorAction 'Stop' -Wait -Force - } | Should Not Throw + It 'Should return true from Test-TargetResource with the same parameters after configuration' { + MSFT_MsiPackage\Test-TargetResource @msiPackageParameters | Should Be $true } - } - finally - { - <# - This must be called after Start-Server to ensure the listening port is closed, - otherwise subsequent tests may fail until the machine is rebooted. - #> - Stop-Server -FileServerStarted $fileServerStarted -Job $job - } - - It 'Should return true from Test-TargetResource with the same parameters after configuration' { - MSFT_MsiPackage\Test-TargetResource @msiPackageParameters | Should Be $true - } - It 'Package should not exist on the machine' { - Test-PackageInstalledById -ProductId $script:packageId | Should Be $false + It 'Package should not exist on the machine' { + Test-PackageInstalledById -ProductId $script:packageId | Should Be $false + } } - } - Context 'Install Msi package from HTTPS Url' { - $configurationName = 'InstallMsiPackageFromHttpS' + Context 'Install Msi package from HTTPS Url' { + $configurationName = 'InstallMsiPackageFromHttpS' - $baseUrl = 'https://localhost:1243/' - $msiUrl = "$baseUrl" + 'package.msi' + $baseUrl = 'https://localhost:1243/' + $msiUrl = "$baseUrl" + 'package.msi' - $fileServerStarted = $null - $job = $null + $fileServerStarted = $null + $job = $null - $msiPackageParameters = @{ - ProductId = $script:packageId - Path = $msiUrl - Ensure = 'Present' - } + $msiPackageParameters = @{ + ProductId = $script:packageId + Path = $msiUrl + Ensure = 'Present' + } - It 'Should return False from Test-TargetResource with the same parameters before configuration' { - $testTargetResourceInitialResult = MSFT_MsiPackage\Test-TargetResource @msiPackageParameters - $testTargetResourceInitialResult | Should Be $false + It 'Should return False from Test-TargetResource with the same parameters before configuration' { + $testTargetResourceInitialResult = MSFT_MsiPackage\Test-TargetResource @msiPackageParameters + $testTargetResourceInitialResult | Should Be $false + + if ($testTargetResourceInitialResult -ne $false) + { + <# + Not throwing an error here since the tests should still run correctly after this, + we just want to notify the user that the tests aren't necessarily testing what + they should be + #> + Write-Error -Message $script:environmentInIncorrectStateErrorMessage + } + } - if ($testTargetResourceInitialResult -ne $false) + It 'Package should not exist on the machine before configuration is run' { + Test-PackageInstalledById -ProductId $script:packageId | Should Be $false + } + + try + { + $serverResult = Start-Server -FilePath $script:msiLocation -LogPath $script:logFile -Https $true + $fileServerStarted = $serverResult.FileServerStarted + $job = $serverResult.Job + + $fileServerStarted.WaitOne(30000) + + It 'Should compile and run configuration' { + { + . $script:configurationFilePathNoOptionalParameters -ConfigurationName $configurationName + & $configurationName -OutputPath $TestDrive @msiPackageParameters + Start-DscConfiguration -Path $TestDrive -ErrorAction 'Stop' -Wait -Force + } | Should Not Throw + } + } + finally { <# - Not throwing an error here since the tests should still run correctly after this, - we just want to notify the user that the tests aren't necessarily testing what - they should be + This must be called after Start-Server to ensure the listening port is closed, + otherwise subsequent tests may fail until the machine is rebooted. #> - Write-Error -Message $script:environmentInIncorrectStateErrorMessage + Stop-Server -FileServerStarted $fileServerStarted -Job $job } - } - It 'Package should not exist on the machine before configuration is run' { - Test-PackageInstalledById -ProductId $script:packageId | Should Be $false - } - - try - { - $serverResult = Start-Server -FilePath $script:msiLocation -LogPath $script:logFile -Https $true - $fileServerStarted = $serverResult.FileServerStarted - $job = $serverResult.Job - - $fileServerStarted.WaitOne(30000) - - It 'Should compile and run configuration' { - { - . $script:configurationFilePathNoOptionalParameters -ConfigurationName $configurationName - & $configurationName -OutputPath $TestDrive @msiPackageParameters - Start-DscConfiguration -Path $TestDrive -ErrorAction 'Stop' -Wait -Force - } | Should Not Throw + It 'Should return true from Test-TargetResource with the same parameters after configuration' { + MSFT_MsiPackage\Test-TargetResource @msiPackageParameters | Should Be $true } - } - finally - { - <# - This must be called after Start-Server to ensure the listening port is closed, - otherwise subsequent tests may fail until the machine is rebooted. - #> - Stop-Server -FileServerStarted $fileServerStarted -Job $job - } - - It 'Should return true from Test-TargetResource with the same parameters after configuration' { - MSFT_MsiPackage\Test-TargetResource @msiPackageParameters | Should Be $true - } - It 'Package should exist on the machine' { - Test-PackageInstalledById -ProductId $script:packageId | Should Be $true + It 'Package should exist on the machine' { + Test-PackageInstalledById -ProductId $script:packageId | Should Be $true + } } - } - Context 'Uninstall Msi package from HTTPS Url' { - $configurationName = 'UninstallMsiPackageFromHttps' + Context 'Uninstall Msi package from HTTPS Url' { + $configurationName = 'UninstallMsiPackageFromHttps' - $baseUrl = 'https://localhost:1243/' - $msiUrl = "$baseUrl" + 'package.msi' + $baseUrl = 'https://localhost:1243/' + $msiUrl = "$baseUrl" + 'package.msi' - $fileServerStarted = $null - $job = $null + $fileServerStarted = $null + $job = $null - $msiPackageParameters = @{ - ProductId = $script:packageId - Path = $msiUrl - Ensure = 'Absent' - } + $msiPackageParameters = @{ + ProductId = $script:packageId + Path = $msiUrl + Ensure = 'Absent' + } + + It 'Should return False from Test-TargetResource with the same parameters before configuration' { + $testTargetResourceInitialResult = MSFT_MsiPackage\Test-TargetResource @msiPackageParameters + $testTargetResourceInitialResult | Should Be $false + + if ($testTargetResourceInitialResult -ne $false) + { + <# + Not throwing an error here since the tests should still run correctly after this, + we just want to notify the user that the tests aren't necessarily testing what + they should be + #> + Write-Error -Message $script:environmentInIncorrectStateErrorMessage + } + } - It 'Should return False from Test-TargetResource with the same parameters before configuration' { - $testTargetResourceInitialResult = MSFT_MsiPackage\Test-TargetResource @msiPackageParameters - $testTargetResourceInitialResult | Should Be $false + It 'Package should exist on the machine before configuration is run' { + Test-PackageInstalledById -ProductId $script:packageId | Should Be $true + } - if ($testTargetResourceInitialResult -ne $false) + try + { + $serverResult = Start-Server -FilePath $script:msiLocation -LogPath $script:logFile -Https $true + $fileServerStarted = $serverResult.FileServerStarted + $job = $serverResult.Job + + $fileServerStarted.WaitOne(30000) + + It 'Should compile and run configuration' { + { + . $script:configurationFilePathNoOptionalParameters -ConfigurationName $configurationName + & $configurationName -OutputPath $TestDrive @msiPackageParameters + Start-DscConfiguration -Path $TestDrive -ErrorAction 'Stop' -Wait -Force + } | Should Not Throw + } + } + finally { <# - Not throwing an error here since the tests should still run correctly after this, - we just want to notify the user that the tests aren't necessarily testing what - they should be + This must be called after Start-Server to ensure the listening port is closed, + otherwise subsequent tests may fail until the machine is rebooted. #> - Write-Error -Message $script:environmentInIncorrectStateErrorMessage + Stop-Server -FileServerStarted $fileServerStarted -Job $job } - } - - It 'Package should exist on the machine before configuration is run' { - Test-PackageInstalledById -ProductId $script:packageId | Should Be $true - } - - try - { - $serverResult = Start-Server -FilePath $script:msiLocation -LogPath $script:logFile -Https $true - $fileServerStarted = $serverResult.FileServerStarted - $job = $serverResult.Job - - $fileServerStarted.WaitOne(30000) - It 'Should compile and run configuration' { - { - . $script:configurationFilePathNoOptionalParameters -ConfigurationName $configurationName - & $configurationName -OutputPath $TestDrive @msiPackageParameters - Start-DscConfiguration -Path $TestDrive -ErrorAction 'Stop' -Wait -Force - } | Should Not Throw + It 'Should return true from Test-TargetResource with the same parameters after configuration' { + MSFT_MsiPackage\Test-TargetResource @msiPackageParameters | Should Be $true } - } - finally - { - <# - This must be called after Start-Server to ensure the listening port is closed, - otherwise subsequent tests may fail until the machine is rebooted. - #> - Stop-Server -FileServerStarted $fileServerStarted -Job $job - } - - It 'Should return true from Test-TargetResource with the same parameters after configuration' { - MSFT_MsiPackage\Test-TargetResource @msiPackageParameters | Should Be $true - } - It 'Package should not exist on the machine' { - Test-PackageInstalledById -ProductId $script:packageId | Should Be $false + It 'Package should not exist on the machine' { + Test-PackageInstalledById -ProductId $script:packageId | Should Be $false + } } } } +finally +{ + Undo-ChangesToStrongCryptoForDotNetFour -OriginalSettings $originalStrongCryptoSettings +} diff --git a/Tests/Integration/MSFT_MsiPackage.Integration.Tests.ps1 b/Tests/Integration/MSFT_MsiPackage.Integration.Tests.ps1 index 740f9bf..a6a5e45 100644 --- a/Tests/Integration/MSFT_MsiPackage.Integration.Tests.ps1 +++ b/Tests/Integration/MSFT_MsiPackage.Integration.Tests.ps1 @@ -19,6 +19,9 @@ $script:testEnvironment = Enter-DscResourceTestEnvironment ` try { + # Make sure strong crypto is enabled in .NET for HTTPS tests + $originalStrongCryptoSettings = Enable-StrongCryptoForDotNetFour + InModuleScope 'MSFT_MsiPackage' { Describe 'MSFT_MsiPackage Integration Tests' { BeforeAll { @@ -306,4 +309,6 @@ try finally { Exit-DscResourceTestEnvironment -TestEnvironment $script:testEnvironment + + Undo-ChangesToStrongCryptoForDotNetFour -OriginalSettings $originalStrongCryptoSettings } diff --git a/Tests/TestHelpers/CommonTestHelper.psm1 b/Tests/TestHelpers/CommonTestHelper.psm1 index c5671e9..725b4ad 100644 --- a/Tests/TestHelpers/CommonTestHelper.psm1 +++ b/Tests/TestHelpers/CommonTestHelper.psm1 @@ -790,6 +790,105 @@ function Exit-DscResourceTestEnvironment Restore-TestEnvironment -TestEnvironment $TestEnvironment } +<# + .SYNOPSIS + Enables strong crypto for .NET v4.0.30319. Returns a Hashtable + containing the relevant, original registry settings, prior to + modification. +#> +function Enable-StrongCryptoForDotNetFour +{ + [OutputType([System.Collections.Hashtable])] + [CmdletBinding()] + param () + + $originalValues = @{} + + $regBases = @( + 'HKLM:\SOFTWARE' + 'HKLM:\SOFTWARE\Wow6432Node' + ) + + $net4Suffix = 'Microsoft\.NetFramework\v4.0.30319' + + foreach ($regBase in $regBases) + { + $regPath = Join-Path -Path $regBase -ChildPath $net4Suffix + + if ($null -ne (Get-Item -Path $regPath -ErrorAction SilentlyContinue)) + { + $useStrongCryptoProp = Get-ItemProperty -Path $regPath -Name 'SchUseStrongCrypto' -ErrorAction SilentlyContinue + $needsUpdate = $false + + if ($null -eq $useStrongCryptoProp) + { + $originalValues.Add($regPath, $null) + $needsUpdate = $true + } + else + { + $originalValues.Add($regPath, $useStrongCryptoProp.SchUseStrongCrypto) + + if ($useStrongCryptoProp.SchUseStrongCrypto -ne 1) + { + $needsUpdate = $true + } + } + + if ($needsUpdate) + { + Write-Verbose -Message "Setting property SchUseStrongCrypto at path '$regPath' to 1" + + Set-ItemProperty -Path $regPath -Name 'SchUseStrongCrypto' -Value '1' -Type DWord -ErrorAction Stop + } + } + else + { + Write-Warning -Message "Failed to find registry key at path: $regPath. Skipping setting SchUseStrongCrypto to 1. This may cause Integration tests to fail that depend on this setting." + continue + } + } + + return $originalValues +} + +<# + .SYNOPSIS + Restores strong crypto for .NET v4.0.30319 settings to what they were + prior to calling Enable-StrongCryptoForDotNetFour. + + .PARAMETER OriginalSettings + A Hashtable containing the original registry settings for strong crypto + for .NET v4.0.30319. +#> +function Undo-ChangesToStrongCryptoForDotNetFour +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.Collections.Hashtable] + $OriginalSettings + ) + + foreach ($regPath in $OriginalSettings.Keys) + { + $useStrongCryptoProp = Get-ItemProperty -Path $regPath -Name 'SchUseStrongCrypto' -ErrorAction SilentlyContinue + + # The SchUseStrongCrypto value previously didn't exist, but now does. Delete it. + if ($null -eq $OriginalSettings[$regPath] -and $null -ne $useStrongCryptoProp) + { + Remove-ItemProperty -Path $regPath -Name 'SchUseStrongCrypto' -ErrorAction Stop + } + # The SchUseStrongCrypto value previously existed but had a different value. + elseif($OriginalSettings[$regPath] -ne $useStrongCryptoProp.SchUseStrongCrypto) + { + Set-ItemProperty -Path $regPath -Name 'SchUseStrongCrypto' -Value $OriginalSettings[$regPath] -Type DWord -ErrorAction Stop + } + } +} + Export-ModuleMember -Function @( 'Test-GetTargetResourceResult', ` 'Wait-ScriptBlockReturnTrue', ` @@ -802,5 +901,7 @@ Export-ModuleMember -Function @( 'Invoke-SetTargetResourceUnitTest', ` 'Invoke-TestTargetResourceUnitTest', ` 'Invoke-ExpectedMocksAreCalledTest', ` - 'Invoke-GenericUnitTest' + 'Invoke-GenericUnitTest', + 'Enable-StrongCryptoForDotNetFour', + 'Undo-ChangesToStrongCryptoForDotNetFour' )