Add tests to do basic verification of docker images (#4244)

This commit is contained in:
Travis Plunk 2017-07-19 16:48:54 -07:00 committed by Dongbo Wang
parent 3b3b3d1b70
commit 8c7f703f82
3 changed files with 321 additions and 0 deletions

25
docker/tests/README.md Normal file
View 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
```

View 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'
}
}

View 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]
}