Test/PSDocker.Tests.ps1
#Requires -Modules Pester param ( [string] $PSScriptRoot = $( if ( $PSScriptRoot ) { $PSScriptRoot } else { Get-Location } ), [string] $ModuleManifestPath = "$PSScriptRoot\..\PSDocker.psd1" ) Describe 'ModuleManifest' { It 'is valid' { Test-ModuleManifest -Path $ModuleManifestPath | Should -Not -BeNullOrEmpty $? | Should -Be $true } } Import-Module "$PSScriptRoot\..\PSDocker.psd1" -Force #region Host system Describe 'Docker Service' { It 'is running' { if ( -not $ENV:APPVEYOR ) { $socket = New-Object Net.Sockets.TcpClient $socket.Connect( '127.0.0.1', 2375 ) $socket.Connected | Should -Be $true } } } Describe 'Get-DockerVersion' { It 'is Linux or Windows mode' { $dockerVersion = Get-DockerVersion $dockerVersion.Server.OSArch | Should -BeIn @( 'windows/amd64', 'linux/amd64' ) } } #endregion $testConfig = New-Object -Type PsObject -Property $( switch ( ( Get-DockerVersion ).Server.OSArch ) { 'windows/amd64' { @{ Image = New-Object PsObject -Property @{ Repository = 'microsoft/nanoserver' Tag = 'latest' Name = 'microsoft/nanoserver:latest' } PrintCommand = 'powershell -c Write-Host' PowershellCommand = 'powershell -c ' MountPoint = 'C:\volume' } | Write-Output } 'linux/amd64' { @{ Image = New-Object PsObject -Property @{ Repository = 'microsoft/powershell' Tag = 'latest' Name = 'microsoft/powershell:latest' } PrintCommand = 'echo' PowershellCommand = 'pwsh -c ' MountPoint = '/tmp/volume' } | Write-Output } default { Write-Error "Missing test for $_" } } ) #region Image Describe 'Search-DockerRepository' { It 'returns a list of images' { $images = Search-DockerRepository -Term 'Hello' -Limit $null $images.Count | Should -BeGreaterThan 0 } It 'returns a limited list of images' { $images = Search-DockerRepository -Term 'Hello' -Limit 5 $images.Count | Should -BeLessOrEqual 5 } } Describe 'Install-DockerImage' { It 'works with named parameters' { Install-DockerImage -Repository $testConfig.Image.Repository } It 'works with pipeline parameters' { Search-DockerRepository -Term $testConfig.Image.Repository -Limit 1 | Install-DockerImage } It 'works with name and tag' { Install-DockerImage -Repository $testConfig.Image.Repository -Tag $testConfig.Image.Tag } It 'throws on invalid image' { { Install-DockerImage -Repository 'foobar' -WarningAction 'SilentlyContinue' } | Should Throw } } Describe 'Get-DockerImage' { BeforeAll { Uninstall-DockerImage -Name $testConfig.Image.Repository Install-DockerImage -Repository $testConfig.Image.Repository } It 'returns a list of images' { Get-DockerImage | Where-Object Name -eq $testConfig.Image.Repository | Should -Be } It 'returns a specific image' { ( Get-DockerImage -Repository $testConfig.Image.Repository -Tag $testConfig.Image.Tag ).Repository | Should -Be $testConfig.Image.Repository } It 'returns the installed images from a search' { ( Search-DockerRepository -Term $testConfig.Image.Repository -Limit 1 | Get-DockerImage | Select-Object 'Repository' | Select-Object -Unique ).Repository | Should -Be $testConfig.Image.Repository } } Describe 'Uninstall-DockerImage' { BeforeAll { $testConfig.Image | Install-DockerImage } It 'works with pipeline parameters' { Get-DockerImage -Repository $testConfig.Image.Repository -Tag $testConfig.Image.Tag | Uninstall-DockerImage Get-DockerImage -Repository $testConfig.Image.Repository -Tag $testConfig.Image.Tag | Should -BeNullOrEmpty } } #endregion #region Container Describe 'New-DockerContainer' { BeforeAll { $testConfig.Image | Install-DockerImage } It 'does not throw' { $container = New-DockerContainer -Image $testConfig.Image.Name -Environment @{"A" = 1; "B" = "C"} $container.Image | Should -Be $testConfig.Image.Name $container | Remove-DockerContainer } It 'accepts Get-Image as parameter' { $container = Get-DockerImage -Repository $testConfig.Image.Repository -Tag $testConfig.Image.Tag | New-DockerContainer $container.Image | Should -Be $testConfig.Image.Name $container | Remove-DockerContainer } It 'mounts a volume' { $testSharePath = ( Get-Item 'TestDrive:\' ).FullName $testText = 'lorem ipsum' Set-Content "$testSharePath\test.txt" -Value $testText $container = Get-DockerImage -Repository $testConfig.Image.Repository -Tag $testConfig.Image.Tag | New-DockerContainer -Volumes @{ $testSharePath = $testConfig.MountPoint } -Detach -Interactive Invoke-DockerCommand -Name $container.Name -Command "$( $testConfig.PowershellCommand ) `"Get-Content -Path '$( $testConfig.MountPoint )/test.txt'`"" -StringOutput | Should -Be $testText Remove-DockerContainer -Name $container.Name -Force } } Describe 'Remove-DockerContainer' { BeforeEach { $container = New-DockerContainer -Image $testConfig.Image.Name } It 'works with named parameters' { Remove-DockerContainer -Name $container.Name } It 'works with pipeline parameters' { $container | Remove-DockerContainer } } Describe 'Get-DockerContainer' { It 'returns the correct number of containers' { $baseLineContainer = @( ( New-DockerContainer -Image $testConfig.Image.Name ), ( New-DockerContainer -Image $testConfig.Image.Name ) ) $previousCount = ( Get-DockerContainer ).Count $container = @( ( New-DockerContainer -Image $testConfig.Image.Name ), ( New-DockerContainer -Image $testConfig.Image.Name ), ( New-DockerContainer -Image $testConfig.Image.Name ), ( New-DockerContainer -Image $testConfig.Image.Name ) ) $afterCount = ( Get-DockerContainer ).Count $afterCount | Should -Be $( $previousCount + 4 ) ( $baseLineContainer + $container ) | ForEach-Object { $_ | Remove-DockerContainer } } } #endregion Describe 'Invoke-DockerCommand' { BeforeAll { try { $container = New-DockerContainer -Image $testConfig.Image.Name -Interactive -Detach } catch { Write-Error $_.Exception -ErrorAction 'Continue' throw } } It 'does not throw' { { Invoke-DockerCommand -Name $container.Name -Command 'hostname' } | Should -Not -Throw } It 'returns string output' { Invoke-DockerCommand -Name $container.Name ` -Command $testConfig.PrintCommand ` -ArgumentList 'foobar' -StringOutput | Should -Be 'foobar' } AfterAll { if ( $container ) { Remove-DockerContainer -Name $container.Name -Force } } } |