beaker 2.18.3 → 2.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +8 -8
  2. data/HISTORY.md +439 -2
  3. data/acceptance/lib/beaker/acceptance/install_utils.rb +58 -0
  4. data/acceptance/pre_suite/puppet_git/install.rb +6 -65
  5. data/acceptance/tests/foss_utils/clone_git_repo_on.rb +49 -0
  6. data/beaker.gemspec +2 -0
  7. data/lib/beaker/dsl/helpers/web_helpers.rb +2 -1
  8. data/lib/beaker/dsl/install_utils/aio_defaults.rb +0 -2
  9. data/lib/beaker/dsl/install_utils/foss_utils.rb +97 -60
  10. data/lib/beaker/dsl/install_utils/pe_utils.rb +30 -53
  11. data/lib/beaker/dsl/install_utils/puppet_utils.rb +43 -0
  12. data/lib/beaker/dsl/install_utils/windows_utils.rb +144 -0
  13. data/lib/beaker/dsl/roles.rb +20 -3
  14. data/lib/beaker/dsl/structure.rb +14 -3
  15. data/lib/beaker/host.rb +24 -3
  16. data/lib/beaker/host/unix/pkg.rb +9 -0
  17. data/lib/beaker/host/windows/exec.rb +3 -0
  18. data/lib/beaker/host_prebuilt_steps.rb +5 -9
  19. data/lib/beaker/hypervisor/aws_sdk.rb +22 -18
  20. data/lib/beaker/hypervisor/docker.rb +7 -0
  21. data/lib/beaker/hypervisor/vmpooler.rb +4 -0
  22. data/lib/beaker/logger.rb +12 -1
  23. data/lib/beaker/options/command_line_parser.rb +9 -0
  24. data/lib/beaker/options/options_hash.rb +3 -296
  25. data/lib/beaker/options/parser.rb +12 -0
  26. data/lib/beaker/options/presets.rb +0 -1
  27. data/lib/beaker/ssh_connection.rb +48 -23
  28. data/lib/beaker/test_case.rb +1 -1
  29. data/lib/beaker/version.rb +1 -1
  30. data/spec/beaker/dsl/helpers/web_helpers_spec.rb +10 -1
  31. data/spec/beaker/dsl/install_utils/foss_utils_spec.rb +194 -49
  32. data/spec/beaker/dsl/install_utils/pe_utils_spec.rb +112 -22
  33. data/spec/beaker/dsl/install_utils/puppet_utils_spec.rb +57 -0
  34. data/spec/beaker/dsl/install_utils/windows_utils_spec.rb +132 -0
  35. data/spec/beaker/dsl/roles_spec.rb +36 -5
  36. data/spec/beaker/dsl/structure_spec.rb +9 -2
  37. data/spec/beaker/host/unix/pkg_spec.rb +26 -6
  38. data/spec/beaker/host_prebuilt_steps_spec.rb +3 -2
  39. data/spec/beaker/host_spec.rb +18 -0
  40. data/spec/beaker/hypervisor/aixer_spec.rb +1 -1
  41. data/spec/beaker/hypervisor/aws_sdk_spec.rb +595 -58
  42. data/spec/beaker/hypervisor/docker_spec.rb +2 -1
  43. data/spec/beaker/hypervisor/solaris_spec.rb +1 -0
  44. data/spec/beaker/hypervisor/vagrant_spec.rb +2 -1
  45. data/spec/beaker/logger_spec.rb +39 -0
  46. data/spec/beaker/options/command_line_parser_spec.rb +2 -2
  47. data/spec/beaker/options/options_hash_spec.rb +1 -102
  48. data/spec/beaker/options/parser_spec.rb +19 -0
  49. data/spec/beaker/options/pe_version_scaper_spec.rb +11 -1
  50. data/spec/beaker/options/presets_spec.rb +8 -0
  51. data/spec/beaker/ssh_connection_spec.rb +39 -21
  52. data/spec/helpers.rb +9 -3
  53. data/spec/mocks.rb +2 -0
  54. metadata +34 -11
  55. data/lib/beaker/answers.rb +0 -143
  56. data/lib/beaker/answers/version20.rb +0 -120
  57. data/lib/beaker/answers/version28.rb +0 -121
  58. data/lib/beaker/answers/version30.rb +0 -227
  59. data/lib/beaker/answers/version32.rb +0 -44
  60. data/lib/beaker/answers/version34.rb +0 -51
  61. data/lib/beaker/answers/version38.rb +0 -29
  62. data/lib/beaker/answers/version40.rb +0 -44
  63. data/spec/beaker/answers_spec.rb +0 -547
@@ -328,6 +328,7 @@ module Beaker
328
328
  end
329
329
 
330
330
  normalize_and_validate_tags()
331
+ resolve_symlinks()
331
332
 
332
333
  #set the default role
333
334
  set_default_host!(@options[:HOSTS])
@@ -365,6 +366,17 @@ module Beaker
365
366
  end
366
367
  end
367
368
 
