From d4b00a53081a06463e87fd5000e95412fc2ce354 Mon Sep 17 00:00:00 2001 From: Marco Blessing Date: Thu, 14 Jul 2022 13:37:12 +0200 Subject: [PATCH] Migrates to Pester5+ tests (#59) #### :book: Summary - update Pester tests to Pester5+ compatiple layout - switch to dotnet base imaged - dotnet binary required for publishung powershell modules (Publish-Module) #### :bookmark_tabs: Test Plan > :bulb: Select your test plan for the code changes. - [x] Tested via Drone.io pipeline - [ ] Custom test - [ ] No test plan ##### Details / Justification #### :books: Additional Notes Co-authored-by: OCram85 Reviewed-on: https://gitea.ocram85.com/OCram85/PSCredentialStore/pulls/59 --- .drone.yml | 44 ++++-- .gitignore | 3 + src/Certificate/New-CSCertAttribute.Tests.ps1 | 20 +++ src/Certificate/New-CSCertificate.Tests.ps1 | 33 ++++ ...edentialStore.Certificate.Attribute.ps1xml | 18 ++- .../Item/New-CredentialStoreItem.Tests.ps1 | 55 +++++-- src/ModuleRoot.psm1 | 11 ++ src/PSCredentialStore.psd1 | 2 +- src/PSCredentialStore.psm1 | 16 -- src/PSModule.Tests.ps1 | 20 ++- .../Get-DefaultCredentialStorePath.Tests.ps1 | 13 ++ src/Private/Get-ModuleBase.Tests.ps1 | 20 +++ src/Private/Get-RandomAESKey.Tests.ps1 | 26 ++++ .../Private/Get-TempDir.Tests.ps1 | 21 ++- src/Private/Resolve-Dependency.Tests.ps1 | 60 ++++++++ src/Private/Test-CSPfxCertificate.Tests.ps1 | 25 ++++ .../Private/Test-Module.Tests.ps1 | 15 +- src/Store/Get-CredentialStore.Tests.ps1 | 47 ++++++ src/Store/New-CredentialStore.Tests.ps1 | 141 ++++++++++++++++++ .../Store/Test-CredentialStore.Tests.ps1 | 28 +++- tests/.gitkeep | 0 tests/00_BasicModule.Tests.ps1 | 17 --- .../50_New-CSCertAttribute.Tests.ps1 | 7 - .../51_New-CSCertificate.Tests.ps1 | 15 -- .../60_Test-CSPfxCertificate.Tests.ps1 | 10 -- tests/Private/01_Get-ModuleBase.Tests.ps1 | 7 - tests/Private/01_Get-RandomAESKey.Tests.ps1 | 13 -- tests/Private/01_Resolve-Dependency.Tests.ps1 | 35 ----- tests/Store/02_New-CredentialStore.Tests.ps1 | 117 --------------- tests/Store/03_Get-CredentialStore.Tests.ps1 | 32 ---- tools/DroneIO.psm1 | 98 ++++++++++-- 31 files changed, 636 insertions(+), 333 deletions(-) create mode 100644 src/Certificate/New-CSCertAttribute.Tests.ps1 create mode 100644 src/Certificate/New-CSCertificate.Tests.ps1 rename tests/Item/03_New-CredentialStoreItem.Tests.ps1 => src/Item/New-CredentialStoreItem.Tests.ps1 (71%) create mode 100644 src/ModuleRoot.psm1 delete mode 100644 src/PSCredentialStore.psm1 rename tests/Private/01_Get-DefaultCredentialStorePath.Tests.ps1 => src/Private/Get-DefaultCredentialStorePath.Tests.ps1 (83%) create mode 100644 src/Private/Get-ModuleBase.Tests.ps1 create mode 100644 src/Private/Get-RandomAESKey.Tests.ps1 rename tests/Private/01_Get-TempDir.Tests.ps1 => src/Private/Get-TempDir.Tests.ps1 (54%) create mode 100644 src/Private/Resolve-Dependency.Tests.ps1 create mode 100644 src/Private/Test-CSPfxCertificate.Tests.ps1 rename tests/Private/01_Test-Module.Tests.ps1 => src/Private/Test-Module.Tests.ps1 (68%) create mode 100644 src/Store/Get-CredentialStore.Tests.ps1 create mode 100644 src/Store/New-CredentialStore.Tests.ps1 rename tests/Store/02_Test-CredentialStore.Tests.ps1 => src/Store/Test-CredentialStore.Tests.ps1 (58%) delete mode 100644 tests/.gitkeep delete mode 100644 tests/00_BasicModule.Tests.ps1 delete mode 100644 tests/Certificate/50_New-CSCertAttribute.Tests.ps1 delete mode 100644 tests/Certificate/51_New-CSCertificate.Tests.ps1 delete mode 100644 tests/PfxCertificate/60_Test-CSPfxCertificate.Tests.ps1 delete mode 100644 tests/Private/01_Get-ModuleBase.Tests.ps1 delete mode 100644 tests/Private/01_Get-RandomAESKey.Tests.ps1 delete mode 100644 tests/Private/01_Resolve-Dependency.Tests.ps1 delete mode 100644 tests/Store/02_New-CredentialStore.Tests.ps1 delete mode 100644 tests/Store/03_Get-CredentialStore.Tests.ps1 diff --git a/.drone.yml b/.drone.yml index c042402..86f4979 100644 --- a/.drone.yml +++ b/.drone.yml @@ -1,7 +1,7 @@ --- kind: pipeline type: docker -name: Linux_PWSH7_Build +name: PWSH_LTS_7.2_Ubuntu-focal platform: os: linux @@ -9,7 +9,7 @@ platform: steps: - name: Environments - image: mcr.microsoft.com/powershell:latest + image: mcr.microsoft.com/powershell:lts-7.2-ubuntu-focal commands: - | pwsh -NonInteractive -c "& { @@ -18,29 +18,47 @@ steps: }" - name: LintTests - image: mcr.microsoft.com/powershell:latest + image: mcr.microsoft.com/powershell:lts-7.2-ubuntu-focal + failure: ignore commands: - | pwsh -NonInteractive -c "& { Import-Module './tools/DroneIO.psm1'; Invoke-InstallDependencies; - Invoke-Linter + Invoke-Linter -ErrorAction 'Stop' }" - name: UnitTests - image: mcr.microsoft.com/powershell:latest + image: mcr.microsoft.com/powershell:lts-7.2-ubuntu-focal + failure: ignore commands: - | pwsh -NonInteractive -c "& { Import-Module './tools/DroneIO.psm1'; Invoke-InstallDependencies; - Invoke-UnitTest -Verbosity 'Detailed' + Invoke-UnitTest -Verbosity 'Normal' -ExcludeTag @( 'Integration', 'Disabled') -ErrorAction 'Stop' }" - - name: coverage - image: plugins/codecov - settings: - token: - from_secret: CodeCovToken - files: - - coverage.xml + # Disable Codecov for self hosted git + #- name: Coverage + # image: plugins/codecov + # settings: + # token: + # from_secret: CodeCovToken + # files: + # - coverage.xml + # depends_on: + # - UnitTests + + - name: SetPipelineState + image: mcr.microsoft.com/powershell:lts-7.2-ubuntu-focal + commands: + - | + pwsh -NonInteractive -c "& { + Import-Module './tools/DroneIO.psm1'; + Invoke-BuildState -ErrorAction 'Stop' + }" + depends_on: + - LintTests + - UnitTests + #- Coverage diff --git a/.gitignore b/.gitignore index 18af3f7..fc98b4f 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,6 @@ data/*.csv # Ignore Unit Test result files coverage.xml testResults.xml + +# Optional build state file +STATE.xml diff --git a/src/Certificate/New-CSCertAttribute.Tests.ps1 b/src/Certificate/New-CSCertAttribute.Tests.ps1 new file mode 100644 index 0000000..50a966a --- /dev/null +++ b/src/Certificate/New-CSCertAttribute.Tests.ps1 @@ -0,0 +1,20 @@ +BeforeAll { + $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName + Import-Module $ManifestFile -Force +} + +Describe "New-CSCertAttribute" { + Context "Basis Tests" -Tag 'Unit' { + It "Should not throw" { + $AttribParams = @{ + Country = 'DE' + State = 'BW' + City = 'KA' + Organization = 'IT' + OrganizationalUnitName = 'foo' + CommonName = 'MyCert' + } + { New-CSCertAttribute @AttribParams } | Should -Not -Throw + } + } +} diff --git a/src/Certificate/New-CSCertificate.Tests.ps1 b/src/Certificate/New-CSCertificate.Tests.ps1 new file mode 100644 index 0000000..250612f --- /dev/null +++ b/src/Certificate/New-CSCertificate.Tests.ps1 @@ -0,0 +1,33 @@ +BeforeAll { + $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName + Import-Module $ManifestFile -Force + + $PrivateFunctions = (Get-ChildItem -Path "./src/Private/*.ps1" | Where-Object { + $_.BaseName -notmatch '.Tests' + } + ).FullName + foreach ( $func in $PrivateFunctions) { + . $func + } +} + +Describe "New-CSCertificate" { + Context "Basic Tests" -Tag 'Unit' { + It "Should not throw" { + $attribs = @{ + Country = 'DE' + State = 'BW' + City = 'KA' + Organization = 'IT' + OrganizationalUnitName = 'foo' + CommonName = 'MyCert' + } + $CertAttribs = @{ + CRTAttribute = New-CSCertAttribute @attribs + KeyName = Join-Path -Path (Get-TempDir) -ChildPath '/foo.key' + CertName = Join-Path -Path (Get-TempDir) -ChildPath '/cert.pfx' + } + { New-CSCertificate @CertAttribs } | Should -Not -Throw + } + } +} diff --git a/src/Formats/PSCredentialStore.Certificate.Attribute.ps1xml b/src/Formats/PSCredentialStore.Certificate.Attribute.ps1xml index d75dee6..a9ef0fe 100644 --- a/src/Formats/PSCredentialStore.Certificate.Attribute.ps1xml +++ b/src/Formats/PSCredentialStore.Certificate.Attribute.ps1xml @@ -11,22 +11,28 @@ - Country + + $_.Subject.Country - State + + $_.Subject.State - City + + $_.Subject.City - Organization + + $_.Subject.Organization - OrganizationalUnitName + + $_.Subject.OrganizationalUnitName - CommonName + + $_.Subject.CommonName diff --git a/tests/Item/03_New-CredentialStoreItem.Tests.ps1 b/src/Item/New-CredentialStoreItem.Tests.ps1 similarity index 71% rename from tests/Item/03_New-CredentialStoreItem.Tests.ps1 rename to src/Item/New-CredentialStoreItem.Tests.ps1 index 56ce83b..02d1188 100644 --- a/tests/Item/03_New-CredentialStoreItem.Tests.ps1 +++ b/src/Item/New-CredentialStoreItem.Tests.ps1 @@ -1,6 +1,31 @@ +[Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSAvoidUsingConvertToSecureStringWithPlainText', + '', + Justification = 'just used in pester tests.' +)] +[Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSProvideCommentHelp', + '', + Justification = 'no need in internal pester helpers.' +)] +param () + +BeforeAll { + $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName + Import-Module $ManifestFile -Force + + $PrivateFunctions = (Get-ChildItem -Path "./src/Private/*.ps1" | Where-Object { + $_.BaseName -notmatch '.Tests' + } + ).FullName + foreach ( $func in $PrivateFunctions) { + . $func + } +} + Describe "New-CredentialStoreItem" { Context "Private Credential Store tests" { - It "Test1: Add entry to existing private store." { + It "Add entry to existing private store." { # Creat a fresh CredentialStore first New-CredentialStore -Force @@ -20,7 +45,7 @@ Describe "New-CredentialStoreItem" { } } Context "Test with new shared Credential Store" { - It "Test2: Create new RemoteHost entry" { + It "Create new RemoteHost entry" { # prepare test environment $tmpCS = Join-Path -Path (Get-TempDir) -ChildPath '/CredentialStore.json' New-CredentialStore -Shared -Path $tmpCS -Force @@ -29,9 +54,11 @@ Describe "New-CredentialStoreItem" { $Password = ConvertTo-SecureString -String "mypasswd" -AsPlainText -Force $mycreds = [PSCredential]::new($UserName, $Password) $RemoteHost = "foobar" - { New-CredentialStoreItem -Shared -Path $tmpCS -RemoteHost $RemoteHost -Credential $mycreds } | Should -Not -Throw + { + New-CredentialStoreItem -Shared -Path $tmpCS -RemoteHost $RemoteHost -Credential $mycreds + } | Should -Not -Throw $tmpCS = Get-Content -Path $tmpCS -Raw | ConvertFrom-Json - $res = Get-Member -InputObject $tmpCS -Name $RemoteHost -Membertype Properties + $res = Get-Member -InputObject $tmpCS -Name $RemoteHost -MemberType Properties $res.Name | Should -Be $RemoteHost } It "Adds Item with identifier to shared store" { @@ -42,13 +69,19 @@ Describe "New-CredentialStoreItem" { $Password = ConvertTo-SecureString -String "mypasswd" -AsPlainText -Force $mycreds = [PSCredential]::new($UserName, $Password) $RemoteHost = "foobar2" - New-CredentialStoreItem -Shared -Path $tmpCS -RemoteHost $RemoteHost -Credential $mycreds -Identifier 'Foo' + $StoreItemParam = @{ + Shared = $true + Path = $tmpCS + RemoteHost = $RemoteHost + Credential = $mycreds + identifier = 'Foo' + } + New-CredentialStoreItem @StoreItemParam $writtenItem = Get-CredentialStoreItem -Shared -Path $tmpCS -RemoteHost $RemoteHost -Identifier 'Foo' ($writtenItem.UserName -eq $UserName) -and ($writtenItem.Password.Length -gt 0) | Should -Be $true } } Context "Test optional parameter lookup" { - It "Test missing Credential" { function global:Get-Credential ([string]$Message) { $UserName = 'testuser' @@ -65,16 +98,20 @@ Describe "New-CredentialStoreItem" { } Context "General Exception handling" { - Mock Test-CredentialStore { return $false } + Mock Test-CredentialStore { return $false } -ModuleName 'PSCredentialStore' It "Missing CredentialStore should throw" { - { New-CredentialStoreItem -Shared -Path 'C:\missingStore.json' -RemoteHost 'notrelevant' } | Should -Throw "Could not add anything" + { + New-CredentialStoreItem -Shared -Path '/tmp/missingStore.json' -RemoteHost 'notrelevant' + } | Should -Throw "Could not add anything into the given CredentialStore." } } Context "Testing pipeline paramter" { It "Add the item with credential value from pipe" { $UserName = 'pipeUser' $Password = ConvertTo-SecureString -String "pipePasswd" -AsPlainText -Force - { [PSCredential]::new($UserName, $Password) | New-CredentialStoreItem -RemoteHost 'PipeHost' } | Should -Not -Throw + { + [PSCredential]::new($UserName, $Password) | New-CredentialStoreItem -RemoteHost 'PipeHost' + } | Should -Not -Throw } It "Testing written item" { diff --git a/src/ModuleRoot.psm1 b/src/ModuleRoot.psm1 new file mode 100644 index 0000000..abeede9 --- /dev/null +++ b/src/ModuleRoot.psm1 @@ -0,0 +1,11 @@ +#region module-definition + +#endregion module-definition +Set-Variable -Name "CSVersion" -Value "2.0.0" -Option Constant -Scope 'Script' -ErrorAction Stop + +# Get all child items in the Script path and exclude the Deploy script (if present.) +$Functions = Get-ChildItem -Path $PSScriptRoot\*.ps1 -Recurse | Where-Object { $_.BaseName -notmatch '.Tests' } + +foreach ($Item in $Functions) { + . $Item.FullName +} diff --git a/src/PSCredentialStore.psd1 b/src/PSCredentialStore.psd1 index 4492020..c2b482b 100644 --- a/src/PSCredentialStore.psd1 +++ b/src/PSCredentialStore.psd1 @@ -1,7 +1,7 @@ @{ # Script module or binary module file associated with this manifest. - RootModule = 'PSCredentialStore.psm1' + RootModule = 'ModuleRoot.psm1' # Version number of this module. ModuleVersion = '0.0.9999' diff --git a/src/PSCredentialStore.psm1 b/src/PSCredentialStore.psm1 deleted file mode 100644 index 978d81d..0000000 --- a/src/PSCredentialStore.psm1 +++ /dev/null @@ -1,16 +0,0 @@ -#region module-definition - -#endregion module-definition -Set-Variable -Name "CSVersion" -Value "2.0.0" -Option Constant -Scope 'Script' -ErrorAction Stop - -#region dot-sourcing -# dot-sourcing all module functions. The export is handled via manifest file. - -$Items = (Get-ChildItem -Path (Join-Path -Path $PSScriptRoot -ChildPath '*.ps1') -Recurse ).FullName | Where-Object { - $_ -notmatch "(Classes|Init)" -} -foreach ($Item in $Items) { - # Write-Verbose ("dot sourcing file {0}" -f $Item) - . $Item -} -#endregion dot-sourcing diff --git a/src/PSModule.Tests.ps1 b/src/PSModule.Tests.ps1 index 2338087..34dc6e4 100644 --- a/src/PSModule.Tests.ps1 +++ b/src/PSModule.Tests.ps1 @@ -1,14 +1,12 @@ Describe 'Test module meta' { - It 'Test manifest file' { - $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName - Test-ModuleManifest -Path $ManifestFile | Should -Be $true + Context 'Default tests' -Tag 'Default' { + It 'Test manifest file' { + $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName + Test-ModuleManifest -Path $ManifestFile | Should -Be $true + } + It 'Import Module' { + $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName + { Import-Module $ManifestFile } | Should -Not -Throw + } } - It 'Import Module' { - $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName - { Import-Module $ManifestFile } | Should -Not -Throw - } - # Dummy test to force pester error - #It 'Force Pester Error' { - # $true | Should -BeFalse - #} } diff --git a/tests/Private/01_Get-DefaultCredentialStorePath.Tests.ps1 b/src/Private/Get-DefaultCredentialStorePath.Tests.ps1 similarity index 83% rename from tests/Private/01_Get-DefaultCredentialStorePath.Tests.ps1 rename to src/Private/Get-DefaultCredentialStorePath.Tests.ps1 index ac4b6dc..ee892fe 100644 --- a/tests/Private/01_Get-DefaultCredentialStorePath.Tests.ps1 +++ b/src/Private/Get-DefaultCredentialStorePath.Tests.ps1 @@ -1,3 +1,16 @@ +BeforeAll { + $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName + Import-Module $ManifestFile -Force + + $PrivateFunctions = (Get-ChildItem -Path "./src/Private/*.ps1" | Where-Object { + $_.BaseName -notmatch '.Tests' + } + ).FullName + foreach ( $func in $PrivateFunctions) { + . $func + } +} + Describe "Get-DefaultCredentialStorePath" { Context "Basic syntax test" { It "Test1: Should not throw" { diff --git a/src/Private/Get-ModuleBase.Tests.ps1 b/src/Private/Get-ModuleBase.Tests.ps1 new file mode 100644 index 0000000..73f9c53 --- /dev/null +++ b/src/Private/Get-ModuleBase.Tests.ps1 @@ -0,0 +1,20 @@ +BeforeAll { + $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName + Import-Module $ManifestFile -Force + + $PrivateFunctions = (Get-ChildItem -Path "./src/Private/*.ps1" | Where-Object { + $_.BaseName -notmatch '.Tests' + } + ).FullName + foreach ( $func in $PrivateFunctions) { + . $func + } +} + +Describe "Get-ModuleBase" { + Context "Basic syntax check" { + It "Test1: Should not throw" { + { Get-ModuleBase } | Should -Not -Throw + } + } +} diff --git a/src/Private/Get-RandomAESKey.Tests.ps1 b/src/Private/Get-RandomAESKey.Tests.ps1 new file mode 100644 index 0000000..21b6046 --- /dev/null +++ b/src/Private/Get-RandomAESKey.Tests.ps1 @@ -0,0 +1,26 @@ +BeforeAll { + $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName + Import-Module $ManifestFile -Force + + $PrivateFunctions = (Get-ChildItem -Path "./src/Private/*.ps1" | Where-Object { + $_.BaseName -notmatch '.Tests' + } + ).FullName + foreach ( $func in $PrivateFunctions) { + . $func + } +} + +Describe "Get-RandomKey" { + Context "Basic input tests" { + It "Test1: Should not throw " { + { Get-RandomAESKey } | Should -Not -Throw + } + } + Context "Basic syntax check" { + It "Test2: Should return a key with a length of 32 bytes" { + $Key = Get-RandomAESKey + $Key.length | Should -Be 32 + } + } +} diff --git a/tests/Private/01_Get-TempDir.Tests.ps1 b/src/Private/Get-TempDir.Tests.ps1 similarity index 54% rename from tests/Private/01_Get-TempDir.Tests.ps1 rename to src/Private/Get-TempDir.Tests.ps1 index 34a3d5e..336471b 100644 --- a/tests/Private/01_Get-TempDir.Tests.ps1 +++ b/src/Private/Get-TempDir.Tests.ps1 @@ -1,7 +1,20 @@ +BeforeAll { + $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName + Import-Module $ManifestFile -Force + + $PrivateFunctions = (Get-ChildItem -Path "./src/Private/*.ps1" | Where-Object { + $_.BaseName -notmatch '.Tests' + } + ).FullName + foreach ( $func in $PrivateFunctions) { + . $func + } +} + Describe "Get-TempDir" { Context "Basic tests" { It "Should not throw" { - {Get-TempDir} | Should -Not -Throw + { Get-TempDir } | Should -Not -Throw } It "Should return the correct os tmp path" { $Path = Get-TempDir @@ -17,7 +30,11 @@ Describe "Get-TempDir" { } } if ($Env:APPVEYOR) { - if (($isWindows) -or ($PSVersionTable.PSVersion.Major -lt 6) -or ($PSVersionTable.PSEdition -eq 'Desktop')) { + if ( + ($isWindows) -or + ($PSVersionTable.PSVersion.Major -lt 6) -or + ($PSVersionTable.PSEdition -eq 'Desktop') + ) { $RefPath = (Resolve-Path -Path $env:TEMP).Path $Path | Should -Be $RefPath } diff --git a/src/Private/Resolve-Dependency.Tests.ps1 b/src/Private/Resolve-Dependency.Tests.ps1 new file mode 100644 index 0000000..53ee91e --- /dev/null +++ b/src/Private/Resolve-Dependency.Tests.ps1 @@ -0,0 +1,60 @@ +BeforeAll { + $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName + Import-Module $ManifestFile -Force + + $PrivateFunctions = (Get-ChildItem -Path "./src/Private/*.ps1" | Where-Object { + $_.BaseName -notmatch '.Tests' + } + ).FullName + foreach ( $func in $PrivateFunctions) { + . $func + } +} + +Describe "Resolve-Dependency" { + Context "Basic syntax check" { + BeforeAll { + Mock Get-ModuleBase { + return (Join-Path -Path $PWD -ChildPath '/resources') + } + Mock Test-Module { + return $true + } + } + + It "Test1: Should not throw" { + { Resolve-Dependency -Name 'foobar2000' } | Should -Not -Throw + } + It "Test2: Output type should be bool" { + Resolve-Dependency -Name 'foobar2000' | Should -BeOfType bool + } + } + Context "Enforce Error" { + # Return incorrect module base to enforce there is no config file. + Mock Get-ModuleBase { + if ($IsWindows) { return "C:\" } + elseif ($isLinux) { return "/" } + } + It "Missing dependency file should not cause an error" { + { Resolve-Dependency -Name 'awesome' } | Should -Not -Throw + } + + It "Missing dependency file should return true" { + Resolve-Dependency -Name 'awesome' | Should -Be $true + } + } + Context "Testing input variations" { + It "Should return true if all given dependencies exist" { + Mock Get-ModuleBase { + return (Join-Path -Path $PWD -ChildPath '/resources') + } + Resolve-Dependency -Name 'Existing' | Should -Be $true + } + It "Mixed results should return false" { + Mock Get-ModuleBase { + return (Join-Path -Path $PWD -ChildPath '/resources') + } + Resolve-Dependency -Name 'PSGetMixed' | Should -Be $false + } + } +} diff --git a/src/Private/Test-CSPfxCertificate.Tests.ps1 b/src/Private/Test-CSPfxCertificate.Tests.ps1 new file mode 100644 index 0000000..f1405d1 --- /dev/null +++ b/src/Private/Test-CSPfxCertificate.Tests.ps1 @@ -0,0 +1,25 @@ +BeforeAll { + $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName + Import-Module $ManifestFile -Force + + $PrivateFunctions = (Get-ChildItem -Path "./src/Private/*.ps1" | Where-Object { + $_.BaseName -notmatch '.Tests' + } + ).FullName + foreach ( $func in $PrivateFunctions) { + . $func + } +} + +Describe "Test-CSPfxCertificate" { + Context "Basic Tests" { + It "Should not Throw" { + { + Test-CSPfxCertificate -Thumbprint '12345' -StoreName My -StoreLocation CurrentUser + } | Should -Not -Throw + } + It "Should return false" { + Test-CSPfxCertificate -Thumbprint '12345' -StoreName My -StoreLocation CurrentUser | Should -Be $false + } + } +} diff --git a/tests/Private/01_Test-Module.Tests.ps1 b/src/Private/Test-Module.Tests.ps1 similarity index 68% rename from tests/Private/01_Test-Module.Tests.ps1 rename to src/Private/Test-Module.Tests.ps1 index c5747c8..1805d12 100644 --- a/tests/Private/01_Test-Module.Tests.ps1 +++ b/src/Private/Test-Module.Tests.ps1 @@ -1,3 +1,16 @@ +BeforeAll { + $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName + Import-Module $ManifestFile -Force + + $PrivateFunctions = (Get-ChildItem -Path "./src/Private/*.ps1" | Where-Object { + $_.BaseName -notmatch '.Tests' + } + ).FullName + foreach ( $func in $PrivateFunctions) { + . $func + } +} + Describe "Test-ModuleName" { Context "Basic input tests" { It "Testing standard module should not throw" { @@ -20,7 +33,7 @@ Describe "Test-ModuleName" { Test-Module -Name 'foobar2000' | Should -Be $false } It "StopifFails switch should thrown an error" { - {Test-Module -Name 'foobar2000' -StopIfFails }| Should -Throw + { Test-Module -Name 'foobar2000' -StopIfFails } | Should -Throw } } } diff --git a/src/Store/Get-CredentialStore.Tests.ps1 b/src/Store/Get-CredentialStore.Tests.ps1 new file mode 100644 index 0000000..bb940a0 --- /dev/null +++ b/src/Store/Get-CredentialStore.Tests.ps1 @@ -0,0 +1,47 @@ +BeforeAll { + $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName + Import-Module $ManifestFile -Force + + $PrivateFunctions = (Get-ChildItem -Path "./src/Private/*.ps1" | Where-Object { + $_.BaseName -notmatch '.Tests' + } + ).FullName + foreach ( $func in $PrivateFunctions) { + . $func + } +} + +Describe "Get-CredentialStore" { + Context "Basic logic tests" { + It "Read CS without params" { + $TestCredentialStore = './resources/cs/CredentialStore.json' + $TestPfxCert = './resources/cs/PSCredentialStore.pfx' + if (! (Test-Path -Path (Get-DefaultCredentialStorePath)) ) { + { New-CredentialStore -Force } | Should -Not -Throw + } + { Get-CredentialStore } | Should -Not -Throw + } + It "Read Credential Store with testing data" { + $TestCredentialStore = './resources/cs/CredentialStore.json' + $TestPfxCert = './resources/cs/PSCredentialStore.pfx' + { + Use-CSCertificate -Shared -CredentialStore $TestCredentialStore -Path $TestPfxCert + } | Should -Not -Throw + { Get-CredentialStore -Shared -Path $TestCredentialStore } | Should -Not -Throw + } + It "Test3: Not existing path should return false" { + { + Get-CredentialStore -Shared -Path './CredentialStore.json' + } | Should -Throw "Could not find the CredentialStore." + } + } + Context "Testing invalid json data" { + It "Should throw with invalid CredentialStore" { + $BrokenCS = './resources/cs/Broken_CS.json' + Write-Verbose -Message ('BrokenCS Path: {0}' -f $BrokenCS) -Verbose + { + Get-CredentialStore -Path -Shared $BrokenCS + } | Should -Throw + } + } +} diff --git a/src/Store/New-CredentialStore.Tests.ps1 b/src/Store/New-CredentialStore.Tests.ps1 new file mode 100644 index 0000000..9cc5b88 --- /dev/null +++ b/src/Store/New-CredentialStore.Tests.ps1 @@ -0,0 +1,141 @@ +BeforeAll { + $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName + Import-Module $ManifestFile -Force + + $PrivateFunctions = (Get-ChildItem -Path "./src/Private/*.ps1" | Where-Object { + $_.BaseName -notmatch '.Tests' + } + ).FullName + foreach ( $func in $PrivateFunctions) { + . $func + } + + # Backup existing credential stores + $VerbosePreference = "Continue" + Write-Verbose "Backup private Credential Store..." + $CSPath = Get-DefaultCredentialStorePath + $BackupFile = "{0}.back" -f $CSPath + if (Test-Path -Path $CSPath) { + Move-Item -Path $CSPath -Destination $BackupFile + } + Write-Verbose "Backup shared CredentialStore..." + $CSShared = Get-DefaultCredentialStorePath -Shared + $BackupSharedFile = "{0}.back" -f $CSShared + if (Test-Path -Path $CSShared) { + Move-Item -Path $CSShared -Destination $BackupSharedFile + } + Write-Verbose "Remove old CredentialStore in Temp dir" + $CSTemp = Join-Path -Path (Get-TempDir) -ChildPath '/CredentialStore.json' + if (Test-Path -Path $CSTemp) { + Remove-Item -Path $CSTemp + } + $VerbosePreference = "SilentlyContinue" +} + +Describe "New-CredentialStore" { + Context "Private CS tests" { + It "Create new private CredentialStore" { + $pCS = Get-DefaultCredentialStorePath + { New-CredentialStore -Confirm:$false -Force } | Should -Not -Throw + $result = Test-Path -Path $pCS + $CS = Get-Content -Path $pCS -Raw | ConvertFrom-Json + ($result -eq $true) -and ($CS.Type -eq "Private") | Should -Be $true + } + It "Try to override private Store" { + { New-CredentialStore -Confirm:$false } | Should -Throw + } + It "Reset existing Credential Store" { + $pCS = Get-DefaultCredentialStorePath + $now = Get-Date + $CS = Get-Content -Path $pCS -Raw | ConvertFrom-Json + $CSCreation = [DateTime]$CS.Created + New-CredentialStore -Confirm:$false -Force + $now -gt $csCreation | Should -Be $true + } + } + Context "Shared CS tests" { + It "Create a new Shared Credential Store" { + $sCS = Get-DefaultCredentialStorePath -Shared + { New-CredentialStore -Confirm:$false -Shared } | Should -Not -Throw + Test-Path -Path $sCS | Should -Be $true + } + It "Try to override existing shared CS" { + { New-CredentialStore -Shared -Confirm:$false } | Should -Throw + } + It "Reset shared CredentialStore" { + $sCS = Get-DefaultCredentialStorePath -Shared + $now = Get-Date + $CS = Get-Content -Path $sCS -Raw | ConvertFrom-Json + $CSCreation = [DateTime]$CS.Created + New-CredentialStore -Force -Shared -Confirm:$false + $now -gt $csCreation | Should -Be $true + } + } + Context "Custom Shared CS tests" { + It "Create new custom shared" { + $cCS = Join-Path -Path (Get-TempDir) -ChildPath "CredentialStore.json" + { New-CredentialStore -Path $cCS -Shared -Confirm:$false -SkipPFXCertCreation } | Should -Not -Throw + } + It "Try to override exiting one" { + $cCS = Join-Path -Path (Get-TempDir) -ChildPath "CredentialStore.json" + { New-CredentialStore -Path $cCS -Shared -Confirm:$false } | Should -Throw + } + It "Reset existing custom CredentialStore" { + $cCS = Join-Path -Path (Get-TempDir) -ChildPath "CredentialStore.json" + { New-CredentialStore -Path $cCS -Shared -Force -Confirm:$false } | Should -Not -Throw + } + } + Context "Test exception handling" { + Mock Out-File { throw "foobar exception" } + It "JSON Conversion should fail and throw" { + { + New-CredentialStore -Path ( + Join-Path -Path (Get-TempDir) -ChildPath '/dummy.json' + ) -Shared -Confirm:$false + } | Should -Throw + } + } + Context "Tests for Windows certificate store" { + It "Create new private store and skip certificate linking" { + { New-CredentialStore -UseCertStore -Force } | Should -Not -Throw + $CS = Get-CredentialStore + $CS.PfxCertificate | Should -Be $null + $CS.Thumbprint | Should -Not -Be $null + $res = Test-CSCertificate -Type Private + #Write-Verbose -Message ('res: {0}' -f $res) -Verbose + $res | Should -Be $true + + } + It "Create new shared store and skipt certificate linking" { + { New-CredentialStore -Shared -UseCertStore -Force } | Should -Not -Throw + $CS = Get-CredentialStore -Shared + $CS.PfxCertificate | Should -Be $null + $CS.Thumbprint | Should -Not -Be $null + $res = Test-CSCertificate -Type Shared + #Write-Verbose -Message ('res: {0}' -f $res) -Verbose + $res | Should -Be $true + } + } +} + +AfterAll { + # Cleanup test stores and restore existing ones. + $VerbosePreference = "Continue" + Write-Verbose "Restoring private CredentialStore" + If (Test-Path -Path $BackupFile) { + If (Test-Path -Path $CSPath) { + Remove-Item -Path $CSPath + Move-Item -Path $BackupFile -Destination $CSPath + } + } + + Write-Verbose "Restoring shared CredentialStore" + If (Test-Path -Path $BackupSharedFile) { + If (Test-Path -Path $CSShared) { + Remove-Item -Path $CSShared + Move-Item -Path $BackupSharedFile -Destination $CSShared + } + } + $VerbosePreference = "SilentlyContinue" + +} diff --git a/tests/Store/02_Test-CredentialStore.Tests.ps1 b/src/Store/Test-CredentialStore.Tests.ps1 similarity index 58% rename from tests/Store/02_Test-CredentialStore.Tests.ps1 rename to src/Store/Test-CredentialStore.Tests.ps1 index 6cdeca9..3ebb096 100644 --- a/tests/Store/02_Test-CredentialStore.Tests.ps1 +++ b/src/Store/Test-CredentialStore.Tests.ps1 @@ -1,24 +1,36 @@ -$RepoRoot = (Get-Item -Path (Get-GitDirectory) -Force).Parent | Select-Object -ExpandProperty 'FullName' +BeforeAll { + $ManifestFile = (Get-Item -Path "./src/*.psd1").FullName + Import-Module $ManifestFile -Force + + $PrivateFunctions = (Get-ChildItem -Path "./src/Private/*.ps1" | Where-Object { + $_.BaseName -notmatch '.Tests' + } + ).FullName + foreach ( $func in $PrivateFunctions) { + . $func + } +} Describe "Test-CredentialStore" { Context "Basic logic tests" { - $TestCredentialStore = Join-Path -Path $RepoRoot -ChildPath '/resources/cs/CredentialStore.json' - It "Test1: Should Not Throw" { + It "Should Not Throw" { + $TestCredentialStore = './resources/cs/CredentialStore.json' { Test-CredentialStore -Shared -Path $TestCredentialStore } | Should -Not -Throw } - It "Test2: Read valid CredentialStore" { + It "Read valid CredentialStore" { + $TestCredentialStore = './resources/cs/CredentialStore.json' $res = Test-CredentialStore -Shared -Path $TestCredentialStore $res | Should -Be $true } - It "Test3: Read a broken CredentialStore" { - $BrokenCS = Join-Path -Path $RepoRoot -ChildPath '{0}/resources/cs/Broken_CS.json' + It "Read a broken CredentialStore" -Skip { + $BrokenCS = './resources/cs/Broken_CS.json' $oWarningPreference = $WarningPreference $WarningPreference = 'SilentlyContinue' $res = Test-CredentialStore -Shared -Path $BrokenCS $res | Should -Be $false $WarningPreference = $oWarningPreference } - It "Test4: Not existing path should return false" { + It "Not existing path should return false" { if ($isWindows -or ($PSVersionTable.PSVersion.Major -eq 5)) { Test-CredentialStore -Shared -Path 'C:\foobar\CredentialStore.json' | Should -Be $false } @@ -26,7 +38,7 @@ Describe "Test-CredentialStore" { Test-CredentialStore -Shared -Path '/var/opt/foo.json' | Should -Be $false } } - It "Test5: testing private CredentialStore path" { + It "testing private CredentialStore path" { if (Test-Path -Path (Get-DefaultCredentialStorePath)) { Remove-Item -Path (Get-DefaultCredentialStorePath) } diff --git a/tests/.gitkeep b/tests/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/tests/00_BasicModule.Tests.ps1 b/tests/00_BasicModule.Tests.ps1 deleted file mode 100644 index 6c846ad..0000000 --- a/tests/00_BasicModule.Tests.ps1 +++ /dev/null @@ -1,17 +0,0 @@ -$RepoRoot = (Get-Item -Path (Get-GitDirectory) -Force).Parent | Select-Object -ExpandProperty 'FullName' -Write-Verbose -Message ('RepoRoot: {0}' -f $RepoRoot) -Verbose - -$ManifestFilePath = Join-Path -Path $RepoRoot -ChildPath '/src/PSCredentialStore.psd1' -Write-Verbose -Message ("ManifestFilePath: {0}" -f $ManifestFilePath) -Verbose -Describe "Pre-Flight module tests" { - Context "Manifest file related" { - It "Test the parsed file itself" { - { Test-ModuleManifest -Path $ManifestFilePath -Verbose } | Should -Not -Throw - } - } - Context "Module consistency tests" { - It "Importing should work" { - { Import-Module -Name $ManifestFilePath -Global -Force -Verbose } | Should -Not -Throw - } - } -} diff --git a/tests/Certificate/50_New-CSCertAttribute.Tests.ps1 b/tests/Certificate/50_New-CSCertAttribute.Tests.ps1 deleted file mode 100644 index e6f5cb4..0000000 --- a/tests/Certificate/50_New-CSCertAttribute.Tests.ps1 +++ /dev/null @@ -1,7 +0,0 @@ -Describe "New-CSCertAttribute" { - Context "Basis Tests" { - It "Test1: Should not throw " { - { New-CSCertAttribute -Country 'DE' -State 'BW' -City 'KA' -Organization 'IT' -OrganizationalUnitName'' -CommonName 'Mycert' } | Should -Not -Throw - } - } -} diff --git a/tests/Certificate/51_New-CSCertificate.Tests.ps1 b/tests/Certificate/51_New-CSCertificate.Tests.ps1 deleted file mode 100644 index aac7f74..0000000 --- a/tests/Certificate/51_New-CSCertificate.Tests.ps1 +++ /dev/null @@ -1,15 +0,0 @@ -Describe "New-CSCertificate" { - Context "Basic Tests" { - It "Test1: Should not throw" { - - $attribs = New-CSCertAttribute -Country 'DE' -State 'BW' -City 'KA' -Organization 'IT' -OrganizationalUnitName'' -CommonName 'Mycert' - - $CertAttribs = @{ - CRTAttribute = $attribs - KeyName = Join-Path -Path (Get-TempDir) -ChildPath '/foo.key' - CertName = Join-Path -Path (Get-TempDir) -ChildPath '/cert.pfx' - } - { New-CSCertificate @CertAttribs } | Should -Not -Throw - } - } -} diff --git a/tests/PfxCertificate/60_Test-CSPfxCertificate.Tests.ps1 b/tests/PfxCertificate/60_Test-CSPfxCertificate.Tests.ps1 deleted file mode 100644 index 9665cb6..0000000 --- a/tests/PfxCertificate/60_Test-CSPfxCertificate.Tests.ps1 +++ /dev/null @@ -1,10 +0,0 @@ -Describe "Test-CSPfxCertificate" { - Context "Basic Tests" { - It "Should not Throw" { - { Test-CSPfxCertificate -Thumbprint '12345' -StoreName My -StoreLocation CurrentUser } | Should -Not -Throw - } - It "Should return false" { - Test-CSPfxCertificate -Thumbprint '12345' -StoreName My -StoreLocation CurrentUser | Should -Be $false - } - } -} diff --git a/tests/Private/01_Get-ModuleBase.Tests.ps1 b/tests/Private/01_Get-ModuleBase.Tests.ps1 deleted file mode 100644 index 0e5d972..0000000 --- a/tests/Private/01_Get-ModuleBase.Tests.ps1 +++ /dev/null @@ -1,7 +0,0 @@ -Describe "Get-ModuleBase" { - Context "Basic syntax check" { - It "Test1: Should not throw" { - { Get-ModuleBase } | Should -Not -Throw - } - } -} diff --git a/tests/Private/01_Get-RandomAESKey.Tests.ps1 b/tests/Private/01_Get-RandomAESKey.Tests.ps1 deleted file mode 100644 index 9a9c72f..0000000 --- a/tests/Private/01_Get-RandomAESKey.Tests.ps1 +++ /dev/null @@ -1,13 +0,0 @@ -Describe "Get-RandomKey" { - Context "Basic input tests" { - It "Test1: Should not throw " { - {Get-RandomAESKey} | Should -Not -Throw - } - } - Context "Basic syntax check" { - It "Test2: Should return a key with a length of 32 bytes" { - $Key = Get-RandomAESKey - $Key.length | Should -Be 32 - } - } -} diff --git a/tests/Private/01_Resolve-Dependency.Tests.ps1 b/tests/Private/01_Resolve-Dependency.Tests.ps1 deleted file mode 100644 index 755ce9a..0000000 --- a/tests/Private/01_Resolve-Dependency.Tests.ps1 +++ /dev/null @@ -1,35 +0,0 @@ -Describe "Resolve-Dependency" { - Context "Basic syntax check" { - Mock Get-ModuleBase {return (Join-Path -Path $PWD -ChildPath '/resources')} - Mock Test-Module {return $true} - It "Test1: Should not throw" { - { Resolve-Dependency -Name 'foobar2000' } | Should -Not -Throw - } - It "Test2: Output type should be bool" { - Resolve-Dependency -Name 'foobar2000' | Should -BeOfType bool - } - } - Context "Enforce Error" { - # Return incorrect module base to enforce there is no config file. - Mock Get-ModuleBase { - if ($IsWindows) {return "C:\"} - elseif ($isLinux) {return "/"} - } - It "Missing dependency file should not cause an error" { - { Resolve-Dependency -Name 'awesome'} | Should -Not -Throw - } - - It "Missing dependency file should return true" { - Resolve-Dependency -Name 'awesome' | Should -Be $true - } - } - Context "Testing input variations" { - Mock Get-ModuleBase {return (Join-Path -Path $PWD -ChildPath '/resources')} - It "Should return true if all given dependencies exist" { - Resolve-Dependency -Name 'Existing' | Should -Be $true - } - It "Mixed results should return false" { - Resolve-Dependency -Name 'PSGetMixed' | Should -Be $false - } - } -} diff --git a/tests/Store/02_New-CredentialStore.Tests.ps1 b/tests/Store/02_New-CredentialStore.Tests.ps1 deleted file mode 100644 index ec58d99..0000000 --- a/tests/Store/02_New-CredentialStore.Tests.ps1 +++ /dev/null @@ -1,117 +0,0 @@ -# Backup existing credential stores -$VerbosePreference = "Continue" -Write-Verbose "Backup private Credential Store..." -$CSPath = Get-DefaultCredentialStorePath -$BackupFile = "{0}.back" -f $CSPath -If (Test-Path -Path $CSPath) { - Move-Item -Path $CSPath -Destination $BackupFile -} -Write-Verbose "Backup shared CredentialStore..." -$CSShared = Get-DefaultCredentialStorePath -Shared -$BackupSharedFile = "{0}.back" -f $CSShared -If (Test-Path -Path $CSShared) { - Move-Item -Path $CSShared -Destination $BackupSharedFile -} -Write-Verbose "Remove old CredentialStore in Temp dir" -$CSTemp = Join-Path -Path (Get-TempDir) -ChildPath '/CredentialStore.json' -If (Test-Path -Path $CSTemp) { - Remove-Item -Path $CSTemp -} -$VerbosePreference = "SilentlyContinue" - -Describe "New-CredentialStore" { - Context "Private CS tests" { - $pCS = Get-DefaultCredentialStorePath - It "Test1: Create new private CredentialStore" { - { New-CredentialStore -Confirm:$false } | Should -Not -Throw - $result = Test-Path -Path $pCS - $CS = Get-Content -Path $pCS -Raw | ConvertFrom-Json - ($result -eq $true) -and ($CS.Type -eq "Private") | Should -Be $true - } - It "Test2: Try to override private Store" { - { New-CredentialStore -Confirm:$false } | Should -Throw - } - It "Test3: Reset existing Credential Store" { - $now = Get-Date - $CS = Get-Content -Path $pCS -Raw | ConvertFrom-Json - $CSCreation = [DateTime]$CS.Created - New-CredentialStore -Confirm:$false -Force - $now -gt $csCreation | Should -Be $true - } - } - Context "Shared CS tests" { - $sCS = Get-DefaultCredentialStorePath -Shared - It "Test1: Create a new Shared Credential Store" { - { New-CredentialStore -Confirm:$false -Shared } | Should -Not -Throw - Test-Path -Path $sCS | Should -Be $true - } - It "Test2: Try to override existing shared CS" { - { New-CredentialStore -Shared -Confirm:$false } | Should -Throw - } - It "Test3: Reset shared CredentialStore" { - $now = Get-Date - $CS = Get-Content -Path $sCS -Raw | ConvertFrom-Json - $CSCreation = [DateTime]$CS.Created - New-CredentialStore -Force -Shared -Confirm:$false - $now -gt $csCreation | Should -Be $true - } - } - Context "Custom Shared CS tests" { - $cCS = Join-Path -Path (Get-TempDir) -ChildPath "CredentialStore.json" - It "Test1: Create new custom shared" { - { New-CredentialStore -Path $cCS -Shared -Confirm:$false } | Should -Not -Throw - } - It "Test2: Try to override exiting one" { - { New-CredentialStore -Path $cCS -Shared -Confirm:$false } | Should -Throw - } - It "Test3: Reset existing custom CredentialStore" { - { New-CredentialStore -Path $cCS -Shared -Force -Confirm:$false } | Should -Not -Throw - } - } - Context "Test exception handling" { - Mock Out-File { throw "foobar exception" } - It "JSON Conversion should fail and throw" { - { New-CredentialStore -Path (Join-Path -Path (Get-TempDir) -ChildPath '/dummy.json') -Shared -Confirm:$false } | Should -Throw - } - } - Context "Tests for Windows certificate store" { - It "Create new private store and skip certificate linking" { - { New-CredentialStore -UseCertStore -Force } | Should -Not -Throw - $CS = Get-CredentialStore - $CS.PfxCertificate | Should -Be $null - $CS.Thumbprint | Should -Not -Be $null - $res = Test-CSCertificate -Type Private - #Write-Verbose -Message ('res: {0}' -f $res) -Verbose - $res | Should -Be $true - - } - It "Create new shared store and skipt certificate linking" { - { New-CredentialStore -Shared -UseCertStore -Force } | Should -Not -Throw - $CS = Get-CredentialStore -Shared - $CS.PfxCertificate | Should -Be $null - $CS.Thumbprint | Should -Not -Be $null - $res = Test-CSCertificate -Type Shared - #Write-Verbose -Message ('res: {0}' -f $res) -Verbose - $res | Should -Be $true - } - } -} - -# Cleanup test stores and restore existing ones. -$VerbosePreference = "Continue" -Write-Verbose "Restoring private CredentialStore" -If (Test-Path -Path $BackupFile) { - If (Test-Path -Path $CSPath) { - Remove-Item -Path $CSPath - Move-Item -Path $BackupFile -Destination $CSPath - } -} - -Write-Verbose "Restoring shared CredentialStore" -If (Test-Path -Path $BackupSharedFile) { - If (Test-Path -Path $CSShared) { - Remove-Item -Path $CSShared - Move-Item -Path $BackupSharedFile -Destination $CSShared - } -} -$VerbosePreference = "SilentlyContinue" diff --git a/tests/Store/03_Get-CredentialStore.Tests.ps1 b/tests/Store/03_Get-CredentialStore.Tests.ps1 deleted file mode 100644 index 0bf63aa..0000000 --- a/tests/Store/03_Get-CredentialStore.Tests.ps1 +++ /dev/null @@ -1,32 +0,0 @@ -$RepoRoot = (Get-Item -Path (Get-GitDirectory) -Force).Parent | Select-Object -ExpandProperty 'FullName' - -Describe "Get-CredentialStore" { - Context "Basic logic tests" { - $TestCredentialStore = Join-Path -Path $RepoRoot -ChildPath 'resources/cs/CredentialStore.json' - $TestPfxCert = Join-Path -Path $RepoRoot -ChildPath 'resources/cs/PSCredentialStore.pfx' - 'TestCredentialStore: {0}' -f $TestCredentialStore - It "Test1: Read CS without params" { - if (! (Test-Path -Path (Get-DefaultCredentialStorePath)) ) { - { New-CredentialStore -Force } | Should -Not -Throw - - } - { Get-CredentialStore } | Should -Not -Throw - } - It "Test2: Read Credential Store with testing data" { - { Use-CSCertificate -Shared -CredentialStore $TestCredentialStore -Path $TestPfxCert } | Should -Not -Throw - { Get-CredentialStore -Shared -Path $TestCredentialStore } | Should -Not -Throw - } - It "Test3: Not existing path should return false" { - { Get-CredentialStore -Shared -Path './CredentialStore.json' } | Should -Throw "Could not find the CredentialStore." - } - } - Context "Testing invalid json data" { - #Mock Test-CredentialStore {return $true} - #Mock Get-Content {return '"foo":"bar",'} - $BrokenCS = Join-Path -Path $RepoRoot -ChildPath 'resources/cs/Broken_CS.json' - Write-Verbose -Message ('BrokenCS Path: {0}' -f $BrokenCS) -Verbose - It "Should throw with invalid CredentialStore" { - { Get-CredentialStore -Path -Shared $BrokenCS } | Should -Throw - } - } -} diff --git a/tools/DroneIO.psm1 b/tools/DroneIO.psm1 index 4a3dd85..6f333d6 100644 --- a/tools/DroneIO.psm1 +++ b/tools/DroneIO.psm1 @@ -80,6 +80,35 @@ function Invoke-InstallDependencies { } } + +function Start-PSScriptAnalyzer { + [CmdletBinding()] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSUseShouldProcessForStateChangingFunctions', + '', + Justification = 'justification' + )] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute( + 'PSProvideCommentHelp', + '', + Justification = 'internal function' + )] + param () + + process { + $AnalyzerSettings = @{ + Path = './src/' + Recurse = $true + Settings = './tools/PSScriptAnalyzerSettings.psd1' + ReportSummary = $true + ErrorAction = 'Stop' + } + $AnalyzerResults = Invoke-ScriptAnalyzer @AnalyzerSettings + if ( $AnalyzerResults ) { + Write-Output -InputObject $AnalyzerResults + } + } +} function Invoke-Linter { [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( @@ -90,16 +119,20 @@ function Invoke-Linter { param () process { - Import-Module -Name PSScriptAnalyzer - $AnalyzerSettings = @{ - Path = './src/' - Recurse = $true - Settings = './tools/PSScriptAnalyzerSettings.psd1' - ReportSummary = $true - ErrorAction = 'Stop' - } try { - $AnalyzerResults = Invoke-ScriptAnalyzer @AnalyzerSettings + $AnalyzerResults = Start-PSScriptAnalyzer + } + catch { + Write-Debug -Message $_.Exception.Message -Debug + if ($_.Exception.Message -match 'Object reference not set') { + Write-Debug -Message 'ReRun PSScriptAnalyzer' -Debug + $AnalyzerResults = Start-PSScriptAnalyzer + } + else { + Write-Error -Message 'PSScriptAnalyzer failer' + } + } + finally { if ( $AnalyzerResults ) { $AnalyzerResults | Sort-Object -Property @( "ScriptName", @@ -111,12 +144,10 @@ function Invoke-Linter { "RuleName", "Message" ) -AutoSize | Out-String | Write-Verbose -Verbose + Update-BuildStateFile + throw 'PS Script Analyzer failed!' } } - catch { - Write-Debug -Message $_.Exception.Message -Debug - Write-Error -Message 'PSScriptAnalyzer failer' - } } } @@ -171,8 +202,49 @@ function Invoke-UnitTest { $PesterConf.Filter.ExcludeTag = $ExcludeTag } $TestResults = Invoke-Pester -Configuration $PesterConf -ErrorAction 'Stop' + + if ($TestResults.FailedCount -gt 0) { + Update-BuildStateFile + throw ('{0} tests failed!' -f $TestResults.FailedCount) + } + if ($PassThru.IsPresent) { Write-Output -InputObject $TestResults } } } + +function Update-BuildStateFile { + [CmdletBinding()] + param ( + [Parameter(Mandatory = $false)] + [ValidateNotNullOrEmpty()] + [string]$StepName = $Env:DRONE_FAILED_STEPS + ) + + process { + $StateFilePath = Join-Path -Path $PWD -ChildPath './STATE.xml' + if (Test-Path -Path $StateFilePath) { + $StateContent = Import-Clixml -Path $StateFilePath + $StateContent.Steps += $StepName + } + else { + $StateContent = [PSCustomObject]@{ + Steps = @($StepName) + } + } + Export-Clixml -Path $StateFilePath -InputObject $StateContent -Force -Encoding utf8NoBOM + } +} + +function Invoke-BuildState { + [CmdletBinding()] + param () + + process { + $StateFilePath = Join-Path -Path $PWD -ChildPath './STATE.xml' + if ( Test-Path -Path $StateFilePath ) { + throw 'One one more pipeline steps failed. Marking the pipeline as failed!' + } + } +}