ObjectHandling/Import-TestToolkitToNavContainer.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
<#
 .Synopsis
  Import TestToolkit to Nav Container
 .Description
  Import the objects from the TestToolkit to the Nav Container.
  The TestToolkit objects are already in a folder on the NAV on Docker image from version 0.0.4.3
 .Parameter containerName
  Name of the container for which you want to enter a session
 .Parameter sqlCredential
  Credentials for the SQL admin user if using NavUserPassword authentication. User will be prompted if not provided
 .Parameter includeTestLibrariesOnly
  Only import TestLibraries (do not import Test Codeunits)
 .Parameter testToolkitCountry
  Only import TestToolkit objects for a specific country.
  You must specify the country code that is used in the TestToolkit object name (e.g. CA, US, MX, etc.).
  This parameter only needs to be used in the event there are multiple country-specific sets of objects in the TestToolkit folder.
 .Parameter doNotUpdateSymbols
  Add this switch to avoid updating symbols when importing the test toolkit
 .Parameter ImportAction
  Specifies the import action. Default is Overwrite.
 .Example
  Import-TestToolkitToNavContainer -containerName test2
  .Example
  Import-TestToolkitToNavContainer -containerName test2 -testToolkitCountry US
#>

function Import-TestToolkitToNavContainer {
    Param(
        [Parameter(Mandatory=$true)]
        [string]$containerName, 
        [PSCredential]$sqlCredential = $null,
        [switch]$includeTestLibrariesOnly,
        [string]$testToolkitCountry,
        [switch]$doNotUpdateSymbols,
        [ValidateSet("Overwrite","Skip")]
        [string]$ImportAction = "Overwrite"
    )

    $inspect = docker inspect $containerName | ConvertFrom-Json
    if ($inspect.Config.Labels.psobject.Properties.Match('nav').Count -eq 0) {
        throw "Container $containerName is not a NAV container"
    }
    [System.Version]$version = $inspect.Config.Labels.version

    $config = Get-NavContainerServerConfiguration -ContainerName $containerName
    $doNotUpdateSymbols = $doNotUpdateSymbols -or (!(([bool]($config.PSobject.Properties.name -match "EnableSymbolLoadingAtServerStartup")) -and $config.EnableSymbolLoadingAtServerStartup -eq "True"))

    $generateSymbols = $false
    if ($version.Major -eq 14 -and !$doNotUpdateSymbols -and $config.ClientServicesCredentialType -ne "Windows") {
        $generateSymbols = $true
        $doNotUpdateSymbols = $true
    }

    if ($version.Major -ge 15) {
        if ($version -lt [Version]("15.0.35528.0")) {
            throw "Container $containerName (platform version $version) doesn't support the Test Toolkit yet, you need a laster version"
        }

        $appFiles = Invoke-ScriptInBCContainer -containerName $containerName -scriptblock { Param($includeTestLibrariesOnly)
            "Microsoft_Any.app", "Microsoft_Library Assert.app", "Microsoft_Test Runner.app" | % {
                @(get-childitem -Path "C:\Applications\*.*" -recurse -filter $_)
            }
            $mockAssembliesPath = "C:\Test Assemblies\Mock Assemblies"
            if (Test-Path $mockAssembliesPath) {
                $serviceTierAddInsFolder = (Get-Item "C:\Program Files\Microsoft Dynamics NAV\*\Service\Add-ins").FullName
                if (!(Test-Path (Join-Path $serviceTierAddInsFolder "Mock Assemblies"))) {
                    new-item -itemtype symboliclink -path $serviceTierAddInsFolder -name "Mock Assemblies" -value $mockAssembliesPath | Out-Null
                }
                "Microsoft_System Application Test Library.app", "Microsoft_Tests-TestLibraries.app" | % {
                    @(get-childitem -Path "C:\Applications\*.*" -recurse -filter $_)
                }

                if (!$includeTestLibrariesOnly) {
                    @(get-childitem -Path "C:\Applications\*.*" -recurse -filter "Microsoft_Tests-*.app") | Where-Object { $_ -notlike "*\Microsoft_Tests-TestLibraries.app" -and $_ -notlike "*\Microsoft_Tests-Marketing.app"}
                }

            }
        } -argumentList $includeTestLibrariesOnly
        $appFiles | % {
            Publish-BCContainerApp -containerName $containerName -appFile ":$($_.FullName)" -sync -install
        }
        Write-Host -ForegroundColor Green "TestToolkit successfully imported"
    }
    else {
        $sqlCredential = Get-DefaultSqlCredential -containerName $containerName -sqlCredential $sqlCredential -doNotAskForCredential
        Invoke-ScriptInNavContainer -containerName $containerName -ScriptBlock { Param([PSCredential]$sqlCredential, $includeTestLibrariesOnly, $testToolkitCountry, $doNotUpdateSymbols, $ImportAction)
        
            $customConfigFile = Join-Path (Get-Item "C:\Program Files\Microsoft Dynamics NAV\*\Service").FullName "CustomSettings.config"
            [xml]$customConfig = [System.IO.File]::ReadAllText($customConfigFile)
            $databaseServer = $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseServer']").Value
            $databaseInstance = $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseInstance']").Value
            $databaseName = $customConfig.SelectSingleNode("//appSettings/add[@key='DatabaseName']").Value
            $managementServicesPort = $customConfig.SelectSingleNode("//appSettings/add[@key='ManagementServicesPort']").Value
            if ($databaseInstance) { $databaseServer += "\$databaseInstance" }
       
            $params = @{}
            if ($sqlCredential) {
                $params = @{ 'Username' = $sqlCredential.UserName; 'Password' = ([System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($sqlCredential.Password))) }
            }
            if ($testToolkitCountry) {
                $fileFilter = "*.$testToolkitCountry.fob"
            }
            else {
                $fileFilter = "*.fob"
            }
            Get-ChildItem -Path "C:\TestToolKit" -Filter $fileFilter | ForEach-Object { 
                if (!$includeTestLibrariesOnly -or $_.Name.StartsWith("CALTestLibraries")) {
                    $objectsFile = $_.FullName
                    Write-Host "Importing Objects from $objectsFile (container path)"
                    $databaseServerParameter = $databaseServer
    
                    if (!$doNotUpdateSymbols) {
                        Write-Host "Generating Symbols while importing"
                        # HACK: Parameter insertion...
                        # generatesymbolreference is not supported by Import-NAVApplicationObject yet
                        # insert an extra parameter for the finsql command by splitting the filter property
                        $databaseServerParameter = '",generatesymbolreference=1,ServerName="'+$databaseServer
                    }
        
                    Import-NAVApplicationObject @params -Path $objectsFile `
                                                -DatabaseName $databaseName `
                                                -DatabaseServer $databaseServerParameter `
                                                -ImportAction $ImportAction `
                                                -SynchronizeSchemaChanges No `
                                                -NavServerName localhost `
                                                -NavServerInstance $ServerInstance `
                                                -NavServerManagementPort "$managementServicesPort" `
                                                -Confirm:$false
        
                }
            }
    
            # Sync after all objects hav been imported
            Get-NAVTenant -ServerInstance $ServerInstance | Sync-NavTenant -Mode ForceSync -Force
    
        } -ArgumentList $sqlCredential, $includeTestLibrariesOnly, $testToolkitCountry, $doNotUpdateSymbols, $ImportAction
    
        if ($generateSymbols) {
            Generate-SymbolsInNavContainer -containerName $containerName -sqlCredential $sqlCredential
        }
        Write-Host -ForegroundColor Green "TestToolkit successfully imported"
    }
}
Set-Alias -Name Import-TestToolkitToBCContainer -Value Import-TestToolkitToNavContainer
Export-ModuleMember -Function Import-TestToolkitToNavContainer -Alias Import-TestToolkitToBCContainer