369
+ # resolves all file symlinks that require it.
370
+ #
371
+ # @note doing it here allows us to not need duplicate logic, which we
372
+ # would need if we were doing it in the parser (--hosts & --config)
373
+ #
374
+ # @return nil
375
+ # @api public
376
+ def resolve_symlinks()
377
+ @options[:hosts_file] = File.realpath(@options[:hosts_file]) if @options[:hosts_file]
378
+ end
379
+
368
380
  private
369
381
 
370
382
  # @api private
@@ -178,7 +178,6 @@ module Beaker
178
178
  :ssh => {
179
179
  :config => false,
180
180
  :paranoid => false,
181
- :timeout => 300,
182
181
  :auth_methods => ["publickey"],
183
182
  :port => 22,
184
183
  :forward_agent => true,
@@ -6,6 +6,7 @@ module Beaker
6
6
  class SshConnection
7
7
 
8
8
  attr_accessor :logger
9
+ attr_accessor :ip, :vmhostname, :hostname
9
10
 
10
11
  RETRYABLE_EXCEPTIONS = [
11
12
  SocketError,
@@ -21,41 +22,65 @@ module Beaker
21
22
  IOError,
22
23
  ]
23
24
 
24
- def initialize hostname, user = nil, ssh_opts = {}, options = {}
25
- @hostname = hostname
25
+ def initialize name_hash, user = nil, ssh_opts = {}, options = {}
26
+ @vmhostname = name_hash[:vmhostname]
27
+ @ip = name_hash[:ip]
28
+ @hostname = name_hash[:hostname]
26
29
  @user = user
27
30
  @ssh_opts = ssh_opts
28
31
  @logger = options[:logger]
29
32
  @options = options
30
33
  end
31
34
 
32
- def self.connect hostname, user = 'root', ssh_opts = {}, options = {}
33
- connection = new hostname, user, ssh_opts, options
35
+ def self.connect name_hash, user = 'root', ssh_opts = {}, options = {}
36
+ connection = new name_hash, user, ssh_opts, options
34
37
  connection.connect
35
38
  connection
36
39
  end
37
40
 
41
+ def connect_block host, user, ssh_opts
42
+ try = 1
43
+ last_wait = 2
44
+ wait = 3
45
+ begin
46
+ @logger.debug "Attempting ssh connection to #{host}, user: #{user}, opts: #{ssh_opts}"
47
+ Net::SSH.start(host, user, ssh_opts)
48
+ rescue *RETRYABLE_EXCEPTIONS => e
49
+ if try <= 8
50
+ @logger.warn "Try #{try} -- Host #{host} unreachable: #{e.class.name} - #{e.message}"
51
+ @logger.warn "Trying again in #{wait} seconds"
52
+ sleep wait
53
+ (last_wait, wait) = wait, last_wait + wait
54
+ try += 1
55
+ retry
56
+ else
57
+ @logger.warn "Failed to connect to #{host}, after #{try} attempts"
58
+ nil
59
+ end
60
+ end
61
+ end
62
+
38
63
  # connect to the host
39
64
  def connect
40
- try = 1
41
- last_wait = 0
42
- wait = 1
43
- @ssh ||= begin
44
- @logger.debug "Attempting ssh connection to #{@hostname}, user: #{@user}, opts: #{@ssh_opts}"
45
- Net::SSH.start(@hostname, @user, @ssh_opts)
46
- rescue *RETRYABLE_EXCEPTIONS => e
47
- if try <= 11
48
- @logger.warn "Try #{try} -- Host #{@hostname} unreachable: #{e.class.name} - #{e.message}"
49
- @logger.warn "Trying again in #{wait} seconds"
50
- sleep wait
51
- (last_wait, wait) = wait, last_wait + wait
52
- try += 1
53
- retry
54
- else
55
- @logger.error "Failed to connect to #{@hostname}"
56
- raise
57
- end
58
- end
65
+ #try three ways to connect to host (ip, vmhostname, hostname)
66
+ methods = []
67
+ if @ip
68
+ @ssh ||= connect_block(@ip, @user, @ssh_opts)
69
+ methods << "ip (#{@ip})"
70
+ end
71
+ if @vmhostname && !@ssh
72
+ @ssh ||= connect_block(@vmhostname, @user, @ssh_opts)
73
+ methods << "vmhostname (#{@vmhostname})"
74
+ end
75
+ if @hostname && !@ssh
76
+ @ssh ||= connect_block(@hostname, @user, @ssh_opts)
77
+ methods << "hostname (#{@hostname})"
78
+ end
79
+ if not @ssh
80
+ @logger.error "Failed to connect to #{@hostname}, attempted #{methods.join(', ')}"
81
+ raise RuntimeError, "Cannot connect to #{@hostname}"
82
+ end
83
+ @ssh
59
84
  end
60
85
 
61
86
  # closes this SshConnection
@@ -1,4 +1,4 @@
1
- [ 'host', 'answers', 'dsl' ].each do |lib|
1
+ [ 'host', 'dsl' ].each do |lib|
2
2
  require "beaker/#{lib}"
3
3
  end
4
4
 
@@ -1,5 +1,5 @@
1
1
  module Beaker
2
2
  module Version
3
- STRING = '2.18.3'
3
+ STRING = '2.19.0'
4
4
  end
5
5
  end
@@ -29,12 +29,21 @@ describe ClassMixedWithDSLHelpers do
29
29
 
30
30
  it "returns its second and third arguments concatenated." do
31
31
  create_files(['destdir/name'])
32
- result = subject.fetch_http_file "http://beaker.tool/", "name", "destdir"
32
+ result = subject.fetch_http_file "http://beaker.tool", "name", "destdir"
33
33
  expect(result).to eq("destdir/name")
34
34
  end
35
35
 
36
36
  end
37
37
 
38
+ describe 'given invalid arguments' do
39
+
40
+ it 'chomps correctly when given a URL ending with a / character' do
41
+ expect( subject ).to receive( :open ).with( 'http://beaker.tool/name', anything )
42
+ subject.fetch_http_file( "http://beaker.tool/", "name", "destdir" )
43
+ end
44
+
45
+ end
46
+
38
47
  end
39
48
 
40
49
  describe "#fetch_http_dir" do
@@ -16,10 +16,11 @@ end
16
16
  describe ClassMixedWithDSLInstallUtils do
17
17
  let(:metadata) { @metadata ||= {} }
18
18
  let(:presets) { Beaker::Options::Presets.new }
19
- let(:opts) { presets.presets.merge(presets.env_vars) }
19
+ let(:opts) { presets.presets.merge(presets.env_vars).merge({ :type => 'foss' }) }
20
20
  let(:basic_hosts) { make_hosts( { :pe_ver => '3.0',
21
- :platform => 'linux',
22
- :roles => [ 'agent' ] }, 4 ) }
21
+ :platform => 'linux',
22
+ :roles => [ 'agent' ],
23
+ :type => 'foss' }, 4 ) }
23
24
  let(:hosts) { basic_hosts[0][:roles] = ['master', 'database', 'dashboard']
24
25
  basic_hosts[1][:platform] = 'windows'
25
26
  basic_hosts[2][:platform] = 'osx-10.9-x86_64'
@@ -29,13 +30,16 @@ describe ClassMixedWithDSLInstallUtils do
29
30
  let(:winhost) { make_host( 'winhost', { :platform => 'windows',
30
31
  :pe_ver => '3.0',
31
32
  :working_dir => '/tmp',
33
+ :type => 'foss',
32
34
  :is_cygwin => true} ) }
33
35
  let(:winhost_non_cygwin) { make_host( 'winhost_non_cygwin', { :platform => 'windows',
34
36
  :pe_ver => '3.0',
35
37
  :working_dir => '/tmp',
38
+ :type => 'foss',
36
39
  :is_cygwin => 'false' } ) }
37
40
  let(:machost) { make_host( 'machost', { :platform => 'osx-10.9-x86_64',
38
41
  :pe_ver => '3.0',
42
+ :type => 'foss',
39
43
  :working_dir => '/tmp' } ) }
40
44
  let(:freebsdhost9) { make_host( 'freebsdhost9', { :platform => 'freebsd-9-x64',
41
45
  :pe_ver => '3.0',
@@ -46,55 +50,60 @@ describe ClassMixedWithDSLInstallUtils do
46
50
  let(:unixhost) { make_host( 'unixhost', { :platform => 'linux',
47
51
  :pe_ver => '3.0',
48
52
  :working_dir => '/tmp',
53
+ :type => 'foss',
49
54
  :dist => 'puppet-enterprise-3.1.0-rc0-230-g36c9e5c-debian-7-i386' } ) }
50
55
  let(:eoshost) { make_host( 'eoshost', { :platform => 'eos',
51
56
  :pe_ver => '3.0',
52
57
  :working_dir => '/tmp',
58
+ :type => 'foss',
53
59
  :dist => 'puppet-enterprise-3.7.1-rc0-78-gffc958f-eos-4-i386' } ) }
60
+ let(:win_temp) { 'C:\\Windows\\Temp' }
54
61
 
55
62
 
56
63
  context '#configure_foss_defaults_on' do
57
- it 'uses aio paths for hosts of type aio' do
64
+ it 'uses aio paths for hosts with role aio' do
58
65
  hosts.each do |host|
59
- host[:type] = 'aio'
66
+ host[:pe_ver] = nil
67
+ host[:version] = nil
68
+ host[:roles] = host[:roles] | ['aio']
60
69
  end
70
+ expect(subject).to receive(:add_foss_defaults_on).exactly(hosts.length).times
61
71
  expect(subject).to receive(:add_aio_defaults_on).exactly(hosts.length).times
62
72
  expect(subject).to receive(:add_puppet_paths_on).exactly(hosts.length).times
63
73
 
64
74
  subject.configure_foss_defaults_on( hosts )
65
75
  end
66
76
 
67
- it 'uses foss paths for hosts of type foss' do
77
+ it 'uses no paths for hosts with no type' do
68
78
  hosts.each do |host|
69
- host[:type] = 'foss'
79
+ host[:type] = nil
70
80
  end
71
- expect(subject).to receive(:add_foss_defaults_on).exactly(hosts.length).times
72
- expect(subject).to receive(:add_puppet_paths_on).exactly(hosts.length).times
81
+ expect(subject).to receive(:add_aio_defaults_on).never
82
+ expect(subject).to receive(:add_foss_defaults_on).never
83
+ expect(subject).to receive(:add_puppet_paths_on).never
73
84
 
74
85
  subject.configure_foss_defaults_on( hosts )
75
86
  end
76
87
 
77
- it 'uses foss paths for hosts with no type and version < 4.0' do
78
- expect(subject).to receive(:add_foss_defaults_on).exactly(hosts.length).times
88
+ it 'uses aio paths for hosts with aio type (backwards compatability)' do
89
+ hosts.each do |host|
90
+ host[:type] = 'aio'
91
+ end
92
+ expect(subject).to receive(:add_aio_defaults_on).exactly(hosts.length).times
93
+ expect(subject).to receive(:add_foss_defaults_on).never
79
94
  expect(subject).to receive(:add_puppet_paths_on).exactly(hosts.length).times
80
95
 
81
96
  subject.configure_foss_defaults_on( hosts )
82
97
  end
83
98
 
84
- it 'uses aio paths for hosts of version >= 4.0, except for master/database/dashboard' do
85
- agents = []
86
- not_agents = []
99
+ it 'uses aio paths for hosts of version >= 4.0' do
87
100
  hosts.each do |host|
88
101
  host[:version] = '4.0'
89
102
  host[:pe_ver] = nil
90
- if subject.agent_only(host)
91
- agents << host
92
- else
93
- not_agents << host
94
- end
103
+ host[:roles] = host[:roles] - ['aio']
95
104
  end
96
- expect(subject).to receive(:add_aio_defaults_on).exactly(agents.length).times
97
- expect(subject).to receive(:add_foss_defaults_on).exactly(not_agents.length).times
105
+ expect(subject).to receive(:add_aio_defaults_on).exactly(hosts.length).times
106
+ expect(subject).to receive(:add_foss_defaults_on).exactly(hosts.length).times
98
107
  expect(subject).to receive(:add_puppet_paths_on).exactly(hosts.length).times
99
108
 
100
109
  subject.configure_foss_defaults_on( hosts )
@@ -103,8 +112,23 @@ describe ClassMixedWithDSLInstallUtils do
103
112
  it 'uses foss paths for hosts of version < 4.0' do
104
113
  hosts.each do |host|
105
114
  host[:version] = '3.8'
115
+ host[:pe_ver] = nil
116
+ end
117
+ expect(subject).to receive(:add_foss_defaults_on).exactly(hosts.length).times
118
+ expect(subject).to receive(:add_aio_defaults_on).never
119
+ expect(subject).to receive(:add_puppet_paths_on).exactly(hosts.length).times
120
+
121
+ subject.configure_foss_defaults_on( hosts )
122
+ end
123
+
124
+ it 'uses foss paths for foss-like type foss-package' do
125
+ hosts.each do |host|
126
+ host[:type] = 'foss-package'
127
+ host[:version] = '3.8'
128
+ host[:pe_ver] = nil
106
129
  end
107
130
  expect(subject).to receive(:add_foss_defaults_on).exactly(hosts.length).times
131
+ expect(subject).to receive(:add_aio_defaults_on).never
108
132
  expect(subject).to receive(:add_puppet_paths_on).exactly(hosts.length).times
109
133
 
110
134
  subject.configure_foss_defaults_on( hosts )
@@ -112,6 +136,54 @@ describe ClassMixedWithDSLInstallUtils do
112
136
 
113
137
  end
114
138
 
139
+ context 'lookup_in_env' do
140
+ it 'returns a default properly' do
141
+ env_var = subject.lookup_in_env('noway', 'nonesuch', 'returnme')
142
+ expect(env_var).to be == 'returnme'
143
+ env_var = subject.lookup_in_env('noway', nil, 'returnme')
144
+ expect(env_var).to be == 'returnme'
145
+ end
146
+ it 'finds correct env variable' do
147
+ allow(ENV).to receive(:[]).with(nil).and_return(nil)
148
+ allow(ENV).to receive(:[]).with('REALLYNONE').and_return(nil)
149
+ allow(ENV).to receive(:[]).with('NONESUCH').and_return('present')
150
+ allow(ENV).to receive(:[]).with('NOWAY_PROJ_NONESUCH').and_return('exists')
151
+ env_var = subject.lookup_in_env('nonesuch', 'noway-proj', 'fail')
152
+ expect(env_var).to be == 'exists'
153
+ env_var = subject.lookup_in_env('nonesuch')
154
+ expect(env_var).to be == 'present'
155
+ env_var = subject.lookup_in_env('reallynone')
156
+ expect(env_var).to be == nil
157
+ env_var = subject.lookup_in_env('reallynone',nil,'default')
158
+ expect(env_var).to be == 'default'
159
+ end
160
+ end
161
+
162
+ context 'build_giturl' do
163
+ it 'returns urls properly' do
164
+ allow(ENV).to receive(:[]).with('SERVER').and_return(nil)
165
+ allow(ENV).to receive(:[]).with('FORK').and_return(nil)
166
+ allow(ENV).to receive(:[]).with('PUPPET_FORK').and_return(nil)
167
+ allow(ENV).to receive(:[]).with('PUPPET_SERVER').and_return(nil)
168
+ url = subject.build_giturl('puppet')
169
+ expect(url).to be == 'https://github.com/puppetlabs/puppet.git'
170
+ url = subject.build_giturl('puppet', 'er0ck')
171
+ expect(url).to be == 'https://github.com/er0ck/puppet.git'
172
+ url = subject.build_giturl('puppet', 'er0ck', 'bitbucket.com')
173
+ expect(url).to be == 'https://bitbucket.com/er0ck-puppet.git'
174
+ url = subject.build_giturl('puppet', 'er0ck', 'github.com', 'https://')
175
+ expect(url).to be == 'https://github.com/er0ck/puppet.git'
176
+ url = subject.build_giturl('puppet', 'er0ck', 'github.com', 'https')
177
+ expect(url).to be == 'https://github.com/er0ck/puppet.git'
178
+ url = subject.build_giturl('puppet', 'er0ck', 'github.com', 'git@')
179
+ expect(url).to be == 'git@github.com:er0ck/puppet.git'
180
+ url = subject.build_giturl('puppet', 'er0ck', 'github.com', 'git')
181
+ expect(url).to be == 'git@github.com:er0ck/puppet.git'
182
+ url = subject.build_giturl('puppet', 'er0ck', 'github.com', 'ssh')
183
+ expect(url).to be == 'git@github.com:er0ck/puppet.git'
184
+ end
185
+ end
186
+
115
187
  context 'extract_repo_info_from' do
116
188
  [{ :protocol => 'git', :path => 'git://github.com/puppetlabs/project.git' },
117
189
  { :protocol => 'ssh', :path => 'git@github.com:puppetlabs/project.git' },
@@ -175,13 +247,15 @@ describe ClassMixedWithDSLInstallUtils do
175
247
  end
176
248
 
177
249
  context 'install_puppet_from_msi' do
250
+ before :each do
251
+ expect(subject).to receive(:get_temp_path).and_return(win_temp)
252
+ end
178
253
 
179
254
  it 'installs puppet on cygwin windows' do
180
255
  allow(subject).to receive(:link_exists?).and_return( true )
181
-
182
- expect(subject).to receive(:on).with(winhost, 'curl -O http://downloads.puppetlabs.com/windows/puppet-3.7.1.msi')
256
+ expect(subject).to receive(:on).with(winhost, "curl -o \"#{win_temp}\\puppet-3.7.1.msi\" -O http://downloads.puppetlabs.com/windows/puppet-3.7.1.msi")
183
257
  expect(subject).to receive(:on).with(winhost, " echo 'export PATH=$PATH:\"/cygdrive/c/Program Files (x86)/Puppet Labs/Puppet/bin\":\"/cygdrive/c/Program Files/Puppet Labs/Puppet/bin\"' > /etc/bash.bashrc ")
184
- expect(subject).to receive(:on).with(winhost, 'cmd /C \'start /w msiexec.exe /qn /i puppet-3.7.1.msi\'')
258
+ expect(subject).to receive(:install_msi_on).with(winhost, "#{win_temp}\\puppet-3.7.1.msi", {}, {:debug => nil})
185
259
 
186
260
  subject.install_puppet_from_msi( winhost, {:version => '3.7.1', :win_download_url => 'http://downloads.puppetlabs.com/windows'} )
187
261
  end
@@ -191,18 +265,18 @@ describe ClassMixedWithDSLInstallUtils do
191
265
 
192
266
  expect(winhost_non_cygwin).to receive(:mkdir_p).with('C:\\ProgramData\\PuppetLabs\\puppet\\etc\\modules')
193
267
 
194
- expect(subject).to receive(:on) do |winhost_non_cygwin, beaker_command|
268
+ expect(subject).to receive(:on).with(winhost_non_cygwin, instance_of( Beaker::Command )) do |host, beaker_command|
195
269
  expect(beaker_command.command).to eq('powershell.exe')
196
- expect(beaker_command.args).to eq(["-ExecutionPolicy Bypass", "-InputFormat None", "-NoLogo", "-NoProfile", "-NonInteractive", "-Command $webclient = New-Object System.Net.WebClient; $webclient.DownloadFile('http://downloads.puppetlabs.com/windows/puppet-3.7.1.msi','C:\\Windows\\Temp\\puppet-3.7.1.msi')"])
197
- end
270
+ expect(beaker_command.args).to eq(["-ExecutionPolicy Bypass", "-InputFormat None", "-NoLogo", "-NoProfile", "-NonInteractive", "-Command $webclient = New-Object System.Net.WebClient; $webclient.DownloadFile('http://downloads.puppetlabs.com/windows/puppet-3.7.1.msi','#{win_temp}\\puppet-3.7.1.msi')"])
271
+ end.once
198
272
 
199
- expect(subject).to receive(:on).with(winhost_non_cygwin, "start /w msiexec.exe /qn /i C:\\Windows\\Temp\\puppet-3.7.1.msi")
273
+ expect(subject).to receive(:install_msi_on).with(winhost_non_cygwin, "#{win_temp}\\puppet-3.7.1.msi", {}, {:debug => nil})
200
274
 
201
275
  subject.install_puppet_from_msi( winhost_non_cygwin, {:version => '3.7.1', :win_download_url => 'http://downloads.puppetlabs.com/windows'} )
202
276
  end
203
277
  end
204
278
 
205
- context 'install_from_git' do
279
+ context 'clone_git_repo_on' do
206
280
  it 'does a ton of stuff it probably shouldnt' do
207
281
  repo = { :name => 'puppet',
208
282
  :path => 'git://my.server.net/puppet.git',
@@ -214,11 +288,11 @@ describe ClassMixedWithDSLInstallUtils do
214
288
  allow( subject ).to receive( :metadata ).and_return( metadata )
215
289
  allow( subject ).to receive( :configure_foss_defaults_on ).and_return( true )
216
290
 
217
- expect( subject ).to receive( :logger ).exactly( 3 ).times.and_return( logger )
218
- expect( subject ).to receive( :on ).exactly( 4 ).times
291
+ expect( subject ).to receive( :logger ).exactly( 2 ).times.and_return( logger )
292
+ expect( subject ).to receive( :on ).exactly( 3 ).times
219
293
 
220
294
  subject.instance_variable_set( :@metadata, {} )
221
- subject.install_from_git( host, path, repo )
295
+ subject.clone_git_repo_on( host, path, repo )
222
296
  end
223
297
 
224
298
  it 'allows a checkout depth of 1' do
@@ -233,15 +307,14 @@ describe ClassMixedWithDSLInstallUtils do
233
307
  logger = double.as_null_object
234
308
  allow( subject ).to receive( :metadata ).and_return( metadata )
235
309
  allow( subject ).to receive( :configure_foss_defaults_on ).and_return( true )
236
- expect( subject ).to receive( :logger ).exactly( 3 ).times.and_return( logger )
237
- expect( subject ).to receive( :on ).with( host,"test -d #{path} || mkdir -p #{path}").exactly( 1 ).times
310
+ expect( subject ).to receive( :logger ).exactly( 2 ).times.and_return( logger )
311
+ expect( subject ).to receive( :on ).with( host, "test -d #{path} || mkdir -p #{path}", {:accept_all_exit_codes=>true} ).exactly( 1 ).times
238
312
  # this is the the command we want to test
239
- expect( subject ).to receive( :on ).with( host, cmd ).exactly( 1 ).times
240
- expect( subject ).to receive( :on ).with( host, "cd #{path}/#{repo[:name]} && git remote rm origin && git remote add origin #{repo[:path]} && git fetch origin +refs/pull/*:refs/remotes/origin/pr/* +refs/heads/*:refs/remotes/origin/* && git clean -fdx && git checkout -f #{repo[:rev]}" ).exactly( 1 ).times
241
- expect( subject ).to receive( :on ).with( host, "cd #{path}/#{repo[:name]} && if [ -f install.rb ]; then ruby ./install.rb ; else true; fi" ).exactly( 1 ).times
313
+ expect( subject ).to receive( :on ).with( host, cmd, {:accept_all_exit_codes=>true} ).exactly( 1 ).times
314
+ expect( subject ).to receive( :on ).with( host, "cd #{path}/#{repo[:name]} && git remote rm origin && git remote add origin #{repo[:path]} && git fetch origin +refs/pull/*:refs/remotes/origin/pr/* +refs/heads/*:refs/remotes/origin/* && git clean -fdx && git checkout -f #{repo[:rev]}", {:accept_all_exit_codes=>true} ).exactly( 1 ).times
242
315
 
243
316
  subject.instance_variable_set( :@metadata, {} )
244
- subject.install_from_git( host, path, repo )
317
+ subject.clone_git_repo_on( host, path, repo )
245
318
  end
246
319
 
247
320
  it 'allows a checkout depth with a rev from a specific branch' do
@@ -257,16 +330,57 @@ describe ClassMixedWithDSLInstallUtils do
257
330
  allow( subject ).to receive( :configure_foss_defaults_on ).and_return( true )
258
331
  logger = double.as_null_object
259
332
  allow( subject ).to receive( :metadata ).and_return( metadata )
260
- expect( subject ).to receive( :logger ).exactly( 3 ).times.and_return( logger )
261
- expect( subject ).to receive( :on ).with( host,"test -d #{path} || mkdir -p #{path}").exactly( 1 ).times
333
+ expect( subject ).to receive( :logger ).exactly( 2 ).times.and_return( logger )
334
+ expect( subject ).to receive( :on ).with( host, "test -d #{path} || mkdir -p #{path}", {:accept_all_exit_codes=>true} ).exactly( 1 ).times
262
335
  # this is the the command we want to test
263
- expect( subject ).to receive( :on ).with( host, cmd ).exactly( 1 ).times
264
- expect( subject ).to receive( :on ).with( host, "cd #{path}/#{repo[:name]} && git remote rm origin && git remote add origin #{repo[:path]} && git fetch origin +refs/pull/*:refs/remotes/origin/pr/* +refs/heads/*:refs/remotes/origin/* && git clean -fdx && git checkout -f #{repo[:rev]}" ).exactly( 1 ).times
265
- expect( subject ).to receive( :on ).with( host, "cd #{path}/#{repo[:name]} && if [ -f install.rb ]; then ruby ./install.rb ; else true; fi" ).exactly( 1 ).times
336
+ expect( subject ).to receive( :on ).with( host, cmd, {:accept_all_exit_codes=>true} ).exactly( 1 ).times
337
+ expect( subject ).to receive( :on ).with( host, "cd #{path}/#{repo[:name]} && git remote rm origin && git remote add origin #{repo[:path]} && git fetch origin +refs/pull/*:refs/remotes/origin/pr/* +refs/heads/*:refs/remotes/origin/* && git clean -fdx && git checkout -f #{repo[:rev]}", {:accept_all_exit_codes=>true} ).exactly( 1 ).times
338
+
339
+ subject.instance_variable_set( :@metadata, {} )
340
+ subject.clone_git_repo_on( host, path, repo )
341
+ end
342
+ end
343
+
344
+ context 'install_from_git' do
345
+ it 'does a ton of stuff it probably shouldnt' do
346
+ repo = { :name => 'puppet',
347
+ :path => 'git://my.server.net/puppet.git',
348
+ :rev => 'master' }
349
+ path = '/path/to/repos'
350
+ host = { 'platform' => 'debian' }
351
+ logger = double.as_null_object
352
+
353
+ allow( subject ).to receive( :metadata ).and_return( metadata )
354
+ allow( subject ).to receive( :configure_foss_defaults_on ).and_return( true )
355
+
356
+ expect( subject ).to receive( :logger ).exactly( 3 ).times.and_return( logger )
357
+ expect( subject ).to receive( :on ).exactly( 4 ).times
266
358
 
267
359
  subject.instance_variable_set( :@metadata, {} )
268
360
  subject.install_from_git( host, path, repo )
269
361
  end
362
+
363
+ it 'should attempt to install ruby code' do
364
+ repo = { :name => 'puppet',
365
+ :path => 'git://my.server.net/puppet.git',
366
+ :rev => 'master',
367
+ :depth => 1 }
368
+
369
+ path = '/path/to/repos'
370
+ cmd = "test -d #{path}/#{repo[:name]} || git clone --branch #{repo[:rev]} --depth #{repo[:depth]} #{repo[:path]} #{path}/#{repo[:name]}"
371
+ host = { 'platform' => 'debian' }
372
+ logger = double.as_null_object
373
+ allow( subject ).to receive( :metadata ).and_return( metadata )
374
+ allow( subject ).to receive( :configure_foss_defaults_on ).and_return( true )
375
+ expect( subject ).to receive( :logger ).exactly( 3 ).times.and_return( logger )
376
+ expect( subject ).to receive( :on ).with( host, "test -d #{path} || mkdir -p #{path}", {:accept_all_exit_codes=>true} ).exactly( 1 ).times
377
+ expect( subject ).to receive( :on ).with( host, cmd, {:accept_all_exit_codes=>true} ).exactly( 1 ).times
378
+ expect( subject ).to receive( :on ).with( host, "cd #{path}/#{repo[:name]} && git remote rm origin && git remote add origin #{repo[:path]} && git fetch origin +refs/pull/*:refs/remotes/origin/pr/* +refs/heads/*:refs/remotes/origin/* && git clean -fdx && git checkout -f #{repo[:rev]}", {:accept_all_exit_codes=>true} ).exactly( 1 ).times
379
+ expect( subject ).to receive( :on ).with( host, "cd #{path}/#{repo[:name]} && if [ -f install.rb ]; then ruby ./install.rb ; else true; fi", {:accept_all_exit_codes=>true} ).exactly( 1 ).times
380
+
381
+ subject.instance_variable_set( :@metadata, {} )
382
+ subject.install_from_git_on( host, path, repo )
383
+ end
270
384
  end
271
385
 
272
386
  describe '#install_puppet' do
@@ -337,19 +451,28 @@ describe ClassMixedWithDSLInstallUtils do
337
451
  end
338
452
  context 'on windows' do
339
453
  let(:platform) { Beaker::Platform.new('windows-2008r2-i386') }
454
+
455
+ before :each do
456
+ expect(subject).to receive(:get_temp_path).exactly(hosts.length).times.and_return(win_temp)
457
+ end
458
+
340
459
  it 'installs specific version of puppet when passed :version' do
341
460
  allow(hosts[0]).to receive(:is_cygwin?).and_return(true)
342
461
  allow(subject).to receive(:link_exists?).and_return( true )
343
- expect(subject).to receive(:on).with(hosts[0], 'curl -O http://downloads.puppetlabs.com/windows/puppet-3.msi')
462
+ expect(subject).to receive(:on).with(hosts[0], "curl -o \"#{win_temp}\\puppet-3.msi\" -O http://downloads.puppetlabs.com/windows/puppet-3.msi")
344
463
  expect(subject).to receive(:on).with(hosts[0], " echo 'export PATH=$PATH:\"/cygdrive/c/Program Files (x86)/Puppet Labs/Puppet/bin\":\"/cygdrive/c/Program Files/Puppet Labs/Puppet/bin\"' > /etc/bash.bashrc ")
345
- expect(subject).to receive(:on).with(hosts[0], 'cmd /C \'start /w msiexec.exe /qn /i puppet-3.msi\'')
464
+ expect(subject).to receive(:install_msi_on).with(hosts[0], "#{win_temp}\\puppet-3.msi", {}, {:debug => nil}).exactly(1).times
465
+ allow(subject).to receive(:install_msi_on).with(any_args)
466
+
346
467
  subject.install_puppet(:version => '3')
347
468
  end
348
469
  it 'installs from custom url when passed :win_download_url' do
349
470
  allow(hosts[0]).to receive(:is_cygwin?).and_return(true)
350
471
  allow(subject).to receive(:link_exists?).and_return( true )
351
- expect(subject).to receive(:on).with(hosts[0], 'curl -O http://nightlies.puppetlabs.com/puppet-latest/repos/windows/puppet-3.msi')
352
- expect(subject).to receive(:on).with(hosts[0], 'cmd /C \'start /w msiexec.exe /qn /i puppet-3.msi\'')
472
+ expect(subject).to receive(:on).with(hosts[0], "curl -o \"#{win_temp}\\puppet-3.msi\" -O http://nightlies.puppetlabs.com/puppet-latest/repos/windows/puppet-3.msi")
473
+ expect(subject).to receive(:install_msi_on).with(hosts[0], "#{win_temp}\\puppet-3.msi", {}, {:debug => nil})
474
+ allow(subject).to receive(:install_msi_on).with(any_args)
475
+
353
476
  subject.install_puppet( :version => '3', :win_download_url => 'http://nightlies.puppetlabs.com/puppet-latest/repos/windows' )
354
477
  end
355
478
  end
@@ -742,13 +865,14 @@ describe ClassMixedWithDSLInstallUtils do
742
865
  host['platform'] = platform
743
866
  opts = { :version => '0.1.0' }
744
867
  allow( subject ).to receive( :options ).and_return( {} )
868
+ copied_path = "#{win_temp}\\puppet-agent-x64.msi"
745
869
  mock_echo = Object.new()
746
- allow( mock_echo ).to receive( :raw_output ).and_return( " " )
870
+ allow( mock_echo ).to receive( :raw_output ).and_return( copied_path )
747
871
 
748
872
  expect(subject).to receive(:fetch_http_file).once.with(/\/windows$/, 'puppet-agent-x64.msi', /\/windows$/)
749
873
  expect(subject).to receive(:scp_to).once.with(host, /\/puppet-agent-x64.msi$/, /cygpath/)
874
+ expect(subject).to receive(:install_msi_on).with(host, copied_path, {}, {:debug => nil}).once
750
875
  expect(subject).to receive(:on).ordered.with(host, /echo/).and_return(mock_echo)
751
- expect(subject).to receive(:on).ordered.with(host, anything)
752
876
 
753
877
  subject.install_puppetagent_dev_repo( host, opts )
754
878
  end
@@ -786,6 +910,25 @@ describe ClassMixedWithDSLInstallUtils do
786
910
  end
787
911
  end
788
912
 
913
+ describe '#install_puppet_agent_pe_promoted_repo_on' do
914
+
915
+ it 'splits the platform string version correctly to get ubuntu puppet-agent packages' do
916
+ platform = Object.new()
917
+ allow(platform).to receive(:to_array) { ['ubuntu', '9999', 'x42']}
918
+ host = basic_hosts.first
919
+ host['platform'] = platform
920
+
921
+ expect(subject).to receive(:fetch_http_file).once.with(/\/puppet-agent\//, "puppet-agent-ubuntu-99.99-x42.tar.gz", /ubuntu/)
922
+ expect(subject).to receive(:scp_to).once.with(host, /-ubuntu-99.99-x42\./, "/root")
923
+ expect(subject).to receive(:on).ordered.with(host, /^tar.*-ubuntu-99.99-x42/)
924
+ expect(subject).to receive(:on).ordered.with(host, /dpkg\ -i\ --force-all/)
925
+ expect(subject).to receive(:on).ordered.with(host, /apt-get\ update/)
926
+
927
+ subject.install_puppet_agent_pe_promoted_repo_on( host, {} )
928
+ end
929
+
930
+ end
931
+
789
932
  describe '#install_cert_on_windows' do
790
933
  before do
791
934
  allow(subject).to receive(:on).and_return(Beaker::Result.new({},''))
@@ -842,11 +985,13 @@ describe ClassMixedWithDSLInstallUtils do
842
985
 
843
986
  before :each do
844
987
  allow( subject ).to receive( :configure_foss_defaults_on ).and_return( true )
988
+ allow( subject ).to receive( :install_msi_on ).with( any_args )
845
989
  end
846
990
 
847
991
  def test_fetch_http_file_no_ending_slash(platform)
848
992
  @platform = platform
849
993
  allow( subject ).to receive( :scp_to )
994
+ allow( subject ).to receive( :configure_type_defaults_on ).with(host)
850
995
 
851
996
  expect( subject ).to receive( :fetch_http_file ).with( /[^\/]\z/, anything, anything )
852
997
  subject.install_puppet_agent_pe_promoted_repo_on( host, opts )