Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes308downloads
Import-Module.Tests.ps1410 linesDownload Raw Back to Microsoft.PowerShell.Core
1# Copyright (c) Microsoft Corporation.2# Licensed under the MIT License.3Describe "Import-Module" -Tags "CI" {4    $moduleName = "Microsoft.PowerShell.Security"5    BeforeAll {6        $originalPSModulePath = $env:PSModulePath7        New-Item -ItemType Directory -Path "$testdrive\Modules\TestModule\1.1" -Force > $null8        New-Item -ItemType Directory -Path "$testdrive\Modules\TestModule\2.0" -Force > $null9        $env:PSModulePath += [System.IO.Path]::PathSeparator + "$testdrive\Modules"10        New-ModuleManifest -Path "$testdrive\Modules\TestModule\1.1\TestModule.psd1" -ModuleVersion 1.111        New-ModuleManifest -Path "$testdrive\Modules\TestModule\2.0\TestModule.psd1" -ModuleVersion 2.012    }13 14    AfterAll {15        $env:PSModulePath = $originalPSModulePath16    }17 18    BeforeEach {19        Remove-Module -Name $moduleName -Force20        (Get-Module -Name $moduleName).Name | Should -BeNullOrEmpty21        Remove-Module -Name TestModule -Force -ErrorAction SilentlyContinue22    }23 24    AfterEach {25        Import-Module -Name $moduleName -Force26        (Get-Module -Name $moduleName).Name | Should -BeExactly $moduleName27    }28 29    It "should be able to add a module with using Name switch" {30        { Import-Module -Name $moduleName } | Should -Not -Throw31        (Get-Module -Name $moduleName).Name | Should -BeExactly $moduleName32    }33 34    It "should be able to load a module with a trailing directory separator: <modulePath>" -TestCases @(35        @{ modulePath = (Get-Module -ListAvailable $moduleName)[0].ModuleBase + [System.IO.Path]::DirectorySeparatorChar; expectedName = $moduleName },36        @{ modulePath = Join-Path -Path $TestDrive -ChildPath "\Modules\TestModule\"; expectedName = "TestModule" }37    ) {38        param( $modulePath, $expectedName )39        { Import-Module -Name $modulePath -ErrorAction Stop } | Should -Not -Throw40        (Get-Module -Name $expectedName).Name | Should -BeExactly $expectedName41    }42 43    It "should be able to add a module with using ModuleInfo switch" {44        $a = (Get-Module -ListAvailable $moduleName)[0]45        { Import-Module -ModuleInfo $a } | Should -Not -Throw46        (Get-Module -Name $moduleName).Name | Should -BeExactly $moduleName47    }48 49    It "should be able to load an already loaded module" {50        Import-Module $moduleName51        { $script:module = Import-Module $moduleName -PassThru -ErrorAction Stop } | Should -Not -Throw52        Get-Module -Name $moduleName | Should -BeExactly $script:module53    }54 55    It "should only load the specified version" {56        Import-Module TestModule -RequiredVersion 1.157        (Get-Module TestModule).Version | Should -BeIn "1.1"58    }59 60    It 'ProcessorArchitecture should work' {61        $currentProcessorArchitecture = switch ([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture) {62            'X86' { 'x86' }63            'X64' { 'amd64' }64            'Arm64' { 'arm' }65            'Arm' { 'arm' }66            default { throw "Unknown processor architecture" }67        }68        New-ModuleManifest -Path "$TestDrive\TestModule.psd1" -ProcessorArchitecture $currentProcessorArchitecture69        $module = Import-Module -Name "$TestDrive\TestModule.psd1" -PassThru70        $module.ProcessorArchitecture | Should -Be $currentProcessorArchitecture71    }72}73 74Describe "Import-Module with ScriptsToProcess" -Tags "CI" {75 76    BeforeAll {77        $moduleRootPath = Join-Path $TestDrive 'TestModules'78        New-Item $moduleRootPath -ItemType Directory -Force | Out-Null79        Push-Location $moduleRootPath80 81        "1 | Out-File out.txt -Append -NoNewline" | Out-File script1.ps182        "2 | Out-File out.txt -Append -NoNewline" | Out-File script2.ps183        New-ModuleManifest module1.psd1 -ScriptsToProcess script1.ps184        New-ModuleManifest module2.psd1 -ScriptsToProcess script2.ps1 -NestedModules module1.psd185    }86 87    AfterAll {88        Pop-Location89    }90 91    BeforeEach {92        New-Item out.txt -ItemType File -Force | Out-Null93    }94 95    AfterEach {96        $m = @('module1','module2','script1','script2')97        Remove-Module $m -Force -ErrorAction SilentlyContinue98        Remove-Item out.txt -Force -ErrorAction SilentlyContinue99    }100 101    $testCases = @(102            @{ TestNameSuffix = 'for top-level module'; ipmoParms =  @{'Name'='.\module1.psd1'}; Expected = '1' }103            @{ TestNameSuffix = 'for top-level and nested module'; ipmoParms =  @{'Name'='.\module2.psd1'}; Expected = '21' }104            @{ TestNameSuffix = 'for top-level module when -Version is specified'; ipmoParms =  @{'Name'='.\module1.psd1'; 'Version'='0.0.1'}; Expected = '1' }105            @{ TestNameSuffix = 'for top-level and nested module when -Version is specified'; ipmoParms =  @{'Name'='.\module2.psd1'; 'Version'='0.0.1'}; Expected = '21' }106        )107 108    It "Verify ScriptsToProcess are executed <TestNameSuffix>" -TestCases $testCases {109        param($TestNameSuffix,$ipmoParms,$Expected)110        Import-Module @ipmoParms111        Get-Content out.txt | Should -BeExactly $Expected112    }113}114 115Describe "Import-Module for Binary Modules in GAC" -Tags 'Feature' {116    Context "Modules are not loaded from GAC" {117        It "Load PSScheduledJob from Windows Powershell Modules folder should fail" -Skip:(-not $IsWindows) {118            # NOTE:119            # This test attempts to load an assembly from the GAC and expects to fail.120            # However, if the assembly is already loaded, the assembly will be resolved before121            # the DisableGACLoading flag comes into effect, meaning no error is thrown and the test fails.122            #123            # Since the System32 module direction is now on the module path and Get-Module -ListAvailable124            # loads assemblies, the assembly is resolved and this test will fail if any other tests before125            # it call Get-Module -ListAvailable.126            #127            # So for now, the solution is to run this test in a fresh process.128            # Since disabling GAC loading is supposed to be a startup option, this is possibly appropriate.129 130            $testScript = {131                [System.Management.Automation.Internal.InternalTestHooks]::SetTestHook('DisableGACLoading', $true)132                $modulePath = Join-Path $env:windir "System32/WindowsPowershell/v1.0/Modules/PSScheduledJob"133                Import-Module $modulePath -SkipEditionCheck134            }135            $err = (& "$PSHOME\pwsh.exe" -c $testScript 2>&1 | Where-Object { $_ -is [System.Management.Automation.ErrorRecord] })[0]136            $err.FullyQualifiedErrorId | Should -Be "FormatXmlUpdateException,Microsoft.PowerShell.Commands.ImportModuleCommand"137        }138    }139 140    Context "Modules are loaded from GAC" {141        It "Load PSScheduledJob from Windows Powershell Modules folder" -Skip:(-not $IsWindows) {142            $modulePath = Join-Path $env:windir "System32/WindowsPowershell/v1.0/Modules/PSScheduledJob"143            Import-Module $modulePath -SkipEditionCheck144            (Get-Command New-JobTrigger).Name | Should -BeExactly 'New-JobTrigger'145        }146    }147}148 149Describe "Import-Module for Binary Modules" -Tags 'CI' {150 151    BeforeAll {152        $src = @"153            using System.Management.Automation;154            namespace ModuleCmdlets155            {156                [Cmdlet(VerbsDiagnostic.Test,"BinaryModuleCmdlet1")]157                public class TestBinaryModuleCmdlet1Command : Cmdlet158                {159                    protected override void BeginProcessing()160                    {161                        WriteObject("BinaryModuleCmdlet1 exported by the ModuleCmdlets module.");162                    }163                }164            }165"@166        Add-Type -TypeDefinition $src -OutputAssembly $TESTDRIVE\System.dll167        Add-Type -TypeDefinition $src -OutputAssembly $TESTDRIVE\System.exe168    }169 170    It "PS should try to load the binary module from a file path with extension: <extension>" -TestCases (171        @{extension = "dll"},172        @{extension = "exe"}173     ) {174         param ($extension)175 176        try {177            $TestModulePath = Join-Path $TESTDRIVE "System.$extension"178            $job = Start-Job -ScriptBlock {179                $module = Import-Module $using:TestModulePath -PassThru;180                $module.ImplementingAssembly.Location;181                Test-BinaryModuleCmdlet1182            }183            $assemblyLocation, $cmdletOutput = $job | Wait-Job -Timeout 30 | Receive-Job184        }185        finally {186            $job | Remove-Job -ErrorAction Ignore187        }188 189        $assemblyLocation | Should -BeExactly $TestModulePath190        $cmdletOutput | Should -BeExactly "BinaryModuleCmdlet1 exported by the ModuleCmdlets module."191    }192 193    It 'PS should be able to load the executable as a root module' {194        $psdFile = Join-Path $TESTDRIVE test.psd1195        $exe = Join-Path $TESTDRIVE System.exe196        New-ModuleManifest -Path $psdFile -RootModule $exe197 198        try {199            $job = Start-Job -ScriptBlock { Import-Module $using:psdFile -PassThru }200            $module = $job | Wait-Job -Timeout 30 | Receive-Job201        }202        finally {203            $job | Remove-Job -ErrorAction Ignore204        }205 206        $module | Should -Not -BeNullOrEmpty207        $module.ModuleType.ToString() | Should -Be 'Binary'208        $module.RootModule | Should -Be $exe209        $module.ExportedCmdlets['Test-BinaryModuleCmdlet1'] | Should -Be 'Test-BinaryModuleCmdlet1'210    }211 212    It 'PS should be able to load the executable as a nested module' {213        $psdFile = Join-Path $TESTDRIVE test.psd1214        $exe = Join-Path $TESTDRIVE System.exe215        New-ModuleManifest -Path $psdFile -NestedModules $exe216 217        try {218            $job = Start-Job -ScriptBlock {219                $module = Import-Module $using:psdFile -PassThru220                # return the module and the nested module assembly location221                $module222                $module.NestedModules[0].ImplementingAssembly.Location223            }224            $module, $location = $job | Wait-Job -Timeout 30 | Receive-Job225        }226        finally {227            $job | Remove-Job -ErrorAction Ignore228        }229 230        $module | Should -Not -BeNullOrEmpty231        $module.ModuleType.ToString() | Should -Be 'Manifest'232        $module.ExportedCmdlets['Test-BinaryModuleCmdlet1'] | Should -Be 'Test-BinaryModuleCmdlet1'233        $module.NestedModules | Should -Not -BeNullOrEmpty234        $location | Should -Be $exe235    }236 237    It "PS should try to load the assembly from assembly name if file path doesn't exist" {238        $psdFile = Join-Path $TESTDRIVE test.psd1239        $nestedModule = Join-Path NOExistedPath Microsoft.PowerShell.Commands.Utility.dll240        New-ModuleManifest -Path $psdFile -NestedModules $nestedModule241 242        try {243            $job = Start-Job -ScriptBlock {244                $module = Import-Module $using:psdFile -PassThru245                # return the module and the assembly location246                $module247                $module.NestedModules[0].ImplementingAssembly.Location248            }249            $module, $location = $job | Wait-Job -Timeout 30 | Receive-Job250        }251        finally {252            $job | Remove-Job -ErrorAction Ignore253        }254 255        $module.NestedModules | Should -Not -BeNullOrEmpty256        $assemblyLocation = [Microsoft.PowerShell.Commands.AddTypeCommand].Assembly.Location257        $location | Should -Be $assemblyLocation258    }259 260    It 'Should load from ModuleBase path before looking up in GAC' -Skip:(-not $IsWindows) {261        $module = Get-Module PSScheduledJob -ListAvailable -SkipEditionCheck262        $moduleBasePath = Split-Path $module.Path263        $destPath = New-Item -ItemType Directory -Path "$TestDrive/PSScheduledJob"264        $gacAssemblyPath = (Get-ChildItem "${env:WinDir}\Microsoft.NET\assembly\GAC_MSIL\Microsoft.PowerShell.ScheduledJob" -Recurse -Filter 'Microsoft.PowerShell.ScheduledJob.dll').FullName265 266        # Copy format, type and psd1267        Copy-Item "$moduleBasePath/PSScheduledJob*.*" -Destination $destPath -Force268 269        # Copy assembly to temp module folder"270        Copy-Item $gacAssemblyPath -Destination $destPath -Force271 272        # Use a different pwsh so that we do not have the PSScheduledJob module already loaded.273        $loadedAssemblyLocation = & "$PSHOME/pwsh" -noprofile -c "Import-Module $destPath -Force; [Microsoft.PowerShell.ScheduledJob.AddJobTriggerCommand].Assembly.Location"274        $loadedAssemblyLocation | Should -BeLike "$TestDrive*\Microsoft.PowerShell.ScheduledJob.dll"275    }276}277 278Describe "Import-Module should be case insensitive" -Tags 'CI' {279    BeforeAll {280        $defaultPSModuleAutoloadingPreference = $PSModuleAutoLoadingPreference281        $originalPSModulePath = $env:PSModulePath.Clone()282        $modulesPath = "$TestDrive\Modules"283        $env:PSModulePath += [System.IO.Path]::PathSeparator + $modulesPath284        $PSModuleAutoLoadingPreference = "none"285    }286 287    AfterAll {288        $global:PSModuleAutoloadingPreference = $defaultPSModuleAutoloadingPreference289        $env:PSModulePath = $originalPSModulePath290    }291 292    AfterEach {293        Remove-Item -Recurse -Path $modulesPath -Force -ErrorAction SilentlyContinue294    }295 296    It "Import-Module can import a module using different casing using '<modulePath>' and manifest:<manifest>" -TestCases @(297        @{modulePath="TESTMODULE/1.1"; manifest=$true},298        @{modulePath="TESTMODULE"    ; manifest=$true},299        @{modulePath="TESTMODULE"    ; manifest=$false}300        ) {301        param ($modulePath, $manifest)302        New-Item -ItemType Directory -Path "$modulesPath/$modulePath" -Force > $null303        if ($manifest) {304            New-ModuleManifest -Path "$modulesPath/$modulePath/TESTMODULE.psd1" -RootModule "TESTMODULE.psm1" -ModuleVersion 1.1305        }306        Set-Content -Path "$modulesPath/$modulePath/TESTMODULE.psm1" -Value "function mytest { 'hello' }"307        Import-Module testMODULE308        $m = Get-Module TESTmodule309        $m | Should -BeOfType System.Management.Automation.PSModuleInfo310        $m.Name | Should -BeIn "TESTMODULE"311        mytest | Should -BeExactly "hello"312        Remove-Module TestModule313        Get-Module tESTmODULE | Should -BeNullOrEmpty314    }315}316 317Describe "Circular nested module test" -tags "CI" {318    BeforeAll {319        $moduleFolder = Join-Path $TestDrive CircularNestedModuleTest320        $psdPath = Join-Path $moduleFolder CircularNestedModuleTest.psd1321        $psmPath = Join-Path $moduleFolder CircularNestedModuleTest.psm1322 323        New-Item -Path $moduleFolder -ItemType Directory -Force > $null324        Set-Content -Path $psdPath -Value "@{ ModuleVersion = '0.0.1'; RootModule = 'CircularNestedModuleTest'; NestedModules = @('CircularNestedModuleTest') }" -Encoding Ascii325        Set-Content -Path $psmPath -Value "function bar {}" -Encoding Ascii326    }327 328    AfterAll {329        Remove-Module -Name CircularNestedModuleTest -Force -ErrorAction SilentlyContinue330    }331 332    It "Loading the module should succeed and return a module with circular nested module" {333        $m = Import-Module $psdPath -PassThru334        $m.NestedModules[0] | Should -Be $m335    }336}337 338Describe "Import-Module -Force behaviour" -Tag "CI" {339    BeforeAll {340        $moduleContent = 'function Test-One { return 101 }'341        $newModuleContent = "function Test-One { return 93 }`nfunction Test-Two { return 14 }"342        $modulePath = Join-Path $TestDrive 'ipmofTestModule.psm1'343    }344 345    AfterEach {346        Get-Module 'ipmofTestModule' | Remove-Module347    }348 349    It "Loads new functions when Import-Module is called with -Force" {350        Set-Content -Path $modulePath -Value $moduleContent351        Import-Module $modulePath352 353        Test-One | Should -Be 101354        { Test-Two } | Should -Throw -ErrorId 'CommandNotFoundException'355 356        Set-Content -Path $modulePath -Value $newModuleContent -Force357        Import-Module -Force $modulePath358 359        Test-One | Should -Be 93360        Test-Two | Should -Be 14361    }362 363    It "Does not load new functions when Import-Module is called without -Force" {364        Set-Content -Path $modulePath -Value $moduleContent365        Import-Module $modulePath366 367        Test-One | Should -Be 101368        { Test-Two } | Should -Throw -ErrorId 'CommandNotFoundException'369 370        Set-Content -Path $modulePath -Value $newModuleContent -Force371        Import-Module $modulePath372 373        Test-One | Should -Be 101374        { Test-Two } | Should -Throw -ErrorId 'CommandNotFoundException'375    }376}377 378Describe "Module with FileList" -Tag "CI" {379    BeforeAll {380        $src = @"381            using System;382            namespace ModuleCmdlets383            {384                public class FileListLoad385                {386                }387            }388"@389 390        $originalPSModulePath = $env:PSModulePath391        New-Item -ItemType Directory -Path "$testdrive\Modules\FileListLoadTest\" -Force > $null392 393        $asmPath = "$TESTDRIVE\Modules\FileListLoadTest\FileListLoadTest.dll"394        Add-Type -TypeDefinition $src -OutputAssembly $asmPath395 396        $env:PSModulePath += [System.IO.Path]::PathSeparator + "$testdrive\Modules"397        New-ModuleManifest -Path "$testdrive\Modules\FileListLoadTest\FileListLoadTest.psd1" -FileList @("FileListLoadTest.dll")398    }399 400    AfterAll {401        $env:PSModulePath = $originalPSModulePath402    }403 404    It "Assemblies in FileList are not loaded" {405        Import-Module FileListLoadTest406        $asms = [System.AppDomain]::CurrentDomain.GetAssemblies().Location407        $asmPath | Should -Not -BeIn $asms408    }409}410