Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/AL-Go-Settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"repoVersion": "30.0",
"memoryLimit": "16G",
"numberOfTenantsForTesting": 4,
"enableCleanTestCodeunitExecution": true,
"maxTestAppReruns": 2,
"failOn": "newWarning",
"workspaceCompilation": {
Expand Down
1 change: 0 additions & 1 deletion build/projects/Test Apps AT/.AL-Go/PipelineFinalize.ps1

This file was deleted.

1 change: 0 additions & 1 deletion build/projects/Test Apps AU/.AL-Go/PipelineFinalize.ps1

This file was deleted.

1 change: 0 additions & 1 deletion build/projects/Test Apps BE/.AL-Go/PipelineFinalize.ps1

This file was deleted.

1 change: 0 additions & 1 deletion build/projects/Test Apps CA/.AL-Go/PipelineFinalize.ps1

This file was deleted.

1 change: 0 additions & 1 deletion build/projects/Test Apps CH/.AL-Go/PipelineFinalize.ps1

This file was deleted.

1 change: 0 additions & 1 deletion build/projects/Test Apps CZ/.AL-Go/PipelineFinalize.ps1

This file was deleted.

1 change: 0 additions & 1 deletion build/projects/Test Apps DE/.AL-Go/PipelineFinalize.ps1

This file was deleted.

1 change: 0 additions & 1 deletion build/projects/Test Apps DK/.AL-Go/PipelineFinalize.ps1

This file was deleted.

1 change: 0 additions & 1 deletion build/projects/Test Apps ES/.AL-Go/PipelineFinalize.ps1

This file was deleted.

1 change: 0 additions & 1 deletion build/projects/Test Apps FI/.AL-Go/PipelineFinalize.ps1

This file was deleted.

1 change: 0 additions & 1 deletion build/projects/Test Apps FR/.AL-Go/PipelineFinalize.ps1

This file was deleted.

1 change: 0 additions & 1 deletion build/projects/Test Apps GB/.AL-Go/PipelineFinalize.ps1

This file was deleted.

1 change: 0 additions & 1 deletion build/projects/Test Apps IN/.AL-Go/PipelineFinalize.ps1

This file was deleted.

1 change: 0 additions & 1 deletion build/projects/Test Apps IS/.AL-Go/PipelineFinalize.ps1

This file was deleted.

1 change: 0 additions & 1 deletion build/projects/Test Apps IT/.AL-Go/PipelineFinalize.ps1

This file was deleted.

1 change: 0 additions & 1 deletion build/projects/Test Apps MX/.AL-Go/PipelineFinalize.ps1

This file was deleted.

1 change: 0 additions & 1 deletion build/projects/Test Apps NL/.AL-Go/PipelineFinalize.ps1

This file was deleted.

1 change: 0 additions & 1 deletion build/projects/Test Apps NO/.AL-Go/PipelineFinalize.ps1

This file was deleted.

1 change: 0 additions & 1 deletion build/projects/Test Apps NZ/.AL-Go/PipelineFinalize.ps1

This file was deleted.

1 change: 0 additions & 1 deletion build/projects/Test Apps RU/.AL-Go/PipelineFinalize.ps1

This file was deleted.

1 change: 0 additions & 1 deletion build/projects/Test Apps SE/.AL-Go/PipelineFinalize.ps1

This file was deleted.

1 change: 0 additions & 1 deletion build/projects/Test Apps US/.AL-Go/PipelineFinalize.ps1

This file was deleted.

1 change: 0 additions & 1 deletion build/projects/Test Apps W1/.AL-Go/PipelineFinalize.ps1

This file was deleted.

117 changes: 0 additions & 117 deletions build/scripts/ApiTestCredential.psm1

This file was deleted.

11 changes: 2 additions & 9 deletions build/scripts/NewBcContainer.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,10 @@ if ($platformVersion) {

New-BcContainer @parameters

if ($parameters.auth -in @('UserPassword', 'NavUserPassword')) {
if (-not $parameters.credential) {
throw "The BCApps UserPassword test container requires a credential."
}

Import-Module (Join-Path $PSScriptRoot 'ApiTestCredential.psm1') -Force
Write-ApiTestPassword -ContainerName $parameters.ContainerName -Credential $parameters.credential
}

Set-BcContainerServerConfiguration -containerName $parameters.ContainerName -keyName "EnforceUserPathForAlFileOperations" -keyValue "false"
Set-BcContainerServerConfiguration -containerName $parameters.ContainerName -keyName "UsePermissionSetsFromExtensions" -keyValue "true"
# API tests call the container's own web services through AL HttpClient, which anti-SSRF blocks for local addresses (same as NAV RunALTests.ps1).
Set-BcContainerServerConfiguration -containerName $parameters.ContainerName -keyName "NavHttpClientAntiSSRFEnabled" -keyValue "false"
Restart-BcContainer -containerName $parameters.ContainerName

$installedApps = Get-BcContainerAppInfo -containerName $parameters.ContainerName -tenantSpecificProperties -sort DependenciesLast
Expand Down
93 changes: 89 additions & 4 deletions build/scripts/ParallelTestExecution.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,58 @@ function New-BcTestTenantTemplate {
return [string]$result[-1]
}

<#
.SYNOPSIS
Returns T-SQL that ends every user session using a database and then drops it.
.DESCRIPTION
The first result set lists the sessions that are ended, for diagnostics. Ending them
explicitly and switching to SINGLE_USER keeps the drop from waiting on a server
session that still holds the database (observed as ~30 minute stalls).
.PARAMETER DatabaseName
Database to drop.
#>
function Get-BcTestTenantDatabaseDropQuery {
param(
[Parameter(Mandatory=$true)]
[string]$DatabaseName
)

$literal = $DatabaseName.Replace("'", "''")
return @"
SET NOCOUNT ON;
DECLARE @db sysname = N'$literal';
IF DB_ID(@db) IS NULL RETURN;
DECLARE @sessions TABLE (session_id int PRIMARY KEY);
INSERT INTO @sessions (session_id)
SELECT s.session_id FROM sys.dm_exec_sessions s
WHERE s.is_user_process = 1 AND s.session_id <> @@SPID AND s.database_id = DB_ID(@db)
UNION
SELECT l.request_session_id FROM sys.dm_tran_locks l
JOIN sys.dm_exec_sessions s ON s.session_id = l.request_session_id
WHERE s.is_user_process = 1 AND l.request_session_id <> @@SPID AND l.resource_database_id = DB_ID(@db);
SELECT s.session_id, s.program_name, s.status, r.command, r.wait_type, r.blocking_session_id
FROM @sessions x
JOIN sys.dm_exec_sessions s ON s.session_id = x.session_id
LEFT JOIN sys.dm_exec_requests r ON r.session_id = x.session_id;
DECLARE @id int, @kill nvarchar(30);
DECLARE session_cursor CURSOR LOCAL FAST_FORWARD FOR SELECT session_id FROM @sessions;
OPEN session_cursor;
FETCH NEXT FROM session_cursor INTO @id;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @kill = N'KILL ' + CAST(@id AS nvarchar(10));
BEGIN TRY EXEC (@kill); END TRY BEGIN CATCH END CATCH;
FETCH NEXT FROM session_cursor INTO @id;
END
CLOSE session_cursor;
DEALLOCATE session_cursor;
DECLARE @statement nvarchar(400) = N'ALTER DATABASE ' + QUOTENAME(@db) + N' SET SINGLE_USER WITH ROLLBACK IMMEDIATE';
EXEC (@statement);
SET @statement = N'DROP DATABASE ' + QUOTENAME(@db);
EXEC (@statement);
"@
}

<#
.SYNOPSIS
Replaces a tenant database with a copy of an idle source database.
Expand All @@ -430,22 +482,55 @@ function Reset-BcTestTenant {
[string]$TemplateDatabaseName
)

$dropQuery = Get-BcTestTenantDatabaseDropQuery -DatabaseName $TenantDatabaseName

Invoke-ScriptInBcContainer -containerName $ContainerName -useSession $false -scriptblock {
Param($tenant, $tenantDatabaseName, $templateDatabaseName)
Param($tenant, $tenantDatabaseName, $templateDatabaseName, $dropQuery)

$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
$mountedTenant = Get-NAVTenant -ServerInstance $ServerInstance -Tenant $tenant -ErrorAction SilentlyContinue
if ($mountedTenant) {
# End the tenant's server sessions first so none of them keeps the database in use.
# Internal sessions report negative IDs, which Remove-NAVServerSession rejects.
try {
$serverSessions = @(Get-NAVServerSession -ServerInstance $ServerInstance -Tenant $tenant -ErrorAction SilentlyContinue | Where-Object { $_.SessionId -ge 0 })
} catch {
Write-Host "WARNING: Could not list server sessions for tenant '$tenant': $($_.Exception.Message)"
$serverSessions = @()
}
foreach ($serverSession in $serverSessions) {
try {
Remove-NAVServerSession -ServerInstance $ServerInstance -Tenant $tenant -SessionId $serverSession.SessionId -Force -ErrorAction Stop
} catch {
Write-Host "WARNING: Could not end server session $($serverSession.SessionId) for tenant '$tenant': $($_.Exception.Message)"
}
}
Dismount-NAVTenant -ServerInstance $ServerInstance -Tenant $tenant -Force | Out-Null
}

$databaseServer = Get-NAVServerConfiguration -ServerInstance $ServerInstance -KeyName DatabaseServer
$databaseInstance = Get-NAVServerConfiguration -ServerInstance $ServerInstance -KeyName DatabaseInstance
if ([string]::IsNullOrWhiteSpace($databaseServer)) { $databaseServer = 'localhost' }
$sqlParameters = @{
ServerInstance = if ([string]::IsNullOrWhiteSpace($databaseInstance)) { $databaseServer } else { "$databaseServer\$databaseInstance" }
Query = $dropQuery
QueryTimeout = 120
ErrorAction = 'Stop'
}
if ((Get-Command Invoke-Sqlcmd).Parameters.ContainsKey('TrustServerCertificate')) {
$sqlParameters['TrustServerCertificate'] = $true
}

$maxAttempts = 3
$retryDelaySeconds = 5
for ($attempt = 1; $attempt -le $maxAttempts; $attempt++) {
try {
if (Test-NAVDatabase -DatabaseName $tenantDatabaseName) {
Remove-NAVDatabase -DatabaseName $tenantDatabaseName | Out-Null
$dropStopwatch = [System.Diagnostics.Stopwatch]::StartNew()
$endedSessions = @(Invoke-Sqlcmd @sqlParameters)
foreach ($session in $endedSessions) {
Write-Host "Ended SQL session $($session.session_id) on '$tenantDatabaseName' (program '$($session.program_name)', status '$($session.status)', command '$($session.command)', wait '$($session.wait_type)', blocked by '$($session.blocking_session_id)')."
}
Write-Host "Dropped database '$tenantDatabaseName' in $([math]::Round($dropStopwatch.Elapsed.TotalSeconds, 2)) seconds after ending $($endedSessions.Count) SQL session(s)."

Copy-NAVDatabase -SourceDatabaseName $templateDatabaseName -DestinationDatabaseName $tenantDatabaseName -DatabaseServer "." | Out-Null
break
Expand Down Expand Up @@ -474,7 +559,7 @@ function Reset-BcTestTenant {

$stopwatch.Stop()
Write-Host "Refreshed tenant '$tenant' from '$templateDatabaseName' in $([math]::Round($stopwatch.Elapsed.TotalSeconds, 2)) seconds."
} -argumentList $Tenant, $TenantDatabaseName, $TemplateDatabaseName
} -argumentList $Tenant, $TenantDatabaseName, $TemplateDatabaseName, $dropQuery
}

function Remove-BcTestTenantTemplate {
Expand Down
13 changes: 0 additions & 13 deletions build/scripts/PipelineFinalize.ps1

This file was deleted.

34 changes: 0 additions & 34 deletions build/scripts/Remove-ApiTestPassword.ps1

This file was deleted.

Loading
Loading