mirror of
https://github.com/PowerShell/PowerShell.git
synced 2024-11-23 17:53:58 +08:00
Add tests to do basic verification of docker images (#4244)
This commit is contained in:
parent
3b3b3d1b70
commit
8c7f703f82
25
docker/tests/README.md
Normal file
25
docker/tests/README.md
Normal file
@ -0,0 +1,25 @@
|
||||
# Docker tests
|
||||
|
||||
## Windows and Linux containers
|
||||
|
||||
The tests must be run separately on the Windows and Linux docker daemons. You can use the Linux docker daemon on Windows, but that will only test Linux containers not Windows Containers.
|
||||
|
||||
## To building and basic behavior of the containers
|
||||
|
||||
```PowerShell
|
||||
Invoke-Pester
|
||||
```
|
||||
|
||||
Note: be sure to do this using both the Windows and Linux docker daemon, as the windows.
|
||||
|
||||
## To test the productions containers
|
||||
|
||||
```PowerShell
|
||||
Invoke-Pester -Tag Behavior
|
||||
```
|
||||
|
||||
## To test only building the containers
|
||||
|
||||
```PowerShell
|
||||
Invoke-Pester -Tag Build
|
||||
```
|
104
docker/tests/container.tests.ps1
Normal file
104
docker/tests/container.tests.ps1
Normal file
@ -0,0 +1,104 @@
|
||||
Import-module -Name "$PSScriptRoot\containerTestCommon.psm1" -Force
|
||||
$script:linuxContainerTests = Get-LinuxContainer
|
||||
$script:windowsContainerTests = Get-WindowsContainer
|
||||
$script:skipLinux = Test-SkipLinux
|
||||
$script:skipWindows = Test-SkipWindows
|
||||
|
||||
Describe "Build Linux Containers" -Tags 'Build', 'Linux' {
|
||||
BeforeAll {
|
||||
Set-RepoName 'pscontainertest'
|
||||
}
|
||||
|
||||
it "$(Get-RepoName):<Name> builds from '<path>'" -TestCases $script:linuxContainerTests -Skip:$script:skipLinux {
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$name,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$path
|
||||
)
|
||||
{ Invoke-Docker -Command build -Params '--pull', '--quiet', '-t', "$(Get-RepoName):${Name}", $path -SuppressHostOutput} | should not throw
|
||||
}
|
||||
}
|
||||
|
||||
Describe "Build Windows Containers" -Tags 'Build', 'Windows' {
|
||||
BeforeAll {
|
||||
Set-RepoName 'pscontainertest'
|
||||
}
|
||||
|
||||
it "$(Get-RepoName):<Name> builds from '<path>'" -TestCases $script:windowsContainerTests -skip:$script:skipWindows {
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$name,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$path
|
||||
)
|
||||
|
||||
{ Invoke-Docker -Command build -Params @(
|
||||
'--pull'
|
||||
'--quiet'
|
||||
'-t'
|
||||
"$(Get-RepoName):${Name}"
|
||||
$path
|
||||
) -SuppressHostOutput} | should not throw
|
||||
}
|
||||
}
|
||||
|
||||
Describe "Linux Containers run PowerShell" -Tags 'Behavior', 'Linux' {
|
||||
BeforeAll{
|
||||
$testContext = Get-TestContext -type Linux
|
||||
}
|
||||
AfterAll{
|
||||
# prune unused volumes
|
||||
$null=Invoke-Docker -Command 'volume', 'prune' -Params '--force' -SuppressHostOutput
|
||||
}
|
||||
BeforeEach
|
||||
{
|
||||
Remove-Item $testContext.resolvedXmlPath -ErrorAction SilentlyContinue
|
||||
Remove-Item $testContext.resolvedLogPath -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
it "Get PSVersion table from $(Get-RepoName):<Name>" -TestCases $script:linuxContainerTests -Skip:$script:skipLinux {
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$name,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$path
|
||||
)
|
||||
|
||||
Get-ContainerPowerShellVersion -TestContext $testContext -Name $Name -RepoName (Get-RepoName) | should be '6.0.0-beta'
|
||||
}
|
||||
}
|
||||
|
||||
Describe "Windows Containers run PowerShell" -Tags 'Behavior', 'Windows' {
|
||||
BeforeAll{
|
||||
$testContext = Get-TestContext -type Windows
|
||||
}
|
||||
BeforeEach
|
||||
{
|
||||
Remove-Item $testContext.resolvedXmlPath -ErrorAction SilentlyContinue
|
||||
Remove-Item $testContext.resolvedLogPath -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
it "Get PSVersion table from $(Get-RepoName):<Name>" -TestCases $script:windowsContainerTests -skip:$script:skipWindows {
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$name,
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$path
|
||||
)
|
||||
|
||||
Get-ContainerPowerShellVersion -TestContext $testContext -Name $Name -RepoName (Get-RepoName) | should be '6.0.0-beta'
|
||||
}
|
||||
}
|
192
docker/tests/containerTestCommon.psm1
Normal file
192
docker/tests/containerTestCommon.psm1
Normal file
@ -0,0 +1,192 @@
|
||||
$script:forcePull = $true
|
||||
# Get docker Engine OS
|
||||
function Get-DockerEngineOs
|
||||
{
|
||||
docker info --format '{{ .OperatingSystem }}'
|
||||
}
|
||||
|
||||
# Call Docker with appropriate result checksfunction Invoke-Docker
|
||||
function Invoke-Docker
|
||||
{
|
||||
param(
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string[]]
|
||||
$Command,
|
||||
[ValidateSet("error","warning",'ignore')]
|
||||
$FailureAction = 'error',
|
||||
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string[]]
|
||||
$Params,
|
||||
|
||||
[switch]
|
||||
$PassThru,
|
||||
[switch]
|
||||
$SuppressHostOutput
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Continue'
|
||||
|
||||
# Log how we are running docker for troubleshooting issues
|
||||
Write-Verbose "Running docker $command $params" -Verbose
|
||||
if($SuppressHostOutput.IsPresent)
|
||||
{
|
||||
$result = docker $command $params 2>&1
|
||||
}
|
||||
else
|
||||
{
|
||||
&'docker' $command $params 2>&1 | Tee-Object -Variable result -ErrorAction SilentlyContinue | Out-String -Stream -ErrorAction SilentlyContinue | Write-Host -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
$dockerExitCode = $LASTEXITCODE
|
||||
if($PassThru.IsPresent)
|
||||
{
|
||||
Write-Verbose "passing through docker result$($result.length)..." -Verbose
|
||||
return $result
|
||||
}
|
||||
elseif($dockerExitCode -ne 0 -and $FailureAction -eq 'error')
|
||||
{
|
||||
Write-Error "docker $command failed with: $result" -ErrorAction Stop
|
||||
return $false
|
||||
}
|
||||
elseif($dockerExitCode -ne 0 -and $FailureAction -eq 'warning')
|
||||
{
|
||||
Write-Warning "docker $command failed with: $result"
|
||||
return $false
|
||||
}
|
||||
elseif($dockerExitCode -ne 0)
|
||||
{
|
||||
return $false
|
||||
}
|
||||
|
||||
return $true
|
||||
}
|
||||
|
||||
# Return a list of Linux Container Test Cases
|
||||
function Get-LinuxContainer
|
||||
{
|
||||
foreach($os in 'centos7','opensuse42.1','ubuntu14.04','ubuntu16.04')
|
||||
{
|
||||
Write-Output @{
|
||||
Name = $os
|
||||
Path = "$psscriptroot/../release/$os"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# Return a list of Windows Container Test Cases
|
||||
function Get-WindowsContainer
|
||||
{
|
||||
foreach($os in 'windowsservercore','nanoserver')
|
||||
{
|
||||
Write-Output @{
|
||||
Name = $os
|
||||
Path = "$psscriptroot/../release/$os"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$script:repoName = 'microsoft/powershell'
|
||||
function Get-RepoName
|
||||
{
|
||||
return $script:repoName
|
||||
}
|
||||
|
||||
function Set-RepoName
|
||||
{
|
||||
param([string]$RepoName)
|
||||
|
||||
$script:repoName = $RepoName
|
||||
$script:forcePull = $false
|
||||
}
|
||||
|
||||
function Test-SkipWindows
|
||||
{
|
||||
[bool] $canRunWindows = (Get-DockerEngineOs) -like 'Windows*'
|
||||
return ($IsLinux -or $IsOSX -or !$canRunWindows)
|
||||
}
|
||||
|
||||
function Test-SkipLinux
|
||||
{
|
||||
return !((Get-DockerEngineOs) -like 'Alpine Linux*')
|
||||
}
|
||||
|
||||
function Get-TestContext
|
||||
{
|
||||
param(
|
||||
[ValidateSet('Linux','Windows','macOS')]
|
||||
[string]$Type
|
||||
)
|
||||
|
||||
$resultFileName = 'results.xml'
|
||||
$logFileName = 'results.log'
|
||||
$containerTestDrive = '/test'
|
||||
|
||||
# Return a windows context if the Context in Windows *AND*
|
||||
# the current system is windows, otherwise Join-path will fail.
|
||||
if($Type -eq 'Windows' -and $IsWindows)
|
||||
{
|
||||
$ContainerTestDrive = 'C:\test'
|
||||
}
|
||||
$resolvedTestDrive = (Resolve-Path "Testdrive:\").providerPath
|
||||
|
||||
return @{
|
||||
ResolvedTestDrive = $resolvedTestDrive
|
||||
ResolvedXmlPath = Join-Path $resolvedTestDrive -ChildPath $resultFileName
|
||||
ResolvedLogPath = Join-Path $resolvedTestDrive -ChildPath $logFileName
|
||||
ContainerTestDrive = $ContainerTestDrive
|
||||
ContainerXmlPath = Join-Path $containerTestDrive -ChildPath $resultFileName
|
||||
ContainerLogPath = Join-Path $containerTestDrive -ChildPath $logFileName
|
||||
Type = $Type
|
||||
ForcePull = $script:forcePull
|
||||
}
|
||||
}
|
||||
|
||||
function Get-ContainerPowerShellVersion
|
||||
{
|
||||
param(
|
||||
[HashTable] $TestContext,
|
||||
[string] $RepoName,
|
||||
[string] $Name
|
||||
)
|
||||
|
||||
$imageTag = "${script:repoName}:${Name}"
|
||||
|
||||
if($TestContext.ForcePull)
|
||||
{
|
||||
$null=Invoke-Docker -Command 'image', 'pull' -Params $imageTag -SuppressHostOutput
|
||||
}
|
||||
|
||||
$runParams = @()
|
||||
$localVolumeName = $testContext.resolvedTestDrive
|
||||
$runParams += '--rm'
|
||||
if($TestContext.Type -ne 'Windows' -and $isWindows)
|
||||
{
|
||||
# use a container volume on windows because host volumes are not automatic
|
||||
$volumeName = "test-volume-" + (Get-Random -Minimum 100 -Maximum 999)
|
||||
|
||||
# using alpine because it's tiny
|
||||
$null=Invoke-Docker -Command create -Params '-v', '/test', '--name', $volumeName, 'alpine' -SuppressHostOutput
|
||||
$runParams += '--volumes-from'
|
||||
$runParams += $volumeName
|
||||
}
|
||||
else {
|
||||
$runParams += '-v'
|
||||
$runParams += "${localVolumeName}:$($testContext.containerTestDrive)"
|
||||
}
|
||||
|
||||
$runParams += $imageTag
|
||||
$runParams += 'powershell'
|
||||
$runParams += '-c'
|
||||
$runParams += ('$PSVersionTable.PSVersion.ToString() | out-string | out-file -encoding ascii -FilePath '+$testContext.containerLogPath)
|
||||
|
||||
$null = Invoke-Docker -Command run -Params $runParams -SuppressHostOutput
|
||||
if($TestContext.Type -ne 'Windows' -and $isWindows)
|
||||
{
|
||||
$null = Invoke-Docker -Command cp -Params "${volumeName}:$($testContext.containerLogPath)", $TestContext.ResolvedLogPath
|
||||
$null = Invoke-Docker -Command container, rm -Params $volumeName, '--force' -SuppressHostOutput
|
||||
}
|
||||
return (Get-Content -Encoding Ascii $testContext.resolvedLogPath)[0]
|
||||
}
|
Loading…
Reference in New Issue
Block a user