249 строки
13 KiB
PowerShell
249 строки
13 KiB
PowerShell
<#
|
|
.Synopsis
|
|
Run a test suite in a NAV/BC Container
|
|
.Description
|
|
.Parameter containerName
|
|
Name of the container in which you want to run a test suite
|
|
.Parameter tenant
|
|
tenant to use if container is multitenant
|
|
.Parameter companyName
|
|
company to use if container
|
|
.Parameter credential
|
|
Credentials of the SUPER user if using NavUserPassword authentication
|
|
.Parameter accesstoken
|
|
If your container is running AAD authentication, you need to specify an accesstoken for the user specified in credential
|
|
.Parameter testSuite
|
|
Name of test suite to run. Default is DEFAULT.
|
|
.Parameter testGroup
|
|
Only supported in 14.x containers or older. Name of test group to run. Wildcards (? and *) are supported. Default is *.
|
|
.Parameter testCodeunit
|
|
Name or ID of test codeunit to run. Wildcards (? and *) are supported. Default is *.
|
|
.Parameter testFunction
|
|
Name of test function to run. Wildcards (? and *) are supported. Default is *.
|
|
.Parameter XUnitResultFileName
|
|
Filename where the function should place an XUnit compatible result file
|
|
.Parameter AppendToXUnitResultFile
|
|
Specify this switch if you want the function to append to the XUnit compatible result file instead of overwriting it
|
|
.Parameter ReRun
|
|
Specify this switch if you want the function to replace an existing test run (of the same test codeunit) in the XUnit compatible result file instead of adding it
|
|
.Parameter AzureDevOps
|
|
Generate Azure DevOps Pipeline compatible output. This setting determines the severity of errors.
|
|
.Parameter detailed
|
|
Include this switch to output success/failure information for all tests.
|
|
.Parameter InteractionTimeout
|
|
Timespan allowed for a single interaction (Running a test codeunit is an interaction). Default is 24 hours.
|
|
.Parameter ReturnTrueIfAllPassed
|
|
Specify this switch if the function should return true/false on whether all tests passes. If not specified, the function returns nothing.
|
|
.Parameter testPage
|
|
ID of the test page to use. Default for 15.x containers is 130455. Default for 14.x containers and earlier is 130409.
|
|
.Parameter debugMode
|
|
Include this switch to output debug information if running the tests fails.
|
|
.Parameter restartContainerAndRetry
|
|
Include this switch to restart container and retry the operation (everything) on non-recoverable errors.
|
|
This is NOT test failures, but more things like out of memory, communication errors or that kind.
|
|
.Example
|
|
Run-TestsInNavContainer -contatinerName test -credential $credential
|
|
.Example
|
|
Run-TestsInNavContainer -contatinerName $containername -credential $credential -XUnitResultFileName "c:\ProgramData\NavContainerHelper\$containername.results.xml" -AzureDevOps "warning"
|
|
#>
|
|
function Run-TestsInNavContainer {
|
|
Param (
|
|
[string] $containerName = "navserver",
|
|
[Parameter(Mandatory=$false)]
|
|
[string] $tenant = "default",
|
|
[Parameter(Mandatory=$false)]
|
|
[string] $companyName = "",
|
|
[Parameter(Mandatory=$false)]
|
|
[PSCredential] $credential = $null,
|
|
[Parameter(Mandatory=$false)]
|
|
[string] $accessToken = "",
|
|
[Parameter(Mandatory=$false)]
|
|
[string] $testSuite = "DEFAULT",
|
|
[Parameter(Mandatory=$false)]
|
|
[string] $testGroup = "*",
|
|
[Parameter(Mandatory=$false)]
|
|
[string] $testCodeunit = "*",
|
|
[Parameter(Mandatory=$false)]
|
|
[string] $testFunction = "*",
|
|
[Parameter(Mandatory=$false)]
|
|
[string] $XUnitResultFileName,
|
|
[switch] $AppendToXUnitResultFile,
|
|
[switch] $ReRun,
|
|
[ValidateSet('no','error','warning')]
|
|
[string] $AzureDevOps = 'no',
|
|
[switch] $detailed,
|
|
[timespan] $interactionTimeout = [timespan]::FromHours(24),
|
|
[switch] $returnTrueIfAllPassed,
|
|
[Parameter(Mandatory=$false)]
|
|
[int] $testPage,
|
|
[switch] $debugMode,
|
|
[switch] $restartContainerAndRetry
|
|
)
|
|
|
|
$navversion = Get-NavContainerNavversion -containerOrImageName $containerName
|
|
$version = [System.Version]($navversion.split('-')[0])
|
|
|
|
$containerXUnitResultFileName = ""
|
|
if ($XUnitResultFileName) {
|
|
$containerXUnitResultFileName = Get-NavContainerPath -containerName $containerName -path $XUnitResultFileName
|
|
if ("$containerXUnitResultFileName" -eq "") {
|
|
throw "The path for XUnitResultFileName ($XUnitResultFileName) is not shared with the container."
|
|
}
|
|
}
|
|
|
|
$PsTestToolFolder = "C:\ProgramData\NavContainerHelper\Extensions\$containerName\PsTestTool-3"
|
|
$PsTestFunctionsPath = Join-Path $PsTestToolFolder "PsTestFunctions.ps1"
|
|
$ClientContextPath = Join-Path $PsTestToolFolder "ClientContext.ps1"
|
|
$fobfile = Join-Path $PsTestToolFolder "PSTestToolPage.fob"
|
|
$serverConfiguration = Get-NavContainerServerConfiguration -ContainerName $containerName
|
|
$clientServicesCredentialType = $serverConfiguration.ClientServicesCredentialType
|
|
|
|
if ($serverConfiguration.PublicWebBaseUrl -eq "") {
|
|
throw "Container $containerName needs to include the WebClient in order to run tests (PublicWebBaseUrl is blank)"
|
|
}
|
|
|
|
if (!$testPage) {
|
|
if ($version.Major -ge 15) {
|
|
$testPage = 130455
|
|
}
|
|
else {
|
|
$testPage = 130409
|
|
}
|
|
}
|
|
|
|
If (!(Test-Path -Path $PsTestToolFolder -PathType Container)) {
|
|
try {
|
|
New-Item -Path $PsTestToolFolder -ItemType Directory | Out-Null
|
|
|
|
Copy-Item -Path (Join-Path $PSScriptRoot "PsTestFunctions.ps1") -Destination $PsTestFunctionsPath -Force
|
|
Copy-Item -Path (Join-Path $PSScriptRoot "ClientContext.ps1") -Destination $ClientContextPath -Force
|
|
|
|
if ($version.Major -ge 15) {
|
|
if ($testPage -eq 130409) {
|
|
Publish-BcContainerApp -containerName $containerName -appFile (Join-Path $PSScriptRoot "Microsoft_PSTestToolPage_15.0.0.0.app") -skipVerification -sync -install
|
|
}
|
|
}
|
|
else {
|
|
if ($version.Major -lt 11) {
|
|
Copy-Item -Path (Join-Path $PSScriptRoot "PSTestToolPage$($version.Major).fob") -Destination $fobfile -Force
|
|
}
|
|
else {
|
|
Copy-Item -Path (Join-Path $PSScriptRoot "PSTestToolPage.fob") -Destination $fobfile -Force
|
|
}
|
|
|
|
if ($clientServicesCredentialType -eq "Windows") {
|
|
Import-ObjectsToNavContainer -containerName $containerName -objectsFile $fobfile
|
|
} else {
|
|
Import-ObjectsToNavContainer -containerName $containerName -objectsFile $fobfile -sqlCredential $credential
|
|
}
|
|
}
|
|
} catch {
|
|
Remove-Item -Path $PsTestToolFolder -Recurse -Force
|
|
throw
|
|
}
|
|
}
|
|
|
|
if ($clientServicesCredentialType -eq "Windows" -and "$CompanyName" -eq "") {
|
|
$myName = $myUserName.SubString($myUserName.IndexOf('\')+1)
|
|
Get-NavContainerNavUser -containerName $containerName | Where-Object { $_.UserName.EndsWith("\$MyName", [System.StringComparison]::InvariantCultureIgnoreCase) -or $_.UserName -eq $myName } | % {
|
|
$companyName = $_.Company
|
|
}
|
|
}
|
|
|
|
while ($true) {
|
|
try
|
|
{
|
|
$allPassed = Invoke-ScriptInNavContainer -containerName $containerName { Param([string] $tenant, [string] $companyName, [pscredential] $credential, [string] $accessToken, [string] $testSuite, [string] $testGroup, [string] $testCodeunit, [string] $testFunction, [string] $PsTestFunctionsPath, [string] $ClientContextPath, [string] $XUnitResultFileName, [bool] $AppendToXUnitResultFile, [bool] $ReRun, [string] $AzureDevOps, [bool] $detailed, [timespan] $interactionTimeout, $testPage, $version, $debugMode)
|
|
|
|
$newtonSoftDllPath = (Get-Item "C:\Program Files\Microsoft Dynamics NAV\*\Service\NewtonSoft.json.dll").FullName
|
|
$clientDllPath = "C:\Test Assemblies\Microsoft.Dynamics.Framework.UI.Client.dll"
|
|
$customConfigFile = Join-Path (Get-Item "C:\Program Files\Microsoft Dynamics NAV\*\Service").FullName "CustomSettings.config"
|
|
[xml]$customConfig = [System.IO.File]::ReadAllText($customConfigFile)
|
|
$publicWebBaseUrl = $customConfig.SelectSingleNode("//appSettings/add[@key='PublicWebBaseUrl']").Value
|
|
$clientServicesCredentialType = $customConfig.SelectSingleNode("//appSettings/add[@key='ClientServicesCredentialType']").Value
|
|
$idx = $publicWebBaseUrl.IndexOf('//')
|
|
$protocol = $publicWebBaseUrl.Substring(0, $idx+2)
|
|
$disableSslVerification = ($protocol -eq "https://")
|
|
if ($version.Major -ge 11) {
|
|
$serviceUrl = "$($protocol)localhost/$($ServerInstance)/cs?tenant=$tenant"
|
|
}
|
|
else {
|
|
$serviceUrl = "$($protocol)localhost/$($ServerInstance)/WebClient/cs?tenant=$tenant"
|
|
}
|
|
|
|
if ($clientServicesCredentialType -eq "Windows") {
|
|
$windowsUserName = whoami
|
|
$NavServerUser = Get-NAVServerUser -ServerInstance $ServerInstance -tenant $tenant -ErrorAction Ignore | Where-Object { $_.UserName -eq $windowsusername }
|
|
if (!($NavServerUser)) {
|
|
Write-Host "Creating $windowsusername as user"
|
|
New-NavServerUser -ServerInstance $ServerInstance -tenant $tenant -WindowsAccount $windowsusername
|
|
New-NavServerUserPermissionSet -ServerInstance $ServerInstance -tenant $tenant -WindowsAccount $windowsusername -PermissionSetId SUPER
|
|
}
|
|
}
|
|
elseif ($accessToken) {
|
|
$clientServicesCredentialType = "AAD"
|
|
$credential = New-Object pscredential $credential.UserName, (ConvertTo-SecureString -String $accessToken -AsPlainText -Force)
|
|
}
|
|
|
|
if ($companyName) {
|
|
$serviceUrl += "&company=$([Uri]::EscapeDataString($companyName))"
|
|
}
|
|
|
|
. $PsTestFunctionsPath -newtonSoftDllPath $newtonSoftDllPath -clientDllPath $clientDllPath -clientContextScriptPath $ClientContextPath
|
|
|
|
try {
|
|
if ($disableSslVerification) {
|
|
Disable-SslVerification
|
|
}
|
|
|
|
$clientContext = New-ClientContext -serviceUrl $serviceUrl -auth $clientServicesCredentialType -credential $credential -interactionTimeout $interactionTimeout -debugMode:$debugMode
|
|
|
|
Run-Tests -clientContext $clientContext `
|
|
-TestSuite $testSuite `
|
|
-TestGroup $testGroup `
|
|
-TestCodeunit $testCodeunit `
|
|
-TestFunction $testFunction `
|
|
-XUnitResultFileName $XUnitResultFileName `
|
|
-AppendToXUnitResultFile:$AppendToXUnitResultFile `
|
|
-ReRun:$ReRun `
|
|
-AzureDevOps $AzureDevOps `
|
|
-detailed:$detailed `
|
|
-testPage $testPage
|
|
}
|
|
catch {
|
|
if ($debugMode) {
|
|
Dump-ClientContext -clientcontext $clientContext
|
|
}
|
|
throw
|
|
}
|
|
finally {
|
|
if ($disableSslVerification) {
|
|
Enable-SslVerification
|
|
}
|
|
Remove-ClientContext -clientContext $clientContext
|
|
}
|
|
|
|
} -argumentList $tenant, $companyName, $credential, $accessToken, $testSuite, $testGroup, $testCodeunit, $testFunction, $PsTestFunctionsPath, $ClientContextPath, $containerXUnitResultFileName, $AppendToXUnitResultFile, $ReRun, $AzureDevOps, $detailed, $interactionTimeout, $testPage, $version, $debugMode
|
|
if ($returnTrueIfAllPassed) {
|
|
$allPassed
|
|
}
|
|
if (!$allPassed) {
|
|
Remove-NavContainerSession -containerName $containerName
|
|
}
|
|
break
|
|
}
|
|
catch {
|
|
if ($restartContainerAndRetry) {
|
|
Write-Host -ForegroundColor Red $_.Exception.Message
|
|
Restart-NavContainer $containerName
|
|
$restartContainerAndRetry = $false
|
|
}
|
|
else {
|
|
throw $_.Exception.Message
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Set-Alias -Name Run-TestsInBCContainer -Value Run-TestsInNavContainer
|
|
Export-ModuleMember -Function Run-TestsInNavContainer -Alias Run-TestsInBCContainer
|