forked from sous-chefs/docker
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request sous-chefs#1049 from smcavallo/lint
Chefspec tests for creating containers and windows support
- Loading branch information
Showing
5 changed files
with
192 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
require 'spec_helper' | ||
require 'docker' | ||
require_relative '../../libraries/docker_base' | ||
require_relative '../../libraries/docker_container' | ||
|
||
describe DockerCookbook::DockerContainer do | ||
let(:resource) { DockerCookbook::DockerContainer.new('hello_world') } | ||
|
||
it 'has a default action of [:run]' do | ||
expect(resource.action).to eql([:run]) | ||
end | ||
|
||
describe 'gets ip_address_from_container_networks' do | ||
let(:options) { { 'id' => rand(10_000).to_s } } | ||
subject do | ||
Docker::Container.send(:new, Docker.connection, options) | ||
end | ||
# https://docs.docker.com/engine/api/version-history/#v121-api-changes | ||
context 'when docker API < 1.21' do | ||
let(:ip_address) { '10.0.0.1' } | ||
let(:options) do | ||
{ | ||
'id' => rand(10_000).to_s, | ||
'IPAddress' => ip_address, | ||
} | ||
end | ||
it 'gets ip_address as nil' do | ||
actual = resource.ip_address_from_container_networks(subject) | ||
expect { resource.ip_address_from_container_networks(subject) }.not_to raise_error | ||
expect(actual).to eq(nil) | ||
end | ||
end | ||
context 'when docker API > 1.21' do | ||
let(:ip_address) { '10.0.0.1' } | ||
let(:options) do | ||
{ | ||
'id' => rand(10_000).to_s, | ||
'NetworkSettings' => { | ||
'Networks' => { | ||
'bridge' => { | ||
'IPAMConfig' => { | ||
'IPv4Address' => ip_address, | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
end | ||
it 'gets ip_address' do | ||
actual = resource.ip_address_from_container_networks(subject) | ||
expect(actual).to eq(ip_address) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,55 +1,126 @@ | ||
# Load all the libraries | ||
require 'spec_helper' | ||
require 'chef' | ||
require 'docker' | ||
Dir['libraries/*.rb'].each { |f| require File.expand_path(f) } | ||
require 'excon' | ||
|
||
describe DockerCookbook::DockerContainer do | ||
let(:resource) { DockerCookbook::DockerContainer.new('hello_world') } | ||
require_relative '../../libraries/docker_base' | ||
require_relative '../../libraries/docker_container' | ||
|
||
it 'has a default action of [:run]' do | ||
expect(resource.action).to eql([:run]) | ||
describe 'docker_container' do | ||
step_into :docker_container | ||
platform 'ubuntu' | ||
|
||
# Info returned by docker api | ||
# https://docs.docker.com/engine/api/v1.39/#tag/Container | ||
let(:container) do | ||
{ | ||
'Id' => '123456789', | ||
'IPAddress' => '10.0.0.1', | ||
'Image' => 'ubuntu:bionic', | ||
'Names' => ['/hello_world'], | ||
'Config' => { 'Labels' => {} }, | ||
'HostConfig' => { 'RestartPolicy' => { 'Name' => 'unless-stopped', | ||
'MaximumRetryCount' => 1 }, | ||
'Binds' => [], | ||
'ReadonlyRootfs' => false }, | ||
'State' => 'not running', | ||
'Warnings' => [], | ||
}.to_json | ||
end | ||
# https://docs.docker.com/engine/api/v1.39/#tag/Image | ||
let(:image) do | ||
{ 'Id' => 'bf119e2', | ||
'Repository' => 'ubuntu', 'Tag' => 'bionic', | ||
'Created' => 1_364_102_658, 'Size' => 24_653, | ||
'VirtualSize' => 180_116_135, | ||
'Config' => { 'Labels' => {} } }.to_json | ||
end | ||
# https://docs.docker.com/engine/api/v1.39/#operation/SystemInfo | ||
let(:info) do | ||
{ 'Labels' => {} }.to_json | ||
end | ||
# https://docs.docker.com/engine/api/v1.39/#operation/ContainerCreate | ||
let(:create) do | ||
{ | ||
'Id' => 'e90e34656806', | ||
'Warnings' => [], | ||
}.to_json | ||
end | ||
|
||
describe 'gets ip_address_from_container_networks' do | ||
let(:options) { { 'id' => rand(10_000).to_s } } | ||
subject do | ||
Docker::Container.send(:new, Docker.connection, options) | ||
end | ||
# https://docs.docker.com/engine/api/version-history/#v121-api-changes | ||
context 'when docker API < 1.21' do | ||
let(:ip_address) { '10.0.0.1' } | ||
let(:options) do | ||
{ | ||
'id' => rand(10_000).to_s, | ||
'IPAddress' => ip_address | ||
} | ||
end | ||
it 'gets ip_address as nil' do | ||
actual = resource.ip_address_from_container_networks(subject) | ||
expect { resource.ip_address_from_container_networks(subject) }.not_to raise_error | ||
expect(actual).to eq(nil) | ||
before do | ||
# Ensure docker api calls are mocked | ||
# It is low level much easier to do in Excon | ||
# Plus, the low level mock allows testing this cookbook | ||
# for multiple docker apis and docker-api gems | ||
# https://github.com/excon/excon#stubs | ||
Excon.defaults[:mock] = true | ||
Excon.stub({ method: :get, path: '/v1.16/containers/hello_world/json' }, body: container, status: 200) | ||
Excon.stub({ method: :get, path: '/v1.16/images/ubuntu:bionic/json' }, body: image, status: 200) | ||
Excon.stub({ method: :get, path: '/v1.16/info' }, body: info, status: 200) | ||
Excon.stub({ method: :delete, path: '/v1.16/containers/123456789' }, body: '', status: 200) | ||
Excon.stub({ method: :post, path: '/v1.16/containers/create' }, body: create, status: 200) | ||
Excon.stub({ method: :get, path: '/v1.16/containers/123456789/start' }, body: '', status: 200) | ||
end | ||
|
||
context 'creates a docker container with default options' do | ||
recipe do | ||
docker_container 'hello_world' do | ||
tag 'ubuntu:latest' | ||
action :create | ||
end | ||
end | ||
context 'when docker API > 1.21' do | ||
let(:ip_address) { '10.0.0.1' } | ||
let(:options) do | ||
{ | ||
'id' => rand(10_000).to_s, | ||
'NetworkSettings' => { | ||
'Networks' => { | ||
'bridge' => { | ||
'IPAMConfig' => { | ||
'IPv4Address' => ip_address | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
it { | ||
expect { chef_run }.to_not raise_error | ||
expect(chef_run).to create_docker_container('hello_world').with( | ||
tag: 'ubuntu:latest', | ||
create_options: { 'name' => 'hello_world', 'Image' => 'hello_world:ubuntu:latest', 'Labels' => {}, 'Cmd' => nil, 'AttachStderr' => false, 'AttachStdin' => false, 'AttachStdout' => false, 'Domainname' => '', 'Entrypoint' => nil, 'Env' => [], 'ExposedPorts' => {}, 'Hostname' => nil, 'MacAddress' => nil, 'NetworkDisabled' => false, 'OpenStdin' => false, 'StdinOnce' => false, 'Tty' => false, 'User' => '', 'Volumes' => {}, 'WorkingDir' => '', 'HostConfig' => { 'Binds' => nil, 'CapAdd' => nil, 'CapDrop' => nil, 'CgroupParent' => '', 'CpuShares' => 0, 'CpusetCpus' => '', 'Devices' => [], 'Dns' => [], 'DnsSearch' => [], 'ExtraHosts' => nil, 'IpcMode' => '', 'Init' => nil, 'KernelMemory' => 0, 'Links' => nil, 'LogConfig' => nil, 'Memory' => 0, 'MemorySwap' => 0, 'MemorySwappiness' => 0, 'MemoryReservation' => 0, 'NetworkMode' => 'bridge', 'OomKillDisable' => false, 'OomScoreAdj' => -500, 'Privileged' => false, 'PidMode' => '', 'PortBindings' => {}, 'PublishAllPorts' => false, 'RestartPolicy' => { 'Name' => nil, 'MaximumRetryCount' => 0 }, 'ReadonlyRootfs' => false, 'Runtime' => 'runc', 'SecurityOpt' => nil, 'Sysctls' => {}, 'Ulimits' => nil, 'UsernsMode' => '', 'UTSMode' => '', 'VolumesFrom' => nil, 'VolumeDriver' => nil }, 'NetworkingConfig' => { 'EndpointsConfig' => { 'bridge' => { 'IPAMConfig' => { 'IPv4Address' => nil }, 'Aliases' => [] } } } } | ||
) | ||
} | ||
end | ||
|
||
context 'creates a docker container with healthcheck options' do | ||
recipe do | ||
docker_container 'hello_world' do | ||
tag 'ubuntu:latest' | ||
health_check( | ||
'Test' => | ||
[ | ||
'string', | ||
], | ||
'Interval' => 0, | ||
'Timeout' => 0, | ||
'Retries' => 0, | ||
'StartPeriod' => 0 | ||
) | ||
action :create | ||
end | ||
it 'gets ip_address' do | ||
actual = resource.ip_address_from_container_networks(subject) | ||
expect(actual).to eq(ip_address) | ||
end | ||
|
||
it { | ||
expect { chef_run }.to_not raise_error | ||
expect(chef_run).to create_docker_container('hello_world').with( | ||
tag: 'ubuntu:latest', | ||
create_options: { 'name' => 'hello_world', 'Image' => 'hello_world:ubuntu:latest', 'Labels' => {}, 'Cmd' => nil, 'AttachStderr' => false, 'AttachStdin' => false, 'AttachStdout' => false, 'Domainname' => '', 'Entrypoint' => nil, 'Env' => [], 'ExposedPorts' => {}, 'Hostname' => nil, 'MacAddress' => nil, 'NetworkDisabled' => false, 'OpenStdin' => false, 'StdinOnce' => false, 'Tty' => false, 'User' => '', 'Volumes' => {}, 'WorkingDir' => '', 'HostConfig' => { 'Binds' => nil, 'CapAdd' => nil, 'CapDrop' => nil, 'CgroupParent' => '', 'CpuShares' => 0, 'CpusetCpus' => '', 'Devices' => [], 'Dns' => [], 'DnsSearch' => [], 'ExtraHosts' => nil, 'IpcMode' => '', 'Init' => nil, 'KernelMemory' => 0, 'Links' => nil, 'LogConfig' => nil, 'Memory' => 0, 'MemorySwap' => 0, 'MemorySwappiness' => 0, 'MemoryReservation' => 0, 'NetworkMode' => 'bridge', 'OomKillDisable' => false, 'OomScoreAdj' => -500, 'Privileged' => false, 'PidMode' => '', 'PortBindings' => {}, 'PublishAllPorts' => false, 'RestartPolicy' => { 'Name' => nil, 'MaximumRetryCount' => 0 }, 'ReadonlyRootfs' => false, 'Runtime' => 'runc', 'SecurityOpt' => nil, 'Sysctls' => {}, 'Ulimits' => nil, 'UsernsMode' => '', 'UTSMode' => '', 'VolumesFrom' => nil, 'VolumeDriver' => nil }, 'NetworkingConfig' => { 'EndpointsConfig' => { 'bridge' => { 'IPAMConfig' => { 'IPv4Address' => nil }, 'Aliases' => [] } } }, 'Healthcheck' => { 'Test' => ['string'], 'Interval' => 0, 'Timeout' => 0, 'Retries' => 0, 'StartPeriod' => 0 } } | ||
) | ||
} | ||
end | ||
|
||
context 'creates a docker container with default options for windows' do | ||
platform 'windows' | ||
recipe do | ||
docker_container 'hello_world' do | ||
tag 'ubuntu:latest' | ||
action :create | ||
end | ||
end | ||
|
||
it { | ||
expect { chef_run }.to_not raise_error | ||
expect(chef_run).to create_docker_container('hello_world').with( | ||
tag: 'ubuntu:latest', | ||
# Should be missing 'MemorySwappiness' | ||
create_options: { 'name' => 'hello_world', 'Image' => 'hello_world:ubuntu:latest', 'Labels' => {}, 'Cmd' => nil, 'AttachStderr' => false, 'AttachStdin' => false, 'AttachStdout' => false, 'Domainname' => '', 'Entrypoint' => nil, 'Env' => [], 'ExposedPorts' => {}, 'Hostname' => nil, 'MacAddress' => nil, 'NetworkDisabled' => false, 'OpenStdin' => false, 'StdinOnce' => false, 'Tty' => false, 'User' => '', 'Volumes' => {}, 'WorkingDir' => '', 'HostConfig' => { 'Binds' => nil, 'CapAdd' => nil, 'CapDrop' => nil, 'CgroupParent' => '', 'CpuShares' => 0, 'CpusetCpus' => '', 'Devices' => [], 'Dns' => [], 'DnsSearch' => [], 'ExtraHosts' => nil, 'IpcMode' => '', 'Init' => nil, 'KernelMemory' => 0, 'Links' => nil, 'LogConfig' => nil, 'Memory' => 0, 'MemorySwap' => 0, 'MemoryReservation' => 0, 'NetworkMode' => 'bridge', 'OomKillDisable' => false, 'OomScoreAdj' => -500, 'Privileged' => false, 'PidMode' => '', 'PortBindings' => {}, 'PublishAllPorts' => false, 'RestartPolicy' => { 'Name' => nil, 'MaximumRetryCount' => 0 }, 'ReadonlyRootfs' => false, 'Runtime' => 'runc', 'SecurityOpt' => nil, 'Sysctls' => {}, 'Ulimits' => nil, 'UsernsMode' => '', 'UTSMode' => '', 'VolumesFrom' => nil, 'VolumeDriver' => nil }, 'NetworkingConfig' => { 'EndpointsConfig' => { 'bridge' => { 'IPAMConfig' => { 'IPv4Address' => nil }, 'Aliases' => [] } } } } | ||
) | ||
} | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters