From 97145c60b84f596446eb328a40478f6861f463ec Mon Sep 17 00:00:00 2001 From: Ruben Guerrero Samaniego Date: Tue, 1 Aug 2023 14:12:40 -0700 Subject: [PATCH 01/15] wip --- .../tests/Microsoft.WinGet.Client.Tests.ps1 | 42 +++++++++++++------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/src/PowerShell/tests/Microsoft.WinGet.Client.Tests.ps1 b/src/PowerShell/tests/Microsoft.WinGet.Client.Tests.ps1 index 00faba7012..c360834737 100644 --- a/src/PowerShell/tests/Microsoft.WinGet.Client.Tests.ps1 +++ b/src/PowerShell/tests/Microsoft.WinGet.Client.Tests.ps1 @@ -5,18 +5,27 @@ .Synopsis Pester tests related to the Microsoft.WinGet.Client PowerShell module. The tests require the localhost web server to be running and serving the test data. - 'Invoke-Pester' should be called in an admin powershell window with the 'Microsoft.WinGet.Client' PowerShell module already imported. + 'Invoke-Pester' should be called in an admin PowerShell window. #> BeforeAll { # Source Add requires admin privileges, this will only execute successfully in an elevated PowerShell. wingetdev source add 'TestSource' 'https://localhost:5001/TestKit/' + Import-Module Microsoft.WinGet.Client + + # TODO: + # wingetdev settings export, parse to get settings file. + # Function that modified the file (just check in json files) + # test that calls Get-WinGetSettings and compares. + # Investigate server not released? } Describe 'Get-WinGetSource' { - + It 'Get Test Source' { $source = Get-WinGetSource -Name 'TestSource' + + $source | Should -Not -BeNullOrEmpty -ErrorAction Stop $source.Name | Should -Be 'TestSource' $source.Argument | Should -Be 'https://localhost:5001/TestKit/' $source.Type | Should -Be 'Microsoft.PreIndexed.Package' @@ -30,12 +39,12 @@ Describe 'Find-WinGetPackage' { } It 'Find by Id' { - $package = Find-WinGetPackage -Source 'TestSource' -Id 'AppInstallerTest.TestExeInstaller' + $package = Find-WinGetPackage -Source 'TestSource' -Id 'AppInstallerTest.TestExampleInstaller' $package | Should -Not -BeNullOrEmpty -ErrorAction Stop - $package.Name | Should -Be 'TestExeInstaller' - $package.Id | Should -Be 'AppInstallerTest.TestExeInstaller' - $package.Version | Should -Be '2.0.0.0' + $package.Name | Should -Be 'TestExampleInstaller' + $package.Id | Should -Be 'AppInstallerTest.TestExampleInstaller' + $package.Version | Should -Be '1.2.3.4' $package.Source | Should -Be 'TestSource' } @@ -56,7 +65,7 @@ Describe 'Find-WinGetPackage' { } It 'Find package and verify PackageVersionInfo' { - $package = Find-WinGetPackage -Source 'TestSource' -Id 'AppInstallerTest.TestPortableExe' -Exact + $package = Find-WinGetPackage -Source 'TestSource' -Id 'AppInstallerTest.TestPortableExe' -MatchOption Equals $package | Should -Not -BeNullOrEmpty -ErrorAction Stop $package.AvailableVersions[0] | Should -Be '3.0.0.0' @@ -76,14 +85,16 @@ Describe 'Install|Update|Uninstall-WinGetPackage' { It 'Install by Id' { $result = Install-WinGetPackage -Id AppInstallerTest.TestExeInstaller -Version '1.0.0.0' + $result | Should -Not -BeNullOrEmpty -ErrorAction Stop $result.InstallerErrorCode | Should -Be 0 $result.Status | Should -Be 'Ok' $result.RebootRequired | Should -Be 'False' } It 'Install by exact Name and Version' { - $result = Install-WinGetPackage -Name TestPortableExe -Version '2.0.0.0' -Exact + $result = Install-WinGetPackage -Name TestPortableExe -Version '2.0.0.0' -MatchOption Equals + $result | Should -Not -BeNullOrEmpty -ErrorAction Stop $result.InstallerErrorCode | Should -Be 0 $result.Status | Should -Be 'Ok' $result.RebootRequired | Should -Be 'False' @@ -92,14 +103,16 @@ Describe 'Install|Update|Uninstall-WinGetPackage' { It 'Update by Id' { $result = Update-WinGetPackage -Id AppInstallerTest.TestExeInstaller + $result | Should -Not -BeNullOrEmpty -ErrorAction Stop $result.InstallerErrorCode | Should -Be 0 $result.Status | Should -Be 'Ok' $result.RebootRequired | Should -Be 'False' } - It 'Update by Name and Version' { + It 'Update by Name' { $result = Update-WinGetPackage -Name TestPortableExe + $result | Should -Not -BeNullOrEmpty -ErrorAction Stop $result.InstallerErrorCode | Should -Be 0 $result.Status | Should -Be 'Ok' $result.RebootRequired | Should -Be 'False' @@ -108,6 +121,7 @@ Describe 'Install|Update|Uninstall-WinGetPackage' { It 'Uninstall by Id' { $result = Uninstall-WinGetPackage -Id AppInstallerTest.TestExeInstaller + $result | Should -Not -BeNullOrEmpty -ErrorAction Stop $result.UninstallerErrorCode | Should -Be 0 $result.Status | Should -Be 'Ok' $result.RebootRequired | Should -Be 'False' @@ -116,6 +130,7 @@ Describe 'Install|Update|Uninstall-WinGetPackage' { It 'Uninstall by Name' { $result = Uninstall-WinGetPackage -Name TestPortableExe + $result | Should -Not -BeNullOrEmpty -ErrorAction Stop $result.UninstallerErrorCode | Should -Be 0 $result.Status | Should -Be 'Ok' $result.RebootRequired | Should -Be 'False' @@ -142,6 +157,7 @@ Describe 'Get-WinGetPackage' { It 'Install by Id' { $result = Install-WinGetPackage -Id AppInstallerTest.TestExeInstaller -Version '1.0.0.0' + $result | Should -Not -BeNullOrEmpty -ErrorAction Stop $result.InstallerErrorCode | Should -Be 0 $result.Status | Should -Be 'Ok' $result.RebootRequired | Should -Be 'False' @@ -153,7 +169,7 @@ Describe 'Get-WinGetPackage' { $result | Should -Not -BeNullOrEmpty -ErrorAction Stop $result.Name | Should -Be 'TestExeInstaller' $result.Id | Should -Be 'AppInstallerTest.TestExeInstaller' - $result.Version | Should -Be '1.0.0.0' + $result.InstalledVersion | Should -Be '1.0.0.0' $result.Source | Should -Be 'TestSource' $result.AvailableVersions[0] | Should -Be '2.0.0.0' } @@ -164,7 +180,7 @@ Describe 'Get-WinGetPackage' { $result | Should -Not -BeNullOrEmpty -ErrorAction Stop $result.Name | Should -Be 'TestExeInstaller' $result.Id | Should -Be 'AppInstallerTest.TestExeInstaller' - $result.Version | Should -Be '1.0.0.0' + $result.InstalledVersion | Should -Be '1.0.0.0' $result.Source | Should -Be 'TestSource' $result.AvailableVersions[0] | Should -Be '2.0.0.0' } @@ -180,6 +196,6 @@ Describe 'Get-WinGetPackage' { } AfterAll { - # Source Remove requires admin privileges, this will only execute successfully in an elevated PowerShell. - wingetdev source remove 'TestSource' + # Source Remove requires admin privileges, this will only execute successfully in an elevated PowerShell. + Start-Process wingetdev source remove 'TestSource' } \ No newline at end of file From ca3edfe58e0e905af6735273e63136f969882e9a Mon Sep 17 00:00:00 2001 From: Ruben Guerrero Samaniego Date: Tue, 1 Aug 2023 16:31:38 -0700 Subject: [PATCH 02/15] Make things ready --- azure-pipelines.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index f7ddc4e59e..d23eb94f43 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -260,6 +260,13 @@ jobs: TargetFolder: '$(artifactsDir)\E2ETests\TestData' condition: succeededOrFailed() + - task: CopyFiles@2 + displayName: 'Copy LocalhostWebServer' + inputs: + SourceFolder: '$(buildOutDir)\LocalhostWebServer' + TargetFolder: '$(artifactsDir)\E2ETests\LocalhostWebServer' + condition: succeededOrFailed() + - task: CopyFiles@2 displayName: 'Copy Files: WinGetUtilInterop.UnitTests' inputs: @@ -390,6 +397,18 @@ jobs: condition: always() steps: + - task: DownloadSecureFile@1 + name: AppInstallerTest + displayName: 'Download Source Package Certificate' + inputs: + secureFile: 'AppInstallerTest.pfx' + + - task: DownloadSecureFile@1 + name: HTTPSDevCert + displayName: 'Download Kestrel Certificate' + inputs: + secureFile: 'HTTPSDevCertV2.pfx' + - task: DownloadPipelineArtifact@2 displayName: 'Download Build Artifacts' @@ -407,6 +426,18 @@ jobs: Contents: '**\*' TargetFolder: '$(Build.ArtifactStagingDirectory)' + - task: PowerShell@2 + displayName: Install Root Certificate + inputs: + filePath: '$(Build.SourcesDirectory)\src\LocalhostWebServer\InstallDevCert.ps1' + arguments: '-pfxpath $(HTTPSDevCert.secureFilePath) -password microsoft' + + - task: PowerShell@2 + displayName: Launch LocalhostWebServer + inputs: + filePath: '$(Build.SourcesDirectory)\src\LocalhostWebServer\Run-LocalhostWebServer.ps1' + arguments: '-BuildRoot $(Pipeline.Workspace)\Build.x64release\E2ETests\LocalhostWebServer -StaticFileRoot $(Pipeline.Workspace)\Build.x64release\E2ETests\TestLocalIndex -CertPath $(HTTPSDevCert.secureFilePath) -CertPassword microsoft' + - task: PublishPipelineArtifact@1 displayName: Publish PowerShell Module Artifacts inputs: From cb1c0e9e8823dc7679c9c4d06d302b00ac3ea171 Mon Sep 17 00:00:00 2001 From: Ruben Guerrero Samaniego Date: Wed, 2 Aug 2023 15:18:54 -0700 Subject: [PATCH 03/15] pester --- azure-pipelines.yml | 22 +++++++++++++------ src/PowerShell/tests/RunTests.ps1 | 36 +++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 7 deletions(-) create mode 100644 src/PowerShell/tests/RunTests.ps1 diff --git a/azure-pipelines.yml b/azure-pipelines.yml index d23eb94f43..0448654d6a 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -426,19 +426,27 @@ jobs: Contents: '**\*' TargetFolder: '$(Build.ArtifactStagingDirectory)' - - task: PowerShell@2 + - pwsh: .\InstallDevCert.ps1 -pfxpath $(HTTPSDevCert.secureFilePath) -password microsoft + workingDirectory: $(Build.SourcesDirectory)\src\LocalhostWebServer displayName: Install Root Certificate - inputs: - filePath: '$(Build.SourcesDirectory)\src\LocalhostWebServer\InstallDevCert.ps1' - arguments: '-pfxpath $(HTTPSDevCert.secureFilePath) -password microsoft' - - task: PowerShell@2 + - pwsh: .\Run-LocalhostWebServer.ps1 -BuildRoot $(Pipeline.Workspace)\Build.x64release\E2ETests\LocalhostWebServer -StaticFileRoot $(Pipeline.Workspace)\Build.x64release\E2ETests\TestLocalIndex -CertPath $(HTTPSDevCert.secureFilePath) -CertPassword microsoft + workingDirectory: $(Build.SourcesDirectory)\src\LocalhostWebServer displayName: Launch LocalhostWebServer + + - pwsh: .\RunTests.ps1 -testModulesPath $(Build.ArtifactStagingDirectory) -outputPath $(Pipeline.Workspace)\PesterTest -packageLayoutPath $(Pipeline.Workspace)\Build.x64release\DevPackage + workingDirectory: $(Build.SourcesDirectory)\Tools\ + displayName: Run Tests + + - task: PublishTestResults@2 + displayName: Publish Pester Test Results inputs: - filePath: '$(Build.SourcesDirectory)\src\LocalhostWebServer\Run-LocalhostWebServer.ps1' - arguments: '-BuildRoot $(Pipeline.Workspace)\Build.x64release\E2ETests\LocalhostWebServer -StaticFileRoot $(Pipeline.Workspace)\Build.x64release\E2ETests\TestLocalIndex -CertPath $(HTTPSDevCert.secureFilePath) -CertPassword microsoft' + testResultsFormat: 'NUnit' + testResultsFiles: '$(Pipeline.Workspace)\PesterTest\TestsPester*.xml' + failTaskOnFailedTests: true - task: PublishPipelineArtifact@1 displayName: Publish PowerShell Module Artifacts inputs: targetPath: '$(Build.ArtifactStagingDirectory)' + condition: succeededOrFailed() diff --git a/src/PowerShell/tests/RunTests.ps1 b/src/PowerShell/tests/RunTests.ps1 new file mode 100644 index 0000000000..d7c246e9da --- /dev/null +++ b/src/PowerShell/tests/RunTests.ps1 @@ -0,0 +1,36 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +[CmdletBinding()] +param( + [string]$testModulesPath, + [string]$outputPath, + [string]$packageLayoutPath, +) + +# This updates pester not always necessary but worth noting +Install-Module -Name Pester -Force -SkipPublisherCheck +Import-Module Pester + +$env:PSModulePath += ";$testModulesPath" + +if (-not Test-Path $outputPath) +{ + New-Item -Path $outputPath -ItemType Directory +} + +# Register the package +if (-not [System.String]::IsNullOrEmpty($packageLayoutPath)) +{ + $local:packageManifestPath = Join-Path $packageLayoutPath "AppxManifest.xml" + + Add-AppxPackage -Register $local:packageManifestPath + + # Configure crash dump and log file settings + $local:settingsExport = ConvertFrom-Json (wingetdev.exe settings export) + $local:settingsFilePath = $local:settingsExport.userSettingsFile + $local:settingsFileContent = ConvertTo-Json @{ debugging= @{ enableSelfInitiatedMinidump=$true ; keepAllLogFiles=$true } } + + Set-Content -Path $local:settingsFilePath -Value $local:settingsFileContent +} + +Invoke-Pester -Script $PSScriptRoot\Microsoft.WinGet.Client.Tests.ps1 -OutputFile $outputPath\TestsPester.WinGetClient.XML -OutputFormat NUnitXML From 888a3db77f8faa2545812533aba7dc0e01ab82c5 Mon Sep 17 00:00:00 2001 From: Ruben Guerrero Samaniego Date: Wed, 2 Aug 2023 16:31:46 -0700 Subject: [PATCH 04/15] Fix --- azure-pipelines.yml | 10 +++++++++- src/PowerShell/tests/Microsoft.WinGet.Client.Tests.ps1 | 8 ++++---- src/PowerShell/tests/RunTests.ps1 | 10 +++++++--- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 0448654d6a..11b448dc08 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -56,6 +56,7 @@ jobs: variables: BuildVer: $[counter(dependencies.GetReleaseTag.outputs['GetTag.tag'], 1)] buildOutDir: $(Build.SourcesDirectory)\src\$(buildPlatform)\$(buildConfiguration) + buildOutDirAnyCpu: $(Build.SourcesDirectory)\src\AnyCPU\$(buildConfiguration) artifactsDir: $(Build.ArtifactStagingDirectory)\$(buildPlatform) packageLayoutDir: $(Build.BinariesDirectory)\WingetPackageLayout @@ -342,6 +343,13 @@ jobs: TargetFolder: '$(artifactsDir)\PowerShell' condition: succeededOrFailed() + - task: CopyFiles@2 + displayName: 'Copy PowerShell AnCPU Module Files' + inputs: + SourceFolder: '$(buildOutDirAnyCpu)\PowerShell' + TargetFolder: '$(artifactsDir)\PowerShell' + condition: succeededOrFailed() + - task: CopyFiles@2 displayName: 'Copy Dev Package (Loose Files)' inputs: @@ -442,7 +450,7 @@ jobs: displayName: Publish Pester Test Results inputs: testResultsFormat: 'NUnit' - testResultsFiles: '$(Pipeline.Workspace)\PesterTest\TestsPester*.xml' + testResultsFiles: '$(Pipeline.Workspace)\PesterTest\Test*.xml' failTaskOnFailedTests: true - task: PublishPipelineArtifact@1 diff --git a/src/PowerShell/tests/Microsoft.WinGet.Client.Tests.ps1 b/src/PowerShell/tests/Microsoft.WinGet.Client.Tests.ps1 index c360834737..1574f2f3ba 100644 --- a/src/PowerShell/tests/Microsoft.WinGet.Client.Tests.ps1 +++ b/src/PowerShell/tests/Microsoft.WinGet.Client.Tests.ps1 @@ -138,13 +138,13 @@ Describe 'Install|Update|Uninstall-WinGetPackage' { AfterAll { # Uninstall all test packages after each for proper cleanup. - $testExe = Get-WinGetPackage -Id AppInstallerTest.TestExeInstaller + $testExe = Get-WinGetPackage -Id AppInstallerTest.TestExeInstaller -MatchOption Equals if ($testExe.Count -gt 0) { Uninstall-WinGetPackage -Id AppInstallerTest.TestExeInstaller - } + } - $testPortable = Get-WinGetPackage -Id AppInstallerTest.TestPortableExe + $testPortable = Get-WinGetPackage -Id AppInstallerTest.TestPortableExe -MatchOption Equals if ($testPortable.Count -gt 0) { Uninstall-WinGetPackage -Id AppInstallerTest.TestPortableExe @@ -197,5 +197,5 @@ Describe 'Get-WinGetPackage' { AfterAll { # Source Remove requires admin privileges, this will only execute successfully in an elevated PowerShell. - Start-Process wingetdev source remove 'TestSource' + Start-Process -FilePath "wingetdev" -ArgumentList "source remove TestSource" } \ No newline at end of file diff --git a/src/PowerShell/tests/RunTests.ps1 b/src/PowerShell/tests/RunTests.ps1 index d7c246e9da..2897e4a622 100644 --- a/src/PowerShell/tests/RunTests.ps1 +++ b/src/PowerShell/tests/RunTests.ps1 @@ -4,7 +4,7 @@ param( [string]$testModulesPath, [string]$outputPath, - [string]$packageLayoutPath, + [string]$packageLayoutPath ) # This updates pester not always necessary but worth noting @@ -13,10 +13,14 @@ Import-Module Pester $env:PSModulePath += ";$testModulesPath" -if (-not Test-Path $outputPath) +if (-not (Test-Path $outputPath)) { New-Item -Path $outputPath -ItemType Directory } +else +{ + Remove-Item $outputPath\* -Recurse -Force +} # Register the package if (-not [System.String]::IsNullOrEmpty($packageLayoutPath)) @@ -33,4 +37,4 @@ if (-not [System.String]::IsNullOrEmpty($packageLayoutPath)) Set-Content -Path $local:settingsFilePath -Value $local:settingsFileContent } -Invoke-Pester -Script $PSScriptRoot\Microsoft.WinGet.Client.Tests.ps1 -OutputFile $outputPath\TestsPester.WinGetClient.XML -OutputFormat NUnitXML +Invoke-Pester -Script $PSScriptRoot\Microsoft.WinGet.Client.Tests.ps1 -OutputFile $outputPath\Tests-WinGetClient.XML -OutputFormat NUnitXML From 4a118384e36d0d0a26157af84c19b97c49b3fe61 Mon Sep 17 00:00:00 2001 From: Ruben Guerrero Samaniego Date: Wed, 2 Aug 2023 18:16:44 -0700 Subject: [PATCH 05/15] Port tests --- azure-pipelines.yml | 6 +- .../tests/Microsoft.WinGet.Client.Tests.ps1 | 213 +++++++++++++++++- src/PowerShell/tests/RunTests.ps1 | 5 +- 3 files changed, 214 insertions(+), 10 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 11b448dc08..13cf4f88a6 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -434,9 +434,11 @@ jobs: Contents: '**\*' TargetFolder: '$(Build.ArtifactStagingDirectory)' - - pwsh: .\InstallDevCert.ps1 -pfxpath $(HTTPSDevCert.secureFilePath) -password microsoft - workingDirectory: $(Build.SourcesDirectory)\src\LocalhostWebServer + - task: PowerShell@2 displayName: Install Root Certificate + inputs: + filePath: '$(Build.SourcesDirectory)\src\LocalhostWebServer\InstallDevCert.ps1' + arguments: '-pfxpath $(HTTPSDevCert.secureFilePath) -password microsoft' - pwsh: .\Run-LocalhostWebServer.ps1 -BuildRoot $(Pipeline.Workspace)\Build.x64release\E2ETests\LocalhostWebServer -StaticFileRoot $(Pipeline.Workspace)\Build.x64release\E2ETests\TestLocalIndex -CertPath $(HTTPSDevCert.secureFilePath) -CertPassword microsoft workingDirectory: $(Build.SourcesDirectory)\src\LocalhostWebServer diff --git a/src/PowerShell/tests/Microsoft.WinGet.Client.Tests.ps1 b/src/PowerShell/tests/Microsoft.WinGet.Client.Tests.ps1 index 1574f2f3ba..8d247c6ebb 100644 --- a/src/PowerShell/tests/Microsoft.WinGet.Client.Tests.ps1 +++ b/src/PowerShell/tests/Microsoft.WinGet.Client.Tests.ps1 @@ -9,15 +9,16 @@ #> BeforeAll { + $settingsFilePath = (ConvertFrom-Json (wingetdev.exe settings export)).userSettingsFile + # Source Add requires admin privileges, this will only execute successfully in an elevated PowerShell. - wingetdev source add 'TestSource' 'https://localhost:5001/TestKit/' + #wingetdev source add 'TestSource' 'https://localhost:5001/TestKit/' Import-Module Microsoft.WinGet.Client - # TODO: - # wingetdev settings export, parse to get settings file. - # Function that modified the file (just check in json files) - # test that calls Get-WinGetSettings and compares. - # Investigate server not released? + function SetWinGetSettingsHelper($settings) { + $content = ConvertTo-Json $settings -Depth 4 + Set-Content -Path $settingsFilePath -Value $content + } } Describe 'Get-WinGetSource' { @@ -153,7 +154,7 @@ Describe 'Install|Update|Uninstall-WinGetPackage' { } Describe 'Get-WinGetPackage' { - + It 'Install by Id' { $result = Install-WinGetPackage -Id AppInstallerTest.TestExeInstaller -Version '1.0.0.0' @@ -195,6 +196,204 @@ Describe 'Get-WinGetPackage' { } } +Describe 'Get-WinGetUserSettings' { + + It 'Get settings' { + $ogSettings = @{ visual= @{ progressBar="rainbow"} ; experimentalFeatures= @{experimentalArg=$false ; experimentalCmd=$true}} + SetWinGetSettingsHelper $ogSettings + + $userSettings = Get-WinGetUserSettings + $userSettings | Should -Not -BeNullOrEmpty -ErrorAction Stop + $userSettings.Count | Should -Be 2 + $userSettings.visual.progressBar | Should -Be 'rainbow' + $userSettings.experimentalFeatures.experimentalArg | Should -Be $false + $userSettings.experimentalFeatures.experimentalCmd | Should -Be $true + } + + It 'Get settings. Bad json file' { + Set-Content -Path $settingsFilePath -Value "Hi, im not a json. Thank you, Test." + { Get-WinGetUserSettings } | Should -Throw + } +} + +Describe 'Test-WinGetUserSettings' { + + It 'Bad json file' { + Set-Content -Path $settingsFilePath -Value "Hi, im not a json. Thank you, Test." + + $inputSettings = @{ visual= @{ progressBar="retro"} } + Test-WinGetUserSettings -UserSettings $inputSettings | Should -Be $false + } + + It 'Equal' { + $ogSettings = @{ visual= @{ progressBar="retro"} ; experimentalFeatures= @{experimentalArg=$false ; experimentalCmd=$true}} + SetWinGetSettingsHelper $ogSettings + + Test-WinGetUserSettings -UserSettings $ogSettings | Should -Be $true + } + + It 'Equal. Ignore schema' { + Set-Content -Path $settingsFilePath -Value '{ "$schema": "https://aka.ms/winget-settings.schema.json", "visual": { "progressBar": "retro" } }' + + $inputSettings = @{ visual= @{ progressBar="retro"} } + Test-WinGetUserSettings -UserSettings $inputSettings | Should -Be $true + } + + It 'Not Equal string' { + $ogSettings = @{ visual= @{ progressBar="rainbow"} ; experimentalFeatures= @{experimentalArg=$false ; experimentalCmd=$true}} + SetWinGetSettingsHelper $ogSettings + + $inputSettings = @{ visual= @{ progressBar="retro"} ; experimentalFeatures= @{experimentalArg=$false ; experimentalCmd=$true}} + Test-WinGetUserSettings -UserSettings $inputSettings | Should -Be $false + } + + It 'Not Equal bool' { + $ogSettings = @{ visual= @{ progressBar="rainbow"} ; experimentalFeatures= @{experimentalArg=$true ; experimentalCmd=$true}} + SetWinGetSettingsHelper $ogSettings + + $inputSettings = @{ visual= @{ progressBar="rainbow"} ; experimentalFeatures= @{experimentalArg=$false ; experimentalCmd=$true}} + Test-WinGetUserSettings -UserSettings $inputSettings | Should -Be $false + } + + It 'Not Equal. More settings' { + $ogSettings = @{ visual= @{ progressBar="rainbow"} ; experimentalFeatures= @{experimentalArg=$false ; experimentalCmd=$true }} + SetWinGetSettingsHelper $ogSettings + + $inputSettings = @{ visual= @{ progressBar="rainbow"} ; experimentalFeatures= @{experimentalArg=$false }} + Test-WinGetUserSettings -UserSettings $inputSettings | Should -Be $false + } + + It 'Not Equal. More settings input' { + $ogSettings = @{ visual= @{ progressBar="rainbow"} ; experimentalFeatures= @{experimentalArg=$false ; }} + SetWinGetSettingsHelper $ogSettings + + $inputSettings = @{ visual= @{ progressBar="rainbow"} ; experimentalFeatures= @{experimentalArg=$false ; experimentalCmd=$true}} + Test-WinGetUserSettings -UserSettings $inputSettings | Should -Be $false + } + + It 'Equal IgnoreNotSet' { + $ogSettings = @{ visual= @{ progressBar="retro"} ; experimentalFeatures= @{experimentalArg=$false ; experimentalCmd=$true}} + SetWinGetSettingsHelper $ogSettings + + Test-WinGetUserSettings -UserSettings $ogSettings -IgnoreNotSet | Should -Be $true + } + + It 'Equal IgnoreNotSet. More settings' { + $ogSettings = @{ visual= @{ progressBar="rainbow"} ; experimentalFeatures= @{experimentalArg=$false ; experimentalCmd=$true }} + SetWinGetSettingsHelper $ogSettings + + $inputSettings = @{ visual= @{ progressBar="rainbow"} ; experimentalFeatures= @{experimentalArg=$false }} + Test-WinGetUserSettings -UserSettings $inputSettings -IgnoreNotSet | Should -Be $true + } + + It 'Not Equal IgnoreNotSet. More settings input' { + $ogSettings = @{ visual= @{ progressBar="rainbow"} ; experimentalFeatures= @{experimentalArg=$false ; }} + SetWinGetSettingsHelper $ogSettings + + $inputSettings = @{ visual= @{ progressBar="rainbow"} ; experimentalFeatures= @{experimentalArg=$false ; experimentalCmd=$true}} + Test-WinGetUserSettings -UserSettings $inputSettings -IgnoreNotSet | Should -Be $false + } + + It 'Not Equal bool IgnoreNotSet' { + $ogSettings = @{ visual= @{ progressBar="rainbow"} ; experimentalFeatures= @{experimentalArg=$true ; experimentalCmd=$true}} + SetWinGetSettingsHelper $ogSettings + + $inputSettings = @{ visual= @{ progressBar="rainbow"} ; experimentalFeatures= @{experimentalArg=$false ; experimentalCmd=$true}} + Test-WinGetUserSettings -UserSettings $inputSettings -IgnoreNotSet | Should -Be $false + } + + It 'Not Equal array IgnoreNotSet' { + $ogSettings = @{ installBehavior= @{ preferences= @{ architectures = @("x86", "x64")} }} + SetWinGetSettingsHelper $ogSettings + + $inputSettings = @{ installBehavior= @{ preferences= @{ architectures = @("x86", "arm64")} }} + Test-WinGetUserSettings -UserSettings $inputSettings -IgnoreNotSet | Should -Be $false + } + + It 'Not Equal wrong type IgnoreNotSet' { + $ogSettings = @{ visual= @{ progressBar="rainbow"} ; experimentalFeatures= @{experimentalArg=$true ; experimentalCmd=$true}} + SetWinGetSettingsHelper $ogSettings + + $inputSettings = @{ visual= @{ progressBar="rainbow"} ; experimentalFeatures= @{experimentalArg=4 ; experimentalCmd=$true}} + Test-WinGetUserSettings -UserSettings $inputSettings -IgnoreNotSet | Should -Be $false + } + + AfterAll { + SetWinGetSettingsHelper @{ debugging= @{ enableSelfInitiatedMinidump=$true ; keepAllLogFiles=$true } } + } +} + +Describe 'Set-WinGetUserSettings' { + + It 'Overwrites' { + $ogSettings = @{ source= @{ autoUpdateIntervalInMinutes=3}} + SetWinGetSettingsHelper $ogSettings + + $inputSettings = @{ visual= @{ progressBar="rainbow"} ; experimentalFeatures= @{experimentalArg=$true ; experimentalCmd=$false}} + $result = Set-WinGetUserSettings -UserSettings $inputSettings + + $result | Should -Not -BeNullOrEmpty -ErrorAction Stop + $result.'$schema' | Should -Not -BeNullOrEmpty + $result.visual | Should -Not -BeNullOrEmpty -ErrorAction Stop + $result.visual.progressBar | Should -Be "rainbow" + $result.experimentalFeatures | Should -Not -BeNullOrEmpty -ErrorAction Stop + $result.experimentalFeatures.experimentalArg | Should -Be $true + $result.experimentalFeatures.experimentalCmd | Should -Be $false + $result.source | Should -BeNullOrEmpty + } + + It 'Merge' { + $ogSettings = @{ source= @{ autoUpdateIntervalInMinutes=3}} + SetWinGetSettingsHelper $ogSettings + + $inputSettings = @{ visual= @{ progressBar="rainbow"} ; experimentalFeatures= @{experimentalArg=$true ; experimentalCmd=$false}} + $result = Set-WinGetUserSettings -UserSettings $inputSettings -Merge + + $result | Should -Not -BeNullOrEmpty -ErrorAction Stop + $result.'$schema' | Should -Not -BeNullOrEmpty + $result.visual | Should -Not -BeNullOrEmpty -ErrorAction Stop + $result.visual.progressBar | Should -Be "rainbow" + $result.experimentalFeatures | Should -Not -BeNullOrEmpty -ErrorAction Stop + $result.experimentalFeatures.experimentalArg | Should -Be $true + $result.experimentalFeatures.experimentalCmd | Should -Be $false + $result.source | Should -Not -BeNullOrEmpty -ErrorAction Stop + $result.source.autoUpdateIntervalInMinutes | Should -Be 3 + } + + It 'Schema.' { + Set-Content -Path $settingsFilePath -Value '{ "$schema": "https://aka.ms/winget-settings.schema.json", "visual": { "progressBar": "retro" } }' + + $inputSettings = @{ visual= @{ progressBar="retro"} } + $result = Set-WinGetUserSettings -UserSettings $inputSettings + + $result | Should -Not -BeNullOrEmpty -ErrorAction Stop + $result.'$schema' | Should -Not -BeNullOrEmpty + $result.visual.progressBar | Should -Be "retro" + } + + It 'Overwrites Bad json file' { + Set-Content -Path $settingsFilePath -Value "Hi, im not a json. Thank you, Test." + + $inputSettings = @{ visual= @{ progressBar="retro"} } + $result = Set-WinGetUserSettings -UserSettings $inputSettings + + $result | Should -Not -BeNullOrEmpty -ErrorAction Stop + $result.'$schema' | Should -Not -BeNullOrEmpty + $result.visual.progressBar | Should -Be "retro" + } + + It 'Overwrites Bad json file' { + Set-Content -Path $settingsFilePath -Value "Hi, im not a json. Thank you, Test." + + $inputSettings = @{ visual= @{ progressBar="retro"} } + { Set-WinGetUserSettings -UserSettings $inputSettings -Merge } | Should -Throw + } + + AfterAll { + SetWinGetSettingsHelper @{ debugging= @{ enableSelfInitiatedMinidump=$true ; keepAllLogFiles=$true } } + } +} + AfterAll { # Source Remove requires admin privileges, this will only execute successfully in an elevated PowerShell. Start-Process -FilePath "wingetdev" -ArgumentList "source remove TestSource" diff --git a/src/PowerShell/tests/RunTests.ps1 b/src/PowerShell/tests/RunTests.ps1 index 2897e4a622..732362fef3 100644 --- a/src/PowerShell/tests/RunTests.ps1 +++ b/src/PowerShell/tests/RunTests.ps1 @@ -11,7 +11,10 @@ param( Install-Module -Name Pester -Force -SkipPublisherCheck Import-Module Pester -$env:PSModulePath += ";$testModulesPath" +if (-not [System.String]::IsNullOrEmpty($testModulesPath)) +{ + $env:PSModulePath += ";$testModulesPath" +} if (-not (Test-Path $outputPath)) { From 5700d095f4a940d0ff7ee20a3a3694cba44ea70a Mon Sep 17 00:00:00 2001 From: Ruben Guerrero Samaniego Date: Thu, 3 Aug 2023 10:33:28 -0700 Subject: [PATCH 06/15] path --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 13cf4f88a6..e0b349ba82 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -445,7 +445,7 @@ jobs: displayName: Launch LocalhostWebServer - pwsh: .\RunTests.ps1 -testModulesPath $(Build.ArtifactStagingDirectory) -outputPath $(Pipeline.Workspace)\PesterTest -packageLayoutPath $(Pipeline.Workspace)\Build.x64release\DevPackage - workingDirectory: $(Build.SourcesDirectory)\Tools\ + workingDirectory: $(Build.SourcesDirectory)\src\PowerShell\tests\ displayName: Run Tests - task: PublishTestResults@2 From db885e97c2b9ce2e6338e02459cad6646219ff59 Mon Sep 17 00:00:00 2001 From: Ruben Guerrero Samaniego Date: Thu, 3 Aug 2023 11:13:11 -0700 Subject: [PATCH 07/15] Remove tests --- .../PowerShell/WinGetClientModule.cs | 986 ------------------ .../tests/Microsoft.WinGet.Client.Tests.ps1 | 10 +- 2 files changed, 9 insertions(+), 987 deletions(-) diff --git a/src/AppInstallerCLIE2ETests/PowerShell/WinGetClientModule.cs b/src/AppInstallerCLIE2ETests/PowerShell/WinGetClientModule.cs index c28705ba13..44810db550 100644 --- a/src/AppInstallerCLIE2ETests/PowerShell/WinGetClientModule.cs +++ b/src/AppInstallerCLIE2ETests/PowerShell/WinGetClientModule.cs @@ -7,10 +7,8 @@ namespace AppInstallerCLIE2ETests.PowerShell { using System; - using System.Collections; using System.Diagnostics; using System.Linq; - using System.Management.Automation; using AppInstallerCLIE2ETests.Helpers; using NUnit.Framework; @@ -22,8 +20,6 @@ namespace AppInstallerCLIE2ETests.PowerShell [Category("PowerShell")] public class WinGetClientModule { - // TODO: Consider using Pester framework for conducting more extensive PowerShell module tests or move to Powershell Host. - /// /// Set setup. /// @@ -74,62 +70,6 @@ public void AssertServerShutdownAfterExecution() Assert.IsTrue(serverProcessExit, $"{Constants.WindowsPackageManagerServer} failed to terminate after creating COM object."); } - /// - /// Test Get-WinGetSource. - /// - [Test] - public void GetWinGetSource() - { - if (!Environment.Is64BitProcess) - { - return; - } - - var getSourceResult = TestCommon.RunPowerShellCoreCommandWithResult(Constants.GetSourceCmdlet, $"-Name {Constants.TestSourceName}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, getSourceResult.ExitCode, $"ExitCode: {getSourceResult.ExitCode} Failed with the following output: {getSourceResult.StdOut}, {getSourceResult.StdErr}"); - Assert.IsTrue(getSourceResult.StdOut.Contains($"{Constants.TestSourceName}")); - } - - /// - /// Tests WinGetPackage cmdlets. - /// Find-WinGetPackage. - /// Install-WinGetPackage. - /// Get-WinGetPackage. - /// Update-WinGetPackage. - /// Uninstall-WinGetPackage. - /// - [Test] - public void WinGetPackageCmdlets() - { - if (!Environment.Is64BitProcess) - { - return; - } - - // TODO: It would be nice to add an installer to be use ONLY by the PowerShell cmdlets for E2E to avoid conflicts and bad - // cleanups in other tests. - var result = TestCommon.RunPowerShellCoreCommandWithResult(Constants.FindCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode, $"ExitCode: {result.ExitCode} Failed with the following output: {result.StdOut}; {result.StdErr}"); - Assert.IsTrue(result.StdOut.Contains("TestExeInstaller")); - - var installResult = TestCommon.RunPowerShellCoreCommandWithResult(Constants.InstallCmdlet, $"-Id {Constants.ExeInstallerPackageId} -Version 1.0.0.0"); - Assert.AreEqual(Constants.ErrorCode.S_OK, installResult.ExitCode, $"Failed with the following output: {installResult.StdOut}"); - - var updateResult = TestCommon.RunPowerShellCoreCommandWithResult(Constants.UpdateCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, updateResult.ExitCode, $"Failed with the following output: {updateResult.StdOut}"); - - var getResult = TestCommon.RunPowerShellCoreCommandWithResult(Constants.GetCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, getResult.ExitCode, $"Failed with the following output: {getResult.StdOut}"); - - var uninstallResult = TestCommon.RunPowerShellCoreCommandWithResult(Constants.UninstallCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, uninstallResult.ExitCode, $"Failed with the following output: {uninstallResult.StdOut}"); - - Assert.IsTrue(!string.IsNullOrEmpty(installResult.StdOut)); - Assert.IsTrue(!string.IsNullOrEmpty(updateResult.StdOut)); - Assert.IsTrue(getResult.StdOut.Contains("2.0.0.0")); - Assert.IsTrue(!string.IsNullOrEmpty(uninstallResult.StdOut)); - } - /// /// There is a known issue where the server takes an abnormally long time to terminate after the E2E test pwsh processes finish execution. /// This test verifies that the server does indeed terminate within 5 minutes after running all of the cmdlets. @@ -154,932 +94,6 @@ public void VerifyServerTermination() Assert.IsTrue(serverProcessExit, $"{Constants.WindowsPackageManagerServer} failed to terminate after creating COM object."); } - /// - /// Test Get-WinGetUserSettings. - /// - [Test] - public void GetWinGetUserSettings() - { - var ogSettings = @"{ - ""visual"": { - ""progressBar"": ""rainbow"" - }, - ""experimentalFeatures"": { - ""experimentalArg"": false, - ""experimentalCmd"": true - } -}"; - - WinGetSettingsHelper.SetWingetSettings(ogSettings); - - using var powerShellHost = new PowerShellHost(); - var result = powerShellHost.PowerShell - .AddCommand("Get-WinGetUserSettings") - .Invoke(); - - Assert.That(result, Has.Exactly(1).Items); - Assert.IsInstanceOf(result[0].BaseObject); - } - - /// - /// Test Get-WinGetUserSettings when the local settings file is not a json. - /// - [Test] - public void GetWinGetUserSettings_BadJsonFile() - { - WinGetSettingsHelper.SetWingetSettings("Hi, im not a json. Thank you, Test."); - - var inputSettings = new Hashtable() - { - { - "visual", - new Hashtable() - { - { "progressBar", "retro" }, - } - }, - }; - - using var powerShellHost = new PowerShellHost(); - - var cmdletException = Assert.Throws( - () => powerShellHost.PowerShell - .AddCommand("Get-WinGetUserSettings") - .Invoke()); - - // If we reference Microsoft.WinGet.Client to this project PowerShell host fails with - // System.Management.Automation.CmdletInvocationException : Operation is not supported on this platform. (0x80131539) - // System.PlatformNotSupportedException : Operation is not supported on this platform. (0x80131539) - // trying to load the runspace. This is most probably because the same dll is already loaded. - // Check the type the long way. - dynamic exception = cmdletException.InnerException; - Assert.AreEqual(exception.GetType().ToString(), "Newtonsoft.Json.JsonReaderException"); - } - - /// - /// Test Test-WinGetUserSettings. Settings are equal. - /// - [Test] - public void TestWinGetUserSettings_Equal() - { - var ogSettings = new Hashtable() - { - { - "visual", - new Hashtable() - { - { "progressBar", "retro" }, - } - }, - { - "experimentalFeatures", - new Hashtable() - { - { "experimentalArg", false }, - { "experimentalCmd", true }, - } - }, - }; - - WinGetSettingsHelper.SetWingetSettings(ogSettings); - - using var powerShellHost = new PowerShellHost(); - var result = powerShellHost.PowerShell - .AddCommand("Test-WinGetUserSettings") - .AddParameter("UserSettings", ogSettings) - .Invoke(); - - Assert.That(result, Has.Exactly(1).Items); - Assert.IsInstanceOf(result[0].BaseObject); - Assert.IsTrue((bool)result[0].BaseObject); - } - - /// - /// Test Test-WinGetUserSettings. Settings are equal. Ignore schema. - /// - [Test] - public void TestWinGetUserSettings_Equal_Schema() - { - var ogSettings = new Hashtable() - { - { - "$schema", - "https://aka.ms/winget-settings.schema.json" - }, - { - "visual", - new Hashtable() - { - { "progressBar", "retro" }, - } - }, - { - "experimentalFeatures", - new Hashtable() - { - { "experimentalArg", false }, - { "experimentalCmd", true }, - } - }, - }; - - WinGetSettingsHelper.SetWingetSettings(ogSettings); - - var inputSettings = new Hashtable() - { - { - "visual", - new Hashtable() - { - { "progressBar", "retro" }, - } - }, - { - "experimentalFeatures", - new Hashtable() - { - { "experimentalArg", false }, - { "experimentalCmd", true }, - } - }, - }; - - using var powerShellHost = new PowerShellHost(); - var result = powerShellHost.PowerShell - .AddCommand("Test-WinGetUserSettings") - .AddParameter("UserSettings", inputSettings) - .Invoke(); - - Assert.That(result, Has.Exactly(1).Items); - Assert.IsInstanceOf(result[0].BaseObject); - Assert.IsTrue((bool)result[0].BaseObject); - } - - /// - /// Test Test-WinGetUserSettings. Settings are not equal. - /// - [Test] - public void TestWinGetUserSettings_NotEqual() - { - var ogSettings = new Hashtable() - { - { - "visual", - new Hashtable() - { - { "progressBar", "retro" }, - } - }, - { - "experimentalFeatures", - new Hashtable() - { - { "experimentalArg", false }, - { "experimentalCmd", true }, - } - }, - }; - - WinGetSettingsHelper.SetWingetSettings(ogSettings); - - var inputSettings = new Hashtable() - { - { - "visual", - new Hashtable() - { - { "progressBar", "rainbow" }, - } - }, - { - "experimentalFeatures", - new Hashtable() - { - { "experimentalArg", false }, - { "experimentalCmd", true }, - } - }, - }; - - using var powerShellHost = new PowerShellHost(); - var result = powerShellHost.PowerShell - .AddCommand("Test-WinGetUserSettings") - .AddParameter("UserSettings", inputSettings) - .Invoke(); - - Assert.That(result, Has.Exactly(1).Items); - Assert.IsInstanceOf(result[0].BaseObject); - Assert.IsFalse((bool)result[0].BaseObject); - } - - /// - /// Test Test-WinGetUserSettings. Local settings has more properties. - /// - [Test] - public void TestWinGetUserSettings_MoreSettingsLocal() - { - var ogSettings = new Hashtable() - { - { - "visual", - new Hashtable() - { - { "progressBar", "retro" }, - } - }, - { - "experimentalFeatures", - new Hashtable() - { - { "experimentalArg", false }, - { "experimentalCmd", true }, - } - }, - }; - - WinGetSettingsHelper.SetWingetSettings(ogSettings); - - var inputSettings = new Hashtable() - { - { - "visual", - new Hashtable() - { - { "progressBar", "retro" }, - } - }, - { - "experimentalFeatures", - new Hashtable() - { - { "experimentalArg", false }, - } - }, - }; - - using var powerShellHost = new PowerShellHost(); - var result = powerShellHost.PowerShell - .AddCommand("Test-WinGetUserSettings") - .AddParameter("UserSettings", inputSettings) - .Invoke(); - - Assert.That(result, Has.Exactly(1).Items); - Assert.IsInstanceOf(result[0].BaseObject); - Assert.IsFalse((bool)result[0].BaseObject); - } - - /// - /// Test Test-WinGetUserSettings. Input has more properties. - /// - [Test] - public void TestWinGetUserSettings_MoreSettingsInput() - { - var ogSettings = new Hashtable() - { - { - "visual", - new Hashtable() - { - { "progressBar", "retro" }, - } - }, - { - "experimentalFeatures", - new Hashtable() - { - { "experimentalArg", false }, - } - }, - }; - - WinGetSettingsHelper.SetWingetSettings(ogSettings); - - var inputSettings = new Hashtable() - { - { - "visual", - new Hashtable() - { - { "progressBar", "retro" }, - } - }, - { - "experimentalFeatures", - new Hashtable() - { - { "experimentalArg", false }, - { "experimentalCmd", true }, - } - }, - }; - - using var powerShellHost = new PowerShellHost(); - var result = powerShellHost.PowerShell.AddCommand("Test-WinGetUserSettings") - .AddParameter("UserSettings", inputSettings) - .Invoke(); - - Assert.That(result, Has.Exactly(1).Items); - Assert.IsInstanceOf(result[0].BaseObject); - Assert.IsFalse((bool)result[0].BaseObject); - } - - /// - /// Test Test-WinGetUserSettings. IgnoreNotSet. - /// They are equal. - /// - [Test] - public void TestWinGetUserSettings_Equal_IgnoreNotSet() - { - var ogSettings = new Hashtable() - { - { - "visual", - new Hashtable() - { - { "progressBar", "retro" }, - } - }, - { - "experimentalFeatures", - new Hashtable() - { - { "experimentalArg", false }, - { "experimentalCmd", true }, - } - }, - }; - - WinGetSettingsHelper.SetWingetSettings(ogSettings); - - using var powerShellHost = new PowerShellHost(); - var result = powerShellHost.PowerShell - .AddCommand("Test-WinGetUserSettings") - .AddParameter("UserSettings", ogSettings) - .AddParameter("IgnoreNotSet") - .Invoke(); - - Assert.That(result, Has.Exactly(1).Items); - Assert.IsInstanceOf(result[0].BaseObject); - Assert.IsTrue((bool)result[0].BaseObject); - } - - /// - /// Test Test-WinGetUserSettings IgnoreNotSet. - /// Ignore comparing properties that are not set in the input. - /// - [Test] - public void TestWinGetUserSettings_MoreSettingsLocal_IgnoreNotSet() - { - var ogSettings = new Hashtable() - { - { - "visual", - new Hashtable() - { - { "progressBar", "retro" }, - } - }, - { - "experimentalFeatures", - new Hashtable() - { - { "experimentalArg", false }, - { "experimentalCmd", true }, - } - }, - }; - - WinGetSettingsHelper.SetWingetSettings(ogSettings); - - var inputSettings = new Hashtable() - { - { - "visual", - new Hashtable() - { - { "progressBar", "retro" }, - } - }, - { - "experimentalFeatures", - new Hashtable() - { - { "experimentalArg", false }, - } - }, - }; - - using var powerShellHost = new PowerShellHost(); - var result = powerShellHost.PowerShell - .AddCommand("Test-WinGetUserSettings") - .AddParameter("UserSettings", inputSettings) - .AddParameter("IgnoreNotSet") - .Invoke(); - - Assert.That(result, Has.Exactly(1).Items); - Assert.IsInstanceOf(result[0].BaseObject); - Assert.IsTrue((bool)result[0].BaseObject); - } - - /// - /// Test Test-WinGetUserSettings IgnoreNotSet. - /// Local settings doesnt have some properties. - /// - [Test] - public void TestWinGetUserSettings_MoreSettingsInput_IgnoreNotSet() - { - var ogSettings = new Hashtable() - { - { - "visual", - new Hashtable() - { - { "progressBar", "retro" }, - } - }, - { - "experimentalFeatures", - new Hashtable() - { - { "experimentalArg", false }, - } - }, - }; - - WinGetSettingsHelper.SetWingetSettings(ogSettings); - - var inputSettings = new Hashtable() - { - { - "visual", - new Hashtable() - { - { "progressBar", "retro" }, - } - }, - { - "experimentalFeatures", - new Hashtable() - { - { "experimentalArg", false }, - { "experimentalCmd", true }, - } - }, - }; - - using var powerShellHost = new PowerShellHost(); - var result = powerShellHost.PowerShell - .AddCommand("Test-WinGetUserSettings") - .AddParameter("UserSettings", inputSettings) - .AddParameter("IgnoreNotSet") - .Invoke(); - - Assert.That(result, Has.Exactly(1).Items); - Assert.IsInstanceOf(result[0].BaseObject); - Assert.IsFalse((bool)result[0].BaseObject); - } - - /// - /// Test Test-WinGetUserSettings IgnoreNotSet. - /// DeepEquals fails, but we should still fail at experimentalArg. - /// - [Test] - public void TestWinGetUserSettings_DifferentValue_IgnoreNotSet() - { - var ogSettings = new Hashtable() - { - { - "visual", - new Hashtable() - { - { "progressBar", "retro" }, - } - }, - { - "experimentalFeatures", - new Hashtable() - { - { "experimentalArg", false }, - } - }, - }; - - WinGetSettingsHelper.SetWingetSettings(ogSettings); - - var inputSettings = new Hashtable() - { - { - "visual", - new Hashtable() - { - { "progressBar", "retro" }, - } - }, - { - "experimentalFeatures", - new Hashtable() - { - { "experimentalArg", true }, - } - }, - }; - - using var powerShellHost = new PowerShellHost(); - var result = powerShellHost.PowerShell - .AddCommand("Test-WinGetUserSettings") - .AddParameter("UserSettings", inputSettings) - .AddParameter("IgnoreNotSet") - .Invoke(); - - Assert.That(result, Has.Exactly(1).Items); - Assert.IsInstanceOf(result[0].BaseObject); - Assert.IsFalse((bool)result[0].BaseObject); - } - - /// - /// Test Test-WinGetUserSettings IgnoreNotSet. - /// DeepEquals fails, but we should still fail at comparing the array. - /// - [Test] - public void TestWinGetUserSettings_ArrayDifferent_IgnoreNotSet() - { - var ogSettings = new Hashtable() - { - { - "installBehavior", - new Hashtable() - { - { - "preferences", - new Hashtable() - { - { "architectures", new string[] { "x64", "x86" } }, - } - }, - } - }, - }; - - WinGetSettingsHelper.SetWingetSettings(ogSettings); - - var inputSettings = new Hashtable() - { - { - "installBehavior", - new Hashtable() - { - { - "preferences", - new Hashtable() - { - { "architectures", new string[] { "x64", "arm64" } }, - } - }, - } - }, - }; - - using var powerShellHost = new PowerShellHost(); - var result = powerShellHost.PowerShell - .AddCommand("Test-WinGetUserSettings") - .AddParameter("UserSettings", inputSettings) - .AddParameter("IgnoreNotSet") - .Invoke(); - - Assert.That(result, Has.Exactly(1).Items); - Assert.IsInstanceOf(result[0].BaseObject); - Assert.IsFalse((bool)result[0].BaseObject); - } - - /// - /// Test Test-WinGetUserSettings IgnoreNotSet. - /// DeepEquals fails, but we should still fail at experimentalArg because is an int. - /// - [Test] - public void TestWinGetUserSettings_DifferentValueType_IgnoreNotSet() - { - var ogSettings = new Hashtable() - { - { - "visual", - new Hashtable() - { - { "progressBar", "retro" }, - } - }, - { - "experimentalFeatures", - new Hashtable() - { - { "experimentalArg", false }, - } - }, - }; - - WinGetSettingsHelper.SetWingetSettings(ogSettings); - - var inputSettings = new Hashtable() - { - { - "visual", - new Hashtable() - { - { "progressBar", "retro" }, - } - }, - { - "experimentalFeatures", - new Hashtable() - { - { "experimentalArg", 4 }, - } - }, - }; - - using var powerShellHost = new PowerShellHost(); - var result = powerShellHost.PowerShell - .AddCommand("Test-WinGetUserSettings") - .AddParameter("UserSettings", inputSettings) - .AddParameter("IgnoreNotSet") - .Invoke(); - - Assert.That(result, Has.Exactly(1).Items); - Assert.IsInstanceOf(result[0].BaseObject); - Assert.IsFalse((bool)result[0].BaseObject); - } - - /// - /// Test Test-WinGetUserSettings. - /// Settings file is not a json. - /// - [Test] - public void TestWinGetUserSettings_BadJsonFile() - { - WinGetSettingsHelper.SetWingetSettings("Hi, im not a json. Thank you, Test."); - - var inputSettings = new Hashtable() - { - { - "visual", - new Hashtable() - { - { "progressBar", "retro" }, - } - }, - }; - - using var powerShellHost = new PowerShellHost(); - var result = powerShellHost.PowerShell - .AddCommand("Test-WinGetUserSettings") - .AddParameter("UserSettings", inputSettings) - .Invoke(); - - Assert.That(result, Has.Exactly(1).Items); - Assert.IsInstanceOf(result[0].BaseObject); - Assert.IsFalse((bool)result[0].BaseObject); - } - - /// - /// Test Set-WinGetUserSettings. - /// - [Test] - public void SetWinGetUserSettings_Overwrite() - { - var ogSettings = new Hashtable() - { - { - "$schema", - "https://aka.ms/winget-settings.schema.json" - }, - { - "source", - new Hashtable() - { - { "autoUpdateIntervalInMinutes", 3 }, - } - }, - }; - - WinGetSettingsHelper.SetWingetSettings(ogSettings); - - var inputSettings = new Hashtable() - { - { - "visual", - new Hashtable() - { - { "progressBar", "retro" }, - } - }, - { - "experimentalFeatures", - new Hashtable() - { - { "experimentalArg", false }, - { "experimentalCmd", true }, - } - }, - }; - - using var powerShellHost = new PowerShellHost(); - var result = powerShellHost.PowerShell - .AddCommand("Set-WinGetUserSettings") - .AddParameter("UserSettings", inputSettings) - .Invoke(); - - Assert.That(result, Has.Exactly(1).Items); - Assert.IsInstanceOf(result[0].BaseObject); - var settingsResult = result[0].BaseObject as Hashtable; - - Assert.True(settingsResult.ContainsKey("$schema")); - Assert.False(settingsResult.ContainsKey("source")); - Assert.True(settingsResult.ContainsKey("experimentalFeatures")); - Assert.True(settingsResult.ContainsKey("visual")); - } - - /// - /// Test Set-WinGetUserSettings. Merge local settings with input. - /// - [Test] - public void SetWinGetUserSettings_Merge() - { - var ogSettings = new Hashtable() - { - { - "source", - new Hashtable() - { - { "autoUpdateIntervalInMinutes", 3 }, - } - }, - }; - - WinGetSettingsHelper.SetWingetSettings(ogSettings); - - var inputSettings = new Hashtable() - { - { - "visual", - new Hashtable() - { - { "progressBar", "retro" }, - } - }, - { - "experimentalFeatures", - new Hashtable() - { - { "experimentalArg", false }, - { "experimentalCmd", true }, - } - }, - }; - - using var powerShellHost = new PowerShellHost(); - var result = powerShellHost.PowerShell - .AddCommand("Set-WinGetUserSettings") - .AddParameter("UserSettings", inputSettings) - .AddParameter("Merge") - .Invoke(); - - Assert.That(result, Has.Exactly(1).Items); - Assert.IsInstanceOf(result[0].BaseObject); - var settingsResult = result[0].BaseObject as Hashtable; - - Assert.True(settingsResult.ContainsKey("$schema")); - Assert.True(settingsResult.ContainsKey("source")); - Assert.True(settingsResult.ContainsKey("experimentalFeatures")); - Assert.True(settingsResult.ContainsKey("visual")); - } - - /// - /// Test Set-WinGetUserSettings when the local settings file already have the schema property. It shouldn't - /// be added twice. - /// - [Test] - public void SetWinGetUserSettings_Schema() - { - var ogSettings = new Hashtable() - { - { - "$schema", - "https://aka.ms/winget-settings.schema.json" - }, - { - "source", - new Hashtable() - { - { "autoUpdateIntervalInMinutes", 3 }, - } - }, - }; - - WinGetSettingsHelper.SetWingetSettings(ogSettings); - - var inputSettings = new Hashtable() - { - { - "visual", - new Hashtable() - { - { "progressBar", "retro" }, - } - }, - { - "experimentalFeatures", - new Hashtable() - { - { "experimentalArg", false }, - { "experimentalCmd", true }, - } - }, - }; - - using var powerShellHost = new PowerShellHost(); - var result = powerShellHost.PowerShell - .AddCommand("Set-WinGetUserSettings") - .AddParameter("UserSettings", inputSettings) - .Invoke(); - - Assert.That(result, Has.Exactly(1).Items); - Assert.IsInstanceOf(result[0].BaseObject); - var settingsResult = result[0].BaseObject as Hashtable; - - Assert.True(settingsResult.ContainsKey("$schema")); - Assert.False(settingsResult.ContainsKey("source")); - Assert.True(settingsResult.ContainsKey("experimentalFeatures")); - } - - /// - /// Test Set-WinGetUserSettings when the local settings file is not a json. - /// - [Test] - public void SetWinGetUserSettings_BadJsonFile() - { - WinGetSettingsHelper.SetWingetSettings("Hi, im not a json. Thank you, Test."); - - var inputSettings = new Hashtable() - { - { - "visual", - new Hashtable() - { - { "progressBar", "retro" }, - } - }, - }; - - using var powerShellHost = new PowerShellHost(); - var result = powerShellHost.PowerShell - .AddCommand("Set-WinGetUserSettings") - .AddParameter("UserSettings", inputSettings) - .Invoke(); - - Assert.That(result, Has.Exactly(1).Items); - Assert.IsInstanceOf(result[0].BaseObject); - var settingsResult = result[0].BaseObject as Hashtable; - - Assert.True(settingsResult.ContainsKey("$schema")); - Assert.True(settingsResult.ContainsKey("visual")); - } - - /// - /// Test Set-WinGetUserSettings when the local settings file is not a json. - /// - [Test] - public void SetWinGetUserSettings_BadJsonFile_Merge() - { - WinGetSettingsHelper.SetWingetSettings("Hi, im not a json. Thank you, Test."); - - var inputSettings = new Hashtable() - { - { - "visual", - new Hashtable() - { - { "progressBar", "retro" }, - } - }, - }; - - using var powerShellHost = new PowerShellHost(); - - var cmdletException = Assert.Throws( - () => powerShellHost.PowerShell - .AddCommand("Set-WinGetUserSettings") - .AddParameter("UserSettings", inputSettings) - .AddParameter("Merge") - .Invoke()); - - // If we reference Microsoft.WinGet.Client to this project PowerShell host fails with - // System.Management.Automation.CmdletInvocationException : Operation is not supported on this platform. (0x80131539) - // System.PlatformNotSupportedException : Operation is not supported on this platform. (0x80131539) - // trying to load the runspace. This is most probably because the same dll is already loaded. - // Check the type the long way. - dynamic exception = cmdletException.InnerException; - Assert.AreEqual(exception.GetType().ToString(), "Microsoft.WinGet.Client.Engine.Exceptions.UserSettingsReadException"); - } - private bool IsRunning(string processName) { return Process.GetProcessesByName(processName).Length > 0; diff --git a/src/PowerShell/tests/Microsoft.WinGet.Client.Tests.ps1 b/src/PowerShell/tests/Microsoft.WinGet.Client.Tests.ps1 index 8d247c6ebb..3cc52d826a 100644 --- a/src/PowerShell/tests/Microsoft.WinGet.Client.Tests.ps1 +++ b/src/PowerShell/tests/Microsoft.WinGet.Client.Tests.ps1 @@ -12,7 +12,7 @@ BeforeAll { $settingsFilePath = (ConvertFrom-Json (wingetdev.exe settings export)).userSettingsFile # Source Add requires admin privileges, this will only execute successfully in an elevated PowerShell. - #wingetdev source add 'TestSource' 'https://localhost:5001/TestKit/' + wingetdev source add 'TestSource' 'https://localhost:5001/TestKit/' Import-Module Microsoft.WinGet.Client function SetWinGetSettingsHelper($settings) { @@ -21,6 +21,14 @@ BeforeAll { } } +Describe 'Get-WinGetVersion' { + + It 'Get-WinGetVersion' { + $version = Get-WinGetVersion + $version | Should -Not -BeNullOrEmpty -ErrorAction Stop + } +} + Describe 'Get-WinGetSource' { It 'Get Test Source' { From df6a77d7274bbf51d5e78bc276177dba6650a0e7 Mon Sep 17 00:00:00 2001 From: Ruben Guerrero Samaniego Date: Thu, 3 Aug 2023 13:36:04 -0700 Subject: [PATCH 08/15] More tests and import appx --- .../tests/Microsoft.WinGet.Client.Tests.ps1 | 90 +++++++++++++++++-- src/PowerShell/tests/RunTests.ps1 | 1 + 2 files changed, 85 insertions(+), 6 deletions(-) diff --git a/src/PowerShell/tests/Microsoft.WinGet.Client.Tests.ps1 b/src/PowerShell/tests/Microsoft.WinGet.Client.Tests.ps1 index 3cc52d826a..f52713895d 100644 --- a/src/PowerShell/tests/Microsoft.WinGet.Client.Tests.ps1 +++ b/src/PowerShell/tests/Microsoft.WinGet.Client.Tests.ps1 @@ -11,14 +11,34 @@ BeforeAll { $settingsFilePath = (ConvertFrom-Json (wingetdev.exe settings export)).userSettingsFile - # Source Add requires admin privileges, this will only execute successfully in an elevated PowerShell. - wingetdev source add 'TestSource' 'https://localhost:5001/TestKit/' Import-Module Microsoft.WinGet.Client function SetWinGetSettingsHelper($settings) { $content = ConvertTo-Json $settings -Depth 4 Set-Content -Path $settingsFilePath -Value $content } + + # Source Add requires admin privileges, this will only execute successfully in an elevated PowerShell. + function AddTestSource { + try { + Get-WinGetSource -Name 'TestSource' + } + catch { + Add-WinGetSource -Name 'TestSource' -Arg 'https://localhost:5001/TestKit/' + } + } + + function RemoveTestSource { + try { + Get-WinGetSource -Name 'TestSource' + } + catch { + # Source Remove requires admin privileges, this will only execute successfully in an elevated PowerShell. + # This is a workaround to an issue where the server takes longer than expected to terminate when + # running from PowerShell. This can cause other E2E tests to fail when attempting to reset the test source. + Start-Process -FilePath "wingetdev" -ArgumentList "source remove TestSource" + } + } } Describe 'Get-WinGetVersion' { @@ -29,9 +49,13 @@ Describe 'Get-WinGetVersion' { } } -Describe 'Get-WinGetSource' { +Describe 'Get|Add|Reset-WinGetSource' { + + BeforeAll { + AddTestSource + } - It 'Get Test Source' { + It 'Get Test source' { $source = Get-WinGetSource -Name 'TestSource' $source | Should -Not -BeNullOrEmpty -ErrorAction Stop @@ -39,9 +63,23 @@ Describe 'Get-WinGetSource' { $source.Argument | Should -Be 'https://localhost:5001/TestKit/' $source.Type | Should -Be 'Microsoft.PreIndexed.Package' } + + It 'Get fake source' { + { Get-WinGetSource -Name 'Fake' } | Should -Throw + } + + # This tests require admin + It 'Reset Test source' { + Reset-WinGetSource -Name TestSource + } } Describe 'Find-WinGetPackage' { + + BeforeAll { + AddTestSource + } + It 'Given no parameters, lists all available packages' { $allPackages = Find-WinGetPackage -Source TestSource $allPackages.Count | Should -BeGreaterThan 0 @@ -91,6 +129,10 @@ Describe 'Find-WinGetPackage' { Describe 'Install|Update|Uninstall-WinGetPackage' { + BeforeAll { + AddTestSource + } + It 'Install by Id' { $result = Install-WinGetPackage -Id AppInstallerTest.TestExeInstaller -Version '1.0.0.0' @@ -163,6 +205,10 @@ Describe 'Install|Update|Uninstall-WinGetPackage' { Describe 'Get-WinGetPackage' { + BeforeAll { + AddTestSource + } + It 'Install by Id' { $result = Install-WinGetPackage -Id AppInstallerTest.TestExeInstaller -Version '1.0.0.0' @@ -402,7 +448,39 @@ Describe 'Set-WinGetUserSettings' { } } +Describe 'Get|Enable|Disable-WinGetSetting' { + + It 'Get-WinGetSetting' { + $settings = Get-WinGetSettings + $settings | Should -Not -BeNullOrEmpty -ErrorAction Stop + $settings.'$schema' | Should -Not -BeNullOrEmpty + $settings.adminSettings | Should -Not -BeNullOrEmpty + $settings.userSettingsFile | Should -Be $settingsFilePath + } + + # This tests require admin + It 'Enable|Disable' { + $settings = Get-WinGetSettings + $settings | Should -Not -BeNullOrEmpty -ErrorAction Stop + $settings.adminSettings | Should -Not -BeNullOrEmpty + $settings.adminSettings.LocalManifestFiles | Should -Be $false + + Enable-WinGetSetting -Name LocalManifestFiles + + $afterEnable = Get-WinGetSettings + $afterEnable | Should -Not -BeNullOrEmpty -ErrorAction Stop + $afterEnable.adminSettings | Should -Not -BeNullOrEmpty + $afterEnable.adminSettings.LocalManifestFiles | Should -Be $true + + Disable-WingetSetting -Name LocalManifestFiles + + $afterDisable = Get-WinGetSettings + $afterDisable | Should -Not -BeNullOrEmpty -ErrorAction Stop + $afterDisable.adminSettings | Should -Not -BeNullOrEmpty + $afterDisable.adminSettings.LocalManifestFiles | Should -Be $false + } +} + AfterAll { - # Source Remove requires admin privileges, this will only execute successfully in an elevated PowerShell. - Start-Process -FilePath "wingetdev" -ArgumentList "source remove TestSource" + RemoveTestSource } \ No newline at end of file diff --git a/src/PowerShell/tests/RunTests.ps1 b/src/PowerShell/tests/RunTests.ps1 index 732362fef3..5321558794 100644 --- a/src/PowerShell/tests/RunTests.ps1 +++ b/src/PowerShell/tests/RunTests.ps1 @@ -30,6 +30,7 @@ if (-not [System.String]::IsNullOrEmpty($packageLayoutPath)) { $local:packageManifestPath = Join-Path $packageLayoutPath "AppxManifest.xml" + Import-Module Appx -UseWindowsPowerShell Add-AppxPackage -Register $local:packageManifestPath # Configure crash dump and log file settings From 9631e9fd63fff7ee3c536eabf21458efdcc8868b Mon Sep 17 00:00:00 2001 From: Ruben Guerrero Samaniego Date: Thu, 3 Aug 2023 15:17:11 -0700 Subject: [PATCH 09/15] install dependencies --- azure-pipelines.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index e0b349ba82..949fffa601 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -268,6 +268,13 @@ jobs: TargetFolder: '$(artifactsDir)\E2ETests\LocalhostWebServer' condition: succeededOrFailed() + - task: CopyFiles@2 + displayName: 'Copy Dev Package Dependencies' + inputs: + SourceFolder: '$(appxPackageDir)\AppInstallerCLIPackage_0.0.2.0_Test\Dependencies\$(buildPlatform)\' + TargetFolder: '$(artifactsDir)\E2ETests\DevPackageDependencies' + condition: succeededOrFailed() + - task: CopyFiles@2 displayName: 'Copy Files: WinGetUtilInterop.UnitTests' inputs: @@ -434,6 +441,14 @@ jobs: Contents: '**\*' TargetFolder: '$(Build.ArtifactStagingDirectory)' + - task: PowerShell@2 + displayName: Install Tests Dependencies + inputs: + targetType: 'inline' + script: | + Get-ChildItem E2ETests\DevPackageDependencies -Filter *.appx | %{ Add-AppxPackage $_.FullName } + workingDirectory: $(Pipeline.Workspace)\Build.x64release\ + - task: PowerShell@2 displayName: Install Root Certificate inputs: From c1ccad0f1413d5ebc408bb226888e44118355fad Mon Sep 17 00:00:00 2001 From: Ruben Guerrero Samaniego Date: Fri, 4 Aug 2023 15:24:05 -0700 Subject: [PATCH 10/15] install cert --- azure-pipelines.yml | 2 +- src/PowerShell/tests/RunTests.ps1 | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 949fffa601..172f8c4565 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -459,7 +459,7 @@ jobs: workingDirectory: $(Build.SourcesDirectory)\src\LocalhostWebServer displayName: Launch LocalhostWebServer - - pwsh: .\RunTests.ps1 -testModulesPath $(Build.ArtifactStagingDirectory) -outputPath $(Pipeline.Workspace)\PesterTest -packageLayoutPath $(Pipeline.Workspace)\Build.x64release\DevPackage + - pwsh: .\RunTests.ps1 -testModulesPath $(Build.ArtifactStagingDirectory) -outputPath $(Pipeline.Workspace)\PesterTest -packageLayoutPath $(Pipeline.Workspace)\Build.x64release\DevPackage -sourceCert $(Build.SourcesDirectory)\src\AppInstallerCLIE2ETests\TestData\AppInstallerTest.cer workingDirectory: $(Build.SourcesDirectory)\src\PowerShell\tests\ displayName: Run Tests diff --git a/src/PowerShell/tests/RunTests.ps1 b/src/PowerShell/tests/RunTests.ps1 index 5321558794..57fbc913f5 100644 --- a/src/PowerShell/tests/RunTests.ps1 +++ b/src/PowerShell/tests/RunTests.ps1 @@ -4,7 +4,8 @@ param( [string]$testModulesPath, [string]$outputPath, - [string]$packageLayoutPath + [string]$packageLayoutPath, + [string]$sourceCert ) # This updates pester not always necessary but worth noting @@ -41,4 +42,10 @@ if (-not [System.String]::IsNullOrEmpty($packageLayoutPath)) Set-Content -Path $local:settingsFilePath -Value $local:settingsFileContent } +if (-not [System.String]::IsNullOrEmpty($sourceCert)) +{ + # Requires admin + & certutil.exe -addstore -f "TRUSTEDPEOPLE" $sourceCert +} + Invoke-Pester -Script $PSScriptRoot\Microsoft.WinGet.Client.Tests.ps1 -OutputFile $outputPath\Tests-WinGetClient.XML -OutputFormat NUnitXML From 1f01411e222b45d9ac24afca7f367426384c6190 Mon Sep 17 00:00:00 2001 From: Ruben Guerrero Samaniego Date: Fri, 4 Aug 2023 17:28:20 -0700 Subject: [PATCH 11/15] spelling --- .github/actions/spelling/expect.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index 705df91ac8..e0df330a13 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -120,6 +120,7 @@ EFGH EFile endregion ENDSESSION +epth EQU errmsg ERRORONEXIT @@ -173,6 +174,7 @@ hmodule Howto hre hresults +hrow hwnd IARP IAttachment From dd9c888a653522ab13e647b0698dcfcb61be949c Mon Sep 17 00:00:00 2001 From: Ruben Guerrero Samaniego Date: Tue, 8 Aug 2023 11:21:16 -0700 Subject: [PATCH 12/15] spelling --- .github/actions/spelling/expect.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index e0df330a13..1762546eb3 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -126,6 +126,7 @@ errmsg ERRORONEXIT ESource ESRB +ests etest etl execustom From 75098e4560722a9bb4aa352149cc2cebbd5a8e35 Mon Sep 17 00:00:00 2001 From: Ruben Guerrero Samaniego Date: Thu, 10 Aug 2023 13:56:46 -0700 Subject: [PATCH 13/15] use e2e setup template --- azure-pipelines.yml | 36 +++++++------------ src/AppInstallerCLIE2ETests/SetUpFixture.cs | 3 +- .../Run-LocalhostWebServer.ps1 | 13 ++++++- src/PowerShell/tests/RunTests.ps1 | 9 +---- templates/e2e-setup.yml | 20 +++++++---- 5 files changed, 40 insertions(+), 41 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 172f8c4565..49bb82b299 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -219,8 +219,11 @@ jobs: - template: templates/e2e-setup.yml parameters: - source: $(Build.SourcesDirectory) - buildOutDir: $(buildOutDir) + sourceDir: $(Build.SourcesDirectory) + buildRoot: $(buildOutDir)\LocalhostWebServer + staticFileRoot: $(Agent.TempDirectory)\TestLocalIndex + localSourceJson: $(Build.SourcesDirectory)\src\AppInstallerCLIE2ETests\TestData\localsource.json + sourceCert: $(Build.SourcesDirectory)\src\AppInstallerCLIE2ETests\TestData\AppInstallerTest.cer - template: templates/e2e-test.template.yml parameters: @@ -412,18 +415,6 @@ jobs: condition: always() steps: - - task: DownloadSecureFile@1 - name: AppInstallerTest - displayName: 'Download Source Package Certificate' - inputs: - secureFile: 'AppInstallerTest.pfx' - - - task: DownloadSecureFile@1 - name: HTTPSDevCert - displayName: 'Download Kestrel Certificate' - inputs: - secureFile: 'HTTPSDevCertV2.pfx' - - task: DownloadPipelineArtifact@2 displayName: 'Download Build Artifacts' @@ -449,17 +440,14 @@ jobs: Get-ChildItem E2ETests\DevPackageDependencies -Filter *.appx | %{ Add-AppxPackage $_.FullName } workingDirectory: $(Pipeline.Workspace)\Build.x64release\ - - task: PowerShell@2 - displayName: Install Root Certificate - inputs: - filePath: '$(Build.SourcesDirectory)\src\LocalhostWebServer\InstallDevCert.ps1' - arguments: '-pfxpath $(HTTPSDevCert.secureFilePath) -password microsoft' - - - pwsh: .\Run-LocalhostWebServer.ps1 -BuildRoot $(Pipeline.Workspace)\Build.x64release\E2ETests\LocalhostWebServer -StaticFileRoot $(Pipeline.Workspace)\Build.x64release\E2ETests\TestLocalIndex -CertPath $(HTTPSDevCert.secureFilePath) -CertPassword microsoft - workingDirectory: $(Build.SourcesDirectory)\src\LocalhostWebServer - displayName: Launch LocalhostWebServer + - template: templates/e2e-setup.yml + parameters: + sourceDir: $(Build.SourcesDirectory) + buildRoot: $(Pipeline.Workspace)\Build.x64release\E2ETests\LocalhostWebServer + staticFileRoot: $(Pipeline.Workspace)\Build.x64release\E2ETests\TestLocalIndex + sourceCert: $(Build.SourcesDirectory)\src\AppInstallerCLIE2ETests\TestData\AppInstallerTest.cer - - pwsh: .\RunTests.ps1 -testModulesPath $(Build.ArtifactStagingDirectory) -outputPath $(Pipeline.Workspace)\PesterTest -packageLayoutPath $(Pipeline.Workspace)\Build.x64release\DevPackage -sourceCert $(Build.SourcesDirectory)\src\AppInstallerCLIE2ETests\TestData\AppInstallerTest.cer + - pwsh: .\RunTests.ps1 -testModulesPath $(Build.ArtifactStagingDirectory) -outputPath $(Pipeline.Workspace)\PesterTest -packageLayoutPath $(Pipeline.Workspace)\Build.x64release\DevPackage workingDirectory: $(Build.SourcesDirectory)\src\PowerShell\tests\ displayName: Run Tests diff --git a/src/AppInstallerCLIE2ETests/SetUpFixture.cs b/src/AppInstallerCLIE2ETests/SetUpFixture.cs index 14b5fdaf59..878e477f60 100644 --- a/src/AppInstallerCLIE2ETests/SetUpFixture.cs +++ b/src/AppInstallerCLIE2ETests/SetUpFixture.cs @@ -41,8 +41,6 @@ public void Setup() shouldRevertDefaultFileTypeRiskOnExit = this.DecreaseFileTypeRisk(".exe;.msi", false); - Assert.True(TestCommon.RunCommand("certutil.exe", "-addstore -f \"TRUSTEDPEOPLE\" " + TestCommon.GetTestDataFile(Constants.AppInstallerTestCert)), "Add AppInstallerTestCert"); - if (testParams.PackagedContext) { if (testParams.LooseFileRegistration) @@ -59,6 +57,7 @@ public void Setup() if (!testParams.SkipTestSource) { TestIndex.GenerateE2ESource(); + Assert.True(TestCommon.RunCommand("certutil.exe", "-addstore -f \"TRUSTEDPEOPLE\" " + TestCommon.GetTestDataFile(Constants.AppInstallerTestCert)), "Add AppInstallerTestCert"); } WinGetSettingsHelper.InitializeWingetSettings(); diff --git a/src/LocalhostWebServer/Run-LocalhostWebServer.ps1 b/src/LocalhostWebServer/Run-LocalhostWebServer.ps1 index ef243af9ed..d3e6bfb72c 100644 --- a/src/LocalhostWebServer/Run-LocalhostWebServer.ps1 +++ b/src/LocalhostWebServer/Run-LocalhostWebServer.ps1 @@ -13,6 +13,8 @@ Export cert location. .PARAMETER LocalSourceJson Local source json definition +.PARAMETER SourceCert + The certificate of the source package. #> param( @@ -32,9 +34,18 @@ param( [string]$OutCertFile, [Parameter()] - [string]$LocalSourceJson + [string]$LocalSourceJson, + + [Parameter()] + [string]$SourceCert ) +if (-not [System.String]::IsNullOrEmpty($sourceCert)) +{ + # Requires admin + & certutil.exe -addstore -f "TRUSTEDPEOPLE" $sourceCert +} + cd $BuildRoot Start-Process -FilePath "LocalhostWebServer.exe" -ArgumentList "StaticFileRoot=$StaticFileRoot CertPath=$CertPath CertPassword=$CertPassword OutCertFile=$OutCertFile LocalSourceJson=$LocalSourceJson" diff --git a/src/PowerShell/tests/RunTests.ps1 b/src/PowerShell/tests/RunTests.ps1 index 57fbc913f5..5321558794 100644 --- a/src/PowerShell/tests/RunTests.ps1 +++ b/src/PowerShell/tests/RunTests.ps1 @@ -4,8 +4,7 @@ param( [string]$testModulesPath, [string]$outputPath, - [string]$packageLayoutPath, - [string]$sourceCert + [string]$packageLayoutPath ) # This updates pester not always necessary but worth noting @@ -42,10 +41,4 @@ if (-not [System.String]::IsNullOrEmpty($packageLayoutPath)) Set-Content -Path $local:settingsFilePath -Value $local:settingsFileContent } -if (-not [System.String]::IsNullOrEmpty($sourceCert)) -{ - # Requires admin - & certutil.exe -addstore -f "TRUSTEDPEOPLE" $sourceCert -} - Invoke-Pester -Script $PSScriptRoot\Microsoft.WinGet.Client.Tests.ps1 -OutputFile $outputPath\Tests-WinGetClient.XML -OutputFormat NUnitXML diff --git a/templates/e2e-setup.yml b/templates/e2e-setup.yml index efff240da3..0bf66d011e 100644 --- a/templates/e2e-setup.yml +++ b/templates/e2e-setup.yml @@ -1,9 +1,17 @@ # Configures local test source and local PowerShell repository. parameters: -- name: source +- name: sourceDir type: string -- name: buildOutDir +- name: buildRoot type: string +- name: staticFileRoot + type: string +- name: localSourceJson + type: string + default: '' +- name: sourceCert + type: string + default: '' steps: - task: DownloadSecureFile@1 @@ -21,18 +29,18 @@ steps: - task: PowerShell@2 displayName: Install Root Certificate inputs: - filePath: '${{ parameters.source }}\src\LocalhostWebServer\InstallDevCert.ps1' + filePath: '${{ parameters.sourceDir }}\src\LocalhostWebServer\InstallDevCert.ps1' arguments: '-pfxpath $(HTTPSDevCert.secureFilePath) -password microsoft' - task: PowerShell@2 displayName: Launch LocalhostWebServer inputs: - filePath: '${{ parameters.source }}\src\LocalhostWebServer\Run-LocalhostWebServer.ps1' - arguments: '-BuildRoot ${{ parameters.buildOutDir }}\LocalhostWebServer -StaticFileRoot $(Agent.TempDirectory)\TestLocalIndex -CertPath $(HTTPSDevCert.secureFilePath) -CertPassword microsoft -OutCertFile $(Agent.TempDirectory)\servercert.cer -LocalSourceJson ${{ parameters.source }}\src\AppInstallerCLIE2ETests\TestData\localsource.json' + filePath: '${{ parameters.sourceDir }}\src\LocalhostWebServer\Run-LocalhostWebServer.ps1' + arguments: '-BuildRoot ${{ parameters.buildRoot }} -StaticFileRoot ${{ parameters.staticFileRoot }} -CertPath $(HTTPSDevCert.secureFilePath) -CertPassword microsoft -OutCertFile $(Agent.TempDirectory)\servercert.cer -LocalSourceJson ${{ parameters.localSourceJson }} -SourceCert ${{ parameters.sourceCert }}' - task: PowerShell@2 displayName: Setup Local PS Repository inputs: - filePath: '${{ parameters.source }}\src\AppInstallerCLIE2ETests\TestData\Configuration\Init-TestRepository.ps1' + filePath: '${{ parameters.sourceDir }}\src\AppInstallerCLIE2ETests\TestData\Configuration\Init-TestRepository.ps1' arguments: '-Force' pwsh: true From 20bc9b7cc5b7b46836fe634f16ab257da033ea1e Mon Sep 17 00:00:00 2001 From: Ruben Guerrero Samaniego Date: Thu, 10 Aug 2023 17:08:38 -0700 Subject: [PATCH 14/15] ok... --- azure-pipelines.yml | 9 ++------- src/AppInstallerCLIE2ETests/SetUpFixture.cs | 3 ++- templates/e2e-setup.yml | 12 ++---------- 3 files changed, 6 insertions(+), 18 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 49bb82b299..d02e112347 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -220,10 +220,7 @@ jobs: - template: templates/e2e-setup.yml parameters: sourceDir: $(Build.SourcesDirectory) - buildRoot: $(buildOutDir)\LocalhostWebServer - staticFileRoot: $(Agent.TempDirectory)\TestLocalIndex - localSourceJson: $(Build.SourcesDirectory)\src\AppInstallerCLIE2ETests\TestData\localsource.json - sourceCert: $(Build.SourcesDirectory)\src\AppInstallerCLIE2ETests\TestData\AppInstallerTest.cer + localhostWebServerArgs: '-BuildRoot $(buildOutDir)\LocalhostWebServer -StaticFileRoot $(Agent.TempDirectory)\TestLocalIndex -LocalSourceJson $(Build.SourcesDirectory)\src\AppInstallerCLIE2ETests\TestData\localsource.json -SourceCert $(Build.SourcesDirectory)\src\AppInstallerCLIE2ETests\TestData\AppInstallerTest.cer' - template: templates/e2e-test.template.yml parameters: @@ -443,9 +440,7 @@ jobs: - template: templates/e2e-setup.yml parameters: sourceDir: $(Build.SourcesDirectory) - buildRoot: $(Pipeline.Workspace)\Build.x64release\E2ETests\LocalhostWebServer - staticFileRoot: $(Pipeline.Workspace)\Build.x64release\E2ETests\TestLocalIndex - sourceCert: $(Build.SourcesDirectory)\src\AppInstallerCLIE2ETests\TestData\AppInstallerTest.cer + localhostWebServerArgs: '-BuildRoot $(Pipeline.Workspace)\Build.x64release\E2ETests\LocalhostWebServer -StaticFileRoot $(Pipeline.Workspace)\Build.x64release\E2ETests\TestLocalIndex -SourceCert $(Build.SourcesDirectory)\src\AppInstallerCLIE2ETests\TestData\AppInstallerTest.cer' - pwsh: .\RunTests.ps1 -testModulesPath $(Build.ArtifactStagingDirectory) -outputPath $(Pipeline.Workspace)\PesterTest -packageLayoutPath $(Pipeline.Workspace)\Build.x64release\DevPackage workingDirectory: $(Build.SourcesDirectory)\src\PowerShell\tests\ diff --git a/src/AppInstallerCLIE2ETests/SetUpFixture.cs b/src/AppInstallerCLIE2ETests/SetUpFixture.cs index 878e477f60..14b5fdaf59 100644 --- a/src/AppInstallerCLIE2ETests/SetUpFixture.cs +++ b/src/AppInstallerCLIE2ETests/SetUpFixture.cs @@ -41,6 +41,8 @@ public void Setup() shouldRevertDefaultFileTypeRiskOnExit = this.DecreaseFileTypeRisk(".exe;.msi", false); + Assert.True(TestCommon.RunCommand("certutil.exe", "-addstore -f \"TRUSTEDPEOPLE\" " + TestCommon.GetTestDataFile(Constants.AppInstallerTestCert)), "Add AppInstallerTestCert"); + if (testParams.PackagedContext) { if (testParams.LooseFileRegistration) @@ -57,7 +59,6 @@ public void Setup() if (!testParams.SkipTestSource) { TestIndex.GenerateE2ESource(); - Assert.True(TestCommon.RunCommand("certutil.exe", "-addstore -f \"TRUSTEDPEOPLE\" " + TestCommon.GetTestDataFile(Constants.AppInstallerTestCert)), "Add AppInstallerTestCert"); } WinGetSettingsHelper.InitializeWingetSettings(); diff --git a/templates/e2e-setup.yml b/templates/e2e-setup.yml index 0bf66d011e..adb1f496aa 100644 --- a/templates/e2e-setup.yml +++ b/templates/e2e-setup.yml @@ -2,16 +2,8 @@ parameters: - name: sourceDir type: string -- name: buildRoot +- name: localhostWebServerArgs type: string -- name: staticFileRoot - type: string -- name: localSourceJson - type: string - default: '' -- name: sourceCert - type: string - default: '' steps: - task: DownloadSecureFile@1 @@ -36,7 +28,7 @@ steps: displayName: Launch LocalhostWebServer inputs: filePath: '${{ parameters.sourceDir }}\src\LocalhostWebServer\Run-LocalhostWebServer.ps1' - arguments: '-BuildRoot ${{ parameters.buildRoot }} -StaticFileRoot ${{ parameters.staticFileRoot }} -CertPath $(HTTPSDevCert.secureFilePath) -CertPassword microsoft -OutCertFile $(Agent.TempDirectory)\servercert.cer -LocalSourceJson ${{ parameters.localSourceJson }} -SourceCert ${{ parameters.sourceCert }}' + arguments: '-CertPath $(HTTPSDevCert.secureFilePath) -CertPassword microsoft -OutCertFile $(Agent.TempDirectory)\servercert.cer ${{ parameters.localhostWebServerArgs }}' - task: PowerShell@2 displayName: Setup Local PS Repository From 9c529cef6b3289d15d4876ec7df67e89bfbdb5b7 Mon Sep 17 00:00:00 2001 From: Ruben Guerrero Samaniego Date: Fri, 11 Aug 2023 14:34:21 -0700 Subject: [PATCH 15/15] spelling --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index d02e112347..5b92e4a54f 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -351,7 +351,7 @@ jobs: condition: succeededOrFailed() - task: CopyFiles@2 - displayName: 'Copy PowerShell AnCPU Module Files' + displayName: 'Copy PowerShell AnyCPU Module Files' inputs: SourceFolder: '$(buildOutDirAnyCpu)\PowerShell' TargetFolder: '$(artifactsDir)\PowerShell'