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.
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