diff --git a/.puppet-lint.rc b/.puppet-lint.rc new file mode 100644 index 0000000..cc96ece --- /dev/null +++ b/.puppet-lint.rc @@ -0,0 +1 @@ +--relative diff --git a/.sync.yml b/.sync.yml index 41f3543..3a8fe94 100644 --- a/.sync.yml +++ b/.sync.yml @@ -1,40 +1,43 @@ --- .gitlab-ci.yml: delete: true .rubocop.yml: default_configs: inherit_from: .rubocop_todo.yml require: - rubocop-rspec .travis.yml: docker_sets: - set: docker/debian-8 - set: docker/ubuntu-14.04 docker_defaults: bundler_args: "" secure: "" branches: - release appveyor.yml: delete: true Gemfile: optional: ':development': - gem: 'github_changelog_generator' git: 'https://github.com/skywinder/github-changelog-generator' ref: '20ee04ba1234e9e83eb2ffb5056e23d641c7a018' condition: "Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.2.2')" required: ':system_tests': - gem: 'puppet-module-posix-system-r#{minor_version}' platforms: ruby - gem: 'puppet-module-win-system-r#{minor_version}' platforms: - mswin - mingw - x64_mingw - - gem: 'rspec-retry' \ No newline at end of file + - gem: 'rspec-retry' + +spec/spec_helper.rb: + unmanaged: true \ No newline at end of file diff --git a/spec/acceptance/compose_v3_spec.rb b/spec/acceptance/compose_v3_spec.rb index d83e228..a7324c7 100644 --- a/spec/acceptance/compose_v3_spec.rb +++ b/spec/acceptance/compose_v3_spec.rb @@ -1,157 +1,157 @@ require 'spec_helper_acceptance' if fact('osfamily') == 'windows' install_dir = '/cygdrive/c/Program Files/Docker' file_extension = '.exe' docker_args = 'docker_ee => true' tmp_path = 'C:/cygwin64/tmp' test_container = 'nanoserver-sac2016' else - if fact('os.name') == 'RedHat' - docker_args = "repo_opt => '--enablerepo=localmirror-extras'" - elsif fact('os.name') == 'Centos' - docker_args = "repo_opt => '--enablerepo=localmirror-extras'" - elsif fact('os.name') == 'Ubuntu' && fact('os.release.full') == '14.04' - docker_args = "version => '18.06.1~ce~3-0~ubuntu'" - else - docker_args = '' - end + docker_args = if fact('os.name') == 'RedHat' + "repo_opt => '--enablerepo=localmirror-extras'" + elsif fact('os.name') == 'Centos' + "repo_opt => '--enablerepo=localmirror-extras'" + elsif fact('os.name') == 'Ubuntu' && fact('os.release.full') == '14.04' + "version => '18.06.1~ce~3-0~ubuntu'" + else + '' + end install_dir = '/usr/local/bin' file_extension = '' tmp_path = '/tmp' test_container = 'debian' end describe 'docker compose' do before(:all) do - retry_on_error_matching(60, 5, /connection failure running/) do + retry_on_error_matching(60, 5, %r{connection failure running}) do install_code = <<-code class { 'docker': #{docker_args} } class { 'docker::compose': version => '1.23.2', } code - apply_manifest(install_code, :catch_failures=>true) + apply_manifest(install_code, catch_failures: true) end end context 'Creating compose v3 projects' do - it 'should have docker compose installed' do - shell('docker-compose --help', :acceptable_exit_codes => [0]) + let(:install_pp) do + <<-MANIFEST + docker_compose { 'web': + compose_files => ['#{tmp_path}/docker-compose-v3.yml'], + ensure => present, + } + MANIFEST end - before(:all) do - @install = <<-code -docker_compose { 'web': - compose_files => ['#{tmp_path}/docker-compose-v3.yml'], - ensure => present, -} - code - apply_manifest(@install, :catch_failures=>true) + + it 'is idempotent' do + idempotent_apply(default, install_pp, {}) end - it 'should be idempotent' do - apply_manifest(@install, :catch_changes=>true) + it 'has docker compose installed' do + shell('docker-compose --help', acceptable_exit_codes: [0]) end - it 'should find a docker container' do - shell('docker inspect web_compose_test_1', :acceptable_exit_codes => [0]) + it 'finds a docker container' do + shell('docker inspect web_compose_test_1', acceptable_exit_codes: [0]) end end context 'creating compose projects with multi compose files' do before(:all) do - @install = <<-pp1 -docker_compose { 'web1': - compose_files => ['#{tmp_path}/docker-compose-v3.yml', '#{tmp_path}/docker-compose-override-v3.yml'], - ensure => present, -} - pp1 + install_pp = <<-MANIFEST + docker_compose { 'web1': + compose_files => ['#{tmp_path}/docker-compose-v3.yml', '#{tmp_path}/docker-compose-override-v3.yml'], + ensure => present, + } + MANIFEST - apply_manifest(@install, :catch_failures=>true) + apply_manifest(install_pp, catch_failures: true) end it "should find container with #{test_container} tag" do - shell("docker inspect web1_compose_test_1 | grep #{test_container}", :acceptable_exit_codes => [0]) + shell("docker inspect web1_compose_test_1 | grep #{test_container}", acceptable_exit_codes: [0]) end end context 'Destroying project with multiple compose files' do + let(:destroy_pp) do + <<-MANIFEST + docker_compose { 'web1': + compose_files => ['#{tmp_path}/docker-compose-v3.yml', '#{tmp_path}/docker-compose-override-v3.yml'], + ensure => absent, + } + MANIFEST + end + before(:all) do - @install = <<-pp1 -docker_compose { 'web1': - compose_files => ['#{tmp_path}/docker-compose-v3.yml', '#{tmp_path}/docker-compose-override-v3.yml'], - ensure => present, -} - pp1 + install_pp = <<-MANIFEST + docker_compose { 'web1': + compose_files => ['#{tmp_path}/docker-compose-v3.yml', '#{tmp_path}/docker-compose-override-v3.yml'], + ensure => present, + } + MANIFEST - @destroy = <<-pp2 -docker_compose { 'web1': - compose_files => ['#{tmp_path}/docker-compose-v3.yml', '#{tmp_path}/docker-compose-override-v3.yml'], - ensure => absent, -} - pp2 - apply_manifest(@install, :catch_failures=>true) - apply_manifest(@destroy, :catch_failures=>true) + apply_manifest(install_pp, catch_failures: true) end - it 'should be idempotent' do - apply_manifest(@destroy, :catch_changes=>true) + it 'is idempotent' do + idempotent_apply(default, destroy_pp, {}) end - it 'should not find a docker container' do - shell('docker inspect web1_compose_test_1', :acceptable_exit_codes => [1]) + it 'does not find a docker container' do + shell('docker inspect web1_compose_test_1', acceptable_exit_codes: [1]) end end context 'Requesting a specific version of compose' do - before(:all) do - @version = '1.21.2' - @pp = <<-code -class { 'docker::compose': - version => '#{@version}', -} - code - apply_manifest(@pp, :catch_failures=>true) + let(:version) do + '1.21.2' end - it 'should be idempotent' do - apply_manifest(@pp, :catch_changes=>true) + it 'is idempotent' do + pp = <<-MANIFEST + class { 'docker::compose': + version => '#{version}', + } + MANIFEST + idempotent_apply(default, pp, {}) end - it 'should have installed the requested version' do - shell('docker-compose --version', :acceptable_exit_codes => [0]) do |r| - expect(r.stdout).to match(/#{@version}/) + it 'has installed the requested version' do + shell('docker-compose --version', acceptable_exit_codes: [0]) do |r| + expect(r.stdout).to match(%r{#{version}}) end end end context 'Removing docker compose' do - before(:all) do - @version = '1.21.2' - @pp = <<-code -class { 'docker::compose': - ensure => absent, - version => '#{@version}', -} - code - apply_manifest(@pp, :catch_failures=>true) + let(:version) do + '1.21.2' end - it 'should be idempotent' do - apply_manifest(@pp, :catch_changes=>true) + it 'is idempotent' do + pp = <<-MANIFEST + class { 'docker::compose': + ensure => absent, + version => '#{version}', + } + MANIFEST + idempotent_apply(default, pp, {}) end - it 'should have removed the relevant files' do - shell("test -e \"#{install_dir}/docker-compose#{file_extension}\"", :acceptable_exit_codes => [1]) - shell("test -e \"#{install_dir}/docker-compose-#{@version}#{file_extension}\"", :acceptable_exit_codes => [1]) + it 'has removed the relevant files' do + shell("test -e \"#{install_dir}/docker-compose#{file_extension}\"", acceptable_exit_codes: [1]) + shell("test -e \"#{install_dir}/docker-compose-#{version}#{file_extension}\"", acceptable_exit_codes: [1]) end after(:all) do - install_code = <<-code + install_pp = <<-MANIFEST class { 'docker': #{docker_args}} class { 'docker::compose': } - code - apply_manifest(install_code, :catch_failures=>true) + MANIFEST + apply_manifest(install_pp, catch_failures: true) end end - end +end diff --git a/spec/acceptance/docker_custom_source_spec.rb b/spec/acceptance/docker_custom_source_spec.rb index 6229ae8..a5675e4 100644 --- a/spec/acceptance/docker_custom_source_spec.rb +++ b/spec/acceptance/docker_custom_source_spec.rb @@ -1,106 +1,107 @@ require 'spec_helper_acceptance' skip = false if fact('osfamily') == 'windows' - docker_args = 'docker_ee => true, docker_ee_source_location => "https://download.docker.com/components/engine/windows-server/17.06/docker-17.06.2-ee-14.zip"' - default_image = 'winamd64/hello-world' - default_image_tag = 'nanoserver-sac2016' - #The default args are set because: - #restart => 'always' - there is no service created to manage containers - #net => 'nat' - docker uses bridged by default when running a container. When installing docker on windows the default network is NAT. - default_docker_run_arg = "restart => 'always', net => 'nat'," - default_run_command = "ping 127.0.0.1 -t" - docker_command = "\"/cygdrive/c/Program Files/Docker/docker\"" - skip = false + docker_args = 'docker_ee => true, docker_ee_source_location => "https://download.docker.com/components/engine/windows-server/17.06/docker-17.06.2-ee-14.zip"' + default_image = 'winamd64/hello-world' + # The default args are set because: + # restart => 'always' - there is no service created to manage containers + # net => 'nat' - docker uses bridged by default when running a container. When installing docker on windows the default network is NAT. + default_docker_run_arg = "restart => 'always', net => 'nat'," + default_run_command = 'ping 127.0.0.1 -t' + docker_command = '"/cygdrive/c/Program Files/Docker/docker"' + skip = false elsif fact('os.name') == 'Ubuntu' && fact('os.release.full') == '14.04' - docker_args = "version => '18.06.1~ce~3-0~ubuntu'" - skip = true + docker_args = "version => '18.06.1~ce~3-0~ubuntu'" + skip = true else - docker_args = '' - skip = true + docker_args = '' + skip = true end describe 'the Puppet Docker module' do - context 'with download location', :skip => skip do - let(:pp) {" - class { 'docker': #{docker_args} } - "} + context 'with download location', skip: skip do + let(:pp) do + " + class { 'docker': #{docker_args} } + " + end - it 'should run successfully' do - apply_manifest(pp, :catch_failures => true) + it 'runs successfully' do + apply_manifest(pp, catch_failures: true) end - it 'should run idempotently' do - apply_manifest(pp, :catch_changes => true) unless fact('selinux') == 'true' + it 'runs idempotently' do + apply_manifest(pp, catch_changes: true) unless fact('selinux') == 'true' end - it 'should be start a docker process' do - if fact('osfamily') == 'windows' + it 'is start a docker process' do + if fact('osfamily') == 'windows' shell('powershell Get-Process -Name dockerd') do |r| - expect(r.stdout).to match(/ProcessName/) + expect(r.stdout).to match(%r{ProcessName}) end - else + else shell('ps aux | grep docker') do |r| - expect(r.stdout).to match(/dockerd -H unix:\/\/\/var\/run\/docker.sock/) - end + expect(r.stdout).to match %r{dockerd -H unix:\/\/\/var\/run\/docker.sock} end + end end - it 'should install a working docker client' do - shell("#{docker_command} ps", :acceptable_exit_codes => [0] ) + it 'installs a working docker client' do + shell("#{docker_command} ps", acceptable_exit_codes: [0]) end - it 'should stop a running container and remove container' do - pp=<<-EOS + it 'stops a running container and remove container' do + pp = <<-EOS class { 'docker': #{docker_args} } docker::image { '#{default_image}': require => Class['docker'], } docker::run { 'container_3_6': image => '#{default_image}', command => '#{default_run_command}', require => Docker::Image['#{default_image}'], #{default_docker_run_arg} } EOS - pp2=<<-EOS + pp2 = <<-EOS class { 'docker': #{docker_args} } docker::image { '#{default_image}': require => Class['docker'], } docker::run { 'container_3_6': ensure => 'absent', image => '#{default_image}', require => Docker::Image['#{default_image}'], } EOS - apply_manifest(pp, :catch_failures => true) - apply_manifest(pp, :catch_changes => true) unless fact('selinux') == 'true' + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) unless fact('selinux') == 'true' - # A sleep to give docker time to execute properly - sleep 15 + # A sleep to give docker time to execute properly + sleep 15 - shell("#{docker_command} ps", :acceptable_exit_codes => [0]) + shell("#{docker_command} ps", acceptable_exit_codes: [0]) - apply_manifest(pp2, :catch_failures => true) - apply_manifest(pp2, :catch_changes => true) unless fact('selinux') == 'true' + apply_manifest(pp2, catch_failures: true) + apply_manifest(pp2, catch_changes: true) unless fact('selinux') == 'true' - # A sleep to give docker time to execute properly - sleep 15 + # A sleep to give docker time to execute properly + sleep 15 - shell("#{docker_command} inspect container-3-6", :acceptable_exit_codes => [1]) - if fact('osfamily') == 'windows' - shell('test -f /cygdrive/c/Users/Administrator/AppData/Local/Temp/container-3-6.service', :acceptable_exit_codes => [1]) - else - shell('test -f /etc/systemd/system/container-3-6.service', :acceptable_exit_codes => [1]) + shell("#{docker_command} inspect container-3-6", acceptable_exit_codes: [1]) + if fact('osfamily') == 'windows' + shell('test -f /cygdrive/c/Users/Administrator/AppData/Local/Temp/container-3-6.service', acceptable_exit_codes: [1]) + else + shell('test -f /etc/systemd/system/container-3-6.service', acceptable_exit_codes: [1]) + end end end end -end \ No newline at end of file diff --git a/spec/acceptance/docker_full_spec.rb b/spec/acceptance/docker_full_spec.rb index 79f2e7b..5f3ee2a 100644 --- a/spec/acceptance/docker_full_spec.rb +++ b/spec/acceptance/docker_full_spec.rb @@ -1,966 +1,958 @@ require 'spec_helper_acceptance' if fact('kernel') == 'windows' docker_args = 'docker_ee => true' default_image = 'winamd64/hello-world' default_image_tag = 'nanoserver-sac2016' default_digest = 'sha256:88f6207b9281e60dc4a91008e68b542cc7350d06985c7fc3c5132e6f6b9b3ebe' second_image = 'winamd64/hola-mundo' default_dockerfile = 'C:/Users/Administrator/AppData/Local/Temp/Dockerfile' dockerfile_test = 'C:/Windows/Dockerfile_test.txt' - #The default args are set because: - #restart => 'always' - there is no service created to manage containers - #net => 'nat' - docker uses bridged by default when running a container. When installing docker on windows the default network is NAT. + # The default args are set because: + # restart => 'always' - there is no service created to manage containers + # net => 'nat' - docker uses bridged by default when running a container. When installing docker on windows the default network is NAT. default_docker_run_arg = "restart => 'always', net => 'nat'," - default_run_command = "ping 127.0.0.1 -t" - docker_command = "\"/cygdrive/c/Program Files/Docker/docker\"" + default_run_command = 'ping 127.0.0.1 -t' + docker_command = '"/cygdrive/c/Program Files/Docker/docker"' default_docker_exec_lr_command = 'cmd /c "ping 127.0.0.1 -t > c:\windows\temp\test_file.txt"' default_docker_exec_command = 'cmd /c "echo test > c:\windows\temp\test_file.txt"' docker_mount_path = 'C:/Users/Administrator/AppData/Local/Temp' - storage_driver = "windowsfilter" + storage_driver = 'windowsfilter' else - if fact('os.family') == 'RedHat' - docker_args = "repo_opt => '--enablerepo=localmirror-extras'" - elsif fact('os.name') == 'Ubuntu' && fact('os.release.full') == '14.04' - docker_args = "version => '18.06.1~ce~3-0~ubuntu'" - else - docker_args = '' - end + docker_args = if fact('os.family') == 'RedHat' + "repo_opt => '--enablerepo=localmirror-extras'" + elsif fact('os.name') == 'Ubuntu' && fact('os.release.full') == '14.04' + "version => '18.06.1~ce~3-0~ubuntu'" + else + '' + end default_image = 'alpine' second_image = 'busybox' default_image_tag = '3.7' default_digest = 'sha256:3dcdb92d7432d56604d4545cbd324b14e647b313626d99b889d0626de158f73a' default_dockerfile = '/root/Dockerfile' dockerfile_test = "#{default_dockerfile}_test.txt" - docker_command = "docker" + docker_command = 'docker' default_docker_run_arg = '' - default_run_command = "init" + default_run_command = 'init' default_docker_exec_lr_command = '/bin/sh -c "touch /root/test_file.txt; while true; do echo hello world; sleep 1; done"' default_docker_exec_command = 'touch /root/test_file.txt' - docker_mount_path = "/root" - storage_driver = "devicemapper" - if fact('os.family') == 'Debian' && fact('os.release.major') =~ (/14.04|^8$/) - storage_driver = "aufs" - elsif fact('os.family') == 'RedHat' - storage_driver = "devicemapper" - else - storage_driver = "overlay2" - end + docker_mount_path = '/root' + storage_driver = 'devicemapper' + storage_driver = if fact('os.family') == 'Debian' && fact('os.release.major') =~ %r{14.04|^8$} + 'aufs' + elsif fact('os.family') == 'RedHat' + 'devicemapper' + else + 'overlay2' + end end describe 'the Puppet Docker module' do context 'clean up before each test' do before(:each) do - retry_on_error_matching(60, 5, /connection failure running/) do + retry_on_error_matching(60, 5, %r{connection failure running}) do # Stop all container using systemd shell('ls -D -1 /etc/systemd/system/docker-container* | sed \'s/\/etc\/systemd\/system\///g\' | sed \'s/\.service//g\' | while read container; do service $container stop; done') # Delete all running containers shell("#{docker_command} rm -f $(#{docker_command} ps -a -q) || true") # Delete all existing images shell("#{docker_command} rmi -f $(#{docker_command} images -q) || true") # Check to make sure no images are present shell("#{docker_command} images | wc -l") do |r| - expect(r.stdout).to match(/^0|1$/) + expect(r.stdout).to match(%r{^0|1$}) # rubocop:disable RSpec/ExpectInHook: end # Check to make sure no running containers are present shell("#{docker_command} ps | wc -l") do |r| - expect(r.stdout).to match(/^0|1$/) + expect(r.stdout).to match(%r{^0|1$}) # rubocop:disable RSpec/ExpectInHook: end end end - describe 'docker class' do context 'without any parameters' do - let(:pp) {" - class { 'docker': #{docker_args} } - "} + let(:pp) { "class { 'docker': #{docker_args} }" } - it 'should run successfully' do - apply_manifest(pp, :catch_failures => true) + it 'runs successfully' do + apply_manifest(pp, catch_failures: true) end - it 'should run idempotently' do - apply_manifest(pp, :catch_changes => true) unless fact('selinux') == 'true' + it 'runs idempotently' do + apply_manifest(pp, catch_changes: true) unless fact('selinux') == 'true' end - it 'should be start a docker process' do + it 'is start a docker process' do if fact('osfamily') == 'windows' shell('powershell Get-Process -Name dockerd') do |r| - expect(r.stdout).to match(/ProcessName/) + expect(r.stdout).to match(%r{ProcessName}) end else shell('ps aux | grep docker') do |r| - expect(r.stdout).to match(/dockerd -H unix:\/\/\/var\/run\/docker.sock/) + expect(r.stdout).to match(%r{dockerd -H unix:\/\/\/var\/run\/docker.sock}) end end end - it 'should install a working docker client' do - shell("#{docker_command} ps", :acceptable_exit_codes => [0] ) + it 'installs a working docker client' do + shell("#{docker_command} ps", acceptable_exit_codes: [0]) end - it 'should stop a running container and remove container' do - pp=<<-EOS + it 'stops a running container and remove container' do + pp = <<-EOS class { 'docker': #{docker_args} } docker::image { '#{default_image}': require => Class['docker'], } docker::run { 'container_3_6': image => '#{default_image}', command => '#{default_run_command}', require => Docker::Image['#{default_image}'], #{default_docker_run_arg} } EOS - pp2=<<-EOS + pp2 = <<-EOS class { 'docker': #{docker_args} } docker::image { '#{default_image}': require => Class['docker'], } docker::run { 'container_3_6': ensure => 'absent', image => '#{default_image}', require => Docker::Image['#{default_image}'], } EOS - apply_manifest(pp, :catch_failures => true) - apply_manifest(pp, :catch_changes => true) unless fact('selinux') == 'true' + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) unless fact('selinux') == 'true' - # A sleep to give docker time to execute properly - sleep 15 + # A sleep to give docker time to execute properly + sleep 15 - shell("#{docker_command} ps", :acceptable_exit_codes => [0]) + shell("#{docker_command} ps", acceptable_exit_codes: [0]) - apply_manifest(pp2, :catch_failures => true) - apply_manifest(pp2, :catch_changes => true) unless fact('selinux') == 'true' + apply_manifest(pp2, catch_failures: true) + apply_manifest(pp2, catch_changes: true) unless fact('selinux') == 'true' - # A sleep to give docker time to execute properly - sleep 15 + # A sleep to give docker time to execute properly + sleep 15 - shell("#{docker_command} inspect container-3-6", :acceptable_exit_codes => [1]) - if fact('osfamily') == 'windows' - shell('test -f /cygdrive/c/Users/Administrator/AppData/Local/Temp/container-3-6.service', :acceptable_exit_codes => [1]) - else - shell('test -f /etc/systemd/system/container-3-6.service', :acceptable_exit_codes => [1]) + shell("#{docker_command} inspect container-3-6", acceptable_exit_codes: [1]) + if fact('osfamily') == 'windows' + shell('test -f /cygdrive/c/Users/Administrator/AppData/Local/Temp/container-3-6.service', acceptable_exit_codes: [1]) + else + shell('test -f /etc/systemd/system/container-3-6.service', acceptable_exit_codes: [1]) + end end end - end context 'passing a storage driver' do - before(:all) do - @pp=<<-EOS + let(:pp) do + <<-MANIFEST class {'docker': - #{docker_args}, - storage_driver => "#{storage_driver}", + #{docker_args}, + storage_driver => "#{storage_driver}", } - EOS + MANIFEST + end - apply_manifest(@pp, :catch_failures => true) + it 'applies manifest' do + apply_manifest(pp, catch_failures: true) sleep 15 - end + end - it 'should result in the docker daemon being configured with the specified storage driver' do - shell("#{docker_command} info -f \"{{ .Driver}}\"") do |r| - expect(r.stdout).to match (/#{storage_driver}/) - end + it 'results in the docker daemon being configured with the specified storage driver' do + shell("#{docker_command} info -f \"{{ .Driver}}\"") do |r| + expect(r.stdout).to match %r{#{storage_driver}} end + end end context 'passing a TCP address to bind to' do - before(:all) do - @pp =<<-EOS + let(:pp) do + <<-MANIFEST class { 'docker': tcp_bind => 'tcp://127.0.0.1:4444', #{docker_args} } - EOS - apply_manifest(@pp, :catch_failures => true) - # A sleep to give docker time to execute properly - sleep 4 + MANIFEST end - it 'should run idempotently' do - apply_manifest(@pp, :catch_changes => true) unless fact('selinux') == 'true' + it 'runs idempotently' do + idempotent_apply(default, pp, {}) unless fact('selinux') == 'true' + sleep 4 end - it 'should result in docker listening on the specified address' do + it 'results in docker listening on the specified address' do if fact('osfamily') == 'windows' shell('netstat -a -b') do |r| - expect(r.stdout).to match(/127.0.0.1:4444/) + expect(r.stdout).to match(%r{127.0.0.1:4444}) end else shell('netstat -tulpn | grep docker') do |r| - expect(r.stdout).to match(/tcp\s+0\s+0\s+127.0.0.1:4444\s+0.0.0.0\:\*\s+LISTEN\s+\d+\/docker/) + expect(r.stdout).to match(%r{tcp\s+0\s+0\s+127.0.0.1:4444\s+0.0.0.0\:\*\s+LISTEN\s+\d+\/docker}) end end end end context 'bound to a particular unix socket' do - before(:each) do - @pp =<<-EOS + let(:pp) do + <<-MANIFEST class { 'docker': socket_bind => 'unix:///var/run/docker.sock', #{docker_args} } - EOS - apply_manifest(@pp, :catch_failures => true) - # A sleep to give docker time to execute properly - sleep 4 + MANIFEST end - it 'should run idempotently' do - apply_manifest(@pp, :catch_changes => true) unless fact('selinux') == 'true' + it 'runs idempotently' do + idempotent_apply(default, pp, {}) unless fact('selinux') == 'true' + sleep 4 end - it 'should show docker listening on the specified unix socket' do + it 'shows docker listening on the specified unix socket' do if fact('osfamily') != 'windows' shell('ps aux | grep docker') do |r| - expect(r.stdout).to match(/unix:\/\/\/var\/run\/docker.sock/) + expect(r.stdout).to match(%r{unix:\/\/\/var\/run\/docker.sock}) end end end end context 'uninstall docker' do after(:all) do - @pp =<<-EOS + pp = <<-EOS class {'docker': #{docker_args}, ensure => 'present' } EOS - apply_manifest(@pp, :catch_failures => true) + apply_manifest(pp, catch_failures: true) # Wait for reboot if windows sleep 300 if fact('osfamily') == 'windows' end - it 'should uninstall successfully' do - @pp =<<-EOS + it 'uninstalls successfully' do + pp = <<-EOS class {'docker': #{docker_args}, ensure => 'absent' } EOS - apply_manifest(@pp, :catch_failures => true) + apply_manifest(pp, catch_failures: true) sleep 4 - shell('docker ps', :acceptable_exit_codes => [1, 127]) + shell('docker ps', acceptable_exit_codes: [1, 127]) end end end describe 'docker::image' do - - it 'should successfully download an image from the Docker Hub' do - pp=<<-EOS + it 'successfullies download an image from the Docker Hub' do + pp = <<-EOS class { 'docker': #{docker_args} } docker::image { '#{default_image}': ensure => present, require => Class['docker'], } EOS - apply_manifest(pp, :catch_failures => true) - apply_manifest(pp, :catch_changes => true) unless fact('selinux') == 'true' + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) unless fact('selinux') == 'true' # A sleep to give docker time to execute properly sleep 4 shell("#{docker_command} images") do |r| - expect(r.stdout).to match(/#{default_image}/) + expect(r.stdout).to match(%r{#{default_image}}) end end - it 'should successfully download an image based on a tag from the Docker Hub' do - pp=<<-EOS + it 'successfullies download an image based on a tag from the Docker Hub' do + pp = <<-EOS class { 'docker': #{docker_args} } docker::image { '#{default_image}': ensure => present, image_tag => '#{default_image_tag}', require => Class['docker'], } EOS - apply_manifest(pp, :catch_failures => true) - apply_manifest(pp, :catch_changes => true) unless fact('selinux') == 'true' + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) unless fact('selinux') == 'true' # A sleep to give docker time to execute properly sleep 4 shell("#{docker_command} images") do |r| - expect(r.stdout).to match(/#{default_image}\s+#{default_image_tag}/) + expect(r.stdout).to match(%r{#{default_image}\s+#{default_image_tag}}) end end - it 'should successfully download an image based on a digest from the Docker Hub' do - pp=<<-EOS + it 'successfullies download an image based on a digest from the Docker Hub' do + pp = <<-EOS class { 'docker': #{docker_args} } docker::image { '#{default_image}': ensure => present, image_digest => '#{default_digest}', require => Class['docker'], } EOS - apply_manifest(pp, :catch_failures => true) - apply_manifest(pp, :catch_changes => true) unless fact('selinux') == 'true' + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) unless fact('selinux') == 'true' # A sleep to give docker time to execute properly sleep 4 shell("#{docker_command} images --digests") do |r| - expect(r.stdout).to match(/#{default_image}.*#{default_digest}/) + expect(r.stdout).to match(%r{#{default_image}.*#{default_digest}}) end end - it 'should create a new image based on a Dockerfile' do + it 'creates a new image based on a Dockerfile' do + run_cmd = if fact('osfamily') == 'windows' + 'RUN echo test > C:\\Windows\\Temp\\Dockerfile_test.txt' + else + "RUN echo test > #{dockerfile_test}" + end - if fact('osfamily') == 'windows' - run_cmd = 'RUN echo test > C:\\Windows\\Temp\\Dockerfile_test.txt' - else - run_cmd = "RUN echo test > #{dockerfile_test}" - end - - pp=<<-EOS + pp = <<-EOS class { 'docker': #{docker_args} } docker::image { 'alpine_with_file': docker_file => "#{default_dockerfile}", require => Class['docker'], } file { '#{default_dockerfile}': ensure => present, content => "FROM #{default_image}\n#{run_cmd}", before => Docker::Image['alpine_with_file'], } EOS - apply_manifest(pp, :catch_failures => true) - apply_manifest(pp, :catch_changes => true) unless fact('selinux') == 'true' + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) unless fact('selinux') == 'true' # A sleep to give docker time to execute properly sleep 4 if fact('osfamily') == 'windows' shell("#{docker_command} run alpine_with_file cmd /c dir Windows\\\\Temp") do |r| - expect(r.stdout).to match(/_test.txt/) + expect(r.stdout).to match(%r{_test.txt}) end else shell("#{docker_command} run alpine_with_file ls #{dockerfile_test}") do |r| - expect(r.stdout).to match(/#{dockerfile_test}/) + expect(r.stdout).to match(%r{#{dockerfile_test}}) end end end - it 'should create a new image based on a tar', :win_broken => true do - pp=<<-EOS + it 'creates a new image based on a tar', win_broken: true do + pp = <<-EOS class { 'docker': #{docker_args} } docker::image { '#{default_image}': require => Class['docker'], ensure => present, } docker::run { 'container_2_4': image => '#{default_image}', command => '/bin/sh -c "touch /root/test_file_for_tar_test.txt; while true; do echo hello world; sleep 1; done"', require => Docker::Image['alpine'], } EOS - pp2=<<-EOS + pp2 = <<-EOS class { 'docker': #{docker_args} } docker::image { 'alpine_from_commit': docker_tar => "/root/rootfs.tar" } EOS - apply_manifest(pp, :catch_failures => true) - apply_manifest(pp, :catch_changes => true) unless fact('selinux') == 'true' + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) unless fact('selinux') == 'true' # A sleep to give docker time to execute properly sleep 4 # Commit currently running container as an image container_id = shell("#{docker_command} ps | awk 'FNR == 2 {print $1}'") shell("#{docker_command} commit #{container_id.stdout.strip} alpine_from_commit") # Stop all container using systemd shell('ls -D -1 /etc/systemd/system/docker-container* | sed \'s/\/etc\/systemd\/system\///g\' | sed \'s/\.service//g\' | while read container; do service $container stop; done') # Stop all running containers shell("#{docker_command} rm -f $(docker ps -a -q) || true") # Make sure no other containers are running shell("#{docker_command} ps | wc -l") do |r| - expect(r.stdout).to match(/^1$/) + expect(r.stdout).to match(%r{^1$}) end # Export new to a tar file shell("#{docker_command} save alpine_from_commit > /root/rootfs.tar") # Remove all images shell("#{docker_command} rmi $(docker images -q) || true") # Make sure no other images are present shell("#{docker_command} images | wc -l") do |r| - expect(r.stdout).to match(/^1$/) + expect(r.stdout).to match(%r{^1$}) end - apply_manifest(pp2, :catch_failures => true) - apply_manifest(pp2, :catch_changes => true) unless fact('selinux') == 'true' + apply_manifest(pp2, catch_failures: true) + apply_manifest(pp2, catch_changes: true) unless fact('selinux') == 'true' # A sleep to give docker time to execute properly sleep 4 shell("#{docker_command} run alpine_from_commit ls /root") do |r| - expect(r.stdout).to match(/test_file_for_tar_test.txt/) + expect(r.stdout).to match(%r{test_file_for_tar_test.txt}) end end - it 'should successfully delete the image' do - pp1=<<-EOS + it 'successfullies delete the image' do + pp1 = <<-EOS class { 'docker': #{docker_args} } docker::image { '#{default_image}': ensure => present, require => Class['docker'], } EOS - apply_manifest(pp1, :catch_failures => true) - pp2=<<-EOS + apply_manifest(pp1, catch_failures: true) + pp2 = <<-EOS class { 'docker': #{docker_args} } docker::image { '#{default_image}': ensure => absent, } EOS - apply_manifest(pp2, :catch_failures => true) - apply_manifest(pp2, :catch_changes => true) unless fact('selinux') == 'true' + apply_manifest(pp2, catch_failures: true) + apply_manifest(pp2, catch_changes: true) unless fact('selinux') == 'true' # A sleep to give docker time to execute properly sleep 4 shell("#{docker_command} images") do |r| - expect(r.stdout).to_not match(/#{default_image}/) + expect(r.stdout).not_to match(%r{#{default_image}}) end end end - describe "docker::run" do - it 'should start a container with a configurable command' do - pp=<<-EOS + describe 'docker::run' do + it 'starts a container with a configurable command' do + pp = <<-EOS class { 'docker': #{docker_args} } docker::image { '#{default_image}': require => Class['docker'], } docker::run { 'container_3_1': image => '#{default_image}', command => '#{default_docker_exec_lr_command}', require => Docker::Image['#{default_image}'], #{default_docker_run_arg} } EOS - apply_manifest(pp, :catch_failures => true) - apply_manifest(pp, :catch_changes => true) unless fact('selinux') == 'true' + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) unless fact('selinux') == 'true' # A sleep to give docker time to execute properly sleep 4 container_id = shell("#{docker_command} ps | awk 'FNR == 2 {print $1}'") if fact('osfamily') == 'windows' shell("#{docker_command} exec #{container_id.stdout.strip} cmd /c dir Windows\\\\Temp") do |r| - expect(r.stdout).to match(/test_file.txt/) + expect(r.stdout).to match(%r{test_file.txt}) end else shell("#{docker_command} exec #{container_id.stdout.strip} ls /root") do |r| - expect(r.stdout).to match(/test_file.txt/) + expect(r.stdout).to match(%r{test_file.txt}) end end container_name = shell("#{docker_command} ps | awk 'FNR == 2 {print $NF}'") - expect("#{container_name.stdout.strip}").to match(/(container-3-1|container_3_1)/) + expect(container_name.stdout.strip.to_s).to match(%r{(container-3-1|container_3_1)}) end - it 'should start a container with port configuration' do - pp=<<-EOS + it 'starts a container with port configuration' do + pp = <<-EOS class { 'docker': #{docker_args}} docker::image { '#{default_image}': require => Class['docker'], } docker::run { 'container_3_2': image => '#{default_image}', command => '#{default_run_command}', ports => ['4444'], expose => ['5555'], require => Docker::Image['#{default_image}'], #{default_docker_run_arg} } EOS - apply_manifest(pp, :catch_failures => true) - apply_manifest(pp, :catch_changes => true) unless fact('selinux') == 'true' + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) unless fact('selinux') == 'true' # A sleep to give docker time to execute properly sleep 4 shell("#{docker_command} ps") do |r| - expect(r.stdout).to match(/"#{default_run_command}".+5555\/tcp\, 0\.0\.0.0\:\d+\-\>4444\/tcp/) + expect(r.stdout).to match(%r{#{default_run_command}.+5555\/tcp\, 0\.0\.0.0\:\d+\-\>4444\/tcp}) end end - it 'should start a container with the hostname set' do - pp=<<-EOS + it 'starts a container with the hostname set' do + pp = <<-EOS class { 'docker': #{docker_args} } docker::image { '#{default_image}': require => Class['docker'], } docker::run { 'container_3_3': image => '#{default_image}', command => '#{default_run_command}', hostname => 'testdomain.com', require => Docker::Image['#{default_image}'], #{default_docker_run_arg} } EOS - apply_manifest(pp, :catch_failures => true) - apply_manifest(pp, :catch_changes => true) unless fact('selinux') == 'true' + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) unless fact('selinux') == 'true' # A sleep to give docker time to execute properly sleep 4 container_id = shell("#{docker_command} ps | awk 'FNR == 2 {print $1}'") shell("#{docker_command} exec #{container_id.stdout.strip} hostname") do |r| - expect(r.stdout).to match(/testdomain.com/) + expect(r.stdout).to match(%r{testdomain.com}) end end - it 'should start a container while mounting local volumes' do - pp=<<-EOS + it 'starts a container while mounting local volumes' do + pp = <<-EOS class { 'docker': #{docker_args} } docker::image { '#{default_image}': require => Class['docker'], } docker::run { 'container_3_4': image => '#{default_image}', command => '#{default_run_command}', volumes => ["#{docker_mount_path}:#{docker_mount_path}/mnt:rw"], require => Docker::Image['#{default_image}'], #{default_docker_run_arg} } file { '#{docker_mount_path}/test_mount.txt': ensure => present, before => Docker::Run['container_3_4'], } EOS - apply_manifest(pp, :catch_failures => true) - apply_manifest(pp, :catch_changes => true) unless fact('selinux') == 'true' + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) unless fact('selinux') == 'true' # A sleep to give docker time to execute properly sleep 4 container_id = shell("#{docker_command} ps | awk 'FNR == 2 {print $1}'") if fact('osfamily') == 'windows' shell("#{docker_command} exec #{container_id.stdout.strip} cmd /c dir Users\\\\Administrator\\\\AppData\\\\Local\\\\Temp\\\\mnt") do |r| - expect(r.stdout).to match(/test_mount.txt/) + expect(r.stdout).to match(%r{test_mount.txt}) end else shell("#{docker_command} exec #{container_id.stdout.strip} ls /root/mnt") do |r| - expect(r.stdout).to match(/test_mount.txt/) + expect(r.stdout).to match(%r{test_mount.txt}) end end end - #cpuset is not supported on Docker Windows - #STDERR: C:/Program Files/Docker/docker.exe: Error response from daemon: invalid option: Windows does not support CpusetCpus. - it 'should start a container with cpuset paramater set', :win_broken => true do - pp=<<-EOS + # cpuset is not supported on Docker Windows + # STDERR: C:/Program Files/Docker/docker.exe: Error response from daemon: invalid option: Windows does not support CpusetCpus. + it 'starts a container with cpuset paramater set', win_broken: true do + pp = <<-EOS class { 'docker': #{docker_args} } docker::image { '#{default_image}': require => Class['docker'], } docker::run { 'container_3_5_5': image => '#{default_image}', command => '#{default_run_command}', cpuset => ['0'], require => Docker::Image['#{default_image}'], #{default_docker_run_arg} } EOS - apply_manifest(pp, :catch_failures => true) - apply_manifest(pp, :catch_changes => true) unless fact('selinux') == 'true' + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) unless fact('selinux') == 'true' # A sleep to give docker time to execute properly sleep 4 shell('#{docker_command} inspect container_3_5_5') do |r| - expect(r.stdout).to match(/"CpusetCpus"\: "0"/) + expect(r.stdout).to match(%r{"CpusetCpus"\: "0"}) end end - #leagacy container linking was not implemented on Windows. --link is a legacy Docker feature: https://docs.docker.com/network/links/ - it 'should start multiple linked containers', :win_broken => true do - pp=<<-EOS + # leagacy container linking was not implemented on Windows. --link is a legacy Docker feature: https://docs.docker.com/network/links/ + it 'starts multiple linked containers', win_broken: true do + pp = <<-EOS class { 'docker': #{docker_args} } docker::image { '#{default_image}': require => Class['docker'], } docker::run { 'container_3_5_1': image => '#{default_image}', command => '#{default_run_command}', require => Docker::Image['#{default_image}'], #{default_docker_run_arg} } EOS - apply_manifest(pp, :catch_failures => true) - apply_manifest(pp, :catch_changes => true) unless fact('selinux') == 'true' + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) unless fact('selinux') == 'true' # A sleep to give docker time to execute properly sleep 4 - container_1 = shell("#{docker_command} ps | awk 'FNR == 2 {print $NF}'") + container1 = shell("#{docker_command} ps | awk 'FNR == 2 {print $NF}'") - pp2=<<-EOS + pp2 = <<-EOS class { 'docker': #{docker_args} } docker::image { '#{default_image}': require => Class['docker'], } docker::run { 'container_3_5_2': image => '#{default_image}', command => '#{default_run_command}', - depends => ['#{container_1.stdout.strip}'], - links => "#{container_1.stdout.strip}:the_link", + depends => ['#{container1.stdout.strip}'], + links => "#{container1.stdout.strip}:the_link", require => Docker::Image['#{default_image}'], #{default_docker_run_arg} } EOS - apply_manifest(pp2, :catch_failures => true) - apply_manifest(pp2, :catch_changes => true) unless fact('selinux') == 'true' + apply_manifest(pp2, catch_failures: true) + apply_manifest(pp2, catch_changes: true) unless fact('selinux') == 'true' # A sleep to give docker time to execute properly sleep 4 - container_2 = shell("#{docker_command} ps | awk 'FNR == 2 {print $NF}'") + container2 = shell("#{docker_command} ps | awk 'FNR == 2 {print $NF}'") container_id = shell("#{docker_command} ps | awk 'FNR == 2 {print $1}'") shell("#{docker_command} inspect -f \"{{ .HostConfig.Links }}\" #{container_id.stdout.strip}") do |r| - expect(r.stdout).to match("/#{container_1.stdout.strip}:/#{container_2.stdout.strip}/the_link") + expect(r.stdout).to match("/#{container1.stdout.strip}:/#{container2.stdout.strip}/the_link") end end - it 'should stop a running container' do - pp=<<-EOS + it 'stops a running container' do + pp = <<-EOS class { 'docker': #{docker_args} } docker::image { '#{default_image}': require => Class['docker'], } docker::run { 'container_3_6': image => '#{default_image}', command => '#{default_run_command}', require => Docker::Image['#{default_image}'], #{default_docker_run_arg} } EOS - pp2=<<-EOS + pp2 = <<-EOS class { 'docker': #{docker_args} } docker::image { '#{default_image}': require => Class['docker'], } docker::run { 'container_3_6': image => '#{default_image}', running => false, require => Docker::Image['#{default_image}'], #{default_docker_run_arg} } EOS - apply_manifest(pp, :catch_failures => true) - apply_manifest(pp, :catch_changes => true) unless fact('selinux') == 'true' + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) unless fact('selinux') == 'true' # A sleep to give docker time to execute properly sleep 4 shell("#{docker_command} ps | wc -l") do |r| - expect(r.stdout).to match(/^2$/) + expect(r.stdout).to match(%r{^2$}) end - apply_manifest(pp2, :catch_failures => true) - apply_manifest(pp2, :catch_changes => true) unless fact('selinux') == 'true' + apply_manifest(pp2, catch_failures: true) + apply_manifest(pp2, catch_changes: true) unless fact('selinux') == 'true' # A sleep to give docker time to execute properly sleep 4 shell("#{docker_command} ps | wc -l") do |r| - expect(r.stdout).to match(/^1$/) + expect(r.stdout).to match(%r{^1$}) end end - it 'should stop a running container and remove container' do - pp=<<-EOS + it 'stops a running container and remove container' do + pp = <<-EOS class { 'docker': #{docker_args} } docker::image { '#{default_image}': require => Class['docker'], } docker::run { 'container_3_6_1': image => '#{default_image}', command => '#{default_run_command}', require => Docker::Image['#{default_image}'], #{default_docker_run_arg} } EOS - pp2=<<-EOS + pp2 = <<-EOS class { 'docker': #{docker_args} } docker::image { '#{default_image}': require => Class['docker'], } docker::run { 'container_3_6_1': ensure => 'absent', image => '#{default_image}', require => Docker::Image['#{default_image}'], } EOS - apply_manifest(pp, :catch_failures => true) - apply_manifest(pp, :catch_changes => true) unless fact('selinux') == 'true' + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) unless fact('selinux') == 'true' # A sleep to give docker time to execute properly sleep 15 - shell("#{docker_command} inspect container_3_6_1", :acceptable_exit_codes => [0]) + shell("#{docker_command} inspect container_3_6_1", acceptable_exit_codes: [0]) - apply_manifest(pp2, :catch_failures => true) - apply_manifest(pp2, :catch_changes => true) unless fact('selinux') == 'true' + apply_manifest(pp2, catch_failures: true) + apply_manifest(pp2, catch_changes: true) unless fact('selinux') == 'true' # A sleep to give docker time to execute properly sleep 15 - shell("#{docker_command} inspect container_3_6_1", :acceptable_exit_codes => [1]) + shell("#{docker_command} inspect container_3_6_1", acceptable_exit_codes: [1]) end - it 'should allow dependency for ordering of independent run and image' do - pp=<<-EOS + it 'allows dependency for ordering of independent run and image' do + pp = <<-EOS class { 'docker': #{docker_args} } docker::image { '#{default_image}': } docker::run { 'container_3_7_1': image => '#{default_image}', command => '#{default_run_command}', #{default_docker_run_arg} } docker::image { '#{second_image}': require => Docker::Run['container_3_7_1'], } docker::run { 'container_3_7_2': image => '#{second_image}', command => '#{default_run_command}', #{default_docker_run_arg} } EOS - apply_manifest(pp, :catch_failures => true) - apply_manifest(pp, :catch_changes => true) unless fact('selinux') == 'true' - + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) unless fact('selinux') == 'true' end - it 'should restart a unhealthy container' do - pp5=<<-EOS + it 'restarts a unhealthy container' do + pp5 = <<-EOS class { 'docker': #{docker_args} } docker::run { 'container_3_7_3': image => '#{default_image}', command => '#{default_run_command}', health_check_cmd => 'echo', restart_on_unhealthy => true, #{default_docker_run_arg} } EOS - pp_delete=<<-EOS + pp_delete = <<-EOS class { 'docker': #{docker_args} } docker::run { 'container_3_7_3': image => '#{default_image}', ensure => absent, } EOS if fact('osfamily') == 'windows' - apply_manifest(pp5, :catch_failures => true) - elsif fact('os.release.major') =~ (/14.04|8/) - apply_manifest(pp5, :catch_failures => true) do |r| - expect(r.stdout).to match(/container_3_7_3/) + apply_manifest(pp5, catch_failures: true) + elsif fact('os.release.major') =~ %r{14.04|8} + apply_manifest(pp5, catch_failures: true) do |r| + expect(r.stdout).to match(%r{container_3_7_3}) end else - apply_manifest(pp5, :catch_failures => true) do |r| - expect(r.stdout).to match(/docker-container_3_7_3-systemd-reload/) + apply_manifest(pp5, catch_failures: true) do |r| + expect(r.stdout).to match(%r{docker-container_3_7_3-systemd-reload}) end end - apply_manifest(pp_delete, :catch_failures => true) - end + apply_manifest(pp_delete, catch_failures: true) end end + end - describe "docker::exec" do - it 'should run a command inside an already running container' do - pp=<<-EOS + describe 'docker::exec' do + it 'runs a command inside an already running container' do + pp = <<-EOS class { 'docker': #{docker_args} } docker::image { '#{default_image}': require => Class['docker'], } docker::run { 'container_4_1': image => '#{default_image}', command => '#{default_run_command}', require => Docker::Image['#{default_image}'], #{default_docker_run_arg} } EOS - apply_manifest(pp, :catch_failures => true) - apply_manifest(pp, :catch_changes => true) unless fact('selinux') == 'true' + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) unless fact('selinux') == 'true' - # A sleep to give docker time to execute properly - sleep 15 + # A sleep to give docker time to execute properly + sleep 15 - container_1 = shell("#{docker_command} ps | awk 'FNR == 2 {print $NF}'") + container1 = shell("#{docker_command} ps | awk 'FNR == 2 {print $NF}'") - pp2=<<-EOS + pp2 = <<-EOS class { 'docker': #{docker_args} } docker::exec { 'test_command': - container => '#{container_1.stdout.strip}', + container => '#{container1.stdout.strip}', command => '#{default_docker_exec_command}', tty => true, } EOS - pp_delete=<<-EOS + pp_delete = <<-EOS docker::run { 'container_4_1': image => '#{default_image}', ensure => absent, } EOS - apply_manifest(pp2, :catch_failures => true) + apply_manifest(pp2, catch_failures: true) - # A sleep to give docker time to execute properly - sleep 4 + # A sleep to give docker time to execute properly + sleep 4 - container_id = shell("#{docker_command} ps | awk 'FNR == 2 {print $1}'") - if fact('osfamily') == 'windows' - shell("#{docker_command} exec #{container_id.stdout.strip} cmd /c dir Windows\\\\Temp") do |r| - expect(r.stdout).to match(/test_file.txt/) - end - else - shell("#{docker_command} exec #{container_id.stdout.strip} ls /root") do |r| - expect(r.stdout).to match(/test_file.txt/) - end + container_id = shell("#{docker_command} ps | awk 'FNR == 2 {print $1}'") + if fact('osfamily') == 'windows' + shell("#{docker_command} exec #{container_id.stdout.strip} cmd /c dir Windows\\\\Temp") do |r| + expect(r.stdout).to match(%r{test_file.txt}) + end + else + shell("#{docker_command} exec #{container_id.stdout.strip} ls /root") do |r| + expect(r.stdout).to match(%r{test_file.txt}) end - apply_manifest(pp_delete, :catch_failures => true) end + apply_manifest(pp_delete, catch_failures: true) + end - it 'should only run if notified when refreshonly is true' do - container_name = 'container_4_2' - pp=<<-EOS + it 'onlies run if notified when refreshonly is true' do + container_name = 'container_4_2' + pp = <<-EOS class { 'docker': #{docker_args} } docker::image { '#{default_image}': } docker::run { '#{container_name}': image => '#{default_image}', command => '#{default_run_command}', #{default_docker_run_arg} } docker::exec { 'test_command': container => '#{container_name}', command => '#{default_docker_exec_command}', refreshonly => true, } EOS - apply_manifest(pp, :catch_failures => true) - apply_manifest(pp, :catch_changes => true) unless fact('selinux') == 'true' + apply_manifest(pp, catch_failures: true) + apply_manifest(pp, catch_changes: true) unless fact('selinux') == 'true' - # A sleep to give docker time to execute properly - sleep 4 + # A sleep to give docker time to execute properly + sleep 4 - if fact('osfamily') == 'windows' - shell("#{docker_command} exec #{container_name} cmd /c dir Windows\\\\Temp") do |r| - expect(r.stdout).to_not match(/test_file.txt/) - end - else - shell("#{docker_command} exec #{container_name} ls /root") do |r| - expect(r.stdout).to_not match(/test_file.txt/) - end + if fact('osfamily') == 'windows' + shell("#{docker_command} exec #{container_name} cmd /c dir Windows\\\\Temp") do |r| + expect(r.stdout).not_to match(%r{test_file.txt}) end + else + shell("#{docker_command} exec #{container_name} ls /root") do |r| + expect(r.stdout).not_to match(%r{test_file.txt}) + end + end - pp_extra=<<-EOS + pp_extra = <<-EOS file { '#{default_dockerfile}_dummy_file': ensure => 'present', notify => Docker::Exec['test_command'], } EOS - pp_delete=<<-EOS + pp_delete = <<-EOS docker::run { '#{container_name}': image => '#{default_image}', ensure => absent, } EOS - pp2 = pp + pp_extra + pp2 = pp + pp_extra - apply_manifest(pp2, :catch_failures => true) - apply_manifest(pp2, :catch_changes => true) unless fact('selinux') == 'true' + apply_manifest(pp2, catch_failures: true) + apply_manifest(pp2, catch_changes: true) unless fact('selinux') == 'true' - # A sleep to give docker time to execute properly - sleep 4 + # A sleep to give docker time to execute properly + sleep 4 - if fact('osfamily') == 'windows' - shell("#{docker_command} exec #{container_name} cmd /c dir Windows\\\\Temp") do |r| - expect(r.stdout).to match(/test_file.txt/) - end - else - shell("#{docker_command} exec #{container_name} ls /root") do |r| - expect(r.stdout).to match(/test_file.txt/) - end + if fact('osfamily') == 'windows' + shell("#{docker_command} exec #{container_name} cmd /c dir Windows\\\\Temp") do |r| + expect(r.stdout).to match(%r{test_file.txt}) + end + else + shell("#{docker_command} exec #{container_name} ls /root") do |r| + expect(r.stdout).to match(%r{test_file.txt}) end - apply_manifest(pp_delete, :catch_failures => true) end + apply_manifest(pp_delete, catch_failures: true) end end +end diff --git a/spec/acceptance/docker_spec.rb b/spec/acceptance/docker_spec.rb index 3b37792..ae8be3f 100644 --- a/spec/acceptance/docker_spec.rb +++ b/spec/acceptance/docker_spec.rb @@ -1,213 +1,225 @@ require 'spec_helper_acceptance' broken = false registry_port = 5000 if fact('osfamily') == 'windows' win_host = only_host_with_role(hosts, 'default') @windows_ip = win_host.ip docker_arg = "docker_ee => true, extra_parameters => '\"insecure-registries\": [ \"#{@windows_ip}:5000\" ]'" docker_registry_image = 'stefanscherer/registry-windows' docker_network = 'nat' registry_host = @windows_ip config_file = '/cygdrive/c/Users/Administrator/.docker/config.json' - root_dir = "C:/Users/Administrator/AppData/Local/Temp" + root_dir = 'C:/Users/Administrator/AppData/Local/Temp' server_strip = "#{registry_host}_#{registry_port}" bad_server_strip = "#{registry_host}_5001" broken = true else - if fact('osfamily') == 'RedHat' - docker_args = "repo_opt => '--enablerepo=localmirror-extras'" - elsif fact('os.name') == 'Ubuntu' && fact('os.release.full') == '14.04' - docker_args = "version => '18.06.1~ce~3-0~ubuntu'" - else - docker_args = '' - end + docker_args = if fact('osfamily') == 'RedHat' + "repo_opt => '--enablerepo=localmirror-extras'" + elsif fact('os.name') == 'Ubuntu' && fact('os.release.full') == '14.04' + "version => '18.06.1~ce~3-0~ubuntu'" + else + '' + end docker_registry_image = 'registry' docker_network = 'bridge' registry_host = '127.0.0.1' server_strip = "#{registry_host}:#{registry_port}" bad_server_strip = "#{registry_host}:5001" config_file = '/root/.docker/config.json' - root_dir = "/root" + root_dir = '/root' end describe 'docker' do package_name = 'docker-ce' service_name = 'docker' command = 'docker' - context 'When adding system user', :win_broken => broken do - let(:pp) {" - class { 'docker': #{docker_arg} - docker_users => ['user1'] - } - "} - - it 'the docker daemon' do - apply_manifest(pp, :catch_failures=>true) do |r| - expect(r.stdout).to_not match(/docker-systemd-reload-before-service/) - end - end - end - - context 'with default parameters', :win_broken => broken do - let(:pp) {" + context 'When adding system user', win_broken: broken do + let(:pp) do + " + class { 'docker': #{docker_arg} + docker_users => ['user1'] + } + " + end + + it 'the docker daemon' do + apply_manifest(pp, catch_failures: true) do |r| + expect(r.stdout).not_to match(%r{docker-systemd-reload-before-service}) + end + end + end + + context 'with default parameters', win_broken: broken do + let(:pp) do + " class { 'docker': docker_users => [ 'testuser' ], #{docker_args} } docker::image { 'nginx': } docker::run { 'nginx': image => 'nginx', net => 'host', require => Docker::Image['nginx'], } docker::run { 'nginx2': image => 'nginx', restart => 'always', require => Docker::Image['nginx'], } - "} + " + end - it 'should apply with no errors' do - apply_manifest(pp, :catch_failures=>true) + it 'applies with no errors' do + apply_manifest(pp, catch_failures: true) end - it 'should be idempotent' do - apply_manifest(pp, :catch_changes=>true) + it 'is idempotent' do + apply_manifest(pp, catch_changes: true) end describe package(package_name) do it { is_expected.to be_installed } end describe service(service_name) do it { is_expected.to be_enabled } it { is_expected.to be_running } end describe command("#{command} version") do - its(:exit_status) { should eq 0 } + its(:exit_status) { is_expected.to eq 0 } end - describe command("#{command} images"), :sudo => true do - its(:exit_status) { should eq 0 } - its(:stdout) { should match /nginx/ } + describe command("#{command} images"), sudo: true do + its(:exit_status) { is_expected.to eq 0 } + its(:stdout) { is_expected.to match %r{nginx} } end - describe command("#{command} inspect nginx"), :sudo => true do - its(:exit_status) { should eq 0 } + describe command("#{command} inspect nginx"), sudo: true do + its(:exit_status) { is_expected.to eq 0 } end - describe command("#{command} inspect nginx2"), :sudo => true do - its(:exit_status) { should eq 0 } + describe command("#{command} inspect nginx2"), sudo: true do + its(:exit_status) { is_expected.to eq 0 } end - describe command("#{command} ps --no-trunc | grep `cat /var/run/docker-nginx2.cid`"), :sudo => true do - its(:exit_status) { should eq 0 } - its(:stdout) { should match /nginx -g 'daemon off;'/ } + describe command("#{command} ps --no-trunc | grep `cat /var/run/docker-nginx2.cid`"), sudo: true do + its(:exit_status) { is_expected.to eq 0 } + its(:stdout) { is_expected.to match %r{nginx -g 'daemon off;'} } end describe command('netstat -tlndp') do - its(:exit_status) { should eq 0 } - its(:stdout) { should match /0\.0\.0\.0\:80/ } + its(:exit_status) { is_expected.to eq 0 } + its(:stdout) { is_expected.to match %r{0\.0\.0\.0\:80} } end describe command('id testuser | grep docker') do - its(:exit_status) { should eq 0 } - its(:stdout) { should match /docker/ } + its(:exit_status) { is_expected.to eq 0 } + its(:stdout) { is_expected.to match %r{docker} } end end - context "When asked to have the latest image of something", :win_broken => broken do - let(:pp) {" + context 'When asked to have the latest image of something', win_broken: broken do + let(:pp) do + " class { 'docker': docker_users => [ 'testuser' ] } docker::image { 'busybox': ensure => latest } - "} - it 'should apply with no errors' do - apply_manifest(pp, :catch_failures=>true) + " + end + + it 'applies with no errors' do + apply_manifest(pp, catch_failures: true) end end - context "When registry_mirror is set", :win_broken => broken do - let(:pp) {" + context 'When registry_mirror is set', win_broken: broken do + let(:pp) do + " class { 'docker': registry_mirror => 'http://testmirror.io' } - "} - it 'should apply with no errors' do - apply_manifest(pp, :catch_failures=>true) - end + " + end + + it 'applies with no errors' do + apply_manifest(pp, catch_failures: true) + end - it 'should have a registry mirror set' do + it 'has a registry mirror set' do shell('ps -aux | grep docker') do |r| - expect(r.stdout).to match(/--registry-mirror=http:\/\/testmirror.io/) + expect(r.stdout).to match(%r{--registry-mirror=http:\/\/testmirror.io}) end end end context 'registry' do - before(:all) do - @registry_address = "#{registry_host}:#{registry_port}" - @registry_bad_address = "#{registry_host}:5001" - # @registry_email = 'user@example.com' - @manifest = <<-EOS + let(:registry_address) do + "#{registry_host}:#{registry_port}" + end + + let(:registry_bad_address) do + "#{registry_host}:5001" + end + + it 'is able to run registry' do + pp = <<-MANIFEST class { 'docker': #{docker_arg}} docker::run { 'registry': image => '#{docker_registry_image}', pull_on_start => true, restart => 'always', net => '#{docker_network}', ports => '#{registry_port}:#{registry_port}', } - EOS - retry_on_error_matching(60, 5, /connection failure running/) do - apply_manifest(@manifest, :catch_failures=>true) + MANIFEST + retry_on_error_matching(60, 5, %r{connection failure running}) do + apply_manifest(pp, catch_failures: true) end # avoid a race condition with the registry taking time to start # on some operating systems sleep 10 end - it 'should be able to login to the registry', :retry => 3, :retry_wait => 10 do - manifest = <<-EOS - docker::registry { '#{@registry_address}': + it 'is able to login to the registry', retry: 3, retry_wait: 10 do + pp = <<-MANIFEST + docker::registry { '#{registry_address}': username => 'username', password => 'password', } - EOS - apply_manifest(manifest, :catch_failures=>true) - shell("grep #{@registry_address} #{config_file}", :acceptable_exit_codes => [0]) - shell("test -e \"#{root_dir}/registry-auth-puppet_receipt_#{server_strip}_root\"", :acceptable_exit_codes => [0]) + MANIFEST + apply_manifest(pp, catch_failures: true) + shell("grep #{registry_address} #{config_file}", acceptable_exit_codes: [0]) + shell("test -e \"#{root_dir}/registry-auth-puppet_receipt_#{server_strip}_root\"", acceptable_exit_codes: [0]) end - it 'should be able to logout from the registry' do - manifest = <<-EOS - docker::registry { '#{@registry_address}': + it 'is able to logout from the registry' do + pp = <<-MANIFEST + docker::registry { '#{registry_address}': ensure=> absent, } - EOS - apply_manifest(manifest, :catch_failures=>true) - shell("grep #{@registry_address} #{config_file}", :acceptable_exit_codes => [1,2]) - # shell("grep #{@registry_email} #{@config_file}", :acceptable_exit_codes => [1,2]) + MANIFEST + apply_manifest(pp, catch_failures: true) + shell("grep #{registry_address} #{config_file}", acceptable_exit_codes: [1, 2]) end - it 'should not create receipt if registry login fails' do - manifest = <<-EOS - docker::registry { '#{@registry_bad_address}': + it 'does not create receipt if registry login fails' do + pp = <<-MANIFEST + docker::registry { '#{registry_bad_address}': username => 'username', password => 'password', } - EOS - apply_manifest(manifest, :catch_failures=>true) - shell("grep #{@registry_bad_address} #{config_file}", :acceptable_exit_codes => [1,2]) - shell("test -e \"#{root_dir}/registry-auth-puppet_receipt_#{bad_server_strip}_root\"", :acceptable_exit_codes => [1]) + MANIFEST + apply_manifest(pp, catch_failures: true) + shell("grep #{registry_bad_address} #{config_file}", acceptable_exit_codes: [1, 2]) + shell("test -e \"#{root_dir}/registry-auth-puppet_receipt_#{bad_server_strip}_root\"", acceptable_exit_codes: [1]) end - end - end diff --git a/spec/acceptance/network_spec.rb b/spec/acceptance/network_spec.rb index 082e47f..bf74894 100644 --- a/spec/acceptance/network_spec.rb +++ b/spec/acceptance/network_spec.rb @@ -1,51 +1,46 @@ require 'spec_helper_acceptance' broken = false +command = 'docker' +network_name = 'test-network' if fact('osfamily') == 'windows' - puts "Not implemented on Windows" + puts 'Not implemented on Windows' broken = true elsif fact('osfamily') == 'RedHat' docker_args = "repo_opt => '--enablerepo=localmirror-extras'" elsif fact('os.name') == 'Ubuntu' && fact('os.release.full') == '14.04' docker_args = "version => '18.06.1~ce~3-0~ubuntu'" else docker_args = '' end -describe 'docker network', :win_broken => broken do - command = 'docker' - +describe 'docker network', win_broken: broken do before(:all) do - install_code = "class { 'docker': #{docker_args}}" - apply_manifest(install_code, :catch_failures=>true) + install_pp = "class { 'docker': #{docker_args}}" + apply_manifest(install_pp, catch_failures: true) end describe command("#{command} network --help") do - its(:exit_status) { should eq 0 } + its(:exit_status) { is_expected.to eq 0 } end context 'with a local bridge network described in Puppet' do - before(:all) do - @name = 'test-network' - @pp = <<-code - docker_network { '#{@name}': - ensure => present, - } - code - apply_manifest(@pp, :catch_failures=>true) - end - - it 'should be idempotent' do - apply_manifest(@pp, :catch_changes=>true) + after(:all) do + shell("#{command} network rm #{network_name}") end - it 'should have created a network' do - shell("#{command} network inspect #{@name}", :acceptable_exit_codes => [0]) + it 'is idempotent' do + pp = <<-MANIFEST + docker_network { '#{network_name}': + ensure => present, + } + MANIFEST + idempotent_apply(default, pp, {}) end - after(:all) do - shell("#{command} network rm #{@name}") + it 'has created a network' do + shell("#{command} network inspect #{network_name}", acceptable_exit_codes: [0]) end end end diff --git a/spec/acceptance/plugin_spec.rb b/spec/acceptance/plugin_spec.rb index b1b3e0e..ea48a21 100644 --- a/spec/acceptance/plugin_spec.rb +++ b/spec/acceptance/plugin_spec.rb @@ -1,49 +1,44 @@ require 'spec_helper_acceptance' broken = false +command = 'docker' +plugin_name = 'vieux/sshfs' if fact('osfamily') == 'windows' - puts "Not implemented on Windows" + puts 'Not implemented on Windows' broken = true elsif fact('osfamily') == 'RedHat' docker_args = "repo_opt => '--enablerepo=localmirror-extras'" elsif fact('os.name') == 'Ubuntu' && fact('os.release.full') == '14.04' docker_args = "version => '18.06.1~ce~3-0~ubuntu'" else docker_args = '' end -describe 'docker plugin', :win_broken => broken do - command = 'docker' - +describe 'docker plugin', win_broken: broken do before(:all) do install_code = "class { 'docker': #{docker_args}}" - apply_manifest(install_code, :catch_failures => true) + apply_manifest(install_code, catch_failures: true) end describe command("#{command} plugin --help") do - its(:exit_status) { should eq 0 } + its(:exit_status) { is_expected.to eq 0 } end context 'manage a plugin' do - before(:all) do - @name = 'vieux/sshfs' - @pp = <<-code - docker::plugin { '#{@name}':} - code - apply_manifest(@pp, :catch_failures => true) - end - - it 'should be idempotent' do - apply_manifest(@pp, :catch_changes => true) + after(:all) do + shell("#{command} plugin rm -f #{plugin_name}") end - it 'should have installed a plugin' do - shell("#{command} plugin inspect #{@name}", :acceptable_exit_codes => [0]) + it 'is idempotent' do + pp = <<-MANIFEST + docker::plugin { '#{plugin_name}':} + MANIFEST + idempotent_apply(default, pp, {}) end - after(:all) do - shell("#{command} plugin rm -f #{@name}") + it 'has installed a plugin' do + shell("#{command} plugin inspect #{plugin_name}", acceptable_exit_codes: [0]) end end end diff --git a/spec/acceptance/stack_spec.rb b/spec/acceptance/stack_spec.rb index 10ccda1..c44403a 100644 --- a/spec/acceptance/stack_spec.rb +++ b/spec/acceptance/stack_spec.rb @@ -1,158 +1,169 @@ require 'spec_helper_acceptance' if fact('osfamily') == 'windows' docker_args = 'docker_ee => true' tmp_path = 'C:/cygwin64/tmp' - test_container = 'nanoserver-sac2016' wait_for_container_seconds = 120 else - if fact('os.name') == 'Ubuntu' && fact('os.release.full') == '14.04' - docker_args = "version => '18.06.1~ce~3-0~ubuntu'" - else - docker_args = '' - end + docker_args = if fact('os.name') == 'Ubuntu' && fact('os.release.full') == '14.04' + "version => '18.06.1~ce~3-0~ubuntu'" + else + '' + end tmp_path = '/tmp' - test_container = 'alpine' wait_for_container_seconds = 10 end describe 'docker stack' do before(:all) do - retry_on_error_matching(60, 5, /connection failure running/) do - @install_code = <<-code + retry_on_error_matching(60, 5, %r{connection failure running}) do + install_pp = <<-MANIFEST class { 'docker': #{docker_args} } docker::swarm {'cluster_manager': init => true, ensure => 'present', advertise_addr => $facts['networking']['ip'], listen_addr => $facts['networking']['ip'], require => Class['docker'], } - code - apply_manifest(@install_code, :catch_failures=>true) + MANIFEST + apply_manifest(install_pp, catch_failures: true) end end context 'Creating stack' do - let(:install) {" - docker_stack { 'web': - compose_files => ['#{tmp_path}/docker-stack.yml'], - ensure => present, - }" - } - - it 'should deploy stack' do - apply_manifest(install, :catch_failures=>true) + let(:install_pp) do + <<-MANIFEST + docker_stack { 'web': + compose_files => ['#{tmp_path}/docker-stack.yml'], + ensure => present, + } + MANIFEST + end + + it 'deploys stack' do + apply_manifest(install_pp, catch_failures: true) sleep wait_for_container_seconds end - it 'should be idempotent' do - apply_manifest(install, :catch_changes=>true) + it 'is idempotent' do + apply_manifest(install_pp, catch_changes: true) end - it 'should find a stack' do - shell('docker stack ls') do |r| - expect(r.stdout).to match(/web/) - end + it 'finds a stack' do + shell('docker stack ls') do |r| + expect(r.stdout).to match(%r{web}) + end end - it 'should not find a docker container' do - shell("docker ps -a -q -f \"name=web_compose_test\"", :acceptable_exit_codes => [0]) + it 'does not find a docker container' do + shell('docker ps -a -q -f "name=web_compose_test"', acceptable_exit_codes: [0]) end end context 'Destroying stack' do - let(:install) {" + let(:install) do + <<-MANIFEST docker_stack { 'web': compose_files => ['#{tmp_path}/docker-stack.yml'], ensure => present, - }" } - let(:destroy) {" - docker_stack { 'web': - compose_files => ['#{tmp_path}/docker-stack.yml'], - ensure => absent, - }" + MANIFEST + end + + let(:destroy) do + <<-MANIFEST + docker_stack { 'web': + compose_files => ['#{tmp_path}/docker-stack.yml'], + ensure => absent, } - it 'should run successfully' do - apply_manifest(destroy, :catch_failures=>true) - sleep 10 - end - - it 'should be idempotent' do - retry_on_error_matching(10, 3, /Removing network web_default/) do - apply_manifest(destroy, :catch_changes=>true) - end - end - - it 'should not find a docker stack' do - shell('docker stack ls') do |r| - expect(r.stdout).to_not match(/web/) - end - end - end - - context 'creating stack with multi compose files' do - - before(:all) do - @install_code = <<-code - docker_stack { 'web': - compose_files => ['#{tmp_path}/docker-stack.yml', '#{tmp_path}/docker-stack-override.yml'], - ensure => present, - } - code - - apply_manifest(@install_code, :catch_failures=>true) - end - - it "should find container with web_compose_test tag" do - sleep wait_for_container_seconds - shell("docker ps | grep web_compose_test", :acceptable_exit_codes => [0]) - end + MANIFEST + end + + it 'runs successfully' do + apply_manifest(destroy, catch_failures: true) + sleep 10 + end + + it 'is idempotent' do + retry_on_error_matching(10, 3, %r{Removing network web_default}) do + apply_manifest(destroy, catch_changes: true) end + end - context 'Destroying project with multiple compose files' do - before(:all) do - @install_code = <<-code - docker_stack { 'web': - compose_files => ['#{tmp_path}/docker-stack.yml', '#{tmp_path}/docker-stack-override.yml'], - ensure => present, - } - code - - apply_manifest(@install_code, :catch_failures=>true) - - @destroy_code = <<-code - docker_stack { 'web': - compose_files => ['#{tmp_path}/docker-stack.yml', '#{tmp_path}/docker-stack-override.yml'], - ensure => absent, - } - code - - retry_on_error_matching(10, 3, /Removing network web_default/) do - apply_manifest(@destroy_code, :catch_failures=>true) - end - sleep 15 # Wait for containers to stop and be destroyed - end - - it 'should be idempotent' do - retry_on_error_matching(10, 3, /Removing network web_default/) do - apply_manifest(@destroy_code, :catch_changes=>true) - end - end - - it 'should not find a docker stack' do - shell('docker stack ls') do |r| - expect(r.stdout).to_not match(/web/) - end - end - - it 'should not find a docker container' do - shell("docker ps", :acceptable_exit_codes => [0]) do |r| - expect(r.stdout).not_to match(/web_compose_test/) - end - end + it 'does not find a docker stack' do + shell('docker stack ls') do |r| + expect(r.stdout).not_to match(%r{web}) end + end + end + context 'creating stack with multi compose files' do + before(:all) do + install_pp = <<-MANIFEST + docker_stack { 'web': + compose_files => ['#{tmp_path}/docker-stack.yml', '#{tmp_path}/docker-stack-override.yml'], + ensure => present, + } + MANIFEST + + apply_manifest(install_pp, catch_failures: true) + end + + it 'finds container with web_compose_test tag' do + sleep wait_for_container_seconds + shell('docker ps | grep web_compose_test', acceptable_exit_codes: [0]) + end + end + + context 'Destroying project with multiple compose files' do + let(:destroy_pp) do + <<-MANIFEST + docker_stack { 'web': + compose_files => ['#{tmp_path}/docker-stack.yml', '#{tmp_path}/docker-stack-override.yml'], + ensure => absent, + } + MANIFEST + end + + before(:all) do + install_pp = <<-MANIFEST + docker_stack { 'web': + compose_files => ['#{tmp_path}/docker-stack.yml', '#{tmp_path}/docker-stack-override.yml'], + ensure => present, + } + MANIFEST + apply_manifest(install_pp, catch_failures: true) + + destroy_pp = <<-MANIFEST + docker_stack { 'web': + compose_files => ['#{tmp_path}/docker-stack.yml', '#{tmp_path}/docker-stack-override.yml'], + ensure => absent, + } + MANIFEST + retry_on_error_matching(10, 3, %r{Removing network web_default}) do + apply_manifest(destroy_pp, catch_failures: true) + end + sleep 15 # Wait for containers to stop and be destroyed + end + + it 'is idempotent' do + retry_on_error_matching(10, 3, %r{Removing network web_default}) do + apply_manifest(destroy_pp, catch_changes: true) + end + end + + it 'does not find a docker stack' do + shell('docker stack ls') do |r| + expect(r.stdout).not_to match(%r{web}) + end + end + + it 'does not find a docker container' do + shell('docker ps', acceptable_exit_codes: [0]) do |r| + expect(r.stdout).not_to match(%r{web_compose_test}) + end + end + end end diff --git a/spec/acceptance/volume_spec.rb b/spec/acceptance/volume_spec.rb index 55fde5f..98f31e0 100644 --- a/spec/acceptance/volume_spec.rb +++ b/spec/acceptance/volume_spec.rb @@ -1,54 +1,50 @@ require 'spec_helper_acceptance' -broken = false +volume_name = 'test-volume' if fact('osfamily') == 'windows' docker_args = 'docker_ee => true' - command = "\"/cygdrive/c/Program Files/Docker/docker\"" -elsif ('osfamily') == 'RedHat' + command = '"/cygdrive/c/Program Files/Docker/docker"' +elsif 'osfamily' == 'RedHat' docker_args = "repo_opt => '--enablerepo=localmirror-extras'" command = 'docker' elsif fact('os.name') == 'Ubuntu' && fact('os.release.full') == '14.04' docker_args = "version => '18.06.1~ce~3-0~ubuntu'" command = 'docker' else docker_args = '' command = 'docker' end describe 'docker volume' do before(:all) do - retry_on_error_matching(60, 5, /connection failure running/) do - install_code = "class { 'docker': #{docker_args} }" - apply_manifest(install_code, :catch_failures => true) + retry_on_error_matching(60, 5, %r{connection failure running}) do + install_pp = "class { 'docker': #{docker_args} }" + apply_manifest(install_pp, catch_failures: true) end end - it 'should expose volume subcommand' do - shell("#{command} volume --help", :acceptable_exit_codes => [0]) + it 'exposes volume subcommand' do + shell("#{command} volume --help", acceptable_exit_codes: [0]) end context 'with a local volume described in Puppet' do - before(:all) do - @name = 'test-volume' - @pp = <<-code - docker_volume { '#{@name}': + it 'applies idempotently' do + pp = <<-MANIFEST + docker_volume { '#{volume_name}': ensure => present, } - code - apply_manifest(@pp, :catch_failures => true) - end + MANIFEST - it 'should be idempotent' do - apply_manifest(@pp, :catch_changes => true) + idempotent_apply(default, pp, {}) end - it 'should have created a volume' do - shell("#{command} volume inspect #{@name}", :acceptable_exit_codes => [0]) + it 'has created a volume' do + shell("#{command} volume inspect #{volume_name}", acceptable_exit_codes: [0]) end after(:all) do - shell("#{command} volume rm #{@name}") + shell("#{command} volume rm #{volume_name}") end end -end \ No newline at end of file +end diff --git a/spec/acceptance_swarm/swarm_spec.rb b/spec/acceptance_swarm/swarm_spec.rb index ad94f82..7cffe17 100644 --- a/spec/acceptance_swarm/swarm_spec.rb +++ b/spec/acceptance_swarm/swarm_spec.rb @@ -1,143 +1,146 @@ require 'spec_helper_acceptance' if fact('osfamily') == 'windows' - install_dir = '/cygdrive/c/Program Files/Docker' - file_extension = '.exe' docker_args = 'docker_ee => true' - tmp_path = 'C:/cygwin64/tmp' test_docker_image = 'hello-world:nanoserver' test_docker_command = 'cmd.exe /C "ping /t 8.8.8.8"' else - install_dir = '/usr/local/bin' - file_extension = '' docker_args = '' - tmp_path = '/tmp' test_docker_image = 'ubuntu:16.04' test_docker_command = '/bin/sh -c "while true; do echo hello world; sleep 1; done"' end skip_tests = false begin swarm_manager = only_host_with_role(hosts, 'swarm-manager') swarm_worker = only_host_with_role(hosts, 'swarm-worker') manager_ip = swarm_manager.ip rescue ArgumentError skip_tests = true end -describe 'docker swarm', :skip => skip_tests do - before(:all) do - retry_on_error_matching(60, 5, /connection failure running/) do - @install_code = <<-code +describe 'docker swarm', skip: skip_tests do + before(:each) do + retry_on_error_matching(60, 5, %r{connection failure running}) do + install_code = <<-code class { 'docker': #{docker_args} } code - apply_manifest_on(swarm_manager, @install_code, :catch_failures=>true) + apply_manifest_on(swarm_manager, install_code, catch_failures: true) end - retry_on_error_matching(60, 5, /connection failure running/) do - apply_manifest_on(swarm_worker, @install_code, :catch_failures=>true) + retry_on_error_matching(60, 5, %r{connection failure running}) do + apply_manifest_on(swarm_worker, install_code, catch_failures: true) end - end - context 'Creating a swarm master' do - before(:all) do - @setup_manager = <<-code + setup_manager_pp = <<-MANIFEST docker::swarm {'cluster_manager': init => true, advertise_addr => '#{manager_ip}', listen_addr => '#{manager_ip}', - ensure => 'present', + ensure => 'present', } - code + MANIFEST - retry_on_error_matching(60, 5, /connection failure running/) do - apply_manifest_on(swarm_manager, @setup_manager, :catch_failures=>true) - end + retry_on_error_matching(60, 5, %r{connection failure running}) do + apply_manifest_on(swarm_manager, setup_manager_pp, catch_failures: true) + end - if fact('osfamily') == 'windows' - on swarm_manager, 'netsh advfirewall firewall add rule name="Swarm mgmgt" dir=in action=allow protocol=TCP localport=2377', :acceptable_exit_codes => [0] - on swarm_manager, 'netsh advfirewall firewall add rule name="Swarm comm tcp" dir=in action=allow protocol=TCP localport=7946', :acceptable_exit_codes => [0] - on swarm_manager, 'netsh advfirewall firewall add rule name="Swarm comm udp" dir=in action=allow protocol=UDP localport=7946', :acceptable_exit_codes => [0] - on swarm_manager, 'netsh advfirewall firewall add rule name="Swarm network" dir=in action=allow protocol=UDP localport=4789', :acceptable_exit_codes => [0] - end + if fact('osfamily') == 'windows' + on swarm_manager, 'netsh advfirewall firewall add rule name="Swarm mgmgt" dir=in action=allow protocol=TCP localport=2377', acceptable_exit_codes: [0] + on swarm_manager, 'netsh advfirewall firewall add rule name="Swarm comm tcp" dir=in action=allow protocol=TCP localport=7946', acceptable_exit_codes: [0] + on swarm_manager, 'netsh advfirewall firewall add rule name="Swarm comm udp" dir=in action=allow protocol=UDP localport=7946', acceptable_exit_codes: [0] + on swarm_manager, 'netsh advfirewall firewall add rule name="Swarm network" dir=in action=allow protocol=UDP localport=4789', acceptable_exit_codes: [0] end + end - it 'should be idempotent' do - apply_manifest_on(swarm_manager, @setup_manager, :catch_failures=>true) + after(:each) do + remove_worker = <<-code + docker::swarm {'cluster_worker': + ensure => 'absent', + } + code + retry_on_error_matching(60, 5, %r{connection failure running}) do + apply_manifest_on(swarm_worker, remove_worker, catch_failures: true) end + remove_mgr_pp = <<-MANIFEST + docker::swarm {'cluster_manager': + ensure => 'absent', + } + MANIFEST + retry_on_error_matching(60, 5, %r{connection failure running}) do + apply_manifest_on(swarm_manager, remove_mgr_pp, catch_failures: true) + end + end + + context 'Creating a swarm master' do + let(:token) { shell('docker swarm join-token -q worker').stdout.strip } + + it 'is idempotent' do + setup_manager_pp = <<-MANIFEST + docker::swarm {'cluster_manager': + init => true, + advertise_addr => '#{manager_ip}', + listen_addr => '#{manager_ip}', + ensure => 'present', + } + MANIFEST - it 'should display nodes' do - on swarm_manager, 'docker node ls', :acceptable_exit_codes => [0] do |result| - expect(result.stdout).to match(/Leader/) + apply_manifest_on(swarm_manager, setup_manager_pp, catch_failures: true) + end + + it 'displays nodes' do + on swarm_manager, 'docker node ls', acceptable_exit_codes: [0] do |result| + expect(result.stdout).to match(%r{Leader}) end end - it 'should join a node' do - token = shell('docker swarm join-token -q worker').stdout.strip - @setup_slave = <<-code - docker::swarm {'cluster_worker': - join => true, - advertise_addr => '#{swarm_worker.ip}', - listen_addr => '#{swarm_worker.ip}', - manager_ip => '#{manager_ip}', - token => '#{token}', + it 'joins a node' do + setup_slave_pp = <<-MANIFEST + docker::swarm {'cluster_worker': + join => true, + advertise_addr => '#{swarm_worker.ip}', + listen_addr => '#{swarm_worker.ip}', + manager_ip => '#{manager_ip}', + token => '#{token}', } - code - retry_on_error_matching(60, 5, /connection failure running/) do - apply_manifest_on(swarm_worker, @setup_slave, :catch_failures=>true) + MANIFEST + + retry_on_error_matching(60, 5, %r{connection failure running}) do + apply_manifest_on(swarm_worker, setup_slave_pp, catch_failures: true) end - retry_on_error_matching(60, 5, /connection failure running/) do + retry_on_error_matching(60, 5, %r{connection failure running}) do on swarm_worker, 'docker info' do |result| - expect(result.stdout).to match(/Swarm: active/) + expect(result.stdout).to match(%r{Swarm: active}) end end if fact('osfamily') == 'windows' - on swarm_worker, 'netsh advfirewall firewall add rule name="Swarm mgmgt" dir=in action=allow protocol=TCP localport=2377', :acceptable_exit_codes => [0] - on swarm_worker, 'netsh advfirewall firewall add rule name="Swarm comm tcp" dir=in action=allow protocol=TCP localport=7946', :acceptable_exit_codes => [0] - on swarm_worker, 'netsh advfirewall firewall add rule name="Swarm comm udp" dir=in action=allow protocol=UDP localport=7946', :acceptable_exit_codes => [0] - on swarm_worker, 'netsh advfirewall firewall add rule name="Swarm network" dir=in action=allow protocol=UDP localport=4789', :acceptable_exit_codes => [0] + on swarm_worker, 'netsh advfirewall firewall add rule name="Swarm mgmgt" dir=in action=allow protocol=TCP localport=2377', acceptable_exit_codes: [0] + on swarm_worker, 'netsh advfirewall firewall add rule name="Swarm comm tcp" dir=in action=allow protocol=TCP localport=7946', acceptable_exit_codes: [0] + on swarm_worker, 'netsh advfirewall firewall add rule name="Swarm comm udp" dir=in action=allow protocol=UDP localport=7946', acceptable_exit_codes: [0] + on swarm_worker, 'netsh advfirewall firewall add rule name="Swarm network" dir=in action=allow protocol=UDP localport=4789', acceptable_exit_codes: [0] end end - it 'should start a container' do - @start_service = <<-code + it 'starts a container' do + start_service = <<-MANIFEST docker::services {'helloworld': create => true, service_name => 'helloworld', image => '#{test_docker_image}', extra_params => ['--endpoint-mode dnsrr'], command => '#{test_docker_command}', replicas => '2', } - code + MANIFEST - apply_manifest_on(swarm_manager, @start_service, :catch_failures=>true) - - #on swarm_manager, "docker service create --name=helloworld --endpoint-mode dnsrr --network=swarmnet #{test_docker_image} #{test_docker_command}", :acceptable_exit_codes => [0] - on swarm_manager, 'docker service ps helloworld', :acceptable_exit_codes => [0] do |result| - expect(result.stdout).to match(/Running/) - end - end + apply_manifest_on(swarm_manager, start_service, catch_failures: true) - after(:all) do - remove_worker = <<-code - docker::swarm {'cluster_worker': - ensure => 'absent', - } - code - retry_on_error_matching(60, 5, /connection failure running/) do - apply_manifest_on(swarm_worker, remove_worker, :catch_failures=>true) - end - remove_mgr = <<-code - docker::swarm {'cluster_manager': - ensure => 'absent', - } - code - retry_on_error_matching(60, 5, /connection failure running/) do - apply_manifest_on(swarm_manager, remove_mgr, :catch_failures=>true) + # on swarm_manager, "docker service create --name=helloworld --endpoint-mode dnsrr --network=swarmnet #{test_docker_image} #{test_docker_command}", :acceptable_exit_codes => [0] + on swarm_manager, 'docker service ps helloworld', acceptable_exit_codes: [0] do |result| + expect(result.stdout).to match(%r{Running}) end end end -end \ No newline at end of file +end diff --git a/spec/classes/compose_spec.rb b/spec/classes/compose_spec.rb index 100359a..de01abb 100644 --- a/spec/classes/compose_spec.rb +++ b/spec/classes/compose_spec.rb @@ -1,88 +1,118 @@ require 'spec_helper' -describe 'docker::compose', :type => :class do +describe 'docker::compose', type: :class do let(:facts) do { - :kernel => 'Linux', - :osfamily => 'Debian', - :operatingsystem => 'Ubuntu', - :lsbdistid => 'Ubuntu', - :lsbdistcodename => 'maverick', - :kernelrelease => '3.8.0-29-generic', - :operatingsystemrelease => '10.04', - :operatingsystemmajrelease => '10', + kernel: 'Linux', + osfamily: 'Debian', + operatingsystem: 'Ubuntu', + lsbdistid: 'Ubuntu', + lsbdistcodename: 'maverick', + kernelrelease: '3.8.0-29-generic', + operatingsystemrelease: '10.04', + operatingsystemmajrelease: '10', } end it { is_expected.to compile } context 'with defaults for all parameters' do - it { should compile.with_all_deps } - it { should contain_exec('Install Docker Compose 1.9.0').with( - 'path' => '/usr/bin/', - 'cwd' => '/tmp', - 'command' => 'curl -s -S -L https://github.com/docker/compose/releases/download/1.9.0/docker-compose-Linux-x86_64 -o /usr/local/bin/docker-compose-1.9.0', - 'creates' => '/usr/local/bin/docker-compose-1.9.0', - 'require' => 'Package[curl]' - )} - it { should contain_file('/usr/local/bin/docker-compose-1.9.0').with( - 'owner' => 'root', - 'mode' => '0755', - 'require' => 'Exec[Install Docker Compose 1.9.0]' - )} - it { should contain_file('/usr/local/bin/docker-compose').with( - 'ensure' => 'link', - 'target' => '/usr/local/bin/docker-compose-1.9.0', - 'require' => 'File[/usr/local/bin/docker-compose-1.9.0]' - )} + it { is_expected.to compile.with_all_deps } + it { + is_expected.to contain_exec('Install Docker Compose 1.9.0').with( + 'path' => '/usr/bin/', + 'cwd' => '/tmp', + 'command' => 'curl -s -S -L https://github.com/docker/compose/releases/download/1.9.0/docker-compose-Linux-x86_64 -o /usr/local/bin/docker-compose-1.9.0', + 'creates' => '/usr/local/bin/docker-compose-1.9.0', + 'require' => 'Package[curl]', + ) + } + it { + is_expected.to contain_file('/usr/local/bin/docker-compose-1.9.0').with( + 'owner' => 'root', + 'mode' => '0755', + 'require' => 'Exec[Install Docker Compose 1.9.0]', + ) + } + it { + is_expected.to contain_file('/usr/local/bin/docker-compose').with( + 'ensure' => 'link', + 'target' => '/usr/local/bin/docker-compose-1.9.0', + 'require' => 'File[/usr/local/bin/docker-compose-1.9.0]', + ) + } end context 'with ensure => absent' do - let (:params) { { :ensure => 'absent' } } - it { should contain_file('/usr/local/bin/docker-compose-1.9.0').with_ensure('absent') } - it { should contain_file('/usr/local/bin/docker-compose').with_ensure('absent') } + let(:params) { { ensure: 'absent' } } + + it { is_expected.to contain_file('/usr/local/bin/docker-compose-1.9.0').with_ensure('absent') } + it { is_expected.to contain_file('/usr/local/bin/docker-compose').with_ensure('absent') } end context 'when no proxy is provided' do - let(:params) { {:version => '1.7.0'} } - it { is_expected.to contain_exec('Install Docker Compose 1.7.0').with_command( - 'curl -s -S -L https://github.com/docker/compose/releases/download/1.7.0/docker-compose-Linux-x86_64 -o /usr/local/bin/docker-compose-1.7.0') + let(:params) { { version: '1.7.0' } } + + it { + is_expected.to contain_exec('Install Docker Compose 1.7.0').with_command( + 'curl -s -S -L https://github.com/docker/compose/releases/download/1.7.0/docker-compose-Linux-x86_64 -o /usr/local/bin/docker-compose-1.7.0', + ) } end context 'when proxy is provided' do - let(:params) { {:proxy => 'http://proxy.example.org:3128/', - :version => '1.7.0'} } + let(:params) do + { proxy: 'http://proxy.example.org:3128/', + version: '1.7.0' } + end + it { is_expected.to compile } - it { is_expected.to contain_exec('Install Docker Compose 1.7.0').with_command( - 'curl -s -S -L --proxy http://proxy.example.org:3128/ https://github.com/docker/compose/releases/download/1.7.0/docker-compose-Linux-x86_64 -o /usr/local/bin/docker-compose-1.7.0') + it { + is_expected.to contain_exec('Install Docker Compose 1.7.0').with_command( + 'curl -s -S -L --proxy http://proxy.example.org:3128/ https://github.com/docker/compose/releases/download/1.7.0/docker-compose-Linux-x86_64 -o /usr/local/bin/docker-compose-1.7.0', + ) } end context 'when proxy is not a http proxy' do - let(:params) { {:proxy => 'this is not a URL'} } + let(:params) { { proxy: 'this is not a URL' } } + it do expect { is_expected.to compile - }.to raise_error(/does not match/) + }.to raise_error(%r{does not match}) end end context 'when proxy contains username and password' do - let(:params) { {:proxy => 'http://user:password@proxy.example.org:3128/', - :version => '1.7.0'} } + let(:params) do + { + proxy: 'http://user:password@proxy.example.org:3128/', + version: '1.7.0', + } + end + it { is_expected.to compile } - it { is_expected.to contain_exec('Install Docker Compose 1.7.0').with_command( - 'curl -s -S -L --proxy http://user:password@proxy.example.org:3128/ https://github.com/docker/compose/releases/download/1.7.0/docker-compose-Linux-x86_64 -o /usr/local/bin/docker-compose-1.7.0') + it { + is_expected.to contain_exec('Install Docker Compose 1.7.0').with_command( + 'curl -s -S -L --proxy http://user:password@proxy.example.org:3128/'\ + ' https://github.com/docker/compose/releases/download/1.7.0/docker-compose-Linux-x86_64'\ + ' -o /usr/local/bin/docker-compose-1.7.0', + ) } end context 'when proxy IP is provided' do - let(:params) { {:proxy => 'http://10.10.10.10:3128/', - :version => '1.7.0'} } + let(:params) do + { proxy: 'http://10.10.10.10:3128/', + version: '1.7.0' } + end + it { is_expected.to compile } - it { is_expected.to contain_exec('Install Docker Compose 1.7.0').with_command( - 'curl -s -S -L --proxy http://10.10.10.10:3128/ https://github.com/docker/compose/releases/download/1.7.0/docker-compose-Linux-x86_64 -o /usr/local/bin/docker-compose-1.7.0') + it { + is_expected.to contain_exec('Install Docker Compose 1.7.0').with_command( + 'curl -s -S -L --proxy http://10.10.10.10:3128/ https://github.com/docker/compose/releases/download/1.7.0/docker-compose-Linux-x86_64 -o /usr/local/bin/docker-compose-1.7.0', + ) } end end diff --git a/spec/classes/compose_windows_spec.rb b/spec/classes/compose_windows_spec.rb index 9c681b9..209c765 100644 --- a/spec/classes/compose_windows_spec.rb +++ b/spec/classes/compose_windows_spec.rb @@ -1,73 +1,87 @@ require 'spec_helper' -describe 'docker::compose', :type => :class do +describe 'docker::compose', type: :class do let(:facts) do { - :architecture => 'amd64', - :osfamily => 'windows', - :operatingsystem => 'windows', - :kernel => 'windows', - :kernelrelease => '10.0.14393', - :operatingsystemrelease => '2016', - :operatingsystemmajrelease => '2016', - :docker_program_data_path => 'C:/ProgramData', - :docker_program_files_path => 'C:/Program Files', - :docker_systemroot => 'C:/Windows', - :docker_user_temp_path => 'C:/Users/Administrator/AppData/Local/Temp', - :os => { :family => 'windows', :name => 'windows', :release => { :major => '2016', :full => '2016' } } + architecture: 'amd64', + osfamily: 'windows', + operatingsystem: 'windows', + kernel: 'windows', + kernelrelease: '10.0.14393', + operatingsystemrelease: '2016', + operatingsystemmajrelease: '2016', + docker_program_data_path: 'C:/ProgramData', + docker_program_files_path: 'C:/Program Files', + docker_systemroot: 'C:/Windows', + docker_user_temp_path: 'C:/Users/Administrator/AppData/Local/Temp', + os: { family: 'windows', name: 'windows', release: { major: '2016', full: '2016' } }, } end it { is_expected.to compile } context 'with defaults for all parameters' do - it { should compile.with_all_deps } + it { is_expected.to compile.with_all_deps } - it { should contain_file('C:/Program Files/Docker/docker-compose.exe').with( - 'ensure' => 'link', - 'target' => 'C:/Program Files/Docker/docker-compose-1.21.2.exe', - 'require' => 'Exec[Install Docker Compose 1.21.2]' - )} + it { + is_expected.to contain_file('C:/Program Files/Docker/docker-compose.exe').with( + 'ensure' => 'link', + 'target' => 'C:/Program Files/Docker/docker-compose-1.21.2.exe', + 'require' => 'Exec[Install Docker Compose 1.21.2]', + ) + } end context 'with ensure => absent' do - let (:params) { { :ensure => 'absent' } } - it { should contain_file('C:/Program Files/Docker/docker-compose-1.21.2.exe').with_ensure('absent') } - it { should contain_file('C:/Program Files/Docker/docker-compose.exe').with_ensure('absent') } + let(:params) { { ensure: 'absent' } } + + it { is_expected.to contain_file('C:/Program Files/Docker/docker-compose-1.21.2.exe').with_ensure('absent') } + it { is_expected.to contain_file('C:/Program Files/Docker/docker-compose.exe').with_ensure('absent') } end context 'when no proxy is provided' do - let(:params) { {:version => '1.7.0'} } + let(:params) { { version: '1.7.0' } } + it { is_expected.to contain_exec('Install Docker Compose 1.7.0') } end context 'when proxy is provided' do - let(:params) { {:proxy => 'http://proxy.example.org:3128/', - :version => '1.7.0'} } + let(:params) do + { proxy: 'http://proxy.example.org:3128/', + version: '1.7.0' } + end + it { is_expected.to compile } it { is_expected.to contain_exec('Install Docker Compose 1.7.0') } end context 'when proxy is not a http proxy' do - let(:params) { {:proxy => 'this is not a URL'} } + let(:params) { { proxy: 'this is not a URL' } } + it do expect { is_expected.to compile - }.to raise_error(/does not match/) + }.to raise_error(%r{does not match}) end end context 'when proxy contains username and password' do - let(:params) { {:proxy => 'http://user:password@proxy.example.org:3128/', - :version => '1.7.0'} } + let(:params) do + { proxy: 'http://user:password@proxy.example.org:3128/', + version: '1.7.0' } + end + it { is_expected.to compile } it { is_expected.to contain_exec('Install Docker Compose 1.7.0') } end context 'when proxy IP is provided' do - let(:params) { {:proxy => 'http://10.10.10.10:3128/', - :version => '1.7.0'} } + let(:params) do + { proxy: 'http://10.10.10.10:3128/', + version: '1.7.0' } + end + it { is_expected.to compile } it { is_expected.to contain_exec('Install Docker Compose 1.7.0') } end end diff --git a/spec/classes/docker_spec.rb b/spec/classes/docker_spec.rb index ed72797..09558d1 100755 --- a/spec/classes/docker_spec.rb +++ b/spec/classes/docker_spec.rb @@ -1,930 +1,1075 @@ require 'spec_helper' -describe 'docker', :type => :class do - +describe 'docker', type: :class do ['Debian', 'Ubuntu', 'RedHat'].each do |osfamily| context "on #{osfamily}" do - if osfamily == 'Debian' - let(:facts) { { - :architecture => 'amd64', - :osfamily => 'Debian', - :operatingsystem => 'Debian', - :lsbdistid => 'Debian', - :lsbdistcodename => 'stretch', - :kernelrelease => '4.9.0-3-amd64', - :operatingsystemrelease => '9.0', - :operatingsystemmajrelease => '9', - :os => { :distro => { :codename => 'wheezy' }, :family => 'Debian', :name => 'Debian', :release => { :major => '7', :full => '7.0' } } - } } + let(:facts) do + { + architecture: 'amd64', + osfamily: 'Debian', + operatingsystem: 'Debian', + lsbdistid: 'Debian', + lsbdistcodename: 'stretch', + kernelrelease: '4.9.0-3-amd64', + operatingsystemrelease: '9.0', + operatingsystemmajrelease: '9', + os: { distro: { codename: 'wheezy' }, family: 'Debian', name: 'Debian', release: { major: '7', full: '7.0' } }, + } + end + service_config_file = '/etc/default/docker' storage_config_file = '/etc/default/docker-storage' context 'It should include default prerequired_packages' do - it { should contain_package('cgroupfs-mount').with_ensure('present') } + it { is_expected.to contain_package('cgroupfs-mount').with_ensure('present') } end end if osfamily == 'Ubuntu' - let(:facts) { { - :architecture => 'amd64', - :osfamily => 'Debian', - :operatingsystem => 'Ubuntu', - :lsbdistid => 'Ubuntu', - :lsbdistcodename => 'xenial', - :kernelrelease => '4.4.0-21-generic', - :operatingsystemrelease => '16.04', - :operatingsystemmajrelease => '16.04', - :os => { :distro => { :codename => 'wheezy' }, :family => 'Debian', :name => 'Debian', :release => { :major => '7', :full => '7.0' } } - } } + let(:facts) do + { + architecture: 'amd64', + osfamily: 'Debian', + operatingsystem: 'Ubuntu', + lsbdistid: 'Ubuntu', + lsbdistcodename: 'xenial', + kernelrelease: '4.4.0-21-generic', + operatingsystemrelease: '16.04', + operatingsystemmajrelease: '16.04', + os: { distro: { codename: 'wheezy' }, family: 'Debian', name: 'Debian', release: { major: '7', full: '7.0' } }, + } + end + service_config_file = '/etc/default/docker' storage_config_file = '/etc/default/docker-storage' - it { should contain_service('docker').with_hasrestart('true') } + it { is_expected.to contain_service('docker').with_hasrestart('true') } context 'It should include default prerequired_packages' do - it { should contain_package('cgroup-lite').with_ensure('present') } - it { should contain_package('apparmor').with_ensure('present') } + it { is_expected.to contain_package('cgroup-lite').with_ensure('present') } + it { is_expected.to contain_package('apparmor').with_ensure('present') } end end - if osfamily == 'Ubuntu' - - it { should contain_class('apt') } - it { should contain_package('docker').with_name('docker-ce').with_ensure('present') } - it { should contain_apt__source('docker').with_location('https://download.docker.com/linux/ubuntu') } - it { should contain_apt__pin('docker') - .with_ensure('present') - .with_origin('download.docker.com') - .with_priority(500) + if ['Debian', 'Ubuntu'].include?(osfamily) + it { is_expected.to contain_class('apt') } + it { is_expected.to contain_package('docker').with_name('docker-ce').with_ensure('present') } + it { + is_expected.to contain_apt__pin('docker') + .with_ensure('present') + .with_origin('download.docker.com') + .with_priority(500) } - it { should contain_package('docker').with_install_options(nil) } + it { is_expected.to contain_package('docker').with_install_options(nil) } + it { is_expected.to contain_file('/etc/default/docker').without_content(%r{icc=}) } + end - it { should contain_file('/etc/default/docker').without_content(/icc=/) } + if osfamily == 'Ubuntu' + it { is_expected.to contain_apt__source('docker').with_location('https://download.docker.com/linux/ubuntu') } end if osfamily == 'Debian' - - it { should contain_class('apt') } - it { should contain_package('docker').with_name('docker-ce').with_ensure('present') } - it { should contain_apt__source('docker').with_location('https://download.docker.com/linux/debian') } - it { should contain_apt__pin('docker') - .with_ensure('present') - .with_origin('download.docker.com') - .with_priority(500) - } - it { should contain_package('docker').with_install_options(nil) } - - it { should contain_file('/etc/default/docker').without_content(/icc=/) } + it { is_expected.to contain_apt__source('docker').with_location('https://download.docker.com/linux/debian') } end - if osfamily == 'Debian' or osfamily == 'Ubuntu' + if ['Debian', 'Ubuntu'].include?(osfamily) context 'with a custom version' do - let(:params) { {'version' => '1.7.0' } } - it { should contain_package('docker').with_ensure('1.7.0').with_name('docker-engine') } + let(:params) { { 'version' => '1.7.0' } } + + it { is_expected.to contain_package('docker').with_ensure('1.7.0').with_name('docker-engine') } end context 'with no upstream package source' do - let(:params) { {'use_upstream_package_source' => false } } - it { should_not contain_apt__source('docker') } - it { should_not contain_apt__pin('docker') } - it { should contain_package('docker').with_name('docker-ce') } + let(:params) { { 'use_upstream_package_source' => false } } + + it { is_expected.not_to contain_apt__source('docker') } + it { is_expected.not_to contain_apt__pin('docker') } + it { is_expected.to contain_package('docker').with_name('docker-ce') } end context 'with no upstream package source' do - let(:params) { {'use_upstream_package_source' => false } } - it { should_not contain_apt__source('docker') } - it { should_not contain_apt__pin('docker') } - it { should contain_package('docker') } + let(:params) { { 'use_upstream_package_source' => false } } + + it { is_expected.not_to contain_apt__source('docker') } + it { is_expected.not_to contain_apt__pin('docker') } + it { is_expected.to contain_package('docker') } end context 'with no package pinning' do - let(:params) { {'pin_upstream_package_source' => false } } - it { should contain_apt__pin('docker').with_ensure('absent') } + let(:params) { { 'pin_upstream_package_source' => false } } + + it { is_expected.to contain_apt__pin('docker').with_ensure('absent') } end context 'with different package pinning priority' do - let(:params) { { - 'pin_upstream_package_source' => true, - 'apt_source_pin_level' => 900, - } } - it { should contain_apt__pin('docker').with_priority(900) } + let(:params) do + { + 'pin_upstream_package_source' => true, + 'apt_source_pin_level' => 900, + } + end + + it { is_expected.to contain_apt__pin('docker').with_priority(900) } end context 'when given a specific tmp_dir' do - let(:params) {{ 'tmp_dir' => '/bigtmp' }} - it { should contain_file('/etc/default/docker').with_content(/TMPDIR="\/bigtmp"/) } + let(:params) { { 'tmp_dir' => '/bigtmp' } } + + it { is_expected.to contain_file('/etc/default/docker').with_content(%r{TMPDIR="\/bigtmp"}) } end context 'with ip_forwaring param set to false' do - let(:params) {{ 'ip_forward' => false }} - it { should contain_file('/etc/default/docker').with_content(/ip-forward=false/) } + let(:params) { { 'ip_forward' => false } } + + it { is_expected.to contain_file('/etc/default/docker').with_content(%r{ip-forward=false}) } end context 'with ip_masq param set to false' do - let(:params) {{ 'ip_masq' => false }} - it { should contain_file('/etc/default/docker').with_content(/ip-masq=false/) } + let(:params) { { 'ip_masq' => false } } + + it { is_expected.to contain_file('/etc/default/docker').with_content(%r{ip-masq=false}) } end context 'with iptables param set to false' do - let(:params) {{ 'iptables' => false }} - it { should contain_file('/etc/default/docker').with_content(/iptables=false/) } + let(:params) { { 'iptables' => false } } + + it { is_expected.to contain_file('/etc/default/docker').with_content(%r{iptables=false}) } end context 'with icc param set to false' do - let(:params) {{ 'icc' => false }} - it { should contain_file('/etc/default/docker').with_content(/icc=false/) } + let(:params) { { 'icc' => false } } + + it { is_expected.to contain_file('/etc/default/docker').with_content(%r{icc=false}) } end context 'with tcp_bind array param' do - let(:params) {{ 'tcp_bind' => ['tcp://127.0.0.1:2375', 'tcp://10.0.0.1:2375'] }} + let(:params) { { 'tcp_bind' => ['tcp://127.0.0.1:2375', 'tcp://10.0.0.1:2375'] } } + it do - should contain_file('/etc/default/docker').with_content( - /tcp:\/\/127.0.0.1:2375 -H tcp:\/\/10.0.0.1:2375/ + is_expected.to contain_file('/etc/default/docker').with_content( + %r{tcp:\/\/127.0.0.1:2375 -H tcp:\/\/10.0.0.1:2375}, ) end end context 'with tcp_bind string param' do - let(:params) {{ 'tcp_bind' => 'tcp://127.0.0.1:2375' }} + let(:params) { { 'tcp_bind' => 'tcp://127.0.0.1:2375' } } + it do - should contain_file('/etc/default/docker').with_content( - /tcp:\/\/127.0.0.1:2375/ + is_expected.to contain_file('/etc/default/docker').with_content( + %r{tcp:\/\/127.0.0.1:2375}, ) end end context 'with tls param' do - let(:params) {{ + let(:params) do + { 'tcp_bind' => 'tcp://127.0.0.1:2375', 'tls_enable' => true, - }} + } + end + it do - should contain_file('/etc/default/docker').with_content( - /tcp:\/\/127.0.0.1:2375/ + is_expected.to contain_file('/etc/default/docker').with_content( + %r{tcp:\/\/127.0.0.1:2375}, ) - should contain_file('/etc/default/docker').with_content( - /--tls --tlsverify --tlscacert=\/etc\/docker\/tls\/ca.pem --tlscert=\/etc\/docker\/tls\/cert.pem --tlskey=\/etc\/docker\/tls\/key.pem/ + is_expected.to contain_file('/etc/default/docker').with_content( + %r{--tls --tlsverify --tlscacert=\/etc\/docker\/tls\/ca.pem --tlscert=\/etc\/docker\/tls\/cert.pem --tlskey=\/etc\/docker\/tls\/key.pem}, ) end end context 'with tls param and without tlsverify' do - let(:params) {{ + let(:params) do + { 'tcp_bind' => 'tcp://127.0.0.1:2375', 'tls_enable' => true, 'tls_verify' => false, - }} + } + end + it do - should contain_file('/etc/default/docker').with_content( - /tcp:\/\/127.0.0.1:2375/ + is_expected.to contain_file('/etc/default/docker').with_content( + %r{tcp:\/\/127.0.0.1:2375}, ) - should contain_file('/etc/default/docker').with_content( - /--tls --tlscacert=\/etc\/docker\/tls\/ca.pem --tlscert=\/etc\/docker\/tls\/cert.pem --tlskey=\/etc\/docker\/tls\/key.pem/ + is_expected.to contain_file('/etc/default/docker').with_content( + %r{--tls --tlscacert=\/etc\/docker\/tls\/ca.pem --tlscert=\/etc\/docker\/tls\/cert.pem --tlskey=\/etc\/docker\/tls\/key.pem}, ) end end context 'with fixed_cidr and bridge params' do - let(:params) {{ 'fixed_cidr' => '10.0.0.0/24' }} - let(:params) {{ - 'fixed_cidr' => '10.0.0.0/24', - 'bridge' => 'br0', - }} - it { should contain_file('/etc/default/docker').with_content(/fixed-cidr 10.0.0.0\/24/) } + let(:params) do + { + 'fixed_cidr' => '10.0.0.0/24', + 'bridge' => 'br0', + } + end + + it { is_expected.to contain_file('/etc/default/docker').with_content(%r{fixed-cidr 10.0.0.0\/24}) } end context 'with ipv6 params' do - let(:params) {{ - 'ipv6' => true, - 'ipv6_cidr' => '2001:db8:1::/64', - 'default_gateway_ipv6' => 'fe80::2d4:12ff:fef6:67a2/16' - }} - it { should contain_file('/etc/default/docker').with_content(/--ipv6/) } - it { should contain_file('/etc/default/docker').with_content(/--fixed-cidr-v6 2001:db8:1::\/64/) } - it { should contain_file('/etc/default/docker').with_content(/--default-gateway-v6 fe80::2d4:12ff:fef6:67a2\/16/) } + let(:params) do + { + 'ipv6' => true, + 'ipv6_cidr' => '2001:db8:1::/64', + 'default_gateway_ipv6' => 'fe80::2d4:12ff:fef6:67a2/16', + } + end + + it { is_expected.to contain_file('/etc/default/docker').with_content(%r{--ipv6}) } + it { is_expected.to contain_file('/etc/default/docker').with_content(%r{--fixed-cidr-v6 2001:db8:1::\/64}) } + it { is_expected.to contain_file('/etc/default/docker').with_content(%r{--default-gateway-v6 fe80::2d4:12ff:fef6:67a2\/16}) } end context 'with default_gateway and bridge params' do - let(:params) {{ - 'default_gateway' => '10.0.0.1', - 'bridge' => 'br0', - }} - it { should contain_file('/etc/default/docker').with_content(/default-gateway 10.0.0.1/) } + let(:params) do + { + 'default_gateway' => '10.0.0.1', + 'bridge' => 'br0', + } + end + + it { is_expected.to contain_file('/etc/default/docker').with_content(%r{default-gateway 10.0.0.1}) } end context 'with bridge param' do - let(:params) {{ 'bridge' => 'br0' }} - it { should contain_file('/etc/default/docker').with_content(/bridge br0/) } + let(:params) { { 'bridge' => 'br0' } } + + it { is_expected.to contain_file('/etc/default/docker').with_content(%r{bridge br0}) } end context 'with custom service_name' do - let(:params) {{ 'service_name' => 'docker.io' }} - it { should contain_file('/etc/default/docker.io') } - end + let(:params) { { 'service_name' => 'docker.io' } } + + it { is_expected.to contain_file('/etc/default/docker.io') } + end end if osfamily == 'RedHat' - let(:facts) { { - :architecture => 'x86_64', - :osfamily => osfamily, - :operatingsystem => 'RedHat', - :operatingsystemrelease => '7.2', - :operatingsystemmajrelease => '7', - :kernelversion => '3.10.0', - } } + let(:facts) do + { + architecture: 'x86_64', + osfamily: osfamily, + operatingsystem: 'RedHat', + operatingsystemrelease: '7.2', + operatingsystemmajrelease: '7', + kernelversion: '3.10.0', + } + end + service_config_file = '/etc/sysconfig/docker' storage_config_file = '/etc/sysconfig/docker-storage' - it { should contain_file('/etc/sysconfig/docker').without_content(/icc=/) } + it { is_expected.to contain_file('/etc/sysconfig/docker').without_content(%r{icc=}) } context 'with proxy param' do - let(:params) { {'proxy' => 'http://127.0.0.1:3128' } } - it { should contain_file(service_config_file).with_content(/http_proxy='http:\/\/127.0.0.1:3128'/) } - it { should contain_file(service_config_file).with_content(/https_proxy='http:\/\/127.0.0.1:3128'/) } + let(:params) { { 'proxy' => 'http://127.0.0.1:3128' } } + + it { is_expected.to contain_file(service_config_file).with_content(%r{http_proxy='http:\/\/127.0.0.1:3128'}) } + it { is_expected.to contain_file(service_config_file).with_content(%r{https_proxy='http:\/\/127.0.0.1:3128'}) } end context 'with no_proxy param' do - let(:params) { {'no_proxy' => '.github.com' } } - it { should contain_file(service_config_file).with_content(/no_proxy='.github.com'/) } + let(:params) { { 'no_proxy' => '.github.com' } } + + it { is_expected.to contain_file(service_config_file).with_content(%r{no_proxy='.github.com'}) } end context 'with registry_mirror param set to mirror value' do - let(:params) {{ 'registry_mirror' => 'https://mirror.gcr.io' }} - it { should contain_file('/etc/sysconfig/docker').with_content(/registry-mirror/) } + let(:params) { { 'registry_mirror' => 'https://mirror.gcr.io' } } + + it { is_expected.to contain_file('/etc/sysconfig/docker').with_content(%r{registry-mirror}) } end context 'when given a specific tmp_dir' do - let(:params) {{ 'tmp_dir' => '/bigtmp' }} - it { should contain_file('/etc/sysconfig/docker').with_content(/TMPDIR="\/bigtmp"/) } + let(:params) { { 'tmp_dir' => '/bigtmp' } } + + it { is_expected.to contain_file('/etc/sysconfig/docker').with_content(%r{TMPDIR="\/bigtmp"}) } end context 'with ip_forwaring param set to false' do - let(:params) {{ 'ip_forward' => false }} - it { should contain_file('/etc/sysconfig/docker').with_content(/ip-forward=false/) } + let(:params) { { 'ip_forward' => false } } + + it { is_expected.to contain_file('/etc/sysconfig/docker').with_content(%r{ip-forward=false}) } end context 'with ip_masq param set to false' do - let(:params) {{ 'ip_masq' => false }} - it { should contain_file('/etc/sysconfig/docker').with_content(/ip-masq=false/) } + let(:params) { { 'ip_masq' => false } } + + it { is_expected.to contain_file('/etc/sysconfig/docker').with_content(%r{ip-masq=false}) } end context 'with iptables param set to false' do - let(:params) {{ 'iptables' => false }} - it { should contain_file('/etc/sysconfig/docker').with_content(/iptables=false/) } + let(:params) { { 'iptables' => false } } + + it { is_expected.to contain_file('/etc/sysconfig/docker').with_content(%r{iptables=false}) } end context 'with icc param set to false' do - let(:params) {{ 'icc' => false }} - it { should contain_file('/etc/sysconfig/docker').with_content(/icc=false/) } + let(:params) { { 'icc' => false } } + + it { is_expected.to contain_file('/etc/sysconfig/docker').with_content(%r{icc=false}) } end context 'with tcp_bind array param' do - let(:params) {{ 'tcp_bind' => ['tcp://127.0.0.1:2375', 'tcp://10.0.0.1:2375'] }} + let(:params) { { 'tcp_bind' => ['tcp://127.0.0.1:2375', 'tcp://10.0.0.1:2375'] } } + it do - should contain_file('/etc/sysconfig/docker').with_content( - /tcp:\/\/127.0.0.1:2375 -H tcp:\/\/10.0.0.1:2375/) + is_expected.to contain_file('/etc/sysconfig/docker').with_content( + %r{tcp:\/\/127.0.0.1:2375 -H tcp:\/\/10.0.0.1:2375}, + ) end end context 'with tcp_bind string param' do - let(:params) {{ 'tcp_bind' => 'tcp://127.0.0.1:2375' }} + let(:params) { { 'tcp_bind' => 'tcp://127.0.0.1:2375' } } + it do - should contain_file('/etc/sysconfig/docker').with_content( - /tcp:\/\/127.0.0.1:2375/) + is_expected.to contain_file('/etc/sysconfig/docker').with_content( + %r{tcp:\/\/127.0.0.1:2375}, + ) end end context 'with tls param' do - let(:params) {{ + let(:params) do + { 'tcp_bind' => 'tcp://127.0.0.1:2375', 'tls_enable' => true, - }} + } + end + it do - should contain_file('/etc/sysconfig/docker').with_content( - /tcp:\/\/127.0.0.1:2375/ + is_expected.to contain_file('/etc/sysconfig/docker').with_content( + %r{tcp:\/\/127.0.0.1:2375}, ) - should contain_file('/etc/sysconfig/docker').with_content( - /--tls --tlsverify --tlscacert=\/etc\/docker\/tls\/ca.pem --tlscert=\/etc\/docker\/tls\/cert.pem --tlskey=\/etc\/docker\/tls\/key.pem/ + is_expected.to contain_file('/etc/sysconfig/docker').with_content( + %r{--tls --tlsverify --tlscacert=\/etc\/docker\/tls\/ca.pem --tlscert=\/etc\/docker\/tls\/cert.pem --tlskey=\/etc\/docker\/tls\/key.pem}, ) end end context 'with tls param and without tlsverify' do - let(:params) {{ + let(:params) do + { 'tcp_bind' => 'tcp://127.0.0.1:2375', 'tls_enable' => true, 'tls_verify' => false, - }} + } + end + it do - should contain_file('/etc/sysconfig/docker').with_content( - /tcp:\/\/127.0.0.1:2375/ + is_expected.to contain_file('/etc/sysconfig/docker').with_content( + %r{tcp:\/\/127.0.0.1:2375}, ) - should contain_file('/etc/sysconfig/docker').with_content( - /--tls --tlscacert=\/etc\/docker\/tls\/ca.pem --tlscert=\/etc\/docker\/tls\/cert.pem --tlskey=\/etc\/docker\/tls\/key.pem/ + is_expected.to contain_file('/etc/sysconfig/docker').with_content( + %r{--tls --tlscacert=\/etc\/docker\/tls\/ca.pem --tlscert=\/etc\/docker\/tls\/cert.pem --tlskey=\/etc\/docker\/tls\/key.pem}, ) end end context 'with fixed_cidr and bridge params' do - let(:params) {{ 'fixed_cidr' => '10.0.0.0/24' }} - let(:params) {{ - 'fixed_cidr' => '10.0.0.0/24', - 'bridge' => 'br0', - }} - it { should contain_file('/etc/sysconfig/docker').with_content(/fixed-cidr 10.0.0.0\/24/) } + let(:params) do + { + 'fixed_cidr' => '10.0.0.0/24', + 'bridge' => 'br0', + } + end + + it { is_expected.to contain_file('/etc/sysconfig/docker').with_content(%r{fixed-cidr 10.0.0.0\/24}) } end context 'with default_gateway and bridge params' do - let(:params) {{ - 'default_gateway' => '10.0.0.1', - 'bridge' => 'br0', - }} - it { should contain_file('/etc/sysconfig/docker').with_content(/default-gateway 10.0.0.1/) } + let(:params) do + { + 'default_gateway' => '10.0.0.1', + 'bridge' => 'br0', + } + end + + it { is_expected.to contain_file('/etc/sysconfig/docker').with_content(%r{default-gateway 10.0.0.1}) } end context 'with bridge param' do - let(:params) {{ 'bridge' => 'br0' }} - it { should contain_file('/etc/sysconfig/docker').with_content(/bridge br0/) } + let(:params) { { 'bridge' => 'br0' } } + + it { is_expected.to contain_file('/etc/sysconfig/docker').with_content(%r{bridge br0}) } end context 'when given specific storage options' do - let(:params) {{ - 'storage_driver' => 'devicemapper', - 'dm_basesize' => '3G' - }} - it { should contain_file('/etc/sysconfig/docker-storage').with_content(/^(DOCKER_STORAGE_OPTIONS=" --storage-driver devicemapper --storage-opt dm.basesize=3G)/) } + let(:params) do + { + 'storage_driver' => 'devicemapper', + 'dm_basesize' => '3G', + } + end + + it { is_expected.to contain_file('/etc/sysconfig/docker-storage').with_content(%r{^(DOCKER_STORAGE_OPTIONS=" --storage-driver devicemapper --storage-opt dm.basesize=3G)}) } end context 'It should include default prerequired_packages' do - it { should contain_package('device-mapper').with_ensure('present') } + it { is_expected.to contain_package('device-mapper').with_ensure('present') } end context 'It should install from rpm package' do - let(:params) { { - 'manage_package' => true, - 'use_upstream_package_source' => false, - 'docker_engine_package_name' => 'docker-engine', - 'package_source' => 'https://get.docker.com/rpm/1.7.0/centos-7/RPMS/x86_64/docker-engine-1.7.0-1.el7.x86_64.rpm' - } } + let(:params) do + { + 'manage_package' => true, + 'use_upstream_package_source' => false, + 'docker_engine_package_name' => 'docker-engine', + 'package_source' => 'https://get.docker.com/rpm/1.7.0/centos-7/RPMS/x86_64/docker-engine-1.7.0-1.el7.x86_64.rpm', + } + end + it do - should contain_package('docker').with( + is_expected.to contain_package('docker').with( 'ensure' => 'present', 'source' => 'https://get.docker.com/rpm/1.7.0/centos-7/RPMS/x86_64/docker-engine-1.7.0-1.el7.x86_64.rpm', - 'name' => 'docker-engine' + 'name' => 'docker-engine', ) end end context 'It should install from rpm package with docker::repo_opt set' do - let(:params) { { - 'manage_package' => true, - 'use_upstream_package_source' => false, - 'docker_engine_package_name' => 'docker-engine', - 'package_source' => 'https://get.docker.com/rpm/1.7.0/centos-7/RPMS/x86_64/docker-engine-1.7.0-1.el7.x86_64.rpm', - 'repo_opt' => '--enablerepo=rhel7-extras' - } } + let(:params) do + { + 'manage_package' => true, + 'use_upstream_package_source' => false, + 'docker_engine_package_name' => 'docker-engine', + 'package_source' => 'https://get.docker.com/rpm/1.7.0/centos-7/RPMS/x86_64/docker-engine-1.7.0-1.el7.x86_64.rpm', + 'repo_opt' => '--enablerepo=rhel7-extras', + } + end + it do - should contain_package('docker').with( + is_expected.to contain_package('docker').with( 'ensure' => 'present', 'source' => 'https://get.docker.com/rpm/1.7.0/centos-7/RPMS/x86_64/docker-engine-1.7.0-1.el7.x86_64.rpm', 'name' => 'docker-engine', - 'install_options' => '--enablerepo=rhel7-extras' + 'install_options' => '--enablerepo=rhel7-extras', ) end end context 'It uses default docker::repo_opt' do - let(:params) { { - 'manage_package' => true, - 'use_upstream_package_source' => false, - 'docker_engine_package_name' => 'docker-engine', - 'package_source' => 'https://get.docker.com/rpm/1.7.0/centos-7/RPMS/x86_64/docker-engine-1.7.0-1.el7.x86_64.rpm' - } } + let(:params) do + { + 'manage_package' => true, + 'use_upstream_package_source' => false, + 'docker_engine_package_name' => 'docker-engine', + 'package_source' => 'https://get.docker.com/rpm/1.7.0/centos-7/RPMS/x86_64/docker-engine-1.7.0-1.el7.x86_64.rpm', + } + end + it do - should contain_package('docker').with( + is_expected.to contain_package('docker').with( 'ensure' => 'present', 'source' => 'https://get.docker.com/rpm/1.7.0/centos-7/RPMS/x86_64/docker-engine-1.7.0-1.el7.x86_64.rpm', 'name' => 'docker-engine', - 'install_options' => '--enablerepo=rhel-7-server-extras-rpms' + 'install_options' => '--enablerepo=rhel-7-server-extras-rpms', ) - end end context 'It allows overwriting docker::repo_opt with empty string' do - let(:params) { { - 'manage_package' => true, - 'use_upstream_package_source' => false, - 'docker_engine_package_name' => 'docker-engine', - 'package_source' => 'https://get.docker.com/rpm/1.7.0/centos-7/RPMS/x86_64/docker-engine-1.7.0-1.el7.x86_64.rpm', - 'repo_opt' => '' - } } + let(:params) do + { + 'manage_package' => true, + 'use_upstream_package_source' => false, + 'docker_engine_package_name' => 'docker-engine', + 'package_source' => 'https://get.docker.com/rpm/1.7.0/centos-7/RPMS/x86_64/docker-engine-1.7.0-1.el7.x86_64.rpm', + 'repo_opt' => '', + } + end + it do - should contain_package('docker').with( + is_expected.to contain_package('docker').with( 'ensure' => 'present', 'source' => 'https://get.docker.com/rpm/1.7.0/centos-7/RPMS/x86_64/docker-engine-1.7.0-1.el7.x86_64.rpm', 'name' => 'docker-engine', - 'install_options' => nil + 'install_options' => nil, ) end end end - it { should compile.with_all_deps } - it { should contain_class('docker::repos').that_comes_before('Class[docker::install]') } - it { should contain_class('docker::install').that_comes_before('Class[docker::config]') } - it { should contain_class('docker::config').that_comes_before('Class[docker::service]') } + it { is_expected.to compile.with_all_deps } + it { is_expected.to contain_class('docker::repos').that_comes_before('Class[docker::install]') } + it { is_expected.to contain_class('docker::install').that_comes_before('Class[docker::config]') } + it { is_expected.to contain_class('docker::config').that_comes_before('Class[docker::service]') } - it { should contain_file(service_config_file).without_content(/icc=/) } + it { is_expected.to contain_file(service_config_file).without_content(%r{icc=}) } # storage_config_file = '/etc/default/docker-storage' context 'with a specific docker command' do - let(:params) {{ 'docker_ce_start_command' => 'docker.io' }} - it { should contain_file('/etc/systemd/system/docker.service.d/service-overrides.conf').with_content(/docker.io/) } + let(:params) { { 'docker_ce_start_command' => 'docker.io' } } + + it { is_expected.to contain_file('/etc/systemd/system/docker.service.d/service-overrides.conf').with_content(%r{docker.io}) } end context 'with an extra After entry' do - let(:params) {{ 'service_after_override' => 'containerd.service' }} - it { should contain_file('/etc/systemd/system/docker.service.d/service-overrides.conf').with_content(/containerd.service/) } + let(:params) { { 'service_after_override' => 'containerd.service' } } + + it { is_expected.to contain_file('/etc/systemd/system/docker.service.d/service-overrides.conf').with_content(%r{containerd.service}) } end context 'with a specific socket group and override' do - let(:params) { { - 'socket_group' => 'root', - 'socket_override' => true, - } } - it { should contain_file('/etc/systemd/system/docker.socket.d/socket-overrides.conf').with_content(/root/) } + let(:params) do + { + 'socket_group' => 'root', + 'socket_override' => true, + } + end + + it { is_expected.to contain_file('/etc/systemd/system/docker.socket.d/socket-overrides.conf').with_content(%r{root}) } end context 'with a custom package name' do - let(:params) { {'docker_ce_package_name' => 'docker-custom-pkg-name' } } - it { should contain_package('docker').with_name('docker-custom-pkg-name').with_ensure('present') } + let(:params) { { 'docker_ce_package_name' => 'docker-custom-pkg-name' } } + + it { is_expected.to contain_package('docker').with_name('docker-custom-pkg-name').with_ensure('present') } end context 'with a custom package name and version' do - let(:params) { { - 'version' => '17.06.2~ce-0~debian', - 'docker_ce_package_name' => 'docker-custom-pkg-name', - } } - it { should contain_package('docker').with_name('docker-custom-pkg-name').with_ensure('17.06.2~ce-0~debian') } + let(:params) do + { + 'version' => '17.06.2~ce-0~debian', + 'docker_ce_package_name' => 'docker-custom-pkg-name', + } + end + + it { is_expected.to contain_package('docker').with_name('docker-custom-pkg-name').with_ensure('17.06.2~ce-0~debian') } end context 'when not managing the package' do let(:params) { { 'manage_package' => false } } + skip 'the APT module at v2.1 does not support STRICT_VARIABLES' do - it { should_not contain_package('docker') } + it { is_expected.not_to contain_package('docker') } end end context 'It should accept custom prerequired_packages' do - let(:params) { {'prerequired_packages' => [ 'test_package' ], - 'manage_package' => false, } } + let(:params) do + { 'prerequired_packages' => ['test_package'], + 'manage_package' => false } + end + skip 'the APT module at v2.1 does not support STRICT_VARIABLES' do - it { should contain_package('test_package').with_ensure('present') } + it { is_expected.to contain_package('test_package').with_ensure('present') } end end context 'with proxy param' do - let(:params) { {'proxy' => 'http://127.0.0.1:3128' } } - it { should contain_file(service_config_file).with_content(/http_proxy='http:\/\/127.0.0.1:3128'/) } - it { should contain_file(service_config_file).with_content(/https_proxy='http:\/\/127.0.0.1:3128'/) } + let(:params) { { 'proxy' => 'http://127.0.0.1:3128' } } + + it { is_expected.to contain_file(service_config_file).with_content(%r{http_proxy='http:\/\/127.0.0.1:3128'}) } + it { is_expected.to contain_file(service_config_file).with_content(%r{https_proxy='http:\/\/127.0.0.1:3128'}) } end context 'with no_proxy param' do - let(:params) { {'no_proxy' => '.github.com' } } - it { should contain_file(service_config_file).with_content(/no_proxy='.github.com'/) } + let(:params) { { 'no_proxy' => '.github.com' } } + + it { is_expected.to contain_file(service_config_file).with_content(%r{no_proxy='.github.com'}) } end context 'with execdriver param lxc' do - let(:params) { { 'execdriver' => 'lxc' }} - it { should contain_file(service_config_file).with_content(/-e lxc/) } + let(:params) { { 'execdriver' => 'lxc' } } + + it { is_expected.to contain_file(service_config_file).with_content(%r{-e lxc}) } end context 'with execdriver param native' do - let(:params) { { 'execdriver' => 'native' }} - it { should contain_file(service_config_file).with_content(/-e native/) } + let(:params) { { 'execdriver' => 'native' } } + + it { is_expected.to contain_file(service_config_file).with_content(%r{-e native}) } end ['aufs', 'devicemapper', 'btrfs', 'overlay', 'overlay2', 'vfs', 'zfs'].each do |driver| context "with #{driver} storage driver" do - let(:params) { { 'storage_driver' => driver }} - it { should contain_file(storage_config_file).with_content(/ --storage-driver #{driver}/) } + let(:params) { { 'storage_driver' => driver } } + + it { is_expected.to contain_file(storage_config_file).with_content(%r{ --storage-driver #{driver}}) } end end context 'with thinpool device param' do - let(:params) { + let(:params) do { 'storage_driver' => 'devicemapper', - 'dm_thinpooldev' => '/dev/mapper/vg_test-docker--pool' - } - } - it { should contain_file(storage_config_file).with_content(/--storage-opt dm\.thinpooldev=\/dev\/mapper\/vg_test-docker--pool/) } + 'dm_thinpooldev' => '/dev/mapper/vg_test-docker--pool' } + end + + it { is_expected.to contain_file(storage_config_file).with_content(%r{--storage-opt dm\.thinpooldev=\/dev\/mapper\/vg_test-docker--pool}) } end context 'with use deferred removal param' do - let(:params) { + let(:params) do { 'storage_driver' => 'devicemapper', - 'dm_use_deferred_removal' => true - } - } - it { should contain_file(storage_config_file).with_content(/--storage-opt dm\.use_deferred_removal=true/) } + 'dm_use_deferred_removal' => true } + end + + it { is_expected.to contain_file(storage_config_file).with_content(%r{--storage-opt dm\.use_deferred_removal=true}) } end context 'with use deferred deletion param' do - let(:params) { + let(:params) do { 'storage_driver' => 'devicemapper', - 'dm_use_deferred_deletion' => true - } - } - it { should contain_file(storage_config_file).with_content(/--storage-opt dm\.use_deferred_deletion=true/) } + 'dm_use_deferred_deletion' => true } + end + + it { is_expected.to contain_file(storage_config_file).with_content(%r{--storage-opt dm\.use_deferred_deletion=true}) } end context 'with block discard param' do - let(:params) { + let(:params) do { 'storage_driver' => 'devicemapper', - 'dm_blkdiscard' => true - } - } - it { should contain_file(storage_config_file).with_content(/--storage-opt dm\.blkdiscard=true/) } + 'dm_blkdiscard' => true } + end + + it { is_expected.to contain_file(storage_config_file).with_content(%r{--storage-opt dm\.blkdiscard=true}) } end context 'with override udev sync check param' do - let(:params) { + let(:params) do { 'storage_driver' => 'devicemapper', - 'dm_override_udev_sync_check' => true - } - } - it { should contain_file(storage_config_file).with_content(/--storage-opt dm\.override_udev_sync_check=true/) } + 'dm_override_udev_sync_check' => true } + end + + it { is_expected.to contain_file(storage_config_file).with_content(%r{--storage-opt dm\.override_udev_sync_check=true}) } end context 'without execdriver param' do - it { should_not contain_file(service_config_file).with_content(/-e lxc/) } - it { should_not contain_file(service_config_file).with_content(/-e native/) } + it { is_expected.not_to contain_file(service_config_file).with_content(%r{-e lxc}) } + it { is_expected.not_to contain_file(service_config_file).with_content(%r{-e native}) } end context 'with multi dns param' do - let(:params) { {'dns' => ['8.8.8.8', '8.8.4.4']} } - it { should contain_file(service_config_file).with_content(/--dns 8.8.8.8/).with_content(/--dns 8.8.4.4/) } + let(:params) { { 'dns' => ['8.8.8.8', '8.8.4.4'] } } + + it { is_expected.to contain_file(service_config_file).with_content(%r{--dns 8.8.8.8}).with_content(%r{--dns 8.8.4.4}) } end context 'with dns param' do - let(:params) { {'dns' => '8.8.8.8'} } - it { should contain_file(service_config_file).with_content(/--dns 8.8.8.8/) } + let(:params) { { 'dns' => '8.8.8.8' } } + + it { is_expected.to contain_file(service_config_file).with_content(%r{--dns 8.8.8.8}) } end context 'with multi dns_search param' do - let(:params) { {'dns_search' => ['my.domain.local', 'other-domain.de']} } - it { should contain_file(service_config_file).with_content(/--dns-search my.domain.local/).with_content(/--dns-search other-domain.de/) } + let(:params) { { 'dns_search' => ['my.domain.local', 'other-domain.de'] } } + + it { is_expected.to contain_file(service_config_file).with_content(%r{--dns-search my.domain.local}).with_content(%r{--dns-search other-domain.de}) } end context 'with dns_search param' do - let(:params) { {'dns_search' => 'my.domain.local'} } - it { should contain_file(service_config_file).with_content(/--dns-search my.domain.local/) } + let(:params) { { 'dns_search' => 'my.domain.local' } } + + it { is_expected.to contain_file(service_config_file).with_content(%r{--dns-search my.domain.local}) } end context 'with multi extra parameters' do - let(:params) { {'extra_parameters' => ['--this this', '--that that'] } } - it { should contain_file(service_config_file).with_content(/--this this/) } - it { should contain_file(service_config_file).with_content(/--that that/) } + let(:params) { { 'extra_parameters' => ['--this this', '--that that'] } } + + it { is_expected.to contain_file(service_config_file).with_content(%r{--this this}) } + it { is_expected.to contain_file(service_config_file).with_content(%r{--that that}) } end context 'with a string extra parameters' do - let(:params) { {'extra_parameters' => '--this this' } } - it { should contain_file(service_config_file).with_content(/--this this/) } + let(:params) { { 'extra_parameters' => '--this this' } } + + it { is_expected.to contain_file(service_config_file).with_content(%r{--this this}) } end context 'with multi shell values' do - let(:params) { {'shell_values' => ['--this this', '--that that'] } } - it { should contain_file(service_config_file).with_content(/--this this/) } - it { should contain_file(service_config_file).with_content(/--that that/) } + let(:params) { { 'shell_values' => ['--this this', '--that that'] } } + + it { is_expected.to contain_file(service_config_file).with_content(%r{--this this}) } + it { is_expected.to contain_file(service_config_file).with_content(%r{--that that}) } end context 'with a string shell values' do - let(:params) { {'shell_values' => '--this this' } } - it { should contain_file(service_config_file).with_content(/--this this/) } + let(:params) { { 'shell_values' => '--this this' } } + + it { is_expected.to contain_file(service_config_file).with_content(%r{--this this}) } end context 'with socket group set' do - let(:params) { { 'socket_group' => 'notdocker' }} - it { should contain_file(service_config_file).with_content(/-G notdocker/) } + let(:params) { { 'socket_group' => 'notdocker' } } + + it { is_expected.to contain_file(service_config_file).with_content(%r{-G notdocker}) } end context 'with labels set' do - let(:params) { { 'labels' => ['storage=ssd','stage=production'] }} - it { should contain_file(service_config_file).with_content(/--label storage=ssd/) } - it { should contain_file(service_config_file).with_content(/--label stage=production/) } + let(:params) { { 'labels' => ['storage=ssd', 'stage=production'] } } + + it { is_expected.to contain_file(service_config_file).with_content(%r{--label storage=ssd}) } + it { is_expected.to contain_file(service_config_file).with_content(%r{--label stage=production}) } end context 'with service_state set to stopped' do - let(:params) { {'service_state' => 'stopped'} } - it { should contain_service('docker').with_ensure('stopped') } + let(:params) { { 'service_state' => 'stopped' } } + + it { is_expected.to contain_service('docker').with_ensure('stopped') } end context 'with a custom service name' do - let(:params) { {'service_name' => 'docker.io'} } - it { should contain_service('docker').with_name('docker.io') } + let(:params) { { 'service_name' => 'docker.io' } } + + it { is_expected.to contain_service('docker').with_name('docker.io') } end context 'with service_enable set to false' do - let(:params) { {'service_enable' => false} } - it { should contain_service('docker').with_enable('false') } + let(:params) { { 'service_enable' => false } } + + it { is_expected.to contain_service('docker').with_enable('false') } end context 'with service_enable set to true' do - let(:params) { {'service_enable' => true} } - it { should contain_service('docker').with_enable('true') } + let(:params) { { 'service_enable' => true } } + + it { is_expected.to contain_service('docker').with_enable('true') } end context 'with service_manage set to false' do - let(:params) { {'manage_service' => false} } - it { should_not contain_service('docker') } + let(:params) { { 'manage_service' => false } } + + it { is_expected.not_to contain_service('docker') } end context 'with specific log_level' do let(:params) { { 'log_level' => 'debug' } } - it { should contain_file(service_config_file).with_content(/-l debug/) } + + it { is_expected.to contain_file(service_config_file).with_content(%r{-l debug}) } end context 'with an invalid log_level' do - let(:params) { { 'log_level' => 'verbose'} } + let(:params) { { 'log_level' => 'verbose' } } + it do expect { - should contain_package('docker') - }.to raise_error(Puppet::Error, /log_level must be one of debug, info, warn, error or fatal/) + is_expected.to contain_package('docker') + }.to raise_error(Puppet::Error, %r{log_level must be one of debug, info, warn, error or fatal}) end end context 'with specific log_driver' do let(:params) { { 'log_driver' => 'json-file' } } - it { should contain_file(service_config_file).with_content(/--log-driver json-file/) } + + it { is_expected.to contain_file(service_config_file).with_content(%r{--log-driver json-file}) } end context 'with an invalid log_driver' do - let(:params) { { 'log_driver' => 'etwlogs'} } + let(:params) { { 'log_driver' => 'etwlogs' } } + it do expect { - should contain_package('docker') - }.to raise_error(Puppet::Error, /log_driver must be one of none, json-file, syslog, journald, gelf, fluentd, splunk or awslogs/) + is_expected.to contain_package('docker') + }.to raise_error(Puppet::Error, %r{log_driver must be one of none, json-file, syslog, journald, gelf, fluentd, splunk or awslogs}) end end context 'with specific log_driver and log_opt' do - let(:params) { + let(:params) do { 'log_driver' => 'json-file', - 'log_opt' => [ 'max-size=1m','max-file=3' ] - } - } - it { should contain_file(service_config_file).with_content(/--log-driver json-file/) } - it { should contain_file(service_config_file).with_content(/--log-opt max-size=1m/) } - it { should contain_file(service_config_file).with_content(/--log-opt max-file=3/) } + 'log_opt' => ['max-size=1m', 'max-file=3'] } + end + + it { is_expected.to contain_file(service_config_file).with_content(%r{--log-driver json-file}) } + it { is_expected.to contain_file(service_config_file).with_content(%r{--log-opt max-size=1m}) } + it { is_expected.to contain_file(service_config_file).with_content(%r{--log-opt max-file=3}) } end context 'without log_driver no log_opt' do - let(:params) { { 'log_opt' => [ 'max-size=1m' ] } } - it { should_not contain_file(service_config_file).with_content(/--log-opt max-size=1m/) } + let(:params) { { 'log_opt' => ['max-size=1m'] } } + + it { is_expected.not_to contain_file(service_config_file).with_content(%r{--log-opt max-size=1m}) } end context 'with storage_driver set to devicemapper and dm_* options set' do - let(:params) { {'storage_driver' => 'devicemapper', - 'dm_datadev' => '/dev/sda', - 'dm_metadatadev' => '/dev/sdb', } } - it { should contain_file(storage_config_file).with_content(/dm.datadev=\/dev\/sda/) } + let(:params) do + { 'storage_driver' => 'devicemapper', + 'dm_datadev' => '/dev/sda', + 'dm_metadatadev' => '/dev/sdb' } + end + + it { is_expected.to contain_file(storage_config_file).with_content(%r{dm.datadev=\/dev\/sda}) } end context 'with storage_driver unset and dm_ options set' do - let(:params) { {'dm_datadev' => '/dev/sda', - 'dm_metadatadev' => '/dev/sdb', } } - it { should raise_error(Puppet::Error, /Values for dm_ variables will be ignored unless storage_driver is set to devicemapper./) } + let(:params) do + { 'dm_datadev' => '/dev/sda', + 'dm_metadatadev' => '/dev/sdb' } + end + + it { is_expected.to raise_error(Puppet::Error, %r{Values for dm_ variables will be ignored unless storage_driver is set to devicemapper.}) } end context 'with storage_driver and dm_basesize set' do - let(:params) { {'storage_driver' => 'devicemapper', - 'dm_basesize' => '20G', }} - it { should contain_file(storage_config_file).with_content(/dm.basesize=20G/) } + let(:params) do + { 'storage_driver' => 'devicemapper', + 'dm_basesize' => '20G' } + end + + it { is_expected.to contain_file(storage_config_file).with_content(%r{dm.basesize=20G}) } end context 'with storage_driver unset and dm_basesize set' do - let(:params) { {'dm_basesize' => '20G' }} - it { should raise_error(Puppet::Error, /Values for dm_ variables will be ignored unless storage_driver is set to devicemapper./) } + let(:params) { { 'dm_basesize' => '20G' } } + + it { is_expected.to raise_error(Puppet::Error, %r{Values for dm_ variables will be ignored unless storage_driver is set to devicemapper.}) } end context 'with specific selinux_enabled parameter' do let(:params) { { 'selinux_enabled' => true } } - it { should contain_file(service_config_file).with_content(/--selinux-enabled=true/) } + + it { is_expected.to contain_file(service_config_file).with_content(%r{--selinux-enabled=true}) } end context 'with an invalid selinux_enabled parameter' do - let(:params) { { 'selinux_enabled' => 'yes'} } + let(:params) { { 'selinux_enabled' => 'yes' } } + it do expect { - should contain_package('docker') - }.to raise_error(Puppet::Error, /got String/) + is_expected.to contain_package('docker') + }.to raise_error(Puppet::Error, %r{got String}) end end context 'with custom root dir && Docker version < 17.06' do - let(:params) { { - 'root_dir' => '/mnt/docker', - 'version' => '17.03', - } } - it { should contain_file(service_config_file).with_content(/-g \/mnt\/docker/) } + let(:params) do + { + 'root_dir' => '/mnt/docker', + 'version' => '17.03', + } + end + + it { is_expected.to contain_file(service_config_file).with_content(%r{-g \/mnt\/docker}) } end context 'with custom root dir && Docker version > 17.05' do - let(:params) { { - 'root_dir' => '/mnt/docker', - 'version' => '18.03', - } } - it { should contain_file(service_config_file).with_content(/--data-root \/mnt\/docker/) } - end + let(:params) do + { + 'root_dir' => '/mnt/docker', + 'version' => '18.03', + } + end + it { is_expected.to contain_file(service_config_file).with_content(%r{--data-root \/mnt\/docker}) } + end context 'with ensure absent' do - let(:params) { {'ensure' => 'absent' } } - it { should contain_package('docker').with_ensure('absent') } + let(:params) { { 'ensure' => 'absent' } } + + it { is_expected.to contain_package('docker').with_ensure('absent') } end context 'with ensure absent and ' do - let(:params) { {'ensure' => 'absent' } } - it { should contain_package('docker').with_ensure('absent') } - it { should contain_package('docker-ce-cli').with_ensure('absent') } - it { should contain_package('containerd.io').with_ensure('absent') } + let(:params) { { 'ensure' => 'absent' } } + + it { is_expected.to contain_package('docker').with_ensure('absent') } + it { is_expected.to contain_package('docker-ce-cli').with_ensure('absent') } + it { is_expected.to contain_package('containerd.io').with_ensure('absent') } end context 'with an invalid combination of devicemapper options' do - let(:params) { + let(:params) do { 'dm_datadev' => '/dev/mapper/vg_test-docker--pool_tdata', 'dm_metadatadev' => '/dev/mapper/vg_test-docker--pool_tmeta', - 'dm_thinpooldev' => '/dev/mapper/vg_test-docker--pool' - } - } + 'dm_thinpooldev' => '/dev/mapper/vg_test-docker--pool' } + end + it do expect { - should contain_package('docker') - }.to raise_error(Puppet::Error, /You can use the \$dm_thinpooldev parameter, or the \$dm_datadev and \$dm_metadatadev parameter pair, but you cannot use both./) + is_expected.to contain_package('docker') + }.to raise_error(Puppet::Error, %r{You can use the \$dm_thinpooldev parameter, or the \$dm_datadev and \$dm_metadatadev parameter pair, but you cannot use both.}) end end - end - end ['RedHat', 'CentOS'].each do |operatingsystem| context "on #{operatingsystem}" do - let(:facts) { { - :architecture => 'x86_64', - :osfamily => 'RedHat', - :operatingsystem => operatingsystem, - :operatingsystemrelease => '7.0', - :operatingsystemmajrelease => '7', - :kernelversion => '3.10.0', - :os => { :distro => { :codename => 'wheezy' }, :family => 'Debian', :name => 'Debian', :release => { :major => '7', :full => '7.0' } } - } } + let(:facts) do + { + architecture: 'x86_64', + osfamily: 'RedHat', + operatingsystem: operatingsystem, + operatingsystemrelease: '7.0', + operatingsystemmajrelease: '7', + kernelversion: '3.10.0', + os: { distro: { codename: 'wheezy' }, family: 'Debian', name: 'Debian', release: { major: '7', full: '7.0' } }, + } + end storage_setup_file = '/etc/sysconfig/docker-storage-setup' context 'with storage driver' do - let(:params) { { 'storage_driver' => 'devicemapper' }} - it { should contain_file(storage_setup_file).with_content(/^STORAGE_DRIVER=devicemapper/) } + let(:params) { { 'storage_driver' => 'devicemapper' } } + + it { is_expected.to contain_file(storage_setup_file).with_content(%r{^STORAGE_DRIVER=devicemapper}) } end context 'with storage devices' do - let(:params) { { 'storage_devs' => '/dev/sda,/dev/sdb' }} - it { should contain_file(storage_setup_file).with_content(/^DEVS="\/dev\/sda,\/dev\/sdb"/) } + let(:params) { { 'storage_devs' => '/dev/sda,/dev/sdb' } } + + it { is_expected.to contain_file(storage_setup_file).with_content(%r{^DEVS="\/dev\/sda,\/dev\/sdb"}) } end context 'with storage volume group' do - let(:params) { { 'storage_vg' => 'vg_test' }} - it { should contain_file(storage_setup_file).with_content(/^VG=vg_test/) } + let(:params) { { 'storage_vg' => 'vg_test' } } + + it { is_expected.to contain_file(storage_setup_file).with_content(%r{^VG=vg_test}) } end context 'with storage root size' do - let(:params) { { 'storage_root_size' => '10G' }} - it { should contain_file(storage_setup_file).with_content(/^ROOT_SIZE=10G/) } + let(:params) { { 'storage_root_size' => '10G' } } + + it { is_expected.to contain_file(storage_setup_file).with_content(%r{^ROOT_SIZE=10G}) } end context 'with storage data size' do - let(:params) { { 'storage_data_size' => '10G' }} - it { should contain_file(storage_setup_file).with_content(/^DATA_SIZE=10G/) } + let(:params) { { 'storage_data_size' => '10G' } } + + it { is_expected.to contain_file(storage_setup_file).with_content(%r{^DATA_SIZE=10G}) } end context 'with storage min data size' do - let(:params) { { 'storage_min_data_size' => '2G' }} - it { should contain_file(storage_setup_file).with_content(/^MIN_DATA_SIZE=2G/) } + let(:params) { { 'storage_min_data_size' => '2G' } } + + it { is_expected.to contain_file(storage_setup_file).with_content(%r{^MIN_DATA_SIZE=2G}) } end context 'with storage chunk size' do - let(:params) { { 'storage_chunk_size' => '10G' }} - it { should contain_file(storage_setup_file).with_content(/^CHUNK_SIZE=10G/) } + let(:params) { { 'storage_chunk_size' => '10G' } } + + it { is_expected.to contain_file(storage_setup_file).with_content(%r{^CHUNK_SIZE=10G}) } end context 'with storage grow partition' do - let(:params) { { 'storage_growpart' => true }} - it { should contain_file(storage_setup_file).with_content(/^GROWPART=true/) } + let(:params) { { 'storage_growpart' => true } } + + it { is_expected.to contain_file(storage_setup_file).with_content(%r{^GROWPART=true}) } end context 'with storage auto extend pool' do - let(:params) { { 'storage_auto_extend_pool' => '1' }} - it { should contain_file(storage_setup_file).with_content(/^AUTO_EXTEND_POOL=1/) } + let(:params) { { 'storage_auto_extend_pool' => '1' } } + + it { is_expected.to contain_file(storage_setup_file).with_content(%r{^AUTO_EXTEND_POOL=1}) } end context 'with storage auto extend threshold' do - let(:params) { { 'storage_pool_autoextend_threshold' => '1' }} - it { should contain_file(storage_setup_file).with_content(/^POOL_AUTOEXTEND_THRESHOLD=1/) } + let(:params) { { 'storage_pool_autoextend_threshold' => '1' } } + + it { is_expected.to contain_file(storage_setup_file).with_content(%r{^POOL_AUTOEXTEND_THRESHOLD=1}) } end context 'with storage auto extend percent' do - let(:params) { { 'storage_pool_autoextend_percent' => '10' }} - it { should contain_file(storage_setup_file).with_content(/^POOL_AUTOEXTEND_PERCENT=10/) } + let(:params) { { 'storage_pool_autoextend_percent' => '10' } } + + it { is_expected.to contain_file(storage_setup_file).with_content(%r{^POOL_AUTOEXTEND_PERCENT=10}) } end context 'with custom storage_setup_file' do - let(:params) { { 'storage_setup_file' => '/etc/sysconfig/docker-latest-storage-setup' }} - it { should contain_file('/etc/sysconfig/docker-latest-storage-setup').with_content(/managed by Puppet/) } - end + let(:params) { { 'storage_setup_file' => '/etc/sysconfig/docker-latest-storage-setup' } } + it { is_expected.to contain_file('/etc/sysconfig/docker-latest-storage-setup').with_content(%r{managed by Puppet}) } + end end end context 'specific to Ubuntu Trusty' do - let(:facts) { { - :architecture => 'amd64', - :osfamily => 'Debian', - :lsbdistid => 'Ubuntu', - :operatingsystem => 'Ubuntu', - :lsbdistcodename => 'trusty', - :operatingsystemrelease => '14.04', - :kernelrelease => '3.8.0-29-generic', - :os => { :distro => { :codename => 'wheezy' }, :family => 'Debian', :name => 'Debian', :release => { :major => '7', :full => '7.0' } } - } } - it { should contain_service('docker').with_provider('upstart') } - it { should contain_package('docker').with_name('docker-ce').with_ensure('present') } - it { should contain_package('apparmor') } + let(:facts) do + { + architecture: 'amd64', + osfamily: 'Debian', + lsbdistid: 'Ubuntu', + operatingsystem: 'Ubuntu', + lsbdistcodename: 'trusty', + operatingsystemrelease: '14.04', + kernelrelease: '3.8.0-29-generic', + os: { distro: { codename: 'wheezy' }, family: 'Debian', name: 'Debian', release: { major: '7', full: '7.0' } }, + } + end + + it { is_expected.to contain_service('docker').with_provider('upstart') } + it { is_expected.to contain_package('docker').with_name('docker-ce').with_ensure('present') } + it { is_expected.to contain_package('apparmor') } end context 'newer versions of Debian and Ubuntu' do context 'Ubuntu >= 15.04' do - let(:facts) { { - :architecture => 'amd64', - :osfamily => 'Debian', - :lsbdistid => 'Ubuntu', - :operatingsystem => 'Ubuntu', - :lsbdistcodename => 'trusty', - :operatingsystemrelease => '15.04', - :kernelrelease => '3.8.0-29-generic', - :os => { :distro => { :codename => 'wheezy' }, :family => 'Debian', :name => 'Debian', :release => { :major => '7', :full => '7.0' } } - } } - - it { should contain_service('docker').with_provider('systemd').with_hasstatus(true).with_hasrestart(true) } + let(:facts) do + { + architecture: 'amd64', + osfamily: 'Debian', + lsbdistid: 'Ubuntu', + operatingsystem: 'Ubuntu', + lsbdistcodename: 'trusty', + operatingsystemrelease: '15.04', + kernelrelease: '3.8.0-29-generic', + os: { distro: { codename: 'wheezy' }, family: 'Debian', name: 'Debian', release: { major: '7', full: '7.0' } }, + } + end + + it { is_expected.to contain_service('docker').with_provider('systemd').with_hasstatus(true).with_hasrestart(true) } end context 'Debian >= 8' do - let(:facts) { { - :architecture => 'amd64', - :osfamily => 'Debian', - :operatingsystem => 'Debian', - :lsbdistid => 'Debian', - :lsbdistcodename => 'jessie', - :kernelrelease => '3.2.0-4-amd64', - :operatingsystemmajrelease => '8', - :os => { :distro => { :codename => 'wheezy' }, :family => 'Debian', :name => 'Debian', :release => { :major => '7', :full => '7.0' } } - } } - - it { should contain_service('docker').with_provider('systemd').with_hasstatus(true).with_hasrestart(true) } + let(:facts) do + { + architecture: 'amd64', + osfamily: 'Debian', + operatingsystem: 'Debian', + lsbdistid: 'Debian', + lsbdistcodename: 'jessie', + kernelrelease: '3.2.0-4-amd64', + operatingsystemmajrelease: '8', + os: { distro: { codename: 'wheezy' }, family: 'Debian', name: 'Debian', release: { major: '7', full: '7.0' } }, + } + end + + it { is_expected.to contain_service('docker').with_provider('systemd').with_hasstatus(true).with_hasrestart(true) } end end context 'with an invalid distro name' do - let(:facts) { { - :architecture => 'Whatever', - :osfamily => 'Whatever', - :operatingsystem => 'Whatever', - :lsbdistid => 'Whatever', - :lsbdistcodename => 'Whatever', - :kernelrelease => 'Whatever', - :operatingsystemmajrelease => 'Whatever', - :os => { :distro => { :codename => 'Whatever' }, :family => 'Whatever', :name => 'Whatever', :release => { :major => 'Whatever', :full => 'Whatever' } } - } } + let(:facts) do + { + architecture: 'Whatever', + osfamily: 'Whatever', + operatingsystem: 'Whatever', + lsbdistid: 'Whatever', + lsbdistcodename: 'Whatever', + kernelrelease: 'Whatever', + operatingsystemmajrelease: 'Whatever', + os: { distro: { codename: 'Whatever' }, family: 'Whatever', name: 'Whatever', release: { major: 'Whatever', full: 'Whatever' } }, + } + end + it do expect { - should contain_package('docker') - }.to raise_error(Puppet::Error, /This module only works on Debian, Red Hat or Windows based systems./) + is_expected.to contain_package('docker') + }.to raise_error(Puppet::Error, %r{This module only works on Debian, Red Hat or Windows based systems.}) end end context 'CentOS < 7' do - let(:facts) { { - :architecture => 'x86_64', - :osfamily => 'RedHat', - :operatingsystem => 'CentOS', - :kernelversion => '3.10.0', - :operatingsystemmajrelease => '6', - :os => { :family => 'RedHat', :name => 'CentOS', :release => { :major => '6', :full => '6.0' } } - } } + let(:facts) do + { + architecture: 'x86_64', + osfamily: 'RedHat', + operatingsystem: 'CentOS', + kernelversion: '3.10.0', + operatingsystemmajrelease: '6', + os: { family: 'RedHat', name: 'CentOS', release: { major: '6', full: '6.0' } }, + } + end it do expect { - should contain_package('docker') - }.to raise_error(Puppet::Error, /This module only works on CentOS version 7 and higher based systems./) + is_expected.to contain_package('docker') + }.to raise_error(Puppet::Error, %r{This module only works on CentOS version 7 and higher based systems.}) end end - end diff --git a/spec/classes/docker_windows_spec.rb b/spec/classes/docker_windows_spec.rb index 9c3e629..6d5b226 100644 --- a/spec/classes/docker_windows_spec.rb +++ b/spec/classes/docker_windows_spec.rb @@ -1,291 +1,384 @@ require 'spec_helper' -describe 'docker', :type => :class do - osfamily = "windows" - context "on #{osfamily}" do - let(:facts) { { - :architecture => 'amd64', - :osfamily => 'windows', - :operatingsystem => 'windows', - :kernelrelease => '10.0.14393', - :operatingsystemrelease => '2016', - :operatingsystemmajrelease => '2016', - :docker_program_data_path => 'C:/ProgramData', - :docker_program_files_path => 'C:/Program Files', - :docker_systemroot => 'C:/Windows', - :docker_user_temp_path => 'C:/Users/Administrator/AppData/Local/Temp', - :os => { :family => 'windows', :name => 'windows', :release => { :major => '2016', :full => '2016' } } - } } - service_config_file = 'C:/ProgramData/docker/config/daemon.json' - let(:params) {{ 'docker_ee' => true }} - - it { should compile.with_all_deps } - it { should contain_file('C:/ProgramData/docker/').with({ - 'ensure' => 'directory' - } ) } - it { should contain_file('C:/ProgramData/docker/config/')} - it { should contain_exec('service-restart-on-failure') } - it { should contain_exec('install-docker-package').with_command(/Install-PackageProvider NuGet -Force/) } - it { should contain_exec('install-docker-package').with_command(/Install-Module \$dockerProviderName -Force/) } - it { should contain_class('docker::repos').that_comes_before('Class[docker::install]') } - it { should contain_class('docker::install').that_comes_before('Class[docker::config]') } - it { should contain_class('docker::config').that_comes_before('Class[docker::service]') } - - it { should contain_file(service_config_file).without_content(/icc=/) } - - context 'with dns' do - let(:params) { { - 'dns' => '8.8.8.8', - 'docker_ee' => true - } } - it { should contain_file(service_config_file).with_content(/"dns": \["8.8.8.8"\],/) } - end - - context 'with multi dns' do - let(:params) { { - 'dns' => ['8.8.8.8', '8.8.4.4'], - 'docker_ee' => true - } } - it { should contain_file(service_config_file).with_content(/"dns": \["8.8.8.8","8.8.4.4"\],/) } - end - - context 'with dns search' do - let(:params) { { - 'dns_search' => ['my.domain.local'], - 'docker_ee' => true - } } - it { should contain_file(service_config_file).with_content(/"dns-search": \["my.domain.local"\],/) } - end - - context 'with multi dns search' do - let(:params) { { - 'dns_search' => ['my.domain.local', 'other-domain.de'], - 'docker_ee' => true - } } - it { should contain_file(service_config_file).with_content(/"dns-search": \["my.domain.local","other-domain.de"\],/) } - end - - context 'with log_driver' do - let(:params) { { - 'log_driver' => 'etwlogs', - 'docker_ee' => true - } } - it { should contain_file(service_config_file).with_content(/"log-driver": "etwlogs"/) } - end - - context 'with invalid log_driver' do - let(:params) { { - 'log_driver' => 'invalid', - 'docker_ee' => true - } } - it do - expect { - should contain_package('docker') - }.to raise_error(Puppet::Error, /log_driver must be one of none, json-file, syslog, gelf, fluentd, splunk, awslogs or etwlogs/) - end - end - - context 'with invalid journald log_driver' do - let(:params) { { - 'log_driver' => 'journald', - 'docker_ee' => true - } } - it do - expect { - should contain_package('docker') - }.to raise_error(Puppet::Error, /log_driver must be one of none, json-file, syslog, gelf, fluentd, splunk, awslogs or etwlogs/) - end - end - - context 'with mtu' do - let(:params) { { - 'mtu' => '1450', - 'docker_ee' => true - } } - it { should contain_file(service_config_file).with_content(/"mtu": 1450/) } - end - - context 'with log_level' do - let(:params) { { - 'log_level' => 'debug', - 'docker_ee' => true - } } - it { should contain_file(service_config_file).with_content(/"log-level": "debug"/) } - end - - context 'with invalid log_level' do - let(:params) { { - 'log_level' => 'verbose', - 'docker_ee' => true - } } - it do - expect { - should contain_package('docker') - }.to raise_error(Puppet::Error, /log_level must be one of debug, info, warn, error or fatal/) - end - end - - context 'with storage_driver' do - let(:params) { { - 'storage_driver' => 'windowsfilter', - 'docker_ee' => true - } } - it { should compile.with_all_deps } - end - - context 'with an invalid storage_driver' do - let(:params) { { - 'storage_driver' => 'invalid', - 'docker_ee' => true - } } - it do - expect { - should contain_package('docker') - }.to raise_error(Puppet::Error, /Valid values for storage_driver on windows are windowsfilter/) - end - end - - context 'with tcp_bind' do - let(:params) { { - 'tcp_bind' => "tcp://0.0.0.0:2376", - 'docker_ee' => true - } } - it { should contain_file(service_config_file).with_content(/"hosts": \["tcp:\/\/0.0.0.0:2376"\]/) } - end - - context 'with multiple tcp_bind' do - let(:params) { { - 'tcp_bind' => ["tcp://0.0.0.0:2376", "npipe://"], - 'docker_ee' => true - } } - it { should contain_file(service_config_file).with_content(/"hosts": \["tcp:\/\/0.0.0.0:2376","npipe:\/\/"\]/) } - end - - context 'with tls_enable, tcp_bind and tls configuration' do - let(:params) { { - 'tls_enable' => true, - 'tcp_bind' => ["tcp://0.0.0.0:2376"], - 'docker_ee' => true - } } - it { should contain_file(service_config_file).with_content( - /"hosts": \["tcp:\/\/0.0.0.0:2376"]/).with_content( - /"tlsverify": true/).with_content( - /"tlscacert": "C:\/ProgramData\/docker\/certs.d\/ca.pem"/).with_content( - /"tlscert": "C:\/ProgramData\/docker\/certs.d\/server-cert.pem"/).with_content( - /"tlskey": "C:\/ProgramData\/docker\/certs.d\/server-key.pem"/) - } - end - - context 'with tls_enable, tcp_bind and custom tls cacert' do - let(:params) { { - 'tls_enable' => true, - 'tcp_bind' => ["tcp://0.0.0.0:2376"], - 'tls_cacert' => 'C:/certs/ca.pem', - 'docker_ee' => true - } } - it { should contain_file(service_config_file).with_content( - /"tlscacert": "C:\/certs\/ca.pem"/) - } - end - - context 'with tls_enable, tcp_bind and custom tls cert' do - let(:params) { { - 'tls_enable' => true, - 'tcp_bind' => ["tcp://0.0.0.0:2376"], - 'tls_cert' => 'C:/certs/server-cert.pem', - 'docker_ee' => true - } } - it { should contain_file(service_config_file).with_content( - /"tlscert": "C:\/certs\/server-cert.pem"/) - } - end - - context 'with tls_enable, tcp_bind and custom tls key' do - let(:params) { { - 'tls_enable' => true, - 'tcp_bind' => ["tcp://0.0.0.0:2376"], - 'tls_key' => 'C:/certs/server-key.pem', - 'docker_ee' => true - } } - it { should contain_file(service_config_file).with_content( - /"tlskey": "C:\/certs\/server-key.pem"/) - } - end - - context 'with custom socket group' do - let(:params) { { - 'socket_group' => "custom", - 'docker_ee' => true - } } - it { should contain_file(service_config_file).with_content(/"group": "custom"/)} - end - - context 'with custom bridge' do - let(:params) { { - 'bridge' => "l2bridge", - 'docker_ee' => true - } } - it { should contain_file(service_config_file).with_content(/"bridge": "l2bridge"/)} - end - - context 'with invalid bridge' do - let(:params) { { - 'bridge' => "invalid", - 'docker_ee' => true - } } - it do - expect { - should contain_package('docker') - }.to raise_error(Puppet::Error, /bridge must be one of none, nat, transparent, overlay, l2bridge or l2tunnel on Windows./) - end - end - - context 'with custom fixed cidr' do - let(:params) { { - 'fixed_cidr'=> "10.0.0.0/24", - 'docker_ee' => true - } } - it { should contain_file(service_config_file).with_content(/"fixed-cidr": "10.0.0.0\/24"/)} - end - - context 'with custom registry mirror' do - let(:params) { { - 'registry_mirror'=> "https://mirror.gcr.io", - 'docker_ee' => true - } } - it { should contain_file(service_config_file).with_content(/"registry-mirrors": \["https:\/\/mirror.gcr.io"\]/)} - end - - context 'with custom label' do - let(:params) { { - 'labels'=> ["mylabel"], - 'docker_ee' => true - } } - it { should contain_file(service_config_file).with_content(/"labels": \["mylabel"\]/)} - end - - context 'with default package name' do - let(:params) { { - 'docker_ee' => true - } } - it { should contain_exec('install-docker-package').with_command(/ Docker /) } - end - - context 'with custom package name' do - let(:params) { { - 'docker_ee_package_name'=> "mydockerpackage", - 'docker_ee' => true - } } - it { should contain_exec('install-docker-package').with_command(/ mydockerpackage /) } - end - - context 'without docker_ee' do - let(:params) {{ 'docker_ee' => false }} - it do - expect { - should contain_package('docker') - }.to raise_error(Puppet::Error, /This module only work for Docker Enterprise Edition on Windows./) - end +describe 'docker', type: :class do + osfamily = 'windows' + context "on #{osfamily}" do + let(:facts) do + { + architecture: 'amd64', + osfamily: 'windows', + operatingsystem: 'windows', + kernelrelease: '10.0.14393', + operatingsystemrelease: '2016', + operatingsystemmajrelease: '2016', + docker_program_data_path: 'C:/ProgramData', + docker_program_files_path: 'C:/Program Files', + docker_systemroot: 'C:/Windows', + docker_user_temp_path: 'C:/Users/Administrator/AppData/Local/Temp', + os: { family: 'windows', name: 'windows', release: { major: '2016', full: '2016' } }, + } + end + let(:params) { { 'docker_ee' => true } } + let(:service_config_file) { 'C:/ProgramData/docker/config/daemon.json' } + + it { is_expected.to compile.with_all_deps } + it { + is_expected.to contain_file('C:/ProgramData/docker/').with('ensure' => 'directory') + } + it { is_expected.to contain_file('C:/ProgramData/docker/config/') } + it { is_expected.to contain_exec('service-restart-on-failure') } + it { is_expected.to contain_exec('install-docker-package').with_command(%r{Install-PackageProvider NuGet -Force}) } + it { is_expected.to contain_exec('install-docker-package').with_command(%r{Install-Module \$dockerProviderName -Force}) } + it { is_expected.to contain_class('docker::repos').that_comes_before('Class[docker::install]') } + it { is_expected.to contain_class('docker::install').that_comes_before('Class[docker::config]') } + it { is_expected.to contain_class('docker::config').that_comes_before('Class[docker::service]') } + + it { is_expected.to contain_file(service_config_file).without_content(%r{icc=}) } + + context 'with dns' do + let(:params) do + { + 'dns' => '8.8.8.8', + 'docker_ee' => true, + } + end + + it { is_expected.to contain_file(service_config_file).with_content(%r{"dns": \["8.8.8.8"\],}) } + end + + context 'with multi dns' do + let(:params) do + { + 'dns' => ['8.8.8.8', '8.8.4.4'], + 'docker_ee' => true, + } + end + + it { is_expected.to contain_file(service_config_file).with_content(%r{"dns": \["8.8.8.8","8.8.4.4"\],}) } + end + + context 'with dns search' do + let(:params) do + { + 'dns_search' => ['my.domain.local'], + 'docker_ee' => true, + } + end + + it { is_expected.to contain_file(service_config_file).with_content(%r{"dns-search": \["my.domain.local"\],}) } + end + + context 'with multi dns search' do + let(:params) do + { + 'dns_search' => ['my.domain.local', 'other-domain.de'], + 'docker_ee' => true, + } + end + + it { is_expected.to contain_file(service_config_file).with_content(%r{"dns-search": \["my.domain.local","other-domain.de"\],}) } + end + + context 'with log_driver' do + let(:params) do + { + 'log_driver' => 'etwlogs', + 'docker_ee' => true, + } + end + + it { is_expected.to contain_file(service_config_file).with_content(%r{"log-driver": "etwlogs"}) } + end + + context 'with invalid log_driver' do + let(:params) do + { + 'log_driver' => 'invalid', + 'docker_ee' => true, + } + end + + it do + expect { + is_expected.to contain_package('docker') + }.to raise_error(Puppet::Error, %r{log_driver must be one of none, json-file, syslog, gelf, fluentd, splunk, awslogs or etwlogs}) + end + end + + context 'with invalid journald log_driver' do + let(:params) do + { + 'log_driver' => 'journald', + 'docker_ee' => true, + } + end + + it do + expect { + is_expected.to contain_package('docker') + }.to raise_error(Puppet::Error, %r{log_driver must be one of none, json-file, syslog, gelf, fluentd, splunk, awslogs or etwlogs}) + end + end + + context 'with mtu' do + let(:params) do + { + 'mtu' => '1450', + 'docker_ee' => true, + } + end + + it { is_expected.to contain_file(service_config_file).with_content(%r{"mtu": 1450}) } + end + + context 'with log_level' do + let(:params) do + { + 'log_level' => 'debug', + 'docker_ee' => true, + } + end + + it { is_expected.to contain_file(service_config_file).with_content(%r{"log-level": "debug"}) } + end + + context 'with invalid log_level' do + let(:params) do + { + 'log_level' => 'verbose', + 'docker_ee' => true, + } + end + + it do + expect { + is_expected.to contain_package('docker') + }.to raise_error(Puppet::Error, %r{log_level must be one of debug, info, warn, error or fatal}) + end + end + + context 'with storage_driver' do + let(:params) do + { + 'storage_driver' => 'windowsfilter', + 'docker_ee' => true, + } + end + + it { is_expected.to compile.with_all_deps } + end + + context 'with an invalid storage_driver' do + let(:params) do + { + 'storage_driver' => 'invalid', + 'docker_ee' => true, + } + end + + it do + expect { + is_expected.to contain_package('docker') + }.to raise_error(Puppet::Error, %r{Valid values for storage_driver on windows are windowsfilter}) + end + end + + context 'with tcp_bind' do + let(:params) do + { + 'tcp_bind' => 'tcp://0.0.0.0:2376', + 'docker_ee' => true, + } + end + + it { is_expected.to contain_file(service_config_file).with_content(%r{"hosts": \["tcp:\/\/0.0.0.0:2376"\]}) } + end + + context 'with multiple tcp_bind' do + let(:params) do + { + 'tcp_bind' => ['tcp://0.0.0.0:2376', 'npipe://'], + 'docker_ee' => true, + } + end + + it { is_expected.to contain_file(service_config_file).with_content(%r{"hosts": \["tcp:\/\/0.0.0.0:2376","npipe:\/\/"\]}) } + end + + context 'with tls_enable, tcp_bind and tls configuration' do + let(:params) do + { + 'tls_enable' => true, + 'tcp_bind' => ['tcp://0.0.0.0:2376'], + 'docker_ee' => true, + } + end + + it { + is_expected.to contain_file(service_config_file).with_content( + %r{"hosts": \["tcp:\/\/0.0.0.0:2376"]}, + ).with_content( + %r{"tlsverify": true}, + ).with_content( + %r{"tlscacert": "C:\/ProgramData\/docker\/certs.d\/ca.pem"}, + ).with_content( + %r{"tlscert": "C:\/ProgramData\/docker\/certs.d\/server-cert.pem"}, + ).with_content( + %r{"tlskey": "C:\/ProgramData\/docker\/certs.d\/server-key.pem"}, + ) + } + end + + context 'with tls_enable, tcp_bind and custom tls cacert' do + let(:params) do + { + 'tls_enable' => true, + 'tcp_bind' => ['tcp://0.0.0.0:2376'], + 'tls_cacert' => 'C:/certs/ca.pem', + 'docker_ee' => true, + } + end + + it { + is_expected.to contain_file(service_config_file).with_content( + %r{"tlscacert": "C:\/certs\/ca.pem"}, + ) + } + end + + context 'with tls_enable, tcp_bind and custom tls cert' do + let(:params) do + { + 'tls_enable' => true, + 'tcp_bind' => ['tcp://0.0.0.0:2376'], + 'tls_cert' => 'C:/certs/server-cert.pem', + 'docker_ee' => true, + } + end + + it { + is_expected.to contain_file(service_config_file).with_content( + %r{"tlscert": "C:\/certs\/server-cert.pem"}, + ) + } + end + + context 'with tls_enable, tcp_bind and custom tls key' do + let(:params) do + { + 'tls_enable' => true, + 'tcp_bind' => ['tcp://0.0.0.0:2376'], + 'tls_key' => 'C:/certs/server-key.pem', + 'docker_ee' => true, + } + end + + it { + is_expected.to contain_file(service_config_file).with_content( + %r{"tlskey": "C:\/certs\/server-key.pem"}, + ) + } + end + + context 'with custom socket group' do + let(:params) do + { + 'socket_group' => 'custom', + 'docker_ee' => true, + } + end + + it { is_expected.to contain_file(service_config_file).with_content(%r{"group": "custom"}) } + end + + context 'with custom bridge' do + let(:params) do + { + 'bridge' => 'l2bridge', + 'docker_ee' => true, + } + end + + it { is_expected.to contain_file(service_config_file).with_content(%r{"bridge": "l2bridge"}) } + end + + context 'with invalid bridge' do + let(:params) do + { + 'bridge' => 'invalid', + 'docker_ee' => true, + } + end + + it do + expect { + is_expected.to contain_package('docker') + }.to raise_error(Puppet::Error, %r{bridge must be one of none, nat, transparent, overlay, l2bridge or l2tunnel on Windows.}) + end + end + + context 'with custom fixed cidr' do + let(:params) do + { + 'fixed_cidr' => '10.0.0.0/24', + 'docker_ee' => true, + } + end + + it { is_expected.to contain_file(service_config_file).with_content(%r{"fixed-cidr": "10.0.0.0\/24"}) } + end + + context 'with custom registry mirror' do + let(:params) do + { + 'registry_mirror' => 'https://mirror.gcr.io', + 'docker_ee' => true, + } + end + + it { is_expected.to contain_file(service_config_file).with_content(%r{"registry-mirrors": \["https:\/\/mirror.gcr.io"\]}) } + end + + context 'with custom label' do + let(:params) do + { + 'labels' => ['mylabel'], + 'docker_ee' => true, + } + end + + it { is_expected.to contain_file(service_config_file).with_content(%r{"labels": \["mylabel"\]}) } + end + + context 'with default package name' do + let(:params) do + { + 'docker_ee' => true, + } + end + + it { is_expected.to contain_exec('install-docker-package').with_command(%r{ Docker }) } + end + + context 'with custom package name' do + let(:params) do + { + 'docker_ee_package_name' => 'mydockerpackage', + 'docker_ee' => true, + } + end + + it { is_expected.to contain_exec('install-docker-package').with_command(%r{ mydockerpackage }) } + end + + context 'without docker_ee' do + let(:params) { { 'docker_ee' => false } } + + it do + expect { + is_expected.to contain_package('docker') + }.to raise_error(Puppet::Error, %r{This module only work for Docker Enterprise Edition on Windows.}) end end + end end diff --git a/spec/classes/machine_spec.rb b/spec/classes/machine_spec.rb index 6c4a35d..ca5cfab 100644 --- a/spec/classes/machine_spec.rb +++ b/spec/classes/machine_spec.rb @@ -1,88 +1,116 @@ require 'spec_helper' -describe 'docker::machine', :type => :class do +describe 'docker::machine', type: :class do let(:facts) do { - :kernel => 'Linux', - :osfamily => 'Debian', - :operatingsystem => 'Ubuntu', - :lsbdistid => 'Ubuntu', - :lsbdistcodename => 'maverick', - :kernelrelease => '3.8.0-29-generic', - :operatingsystemrelease => '10.04', - :operatingsystemmajrelease => '10', + kernel: 'Linux', + osfamily: 'Debian', + operatingsystem: 'Ubuntu', + lsbdistid: 'Ubuntu', + lsbdistcodename: 'maverick', + kernelrelease: '3.8.0-29-generic', + operatingsystemrelease: '10.04', + operatingsystemmajrelease: '10', } end it { is_expected.to compile } context 'with defaults for all parameters' do - it { should compile.with_all_deps } - it { should contain_exec('Install Docker Machine 0.16.1').with( - 'path' => '/usr/bin/', - 'cwd' => '/tmp', - 'command' => 'curl -s -S -L https://github.com/docker/machine/releases/download/v0.16.1/docker-machine-Linux-x86_64 -o /usr/local/bin/docker-machine-0.16.1', - 'creates' => '/usr/local/bin/docker-machine-0.16.1', - 'require' => 'Package[curl]' - )} - it { should contain_file('/usr/local/bin/docker-machine-0.16.1').with( - 'owner' => 'root', - 'mode' => '0755', - 'require' => 'Exec[Install Docker Machine 0.16.1]' - )} - it { should contain_file('/usr/local/bin/docker-machine').with( - 'ensure' => 'link', - 'target' => '/usr/local/bin/docker-machine-0.16.1', - 'require' => 'File[/usr/local/bin/docker-machine-0.16.1]' - )} + it { is_expected.to compile.with_all_deps } + it { + is_expected.to contain_exec('Install Docker Machine 0.16.1').with( + 'path' => '/usr/bin/', + 'cwd' => '/tmp', + 'command' => 'curl -s -S -L https://github.com/docker/machine/releases/download/v0.16.1/docker-machine-Linux-x86_64 -o /usr/local/bin/docker-machine-0.16.1', + 'creates' => '/usr/local/bin/docker-machine-0.16.1', + 'require' => 'Package[curl]', + ) + } + it { + is_expected.to contain_file('/usr/local/bin/docker-machine-0.16.1').with( + 'owner' => 'root', + 'mode' => '0755', + 'require' => 'Exec[Install Docker Machine 0.16.1]', + ) + } + it { + is_expected.to contain_file('/usr/local/bin/docker-machine').with( + 'ensure' => 'link', + 'target' => '/usr/local/bin/docker-machine-0.16.1', + 'require' => 'File[/usr/local/bin/docker-machine-0.16.1]', + ) + } end context 'with ensure => absent' do - let (:params) { { :ensure => 'absent' } } - it { should contain_file('/usr/local/bin/docker-machine-0.16.1').with_ensure('absent') } - it { should contain_file('/usr/local/bin/docker-machine').with_ensure('absent') } + let(:params) { { ensure: 'absent' } } + + it { is_expected.to contain_file('/usr/local/bin/docker-machine-0.16.1').with_ensure('absent') } + it { is_expected.to contain_file('/usr/local/bin/docker-machine').with_ensure('absent') } end context 'when no proxy is provided' do - let(:params) { {:version => '0.16.0'} } - it { is_expected.to contain_exec('Install Docker Machine 0.16.0').with_command( - 'curl -s -S -L https://github.com/docker/machine/releases/download/v0.16.0/docker-machine-Linux-x86_64 -o /usr/local/bin/docker-machine-0.16.0') + let(:params) { { version: '0.16.0' } } + + it { + is_expected.to contain_exec('Install Docker Machine 0.16.0').with_command( + 'curl -s -S -L https://github.com/docker/machine/releases/download/v0.16.0/docker-machine-Linux-x86_64 -o /usr/local/bin/docker-machine-0.16.0', + ) } end context 'when proxy is provided' do - let(:params) { {:proxy => 'http://proxy.example.org:3128/', - :version => '0.16.0'} } + let(:params) do + { proxy: 'http://proxy.example.org:3128/', + version: '0.16.0' } + end + it { is_expected.to compile } - it { is_expected.to contain_exec('Install Docker Machine 0.16.0').with_command( - 'curl -s -S -L --proxy http://proxy.example.org:3128/ https://github.com/docker/machine/releases/download/v0.16.0/docker-machine-Linux-x86_64 -o /usr/local/bin/docker-machine-0.16.0') + it { + is_expected.to contain_exec('Install Docker Machine 0.16.0').with_command( + 'curl -s -S -L --proxy http://proxy.example.org:3128/ https://github.com/docker/machine/releases/download/v0.16.0/docker-machine-Linux-x86_64 -o /usr/local/bin/docker-machine-0.16.0', + ) } end context 'when proxy is not a http proxy' do - let(:params) { {:proxy => 'this is not a URL'} } + let(:params) { { proxy: 'this is not a URL' } } + it do expect { is_expected.to compile - }.to raise_error(/does not match/) + }.to raise_error(%r{does not match}) end end context 'when proxy contains username and password' do - let(:params) { {:proxy => 'http://user:password@proxy.example.org:3128/', - :version => '0.16.0'} } + let(:params) do + { proxy: 'http://user:password@proxy.example.org:3128/', + version: '0.16.0' } + end + it { is_expected.to compile } - it { is_expected.to contain_exec('Install Docker Machine 0.16.0').with_command( - 'curl -s -S -L --proxy http://user:password@proxy.example.org:3128/ https://github.com/docker/machine/releases/download/v0.16.0/docker-machine-Linux-x86_64 -o /usr/local/bin/docker-machine-0.16.0') + it { + is_expected.to contain_exec('Install Docker Machine 0.16.0').with_command( + 'curl -s -S -L --proxy http://user:password@proxy.example.org:3128/'\ + ' https://github.com/docker/machine/releases/download/v0.16.0/docker-machine-Linux-x86_64'\ + ' -o /usr/local/bin/docker-machine-0.16.0', + ) } end context 'when proxy IP is provided' do - let(:params) { {:proxy => 'http://10.10.10.10:3128/', - :version => '0.16.0'} } + let(:params) do + { proxy: 'http://10.10.10.10:3128/', + version: '0.16.0' } + end + it { is_expected.to compile } - it { is_expected.to contain_exec('Install Docker Machine 0.16.0').with_command( - 'curl -s -S -L --proxy http://10.10.10.10:3128/ https://github.com/docker/machine/releases/download/v0.16.0/docker-machine-Linux-x86_64 -o /usr/local/bin/docker-machine-0.16.0') + it { + is_expected.to contain_exec('Install Docker Machine 0.16.0').with_command( + 'curl -s -S -L --proxy http://10.10.10.10:3128/ https://github.com/docker/machine/releases/download/v0.16.0/docker-machine-Linux-x86_64 -o /usr/local/bin/docker-machine-0.16.0', + ) } end end diff --git a/spec/classes/system_reload_spec.rb b/spec/classes/system_reload_spec.rb index 983e7d7..a17620b 100644 --- a/spec/classes/system_reload_spec.rb +++ b/spec/classes/system_reload_spec.rb @@ -1,22 +1,25 @@ require 'spec_helper' -describe 'docker::systemd_reload', :type => :class do - - let(:facts) { { - :osfamily => 'Debian', - :operatingsystem => 'Debian', - :lsbdistid => 'Debian', - :lsbdistcodename => 'stretch', - :kernelrelease => '9.3.0-amd64', - :operatingsystemrelease => '9.3', - :operatingsystemmajrelease => '9', - } } +describe 'docker::systemd_reload', type: :class do + let(:facts) do + { + osfamily: 'Debian', + operatingsystem: 'Debian', + lsbdistid: 'Debian', + lsbdistcodename: 'stretch', + kernelrelease: '9.3.0-amd64', + operatingsystemrelease: '9.3', + operatingsystemmajrelease: '9', + } + end context 'with systems that have systemd' do - it { should contain_exec('docker-systemd-reload').with( - 'path' => ['/bin/', '/sbin/', '/usr/bin/', '/usr/sbin/'], - 'command' => 'systemctl daemon-reload', - 'refreshonly' => 'true' - ) } + it { + is_expected.to contain_exec('docker-systemd-reload').with( + 'path' => ['/bin/', '/sbin/', '/usr/bin/', '/usr/sbin/'], + 'command' => 'systemctl daemon-reload', + 'refreshonly' => 'true', + ) + } end -end \ No newline at end of file +end diff --git a/spec/defines/exec_spec.rb b/spec/defines/exec_spec.rb index bb47210..56bf54b 100644 --- a/spec/defines/exec_spec.rb +++ b/spec/defines/exec_spec.rb @@ -1,63 +1,75 @@ require 'spec_helper' -describe 'docker::exec', :type => :define do +describe 'docker::exec', type: :define do let(:title) { 'sample' } - let(:facts) { { - :osfamily => 'Debian', - :operatingsystem => 'Debian', - :lsbdistid => 'Debian', - :lsbdistcodename => 'jessie', - :kernelrelease => '3.2.0-4-amd64', - :operatingsystemmajrelease => '8', - } } + let(:facts) do + { + osfamily: 'Debian', + operatingsystem: 'Debian', + lsbdistid: 'Debian', + lsbdistcodename: 'jessie', + kernelrelease: '3.2.0-4-amd64', + operatingsystemmajrelease: '8', + } + end context 'when running detached' do - let(:params) { {'command' => 'command', 'container' => 'container', 'detach' => true} } - it { should contain_exec('docker exec --detach=true container command') } + let(:params) { { 'command' => 'command', 'container' => 'container', 'detach' => true } } + + it { is_expected.to contain_exec('docker exec --detach=true container command') } end context 'when running with tty' do - let(:params) { {'command' => 'command', 'container' => 'container', 'tty' => true} } - it { should contain_exec('docker exec --tty=true container command') } + let(:params) { { 'command' => 'command', 'container' => 'container', 'tty' => true } } + + it { is_expected.to contain_exec('docker exec --tty=true container command') } end context 'when running with interactive' do - let(:params) { {'command' => 'command', 'container' => 'container', 'interactive' => true} } - it { should contain_exec('docker exec --interactive=true container command') } + let(:params) { { 'command' => 'command', 'container' => 'container', 'interactive' => true } } + + it { is_expected.to contain_exec('docker exec --interactive=true container command') } end context 'when running with onlyif "running"' do - let(:params) { {'command' => 'command', 'container' => 'container', 'interactive' => true, 'onlyif' => 'running'} } - it { should contain_exec('docker exec --interactive=true container command').with_onlyif ('docker ps --no-trunc --format=\'table {{.Names}}\' | grep \'^container$\'') } + let(:params) { { 'command' => 'command', 'container' => 'container', 'interactive' => true, 'onlyif' => 'running' } } + + it { is_expected.to contain_exec('docker exec --interactive=true container command').with_onlyif 'docker ps --no-trunc --format=\'table {{.Names}}\' | grep \'^container$\'' } end context 'when running without onlyif custom command' do - let(:params) { {'command' => 'command', 'container' => 'container', 'interactive' => true, 'onlyif' => 'custom'} } - it { should contain_exec('docker exec --interactive=true container command').with_onlyif ('custom') } + let(:params) { { 'command' => 'command', 'container' => 'container', 'interactive' => true, 'onlyif' => 'custom' } } + + it { is_expected.to contain_exec('docker exec --interactive=true container command').with_onlyif 'custom' } end context 'when running without onlyif' do - let(:params) { {'command' => 'command', 'container' => 'container', 'interactive' => true} } - it { should contain_exec('docker exec --interactive=true container command').with_onlyif (nil) } + let(:params) { { 'command' => 'command', 'container' => 'container', 'interactive' => true } } + + it { is_expected.to contain_exec('docker exec --interactive=true container command').with_onlyif nil } end context 'when running with unless' do - let(:params) { {'command' => 'command', 'container' => 'container', 'interactive' => true, 'unless' => 'some_command arg1'} } - it { should contain_exec('docker exec --interactive=true container command').with_unless ('docker exec --interactive=true container some_command arg1') } + let(:params) { { 'command' => 'command', 'container' => 'container', 'interactive' => true, 'unless' => 'some_command arg1' } } + + it { is_expected.to contain_exec('docker exec --interactive=true container command').with_unless 'docker exec --interactive=true container some_command arg1' } end context 'when running without unless' do - let(:params) { {'command' => 'command', 'container' => 'container', 'interactive' => true,} } - it { should contain_exec('docker exec --interactive=true container command').with_unless (nil) } + let(:params) { { 'command' => 'command', 'container' => 'container', 'interactive' => true } } + + it { is_expected.to contain_exec('docker exec --interactive=true container command').with_unless nil } end context 'with title that need sanitisation' do - let(:params) { {'command' => 'command', 'container' => 'container_sample/1', 'detach' => true, 'sanitise_name' => true} } - it { should contain_exec('docker exec --detach=true container_sample-1 command') } + let(:params) { { 'command' => 'command', 'container' => 'container_sample/1', 'detach' => true, 'sanitise_name' => true } } + + it { is_expected.to contain_exec('docker exec --detach=true container_sample-1 command') } end context 'with environment variables passed to exec' do - let(:params) { {'command' => 'command', 'container' => 'container', 'env' => ['FOO=BAR','FOO2=BAR2']} } - it { should contain_exec('docker exec --env FOO=BAR --env FOO2=BAR2 container command') } + let(:params) { { 'command' => 'command', 'container' => 'container', 'env' => ['FOO=BAR', 'FOO2=BAR2'] } } + + it { is_expected.to contain_exec('docker exec --env FOO=BAR --env FOO2=BAR2 container command') } end end diff --git a/spec/defines/exec_windows_spec.rb b/spec/defines/exec_windows_spec.rb index 1cdb68c..bfcd281 100644 --- a/spec/defines/exec_windows_spec.rb +++ b/spec/defines/exec_windows_spec.rb @@ -1,63 +1,74 @@ require 'spec_helper' -describe 'docker::exec', :type => :define do +describe 'docker::exec', type: :define do let(:title) { 'sample' } - let(:facts) { { - :architecture => 'amd64', - :osfamily => 'windows', - :operatingsystem => 'windows', - :kernelrelease => '10.0.14393', - :operatingsystemrelease => '2016', - :operatingsystemmajrelease => '2016', - :docker_program_data_path => 'C:/ProgramData', - :docker_program_files_path => 'C:/Program Files', - :docker_systemroot => 'C:/Windows', - :docker_user_temp_path => 'C:/Users/Administrator/AppData/Local/Temp', - :os => { :family => 'windows', :name => 'windows', :release => { :major => '2016', :full => '2016' } } - } } + let(:facts) do + { + architecture: 'amd64', + osfamily: 'windows', + operatingsystem: 'windows', + kernelrelease: '10.0.14393', + operatingsystemrelease: '2016', + operatingsystemmajrelease: '2016', + docker_program_data_path: 'C:/ProgramData', + docker_program_files_path: 'C:/Program Files', + docker_systemroot: 'C:/Windows', + docker_user_temp_path: 'C:/Users/Administrator/AppData/Local/Temp', + os: { family: 'windows', name: 'windows', release: { major: '2016', full: '2016' } }, + } + end context 'when running detached' do - let(:params) { {'command' => 'command', 'container' => 'container', 'detach' => true} } - it { should contain_exec('docker exec --detach=true container command') } + let(:params) { { 'command' => 'command', 'container' => 'container', 'detach' => true } } + + it { is_expected.to contain_exec('docker exec --detach=true container command') } end context 'when running with tty' do - let(:params) { {'command' => 'command', 'container' => 'container', 'tty' => true} } - it { should contain_exec('docker exec --tty=true container command') } + let(:params) { { 'command' => 'command', 'container' => 'container', 'tty' => true } } + + it { is_expected.to contain_exec('docker exec --tty=true container command') } end context 'when running with interactive' do - let(:params) { {'command' => 'command', 'container' => 'container', 'interactive' => true} } - it { should contain_exec('docker exec --interactive=true container command') } + let(:params) { { 'command' => 'command', 'container' => 'container', 'interactive' => true } } + + it { is_expected.to contain_exec('docker exec --interactive=true container command') } end context 'when running with onlyif "running"' do - let(:params) { {'command' => 'command', 'container' => 'container', 'interactive' => true, 'onlyif' => 'running'} } - it { should contain_exec('docker exec --interactive=true container command').with_onlyif ('docker ps --no-trunc --format=\'table {{.Names}}\' | grep \'^container$\'') } + let(:params) { { 'command' => 'command', 'container' => 'container', 'interactive' => true, 'onlyif' => 'running' } } + + it { is_expected.to contain_exec('docker exec --interactive=true container command').with_onlyif 'docker ps --no-trunc --format=\'table {{.Names}}\' | grep \'^container$\'' } end context 'when running without onlyif custom command' do - let(:params) { {'command' => 'command', 'container' => 'container', 'interactive' => true, 'onlyif' => 'custom'} } - it { should contain_exec('docker exec --interactive=true container command').with_onlyif ('custom') } + let(:params) { { 'command' => 'command', 'container' => 'container', 'interactive' => true, 'onlyif' => 'custom' } } + + it { is_expected.to contain_exec('docker exec --interactive=true container command').with_onlyif 'custom' } end context 'when running without onlyif' do - let(:params) { {'command' => 'command', 'container' => 'container', 'interactive' => true} } - it { should contain_exec('docker exec --interactive=true container command').with_onlyif (nil) } + let(:params) { { 'command' => 'command', 'container' => 'container', 'interactive' => true } } + + it { is_expected.to contain_exec('docker exec --interactive=true container command').with_onlyif nil } end context 'when running with unless' do - let(:params) { {'command' => 'command', 'container' => 'container', 'interactive' => true, 'unless' => 'some_command arg1'} } - it { should contain_exec('docker exec --interactive=true container command').with_unless ('docker exec --interactive=true container some_command arg1') } + let(:params) { { 'command' => 'command', 'container' => 'container', 'interactive' => true, 'unless' => 'some_command arg1' } } + + it { is_expected.to contain_exec('docker exec --interactive=true container command').with_unless 'docker exec --interactive=true container some_command arg1' } end context 'when running without unless' do - let(:params) { {'command' => 'command', 'container' => 'container', 'interactive' => true,} } - it { should contain_exec('docker exec --interactive=true container command').with_unless (nil) } + let(:params) { { 'command' => 'command', 'container' => 'container', 'interactive' => true } } + + it { is_expected.to contain_exec('docker exec --interactive=true container command').with_unless nil } end context 'with title that need sanitisation' do - let(:params) { {'command' => 'command', 'container' => 'container_sample/1', 'detach' => true, 'sanitise_name' => true} } - it { should contain_exec('docker exec --detach=true container_sample-1 command') } + let(:params) { { 'command' => 'command', 'container' => 'container_sample/1', 'detach' => true, 'sanitise_name' => true } } + + it { is_expected.to contain_exec('docker exec --detach=true container_sample-1 command') } end end diff --git a/spec/defines/image_spec.rb b/spec/defines/image_spec.rb index 0d02981..68d6316 100644 --- a/spec/defines/image_spec.rb +++ b/spec/defines/image_spec.rb @@ -1,167 +1,194 @@ require 'spec_helper' -describe 'docker::image', :type => :define do +describe 'docker::image', type: :define do let(:title) { 'base' } - let(:facts) { { - :osfamily => 'Debian', - :operatingsystem => 'Debian', - :lsbdistid => 'Debian', - :lsbdistcodename => 'jessie', - :kernelrelease => '3.2.0-4-amd64', - :operatingsystemmajrelease => '8', - } } + let(:facts) do + { + osfamily: 'Debian', + operatingsystem: 'Debian', + lsbdistid: 'Debian', + lsbdistcodename: 'jessie', + kernelrelease: '3.2.0-4-amd64', + operatingsystemmajrelease: '8', + } + end context 'with ensure => absent' do let(:params) { { 'ensure' => 'absent' } } - it { should contain_exec('docker rmi base') } + + it { is_expected.to contain_exec('docker rmi base') } end context 'with ensure => absent and force => true' do let(:params) { { 'ensure' => 'absent', 'force' => true } } - it { should contain_exec('docker rmi -f base') } + + it { is_expected.to contain_exec('docker rmi -f base') } end context 'with ensure => absent and image_tag => precise' do let(:params) { { 'ensure' => 'absent', 'image_tag' => 'precise' } } - it { should contain_exec('docker rmi base:precise') } + + it { is_expected.to contain_exec('docker rmi base:precise') } end context 'with ensure => present' do let(:params) { { 'ensure' => 'present' } } - it { should contain_file('/usr/local/bin/update_docker_image.sh') } - it { should contain_exec('/usr/local/bin/update_docker_image.sh base') } + + it { is_expected.to contain_file('/usr/local/bin/update_docker_image.sh') } + it { is_expected.to contain_exec('/usr/local/bin/update_docker_image.sh base') } end context 'with docker_file => Dockerfile' do - let(:params) { { 'docker_file' => 'Dockerfile' }} - it { should contain_exec('docker build -t base - < Dockerfile') } + let(:params) { { 'docker_file' => 'Dockerfile' } } + + it { is_expected.to contain_exec('docker build -t base - < Dockerfile') } end context 'with ensure => present and docker_file => Dockerfile' do let(:params) { { 'ensure' => 'present', 'docker_file' => 'Dockerfile' } } - it { should contain_exec('docker build -t base - < Dockerfile') } + + it { is_expected.to contain_exec('docker build -t base - < Dockerfile') } end context 'with docker_dir => /tmp/docker_images/test1 and docker_file => /tmp/docker_images/test1/Dockerfile_altbuild' do - let(:params) { { 'docker_dir' => '/tmp/docker_images/test1', 'docker_file' => '/tmp/docker_images/test1/Dockerfile_altbuild' }} - it { should contain_exec('docker build -t base -f /tmp/docker_images/test1/Dockerfile_altbuild /tmp/docker_images/test1') } + let(:params) { { 'docker_dir' => '/tmp/docker_images/test1', 'docker_file' => '/tmp/docker_images/test1/Dockerfile_altbuild' } } + + it { is_expected.to contain_exec('docker build -t base -f /tmp/docker_images/test1/Dockerfile_altbuild /tmp/docker_images/test1') } end context 'with docker_dir => /tmp/docker_images/test1' do - let(:params) { { 'docker_dir' => '/tmp/docker_images/test1' }} - it { should contain_exec('docker build -t base /tmp/docker_images/test1') } + let(:params) { { 'docker_dir' => '/tmp/docker_images/test1' } } + + it { is_expected.to contain_exec('docker build -t base /tmp/docker_images/test1') } end context 'with ensure => present and docker_dir => /tmp/docker_images/test1' do let(:params) { { 'ensure' => 'present', 'docker_dir' => '/tmp/docker_images/test1' } } - it { should contain_exec('docker build -t base /tmp/docker_images/test1') } + + it { is_expected.to contain_exec('docker build -t base /tmp/docker_images/test1') } end context 'with ensure => present and image_tag => precise' do let(:params) { { 'ensure' => 'present', 'image_tag' => 'precise' } } - it { should contain_exec('/usr/local/bin/update_docker_image.sh base:precise') } + + it { is_expected.to contain_exec('/usr/local/bin/update_docker_image.sh base:precise') } end context 'with ensure => present and image_digest => sha256:deadbeef' do let(:params) { { 'ensure' => 'present', 'image_digest' => 'sha256:deadbeef' } } - it { should contain_exec('/usr/local/bin/update_docker_image.sh base@sha256:deadbeef') } + + it { is_expected.to contain_exec('/usr/local/bin/update_docker_image.sh base@sha256:deadbeef') } end context 'with ensure => present and image_tag => precise and docker_file => Dockerfile' do let(:params) { { 'ensure' => 'present', 'image_tag' => 'precise', 'docker_file' => 'Dockerfile' } } - it { should contain_exec('docker build -t base:precise - < Dockerfile') } + + it { is_expected.to contain_exec('docker build -t base:precise - < Dockerfile') } end context 'with ensure => present and image_tag => precise and docker_dir => /tmp/docker_images/test1' do let(:params) { { 'ensure' => 'present', 'image_tag' => 'precise', 'docker_dir' => '/tmp/docker_images/test1' } } - it { should contain_exec('docker build -t base:precise /tmp/docker_images/test1') } + + it { is_expected.to contain_exec('docker build -t base:precise /tmp/docker_images/test1') } end context 'with docker_tar => /tmp/docker_tars/test1.tar' do let(:params) { { 'docker_tar' => '/tmp/docker_tars/test1.tar' } } - it { should contain_exec('docker load -i /tmp/docker_tars/test1.tar') } + + it { is_expected.to contain_exec('docker load -i /tmp/docker_tars/test1.tar') } end context 'with ensure => present and docker_tar => /tmp/docker_tars/test1.tar' do let(:params) { { 'ensure' => 'present', 'docker_tar' => '/tmp/docker_tars/test1.tar' } } - it { should contain_exec('docker load -i /tmp/docker_tars/test1.tar') } + + it { is_expected.to contain_exec('docker load -i /tmp/docker_tars/test1.tar') } end context 'with docker_file => Dockerfile and docker_tar => /tmp/docker_tars/test1.tar' do - let(:params) { { 'docker_file' => 'Dockerfile', 'docker_tar' => '/tmp/docker_tars/test1.tar' }} + let(:params) { { 'docker_file' => 'Dockerfile', 'docker_tar' => '/tmp/docker_tars/test1.tar' } } + it do expect { - should have_exec_resource_count(1) + is_expected.to have_exec_resource_count(1) }.to raise_error(Puppet::Error) end end context 'with docker_tar => /tmp/docker_tars/test1.tar and docker_dir => /tmp/docker_images/test1' do - let(:params) { { 'docker_tar' => '/tmp/docker_tars/test1.tar', 'docker_dir' => '/tmp/docker_images/test1' }} + let(:params) { { 'docker_tar' => '/tmp/docker_tars/test1.tar', 'docker_dir' => '/tmp/docker_images/test1' } } + it do expect { - should have_exec_resource_count(1) + is_expected.to have_exec_resource_count(1) }.to raise_error(Puppet::Error) end end context 'with image_digest => sha256:deadbeef and docker_file => Dockerfile' do - let(:params) { { 'image_digest' => 'sha256:deadbeef', 'docker_file' => 'Dockerfile' }} + let(:params) { { 'image_digest' => 'sha256:deadbeef', 'docker_file' => 'Dockerfile' } } + it do expect { - should have_exec_resource_count(1) + is_expected.to have_exec_resource_count(1) }.to raise_error(Puppet::Error) end end context 'with image_digest => sha256:deadbeef and docker_dir => /tmp/docker_images/test1' do - let(:params) { { 'image_digest' => 'sha256:deadbeef', 'docker_dir' => '/tmp/docker_images/test1' }} + let(:params) { { 'image_digest' => 'sha256:deadbeef', 'docker_dir' => '/tmp/docker_images/test1' } } + it do expect { - should have_exec_resource_count(1) + is_expected.to have_exec_resource_count(1) }.to raise_error(Puppet::Error) end end context 'with image_digest => sha256:deadbeef and docker_tar => /tmp/docker_tars/test1.tar' do - let(:params) { { 'image_digest' => 'sha256:deadbeef', 'docker_tar' => '/tmp/docker_tars/test1.tar' }} + let(:params) { { 'image_digest' => 'sha256:deadbeef', 'docker_tar' => '/tmp/docker_tars/test1.tar' } } + it do expect { - should have_exec_resource_count(1) + is_expected.to have_exec_resource_count(1) }.to raise_error(Puppet::Error) end end context 'with ensure => latest' do let(:params) { { 'ensure' => 'latest' } } - it { should contain_exec("echo 'Update of base complete'").with_onlyif('/usr/local/bin/update_docker_image.sh base') } + + it { is_expected.to contain_exec("echo 'Update of base complete'").with_onlyif('/usr/local/bin/update_docker_image.sh base') } end context 'with ensure => latest and image_tag => precise' do let(:params) { { 'ensure' => 'latest', 'image_tag' => 'precise' } } - it { should contain_exec("echo 'Update of base:precise complete'") } + + it { is_expected.to contain_exec("echo 'Update of base:precise complete'") } end context 'with ensure => latest and image_digest => sha256:deadbeef' do let(:params) { { 'ensure' => 'latest', 'image_digest' => 'sha256:deadbeef' } } - it { should contain_exec("echo 'Update of base@sha256:deadbeef complete'") } + + it { is_expected.to contain_exec("echo 'Update of base@sha256:deadbeef complete'") } end context 'with an invalid image name' do let(:title) { 'with spaces' } + it do expect { - should contain_exec('/usr/local/bin/update_docker_image.sh with spaces') + is_expected.to contain_exec('/usr/local/bin/update_docker_image.sh with spaces') }.to raise_error(Puppet::Error) end end context 'with an invalid ensure value' do let(:params) { { 'ensure' => 'not present or absent' } } + it do expect { - should contain_exec('docker rmi base') + is_expected.to contain_exec('docker rmi base') }.to raise_error(Puppet::Error) end end end diff --git a/spec/defines/image_windows_spec.rb b/spec/defines/image_windows_spec.rb index 7bd3376..860fd0c 100644 --- a/spec/defines/image_windows_spec.rb +++ b/spec/defines/image_windows_spec.rb @@ -1,54 +1,63 @@ require 'spec_helper' -describe 'docker::image', :type => :define do +describe 'docker::image', type: :define do let(:title) { 'base' } - let(:facts) { { - :architecture => 'amd64', - :osfamily => 'windows', - :operatingsystem => 'windows', - :kernelrelease => '10.0.14393', - :operatingsystemrelease => '2016', - :operatingsystemmajrelease => '2016', - :docker_program_data_path => 'C:/ProgramData', - :docker_program_files_path => 'C:/Program Files', - :docker_systemroot => 'C:/Windows', - :docker_user_temp_path => 'C:/Users/Administrator/AppData/Local/Temp', - :os => { :family => 'windows', :name => 'windows', :release => { :major => '2016', :full => '2016' } } - } } + let(:facts) do + { + architecture: 'amd64', + osfamily: 'windows', + operatingsystem: 'windows', + kernelrelease: '10.0.14393', + operatingsystemrelease: '2016', + operatingsystemmajrelease: '2016', + docker_program_data_path: 'C:/ProgramData', + docker_program_files_path: 'C:/Program Files', + docker_systemroot: 'C:/Windows', + docker_user_temp_path: 'C:/Users/Administrator/AppData/Local/Temp', + os: { family: 'windows', name: 'windows', release: { major: '2016', full: '2016' } }, + } + end + context 'with ensure => present' do - let(:params) { { 'ensure' => 'present' } } - it { should contain_file('C:/Users/Administrator/AppData/Local/Temp/update_docker_image.ps1') } - it { should contain_exec('& C:/Users/Administrator/AppData/Local/Temp/update_docker_image.ps1 -DockerImage base') } + let(:params) { { 'ensure' => 'present' } } + + it { is_expected.to contain_file('C:/Users/Administrator/AppData/Local/Temp/update_docker_image.ps1') } + it { is_expected.to contain_exec('& C:/Users/Administrator/AppData/Local/Temp/update_docker_image.ps1 -DockerImage base') } end context 'with docker_file => Dockerfile' do - let(:params) { { 'docker_file' => 'Dockerfile' }} - it { should contain_exec('Get-Content Dockerfile -Raw | docker build -t base -') } - end - - context 'with ensure => present and docker_file => Dockerfile' do - let(:params) { { 'ensure' => 'present', 'docker_file' => 'Dockerfile' } } - it { should contain_exec('Get-Content Dockerfile -Raw | docker build -t base -') } - end - - context 'with ensure => present and image_tag => nanoserver' do - let(:params) { { 'ensure' => 'present', 'image_tag' => 'nanoserver' } } - it { should contain_exec('& C:/Users/Administrator/AppData/Local/Temp/update_docker_image.ps1 -DockerImage base:nanoserver') } - end - - context 'with ensure => present and image_digest => sha256:deadbeef' do - let(:params) { { 'ensure' => 'present', 'image_digest' => 'sha256:deadbeef' } } - it { should contain_exec('& C:/Users/Administrator/AppData/Local/Temp/update_docker_image.ps1 -DockerImage base@sha256:deadbeef') } - end - - context 'with ensure => present and image_tag => nanoserver and docker_file => Dockerfile' do - let(:params) { { 'ensure' => 'present', 'image_tag' => 'nanoserver', 'docker_file' => 'Dockerfile' } } - it { should contain_exec('Get-Content Dockerfile -Raw | docker build -t base:nanoserver -') } - end - - context 'with ensure => latest' do - let(:params) { { 'ensure' => 'latest' } } - it { should contain_exec("echo 'Update of base complete'").with_onlyif('& C:/Users/Administrator/AppData/Local/Temp/update_docker_image.ps1 -DockerImage base') } - end - -end \ No newline at end of file + let(:params) { { 'docker_file' => 'Dockerfile' } } + + it { is_expected.to contain_exec('Get-Content Dockerfile -Raw | docker build -t base -') } + end + + context 'with ensure => present and docker_file => Dockerfile' do + let(:params) { { 'ensure' => 'present', 'docker_file' => 'Dockerfile' } } + + it { is_expected.to contain_exec('Get-Content Dockerfile -Raw | docker build -t base -') } + end + + context 'with ensure => present and image_tag => nanoserver' do + let(:params) { { 'ensure' => 'present', 'image_tag' => 'nanoserver' } } + + it { is_expected.to contain_exec('& C:/Users/Administrator/AppData/Local/Temp/update_docker_image.ps1 -DockerImage base:nanoserver') } + end + + context 'with ensure => present and image_digest => sha256:deadbeef' do + let(:params) { { 'ensure' => 'present', 'image_digest' => 'sha256:deadbeef' } } + + it { is_expected.to contain_exec('& C:/Users/Administrator/AppData/Local/Temp/update_docker_image.ps1 -DockerImage base@sha256:deadbeef') } + end + + context 'with ensure => present and image_tag => nanoserver and docker_file => Dockerfile' do + let(:params) { { 'ensure' => 'present', 'image_tag' => 'nanoserver', 'docker_file' => 'Dockerfile' } } + + it { is_expected.to contain_exec('Get-Content Dockerfile -Raw | docker build -t base:nanoserver -') } + end + + context 'with ensure => latest' do + let(:params) { { 'ensure' => 'latest' } } + + it { is_expected.to contain_exec("echo 'Update of base complete'").with_onlyif('& C:/Users/Administrator/AppData/Local/Temp/update_docker_image.ps1 -DockerImage base') } + end +end diff --git a/spec/defines/plugin_spec.rb b/spec/defines/plugin_spec.rb index c887cc6..a5b673b 100644 --- a/spec/defines/plugin_spec.rb +++ b/spec/defines/plugin_spec.rb @@ -1,30 +1,34 @@ require 'spec_helper' -describe 'docker::plugin', :type => :define do +describe 'docker::plugin', type: :define do let(:title) { 'foo/plugin:latest' } - let(:facts) { { - :osfamily => 'Debian', - :operatingsystem => 'Debian', - :lsbdistid => 'Debian', - :lsbdistcodename => 'jessie', - :kernelrelease => '3.2.0-4-amd64', - :operatingsystemmajrelease => '8', - } } + let(:facts) do + { + osfamily: 'Debian', + operatingsystem: 'Debian', + lsbdistid: 'Debian', + lsbdistcodename: 'jessie', + kernelrelease: '3.2.0-4-amd64', + operatingsystemmajrelease: '8', + } + end context 'with defaults for all parameters' do it { is_expected.to compile.with_all_deps } - it { should contain_exec('plugin install foo/plugin:latest').with_command(/docker plugin install/) } + it { is_expected.to contain_exec('plugin install foo/plugin:latest').with_command(%r{docker plugin install}) } end context 'with enabled => false' do - let(:params) { { 'enabled' => false, } } + let(:params) { { 'enabled' => false } } + it { is_expected.to compile.with_all_deps } - it { should contain_exec("disable foo/plugin:latest").with_command(/docker plugin disable/) } + it { is_expected.to contain_exec('disable foo/plugin:latest').with_command(%r{docker plugin disable}) } end context 'with ensure => absent' do - let(:params) { { 'ensure' => 'absent'} } + let(:params) { { 'ensure' => 'absent' } } + it { is_expected.to compile.with_all_deps } - it { should contain_exec('plugin remove foo/plugin:latest').with_command(/docker plugin rm/) } + it { is_expected.to contain_exec('plugin remove foo/plugin:latest').with_command(%r{docker plugin rm}) } end end diff --git a/spec/defines/registry_spec.rb b/spec/defines/registry_spec.rb index 35bd543..420702d 100644 --- a/spec/defines/registry_spec.rb +++ b/spec/defines/registry_spec.rb @@ -1,69 +1,82 @@ require 'spec_helper' -describe 'docker::registry', :type => :define do +describe 'docker::registry', type: :define do let(:title) { 'localhost:5000' } - let(:facts) { { - :osfamily => 'Debian', - :operatingsystem => 'Debian', - :lsbdistid => 'Debian', - :lsbdistcodename => 'jessie', - :kernelrelease => '3.2.0-4-amd64', - :operatingsystemmajrelease => '8', - } } + let(:facts) do + { + osfamily: 'Debian', + operatingsystem: 'Debian', + lsbdistid: 'Debian', + lsbdistcodename: 'jessie', + kernelrelease: '3.2.0-4-amd64', + operatingsystemmajrelease: '8', + } + end let(:params) { { 'version' => '17.06', 'pass_hash' => 'test1234', 'receipt' => false } } - it { should contain_exec('localhost:5000 auth') } + + it { is_expected.to contain_exec('localhost:5000 auth') } context 'with ensure => present' do let(:params) { { 'ensure' => 'absent', 'version' => '17.06', 'pass_hash' => 'test1234', 'receipt' => false } } - it { should contain_exec('localhost:5000 auth').with_command('docker logout localhost:5000') } + + it { is_expected.to contain_exec('localhost:5000 auth').with_command('docker logout localhost:5000') } end context 'with ensure => present' do let(:params) { { 'ensure' => 'present', 'version' => '17.06', 'pass_hash' => 'test1234', 'receipt' => false } } - it { should contain_exec('localhost:5000 auth').with_command('docker login localhost:5000') } + + it { is_expected.to contain_exec('localhost:5000 auth').with_command('docker login localhost:5000') } end context 'with ensure => present and username => user1' do let(:params) { { 'ensure' => 'present', 'username' => 'user1', 'version' => '17.06', 'pass_hash' => 'test1234', 'receipt' => false } } - it { should contain_exec('localhost:5000 auth').with_command('docker login localhost:5000') } + + it { is_expected.to contain_exec('localhost:5000 auth').with_command('docker login localhost:5000') } end context 'with ensure => present and password => secret' do let(:params) { { 'ensure' => 'present', 'password' => 'secret', 'version' => '17.06', 'pass_hash' => 'test1234', 'receipt' => false } } - it { should contain_exec('localhost:5000 auth').with_command('docker login localhost:5000') } + + it { is_expected.to contain_exec('localhost:5000 auth').with_command('docker login localhost:5000') } end context 'with ensure => present and email => user1@example.io' do let(:params) { { 'ensure' => 'present', 'email' => 'user1@example.io', 'version' => '17.06', 'pass_hash' => 'test1234', 'receipt' => false } } - it { should contain_exec('localhost:5000 auth').with_command('docker login localhost:5000') } + + it { is_expected.to contain_exec('localhost:5000 auth').with_command('docker login localhost:5000') } end context 'with ensure => present and username => user1, and password => secret and email => user1@example.io' do let(:params) { { 'ensure' => 'present', 'username' => 'user1', 'password' => 'secret', 'email' => 'user1@example.io', 'version' => '17.06', 'pass_hash' => 'test1234', 'receipt' => false } } - it { should contain_exec('localhost:5000 auth').with_command("docker login -u 'user1' -p \"${password}\" localhost:5000").with_environment(/password=secret/) } + + it { is_expected.to contain_exec('localhost:5000 auth').with_command("docker login -u 'user1' -p \"${password}\" localhost:5000").with_environment(%r{password=secret}) } end - context 'with ensure => present and username => user1, and password => secret and email => user1@example.io and version < 1.11.0' do + context 'with ensure => present and username => user1, and password => secret and email => user1@example.io and version < 1.11.0' do let(:params) { { 'ensure' => 'present', 'username' => 'user1', 'password' => 'secret', 'email' => 'user1@example.io', 'version' => '1.9.0', 'pass_hash' => 'test1234', 'receipt' => false } } - it { should contain_exec('localhost:5000 auth').with_command("docker login -u 'user1' -p \"${password}\" -e 'user1@example.io' localhost:5000").with_environment(/password=secret/) } + + it { is_expected.to contain_exec('localhost:5000 auth').with_command("docker login -u 'user1' -p \"${password}\" -e 'user1@example.io' localhost:5000").with_environment(%r{password=secret}) } end context 'with username => user1, and password => secret' do let(:params) { { 'username' => 'user1', 'password' => 'secret', 'version' => '17.06', 'pass_hash' => 'test1234', 'receipt' => false } } - it { should contain_exec('localhost:5000 auth').with_command("docker login -u 'user1' -p \"${password}\" localhost:5000").with_environment(/password=secret/) } + + it { is_expected.to contain_exec('localhost:5000 auth').with_command("docker login -u 'user1' -p \"${password}\" localhost:5000").with_environment(%r{password=secret}) } end context 'with username => user1, and password => secret and local_user => testuser' do let(:params) { { 'username' => 'user1', 'password' => 'secret', 'local_user' => 'testuser', 'version' => '17.06', 'pass_hash' => 'test1234', 'receipt' => false } } - it { should contain_exec('localhost:5000 auth').with_command("docker login -u 'user1' -p \"${password}\" localhost:5000").with_user('testuser').with_environment(/password=secret/) } + + it { is_expected.to contain_exec('localhost:5000 auth').with_command("docker login -u 'user1' -p \"${password}\" localhost:5000").with_user('testuser').with_environment(%r{password=secret}) } end context 'with an invalid ensure value' do let(:params) { { 'ensure' => 'not present or absent' } } + it do expect { - should contain_exec('docker logout localhost:5000') + is_expected.to contain_exec('docker logout localhost:5000') }.to raise_error(Puppet::Error) end end end diff --git a/spec/defines/run_spec.rb b/spec/defines/run_spec.rb index e2398bf..6572640 100755 --- a/spec/defines/run_spec.rb +++ b/spec/defines/run_spec.rb @@ -1,685 +1,773 @@ require 'spec_helper' ['Debian', 'RedHat', 'generic systemd'].each do |osfamily| - describe 'docker::run', :type => :define do + describe 'docker::run', type: :define do let(:title) { 'sample' } - params = {'command' => 'command', 'image' => 'base'} + params = { 'command' => 'command', 'image' => 'base' } context "on #{osfamily}" do - initscript = '/etc/systemd/system/docker-sample.service' - startscript = "/usr/local/bin/docker-run-sample-start.sh" - stopscript = "/usr/local/bin/docker-run-sample-stop.sh" + startscript = '/usr/local/bin/docker-run-sample-start.sh' + stopscript = '/usr/local/bin/docker-run-sample-stop.sh' if osfamily == 'Debian' pre_condition = "class { 'docker': docker_group => 'docker', service_name => 'docker' }" let(:pre_condition) { pre_condition } - let(:facts) { { - :architecture => 'amd64', - :osfamily => 'Debian', - :operatingsystem => 'Ubuntu', - :lsbdistid => 'Ubuntu', - :lsbdistcodename => 'xenial', - :kernelrelease => '4.4.0-21-generic', - :operatingsystemrelease => '16.04', - :operatingsystemmajrelease => '16.04', - :os => { :distro => { :codename => 'wheezy' }, :family => 'Debian', :name => 'Debian', :release => { :major => '7', :full => '7.0' } } - } } + let(:facts) do + { + architecture: 'amd64', + osfamily: 'Debian', + operatingsystem: 'Ubuntu', + lsbdistid: 'Ubuntu', + lsbdistcodename: 'xenial', + kernelrelease: '4.4.0-21-generic', + operatingsystemrelease: '16.04', + operatingsystemmajrelease: '16.04', + os: { distro: { codename: 'wheezy' }, family: 'Debian', name: 'Debian', release: { major: '7', full: '7.0' } }, + } + end + systemd = true elsif osfamily == 'RedHat' pre_condition = "class { 'docker': docker_group => 'docker', service_name => 'docker' }" let(:pre_condition) { pre_condition } - let(:facts) { { - :architecture => 'x86_64', - :osfamily => osfamily, - :operatingsystem => 'RedHat', - :lsbdistcodename => 'xenial', - :operatingsystemrelease => '7.2', - :operatingsystemmajrelease => '7', - :kernelversion => '3.10.0', - :os => { :distro => { :codename => 'wheezy' }, :family => osfamily, :name => osfamily, :release => { :major => '7', :full => '7.0' } } - } } + let(:facts) do + { + architecture: 'x86_64', + osfamily: osfamily, + operatingsystem: 'RedHat', + lsbdistcodename: 'xenial', + operatingsystemrelease: '7.2', + operatingsystemmajrelease: '7', + kernelversion: '3.10.0', + os: { distro: { codename: 'wheezy' }, family: osfamily, name: osfamily, release: { major: '7', full: '7.0' } }, + } + end + systemd = true elsif osfamily == 'generic systemd' pre_condition = "class { 'docker': docker_group => 'docker', service_name => 'docker', service_provider => systemd, acknowledge_unsupported_os => true }" let(:pre_condition) { pre_condition } - let(:facts) { { - :osfamily => 'Gentoo', - :operatingsystem => 'Generic', - } } - params.merge!({'service_provider' => 'systemd'}) + let(:facts) do + { + osfamily: 'Gentoo', + operatingsystem: 'Generic', + } + end + + params['service_provider'] = 'systemd' systemd = true end startscript_or_init = systemd ? startscript : initscript stopscript_or_init = systemd ? stopscript : initscript context 'passing the required params' do let(:params) { params } - it { should compile.with_all_deps } - it { should contain_service('docker-sample') } - it { should contain_file(initscript).with_content(/#{Regexp.escape(startscript)}/).with_mode('0644') } - it { should contain_file(initscript).with_content(/#{Regexp.escape(stopscript)}/) } - it { should contain_file(startscript_or_init).with_content(/docker start/).with_content(/command/).with_content(/base/)} + + it { is_expected.to compile.with_all_deps } + it { is_expected.to contain_service('docker-sample') } + it { is_expected.to contain_file(initscript).with_content(%r{#{Regexp.escape(startscript)}}).with_mode('0644') } + it { is_expected.to contain_file(initscript).with_content(%r{#{Regexp.escape(stopscript)}}) } + it { is_expected.to contain_file(startscript_or_init).with_content(%r{docker start}).with_content(%r{command}).with_content(%r{base}) } if systemd - it { should contain_file(initscript).with_content(/^SyslogIdentifier=docker-sample$/) } + it { is_expected.to contain_file(initscript).with_content(%r{^SyslogIdentifier=docker-sample$}) } end - end context 'when passing `after` containers' do - let(:params) { params.merge({'after' => ['foo', 'bar', 'foo_bar/baz']}) } - if (systemd) - it { should contain_file(initscript).with_content(/After=(.*\s+)?docker-foo.service/) } - it { should contain_file(initscript).with_content(/After=(.*\s+)?docker-bar.service/) } - it { should contain_file(initscript).with_content(/After=(.*\s+)?docker-foo_bar-baz.service/) } - it { should contain_file(initscript).with_content(/Wants=(.*\s+)?docker-foo.service/) } - it { should contain_file(initscript).with_content(/Wants=(.*\s+)?docker-bar.service/) } - it { should contain_file(initscript).with_content(/Wants=(.*\s+)?docker-foo_bar-baz.service/) } + let(:params) { params.merge('after' => ['foo', 'bar', 'foo_bar/baz']) } + + if systemd + it { is_expected.to contain_file(initscript).with_content(%r{After=(.*\s+)?docker-foo.service}) } + it { is_expected.to contain_file(initscript).with_content(%r{After=(.*\s+)?docker-bar.service}) } + it { is_expected.to contain_file(initscript).with_content(%r{After=(.*\s+)?docker-foo_bar-baz.service}) } + it { is_expected.to contain_file(initscript).with_content(%r{Wants=(.*\s+)?docker-foo.service}) } + it { is_expected.to contain_file(initscript).with_content(%r{Wants=(.*\s+)?docker-bar.service}) } + it { is_expected.to contain_file(initscript).with_content(%r{Wants=(.*\s+)?docker-foo_bar-baz.service}) } else - it { should contain_file(initscript).with_content(/Required-Start:.*\s+docker-foo/) } - it { should contain_file(initscript).with_content(/Required-Start:.*\s+docker-bar/) } - it { should contain_file(initscript).with_content(/Required-Start:.*\s+docker-foo_bar-baz/) } + it { is_expected.to contain_file(initscript).with_content(%r{Required-Start:.*\s+docker-foo}) } + it { is_expected.to contain_file(initscript).with_content(%r{Required-Start:.*\s+docker-bar}) } + it { is_expected.to contain_file(initscript).with_content(%r{Required-Start:.*\s+docker-foo_bar-baz}) } end end context 'when passing `depends` containers' do - let(:params) { params.merge({'depends' => ['foo', 'bar', 'foo_bar/baz']}) } - if (systemd) - it { should contain_file(initscript).with_content(/After=(.*\s+)?docker-foo.service/) } - it { should contain_file(initscript).with_content(/After=(.*\s+)?docker-bar.service/) } - it { should contain_file(initscript).with_content(/After=(.*\s+)?docker-foo_bar-baz.service/) } - it { should contain_file(initscript).with_content(/Requires=(.*\s+)?docker-foo.service/) } - it { should contain_file(initscript).with_content(/Requires=(.*\s+)?docker-bar.service/) } - it { should contain_file(initscript).with_content(/Requires=(.*\s+)?docker-foo_bar-baz.service/) } + let(:params) { params.merge('depends' => ['foo', 'bar', 'foo_bar/baz']) } + + if systemd + it { is_expected.to contain_file(initscript).with_content(%r{After=(.*\s+)?docker-foo.service}) } + it { is_expected.to contain_file(initscript).with_content(%r{After=(.*\s+)?docker-bar.service}) } + it { is_expected.to contain_file(initscript).with_content(%r{After=(.*\s+)?docker-foo_bar-baz.service}) } + it { is_expected.to contain_file(initscript).with_content(%r{Requires=(.*\s+)?docker-foo.service}) } + it { is_expected.to contain_file(initscript).with_content(%r{Requires=(.*\s+)?docker-bar.service}) } + it { is_expected.to contain_file(initscript).with_content(%r{Requires=(.*\s+)?docker-foo_bar-baz.service}) } else - it { should contain_file(initscript).with_content(/Required-Start:.*\s+docker-foo/) } - it { should contain_file(initscript).with_content(/Required-Start:.*\s+docker-bar/) } - it { should contain_file(initscript).with_content(/Required-Start:.*\s+docker-foo_bar-baz/) } - it { should contain_file(initscript).with_content(/Required-Stop:.*\s+docker-foo/) } - it { should contain_file(initscript).with_content(/Required-Stop:.*\s+docker-bar/) } - it { should contain_file(initscript).with_content(/Required-Stop:.*\s+docker-foo_bar-baz/) } + it { is_expected.to contain_file(initscript).with_content(%r{Required-Start:.*\s+docker-foo}) } + it { is_expected.to contain_file(initscript).with_content(%r{Required-Start:.*\s+docker-bar}) } + it { is_expected.to contain_file(initscript).with_content(%r{Required-Start:.*\s+docker-foo_bar-baz}) } + it { is_expected.to contain_file(initscript).with_content(%r{Required-Stop:.*\s+docker-foo}) } + it { is_expected.to contain_file(initscript).with_content(%r{Required-Stop:.*\s+docker-bar}) } + it { is_expected.to contain_file(initscript).with_content(%r{Required-Stop:.*\s+docker-foo_bar-baz}) } end end context 'when passing `depend_services`' do - let(:params) { params.merge({'depend_services' => ['foo', 'bar']}) } - if (systemd) - it { should contain_file(initscript).with_content(/After=(.*\s+)?foo.service/) } - it { should contain_file(initscript).with_content(/After=(.*\s+)?bar.service/) } - it { should contain_file(initscript).with_content(/Requires=(.*\s+)?foo.service/) } - it { should contain_file(initscript).with_content(/Requires=(.*\s+)?bar.service/) } + let(:params) { params.merge('depend_services' => ['foo', 'bar']) } + + if systemd + it { is_expected.to contain_file(initscript).with_content(%r{After=(.*\s+)?foo.service}) } + it { is_expected.to contain_file(initscript).with_content(%r{After=(.*\s+)?bar.service}) } + it { is_expected.to contain_file(initscript).with_content(%r{Requires=(.*\s+)?foo.service}) } + it { is_expected.to contain_file(initscript).with_content(%r{Requires=(.*\s+)?bar.service}) } context 'with full systemd unit names' do - let(:params) { params.merge({'depend_services' => ['foo', 'bar.service', 'baz.target']}) } - it { should contain_file(initscript).with_content(/After=(.*\s+)?foo.service(\s+|$)/) } - it { should contain_file(initscript).with_content(/After=(.*\s+)?bar.service(\s+|$)/) } - it { should contain_file(initscript).with_content(/After=(.*\s+)?baz.target(\s+|$)/) } - it { should contain_file(initscript).with_content(/Requires=(.*\s+)?foo.service(\s+|$)/) } - it { should contain_file(initscript).with_content(/Requires=(.*\s+)?bar.service(\s+|$)/) } - it { should contain_file(initscript).with_content(/Requires=(.*\s+)?baz.target(\s+|$)/) } + let(:params) { params.merge('depend_services' => ['foo', 'bar.service', 'baz.target']) } + + it { is_expected.to contain_file(initscript).with_content(%r{After=(.*\s+)?foo.service(\s+|$)}) } + it { is_expected.to contain_file(initscript).with_content(%r{After=(.*\s+)?bar.service(\s+|$)}) } + it { is_expected.to contain_file(initscript).with_content(%r{After=(.*\s+)?baz.target(\s+|$)}) } + it { is_expected.to contain_file(initscript).with_content(%r{Requires=(.*\s+)?foo.service(\s+|$)}) } + it { is_expected.to contain_file(initscript).with_content(%r{Requires=(.*\s+)?bar.service(\s+|$)}) } + it { is_expected.to contain_file(initscript).with_content(%r{Requires=(.*\s+)?baz.target(\s+|$)}) } end else - it { should contain_file(initscript).with_content(/Required-Start:.*\s+foo/) } - it { should contain_file(initscript).with_content(/Required-Start:.*\s+bar/) } - it { should contain_file(initscript).with_content(/Required-Stop:.*\s+foo/) } - it { should contain_file(initscript).with_content(/Required-Stop:.*\s+bar/) } + it { is_expected.to contain_file(initscript).with_content(%r{Required-Start:.*\s+foo}) } + it { is_expected.to contain_file(initscript).with_content(%r{Required-Start:.*\s+bar}) } + it { is_expected.to contain_file(initscript).with_content(%r{Required-Stop:.*\s+foo}) } + it { is_expected.to contain_file(initscript).with_content(%r{Required-Stop:.*\s+bar}) } end end context 'removing containers and volumes' do context 'when trying to remove the volume and not the container on stop' do - let(:params) { params.merge({ - 'remove_container_on_stop' => false, - 'remove_volume_on_stop' => true, - }) } + let(:params) do + params.merge('remove_container_on_stop' => false, + 'remove_volume_on_stop' => true) + end + it do expect { - should contain_service('docker-sample') + is_expected.to contain_service('docker-sample') }.to raise_error(Puppet::Error) end end context 'when trying to remove the volume and not the container on start' do - let(:params) { params.merge({ - 'remove_container_on_start' => false, - 'remove_volume_on_start' => true, - }) } + let(:params) do + params.merge('remove_container_on_start' => false, + 'remove_volume_on_start' => true) + end + it do expect { - should contain_service('docker-sample') + is_expected.to contain_service('docker-sample') }.to raise_error(Puppet::Error) end end context 'When restarting an unhealthy container' do - let(:params) { params.merge({ - 'health_check_cmd' => 'pwd', - 'restart_on_unhealthy' => true, - 'health_check_interval' => 60, - }) } - if (systemd) - it { should contain_file(stopscript).with_content(/\/usr\/bin\/docker stop --time=0 /).with_content(/\/usr\/bin\/docker rm/) } - it { should contain_file(startscript).with_content(/--health-cmd/) } - end + let(:params) do + params.merge('health_check_cmd' => 'pwd', + 'restart_on_unhealthy' => true, + 'health_check_interval' => 60) + end + + if systemd + it { is_expected.to contain_file(stopscript).with_content(%r{\/usr\/bin\/docker stop --time=0 }).with_content(%r{\/usr\/bin\/docker rm}) } + it { is_expected.to contain_file(startscript).with_content(%r{--health-cmd}) } + end end context 'when not removing containers on container start and stop' do - let(:params) { params.merge({ - 'remove_container_on_start' => false, - 'remove_container_on_stop' => false, - }) } - it { should_not contain_file(startscript_or_init).with_content(/\/usr\/bin\/docker rm sample/) } + let(:params) do + params.merge('remove_container_on_start' => false, + 'remove_container_on_stop' => false) + end + + it { is_expected.not_to contain_file(startscript_or_init).with_content(%r{\/usr\/bin\/docker rm sample}) } end context 'when removing containers on container start' do - let(:params) { params.merge({'remove_container_on_start' => true}) } - it { should contain_file(startscript_or_init).with_content(/\/usr\/bin\/docker rm sample/) } + let(:params) { params.merge('remove_container_on_start' => true) } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{\/usr\/bin\/docker rm sample}) } end context 'when removing containers on container stop' do - let(:params) { params.merge({'remove_container_on_stop' => true}) } - it { should contain_file(stopscript_or_init).with_content(/\/usr\/bin\/docker rm sample/) } + let(:params) { params.merge('remove_container_on_stop' => true) } + + it { is_expected.to contain_file(stopscript_or_init).with_content(%r{\/usr\/bin\/docker rm sample}) } end context 'when not removing volumes on container start' do - let(:params) { params.merge({'remove_volume_on_start' => false}) } - it { should_not contain_file(startscript_or_init).with_content(/\/usr\/bin\/docker rm -v sample/) } + let(:params) { params.merge('remove_volume_on_start' => false) } + + it { is_expected.not_to contain_file(startscript_or_init).with_content(%r{\/usr\/bin\/docker rm -v sample}) } end context 'when removing volumes on container start' do - let(:params) { params.merge({'remove_volume_on_start' => true}) } - it { should contain_file(startscript_or_init).with_content(/\/usr\/bin\/docker rm -v/) } + let(:params) { params.merge('remove_volume_on_start' => true) } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{\/usr\/bin\/docker rm -v}) } end context 'when not removing volumes on container stop' do - let(:params) { params.merge({'remove_volume_on_stop' => false}) } - it { should_not contain_file(stopscript_or_init).with_content(/\/usr\/bin\/docker rm -v sample/) } + let(:params) { params.merge('remove_volume_on_stop' => false) } + + it { is_expected.not_to contain_file(stopscript_or_init).with_content(%r{\/usr\/bin\/docker rm -v sample}) } end context 'when removing volumes on container stop' do - let(:params) { params.merge({'remove_volume_on_stop' => true}) } - it { should contain_file(stopscript_or_init).with_content(/\/usr\/bin\/docker rm -v/) } + let(:params) { params.merge('remove_volume_on_stop' => true) } + + it { is_expected.to contain_file(stopscript_or_init).with_content(%r{\/usr\/bin\/docker rm -v}) } end end context 'with autorestart functionality' do let(:params) { params } - if (systemd) - it { should contain_file(initscript).with_content(/Restart=on-failure/) } + + if systemd + it { is_expected.to contain_file(initscript).with_content(%r{Restart=on-failure}) } end end context 'when lxc_conf disables swap' do - let(:params) { params.merge({'lxc_conf' => 'lxc.cgroup.memory.memsw.limit_in_bytes=536870912'}) } - it { should contain_file(startscript_or_init).with_content(/-lxc-conf=\"lxc.cgroup.memory.memsw.limit_in_bytes=536870912\"/) } + let(:params) { params.merge('lxc_conf' => 'lxc.cgroup.memory.memsw.limit_in_bytes=536870912') } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{-lxc-conf=\"lxc.cgroup.memory.memsw.limit_in_bytes=536870912\"}) } end context 'when `use_name` is true' do - let(:params) { params.merge({'use_name' => true }) } - it { should contain_file(startscript_or_init).with_content(/--name sample /) } + let(:params) { params.merge('use_name' => true) } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{--name sample }) } end context 'when stopping the service' do - let(:params) { params.merge({'running' => false}) } - it { should contain_service('docker-sample').with_ensure(false) } + let(:params) { params.merge('running' => false) } + + it { is_expected.to contain_service('docker-sample').with_ensure(false) } end context 'when passing a memory limit in bytes' do - let(:params) { params.merge({'memory_limit' => '1000b'}) } - it { should contain_file(startscript_or_init).with_content(/-m 1000b/) } + let(:params) { params.merge('memory_limit' => '1000b') } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{-m 1000b}) } end context 'when passing a cpuset' do - let(:params) { params.merge({'cpuset' => '3'}) } - it { should contain_file(startscript_or_init).with_content(/--cpuset-cpus=3/) } + let(:params) { params.merge('cpuset' => '3') } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{--cpuset-cpus=3}) } end context 'when passing a multiple cpu cpuset' do - let(:params) { params.merge({'cpuset' => ['0', '3']}) } - it { should contain_file(startscript_or_init).with_content(/--cpuset-cpus=0,3/) } + let(:params) { params.merge('cpuset' => ['0', '3']) } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{--cpuset-cpus=0,3}) } end context 'when not passing a cpuset' do let(:params) { params } - it { should contain_file(startscript_or_init).without_content(/--cpuset-cpus=/) } + + it { is_expected.to contain_file(startscript_or_init).without_content(%r{--cpuset-cpus=}) } end context 'when passing a links option' do - let(:params) { params.merge({'links' => ['example:one', 'example:two']}) } - it { should contain_file(startscript_or_init).with_content(/--link example:one/).with_content(/--link example:two/) } + let(:params) { params.merge('links' => ['example:one', 'example:two']) } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{--link example:one}).with_content(%r{--link example:two}) } end context 'when passing a hostname' do - let(:params) { params.merge({'hostname' => 'example.com'}) } - it { should contain_file(startscript_or_init).with_content(/-h 'example.com'/) } + let(:params) { params.merge('hostname' => 'example.com') } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{-h 'example.com'}) } end context 'when not passing a hostname' do let(:params) { params } - it { should contain_file(startscript_or_init).without_content(/-h ''/) } + + it { is_expected.to contain_file(startscript_or_init).without_content(%r{-h ''}) } end context 'when passing a username' do - let(:params) { params.merge({'username' => 'bob'}) } - it { should contain_file(startscript_or_init).with_content(/-u 'bob'/) } + let(:params) { params.merge('username' => 'bob') } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{-u 'bob'}) } end context 'when not passing a username' do let(:params) { params } - it { should contain_file(startscript_or_init).without_content(/-u ''/) } + + it { is_expected.to contain_file(startscript_or_init).without_content(%r{-u ''}) } end context 'when passing a port number' do - let(:params) { params.merge({'ports' => '4444'}) } - it { should contain_file(startscript_or_init).with_content(/-p 4444/) } + let(:params) { params.merge('ports' => '4444') } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{-p 4444}) } end context 'when passing a port to expose' do - let(:params) { params.merge({'expose' => '4666'}) } - it { should contain_file(startscript_or_init).with_content(/--expose=4666/) } + let(:params) { params.merge('expose' => '4666') } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{--expose=4666}) } end context 'when passing a label' do - let(:params) { params.merge({'labels' => 'key=value'}) } - it { should contain_file(startscript_or_init).with_content(/-l key=value/) } + let(:params) { params.merge('labels' => 'key=value') } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{-l key=value}) } end context 'when passing a hostentry' do - let(:params) { params.merge({'hostentries' => 'dummyhost:127.0.0.2'}) } - it { should contain_file(startscript_or_init).with_content(/--add-host dummyhost:127.0.0.2/) } + let(:params) { params.merge('hostentries' => 'dummyhost:127.0.0.2') } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{--add-host dummyhost:127.0.0.2}) } end context 'when connecting to shared data volumes' do - let(:params) { params.merge({'volumes_from' => '6446ea52fbc9'}) } - it { should contain_file(startscript_or_init).with_content(/--volumes-from 6446ea52fbc9/) } + let(:params) { params.merge('volumes_from' => '6446ea52fbc9') } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{--volumes-from 6446ea52fbc9}) } end context 'when connecting to several shared data volumes' do - let(:params) { params.merge({'volumes_from' => ['sample-linked-container-1', 'sample-linked-container-2']}) } - it { should contain_file(startscript_or_init).with_content(/--volumes-from sample-linked-container-1/) } - it { should contain_file(startscript_or_init).with_content(/--volumes-from sample-linked-container-2/) } + let(:params) { params.merge('volumes_from' => ['sample-linked-container-1', 'sample-linked-container-2']) } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{--volumes-from sample-linked-container-1}) } + it { is_expected.to contain_file(startscript_or_init).with_content(%r{--volumes-from sample-linked-container-2}) } end context 'when passing several port numbers' do - let(:params) { params.merge({'ports' => ['4444', '4555']}) } - it { should contain_file(startscript_or_init).with_content(/-p 4444/).with_content(/-p 4555/) } + let(:params) { params.merge('ports' => ['4444', '4555']) } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{-p 4444}).with_content(%r{-p 4555}) } end context 'when passing several labels' do - let(:params) { params.merge({'labels' => ['key1=value1', 'key2=value2']}) } - it { should contain_file(startscript_or_init).with_content(/-l key1=value1/).with_content(/-l key2=value2/) } + let(:params) { params.merge('labels' => ['key1=value1', 'key2=value2']) } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{-l key1=value1}).with_content(%r{-l key2=value2}) } end context 'when passing several ports to expose' do - let(:params) { params.merge({'expose' => ['4666', '4777']}) } - it { should contain_file(startscript_or_init).with_content(/--expose=4666/).with_content(/--expose=4777/) } + let(:params) { params.merge('expose' => ['4666', '4777']) } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{--expose=4666}).with_content(%r{--expose=4777}) } end context 'when passing serveral environment variables' do - let(:params) { params.merge({'env' => ['FOO=BAR', 'FOO2=BAR2']}) } - it { should contain_file(startscript_or_init).with_content(/-e "FOO=BAR"/).with_content(/-e "FOO2=BAR2"/) } + let(:params) { params.merge('env' => ['FOO=BAR', 'FOO2=BAR2']) } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{-e "FOO=BAR"}).with_content(%r{-e "FOO2=BAR2"}) } end context 'when passing an environment variable' do - let(:params) { params.merge({'env' => 'FOO=BAR'}) } - it { should contain_file(startscript_or_init).with_content(/-e "FOO=BAR"/) } + let(:params) { params.merge('env' => 'FOO=BAR') } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{-e "FOO=BAR"}) } end context 'when passing serveral environment files' do - let(:params) { params.merge({'env_file' => ['/etc/foo.env', '/etc/bar.env']}) } - it { should contain_file(startscript_or_init).with_content(/--env-file \/etc\/foo.env/).with_content(/--env-file \/etc\/bar.env/) } + let(:params) { params.merge('env_file' => ['/etc/foo.env', '/etc/bar.env']) } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{--env-file \/etc\/foo.env}).with_content(%r{--env-file \/etc\/bar.env}) } end context 'when passing an environment file' do - let(:params) { params.merge({'env_file' => '/etc/foo.env'}) } - it { should contain_file(startscript_or_init).with_content(/--env-file \/etc\/foo.env/) } + let(:params) { params.merge('env_file' => '/etc/foo.env') } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{--env-file \/etc\/foo.env}) } end context 'when passing serveral dns addresses' do - let(:params) { params.merge({'dns' => ['8.8.8.8', '8.8.4.4']}) } - it { should contain_file(startscript_or_init).with_content(/--dns 8.8.8.8/).with_content(/--dns 8.8.4.4/) } + let(:params) { params.merge('dns' => ['8.8.8.8', '8.8.4.4']) } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{--dns 8.8.8.8}).with_content(%r{--dns 8.8.4.4}) } end context 'when passing a dns address' do - let(:params) { params.merge({'dns' => '8.8.8.8'}) } - it { should contain_file(startscript_or_init).with_content(/--dns 8.8.8.8/) } + let(:params) { params.merge('dns' => '8.8.8.8') } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{--dns 8.8.8.8}) } end context 'when passing serveral sockets to connect to' do - let(:params) { params.merge({'socket_connect' => ['tcp://127.0.0.1:4567', 'tcp://127.0.0.2:4567']}) } - it { should contain_file(startscript_or_init).with_content(/-H tcp:\/\/127.0.0.1:4567/) } + let(:params) { params.merge('socket_connect' => ['tcp://127.0.0.1:4567', 'tcp://127.0.0.2:4567']) } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{-H tcp:\/\/127.0.0.1:4567}) } end context 'when passing a socket to connect to' do - let(:params) { params.merge({'socket_connect' => 'tcp://127.0.0.1:4567'}) } - it { should contain_file(startscript_or_init).with_content(/-H tcp:\/\/127.0.0.1:4567/) } + let(:params) { params.merge('socket_connect' => 'tcp://127.0.0.1:4567') } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{-H tcp:\/\/127.0.0.1:4567}) } end context 'when passing serveral dns search domains' do - let(:params) { params.merge({'dns_search' => ['my.domain.local', 'other-domain.de']}) } - it { should contain_file(startscript_or_init).with_content(/--dns-search my.domain.local/).with_content(/--dns-search other-domain.de/) } + let(:params) { params.merge('dns_search' => ['my.domain.local', 'other-domain.de']) } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{--dns-search my.domain.local}).with_content(%r{--dns-search other-domain.de}) } end context 'when passing a dns search domain' do - let(:params) { params.merge({'dns_search' => 'my.domain.local'}) } - it { should contain_file(startscript_or_init).with_content(/--dns-search my.domain.local/) } + let(:params) { params.merge('dns_search' => 'my.domain.local') } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{--dns-search my.domain.local}) } end context 'when disabling network' do - let(:params) { params.merge({'disable_network' => true}) } - it { should contain_file(startscript_or_init).with_content(/-n false/) } + let(:params) { params.merge('disable_network' => true) } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{-n false}) } end context 'when running privileged' do - let(:params) { params.merge({'privileged' => true}) } - it { should contain_file(startscript_or_init).with_content(/--privileged/) } + let(:params) { params.merge('privileged' => true) } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{--privileged}) } end context 'should run with correct detached value' do let(:params) { params } - if (systemd) - it { should_not contain_file(startscript).with_content(/--detach=true/) } + + if systemd + it { is_expected.not_to contain_file(startscript).with_content(%r{--detach=true}) } else - it { should contain_file(initscript).with_content(/--detach=true/) } + it { is_expected.to contain_file(initscript).with_content(%r{--detach=true}) } end end context 'should be able to override detached' do - let(:params) { params.merge({'detach' => false}) } - it { should contain_file(startscript_or_init).without_content(/--detach=true/) } + let(:params) { params.merge('detach' => false) } + + it { is_expected.to contain_file(startscript_or_init).without_content(%r{--detach=true}) } end context 'when running with a tty' do - let(:params) { params.merge({'tty' => true}) } - it { should contain_file(startscript_or_init).with_content(/-t/) } + let(:params) { params.merge('tty' => true) } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{-t}) } end context 'when running with read-only image' do - let(:params) { params.merge({'read_only' => true}) } - it { should contain_file(startscript_or_init).with_content(/--read-only=true/) } + let(:params) { params.merge('read_only' => true) } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{--read-only=true}) } end context 'when passing serveral extra parameters' do - let(:params) { params.merge({'extra_parameters' => ['--rm', '-w /tmp']}) } - it { should contain_file(startscript_or_init).with_content(/--rm/).with_content(/-w \/tmp/) } + let(:params) { params.merge('extra_parameters' => ['--rm', '-w /tmp']) } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{--rm}).with_content(%r{-w \/tmp}) } end context 'when passing an extra parameter' do - let(:params) { params.merge({'extra_parameters' => '-c 4'}) } - it { should contain_file(startscript_or_init).with_content(/-c 4/) } + let(:params) { params.merge('extra_parameters' => '-c 4') } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{-c 4}) } end context 'when passing a data volume' do - let(:params) { params.merge({'volumes' => '/var/log'}) } - it { should contain_file(startscript_or_init).with_content(/-v \/var\/log/) } + let(:params) { params.merge('volumes' => '/var/log') } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{-v \/var\/log}) } end context 'when passing serveral data volume' do - let(:params) { params.merge({'volumes' => ['/var/lib/couchdb', '/var/log']}) } - it { should contain_file(startscript_or_init).with_content(/-v \/var\/lib\/couchdb/) } - it { should contain_file(startscript_or_init).with_content(/-v \/var\/log/) } + let(:params) { params.merge('volumes' => ['/var/lib/couchdb', '/var/log']) } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{-v \/var\/lib\/couchdb}) } + it { is_expected.to contain_file(startscript_or_init).with_content(%r{-v \/var\/log}) } end context 'when using network mode with a single network' do - let(:params) { params.merge({'net' => 'host'}) } - it { should contain_file(startscript_or_init).with_content(/--net host/) } + let(:params) { params.merge('net' => 'host') } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{--net host}) } end context 'when using network mode with multiple networks' do - let(:params) { params.merge({'net' => ['host','foo']}) } - it { should contain_file(startscript_or_init).with_content(/docker network connect host sample/) } - it { should contain_file(startscript_or_init).with_content(/docker network connect foo sample/) } + let(:params) { params.merge('net' => ['host', 'foo']) } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{docker network connect host sample}) } + it { is_expected.to contain_file(startscript_or_init).with_content(%r{docker network connect foo sample}) } end context 'when `pull_on_start` is true' do - let(:params) { params.merge({'pull_on_start' => true}) } - it { should contain_file(startscript_or_init).with_content(/docker pull base/) } + let(:params) { params.merge('pull_on_start' => true) } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{docker pull base}) } end context 'when `pull_on_start` is false' do - let(:params) { params.merge({'pull_on_start' => false}) } - it { should_not contain_file(startscript_or_init).with_content(/docker pull base/) } + let(:params) { params.merge('pull_on_start' => false) } + + it { is_expected.not_to contain_file(startscript_or_init).with_content(%r{docker pull base}) } end context 'when `before_start` is set' do - let(:params) { params.merge({'before_start' => "echo before_start"}) } - it { should contain_file(startscript_or_init).with_content(/before_start/) } + let(:params) { params.merge('before_start' => 'echo before_start') } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{before_start}) } end context 'when `before_start` is not set' do - let(:params) { params.merge({'before_start' => false}) } - it { should_not contain_file(startscript_or_init).with_content(/before_start/) } + let(:params) { params.merge('before_start' => false) } + + it { is_expected.not_to contain_file(startscript_or_init).with_content(%r{before_start}) } end context 'when `before_stop` is set' do - let(:params) { params.merge({'before_stop' => "echo before_stop"}) } - it { should contain_file(stopscript_or_init).with_content(/before_stop/) } + let(:params) { params.merge('before_stop' => 'echo before_stop') } + + it { is_expected.to contain_file(stopscript_or_init).with_content(%r{before_stop}) } end context 'when `before_stop` is not set' do - let(:params) { params.merge({'before_stop' => false}) } - it { should_not contain_file(stopscript_or_init).with_content(/before_stop/) } + let(:params) { params.merge('before_stop' => false) } + + it { is_expected.not_to contain_file(stopscript_or_init).with_content(%r{before_stop}) } end context 'when `after_create` is set' do - let(:params) { params.merge({'after_create' => "echo after_create"}) } - it { should contain_file(startscript_or_init).with_content(/after_create/) } + let(:params) { params.merge('after_create' => 'echo after_create') } + + it { is_expected.to contain_file(startscript_or_init).with_content(%r{after_create}) } end context 'with an title that will not format into a path' do let(:title) { 'this/that' } let(:params) { params } new_initscript = '/etc/systemd/system/docker-this-that.service' new_startscript = '/usr/local/bin/docker-run-this-that-start.sh' new_stopscript = '/usr/local/bin/docker-run-this-that-stop.sh' - it { should contain_service('docker-this-that') } - it { should contain_file(new_initscript) } - it { should contain_file(new_startscript) } - it { should contain_file(new_stopscript) } + it { is_expected.to contain_service('docker-this-that') } + it { is_expected.to contain_file(new_initscript) } + it { is_expected.to contain_file(new_startscript) } + it { is_expected.to contain_file(new_stopscript) } end context 'with manage_service turned off' do let(:title) { 'this/that' } - let(:params) { params.merge({'manage_service' => false}) } + let(:params) { params.merge('manage_service' => false) } new_initscript = '/etc/systemd/system/docker-this-that.service' new_startscript = '/usr/local/bin/docker-run-this-that-start.sh' new_stopscript = '/usr/local/bin/docker-run-this-that-stop.sh' - it { should_not contain_service('docker-this-that') } - it { should contain_file(new_initscript) } - it { should contain_file(new_startscript) } - it { should contain_file(new_stopscript) } + it { is_expected.not_to contain_service('docker-this-that') } + it { is_expected.to contain_file(new_initscript) } + it { is_expected.to contain_file(new_startscript) } + it { is_expected.to contain_file(new_stopscript) } end context 'with service_prefix set to empty string' do let(:title) { 'this/that' } - let(:params) { params.merge({'service_prefix' => ''}) } + let(:params) { params.merge('service_prefix' => '') } new_initscript = '/etc/systemd/system/this-that.service' new_startscript = '/usr/local/bin/docker-run-this-that-start.sh' new_stopscript = '/usr/local/bin/docker-run-this-that-stop.sh' - it { should contain_service('this-that') } - it { should contain_file(new_initscript) } - it { should contain_file(new_startscript) } - it { should contain_file(new_stopscript) } + it { is_expected.to contain_service('this-that') } + it { is_expected.to contain_file(new_initscript) } + it { is_expected.to contain_file(new_startscript) } + it { is_expected.to contain_file(new_stopscript) } end context 'with an invalid title' do let(:title) { 'with spaces' } + it do expect { - should contain_service('docker-sample') + is_expected.to contain_service('docker-sample') }.to raise_error(Puppet::Error) end end context 'with title that need sanitisation' do let(:title) { 'this/that_other' } let(:params) { params } new_initscript = '/etc/systemd/system/docker-this-that_other.service' new_startscript = '/usr/local/bin/docker-run-this-that_other-start.sh' new_stopscript = '/usr/local/bin/docker-run-this-that_other-stop.sh' - it { should contain_service('docker-this-that_other') } - it { should contain_file(new_initscript) } - it { should contain_file(new_startscript) } - it { should contain_file(new_stopscript) } + it { is_expected.to contain_service('docker-this-that_other') } + it { is_expected.to contain_file(new_initscript) } + it { is_expected.to contain_file(new_startscript) } + it { is_expected.to contain_file(new_stopscript) } end context 'with an invalid image name' do - let(:params) { params.merge({'image' => 'with spaces', 'running' => 'not a boolean'}) } + let(:params) { params.merge('image' => 'with spaces', 'running' => 'not a boolean') } + it do expect { - should contain_service('docker-sample') + is_expected.to contain_service('docker-sample') }.to raise_error(Puppet::Error) end end context 'with an invalid running value' do let(:title) { 'with spaces' } - let(:params) { params.merge({'running' => 'not a boolean'}) } + let(:params) { params.merge('running' => 'not a boolean') } + it do expect { - should contain_service('docker-sample') + is_expected.to contain_service('docker-sample') }.to raise_error(Puppet::Error) end end context 'with an invalid memory value' do let(:title) { 'with spaces' } - let(:params) { params.merge({'memory' => 'not a number'}) } + let(:params) { params.merge('memory' => 'not a number') } + it do expect { - should contain_service('docker-sample') + is_expected.to contain_service('docker-sample') }.to raise_error(Puppet::Error) end end context 'with a missing memory unit' do let(:title) { 'with spaces' } - let(:params) { params.merge({'memory' => '10240'}) } + let(:params) { params.merge('memory' => '10240') } + it do expect { - should contain_service('docker-sample') + is_expected.to contain_service('docker-sample') }.to raise_error(Puppet::Error) end end context 'with restart policy set to no' do - let(:params) { params.merge({'restart' => 'no', 'extra_parameters' => '-c 4'}) } - it { should contain_exec('run sample with docker') } - it { should contain_exec('run sample with docker').with_unless(/sample/) } - it { should contain_exec('run sample with docker').with_unless(/inspect/) } - it { should contain_exec('run sample with docker').with_command(/--cidfile=\/var\/run\/docker-sample.cid/) } - it { should contain_exec('run sample with docker').with_command(/-c 4/) } - it { should contain_exec('run sample with docker').with_command(/--restart="no"/) } - it { should contain_exec('run sample with docker').with_command(/base command/) } - it { should contain_exec('run sample with docker').with_timeout(0) } + let(:params) { params.merge('restart' => 'no', 'extra_parameters' => '-c 4') } + + it { is_expected.to contain_exec('run sample with docker') } + it { is_expected.to contain_exec('run sample with docker').with_unless(%r{sample}) } + it { is_expected.to contain_exec('run sample with docker').with_unless(%r{inspect}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{--cidfile=\/var\/run\/docker-sample.cid}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{-c 4}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{--restart="no"}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{base command}) } + it { is_expected.to contain_exec('run sample with docker').with_timeout(0) } end context 'with restart policy set to always' do - let(:params) { params.merge({'restart' => 'always', 'extra_parameters' => '-c 4'}) } - it { should contain_exec('run sample with docker') } - it { should contain_exec('run sample with docker').with_unless(/sample/) } - it { should contain_exec('run sample with docker').with_unless(/inspect/) } - it { should contain_exec('run sample with docker').with_command(/--cidfile=\/var\/run\/docker-sample.cid/) } - it { should contain_exec('run sample with docker').with_command(/-c 4/) } - it { should contain_exec('run sample with docker').with_command(/--restart="always"/) } - it { should contain_exec('run sample with docker').with_command(/base command/) } - it { should contain_exec('run sample with docker').with_timeout(0) } + let(:params) { params.merge('restart' => 'always', 'extra_parameters' => '-c 4') } + + it { is_expected.to contain_exec('run sample with docker') } + it { is_expected.to contain_exec('run sample with docker').with_unless(%r{sample}) } + it { is_expected.to contain_exec('run sample with docker').with_unless(%r{inspect}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{--cidfile=\/var\/run\/docker-sample.cid}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{-c 4}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{--restart="always"}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{base command}) } + it { is_expected.to contain_exec('run sample with docker').with_timeout(0) } end context 'with restart policy set to on-failure' do - let(:params) { params.merge({'restart' => 'on-failure', 'extra_parameters' => '-c 4'}) } - it { should contain_exec('run sample with docker') } - it { should contain_exec('run sample with docker').with_unless(/sample/) } - it { should contain_exec('run sample with docker').with_unless(/inspect/) } - it { should contain_exec('run sample with docker').with_command(/--cidfile=\/var\/run\/docker-sample.cid/) } - it { should contain_exec('run sample with docker').with_command(/-c 4/) } - it { should contain_exec('run sample with docker').with_command(/--restart="on-failure"/) } - it { should contain_exec('run sample with docker').with_command(/base command/) } - it { should contain_exec('run sample with docker').with_timeout(0) } + let(:params) { params.merge('restart' => 'on-failure', 'extra_parameters' => '-c 4') } + + it { is_expected.to contain_exec('run sample with docker') } + it { is_expected.to contain_exec('run sample with docker').with_unless(%r{sample}) } + it { is_expected.to contain_exec('run sample with docker').with_unless(%r{inspect}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{--cidfile=\/var\/run\/docker-sample.cid}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{-c 4}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{--restart="on-failure"}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{base command}) } + it { is_expected.to contain_exec('run sample with docker').with_timeout(0) } end context 'with restart policy set to on-failure:3' do - let(:params) { params.merge({'restart' => 'on-failure:3', 'extra_parameters' => '-c 4'}) } - it { should contain_exec('run sample with docker') } - it { should contain_exec('run sample with docker').with_unless(/sample/) } - it { should contain_exec('run sample with docker').with_unless(/inspect/) } - it { should contain_exec('run sample with docker').with_command(/--cidfile=\/var\/run\/docker-sample.cid/) } - it { should contain_exec('run sample with docker').with_command(/-c 4/) } - it { should contain_exec('run sample with docker').with_command(/--restart="on-failure:3"/) } - it { should contain_exec('run sample with docker').with_command(/base command/) } - it { should contain_exec('run sample with docker').with_timeout(0) } + let(:params) { params.merge('restart' => 'on-failure:3', 'extra_parameters' => '-c 4') } + + it { is_expected.to contain_exec('run sample with docker') } + it { is_expected.to contain_exec('run sample with docker').with_unless(%r{sample}) } + it { is_expected.to contain_exec('run sample with docker').with_unless(%r{inspect}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{--cidfile=\/var\/run\/docker-sample.cid}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{-c 4}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{--restart="on-failure:3"}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{base command}) } + it { is_expected.to contain_exec('run sample with docker').with_timeout(0) } end context 'when `docker_service` is false' do - let(:params) { params.merge({'docker_service' => false}) } - it { should compile.with_all_deps } - it { should contain_service('docker-sample') } + let(:params) { params.merge('docker_service' => false) } + + it { is_expected.to compile.with_all_deps } + it { is_expected.to contain_service('docker-sample') } end context 'when `docker_service` is true' do - let(:params) { params.merge({'docker_service' => true}) } + let(:params) { params.merge('docker_service' => true) } let(:pre_condition) { ["service { 'docker': provider => systemd }", pre_condition] } - it { should compile.with_all_deps } - it { should contain_service('docker').that_comes_before('Service[docker-sample]') } - it { should contain_service('docker').that_notifies('Service[docker-sample]') } + + it { is_expected.to compile.with_all_deps } + it { is_expected.to contain_service('docker').that_comes_before('Service[docker-sample]') } + it { is_expected.to contain_service('docker').that_notifies('Service[docker-sample]') } end context 'when `docker_service` is true and `restart_service_on_docker_refresh` is false' do - let(:params) { params.merge({'docker_service' => true, 'restart_service_on_docker_refresh' => false}) } + let(:params) { params.merge('docker_service' => true, 'restart_service_on_docker_refresh' => false) } let(:pre_condition) { ["service { 'docker': provider => systemd }", pre_condition] } - it { should compile.with_all_deps } - it { should contain_service('docker').that_comes_before('Service[docker-sample]') } + + it { is_expected.to compile.with_all_deps } + it { is_expected.to contain_service('docker').that_comes_before('Service[docker-sample]') } end context 'when `docker_service` is `my-docker`' do - let(:params) { params.merge({'docker_service' => 'my-docker'}) } + let(:params) { params.merge('docker_service' => 'my-docker') } let(:pre_condition) { ["service { 'my-docker': provider => systemd }", pre_condition] } - it { should compile.with_all_deps } - it { should contain_service('my-docker').that_comes_before('Service[docker-sample]') } - it { should contain_service('my-docker').that_notifies('Service[docker-sample]') } + + it { is_expected.to compile.with_all_deps } + it { is_expected.to contain_service('my-docker').that_comes_before('Service[docker-sample]') } + it { is_expected.to contain_service('my-docker').that_notifies('Service[docker-sample]') } end context 'when `docker_service` is `my-docker` and `restart_service_on_docker_refresh` is false' do - let(:params) { params.merge({'docker_service' => 'my-docker', 'restart_service_on_docker_refresh' => false}) } + let(:params) { params.merge('docker_service' => 'my-docker', 'restart_service_on_docker_refresh' => false) } let(:pre_condition) { ["service { 'my-docker': provider => systemd }", pre_condition] } - it { should compile.with_all_deps } - it { should contain_service('my-docker').that_comes_before('Service[docker-sample]') } + + it { is_expected.to compile.with_all_deps } + it { is_expected.to contain_service('my-docker').that_comes_before('Service[docker-sample]') } end context 'with syslog_identifier' do - let(:params) { params.merge({'syslog_identifier' => 'docker-universe' }) } + let(:params) { params.merge('syslog_identifier' => 'docker-universe') } + if systemd - it { should contain_file(initscript).with_content(/^SyslogIdentifier=docker-universe$/) } + it { is_expected.to contain_file(initscript).with_content(%r{^SyslogIdentifier=docker-universe$}) } end end context 'with extra_systemd_parameters' do - let(:params) { params.merge({'extra_systemd_parameters' => {'RestartSec' => 5}}) } - if (systemd) - it { should contain_file(initscript).with_content(/^RestartSec=5$/) } + let(:params) { params.merge('extra_systemd_parameters' => { 'RestartSec' => 5 }) } + + if systemd + it { is_expected.to contain_file(initscript).with_content(%r{^RestartSec=5$}) } end end context 'with ensure absent' do - let(:params) { params.merge({'ensure' => 'absent'}) } - it { should compile.with_all_deps } - it { should contain_service('docker-sample').with_ensure(false) } - it { should contain_exec("remove container docker-sample").with_command('docker rm -v sample') } - it { should_not contain_file('docker-sample.service')} - end + let(:params) { params.merge('ensure' => 'absent') } + it { is_expected.to compile.with_all_deps } + it { is_expected.to contain_service('docker-sample').with_ensure(false) } + it { is_expected.to contain_exec('remove container docker-sample').with_command('docker rm -v sample') } + it { is_expected.not_to contain_file('docker-sample.service') } + end end end - end diff --git a/spec/defines/run_windows_spec.rb b/spec/defines/run_windows_spec.rb index 03afa37..8635684 100755 --- a/spec/defines/run_windows_spec.rb +++ b/spec/defines/run_windows_spec.rb @@ -1,100 +1,109 @@ require 'spec_helper' -describe 'docker::run', :type => :define do +describe 'docker::run', type: :define do let(:title) { 'sample' } let(:pre_condition) { 'class { \'docker\': docker_ee => true }' } - let(:facts) { { - :architecture => 'amd64', - :osfamily => 'windows', - :operatingsystem => 'windows', - :kernelrelease => '10.0.14393', - :operatingsystemrelease => '2016', - :operatingsystemmajrelease => '2016', - :docker_program_data_path => 'C:/ProgramData', - :docker_program_files_path => 'C:/Program Files', - :docker_systemroot => 'C:/Windows', - :docker_user_temp_path => 'C:/Users/Administrator/AppData/Local/Temp', - :os => { :family => 'windows', :name => 'windows', :release => { :major => '2016', :full => '2016' } } - } } - command = 'docker' + let(:facts) do + { + architecture: 'amd64', + osfamily: 'windows', + operatingsystem: 'windows', + kernelrelease: '10.0.14393', + operatingsystemrelease: '2016', + operatingsystemmajrelease: '2016', + docker_program_data_path: 'C:/ProgramData', + docker_program_files_path: 'C:/Program Files', + docker_systemroot: 'C:/Windows', + docker_user_temp_path: 'C:/Users/Administrator/AppData/Local/Temp', + os: { family: 'windows', name: 'windows', release: { major: '2016', full: '2016' } }, + } + end context 'with restart policy set to no' do - let(:params) { {'restart' => 'no', 'command' => 'command', 'image' => 'base', 'extra_parameters' => '-c 4'} } - it { should contain_exec('run sample with docker') } - it { should contain_exec('run sample with docker').with_unless(/sample/) } - it { should contain_exec('run sample with docker').with_unless(/inspect/) } - it { should contain_exec('run sample with docker').with_command(/--cidfile=C:\/Users\/Administrator\/AppData\/Local\/Temp\/docker-sample.cid/) } - it { should contain_exec('run sample with docker').with_command(/-c 4/) } - it { should contain_exec('run sample with docker').with_command(/--restart="no"/) } - it { should contain_exec('run sample with docker').with_command(/base command/) } - it { should contain_exec('run sample with docker').with_timeout(3000) } + let(:params) { { 'restart' => 'no', 'command' => 'command', 'image' => 'base', 'extra_parameters' => '-c 4' } } + + it { is_expected.to contain_exec('run sample with docker') } + it { is_expected.to contain_exec('run sample with docker').with_unless(%r{sample}) } + it { is_expected.to contain_exec('run sample with docker').with_unless(%r{inspect}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{--cidfile=C:\/Users\/Administrator\/AppData\/Local\/Temp\/docker-sample.cid}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{-c 4}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{--restart="no"}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{base command}) } + it { is_expected.to contain_exec('run sample with docker').with_timeout(3000) } end context 'with restart policy set to always' do - let(:params) { {'restart' => 'always', 'command' => 'command', 'image' => 'base', 'extra_parameters' => '-c 4'} } - it { should contain_exec('run sample with docker') } - it { should contain_exec('run sample with docker').with_unless(/sample/) } - it { should contain_exec('run sample with docker').with_unless(/inspect/) } - it { should contain_exec('run sample with docker').with_command(/--cidfile=C:\/Users\/Administrator\/AppData\/Local\/Temp\/docker-sample.cid/) } - it { should contain_exec('run sample with docker').with_command(/-c 4/) } - it { should contain_exec('run sample with docker').with_command(/--restart="always"/) } - it { should contain_exec('run sample with docker').with_command(/base command/) } - it { should contain_exec('run sample with docker').with_timeout(3000) } - it { should contain_exec('start sample with docker').with_command(/docker start sample/) } + let(:params) { { 'restart' => 'always', 'command' => 'command', 'image' => 'base', 'extra_parameters' => '-c 4' } } + + it { is_expected.to contain_exec('run sample with docker') } + it { is_expected.to contain_exec('run sample with docker').with_unless(%r{sample}) } + it { is_expected.to contain_exec('run sample with docker').with_unless(%r{inspect}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{--cidfile=C:\/Users\/Administrator\/AppData\/Local\/Temp\/docker-sample.cid}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{-c 4}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{--restart="always"}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{base command}) } + it { is_expected.to contain_exec('run sample with docker').with_timeout(3000) } + it { is_expected.to contain_exec('start sample with docker').with_command(%r{docker start sample}) } end context 'with restart policy set to on-failure' do - let(:params) { {'restart' => 'on-failure', 'command' => 'command', 'image' => 'base', 'extra_parameters' => '-c 4'} } - it { should contain_exec('run sample with docker') } - it { should contain_exec('run sample with docker').with_unless(/sample/) } - it { should contain_exec('run sample with docker').with_unless(/inspect/) } - it { should contain_exec('run sample with docker').with_command(/--cidfile=C:\/Users\/Administrator\/AppData\/Local\/Temp\/docker-sample.cid/) } - it { should contain_exec('run sample with docker').with_command(/-c 4/) } - it { should contain_exec('run sample with docker').with_command(/--restart="on-failure"/) } - it { should contain_exec('run sample with docker').with_command(/base command/) } - it { should contain_exec('run sample with docker').with_timeout(3000) } + let(:params) { { 'restart' => 'on-failure', 'command' => 'command', 'image' => 'base', 'extra_parameters' => '-c 4' } } + + it { is_expected.to contain_exec('run sample with docker') } + it { is_expected.to contain_exec('run sample with docker').with_unless(%r{sample}) } + it { is_expected.to contain_exec('run sample with docker').with_unless(%r{inspect}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{--cidfile=C:\/Users\/Administrator\/AppData\/Local\/Temp\/docker-sample.cid}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{-c 4}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{--restart="on-failure"}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{base command}) } + it { is_expected.to contain_exec('run sample with docker').with_timeout(3000) } end context 'with restart policy set to on-failure:3' do - let(:params) { {'restart' => 'on-failure:3', 'command' => 'command', 'image' => 'base', 'extra_parameters' => '-c 4'} } - it { should contain_exec('run sample with docker') } - it { should contain_exec('run sample with docker').with_unless(/sample/) } - it { should contain_exec('run sample with docker').with_unless(/inspect/) } - it { should contain_exec('run sample with docker').with_command(/--cidfile=C:\/Users\/Administrator\/AppData\/Local\/Temp\/docker-sample.cid/) } - it { should contain_exec('run sample with docker').with_command(/-c 4/) } - it { should contain_exec('run sample with docker').with_command(/--restart="on-failure:3"/) } - it { should contain_exec('run sample with docker').with_command(/base command/) } - it { should contain_exec('run sample with docker').with_timeout(3000) } + let(:params) { { 'restart' => 'on-failure:3', 'command' => 'command', 'image' => 'base', 'extra_parameters' => '-c 4' } } + + it { is_expected.to contain_exec('run sample with docker') } + it { is_expected.to contain_exec('run sample with docker').with_unless(%r{sample}) } + it { is_expected.to contain_exec('run sample with docker').with_unless(%r{inspect}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{--cidfile=C:\/Users\/Administrator\/AppData\/Local\/Temp\/docker-sample.cid}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{-c 4}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{--restart="on-failure:3"}) } + it { is_expected.to contain_exec('run sample with docker').with_command(%r{base command}) } + it { is_expected.to contain_exec('run sample with docker').with_timeout(3000) } end context 'with ensure absent' do - let(:params) { {'ensure' => 'absent', 'command' => 'command', 'image' => 'base'} } - it { should compile.with_all_deps } - it { should contain_exec("stop container docker-sample").with_command('docker stop --time=0 sample') } - it { should contain_exec("remove container docker-sample").with_command('docker rm -v sample') } - it { should_not contain_file('C:/Users/Administrator/AppData/Local/Temp/docker-sample.cid"')} + let(:params) { { 'ensure' => 'absent', 'command' => 'command', 'image' => 'base' } } + + it { is_expected.to compile.with_all_deps } + it { is_expected.to contain_exec('stop container docker-sample').with_command('docker stop --time=0 sample') } + it { is_expected.to contain_exec('remove container docker-sample').with_command('docker rm -v sample') } + it { is_expected.not_to contain_file('C:/Users/Administrator/AppData/Local/Temp/docker-sample.cid"') } end context 'with ensure absent and restart policy' do - let(:params) { {'ensure' => 'absent', 'command' => 'command', 'image' => 'base', 'restart' => 'always'} } - it { should compile.with_all_deps } - it { should contain_exec("stop sample with docker").with_command('docker stop --time=0 sample') } - it { should contain_exec("remove sample with docker").with_command('docker rm -v sample') } - it { should_not contain_file('C:/Users/Administrator/AppData/Local/Temp/docker-sample.cid"')} + let(:params) { { 'ensure' => 'absent', 'command' => 'command', 'image' => 'base', 'restart' => 'always' } } + + it { is_expected.to compile.with_all_deps } + it { is_expected.to contain_exec('stop sample with docker').with_command('docker stop --time=0 sample') } + it { is_expected.to contain_exec('remove sample with docker').with_command('docker rm -v sample') } + it { is_expected.not_to contain_file('C:/Users/Administrator/AppData/Local/Temp/docker-sample.cid"') } end context 'with ensure present and running false' do - let(:params) { {'ensure' => 'present', 'image' => 'base', 'restart' => 'always', 'running' => false} } - it { should compile.with_all_deps } - it { should contain_exec("stop sample with docker").with_command('docker stop --time=0 sample') } + let(:params) { { 'ensure' => 'present', 'image' => 'base', 'restart' => 'always', 'running' => false } } + + it { is_expected.to compile.with_all_deps } + it { is_expected.to contain_exec('stop sample with docker').with_command('docker stop --time=0 sample') } end context 'with ensure present and no restart policy' do - let(:params) { {'ensure' => 'present', 'image' => 'base'} } + let(:params) { { 'ensure' => 'present', 'image' => 'base' } } + it do expect { - should_not contain_file('C:/Users/Administrator/AppData/Local/Temp/docker-sample.cid"') + is_expected.not_to contain_file('C:/Users/Administrator/AppData/Local/Temp/docker-sample.cid"') }.to raise_error(Puppet::Error) end end end diff --git a/spec/defines/secrets_spec.rb b/spec/defines/secrets_spec.rb index a4ec698..cdb52cc 100644 --- a/spec/defines/secrets_spec.rb +++ b/spec/defines/secrets_spec.rb @@ -1,43 +1,51 @@ require 'spec_helper' -describe 'docker::secrets', :type => :define do +describe 'docker::secrets', type: :define do let(:title) { 'test_secret' } - let(:facts) { { - :osfamily => 'Debian', - :operatingsystem => 'Debian', - :lsbdistid => 'Debian', - :lsbdistcodename => 'jessie', - :kernelrelease => '3.2.0-4-amd64', - :operatingsystemmajrelease => '8', - } } + let(:facts) do + { + osfamily: 'Debian', + operatingsystem: 'Debian', + lsbdistid: 'Debian', + lsbdistcodename: 'jessie', + kernelrelease: '3.2.0-4-amd64', + operatingsystemmajrelease: '8', + } + end context 'with secret_name => test_secret and secret_path => /root/secret.txt and label => test' do - let(:params) { { - 'secret_name' => 'test_secret', - 'secret_path' => '/root/secret.txt', - 'label' => ['test'], - } } - it { should contain_exec('test_secret docker secret create').with_command(/docker secret create/) } + let(:params) do + { + 'secret_name' => 'test_secret', + 'secret_path' => '/root/secret.txt', + 'label' => ['test'], + } + end + + it { is_expected.to contain_exec('test_secret docker secret create').with_command(%r{docker secret create}) } context 'multiple secrets declaration' do - let(:pre_condition) { + let(:pre_condition) do " docker::secrets{'test_secret_2': secret_name => 'test_secret_2', secret_path => '/root/secret_2.txt', } " - } - it { should contain_exec('test_secret docker secret create').with_command(/docker secret create/) } - it { should contain_exec('test_secret_2 docker secret create').with_command(/docker secret create/) } + end + + it { is_expected.to contain_exec('test_secret docker secret create').with_command(%r{docker secret create}) } + it { is_expected.to contain_exec('test_secret_2 docker secret create').with_command(%r{docker secret create}) } end end context 'with ensure => absent and secret_name => test_secret' do - let(:params) { { - 'ensure' => 'absent', - 'secret_name' => 'test_secret'} } - it { should contain_exec('test_secret docker secret rm').with_command(/docker secret rm/) } - end - + let(:params) do + { + 'ensure' => 'absent', + 'secret_name' => 'test_secret', + } + end + it { is_expected.to contain_exec('test_secret docker secret rm').with_command(%r{docker secret rm}) } + end end diff --git a/spec/defines/services_spec.rb b/spec/defines/services_spec.rb index e35fdff..a5f80c5 100644 --- a/spec/defines/services_spec.rb +++ b/spec/defines/services_spec.rb @@ -1,108 +1,126 @@ require 'spec_helper' -describe 'docker::services', :type => :define do +describe 'docker::services', type: :define do let(:title) { 'test_service' } - let(:facts) { { - :osfamily => 'Debian', - :operatingsystem => 'Debian', - :lsbdistid => 'Debian', - :lsbdistcodename => 'jessie', - :kernelrelease => '3.2.0-4-amd64', - :operatingsystemmajrelease => '8', - } } + let(:facts) do + { + osfamily: 'Debian', + operatingsystem: 'Debian', + lsbdistid: 'Debian', + lsbdistcodename: 'jessie', + kernelrelease: '3.2.0-4-amd64', + operatingsystemmajrelease: '8', + } + end context 'with ensure => present and service create' do - let(:params) { { - 'create' => true, - 'service_name' => 'foo', - 'image' => 'foo:bar', - 'publish' => '80:80', - 'replicas' => '5', - 'extra_params' => ['--update-delay 1m', '--restart-window 30s'], - 'env' => ['MY_ENV=1', 'MY_ENV2=2'], - 'label' => ['com.example.foo="bar"', 'bar=baz'], - 'mounts' => ['type=bind,src=/tmp/a,dst=/tmp/a', 'type=bind,src=/tmp/b,dst=/tmp/b,readonly'], - 'networks' => ['overlay'], - 'command' => 'echo hello world', - } } + let(:params) do + { + 'create' => true, + 'service_name' => 'foo', + 'image' => 'foo:bar', + 'publish' => '80:80', + 'replicas' => '5', + 'extra_params' => ['--update-delay 1m', '--restart-window 30s'], + 'env' => ['MY_ENV=1', 'MY_ENV2=2'], + 'label' => ['com.example.foo="bar"', 'bar=baz'], + 'mounts' => ['type=bind,src=/tmp/a,dst=/tmp/a', 'type=bind,src=/tmp/b,dst=/tmp/b,readonly'], + 'networks' => ['overlay'], + 'command' => 'echo hello world', + } + end + it { is_expected.to compile.with_all_deps } - it { should contain_exec('test_service docker service create').with_command(/docker service create/) } - it { should contain_exec('test_service docker service create').with_command(/--env MY_ENV=1/) } - it { should contain_exec('test_service docker service create').with_command(/--label bar=baz/) } - it { should contain_exec('test_service docker service create').with_command(/--mount type=bind,src=\/tmp\/b,dst=\/tmp\/b,readonly/) } - it { should contain_exec('test_service docker service create').with_command(/--network overlay/) } - it { should contain_exec('test_service docker service create').with_command(/echo hello world/) } + it { is_expected.to contain_exec('test_service docker service create').with_command(%r{docker service create}) } + it { is_expected.to contain_exec('test_service docker service create').with_command(%r{--env MY_ENV=1}) } + it { is_expected.to contain_exec('test_service docker service create').with_command(%r{--label bar=baz}) } + it { is_expected.to contain_exec('test_service docker service create').with_command(%r{--mount type=bind,src=\/tmp\/b,dst=\/tmp\/b,readonly}) } + it { is_expected.to contain_exec('test_service docker service create').with_command(%r{--network overlay}) } + it { is_expected.to contain_exec('test_service docker service create').with_command(%r{echo hello world}) } context 'multiple services declaration' do - let(:pre_condition) { + let(:pre_condition) do " docker::services { 'test_service_2': service_name => 'foo_2', image => 'foo:bar', command => ['echo', 'hello', 'world'], } " - } - it { should contain_exec('test_service docker service create').with_command(/docker service create/) } - it { should contain_exec('test_service_2 docker service create').with_command(/docker service create/) } - it { should contain_exec('test_service_2 docker service create').with_command(/echo hello world/) } + end + + it { is_expected.to contain_exec('test_service docker service create').with_command(%r{docker service create}) } + it { is_expected.to contain_exec('test_service_2 docker service create').with_command(%r{docker service create}) } + it { is_expected.to contain_exec('test_service_2 docker service create').with_command(%r{echo hello world}) } end context 'multiple publish ports and multiple networks' do - let(:pre_condition) { + let(:pre_condition) do " docker::services { 'test_service_3': service_name => 'foo_3', image => 'foo:bar', publish => ['80:8080', '9000:9000' ], networks => ['foo_1', 'foo_2'], } " - } - it { should contain_exec('test_service_3 docker service create').with_command(/--publish 80:8080/) } - it { should contain_exec('test_service_3 docker service create').with_command(/--publish 9000:9000/) } - it { should contain_exec('test_service_3 docker service create').with_command(/--network foo_1/) } - it { should contain_exec('test_service_3 docker service create').with_command(/--network foo_2/) } - end + end + it { is_expected.to contain_exec('test_service_3 docker service create').with_command(%r{--publish 80:8080}) } + it { is_expected.to contain_exec('test_service_3 docker service create').with_command(%r{--publish 9000:9000}) } + it { is_expected.to contain_exec('test_service_3 docker service create').with_command(%r{--network foo_1}) } + it { is_expected.to contain_exec('test_service_3 docker service create').with_command(%r{--network foo_2}) } + end end context 'with ensure => present and service update' do - let(:params) { { - 'create' => false, - 'update' => true, - 'service_name' => 'foo', - 'image' => 'bar:latest', - } } + let(:params) do + { + 'create' => false, + 'update' => true, + 'service_name' => 'foo', + 'image' => 'bar:latest', + } + end + it { is_expected.to compile.with_all_deps } - it { should contain_exec('test_service docker service update').with_command(/docker service update/) } + it { is_expected.to contain_exec('test_service docker service update').with_command(%r{docker service update}) } end context 'with ensure => present and service scale' do - let(:params) { { - 'create' => false, - 'scale' => true, - 'service_name' => 'bar', - 'replicas' => '5', - } } + let(:params) do + { + 'create' => false, + 'scale' => true, + 'service_name' => 'bar', + 'replicas' => '5', + } + end + it { is_expected.to compile.with_all_deps } - it { should contain_exec('test_service docker service scale').with_command(/docker service scale/) } + it { is_expected.to contain_exec('test_service docker service scale').with_command(%r{docker service scale}) } end context 'with ensure => absent' do - let(:params) { { - 'ensure' => 'absent', - 'service_name' => 'foo', - } } + let(:params) do + { + 'ensure' => 'absent', + 'service_name' => 'foo', + } + end + it { is_expected.to compile.with_all_deps } - it { should contain_exec('test_service docker service remove').with_command(/docker service rm/) } + it { is_expected.to contain_exec('test_service docker service remove').with_command(%r{docker service rm}) } end context 'when adding a system user' do - let(:params) { { + let(:params) do + { 'user' => ['user1'], - } } + } + end + it { is_expected.to compile.with_all_deps } - it { should_not contain_exec('docker-systemd-reload-before-service') } + it { is_expected.not_to contain_exec('docker-systemd-reload-before-service') } end end diff --git a/spec/defines/stack_spec.rb b/spec/defines/stack_spec.rb index 2f953fe..ffde808 100644 --- a/spec/defines/stack_spec.rb +++ b/spec/defines/stack_spec.rb @@ -1,67 +1,87 @@ require 'spec_helper' ['Debian', 'Windows'].each do |osfamily| - describe 'docker::stack', :type => :define do + describe 'docker::stack', type: :define do let(:title) { 'test_stack' } + if osfamily == 'Debian' - let(:facts) { { - :osfamily => 'Debian', - :operatingsystem => 'Debian', - :lsbdistid => 'Debian', - :lsbdistcodename => 'jessie', - :kernelrelease => '3.2.0-4-amd64', - :operatingsystemmajrelease => '8', - } } + let(:facts) do + { + osfamily: 'Debian', + operatingsystem: 'Debian', + lsbdistid: 'Debian', + lsbdistcodename: 'jessie', + kernelrelease: '3.2.0-4-amd64', + operatingsystemmajrelease: '8', + } + end + elsif osfamily == 'Windows' - let(:facts) { { - :osfamily => 'windows', - :operatingsystem => 'windows', - :kernelrelease => '10.0.14393', - :operatingsystemmajrelease => '2016', - :docker_program_data_path => 'C:/ProgramData', - :docker_program_files_path => 'C:/Program Files', - :docker_systemroot => 'C:/Windows', - :docker_user_temp_path => 'C:/Users/Administrator/AppData/Local/Temp', - } } + let(:facts) do + { + osfamily: 'windows', + operatingsystem: 'windows', + kernelrelease: '10.0.14393', + operatingsystemmajrelease: '2016', + docker_program_data_path: 'C:/ProgramData', + docker_program_files_path: 'C:/Program Files', + docker_systemroot: 'C:/Windows', + docker_user_temp_path: 'C:/Users/Administrator/AppData/Local/Temp', + } + end + end context 'Create stack with compose file' do - let(:params) { { - 'stack_name' => 'foo', - 'compose_files' => ['/tmp/docker-compose.yaml'], - 'resolve_image' => 'always', - } } - it { should contain_exec('docker stack create foo').with_command(/docker stack deploy/) } - it { should contain_exec('docker stack create foo').with_command(/--compose-file '\/tmp\/docker-compose.yaml'/) } + let(:params) do + { + 'stack_name' => 'foo', + 'compose_files' => ['/tmp/docker-compose.yaml'], + 'resolve_image' => 'always', + } + end + + it { is_expected.to contain_exec('docker stack create foo').with_command(%r{docker stack deploy}) } + it { is_expected.to contain_exec('docker stack create foo').with_command(%r{--compose-file '\/tmp\/docker-compose.yaml'}) } end context 'Create stack with multiple compose files' do - let(:params) { { - 'stack_name' => 'foo', - 'compose_files' => ['/tmp/docker-compose.yaml', '/tmp/docker-compose-2.yaml'], - 'resolve_image' => 'always', - } } - it { should contain_exec('docker stack create foo').with_command(/docker stack deploy/) } - it { should contain_exec('docker stack create foo').with_command(/--compose-file '\/tmp\/docker-compose.yaml'/) } - it { should contain_exec('docker stack create foo').with_command(/--compose-file '\/tmp\/docker-compose-2.yaml'/) } + let(:params) do + { + 'stack_name' => 'foo', + 'compose_files' => ['/tmp/docker-compose.yaml', '/tmp/docker-compose-2.yaml'], + 'resolve_image' => 'always', + } + end + + it { is_expected.to contain_exec('docker stack create foo').with_command(%r{docker stack deploy}) } + it { is_expected.to contain_exec('docker stack create foo').with_command(%r{--compose-file '\/tmp\/docker-compose.yaml'}) } + it { is_expected.to contain_exec('docker stack create foo').with_command(%r{--compose-file '\/tmp\/docker-compose-2.yaml'}) } end context 'with prune' do - let(:params) { { - 'stack_name' => 'foo', - 'compose_files' => ['/tmp/docker-compose.yaml'], - 'prune' => true, - } } - it { should contain_exec('docker stack create foo').with_command(/docker stack deploy/) } - it { should contain_exec('docker stack create foo').with_command(/--compose-file '\/tmp\/docker-compose.yaml'/) } - it { should contain_exec('docker stack create foo').with_command(/--prune/) } + let(:params) do + { + 'stack_name' => 'foo', + 'compose_files' => ['/tmp/docker-compose.yaml'], + 'prune' => true, + } + end + + it { is_expected.to contain_exec('docker stack create foo').with_command(%r{docker stack deploy}) } + it { is_expected.to contain_exec('docker stack create foo').with_command(%r{--compose-file '\/tmp\/docker-compose.yaml'}) } + it { is_expected.to contain_exec('docker stack create foo').with_command(%r{--prune}) } end - context 'with ensure => absent' do - let(:params) { { - 'ensure' => 'absent', - 'stack_name' => 'foo'} } - it { should contain_exec('docker stack destroy foo').with_command(/docker stack rm/) } + context 'with ensure => absent' do + let(:params) do + { + 'ensure' => 'absent', + 'stack_name' => 'foo', + } + end + + it { is_expected.to contain_exec('docker stack destroy foo').with_command(%r{docker stack rm}) } end end -end \ No newline at end of file +end diff --git a/spec/defines/swarm_spec.rb b/spec/defines/swarm_spec.rb index af1516d..2892647 100644 --- a/spec/defines/swarm_spec.rb +++ b/spec/defines/swarm_spec.rb @@ -1,77 +1,96 @@ require 'spec_helper' ['Debian', 'Windows'].each do |osfamily| - describe 'docker::swarm', :type => :define do + describe 'docker::swarm', type: :define do let(:title) { 'create swarm' } + context "on #{osfamily}" do if osfamily == 'Debian' - let(:facts) { { - :osfamily => 'Debian', - :operatingsystem => 'Debian', - :lsbdistid => 'Debian', - :lsbdistcodename => 'jessie', - :kernelrelease => '3.2.0-4-amd64', - :operatingsystemmajrelease => '8', - } } + let(:facts) do + { + osfamily: 'Debian', + operatingsystem: 'Debian', + lsbdistid: 'Debian', + lsbdistcodename: 'jessie', + kernelrelease: '3.2.0-4-amd64', + operatingsystemmajrelease: '8', + } + end + elsif osfamily == 'Windows' - let(:facts) { { - :osfamily => 'Windows', - :operatingsystem => 'Windows', - :kernelrelease => '10.0.14393', - :operatingsystemmajrelease => '2016', - :docker_program_data_path => 'C:/ProgramData', - :docker_program_files_path => 'C:/Program Files', - :docker_systemroot => 'C:/Windows', - :docker_user_temp_path => 'C:/Users/Administrator/AppData/Local/Temp', - } } + let(:facts) do + { + osfamily: 'Windows', + operatingsystem: 'Windows', + kernelrelease: '10.0.14393', + operatingsystemmajrelease: '2016', + docker_program_data_path: 'C:/ProgramData', + docker_program_files_path: 'C:/Program Files', + docker_systemroot: 'C:/Windows', + docker_user_temp_path: 'C:/Users/Administrator/AppData/Local/Temp', + } + end + end context 'with ensure => present and swarm init' do - let(:params) { { - 'init' => true, - 'advertise_addr' => '192.168.1.1', - 'listen_addr' => '192.168.1.1', - } } + let(:params) do + { + 'init' => true, + 'advertise_addr' => '192.168.1.1', + 'listen_addr' => '192.168.1.1', + } + end + it { is_expected.to compile.with_all_deps } - it { should contain_exec('Swarm init').with_command(/docker swarm init/) } + it { is_expected.to contain_exec('Swarm init').with_command(%r{docker swarm init}) } end context 'with ensure => present and swarm init and default-addr-pool and default_addr_pool_mask_length' do - let(:params) { { - 'init' => true, - 'advertise_addr' => '192.168.1.1', - 'listen_addr' => '192.168.1.1', - 'default_addr_pool' => ['30.30.0.0/16', '40.40.0.0/16'], - 'default_addr_pool_mask_length' => '24', - } } + let(:params) do + { + 'init' => true, + 'advertise_addr' => '192.168.1.1', + 'listen_addr' => '192.168.1.1', + 'default_addr_pool' => ['30.30.0.0/16', '40.40.0.0/16'], + 'default_addr_pool_mask_length' => '24', + } + end + it { is_expected.to compile.with_all_deps } - it { should contain_exec('Swarm init').with_command(/docker swarm init/) } + it { is_expected.to contain_exec('Swarm init').with_command(%r{docker swarm init}) } end context 'with ensure => present and swarm join' do - let(:params) { { - 'join' => true, - 'advertise_addr' => '192.168.1.1', - 'listen_addr' => '192.168.1.1', - 'token' => 'foo', - 'manager_ip' => '192.168.1.2' - } } + let(:params) do + { + 'join' => true, + 'advertise_addr' => '192.168.1.1', + 'listen_addr' => '192.168.1.1', + 'token' => 'foo', + 'manager_ip' => '192.168.1.2', + } + end + it { is_expected.to compile.with_all_deps } - it { should contain_exec('Swarm join').with_command(/docker swarm join/) } + it { is_expected.to contain_exec('Swarm join').with_command(%r{docker swarm join}) } end context 'with ensure => absent' do - let(:params) { { - 'ensure' => 'absent', - 'join' => true, - 'advertise_addr' => '192.168.1.1', - 'listen_addr' => '192.168.1.1', - 'token' => 'foo', - 'manager_ip' => '192.168.1.2' - } } + let(:params) do + { + 'ensure' => 'absent', + 'join' => true, + 'advertise_addr' => '192.168.1.1', + 'listen_addr' => '192.168.1.1', + 'token' => 'foo', + 'manager_ip' => '192.168.1.2', + } + end + it { is_expected.to compile.with_all_deps } - it { should contain_exec('Leave swarm').with_command(/docker swarm leave --force/) } + it { is_expected.to contain_exec('Leave swarm').with_command(%r{docker swarm leave --force}) } end end end end diff --git a/spec/defines/system_user_spec.rb b/spec/defines/system_user_spec.rb index da8a03f..9e2e1b2 100644 --- a/spec/defines/system_user_spec.rb +++ b/spec/defines/system_user_spec.rb @@ -1,27 +1,30 @@ require 'spec_helper' -describe 'docker::system_user', :type => :define do +describe 'docker::system_user', type: :define do let(:title) { 'testuser' } - let(:facts) { { - :osfamily => 'Debian', - :operatingsystem => 'Debian', - :lsbdistid => 'Debian', - :lsbdistcodename => 'jessie', - :kernelrelease => '3.2.0-4-amd64', - :operatingsystemmajrelease => '8', - :os => { :distro => { :codename => 'wheezy' }, :family => 'Debian', :name => 'Debian', :release => { :major => '7', :full => '7.0' } } - } } - + let(:facts) do + { + osfamily: 'Debian', + operatingsystem: 'Debian', + lsbdistid: 'Debian', + lsbdistcodename: 'jessie', + kernelrelease: '3.2.0-4-amd64', + operatingsystemmajrelease: '8', + os: { distro: { codename: 'wheezy' }, family: 'Debian', name: 'Debian', release: { major: '7', full: '7.0' } }, + } + end + context 'with default' do - let(:params) { {'create_user' => true} } - it { should contain_user('testuser') } - it { should contain_exec('docker-system-user-testuser').with_command(/docker testuser/) } - it { should contain_exec('docker-system-user-testuser').with_unless(/grep -qw testuser/) } + let(:params) { { 'create_user' => true } } + + it { is_expected.to contain_user('testuser') } + it { is_expected.to contain_exec('docker-system-user-testuser').with_command(%r{docker testuser}) } + it { is_expected.to contain_exec('docker-system-user-testuser').with_unless(%r{grep -qw testuser}) } end context 'with create_user => false' do - let(:params) { {'create_user' => false} } - it { should contain_exec('docker-system-user-testuser').with_command(/docker testuser/) } - end + let(:params) { { 'create_user' => false } } + it { is_expected.to contain_exec('docker-system-user-testuser').with_command(%r{docker testuser}) } + end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 3ac4f0d..f0f6d53 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,49 +1,75 @@ require 'puppetlabs_spec_helper/module_spec_helper' require 'rspec-puppet-facts' require 'spec_helper_local' if File.file?(File.join(File.dirname(__FILE__), 'spec_helper_local.rb')) include RspecPuppetFacts default_facts = { puppetversion: Puppet.version, facterversion: Facter.version, } default_fact_files = [ File.expand_path(File.join(File.dirname(__FILE__), 'default_facts.yml')), File.expand_path(File.join(File.dirname(__FILE__), 'default_module_facts.yml')), ] default_fact_files.each do |f| next unless File.exist?(f) && File.readable?(f) && File.size?(f) begin default_facts.merge!(YAML.safe_load(File.read(f), [], [], true)) rescue => e RSpec.configuration.reporter.message "WARNING: Unable to load #{f}: #{e}" end end RSpec.configure do |c| c.default_facts = default_facts c.before :each do # set to strictest setting for testing # by default Puppet runs at warning level Puppet.settings[:strict] = :warning end c.filter_run_excluding(bolt: true) unless ENV['GEM_BOLT'] c.after(:suite) do end end # Ensures that a module is defined # @param module_name Name of the module def ensure_module_defined(module_name) module_name.split('::').reduce(Object) do |last_module, next_module| last_module.const_set(next_module, Module.new) unless last_module.const_defined?(next_module, false) last_module.const_get(next_module, false) end end +RSpec::Matchers.define :require_string_for do |property| + match do |type_class| + config = { name: 'name' } + config[property] = 2 + expect { + type_class.new(config) + }.to raise_error(Puppet::Error, %r{#{property} should be a String}) + end + failure_message do |type_class| + "#{type_class} should require #{property} to be a String" + end +end + +RSpec::Matchers.define :require_hash_for do |property| + match do |type_class| + config = { name: 'name' } + config[property] = 2 + expect { + type_class.new(config) + }.to raise_error(Puppet::Error, %r{#{property} should be a Hash}) + end + failure_message do |type_class| + "#{type_class} should require #{property} to be a Hash" + end +end + # 'spec_overrides' from sync.yml will appear below this line diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb index b98127c..b56a296 100644 --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -1,171 +1,185 @@ # frozen_string_literal: true require 'beaker-rspec/spec_helper' require 'beaker-rspec/helpers/serverspec' require 'beaker/puppet_install_helper' require 'rspec/retry' begin require 'pry' rescue LoadError # rubocop:disable Lint/HandleExceptions for optional loading end +def idempotent_apply(hosts, manifest, opts = {}, &block) + block_on hosts, opts do |host| + file_path = host.tmpfile('apply_manifest.pp') + create_remote_file(host, file_path, manifest + "\n") + + puppet_apply_opts = { :verbose => nil, 'detailed-exitcodes' => nil } + on_options = { acceptable_exit_codes: [0, 2] } + on host, puppet('apply', file_path, puppet_apply_opts), on_options, &block + puppet_apply_opts2 = { :verbose => nil, 'detailed-exitcodes' => nil } + on_options2 = { acceptable_exit_codes: [0] } + on host, puppet('apply', file_path, puppet_apply_opts2), on_options2, &block + end +end + # This method allows a block to be passed in and if an exception is raised # that matches the 'error_matcher' matcher, the block will wait a set number # of seconds before retrying. # Params: # - max_retry_count - Max number of retries # - retry_wait_interval_secs - Number of seconds to wait before retry # - error_matcher - Matcher which the exception raised must match to allow retry # Example Usage: # retry_on_error_matching(3, 5, /OpenGPG Error/) do # apply_manifest(pp, :catch_failures => true) # end def retry_on_error_matching(max_retry_count = 3, retry_wait_interval_secs = 5, error_matcher = nil) try = 0 begin try += 1 yield rescue StandardError => e raise unless try < max_retry_count && (error_matcher.nil? || e.message =~ error_matcher) sleep retry_wait_interval_secs retry end end run_puppet_install_helper unless ENV['BEAKER_provision'] == 'no' RSpec.configure do |c| # Add exclusive filter for Windows untill all the windows functionality is implemented c.filter_run_excluding win_broken: true # Project root proj_root = File.expand_path(File.join(File.dirname(__FILE__), '..')) # Readable test descriptions c.formatter = :documentation # show retry status in spec process c.verbose_retry = true # show exception that triggers a retry if verbose_retry is set to true c.display_try_failure_messages = true # Configure all nodes in nodeset c.before :suite do # Install module and dependencies hosts.each do |host| next unless not_controller(host) copy_module_to(host, source: proj_root, module_name: 'docker') # Due to RE-6764, running yum update renders the machine unable to install # other software. Thus this workaround. if fact_on(host, 'operatingsystem') == 'RedHat' on(host, 'mv /etc/yum.repos.d/redhat.repo /etc/yum.repos.d/internal-mirror.repo') on(host, 'rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm') end on(host, 'yum update -y -q') if fact_on(host, 'osfamily') == 'RedHat' on host, puppet('module', 'install', 'puppetlabs-stdlib', '--version', '4.24.0'), acceptable_exit_codes: [0, 1] on host, puppet('module', 'install', 'puppetlabs-apt', '--version', '4.4.1'), acceptable_exit_codes: [0, 1] on host, puppet('module', 'install', 'puppetlabs-translate', '--version', '1.0.0'), acceptable_exit_codes: [0, 1] on host, puppet('module', 'install', 'puppetlabs-powershell', '--version', '2.1.5'), acceptable_exit_codes: [0, 1] on host, puppet('module', 'install', 'puppetlabs-reboot', '--version', '2.0.0'), acceptable_exit_codes: [0, 1] # net-tools required for netstat utility being used by some tests if fact_on(host, 'osfamily') == 'RedHat' && fact_on(host, 'operatingsystemmajrelease') == '7' on(host, 'yum install -y net-tools device-mapper') end if fact_on(host, 'osfamily') == 'Debian' on(host, 'apt-get install net-tools') end docker_compose_content_v3 = <<-EOS version: "3.4" x-images: &default-image alpine:3.8 services: compose_test: image: *default-image command: /bin/sh -c "while true; do echo hello world; sleep 1; done" EOS docker_compose_override_v3 = <<-EOS version: "3.4" x-images: &default-image debian:stable-slim services: compose_test: image: *default-image command: /bin/sh -c "while true; do echo hello world; sleep 1; done" EOS docker_stack_override_v3 = <<-EOS version: "3.4" x-images: &default-image debian:stable-slim services: compose_test: image: *default-image command: /bin/sh -c "while true; do echo hello world; sleep 1; done" EOS docker_compose_content_v3_windows = <<-EOS version: "3" services: compose_test: image: winamd64/hello-world command: cmd.exe /C "ping 8.8.8.8 -t" networks: default: external: name: nat EOS docker_compose_override_v3_windows = <<-EOS version: "3" services: compose_test: image: winamd64/hello-world:nanoserver-sac2016 command: cmd.exe /C "ping 8.8.8.8 -t" networks: default: external: name: nat EOS docker_stack_content_windows = <<-EOS version: "3" services: compose_test: image: winamd64/hello-world command: cmd.exe /C "ping 8.8.8.8 -t" EOS docker_stack_override_windows = <<-EOS version: "3" services: compose_test: image: winamd64/hello-world:nanoserver-sac2016 EOS if fact_on(host, 'osfamily') == 'windows' create_remote_file(host, '/tmp/docker-compose-v3.yml', docker_compose_content_v3_windows) create_remote_file(host, '/tmp/docker-stack.yml', docker_stack_content_windows) create_remote_file(host, '/tmp/docker-compose-override-v3.yml', docker_compose_override_v3_windows) create_remote_file(host, '/tmp/docker-stack-override.yml', docker_stack_override_windows) else create_remote_file(host, '/tmp/docker-compose-v3.yml', docker_compose_content_v3) create_remote_file(host, '/tmp/docker-stack.yml', docker_compose_content_v3) create_remote_file(host, '/tmp/docker-compose-override-v3.yml', docker_compose_override_v3) create_remote_file(host, '/tmp/docker-stack-override.yml', docker_stack_override_v3) end next unless fact_on(host, 'osfamily') == 'windows' win_host = only_host_with_role(hosts, 'default') retry_on_error_matching(60, 5, %r{connection failure running}) do @windows_ip = win_host.ip end apply_manifest_on(host, "class { 'docker': docker_ee => true, extra_parameters => '\"insecure-registries\": [ \"#{@windows_ip}:5000\" ]' }") docker_path = '/cygdrive/c/Program Files/Docker' host.add_env_var('PATH', docker_path) host.add_env_var('TEMP', 'C:\Users\Administrator\AppData\Local\Temp') puts 'Waiting for box to come online' sleep 300 end end end diff --git a/spec/unit/docker_network_spec.rb b/spec/unit/docker_network_spec.rb deleted file mode 100644 index 2d07012..0000000 --- a/spec/unit/docker_network_spec.rb +++ /dev/null @@ -1,63 +0,0 @@ -require 'spec_helper' - -network = Puppet::Type.type(:docker_network) - -describe network do - - let :params do - [ - :name, - :provider, - :subnet, - :gateway, - :ip_range, - :aux_address, - :options, - ] - end - - let :properties do - [ - :ensure, - :driver, - :ipam_driver, - :id, - ] - end - - it 'should have expected properties' do - properties.each do |property| - expect(network.properties.map(&:name)).to be_include(property) - end - end - - it 'should have expected parameters' do - params.each do |param| - expect(network.parameters).to be_include(param) - end - end -end - -describe Puppet::Type.type(:docker_network).provider(:docker_network) do - let(:provider) { resource.provider } - let(:instance) { provider.class.instances.first } - let(:resource) do - Puppet::Type.type(:docker_network).new( - ensure: :present, - name: 'test-network', - driver: 'host', - subnet: ['192.168.3.0/24', '10.0.0.0/24'] - ) - end - - before :each do - Puppet::Util.stubs(:which).with('docker').returns('/usr/local/bin/docker') - end - - describe 'create' do - it 'creates a docker network' do - provider.class.expects(:docker).with(["network", "create", "--driver=#{resource[:driver]}", "--subnet=#{resource[:subnet][0]}", "--subnet=#{resource[:subnet][1]}", resource[:name]]) - expect(provider.create).to be_nil - end - end -end \ No newline at end of file diff --git a/spec/unit/docker_facts_spec.rb b/spec/unit/lib/facter/docker_spec.rb similarity index 80% rename from spec/unit/docker_facts_spec.rb rename to spec/unit/lib/facter/docker_spec.rb index 91ee847..d16ea17 100644 --- a/spec/unit/docker_facts_spec.rb +++ b/spec/unit/lib/facter/docker_spec.rb @@ -1,96 +1,93 @@ require 'spec_helper' require 'json' - -describe Facter::Util::Fact, type: :fact do +describe 'Facter::Util::Fact' do before :each do Facter.clear if Facter.value(:kernel) == 'windows' docker_command = 'powershell -NoProfile -NonInteractive -NoLogo -ExecutionPolicy Bypass -c docker' Facter::Util::Resolution.stubs(:which).with('docker').returns('C:\Program Files\Docker\docker.exe') else docker_command = 'docker' Facter::Util::Resolution.stubs(:which).with('docker').returns('/usr/bin/docker') end docker_info = File.read(fixtures('facts', 'docker_info')) Facter::Util::Resolution.stubs(:exec).with("#{docker_command} info --format '{{json .}}'").returns(docker_info) processors = File.read(fixtures('facts', 'processors')) Facter.fact(:processors).stubs(:value).returns(JSON.parse(processors)) docker_network_list = File.read(fixtures('facts', 'docker_network_list')) Facter::Util::Resolution.stubs(:exec).with("#{docker_command} network ls | tail -n +2").returns(docker_network_list) - docker_network_names = Array.new - docker_network_list.each_line {|line| docker_network_names.push line.split[1] } + docker_network_names = [] + docker_network_list.each_line { |line| docker_network_names.push line.split[1] } docker_network_names.each do |network| inspect = File.read(fixtures('facts', "docker_network_inspect_#{network}")) Facter::Util::Resolution.stubs(:exec).with("#{docker_command} network inspect #{network}").returns(inspect) end end - after { Facter.clear } + after(:each) { Facter.clear } describe 'docker fact with composer network' do before :each do - docker_info = File.read(fixtures('facts', 'docker_info')) Facter.fact(:interfaces).stubs(:value).returns('br-c5810f1e3113,docker0,eth0,lo') - end it do fact = File.read(fixtures('facts', 'facts_with_compose')) - fact = JSON.parse(fact.to_json, {:quirks_mode => true}) - facts = eval(fact) + fact = JSON.parse(fact.to_json, quirks_mode: true) + facts = eval(fact) # rubocop:disable Security/Eval expect(Facter.fact(:docker).value).to include( - 'network' => facts['network'] + 'network' => facts['network'], ) end end describe 'docker fact without composer network' do before :each do Facter.fact(:interfaces).stubs(:value).returns('br-19a6ebf6f5a5,docker0,eth0,lo') end it do fact = File.read(fixtures('facts', 'facts_without_compose')).chomp fact_json = fact.to_json - facts = JSON.parse(fact_json, {:quirks_mode => true}) - facts = eval(facts) + facts = JSON.parse(fact_json, quirks_mode: true) + facts = eval(facts) # rubocop:disable Security/Eval + expect(Facter.fact(:docker).value).to include( - 'network' => facts['network'] + 'network' => facts['network'], ) end end - describe'docker client version' do - before do + describe 'docker client version' do + before(:each) do docker_version = File.read(fixtures('facts', 'docker_version')) Facter.fact(:docker_version).stubs(:value).returns(JSON.parse(docker_version)) Facter.fact(:interfaces).stubs(:value).returns('br-19a6ebf6f5a5,docker0,eth0,lo') - end it do expect(Facter.fact(:docker_client_version).value).to eq( - '17.03.1-ce-client' + '17.03.1-ce-client', ) end end describe 'docker server version' do - before do + before(:each) do docker_version = File.read(fixtures('facts', 'docker_version')) Facter.fact(:docker_version).stubs(:value).returns(JSON.parse(docker_version)) Facter.fact(:interfaces).stubs(:value).returns('br-19a6ebf6f5a5,docker0,eth0,lo') end it do expect(Facter.fact(:docker_server_version).value).to eq( - '17.03.1-ce-server' + '17.03.1-ce-server', ) end end describe 'docker info' do it 'has valid entries' do expect(Facter.fact(:docker).value).to include( - 'Architecture' => 'x86_64' + 'Architecture' => 'x86_64', ) end end end diff --git a/spec/unit/lib/puppet/provider/docker_network_spec.rb b/spec/unit/lib/puppet/provider/docker_network_spec.rb new file mode 100644 index 0000000..e252c51 --- /dev/null +++ b/spec/unit/lib/puppet/provider/docker_network_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper' + +describe Puppet::Type.type(:docker_network).provider(:docker_network) do + let(:provider) { resource.provider } + let(:instance) { provider.class.instances.first } + let(:resource) do + Puppet::Type.type(:docker_network).new( + ensure: :present, + name: 'test-network', + driver: 'host', + subnet: ['192.168.3.0/24', '10.0.0.0/24'], + ) + end + + before :each do + Puppet::Util.stubs(:which).with('docker').returns('/usr/local/bin/docker') + end + + describe 'create' do + it 'creates a docker network' do + provider.class.expects(:docker).with(['network', 'create', "--driver=#{resource[:driver]}", "--subnet=#{resource[:subnet][0]}", "--subnet=#{resource[:subnet][1]}", resource[:name]]) + expect(provider.create).to be_nil + end + end +end diff --git a/spec/unit/docker_compose_spec.rb b/spec/unit/lib/puppet/type/docker_compose_spec.rb similarity index 57% rename from spec/unit/docker_compose_spec.rb rename to spec/unit/lib/puppet/type/docker_compose_spec.rb index 4db1ba6..aec8bb2 100644 --- a/spec/unit/docker_compose_spec.rb +++ b/spec/unit/lib/puppet/type/docker_compose_spec.rb @@ -1,46 +1,45 @@ require 'spec_helper' compose = Puppet::Type.type(:docker_compose) describe compose do - let :params do [ :name, :provider, :scale, :options, :up_args, ] end let :properties do [ :ensure, ] end - it 'should have expected properties' do + it 'has expected properties' do properties.each do |property| expect(compose.properties.map(&:name)).to be_include(property) end end - it 'should have expected parameters' do + it 'has expected parameters' do params.each do |param| expect(compose.parameters).to be_include(param) end end - it 'should require options to be a string' do - expect(compose).to require_string_for('options') + it 'requires options to be a string' do + expect(compose).to require_string_for('options') end - it 'should require up_args to be a string' do - expect(compose).to require_string_for('up_args') + it 'requires up_args to be a string' do + expect(compose).to require_string_for('up_args') end - it 'should require scale to be a hash' do - expect(compose).to require_hash_for('scale') + it 'requires scale to be a hash' do + expect(compose).to require_hash_for('scale') end end diff --git a/spec/unit/lib/puppet/type/docker_network_spec.rb b/spec/unit/lib/puppet/type/docker_network_spec.rb new file mode 100644 index 0000000..ed8444b --- /dev/null +++ b/spec/unit/lib/puppet/type/docker_network_spec.rb @@ -0,0 +1,38 @@ +require 'spec_helper' + +network = Puppet::Type.type(:docker_network) + +describe network do + let :params do + [ + :name, + :provider, + :subnet, + :gateway, + :ip_range, + :aux_address, + :options, + ] + end + + let :properties do + [ + :ensure, + :driver, + :ipam_driver, + :id, + ] + end + + it 'has expected properties' do + properties.each do |property| + expect(network.properties.map(&:name)).to be_include(property) + end + end + + it 'has expected parameters' do + params.each do |param| + expect(network.parameters).to be_include(param) + end + end +end diff --git a/spec/unit/docker_stack_spec.rb b/spec/unit/lib/puppet/type/docker_stack_spec.rb similarity index 70% rename from spec/unit/docker_stack_spec.rb rename to spec/unit/lib/puppet/type/docker_stack_spec.rb index 2a5958f..4cfb8ec 100644 --- a/spec/unit/docker_stack_spec.rb +++ b/spec/unit/lib/puppet/type/docker_stack_spec.rb @@ -1,36 +1,35 @@ require 'spec_helper' stack = Puppet::Type.type(:docker_stack) describe stack do - let :params do [ :name, :provider, :up_args, ] end let :properties do [ :ensure, ] end - it 'should have expected properties' do + it 'has expected properties' do properties.each do |property| expect(stack.properties.map(&:name)).to be_include(property) end end - it 'should have expected parameters' do + it 'has expected parameters' do params.each do |param| expect(stack.parameters).to be_include(param) end end - it 'should require up_args to be a string' do - expect(stack).to require_string_for('up_args') + it 'requires up_args to be a string' do + expect(stack).to require_string_for('up_args') end end diff --git a/spec/unit/docker_volume_spec.rb b/spec/unit/lib/puppet/type/docker_volume_spec.rb similarity index 83% rename from spec/unit/docker_volume_spec.rb rename to spec/unit/lib/puppet/type/docker_volume_spec.rb index 8df44af..992449b 100644 --- a/spec/unit/docker_volume_spec.rb +++ b/spec/unit/lib/puppet/type/docker_volume_spec.rb @@ -1,32 +1,32 @@ require 'spec_helper' volume = Puppet::Type.type(:docker_volume) describe volume do let :params do [ :name, :provider, ] end let :properties do [ :driver, :options, :mountpoint, ] end - it 'should have expected properties' do + it 'has expected properties' do properties.each do |property| expect(volume.properties.map(&:name)).to be_include(property) end end - it 'should have expected parameters' do + it 'has expected parameters' do params.each do |param| expect(volume.parameters).to be_include(param) end end -end \ No newline at end of file +end