diff --git a/F5-LTM/F5-LTM.Tests.ps1 b/F5-LTM/F5-LTM.Tests.ps1 new file mode 100644 index 0000000..1011e82 --- /dev/null +++ b/F5-LTM/F5-LTM.Tests.ps1 @@ -0,0 +1,259 @@ +# PSScriptAnalyzer - ignore creation of a SecureString using plain text for the contents of this script file +[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "")] +param() + +$scriptroot = Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Path) +Import-Module (Join-Path $scriptroot 'F5-LTM\F5-LTM.psm1') -Force + +Describe 'Get-BigIPPartition' -Tags 'Unit' { + InModuleScope F5-LTM { + Context "Strict mode PS$($PSVersionTable.PSVersion.Major)" { + Set-StrictMode -Version latest + +#region Arrange: Initialize Mocks + + # Mocking Invoke-RestMethodOverride for unit testing Module without F5 device connectivity + Mock Invoke-RestMethodOverride { + # Behavior (not state) verification is applied to this mock. + # Therefore, the output need only meet the bare minimum requirements to maximize code coverage of the Subject Under Test. + if ($URI -match 'JSON') { + # This case included to support maximum code coverage + [pscustomobject]@{ + items=$null + name='name' + subPath='subPath' + selfLink="https://localhost/mgmt/tm/sys/folder/~name?ver=12.1.2" + } + } else { + [pscustomobject]@{ + items=@(@{name='bogus item for testing';subPath='subPath'}) + name='name' + selfLink="https://localhost/mgmt/tm/sys/folder/~name?ver=12.1.2" + } + } + } + # Mock session with fictional IP,credentials, and version + $mocksession = [pscustomobject]@{ + Name = '192.168.1.1' + BaseURL = 'https://192.168.1.1/mgmt/tm/ltm/' + Credential = New-Object System.Management.Automation.PSCredential ('georgejetson', (ConvertTo-SecureString 'judyr0ck$!' -AsPlainText -Force)) + LTMVersion = [Version]'11.5.1' + WebSession = New-Object Microsoft.PowerShell.Commands.WebRequestSession + } | Add-Member -Name GetLink -MemberType ScriptMethod { + param($Link) + $Link -replace 'localhost', $this.Name + } -PassThru + +#endregion Arrange: Initialize Mocks + + It "Requests BigIP partitions *" { + Get-BigIPPartition -F5Session $mocksession | + ForEach-Object { $_.PSObject.TypeNames[0] | Should Be 'string' } + Assert-MockCalled Invoke-RestMethodOverride -Times 1 -Exactly -Scope It -ParameterFilter { $Uri.AbsoluteUri -eq ($mocksession.BaseURL -replace 'ltm/','sys/folder/?$select=name,subPath') } + } + # JSON test also forces a codecoverage scenario for a single item without an items property returned from the F5 + It "Requests BigIP partitions by Name ''" -TestCases @(@{name='Common'},@{name='Development'},@{name='Production'},@{name='JSON'}) { + param($name) + Get-BigIPPartition -F5Session $mocksession -Name $name | + ForEach-Object { $_.PSObject.TypeNames[0] | Should Be 'string' } + Assert-MockCalled Invoke-RestMethodOverride -Times 1 -Exactly -Scope It -ParameterFilter { $Uri.AbsoluteUri -eq (($mocksession.BaseURL -replace 'ltm/','sys/folder') + ('/~{0}?$select=name,subPath' -f $name)) } + } + It "Requests BigIP partitions with Name [-Folder alias] ''" -TestCases @(@{name='Common'}) { + param($name) + Get-BigIPPartition -F5Session $mocksession -Folder $name | + ForEach-Object { $_.PSObject.TypeNames[0] | Should Be 'string' } + Assert-MockCalled Invoke-RestMethodOverride -Times 1 -Exactly -Scope It -ParameterFilter { $Uri.AbsoluteUri -eq (($mocksession.BaseURL -replace 'ltm/','sys/folder') + ('/~{0}?$select=name,subPath' -f $name)) } + } + It "Requests BigIP partitions with Name [-Partition alias] ''" -TestCases @(@{name='Common'}) { + param($name) + Get-BigIPPartition -F5Session $mocksession -Partition $name | + ForEach-Object { $_.PSObject.TypeNames[0] | Should Be 'string' } + Assert-MockCalled Invoke-RestMethodOverride -Times 1 -Exactly -Scope It -ParameterFilter { $Uri.AbsoluteUri -eq (($mocksession.BaseURL -replace 'ltm/','sys/folder') + ('/~{0}?$select=name,subPath' -f $name)) } + } + It "Requests BigIP partitions by Name[]" -TestCases @(@{name=@('Common','Development','Production')}) { + param($name) + Get-BigIPPartition -F5Session $mocksession -Name $name | + ForEach-Object { $_.PSObject.TypeNames[0] | Should Be 'string' } + Assert-MockCalled Invoke-RestMethodOverride -Times 3 -Exactly -Scope It + } + It "Requests BigIP partitions by Name From Pipeline" -TestCases @(@{ object = ([pscustomobject]@{name = 'Common'}),([pscustomobject]@{name = 'Development'}) }) { + param($object) + $object | Get-BigIPPartition -F5Session $mocksession | + ForEach-Object { $_.PSObject.TypeNames[0] | Should Be 'string' } + Assert-MockCalled Invoke-RestMethodOverride -Times ($object.Count) -Exactly -Scope It + } + } + } +} + +Describe 'Get-HealthMonitor' -Tags 'Unit' { + InModuleScope F5-LTM { + Context "Strict mode PS$($PSVersionTable.PSVersion.Major)" { + Set-StrictMode -Version latest + +#region Arrange: Initialize Mocks + + # We aren't testing Get-HealthMonitorType here, just Get-HealthMonitor + # Using a mock to return a static set of types for use by subsequent requests + $healthmonitortypes = @('http','https','icmp','smtp','tcp') + Mock Get-HealthMonitorType { $healthmonitortypes } + + # Mocking Invoke-RestMethodOverride for unit testing Module without F5 device connectivity + Mock Invoke-RestMethodOverride { + # Behavior (not state) verification is applied to this mock. + # Therefore, the output need only meet the bare minimum requirements to maximize code coverage of the Subject Under Test. + [pscustomobject]@{ + kind="tm:ltm:monitor:http:httpstate" + items=@('bogus item for testing') + name='name' + partition='partition' + fullPath='/partition/name' + selfLink="https://localhost/mgmt/tm/ltm/monitor/type/~partition~name?ver=12.1.2" + } + } + # Mock session with fictional IP,credentials, and version + $mocksession = [pscustomobject]@{ + Name = '192.168.1.1' + BaseURL = 'https://192.168.1.1/mgmt/tm/ltm/' + Credential = New-Object System.Management.Automation.PSCredential ('georgejetson', (ConvertTo-SecureString 'judyr0ck$!' -AsPlainText -Force)) + LTMVersion = [Version]'11.5.1' + WebSession = New-Object Microsoft.PowerShell.Commands.WebRequestSession + } | Add-Member -Name GetLink -MemberType ScriptMethod { + param($Link) + $Link -replace 'localhost', $this.Name + } -PassThru + +#endregion Arrange: Initialize Mocks + + It "Requests health monitors *" { + Get-HealthMonitor -F5Session $mocksession | + ForEach-Object { $_.PSObject.TypeNames[0] | Should Be 'PoshLTM.HealthMonitor' } + Assert-MockCalled Get-HealthMonitorType -Times 1 -Exactly -Scope It + Assert-MockCalled Invoke-RestMethodOverride -Times $healthmonitortypes.Count -Exactly -Scope It + } + It "Requests health monitors of type ''" -TestCases @(@{type='http'},@{type='https'}) { + param($type) + Get-HealthMonitor -F5Session $mocksession -Type $type | + ForEach-Object { $_.PSObject.TypeNames[0] | Should Be 'PoshLTM.HealthMonitor' } + Assert-MockCalled Get-HealthMonitorType -Times 0 -Scope It + Assert-MockCalled Invoke-RestMethodOverride -Times 1 -Exactly -Scope It -ParameterFilter { $Uri.AbsoluteUri -eq ('{0}monitor/{1}/' -f $mocksession.BaseURL,$type) } + } + It "Requests health monitors in partition ''" -TestCases @(@{partition='Development'},@{partition='Common'}) { + param($partition) + Get-HealthMonitor -F5Session $mocksession -Partition $partition | + ForEach-Object { $_.PSObject.TypeNames[0] | Should Be 'PoshLTM.HealthMonitor' } + Assert-MockCalled Get-HealthMonitorType -Times 1 -Exactly -Scope It + Assert-MockCalled Invoke-RestMethodOverride -Times $healthmonitortypes.Count -Exactly -Scope It + } + It "Requests health monitors in partition '' by Name ''" -TestCases @(@{partition='Common';name='http'},@{partition='Development';name='Test'}) { + param($partition, $name) + Get-HealthMonitor -F5Session $mocksession -Partition $partition -Name $name | + ForEach-Object { $_.PSObject.TypeNames[0] | Should Be 'PoshLTM.HealthMonitor' } + Assert-MockCalled Get-HealthMonitorType -Times 1 -Exactly -Scope It + Assert-MockCalled Invoke-RestMethodOverride -Times $healthmonitortypes.Count -Exactly -Scope It + } + It "Requests health monitors by fullPath ''" -TestCases @(@{fullpath='/Common/https'}) { + param($fullpath) + Get-HealthMonitor -F5Session $mocksession -Name $fullPath | + ForEach-Object { $_.PSObject.TypeNames[0] | Should Be 'PoshLTM.HealthMonitor' } + Assert-MockCalled Get-HealthMonitorType -Times 1 -Exactly -Scope It + Assert-MockCalled Invoke-RestMethodOverride -Times $healthmonitortypes.Count -Exactly -Scope It + } + It "Requests health monitors by Name[]" -TestCases @(@{name=@('http','https','tcp')}) { + param($name) + Get-HealthMonitor -F5Session $mocksession -Name $name | + ForEach-Object { $_.PSObject.TypeNames[0] | Should Be 'PoshLTM.HealthMonitor' } + Assert-MockCalled Get-HealthMonitorType -Times 1 -Exactly -Scope It + Assert-MockCalled Invoke-RestMethodOverride -Times ($name.Count * $healthmonitortypes.Count) -Exactly -Scope It + } + It "Requests health monitors by Name From Pipeline" -TestCases @(@{name=@('http','https')}) { + param($name) + $name | Get-HealthMonitor -F5Session $mocksession | + ForEach-Object { $_.PSObject.TypeNames[0] | Should Be 'PoshLTM.HealthMonitor' } + Assert-MockCalled Get-HealthMonitorType -Times 1 -Exactly -Scope It + Assert-MockCalled Invoke-RestMethodOverride -Times ($name.Count * $healthmonitortypes.Count) -Exactly -Scope It + } + It "Requests health monitors by Name and Partition From Pipeline" -TestCases @(@{ object = ([pscustomobject]@{name = 'http'; partition = 'Common'}),([pscustomobject]@{name = 'host_ashx'; partition = 'Common'}) }) { + param($object) + $object | Get-HealthMonitor -F5Session $mocksession | + ForEach-Object { $_.PSObject.TypeNames[0] | Should Be 'PoshLTM.HealthMonitor' } + Assert-MockCalled Get-HealthMonitorType -Times 1 -Exactly -Scope It + Assert-MockCalled Invoke-RestMethodOverride -Times ($object.Count * $healthmonitortypes.Count) -Exactly -Scope It + } + } + } +} +Describe 'New-F5Session' -Tags 'Unit' { + InModuleScope F5-LTM { + Context "Strict mode PS$($PSVersionTable.PSVersion.Major)" { + Set-StrictMode -Off + +#region Arrange: Initialize Mocks + + # Mocking Invoke-RestMethodOverride for unit testing Module without F5 device connectivity + Mock Invoke-RestMethodOverride { + switch ($LTMName) { + 'version11' { + if ($URI -match 'sys/version/') { + '{"version":"11.5.1"}' + } else { + throw '404 Not found' + } + } + Default { + if ($URI -match 'mgmt/shared/authn/login') { + [pscustomobject]@{token=@{token='dummytoken';starttime=[DateTime]::Now;uuid='9912a8f9-6fa9-474d-b00d-3f16226352b7'}} + #} elseif ($URI -match 'mgmt/shared/authz/tokens') { + # token extension request currently doesn't have to return anything, just not fail + } elseif ($URI -match 'sys/version/') { + '{"version":"12.1.0"}' + } + } + } + } + Mock Invoke-WebRequest { $true } + + $credentials = New-Object System.Management.Automation.PSCredential ('georgejetson', (ConvertTo-SecureString 'judyr0ck$!' -AsPlainText -Force)) + +#endregion Arrange: Initialize Mocks + + It "`$Script:F5Session initialized on 1st call" { + $testsession = New-F5Session -LTMName 'any' -LTMCredentials $credentials -PassThru + Assert-MockCalled Invoke-WebRequest -Times 0 -Exactly -Scope It # Only v11 calls Invoke-WebRequest + Assert-MockCalled Invoke-RestMethodOverride -Times 2 -Exactly -Scope It + $Script:F5Session.BaseURL -eq $testsession.BaseURL | Should Be $true + $Script:F5Session.LTMVersion -eq $testsession.LTMVersion | Should Be $true + } + It "`$Script:F5Session overridden with -Default switch" { + $testsession = New-F5Session -LTMName 'newdefault' -LTMCredentials $credentials -Default -PassThru + Assert-MockCalled Invoke-WebRequest -Times 0 -Exactly -Scope It # Only v11 calls Invoke-WebRequest + Assert-MockCalled Invoke-RestMethodOverride -Times 2 -Exactly -Scope It + $Script:F5Session.BaseURL -eq $testsession.BaseURL | Should Be $true + $Script:F5Session.LTMVersion -eq $testsession.LTMVersion | Should Be $true + } + It "v11: Authentication with Credentials" { + $testsession = New-F5Session -LTMName 'version11' -LTMCredentials $credentials -PassThru + Assert-MockCalled Invoke-WebRequest -Times 1 -Exactly -Scope It # Only v11 calls Invoke-WebRequest + Assert-MockCalled Invoke-RestMethodOverride -Times 2 -Exactly -Scope It + $testsession.LTMVersion -eq [Version]'11.5.1' | Should Be $true + } + It "v12+: Authentication with X-F5-Auth-Token header" { + $testsession = New-F5Session -LTMName 'version12' -LTMCredentials $credentials -PassThru + Assert-MockCalled Invoke-WebRequest -Times 0 -Scope It # Only v11 calls Invoke-WebRequest + Assert-MockCalled Invoke-RestMethodOverride -Times 2 -Exactly -Scope It + $testsession.WebSession.Headers.Keys.Contains('X-F5-Auth-Token') | Should Be $true + $testsession.WebSession.Headers.Keys.Contains('Token-Expiration') | Should Be $true + } + It "v12+: Authentication with X-F5-Auth-Token header + custom TokenLifespan" { + $testsession = New-F5Session -LTMName 'version12' -LTMCredentials $credentials -TokenLifespan 36000 -PassThru + Assert-MockCalled Invoke-WebRequest -Times 0 -Scope It # Only v11 calls Invoke-WebRequest + Assert-MockCalled Invoke-RestMethodOverride -Times 3 -Exactly -Scope It #3rd call for TokenLifespan change + $testsession.WebSession.Headers.Keys.Contains('X-F5-Auth-Token') | Should Be $true + $testsession.WebSession.Headers.Keys.Contains('Token-Expiration') | Should Be $true + } + It "Throws an error if TokenLifespan is out of range" { + { New-F5Session -LTMName 'version12' -LTMCredentials $credentials -TokenLifespan 60000 } | Should Throw + } + } + } +} \ No newline at end of file diff --git a/F5-LTM/F5-LTM.psm1 b/F5-LTM/F5-LTM.psm1 index 74bb3d3..dd06513 100644 --- a/F5-LTM/F5-LTM.psm1 +++ b/F5-LTM/F5-LTM.psm1 @@ -18,31 +18,28 @@ Add-Type -Path "${PSScriptRoot}\Validation.cs" Add-Type -Path "${PSScriptRoot}\TypeData\PoshLTM.Types.cs" Update-FormatData "${PSScriptRoot}\TypeData\PoshLTM.Format.ps1xml" $ScriptPath = Split-Path $MyInvocation.MyCommand.Path - #region Load Public Functions -try { Get-ChildItem "$ScriptPath\Public" -Filter *.ps1 -Recurse| Select-Object -Expand FullName | ForEach-Object { $Function = Split-Path $_ -Leaf - . $_ - } -} catch { - Write-Warning ("{0}: {1}" -f $Function,$_.Exception.Message) - Continue -} + try { + . $_ + } catch { + Write-Warning ("{0}: {1}" -f $Function,$_.Exception.Message) + } + } #endregion #region Load Private Functions -try { - Get-ChildItem "$ScriptPath\Private" -Filter *.ps1 -Recurse | Select-Object -Expand FullName | ForEach-Object { - $Function = Split-Path $_ -Leaf - . $_ - } -} catch { - Write-Warning ("{0}: {1}" -f $Function,$_.Exception.Message) - Continue -} + Get-ChildItem "$ScriptPath\Private" -Filter *.ps1 -Recurse | Select-Object -Expand FullName | ForEach-Object { + $Function = Split-Path $_ -Leaf + try { + . $_ + } catch { + Write-Warning ("{0}: {1}" -f $Function,$_.Exception.Message) + } + } #endregion \ No newline at end of file diff --git a/F5-LTM/Private/Resolve-NestedStats.ps1 b/F5-LTM/Private/Resolve-NestedStats.ps1 index 50b3542..8a891ad 100644 --- a/F5-LTM/Private/Resolve-NestedStats.ps1 +++ b/F5-LTM/Private/Resolve-NestedStats.ps1 @@ -6,7 +6,7 @@ To resolve this discrepancy, this function performs version-specific transformations to the JSON data and returns it in a standardized format with the "entries" property at the top. #> - + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] param ( $F5Session=$Script:F5Session, diff --git a/F5-LTM/Public/Disable-VirtualServer.ps1 b/F5-LTM/Public/Disable-VirtualServer.ps1 index 8148cd8..cf33a98 100644 --- a/F5-LTM/Public/Disable-VirtualServer.ps1 +++ b/F5-LTM/Public/Disable-VirtualServer.ps1 @@ -32,7 +32,7 @@ foreach($vs in $InputObject) { $URI = $F5Session.GetLink($vs.selfLink) $FullPath = $vs.fullPath - $JSON = Invoke-F5RestMethod -Method PATCH -Uri $URI -F5Session $F5Session -Body $JSONBody + $null = Invoke-F5RestMethod -Method PATCH -Uri $URI -F5Session $F5Session -Body $JSONBody Get-VirtualServer -F5Session $F5Session -Name $FullPath } } diff --git a/F5-LTM/Public/Enable-VirtualServer.ps1 b/F5-LTM/Public/Enable-VirtualServer.ps1 index bca95f6..4b05c36 100644 --- a/F5-LTM/Public/Enable-VirtualServer.ps1 +++ b/F5-LTM/Public/Enable-VirtualServer.ps1 @@ -32,7 +32,7 @@ foreach($vs in $InputObject) { $URI = $F5Session.GetLink($vs.selfLink) $FullPath = $vs.fullPath - $JSON = Invoke-F5RestMethod -Method PATCH -Uri $URI -F5Session $F5Session -Body $JSONBody + $null = Invoke-F5RestMethod -Method PATCH -Uri $URI -F5Session $F5Session -Body $JSONBody Get-VirtualServer -F5Session $F5Session -Name $FullPath } } diff --git a/F5-LTM/Public/Get-PoolMemberStats.ps1 b/F5-LTM/Public/Get-PoolMemberStats.ps1 index 6d600e9..5cdf419 100644 --- a/F5-LTM/Public/Get-PoolMemberStats.ps1 +++ b/F5-LTM/Public/Get-PoolMemberStats.ps1 @@ -6,6 +6,7 @@ Pool and member names are case-specific. #> [cmdletBinding()] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] param ( $F5Session=$Script:F5Session, diff --git a/F5-LTM/Public/Set-Pool.ps1 b/F5-LTM/Public/Set-Pool.ps1 index 6aab1aa..fd10bd8 100644 --- a/F5-LTM/Public/Set-Pool.ps1 +++ b/F5-LTM/Public/Set-Pool.ps1 @@ -124,10 +124,10 @@ # This performs the magic necessary for ChgProperties to override $InputObject properties $NewObject = Join-Object -Left $InputObject -Right ([pscustomobject]$ChgProperties) -Join FULL -WarningAction SilentlyContinue - if ($NewObject -ne $null -and $pscmdlet.ShouldProcess($F5Session.Name, "Setting Pool $Name")) { + if ($null -ne $NewObject -and $pscmdlet.ShouldProcess($F5Session.Name, "Setting Pool $Name")) { # We only update the pool if properties other than 'Name' are passed in - If ($NewObject | Get-Member -MemberType NoteProperty | Where Name -ne 'Name'){ + If ($NewObject | Get-Member -MemberType NoteProperty | Where-Object Name -ne 'Name'){ Write-Verbose -Message 'Setting Pool details...' @@ -144,7 +144,7 @@ #endregion - $result = Invoke-F5RestMethod -Method PATCH -URI "$URI" -F5Session $F5Session -Body $JSONBody -ContentType 'application/json' + $null = Invoke-F5RestMethod -Method PATCH -URI "$URI" -F5Session $F5Session -Body $JSONBody -ContentType 'application/json' } diff --git a/F5-LTM/Public/Set-VirtualServer.ps1 b/F5-LTM/Public/Set-VirtualServer.ps1 index 45be117..7ae5ca9 100644 --- a/F5-LTM/Public/Set-VirtualServer.ps1 +++ b/F5-LTM/Public/Set-VirtualServer.ps1 @@ -219,7 +219,7 @@ Function Set-VirtualServer { if (-not $NewProperties.ContainsKey('DestinationIP')) { $destination = if ($InputObject -and $InputObject.destination) { $InputObject.destination - } elseif ($ExistingVirtualServer -ne $null) { + } elseif ($null -ne $ExistingVirtualServer) { $ExistingVirtualServer.destination } if ($destination) { $NewProperties['DestinationIP'] = ($destination -split ':')[0] } @@ -227,7 +227,7 @@ Function Set-VirtualServer { if (-not $NewProperties.ContainsKey('DestinationPort')) { $destination = if ($InputObject -and $InputObject.destination) { $InputObject.destination - } elseif ($ExistingVirtualServer -ne $null) { + } elseif ($null -eq $ExistingVirtualServer) { $ExistingVirtualServer.destination } if ($destination) { $NewProperties['DestinationPort'] = ($destination -split ':')[1] } @@ -243,7 +243,7 @@ Function Set-VirtualServer { } # This performs the magic necessary for ChgProperties to override $InputObject properties $NewObject = Join-Object -Left $InputObject -Right ([pscustomobject]$ChgProperties) -Join FULL -WarningAction SilentlyContinue - if ($NewObject -ne $null -and $pscmdlet.ShouldProcess($F5Session.Name, "Setting VirtualServer $Name")) { + if ($null -ne $NewObject -and $pscmdlet.ShouldProcess($F5Session.Name, "Setting VirtualServer $Name")) { Write-Verbose -Message 'Setting VirtualServer details...' $URI = $F5Session.BaseURL + 'virtual/{0}' -f (Get-ItemPath -Name $Name -Application $Application -Partition $Partition) @@ -259,7 +259,7 @@ Function Set-VirtualServer { #endregion - $result = Invoke-F5RestMethod -Method PATCH -URI "$URI" -F5Session $F5Session -Body $JSONBody -ContentType 'application/json' + $null = Invoke-F5RestMethod -Method PATCH -URI "$URI" -F5Session $F5Session -Body $JSONBody -ContentType 'application/json' } if ($PassThru) { Get-VirtualServer -F5Session $F5Session -Name $Name -Application $Application -Partition $Partition } } diff --git a/appveyor.yml b/appveyor.yml index 98c771a..8df1ae6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -18,7 +18,7 @@ install: # Force bootstrap of the Nuget PackageManagement Provider; Reference: http://www.powershellgallery.com/GettingStarted?section=Get%20Started - ps: Get-PackageProvider -Name NuGet -Force # Install pester PowerShell Unit Testing module - #- cinst -y pester + - cinst -y pester before_test: # Set FunctionsToExport and ModuleVersion in the module manifest (F5-LTM.psd1); Fixes #37 Do not export Private\*.ps1 functions @@ -35,20 +35,14 @@ test_script: # Invoke PSScriptAnalyzer against the module to make sure it's not failing any tests - ps: Invoke-ScriptAnalyzer -Path (Join-Path $env:APPVEYOR_BUILD_FOLDER 'F5-LTM') -Recurse # Invoke-Pester unit tests - #- ps: | - # $testResultsFile = '.\TestsResults.xml' - # - # # run tests - # $res = Invoke-Pester -OutputFormat NUnitXml -OutputFile $testResultsFile -PassThru - # - # # upload results to AppVeyor - # (New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path $testResultsFile)) - # - # # if failures, quit to prevent publish - # if ($res.FailedCount -gt 0) { - # throw "$($res.FailedCount) tests failed." - # } - + - ps: $testResultsFile = '.\TestsResults.xml' + # run tests + - ps: $res = Invoke-Pester -OutputFormat NUnitXml -OutputFile $testResultsFile -PassThru + # upload results to AppVeyor + - ps: (New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path $testResultsFile)) + # if failures, quit to prevent publish + - ps: if ($res.FailedCount -gt 0) { "$($res.FailedCount) tests failed." } + deploy_script: # Publish module to the PowerShellGallery - ps: Publish-Module -NugetApiKey $env:POWERSHELLGALLERY_APIKEY -Path (Join-Path $env:APPVEYOR_BUILD_FOLDER 'F5-LTM')