beaker 0.0.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/.travis.yml +8 -0
- data/README.md +6 -6
- data/beaker.gemspec +6 -2
- data/lib/beaker.rb +1 -1
- data/lib/beaker/answers.rb +34 -7
- data/lib/beaker/answers/version20.rb +124 -0
- data/lib/beaker/answers/version28.rb +21 -0
- data/lib/beaker/answers/version30.rb +24 -5
- data/lib/beaker/cli.rb +55 -41
- data/lib/beaker/command.rb +2 -2
- data/lib/beaker/dsl/helpers.rb +320 -106
- data/lib/beaker/dsl/install_utils.rb +202 -81
- data/lib/beaker/dsl/roles.rb +40 -0
- data/lib/beaker/host.rb +28 -20
- data/lib/beaker/host/unix.rb +7 -4
- data/lib/beaker/host/unix/pkg.rb +42 -12
- data/lib/beaker/host/windows.rb +9 -5
- data/lib/beaker/host/windows/group.rb +1 -1
- data/lib/beaker/host/windows/pkg.rb +41 -8
- data/lib/beaker/hypervisor.rb +23 -10
- data/lib/beaker/hypervisor/aixer.rb +15 -19
- data/lib/beaker/hypervisor/blimper.rb +71 -72
- data/lib/beaker/hypervisor/fusion.rb +11 -10
- data/lib/beaker/hypervisor/solaris.rb +17 -23
- data/lib/beaker/hypervisor/vagrant.rb +27 -12
- data/lib/beaker/hypervisor/vcloud.rb +154 -138
- data/lib/beaker/hypervisor/vcloud_pooled.rb +97 -0
- data/lib/beaker/hypervisor/vsphere.rb +8 -5
- data/lib/beaker/hypervisor/vsphere_helper.rb +43 -33
- data/lib/beaker/network_manager.rb +16 -12
- data/lib/beaker/options/command_line_parser.rb +199 -0
- data/lib/beaker/options/hosts_file_parser.rb +39 -0
- data/lib/beaker/options/options_file_parser.rb +45 -0
- data/lib/beaker/options/options_hash.rb +294 -0
- data/lib/beaker/options/parser.rb +288 -0
- data/lib/beaker/options/pe_version_scraper.rb +35 -0
- data/lib/beaker/options/presets.rb +70 -0
- data/lib/beaker/shared.rb +2 -1
- data/lib/beaker/shared/host_handler.rb +7 -2
- data/lib/beaker/shared/repetition.rb +1 -0
- data/lib/beaker/shared/timed.rb +14 -0
- data/lib/beaker/test_case.rb +2 -38
- data/lib/beaker/test_suite.rb +11 -25
- data/lib/beaker/utils/repo_control.rb +6 -8
- data/lib/beaker/utils/setup_helper.rb +9 -20
- data/spec/beaker/answers_spec.rb +109 -0
- data/spec/beaker/command_spec.rb +2 -2
- data/spec/beaker/dsl/assertions_spec.rb +1 -3
- data/spec/beaker/dsl/helpers_spec.rb +519 -84
- data/spec/beaker/dsl/install_utils_spec.rb +265 -16
- data/spec/beaker/dsl/roles_spec.rb +31 -10
- data/spec/beaker/host/windows/group_spec.rb +55 -0
- data/spec/beaker/host_spec.rb +130 -40
- data/spec/beaker/hypervisor/aixer_spec.rb +34 -0
- data/spec/beaker/hypervisor/blimper_spec.rb +77 -0
- data/spec/beaker/hypervisor/fusion_spec.rb +26 -0
- data/spec/beaker/hypervisor/hypervisor_spec.rb +66 -0
- data/spec/beaker/hypervisor/solaris_spec.rb +39 -0
- data/spec/beaker/hypervisor/vagrant_spec.rb +105 -0
- data/spec/beaker/hypervisor/vcloud_pooled_spec.rb +60 -0
- data/spec/beaker/hypervisor/vcloud_spec.rb +70 -0
- data/spec/beaker/hypervisor/vsphere_helper_spec.rb +162 -0
- data/spec/beaker/hypervisor/vsphere_spec.rb +76 -0
- data/spec/beaker/options/command_line_parser_spec.rb +25 -0
- data/spec/beaker/options/data/LATEST +1 -0
- data/spec/beaker/options/data/badyaml.cfg +21 -0
- data/spec/beaker/options/data/hosts.cfg +21 -0
- data/spec/beaker/options/data/opts.txt +6 -0
- data/spec/beaker/options/hosts_file_parser_spec.rb +30 -0
- data/spec/beaker/options/options_file_parser_spec.rb +23 -0
- data/spec/beaker/options/options_hash_spec.rb +111 -0
- data/spec/beaker/options/parser_spec.rb +172 -0
- data/spec/beaker/options/pe_version_scaper_spec.rb +15 -0
- data/spec/beaker/options/presets_spec.rb +24 -0
- data/spec/beaker/puppet_command_spec.rb +54 -21
- data/spec/beaker/shared/error_handler_spec.rb +40 -0
- data/spec/beaker/shared/host_handler_spec.rb +104 -0
- data/spec/beaker/shared/repetition_spec.rb +72 -0
- data/spec/beaker/test_suite_spec.rb +3 -16
- data/spec/beaker/utils/ntp_control_spec.rb +42 -0
- data/spec/beaker/utils/repo_control_spec.rb +168 -0
- data/spec/beaker/utils/setup_helper_spec.rb +82 -0
- data/spec/beaker/utils/validator_spec.rb +58 -0
- data/spec/helpers.rb +97 -0
- data/spec/matchers.rb +39 -0
- data/spec/mock_blimpy.rb +48 -0
- data/spec/mock_fission.rb +60 -0
- data/spec/mock_vsphere.rb +310 -0
- data/spec/mock_vsphere_helper.rb +183 -0
- data/spec/mocks.rb +83 -0
- data/spec/spec_helper.rb +8 -1
- metadata +106 -13
- data/beaker.rb +0 -10
- data/lib/beaker/options_parsing.rb +0 -323
- data/lib/beaker/test_config.rb +0 -148
- data/spec/beaker/options_parsing_spec.rb +0 -37
- data/spec/mocks_and_helpers.rb +0 -34
|
@@ -3,21 +3,37 @@ require 'spec_helper'
|
|
|
3
3
|
class ClassMixedWithDSLInstallUtils
|
|
4
4
|
include Beaker::DSL::InstallUtils
|
|
5
5
|
include Beaker::DSL::Structure
|
|
6
|
+
include Beaker::DSL::Roles
|
|
6
7
|
end
|
|
7
8
|
|
|
8
9
|
describe ClassMixedWithDSLInstallUtils do
|
|
10
|
+
let(:basic_hosts) { make_hosts( { :pe_ver => '3.0',
|
|
11
|
+
:platform => 'linux',
|
|
12
|
+
:roles => [ 'agent' ] } ) }
|
|
13
|
+
let(:hosts) { basic_hosts[0][:roles] = ['master', 'database', 'dashboard']
|
|
14
|
+
basic_hosts[1][:platform] = 'windows'
|
|
15
|
+
basic_hosts }
|
|
16
|
+
let(:winhost) { make_host( 'winhost', { :platform => 'windows',
|
|
17
|
+
:pe_ver => '3.0',
|
|
18
|
+
:working_dir => '/tmp' } ) }
|
|
19
|
+
let(:unixhost) { make_host( 'unixhost', { :platform => 'linux',
|
|
20
|
+
:pe_ver => '3.0',
|
|
21
|
+
:working_dir => '/tmp',
|
|
22
|
+
:dist => 'puppet-enterprise-3.1.0-rc0-230-g36c9e5c-debian-7-i386' } ) }
|
|
23
|
+
|
|
24
|
+
|
|
9
25
|
context 'extract_repo_info_from' do
|
|
10
|
-
[{:protocol => 'git', :path => 'git://github.com/puppetlabs/project.git'},
|
|
11
|
-
{:protocol => 'ssh', :path => 'git@github.com:puppetlabs/project.git'},
|
|
12
|
-
{:protocol => 'https', :path => 'https://github.com:puppetlabs/project'},
|
|
13
|
-
{:protocol => 'file', :path => 'file:///home/example/project'}
|
|
26
|
+
[{ :protocol => 'git', :path => 'git://github.com/puppetlabs/project.git' },
|
|
27
|
+
{ :protocol => 'ssh', :path => 'git@github.com:puppetlabs/project.git' },
|
|
28
|
+
{ :protocol => 'https', :path => 'https://github.com:puppetlabs/project' },
|
|
29
|
+
{ :protocol => 'file', :path => 'file:///home/example/project' }
|
|
14
30
|
].each do |type|
|
|
15
|
-
it "handles #{type[:protocol]} uris" do
|
|
16
|
-
uri = "#{type[:path]}#master"
|
|
31
|
+
it "handles #{ type[:protocol] } uris" do
|
|
32
|
+
uri = "#{ type[:path] }#master"
|
|
17
33
|
repo_info = subject.extract_repo_info_from uri
|
|
18
|
-
expect(repo_info[:name]).to be == 'project'
|
|
19
|
-
expect(repo_info[:path]).to be == type[:path]
|
|
20
|
-
expect(repo_info[:rev]).to be == 'master'
|
|
34
|
+
expect( repo_info[:name] ).to be == 'project'
|
|
35
|
+
expect( repo_info[:path] ).to be == type[:path]
|
|
36
|
+
expect( repo_info[:rev] ).to be == 'master'
|
|
21
37
|
end
|
|
22
38
|
end
|
|
23
39
|
end
|
|
@@ -25,7 +41,7 @@ describe ClassMixedWithDSLInstallUtils do
|
|
|
25
41
|
context 'order_packages' do
|
|
26
42
|
it 'orders facter, hiera before puppet, before anything else' do
|
|
27
43
|
named_repos = [
|
|
28
|
-
{:name => 'puppet_plugin'}, {:name => 'puppet'}, {:name => 'facter'}
|
|
44
|
+
{ :name => 'puppet_plugin' }, { :name => 'puppet' }, { :name => 'facter' }
|
|
29
45
|
]
|
|
30
46
|
ordered_repos = subject.order_packages named_repos
|
|
31
47
|
expect( ordered_repos[0][:name] ).to be == 'facter'
|
|
@@ -36,19 +52,19 @@ describe ClassMixedWithDSLInstallUtils do
|
|
|
36
52
|
|
|
37
53
|
context 'find_git_repo_versions' do
|
|
38
54
|
it 'returns a hash of :name => version' do
|
|
39
|
-
host =
|
|
40
|
-
repository = {:name => 'name'}
|
|
55
|
+
host = double( 'Host' )
|
|
56
|
+
repository = { :name => 'name' }
|
|
41
57
|
path = '/path/to/repo'
|
|
42
58
|
cmd = 'cd /path/to/repo/name && git describe || true'
|
|
43
59
|
logger = double.as_null_object
|
|
44
60
|
|
|
45
61
|
subject.should_receive( :logger ).and_return( logger )
|
|
46
|
-
subject.should_receive( :on ).with(host, cmd).and_yield
|
|
62
|
+
subject.should_receive( :on ).with( host, cmd ).and_yield
|
|
47
63
|
subject.should_receive( :stdout ).and_return( '2' )
|
|
48
64
|
|
|
49
|
-
version = subject.find_git_repo_versions(host, path, repository)
|
|
65
|
+
version = subject.find_git_repo_versions( host, path, repository )
|
|
50
66
|
|
|
51
|
-
expect(version).to be == {'name' => '2'}
|
|
67
|
+
expect( version ).to be == { 'name' => '2' }
|
|
52
68
|
end
|
|
53
69
|
end
|
|
54
70
|
|
|
@@ -61,10 +77,243 @@ describe ClassMixedWithDSLInstallUtils do
|
|
|
61
77
|
host = { 'platform' => 'debian' }
|
|
62
78
|
logger = double.as_null_object
|
|
63
79
|
|
|
64
|
-
subject.should_receive( :logger ).
|
|
80
|
+
subject.should_receive( :logger ).exactly( 3 ).times.and_return( logger )
|
|
65
81
|
subject.should_receive( :on ).exactly( 4 ).times
|
|
66
82
|
|
|
67
83
|
subject.install_from_git( host, path, repo )
|
|
68
84
|
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
describe 'sorted_hosts' do
|
|
88
|
+
it 'can reorder so that the master comes first' do
|
|
89
|
+
subject.stub( :hosts ).and_return( [ hosts[1], hosts[0], hosts[2] ] )
|
|
90
|
+
expect( subject.sorted_hosts ).to be === hosts
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it 'leaves correctly ordered hosts alone' do
|
|
94
|
+
subject.stub( :hosts ).and_return( hosts )
|
|
95
|
+
expect( subject.sorted_hosts ).to be === hosts
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
describe 'version_is_less' do
|
|
100
|
+
|
|
101
|
+
it 'reports 3.0.0-160-gac44cfb is not less than 3.0.0' do
|
|
102
|
+
expect( subject.version_is_less( '3.0.0-160-gac44cfb', '3.0.0' ) ).to be === false
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it 'reports 3.0.0-160-gac44cfb is not less than 2.8.2' do
|
|
106
|
+
expect( subject.version_is_less( '3.0.0-160-gac44cfb', '2.8.2' ) ).to be === false
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it 'reports 3.0.0 is less than 3.0.0-160-gac44cfb' do
|
|
110
|
+
expect( subject.version_is_less( '3.0.0', '3.0.0-160-gac44cfb' ) ).to be === true
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
it 'reports 2.8.2 is less than 3.0.0-160-gac44cfb' do
|
|
114
|
+
expect( subject.version_is_less( '2.8.2', '3.0.0-160-gac44cfb' ) ).to be === true
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it 'reports 2.8 is less than 3.0.0-160-gac44cfb' do
|
|
118
|
+
expect( subject.version_is_less( '2.8', '3.0.0-160-gac44cfb' ) ).to be === true
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it 'reports 2.8 is less than 2.9' do
|
|
122
|
+
expect( subject.version_is_less( '2.8', '2.9' ) ).to be === true
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
describe 'installer_cmd' do
|
|
127
|
+
|
|
128
|
+
it 'generates a windows PE install command for a windows host' do
|
|
129
|
+
expect( subject.installer_cmd( winhost, {} ) ).to be === "cd /tmp && msiexec.exe /qn /i puppet-enterprise-3.0.msi"
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
it 'generates a unix PE install command for a unix host' do
|
|
133
|
+
expect( subject.installer_cmd( unixhost, { :installer => 'puppet-enterprise-installer' } ) ).to be === "cd /tmp/puppet-enterprise-3.1.0-rc0-230-g36c9e5c-debian-7-i386 && ./puppet-enterprise-installer"
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
describe 'fetch_puppet' do
|
|
138
|
+
|
|
139
|
+
it 'can push a local PE .tar.gz to a host and unpack it' do
|
|
140
|
+
File.stub( :directory? ).and_return( true ) #is local
|
|
141
|
+
File.stub( :exists? ).and_return( true ) #is a .tar.gz
|
|
142
|
+
unixhost['pe_dir'] = '/local/file/path'
|
|
143
|
+
subject.stub( :scp_to ).and_return( true )
|
|
144
|
+
|
|
145
|
+
path = unixhost['pe_dir']
|
|
146
|
+
filename = "#{ unixhost['dist'] }"
|
|
147
|
+
extension = '.tar.gz'
|
|
148
|
+
subject.should_receive( :scp_to ).with( unixhost, "#{ path }/#{ filename }#{ extension }", "#{ unixhost['working_dir'] }/#{ filename }#{ extension }" ).once
|
|
149
|
+
subject.should_receive( :on ).with( unixhost, /gunzip/ ).once
|
|
150
|
+
subject.should_receive( :on ).with( unixhost, /tar -xvf/ ).once
|
|
151
|
+
subject.fetch_puppet( [unixhost], {} )
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
it 'can download a PE .tar from a URL to a host and unpack it' do
|
|
155
|
+
File.stub( :directory? ).and_return( false ) #is not local
|
|
156
|
+
unixhost['pe_dir'] = 'http://www.path.com/dir/'
|
|
157
|
+
subject.stub( :link_exists? ) do |arg|
|
|
158
|
+
if arg =~ /.tar.gz/ #there is no .tar.gz link, only a .tar
|
|
159
|
+
false
|
|
160
|
+
else
|
|
161
|
+
true
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
subject.stub( :on ).and_return( true )
|
|
165
|
+
|
|
166
|
+
path = unixhost['pe_dir']
|
|
167
|
+
filename = "#{ unixhost['dist'] }"
|
|
168
|
+
extension = '.tar'
|
|
169
|
+
subject.should_receive( :on ).with( unixhost, "cd #{ unixhost['working_dir'] }; curl #{ path }/#{ filename }#{ extension } -o #{ filename }#{ extension }" ).once
|
|
170
|
+
subject.should_receive( :on ).with( unixhost, /tar -xvf/ ).once
|
|
171
|
+
subject.fetch_puppet( [unixhost], {} )
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
it 'can download a PE .tar.gz from a URL to a host and unpack it' do
|
|
175
|
+
File.stub( :directory? ).and_return( false ) #is not local
|
|
176
|
+
unixhost['pe_dir'] = 'http://www.path.com/dir/'
|
|
177
|
+
subject.stub( :link_exists? ).and_return( true ) #is a tar.gz
|
|
178
|
+
subject.stub( :on ).and_return( true )
|
|
179
|
+
|
|
180
|
+
path = unixhost['pe_dir']
|
|
181
|
+
filename = "#{ unixhost['dist'] }"
|
|
182
|
+
extension = '.tar.gz'
|
|
183
|
+
subject.should_receive( :on ).with( unixhost, "cd #{ unixhost['working_dir'] }; curl #{ path }/#{ filename }#{ extension } -o #{ filename }#{ extension }" ).once
|
|
184
|
+
subject.should_receive( :on ).with( unixhost, /gunzip/ ).once
|
|
185
|
+
subject.should_receive( :on ).with( unixhost, /tar -xvf/ ).once
|
|
186
|
+
subject.fetch_puppet( [unixhost], {} )
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
it 'can push a local PE package to a windows host' do
|
|
190
|
+
File.stub( :directory? ).and_return( true ) #is local
|
|
191
|
+
File.stub( :exists? ).and_return( true ) #is present
|
|
192
|
+
winhost['pe_dir'] = '/local/file/path'
|
|
193
|
+
subject.stub( :scp_to ).and_return( true )
|
|
194
|
+
|
|
195
|
+
path = winhost['pe_dir']
|
|
196
|
+
filename = "puppet-enterprise-#{ winhost['pe_ver'] }"
|
|
197
|
+
extension = '.msi'
|
|
198
|
+
subject.should_receive( :scp_to ).with( winhost, "#{ path }/#{ filename }#{ extension }", "#{ winhost['working_dir'] }/#{ filename }#{ extension }" ).once
|
|
199
|
+
subject.fetch_puppet( [winhost], {} )
|
|
200
|
+
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
describe 'do_install' do
|
|
205
|
+
it 'can preform a simple installation' do
|
|
206
|
+
subject.stub( :on ).and_return( Beaker::Result.new( {}, '' ) )
|
|
207
|
+
subject.stub( :fetch_puppet ).and_return( true )
|
|
208
|
+
subject.stub( :create_remote_file ).and_return( true )
|
|
209
|
+
subject.stub( :sign_certificate_for ).and_return( true )
|
|
210
|
+
subject.stub( :stop_agent_on ).and_return( true )
|
|
211
|
+
subject.stub( :sleep_until_puppetdb_started ).and_return( true )
|
|
212
|
+
subject.stub( :wait_for_host_in_dashboard ).and_return( true )
|
|
213
|
+
subject.stub( :puppet_agent ).and_return( "puppet agent" )
|
|
214
|
+
|
|
215
|
+
subject.stub( :hosts ).and_return( hosts )
|
|
216
|
+
#determine mastercert
|
|
217
|
+
subject.should_receive( :on ).with( hosts[0], /uname/ ).once
|
|
218
|
+
#create working dirs per-host
|
|
219
|
+
subject.should_receive( :on ).with( hosts[0], /mkdir/ ).once
|
|
220
|
+
subject.should_receive( :on ).with( hosts[1], /mkdir/ ).once
|
|
221
|
+
subject.should_receive( :on ).with( hosts[2], /mkdir/ ).once
|
|
222
|
+
#create answers file per-host, except windows
|
|
223
|
+
subject.should_receive( :create_remote_file ).with( hosts[0], /answers/, /q/ ).once
|
|
224
|
+
subject.should_receive( :create_remote_file ).with( hosts[2], /answers/, /q/ ).once
|
|
225
|
+
#run installer on all hosts
|
|
226
|
+
subject.should_receive( :on ).with( hosts[0], /puppet-enterprise-installer/ ).once
|
|
227
|
+
subject.should_receive( :on ).with( hosts[1], /msiexec.exe/ ).once
|
|
228
|
+
subject.should_receive( :on ).with( hosts[2], /puppet-enterprise-installer/ ).once
|
|
229
|
+
#sign certificate per-host
|
|
230
|
+
subject.should_receive( :sign_certificate_for ).with( hosts[0] ).once
|
|
231
|
+
subject.should_receive( :sign_certificate_for ).with( hosts[1] ).once
|
|
232
|
+
subject.should_receive( :sign_certificate_for ).with( hosts[2] ).once
|
|
233
|
+
#stop puppet agent on all hosts
|
|
234
|
+
subject.should_receive( :stop_agent_on ).with( hosts[0] ).once
|
|
235
|
+
subject.should_receive( :stop_agent_on ).with( hosts[1] ).once
|
|
236
|
+
subject.should_receive( :stop_agent_on ).with( hosts[2] ).once
|
|
237
|
+
#wait for puppetdb to start
|
|
238
|
+
subject.should_receive( :sleep_until_puppetdb_started ).with( hosts[0] ).once
|
|
239
|
+
#run each puppet agent once
|
|
240
|
+
subject.should_receive( :on ).with( hosts[0], /puppet agent/, :acceptable_exit_codes => [0,2] ).once
|
|
241
|
+
subject.should_receive( :on ).with( hosts[1], /puppet agent/, :acceptable_exit_codes => [0,2] ).once
|
|
242
|
+
subject.should_receive( :on ).with( hosts[2], /puppet agent/, :acceptable_exit_codes => [0,2] ).once
|
|
243
|
+
#run rake task on dashboard
|
|
244
|
+
subject.should_receive( :on ).with( hosts[0], /\/opt\/puppet\/bin\/rake -sf \/opt\/puppet\/share\/puppet-dashboard\/Rakefile .* RAILS_ENV=production/ ).once
|
|
245
|
+
#wait for all hosts to appear in the dashboard
|
|
246
|
+
subject.should_receive( :wait_for_host_in_dashboard ).with( hosts[0] ).once
|
|
247
|
+
subject.should_receive( :wait_for_host_in_dashboard ).with( hosts[1] ).once
|
|
248
|
+
subject.should_receive( :wait_for_host_in_dashboard ).with( hosts[2] ).once
|
|
249
|
+
#run puppet agent now that installation is complete
|
|
250
|
+
subject.should_receive( :on ).with( hosts, /puppet agent/, :acceptable_exit_codes => [0,2] ).once
|
|
251
|
+
subject.do_install( hosts )
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
describe 'install_pe' do
|
|
256
|
+
|
|
257
|
+
it 'calls do_install with sorted hosts' do
|
|
258
|
+
subject.stub( :hosts ).and_return( [ hosts[1], hosts[0], hosts[2] ] )
|
|
259
|
+
subject.stub( :do_install ).and_return( true )
|
|
260
|
+
subject.should_receive( :do_install ).with( hosts )
|
|
261
|
+
subject.install_pe
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
it 'fills in missing pe_ver' do
|
|
265
|
+
hosts.each do |h|
|
|
266
|
+
h['pe_ver'] = nil
|
|
267
|
+
end
|
|
268
|
+
Beaker::Options::PEVersionScraper.stub( :load_pe_version ).and_return( '2.8' )
|
|
269
|
+
subject.stub( :hosts ).and_return( [ hosts[1], hosts[0], hosts[2] ] )
|
|
270
|
+
subject.stub( :options ).and_return( {} )
|
|
271
|
+
subject.stub( :do_install ).and_return( true )
|
|
272
|
+
subject.should_receive( :do_install ).with( hosts )
|
|
273
|
+
subject.install_pe
|
|
274
|
+
hosts.each do |h|
|
|
275
|
+
expect( h['pe_ver'] ).to be === '2.8'
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
describe 'upgrade_pe' do
|
|
281
|
+
|
|
282
|
+
it 'calls puppet-enterprise-upgrader for pre 3.0 upgrades' do
|
|
283
|
+
Beaker::Options::PEVersionScraper.stub( :load_pe_version ).and_return( '2.8' )
|
|
284
|
+
Beaker::Options::PEVersionScraper.stub( :load_pe_version_win ).and_return( '2.8' )
|
|
285
|
+
subject.stub( :hosts ).and_return( [ hosts[1], hosts[0], hosts[2] ] )
|
|
286
|
+
subject.stub( :options ).and_return( {} )
|
|
287
|
+
version = version_win = '2.8'
|
|
288
|
+
path = "/path/to/upgradepkg"
|
|
289
|
+
subject.should_receive( :do_install ).with( hosts, { :type => :upgrade, :pe_dir => path, :pe_ver => version, :pe_ver_win => version_win, :installer => 'puppet-enterprise-upgrader' } )
|
|
290
|
+
subject.upgrade_pe( path )
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
it 'uses standard upgrader for post 3.0 upgrades' do
|
|
294
|
+
Beaker::Options::PEVersionScraper.stub( :load_pe_version ).and_return( '3.1' )
|
|
295
|
+
Beaker::Options::PEVersionScraper.stub( :load_pe_version_win ).and_return( '3.1' )
|
|
296
|
+
subject.stub( :hosts ).and_return( [ hosts[1], hosts[0], hosts[2] ] )
|
|
297
|
+
subject.stub( :options ).and_return( {} )
|
|
298
|
+
version = version_win = '3.1'
|
|
299
|
+
path = "/path/to/upgradepkg"
|
|
300
|
+
subject.should_receive( :do_install ).with( hosts, { :type => :upgrade, :pe_dir => path, :pe_ver => version, :pe_ver_win => version_win } )
|
|
301
|
+
subject.upgrade_pe( path )
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
it 'updates pe_ver post upgrade' do
|
|
305
|
+
Beaker::Options::PEVersionScraper.stub( :load_pe_version ).and_return( '2.8' )
|
|
306
|
+
Beaker::Options::PEVersionScraper.stub( :load_pe_version_win ).and_return( '2.8' )
|
|
307
|
+
subject.stub( :hosts ).and_return( [ hosts[1], hosts[0], hosts[2] ] )
|
|
308
|
+
subject.stub( :options ).and_return( {} )
|
|
309
|
+
version = version_win = '2.8'
|
|
310
|
+
path = "/path/to/upgradepkg"
|
|
311
|
+
subject.should_receive( :do_install ).with( hosts, { :type => :upgrade, :pe_dir => path, :pe_ver => version, :pe_ver_win => version_win, :installer => 'puppet-enterprise-upgrader' } )
|
|
312
|
+
subject.upgrade_pe( path )
|
|
313
|
+
hosts.each do |h|
|
|
314
|
+
expect( h['pe_ver'] ).to be === '2.8'
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
|
|
69
318
|
end
|
|
70
319
|
end
|
|
@@ -8,16 +8,15 @@ end
|
|
|
8
8
|
|
|
9
9
|
describe ClassMixedWithDSLRoles do
|
|
10
10
|
|
|
11
|
-
let(:hosts) { @hosts || Hash.new
|
|
12
|
-
let(:agent1) {
|
|
13
|
-
let(:agent2) {
|
|
14
|
-
let(:a_and_dash) {
|
|
15
|
-
let(:custom) {
|
|
16
|
-
let(:db) {
|
|
17
|
-
let(:master) {
|
|
18
|
-
let(:
|
|
19
|
-
|
|
20
|
-
end
|
|
11
|
+
let( :hosts ) { @hosts || Hash.new }
|
|
12
|
+
let( :agent1 ) { make_host( 'agent1', { :roles => [ 'agent' ] } ) }
|
|
13
|
+
let( :agent2 ) { make_host( 'agent2', { :roles => [ 'agent' ] } ) }
|
|
14
|
+
let( :a_and_dash ) { make_host( 'a_and_dash', { :roles => [ 'agent', 'dashboard' ] } ) }
|
|
15
|
+
let( :custom ) { make_host( 'custom', { :roles => [ 'custome_role' ] } ) }
|
|
16
|
+
let( :db ) { make_host( 'db', { :roles => [ 'database' ] } ) }
|
|
17
|
+
let( :master ) { make_host( 'master', { :roles => [ 'master', 'agent' ] } ) }
|
|
18
|
+
let( :default ) { make_host( 'default', { :roles => [ 'default'] } ) }
|
|
19
|
+
let( :monolith ) { make_host( 'monolith', { :roles => [ 'agent', 'dashboard', 'database', 'master', 'custom_role'] } ) }
|
|
21
20
|
|
|
22
21
|
describe '#agents' do
|
|
23
22
|
it 'returns an array of hosts that are agents' do
|
|
@@ -83,4 +82,26 @@ describe ClassMixedWithDSLRoles do
|
|
|
83
82
|
expect { subject.database }.to raise_error Beaker::DSL::FailTest
|
|
84
83
|
end
|
|
85
84
|
end
|
|
85
|
+
describe '#default' do
|
|
86
|
+
it 'returns the default host when one is specified' do
|
|
87
|
+
@hosts = [ db, agent1, agent2, default, master]
|
|
88
|
+
subject.should_receive( :hosts ).exactly( 3 ).times.and_return( hosts )
|
|
89
|
+
expect( subject.default ).to be == default
|
|
90
|
+
end
|
|
91
|
+
it 'returns the master if no default host is set' do
|
|
92
|
+
@hosts = [ db, agent1, agent2, master]
|
|
93
|
+
subject.should_receive( :hosts ).exactly( 4 ).times.and_return( hosts )
|
|
94
|
+
expect( subject.default ).to be == master
|
|
95
|
+
end
|
|
96
|
+
it 'returns the only host when only a single host is defined' do
|
|
97
|
+
@hosts = [ agent1 ]
|
|
98
|
+
subject.should_receive( :hosts ).exactly( 2 ).times.and_return( hosts )
|
|
99
|
+
expect( subject.default ).to be == agent1
|
|
100
|
+
end
|
|
101
|
+
it 'raises an error when there is no default (no default, no master, no single host)' do
|
|
102
|
+
@hosts = [ agent1, agent2 ]
|
|
103
|
+
subject.should_receive( :hosts ).exactly( 3 ).times.and_return( hosts )
|
|
104
|
+
expect{ subject.default }.to raise_error Beaker::DSL::FailTest
|
|
105
|
+
end
|
|
106
|
+
end
|
|
86
107
|
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Beaker
|
|
4
|
+
describe Windows::Group do
|
|
5
|
+
class WindowsGroupTest
|
|
6
|
+
include Windows::Group
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
let(:instance) { WindowsGroupTest.new }
|
|
10
|
+
let(:result) { double(:result, :stdout => group_list_output) }
|
|
11
|
+
let(:group_list_output) do <<-EOS
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
Name=Foo
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
Name=Bar6
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
EOS
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def add_group(group_name)
|
|
24
|
+
group_list_output << <<-EOS
|
|
25
|
+
Name=#{group_name}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
EOS
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
before(:each) do
|
|
32
|
+
instance.should_receive(:execute).with(/wmic group where/).and_yield(result)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "gets a group_list" do
|
|
36
|
+
expect(instance.group_list).to eql(["Foo", "Bar6"])
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "gets groups with spaces" do
|
|
40
|
+
add_group("With Spaces")
|
|
41
|
+
expect(instance.group_list).to eql(["Foo", "Bar6", "With Spaces"])
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
it "gets groups with dashes" do
|
|
46
|
+
add_group("With-Dashes")
|
|
47
|
+
expect(instance.group_list).to eql(["Foo", "Bar6", "With-Dashes"])
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "gets groups with underscores" do
|
|
51
|
+
add_group("With_Underscores")
|
|
52
|
+
expect(instance.group_list).to eql(["Foo", "Bar6", "With_Underscores"])
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
data/spec/beaker/host_spec.rb
CHANGED
|
@@ -2,22 +2,21 @@ require 'spec_helper'
|
|
|
2
2
|
|
|
3
3
|
module Beaker
|
|
4
4
|
describe Host do
|
|
5
|
-
let :
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
let(:options) { @options || Hash.new }
|
|
10
|
-
let(:host) { Host.create 'name', options, config }
|
|
5
|
+
let(:options) { @options ? @options : {} }
|
|
6
|
+
let(:platform) { @platform ? { :platform => @platform } : {} }
|
|
7
|
+
let(:host) { make_host( 'name', options.merge(platform) ) }
|
|
11
8
|
|
|
12
9
|
it 'creates a windows host given a windows config' do
|
|
13
10
|
@platform = 'windows'
|
|
14
11
|
expect( host ).to be_a_kind_of Windows::Host
|
|
15
12
|
end
|
|
16
13
|
|
|
17
|
-
it
|
|
14
|
+
it 'defaults to a unix host' do
|
|
15
|
+
expect( host ).to be_a_kind_of Unix::Host
|
|
16
|
+
end
|
|
18
17
|
|
|
19
18
|
it 'can be read like a hash' do
|
|
20
|
-
expect
|
|
19
|
+
expect{ host['value'] }.to_not raise_error
|
|
21
20
|
end
|
|
22
21
|
|
|
23
22
|
it 'can be written like a hash' do
|
|
@@ -25,40 +24,148 @@ module Beaker
|
|
|
25
24
|
expect( host['value'] ).to be === 'blarg'
|
|
26
25
|
end
|
|
27
26
|
|
|
27
|
+
describe "windows hosts" do
|
|
28
|
+
describe "install_package" do
|
|
29
|
+
let(:cygwin) { 'setup-x86.exe' }
|
|
30
|
+
let(:cygwin64) { 'setup-x86_64.exe' }
|
|
31
|
+
let(:package) { 'foo' }
|
|
32
|
+
|
|
33
|
+
before(:each) do
|
|
34
|
+
@platform = 'windows'
|
|
35
|
+
host.stub(:check_for_package).and_return(true)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
context "testing osarchitecture" do
|
|
39
|
+
|
|
40
|
+
before(:each) do
|
|
41
|
+
host.should_receive(:execute).with(/wmic os get osarchitecture/, anything).and_yield(success_osarch_check)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
context "32 bit" do
|
|
45
|
+
let(:success_osarch_check) { double(:success, :exit_code => 0, :stdout => '32-bit') }
|
|
46
|
+
|
|
47
|
+
it "uses 32 bit cygwin" do
|
|
48
|
+
host.should_receive(:execute).with(/#{cygwin}.*#{package}/)
|
|
49
|
+
host.install_package(package)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
context "64 bit" do
|
|
54
|
+
let(:success_osarch_check) { double(:success, :exit_code => 0, :stdout => '64-bit') }
|
|
55
|
+
|
|
56
|
+
it "uses 64 bit cygwin" do
|
|
57
|
+
host.should_receive(:execute).with(/#{cygwin64}.*#{package}/)
|
|
58
|
+
host.install_package(package)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
context "testing os name" do
|
|
64
|
+
let(:failed_osarch_check) { double(:failed, :exit_code => 1) }
|
|
65
|
+
|
|
66
|
+
before(:each) do
|
|
67
|
+
host.should_receive(:execute).with(/wmic os get osarchitecture/, anything).and_yield(failed_osarch_check)
|
|
68
|
+
host.should_receive(:execute).with(/wmic os get name/, anything).and_yield(name_check)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
context "32 bit" do
|
|
72
|
+
let(:name_check) { double(:failure, :exit_code => 1) }
|
|
73
|
+
|
|
74
|
+
it "uses 32 bit cygwin" do
|
|
75
|
+
host.should_receive(:execute).with(/#{cygwin}.*#{package}/)
|
|
76
|
+
host.install_package(package)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
context "64 bit" do
|
|
81
|
+
let(:name_check) { double(:success, :exit_code => 0) }
|
|
82
|
+
|
|
83
|
+
it "uses 64 bit cygwin" do
|
|
84
|
+
host.should_receive(:execute).with(/#{cygwin64}.*#{package}/)
|
|
85
|
+
host.install_package(package)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
28
91
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
92
|
+
describe "executing commands" do
|
|
93
|
+
let(:command) { Beaker::Command.new('ls') }
|
|
94
|
+
let(:host) { Beaker::Host.create('host', make_host_opts('host', options.merge(platform))) }
|
|
95
|
+
let(:result) { Beaker::Result.new(host, 'ls') }
|
|
96
|
+
|
|
97
|
+
before :each do
|
|
98
|
+
result.stdout = 'stdout'
|
|
99
|
+
result.stderr = 'stderr'
|
|
100
|
+
|
|
101
|
+
logger = double(:logger)
|
|
102
|
+
logger.stub(:host_output)
|
|
103
|
+
logger.stub(:debug)
|
|
104
|
+
host.instance_variable_set :@logger, logger
|
|
105
|
+
conn = double(:connection)
|
|
106
|
+
conn.stub(:execute).and_return(result)
|
|
107
|
+
host.instance_variable_set :@connection, conn
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it 'takes a command object and a hash of options'
|
|
111
|
+
it "acts on the host's logger and connection object"
|
|
112
|
+
it 'receives a result object from the connection#execute'
|
|
113
|
+
it "returns the result object"
|
|
114
|
+
|
|
115
|
+
context "controls the result objects logging" do
|
|
116
|
+
it "and passes a test if the exit_code doesn't match the default :acceptable_exit_codes of 0" do
|
|
117
|
+
result.exit_code = 0
|
|
118
|
+
expect{ host.exec(command,{}) }.to_not raise_error
|
|
119
|
+
end
|
|
120
|
+
it "and fails a test if the exit_code doesn't match the default :acceptable_exit_codes of 0" do
|
|
121
|
+
result.exit_code = 1
|
|
122
|
+
expect{ host.exec(command,{}) }.to raise_error
|
|
123
|
+
end
|
|
124
|
+
it "and passes a test if the exit_code matches :acceptable_exit_codes" do
|
|
125
|
+
result.exit_code = 0
|
|
126
|
+
expect{ host.exec(command,{:acceptable_exit_codes => 0}) }.to_not raise_error
|
|
127
|
+
end
|
|
128
|
+
it "and fails a test if the exit_code doesn't match :acceptable_exit_codes" do
|
|
129
|
+
result.exit_code = 0
|
|
130
|
+
expect{ host.exec(command,{:acceptable_exit_codes => 1}) }.to raise_error
|
|
131
|
+
end
|
|
132
|
+
it "and passes a test if the exit_code matches one of the :acceptable_exit_codes" do
|
|
133
|
+
result.exit_code = 127
|
|
134
|
+
expect{ host.exec(command,{:acceptable_exit_codes => [1,127]}) }.to_not raise_error
|
|
135
|
+
end
|
|
136
|
+
it "and passes a test if the exit_code matches one of the range of :acceptable_exit_codes" do
|
|
137
|
+
result.exit_code = 1
|
|
138
|
+
expect{ host.exec(command,{:acceptable_exit_codes => (0..127)}) }.to_not raise_error
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
37
142
|
|
|
38
143
|
# it takes a location and a destination
|
|
39
144
|
# it basically proxies that to the connection object
|
|
40
145
|
it 'do_scp_to logs info and proxies to the connection' do
|
|
41
|
-
logger =
|
|
42
|
-
conn =
|
|
146
|
+
logger = host[:logger]
|
|
147
|
+
conn = double(:connection)
|
|
43
148
|
@options = { :logger => logger }
|
|
44
149
|
host.instance_variable_set :@connection, conn
|
|
45
150
|
args = [ 'source', 'target', {} ]
|
|
151
|
+
conn_args = args + [ nil ]
|
|
46
152
|
|
|
47
153
|
logger.should_receive(:debug)
|
|
48
|
-
conn.should_receive(:scp_to).with(*
|
|
154
|
+
conn.should_receive(:scp_to).with( *conn_args )
|
|
49
155
|
|
|
50
156
|
host.do_scp_to *args
|
|
51
157
|
end
|
|
52
158
|
|
|
53
159
|
it 'do_scp_from logs info and proxies to the connection' do
|
|
54
|
-
logger =
|
|
55
|
-
conn =
|
|
160
|
+
logger = host[:logger]
|
|
161
|
+
conn = double(:connection)
|
|
56
162
|
@options = { :logger => logger }
|
|
57
163
|
host.instance_variable_set :@connection, conn
|
|
58
164
|
args = [ 'source', 'target', {} ]
|
|
165
|
+
conn_args = args + [ nil ]
|
|
59
166
|
|
|
60
167
|
logger.should_receive(:debug)
|
|
61
|
-
conn.should_receive(:scp_from).with(*
|
|
168
|
+
conn.should_receive(:scp_from).with( *conn_args )
|
|
62
169
|
|
|
63
170
|
host.do_scp_from *args
|
|
64
171
|
end
|
|
@@ -69,27 +176,10 @@ module Beaker
|
|
|
69
176
|
|
|
70
177
|
context 'merging defaults' do
|
|
71
178
|
it 'knows the difference between foss and pe' do
|
|
72
|
-
@
|
|
179
|
+
@options = { :type => 'pe' }
|
|
73
180
|
expect( host['puppetpath'] ).to be === '/etc/puppetlabs/puppet'
|
|
74
181
|
end
|
|
75
182
|
|
|
76
|
-
it 'correctly merges network configs over defaults?' do
|
|
77
|
-
overridden_config = MockConfig.new( {'puppetpath'=> '/i/do/what/i/want'},
|
|
78
|
-
{'name' => {} },
|
|
79
|
-
false )
|
|
80
|
-
merged_host = Host.create 'name', options, overridden_config
|
|
81
|
-
expect( merged_host['puppetpath'] ).to be === '/i/do/what/i/want'
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
it 'correctly merges host specifics over defaults' do
|
|
85
|
-
overriding_config = MockConfig.new( {},
|
|
86
|
-
{'name' => {
|
|
87
|
-
'puppetpath' => '/utter/awesomeness'}
|
|
88
|
-
}, true )
|
|
89
|
-
|
|
90
|
-
merged_host = Host.create 'name', options, overriding_config
|
|
91
|
-
expect( merged_host['puppetpath'] ).to be === '/utter/awesomeness'
|
|
92
|
-
end
|
|
93
183
|
end
|
|
94
184
|
end
|
|
95
185
|
end
|