beaker 0.0.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +8 -8
  2. data/.travis.yml +8 -0
  3. data/README.md +6 -6
  4. data/beaker.gemspec +6 -2
  5. data/lib/beaker.rb +1 -1
  6. data/lib/beaker/answers.rb +34 -7
  7. data/lib/beaker/answers/version20.rb +124 -0
  8. data/lib/beaker/answers/version28.rb +21 -0
  9. data/lib/beaker/answers/version30.rb +24 -5
  10. data/lib/beaker/cli.rb +55 -41
  11. data/lib/beaker/command.rb +2 -2
  12. data/lib/beaker/dsl/helpers.rb +320 -106
  13. data/lib/beaker/dsl/install_utils.rb +202 -81
  14. data/lib/beaker/dsl/roles.rb +40 -0
  15. data/lib/beaker/host.rb +28 -20
  16. data/lib/beaker/host/unix.rb +7 -4
  17. data/lib/beaker/host/unix/pkg.rb +42 -12
  18. data/lib/beaker/host/windows.rb +9 -5
  19. data/lib/beaker/host/windows/group.rb +1 -1
  20. data/lib/beaker/host/windows/pkg.rb +41 -8
  21. data/lib/beaker/hypervisor.rb +23 -10
  22. data/lib/beaker/hypervisor/aixer.rb +15 -19
  23. data/lib/beaker/hypervisor/blimper.rb +71 -72
  24. data/lib/beaker/hypervisor/fusion.rb +11 -10
  25. data/lib/beaker/hypervisor/solaris.rb +17 -23
  26. data/lib/beaker/hypervisor/vagrant.rb +27 -12
  27. data/lib/beaker/hypervisor/vcloud.rb +154 -138
  28. data/lib/beaker/hypervisor/vcloud_pooled.rb +97 -0
  29. data/lib/beaker/hypervisor/vsphere.rb +8 -5
  30. data/lib/beaker/hypervisor/vsphere_helper.rb +43 -33
  31. data/lib/beaker/network_manager.rb +16 -12
  32. data/lib/beaker/options/command_line_parser.rb +199 -0
  33. data/lib/beaker/options/hosts_file_parser.rb +39 -0
  34. data/lib/beaker/options/options_file_parser.rb +45 -0
  35. data/lib/beaker/options/options_hash.rb +294 -0
  36. data/lib/beaker/options/parser.rb +288 -0
  37. data/lib/beaker/options/pe_version_scraper.rb +35 -0
  38. data/lib/beaker/options/presets.rb +70 -0
  39. data/lib/beaker/shared.rb +2 -1
  40. data/lib/beaker/shared/host_handler.rb +7 -2
  41. data/lib/beaker/shared/repetition.rb +1 -0
  42. data/lib/beaker/shared/timed.rb +14 -0
  43. data/lib/beaker/test_case.rb +2 -38
  44. data/lib/beaker/test_suite.rb +11 -25
  45. data/lib/beaker/utils/repo_control.rb +6 -8
  46. data/lib/beaker/utils/setup_helper.rb +9 -20
  47. data/spec/beaker/answers_spec.rb +109 -0
  48. data/spec/beaker/command_spec.rb +2 -2
  49. data/spec/beaker/dsl/assertions_spec.rb +1 -3
  50. data/spec/beaker/dsl/helpers_spec.rb +519 -84
  51. data/spec/beaker/dsl/install_utils_spec.rb +265 -16
  52. data/spec/beaker/dsl/roles_spec.rb +31 -10
  53. data/spec/beaker/host/windows/group_spec.rb +55 -0
  54. data/spec/beaker/host_spec.rb +130 -40
  55. data/spec/beaker/hypervisor/aixer_spec.rb +34 -0
  56. data/spec/beaker/hypervisor/blimper_spec.rb +77 -0
  57. data/spec/beaker/hypervisor/fusion_spec.rb +26 -0
  58. data/spec/beaker/hypervisor/hypervisor_spec.rb +66 -0
  59. data/spec/beaker/hypervisor/solaris_spec.rb +39 -0
  60. data/spec/beaker/hypervisor/vagrant_spec.rb +105 -0
  61. data/spec/beaker/hypervisor/vcloud_pooled_spec.rb +60 -0
  62. data/spec/beaker/hypervisor/vcloud_spec.rb +70 -0
  63. data/spec/beaker/hypervisor/vsphere_helper_spec.rb +162 -0
  64. data/spec/beaker/hypervisor/vsphere_spec.rb +76 -0
  65. data/spec/beaker/options/command_line_parser_spec.rb +25 -0
  66. data/spec/beaker/options/data/LATEST +1 -0
  67. data/spec/beaker/options/data/badyaml.cfg +21 -0
  68. data/spec/beaker/options/data/hosts.cfg +21 -0
  69. data/spec/beaker/options/data/opts.txt +6 -0
  70. data/spec/beaker/options/hosts_file_parser_spec.rb +30 -0
  71. data/spec/beaker/options/options_file_parser_spec.rb +23 -0
  72. data/spec/beaker/options/options_hash_spec.rb +111 -0
  73. data/spec/beaker/options/parser_spec.rb +172 -0
  74. data/spec/beaker/options/pe_version_scaper_spec.rb +15 -0
  75. data/spec/beaker/options/presets_spec.rb +24 -0
  76. data/spec/beaker/puppet_command_spec.rb +54 -21
  77. data/spec/beaker/shared/error_handler_spec.rb +40 -0
  78. data/spec/beaker/shared/host_handler_spec.rb +104 -0
  79. data/spec/beaker/shared/repetition_spec.rb +72 -0
  80. data/spec/beaker/test_suite_spec.rb +3 -16
  81. data/spec/beaker/utils/ntp_control_spec.rb +42 -0
  82. data/spec/beaker/utils/repo_control_spec.rb +168 -0
  83. data/spec/beaker/utils/setup_helper_spec.rb +82 -0
  84. data/spec/beaker/utils/validator_spec.rb +58 -0
  85. data/spec/helpers.rb +97 -0
  86. data/spec/matchers.rb +39 -0
  87. data/spec/mock_blimpy.rb +48 -0
  88. data/spec/mock_fission.rb +60 -0
  89. data/spec/mock_vsphere.rb +310 -0
  90. data/spec/mock_vsphere_helper.rb +183 -0
  91. data/spec/mocks.rb +83 -0
  92. data/spec/spec_helper.rb +8 -1
  93. metadata +106 -13
  94. data/beaker.rb +0 -10
  95. data/lib/beaker/options_parsing.rb +0 -323
  96. data/lib/beaker/test_config.rb +0 -148
  97. data/spec/beaker/options_parsing_spec.rb +0 -37
  98. 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 = stub('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 ).any_number_of_times.and_return( 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) { {'roles' => [ 'agent' ] } }
13
- let(:agent2) { {'roles' => [ 'agent' ] } }
14
- let(:a_and_dash) { {'roles' => [ 'agent', 'dashboard' ] } }
15
- let(:custom) { {'roles' => [ 'custome_role' ] } }
16
- let(:db) { {'roles' => [ 'database' ] } }
17
- let(:master) { {'roles' => [ 'master', 'agent' ] } }
18
- let(:monolith) do
19
- {'roles' => [ 'agent', 'dashboard', 'database', 'master', 'custom_role' ] }
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
@@ -2,22 +2,21 @@ require 'spec_helper'
2
2
 
3
3
  module Beaker
4
4
  describe Host do
5
- let :config do
6
- MockConfig.new({}, {'name' => {'platform' => @platform}}, @pe)
7
- end
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( 'defaults to a unix host' ) { expect( host ).to be_a_kind_of Unix::Host }
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 { host['value'] }.to_not raise_error NoMethodError
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
- # it takes a command object and a hash of options,
30
- # it acts on the host's logger and connection object
31
- # it receives a result object from the connection#execute
32
- # (which it's really just a confusing wrapper for)
33
- # it controls the result objects logging and fails a test for TestCase
34
- # if the exit_code doesn't match
35
- # it returns the result object
36
- it 'EXEC!'
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 = mock(:logger)
42
- conn = mock(:connection)
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(*args)
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 = mock(:logger)
55
- conn = mock(:connection)
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(*args)
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
- @pe = true
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