Skip to content

Commit fdf2b78

Browse files
florindragosMarkW
authored andcommitted
Add docker stack tests (#356)
1 parent b53adc6 commit fdf2b78

File tree

5 files changed

+206
-15
lines changed

5 files changed

+206
-15
lines changed

lib/puppet/parser/functions/docker_stack_flags.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ module Puppet::Parser::Functions
1212
flags << "--bundle-file '#{opts['bundle_file']}'"
1313
end
1414

15-
if opts['compose_file'].to_s != 'undef'
16-
flags << "--compose-file '#{opts['compose_file']}'"
15+
if opts['compose_files'].to_s != 'undef'
16+
opts['compose_files'].each do |file|
17+
flags << "--compose-file '#{file}'"
18+
end
1719
end
1820

1921
if opts['resolve_image'].to_s != 'undef'

manifests/stack.pp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
Optional[Pattern[/^present$|^absent$/]] $ensure = 'present',
4040
Optional[String] $stack_name = undef,
4141
Optional[String] $bundle_file = undef,
42-
Optional[String] $compose_file = undef,
42+
Optional[Array] $compose_files = undef,
4343
Optional[String] $prune = undef,
4444
Optional[String] $with_registry_auth = undef,
4545
Optional[Pattern[/^always$|^changed$|^never$/]] $resolve_image = undef,
@@ -51,17 +51,20 @@
5151

5252
if $::osfamily == 'windows' {
5353
$exec_path = ['C:/Program Files/Docker/']
54-
$check_stack = "${docker_command} ls | select-string -pattern ${stack_name}"
54+
$check_stack = '$info = docker stack ls | select-string -pattern web
55+
if ($info -eq $null) { Exit 1 } else { Exit 0 }'
56+
$provider = 'powershell'
5557
} else {
5658
$exec_path = ['/bin', '/usr/bin']
5759
$check_stack = "${docker_command} ls | grep ${stack_name}"
60+
$provider = undef
5861
}
5962

6063
if $ensure == 'present'{
6164
$docker_stack_flags = docker_stack_flags ({
6265
stack_name => $stack_name,
6366
bundle_file => $bundle_file,
64-
compose_file => $compose_file,
67+
compose_files => $compose_files,
6568
prune => $prune,
6669
with_registry_auth => $with_registry_auth,
6770
resolve_image => $resolve_image,
@@ -70,18 +73,20 @@
7073
$exec_stack = "${docker_command} deploy ${docker_stack_flags} ${stack_name}"
7174

7275
exec { "docker stack create ${stack_name}":
73-
command => $exec_stack,
74-
unless => $check_stack,
75-
path => $exec_path,
76+
command => $exec_stack,
77+
unless => $check_stack,
78+
path => $exec_path,
79+
provider => $provider,
7680
}
7781
}
7882

7983
if $ensure == 'absent'{
8084

81-
exec { "docker stack ${stack_name}":
82-
command => "${docker_command} rm ${stack_name}",
83-
onlyif => $check_stack,
84-
path => $exec_path,
85+
exec { "docker stack destroy ${stack_name}":
86+
command => "${docker_command} rm ${stack_name}",
87+
onlyif => $check_stack,
88+
path => $exec_path,
89+
provider => $provider,
8590
}
8691
}
8792
}

spec/acceptance/stack_spec.rb

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
require 'spec_helper_acceptance'
2+
3+
if fact('osfamily') == 'windows'
4+
docker_args = 'docker_ee => true'
5+
tmp_path = 'C:/cygwin64/tmp'
6+
test_container = 'nanoserver-sac2016'
7+
wait_for_container_seconds = 120
8+
else
9+
docker_args = ''
10+
tmp_path = '/tmp'
11+
test_container = 'debian'
12+
wait_for_container_seconds = 10
13+
end
14+
15+
describe 'docker stack' do
16+
before(:all) do
17+
retry_on_error_matching(60, 5, /connection failure running/) do
18+
@install_code = <<-code
19+
class { 'docker': #{docker_args} }
20+
docker::swarm {'cluster_manager':
21+
init => true,
22+
ensure => 'present',
23+
}
24+
code
25+
apply_manifest(@install_code, :catch_failures=>true)
26+
end
27+
end
28+
29+
context 'Creating stack' do
30+
let(:install) {"
31+
docker::stack { 'web':
32+
stack_name => 'web',
33+
compose_files => ['#{tmp_path}/docker-stack.yml'],
34+
ensure => present,
35+
}"
36+
}
37+
38+
it 'should deploy stack' do
39+
apply_manifest(install, :catch_failures=>true)
40+
sleep wait_for_container_seconds
41+
end
42+
43+
it 'should be idempotent' do
44+
apply_manifest(install, :catch_changes=>true)
45+
end
46+
47+
it 'should find a stack' do
48+
shell('docker stack ls') do |r|
49+
expect(r.stdout).to match(/web/)
50+
end
51+
end
52+
53+
it 'should find a docker container' do
54+
shell("docker ps | grep web_compose_test", :acceptable_exit_codes => [0])
55+
end
56+
end
57+
58+
context 'Destroying stack' do
59+
let(:install) {"
60+
docker::stack { 'web':
61+
stack_name => 'web',
62+
compose_files => ['#{tmp_path}/docker-stack.yml'],
63+
ensure => present,
64+
}"
65+
}
66+
let(:destroy) {"
67+
docker::stack { 'web':
68+
stack_name => 'web',
69+
compose_files => ['#{tmp_path}/docker-stack.yml'],
70+
ensure => absent,
71+
}"
72+
}
73+
it 'should run successfully' do
74+
apply_manifest(destroy, :catch_failures=>true)
75+
end
76+
77+
it 'should be idempotent' do
78+
apply_manifest(destroy, :catch_changes=>true)
79+
end
80+
81+
it 'should not find a docker stack' do
82+
shell('docker stack ls') do |r|
83+
expect(r.stdout).to_not match(/web/)
84+
end
85+
end
86+
end
87+
88+
context 'creating stack with multi compose files' do
89+
90+
before(:all) do
91+
@install_code = <<-code
92+
docker::stack { 'web':
93+
stack_name => 'web',
94+
compose_files => ['#{tmp_path}/docker-stack.yml', '#{tmp_path}/docker-stack-override.yml'],
95+
ensure => present,
96+
}
97+
code
98+
99+
apply_manifest(@install_code, :catch_failures=>true)
100+
end
101+
102+
it "should find container with web_compose_test tag" do
103+
sleep wait_for_container_seconds
104+
shell("docker ps | grep web_compose_test", :acceptable_exit_codes => [0])
105+
end
106+
end
107+
108+
context 'Destroying project with multiple compose files' do
109+
before(:all) do
110+
@install_code = <<-code
111+
docker::stack { 'web':
112+
stack_name => 'web',
113+
compose_files => ['#{tmp_path}/docker-stack.yml', '#{tmp_path}/docker-stack-override.yml'],
114+
ensure => present,
115+
}
116+
code
117+
118+
apply_manifest(@install_code, :catch_failures=>true)
119+
120+
@destroy_code = <<-code
121+
docker::stack { 'web':
122+
stack_name => 'web',
123+
compose_files => ['#{tmp_path}/docker-stack.yml', '#{tmp_path}/docker-stack-override.yml'],
124+
ensure => absent,
125+
}
126+
code
127+
128+
apply_manifest(@destroy_code, :catch_failures=>true)
129+
sleep 5 # wait for containers to stop
130+
end
131+
132+
it 'should be idempotent' do
133+
apply_manifest(@destroy_code, :catch_changes=>true)
134+
end
135+
136+
it 'should not find a docker stack' do
137+
shell('docker stack ls') do |r|
138+
expect(r.stdout).to_not match(/web/)
139+
end
140+
end
141+
142+
it 'should not find a docker container' do
143+
shell("docker ps | grep #{test_container}", :acceptable_exit_codes => [1])
144+
end
145+
end
146+
147+
end

spec/defines/stack.rb renamed to spec/defines/stack_spec.rb

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,29 @@
2424
context 'Create stack with compose file' do
2525
let(:params) { {
2626
'stack_name' => 'foo',
27-
'compose_file' => '/tmp/docker-compose.yaml',
27+
'compose_files' => ['/tmp/docker-compose.yaml'],
2828
'resolve_image' => 'always',
2929
} }
30-
it { should contain_exec('docker stack deploy').with_command(/docker stack deploy/) }
30+
it { should contain_exec('docker stack create foo').with_command(/docker stack deploy/) }
31+
it { should contain_exec('docker stack create foo').with_command(/--compose-file '\/tmp\/docker-compose.yaml'/) }
32+
end
33+
34+
context 'Create stack with multiple compose files' do
35+
let(:params) { {
36+
'stack_name' => 'foo',
37+
'compose_files' => ['/tmp/docker-compose.yaml', '/tmp/docker-compose-2.yaml'],
38+
'resolve_image' => 'always',
39+
} }
40+
it { should contain_exec('docker stack create foo').with_command(/docker stack deploy/) }
41+
it { should contain_exec('docker stack create foo').with_command(/--compose-file '\/tmp\/docker-compose.yaml'/) }
42+
it { should contain_exec('docker stack create foo').with_command(/--compose-file '\/tmp\/docker-compose-2.yaml'/) }
3143
end
3244

3345
context 'with ensure => absent' do
3446
let(:params) { {
3547
'ensure' => 'absent',
3648
'stack_name' => 'foo'} }
37-
it { should contain_exec('docker stack rm').with_command(/docker stack rm/) }
49+
it { should contain_exec('docker stack destroy foo').with_command(/docker stack rm/) }
3850
end
3951
end
4052
end

spec/spec_helper_acceptance.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,13 @@ def retry_on_error_matching(max_retry_count = 3, retry_wait_interval_secs = 5, e
8282
EOS
8383
docker_compose_override_v3 = <<-EOS
8484
version: "3.4"
85+
services:
86+
compose_test:
87+
image: debian:jessie
88+
command: /bin/sh -c "while true; do echo hello world; sleep 1; done"
89+
EOS
90+
docker_stack_override_v3 = <<-EOS
91+
version: "3.4"
8592
services:
8693
compose_test:
8794
image: debian:jessie
@@ -108,13 +115,31 @@ def retry_on_error_matching(max_retry_count = 3, retry_wait_interval_secs = 5, e
108115
default:
109116
external:
110117
name: nat
118+
EOS
119+
docker_stack_content_windows = <<-EOS
120+
version: "3"
121+
services:
122+
compose_test:
123+
image: hello-world:nanoserver
124+
command: cmd.exe /C "ping /t 8.8.8.8"
125+
EOS
126+
docker_stack_override_windows = <<-EOS
127+
version: "3"
128+
services:
129+
compose_test:
130+
image: hello-world:nanoserver-sac2016
131+
command: cmd.exe /C "ping /t 8.8.8.8"
111132
EOS
112133
if fact_on(host, 'osfamily') == 'windows'
113134
create_remote_file(host, "/tmp/docker-compose-v3.yml", docker_compose_content_v3_windows)
135+
create_remote_file(host, "/tmp/docker-stack.yml", docker_stack_content_windows)
114136
create_remote_file(host, "/tmp/docker-compose-override-v3.yml", docker_compose_override_v3_windows)
137+
create_remote_file(host, "/tmp/docker-stack-override.yml", docker_stack_override_windows)
115138
else
116139
create_remote_file(host, "/tmp/docker-compose-v3.yml", docker_compose_content_v3)
140+
create_remote_file(host, "/tmp/docker-stack.yml", docker_compose_content_v3)
117141
create_remote_file(host, "/tmp/docker-compose-override-v3.yml", docker_compose_override_v3)
142+
create_remote_file(host, "/tmp/docker-stack-override.yml", docker_stack_override_v3)
118143
end
119144

120145
if fact_on(host, 'osfamily') == 'windows'

0 commit comments

Comments
 (0)