beaker 2.8.0 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZjYxOGQ2OTU1ODFmMGMyYzU5YTE3ZTg2ZTNhYjUzYzVkMTE4ZmZhNg==
4
+ NTRiYTFlN2E4ZTQyNWUxMWJlZGRmNzNmNTNmN2NhYzk3OTFjODYzYg==
5
5
  data.tar.gz: !binary |-
6
- NGU4Y2UxNGI0YmMxZjRiZTRkNmY2ZjljNDlmZTY2YjUzZDg0ZDdkNw==
6
+ YjNkMGZkODlhYmM3Y2Q2ZDA5OGE1OTM2ODQ2MWIxNzkxYmViMDY3ZQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- OTYwZTkxZDE1ZjIxZjdjNjcwZWM2OTg2MGM0YWIyZDUyMTEyY2U3OGExY2Jh
10
- ZGNlNGMyYjA5YjJhOGIyZWE2MmI1NDlhMWM3NzI4YzZlNzkzNjg1MTY4ZWQ2
11
- MWJmOTFiYjYzYTg1NTFkZDIxZTkxMmJlMzJkNmM3YTJkODE1YzQ=
9
+ ZDkyODM0NzY1ZGY0MzdiNzViMzEyZTZhMmRiNTAyNTAzMDQzMmU3Y2IwNTM3
10
+ YmQ5OWViYzYzNDUzYWE5OTlmNGNkZjljNzgwMmE4MmQwODZhNTE3ZTQ4MjZl
11
+ ODE3Mzg1MmMxOTFjMmRhMWM5ZmFmNGRjOWExNWU1MGFhYjQ5MjM=
12
12
  data.tar.gz: !binary |-
13
- MWYzNWYxNzcwZDI2YTc1ZWFmOGE4M2ZjNjNmMGY5NjRiMDVhMmZhNzE1ODJl
14
- NjAxN2U5ZmQ4Yjc1NDZkYTkwYzkzZDIxOTY0NDNjZjYyMjdlYTk2NTdjOGRh
15
- NWI2YmU3YjgyODM0ZDQ3ZjNhMGQyZmMyMDBmZjkyZDU0OTNiNDA=
13
+ MDEzZjUxNmZmMmI1MjdiZjcwZjFjNDY3ODA2MDdlYmY3MTQwNGMxZWNjNjcy
14
+ MmM4NzZhMjcxMDljNWE4NDU4MGE3MmQ2MGQxYWFhOWNjMzYzZTk2M2Y2MmU5
15
+ MThkNWE5MTQzYjRmNDg3MWU3MzQyZjA4MjVlYzZhZDZhZDFkZWE=
data/.simplecov CHANGED
@@ -1,15 +1,15 @@
1
1
  SimpleCov.configure do
2
2
  add_filter 'spec/'
3
+ add_filter 'vendor/'
3
4
  add_filter do |file|
4
5
  file.lines_of_code < 10
5
6
  end
6
- add_group 'DSL', '/dsl'
7
- add_group 'Host', '/host'
8
- add_group 'Utils' do |file|
9
- files = %w(cli.rb logger.rb options_parsing.rb test_config.rb utils/)
10
- files.any? {|f| file.filename =~ Regexp.new( Regexp.quote(f) ) }
11
- end
12
- add_group 'Hypervisors', '/hypervisor'
7
+ add_group 'Answers', '/answers/'
8
+ add_group 'DSL', '/dsl/'
9
+ add_group 'Host', '/host/'
10
+ add_group 'Hypervisors', '/hypervisor/'
11
+ add_group 'Options', '/options/'
12
+ add_group 'Shared', '/shared/'
13
13
  end
14
14
 
15
- SimpleCov.start if ENV['COVERAGE']
15
+ SimpleCov.start if ENV['BEAKER_COVERAGE']
data/HISTORY.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # default - History
2
2
  ## Tags
3
- * [LATEST - 26 Mar, 2015 (f320c276)](#LATEST)
3
+ * [LATEST - 9 Apr, 2015 (901c4a94)](#LATEST)
4
+ * [beaker2.8.0 - 26 Mar, 2015 (2d25d06d)](#beaker2.8.0)
4
5
  * [beaker2.7.1 - 19 Mar, 2015 (45b2bf10)](#beaker2.7.1)
5
6
  * [beaker2.7.0 - 19 Mar, 2015 (38b14ef8)](#beaker2.7.0)
6
7
  * [beaker2.6.0 - 12 Mar, 2015 (d4e731ab)](#beaker2.6.0)
@@ -76,7 +77,245 @@
76
77
  * [pe1.2 - 6 Sep, 2011 (ba3dadd2)](#pe1.2)
77
78
 
78
79
  ## Details
79
- ### <a name = "LATEST">LATEST - 26 Mar, 2015 (f320c276)
80
+ ### <a name = "LATEST">LATEST - 9 Apr, 2015 (901c4a94)
81
+
82
+ * (GEM) update beaker version to 2.9.0 (901c4a94)
83
+
84
+ * Merge pull request #783 from anodelman/maint (62b5ac60)
85
+
86
+
87
+ ```
88
+ Merge pull request #783 from anodelman/maint
89
+
90
+ (BKR-70) Make SshConnection.close more robust...
91
+ ```
92
+ * (BKR-70) Make SshConnection.close more robust... (3bb4f7ca)
93
+
94
+
95
+ ```
96
+ (BKR-70) Make SshConnection.close more robust...
97
+
98
+ ...(so that on(host, "reboot") works correctly)
99
+
100
+ - catch IOErrors
101
+ - added additional execution option ':expect_connection_failure' for
102
+ operations that you believe should result in the connection to the
103
+ host being dropped or broken
104
+ - tested with rebooting centos7 box, successfully rebuilds connection
105
+ and continues test execution
106
+ ```
107
+ * Merge pull request #781 from anodelman/zombie (959952a7)
108
+
109
+
110
+ ```
111
+ Merge pull request #781 from anodelman/zombie
112
+
113
+ (BKR-192) can't run beaker without a host file specified
114
+ ```
115
+ * (BKR-192) can't run beaker without a host file specified (5cf28b4c)
116
+
117
+
118
+ ```
119
+ (BKR-192) can't run beaker without a host file specified
120
+
121
+ - the hosts file was being defaulted to to provide a log name prefix -
122
+ it needs a default value for when there is no user provided value plus
123
+ no hosts file
124
+ ```
125
+ * Merge pull request #778 from anodelman/maint (e2d23066)
126
+
127
+
128
+ ```
129
+ Merge pull request #778 from anodelman/maint
130
+
131
+ (BKR-188) have beaker support a 'test' raketask.
132
+ ```
133
+ * Merge pull request #780 from anodelman/spec-tests (a64a3a10)
134
+
135
+
136
+ ```
137
+ Merge pull request #780 from anodelman/spec-tests
138
+
139
+ (BKR-183) simplecov busted in beaker
140
+ ```
141
+ * (BKR-183) simplecov busted in beaker (3ae9cd7f)
142
+
143
+
144
+ ```
145
+ (BKR-183) simplecov busted in beaker
146
+
147
+ - accidentally busted when we dropped ruby 1.8 support
148
+ - updated to look nice with the current beaker directory structure
149
+ - updated env var to meet beaker standards
150
+ ```
151
+ * (BKR-188) have beaker support a 'test' raketask. (93faeffa)
152
+
153
+
154
+ ```
155
+ (BKR-188) have beaker support a 'test' raketask.
156
+
157
+ - meets our gem standards
158
+ ```
159
+ * Merge pull request #767 from petems/BKR-113-freebsd_pkg_commands (a18ff029)
160
+
161
+
162
+ ```
163
+ Merge pull request #767 from petems/BKR-113-freebsd_pkg_commands
164
+
165
+ (BKR-113) Add pkg commands for FreeBSD
166
+ ```
167
+ * Merge pull request #764 from petems/BKR-113-add_freebsd_host_class (cc6b606e)
168
+
169
+
170
+ ```
171
+ Merge pull request #764 from petems/BKR-113-add_freebsd_host_class
172
+
173
+ (BKR-113) Add FreeBSD host class
174
+ ```
175
+ * Merge pull request #768 from anodelman/maint (5a8d8b0c)
176
+
177
+
178
+ ```
179
+ Merge pull request #768 from anodelman/maint
180
+
181
+ (QENG-2083) share out beaker's history file generation tool
182
+ ```
183
+ * Merge pull request #770 from madAndroid/BKR-165-hack_etc_hosts_docker (bfd12ca9)
184
+
185
+
186
+ ```
187
+ Merge pull request #770 from madAndroid/BKR-165-hack_etc_hosts_docker
188
+
189
+ (BKR-165) hack_etc_hosts method doesn't work for Docker provider
190
+ ```
191
+ * Merge pull request #773 from liamjbennett/install_windows_cert (3aa42917)
192
+
193
+
194
+ ```
195
+ Merge pull request #773 from liamjbennett/install_windows_cert
196
+
197
+ (gh-691) Add function to install certs on windows agents
198
+ ```
199
+ * Merge pull request #771 from justinstoller/maint/master/pc1 (8909e35a)
200
+
201
+
202
+ ```
203
+ Merge pull request #771 from justinstoller/maint/master/pc1
204
+
205
+ (QENG-2096) Update dev repo for new AIO repo name
206
+ ```
207
+ * Merge pull request #762 from sschneid/bkr-161_tagging (084ee947)
208
+
209
+
210
+ ```
211
+ Merge pull request #762 from sschneid/bkr-161_tagging
212
+
213
+ (BKR-161) Beaker tagging improvements
214
+ ```
215
+ * (gh-691) Add function to install certs on windows agents (ccf0bb7e)
216
+
217
+
218
+ ```
219
+ (gh-691) Add function to install certs on windows agents
220
+
221
+ This fixes the issue raised in PUP-2365
222
+ ```
223
+ * BKR-165 - Add spec test to check for presence of /etc/hosts for docker provider (d5da2ee2)
224
+
225
+ * BKR-165 - Amend hack_etc_hosts to set host file entry to host['vm_ip'], if present; add comments to that affect (9c8874b8)
226
+
227
+ * BKR-165 - add hack_etc_hosts method to beaker hypervisor, and set host['vm_ip'] to correct container IP (b324abe7)
228
+
229
+ * (QENG-2096) Update dev repo for new AIO repo name (06e3da46)
230
+
231
+
232
+ ```
233
+ (QENG-2096) Update dev repo for new AIO repo name
234
+
235
+ Soon AIO builds will only be published to the repo "PC1" (not
236
+ products/devel or main as previously). This allows Beaker to install
237
+ from both new AIO repos or legacy repos.
238
+ ```
239
+ * (QENG-2083) share out beaker's history file generation tool (afe0d24c)
240
+
241
+
242
+ ```
243
+ (QENG-2083) share out beaker's history file generation tool
244
+
245
+ - remove the history file generator used exclusively by beaker in favor of the
246
+ new, general use tool
247
+ ```
248
+ * Merge pull request #763 from mullr/fix-ezbake-package-version (3e2e1e6d)
249
+
250
+
251
+ ```
252
+ Merge pull request #763 from mullr/fix-ezbake-package-version
253
+
254
+ Fix ezbake version string extraction
255
+ ```
256
+ * Merge pull request #753 from petems/MAINT-fix_copy_module_to_on_non_cygwin (30a9ee04)
257
+
258
+
259
+ ```
260
+ Merge pull request #753 from petems/MAINT-fix_copy_module_to_on_non_cygwin
261
+
262
+ (MAINT) Fix copy module to on non-cygwin
263
+ ```
264
+ * Merge pull request #761 from petems/MAINT-show_error_from_docker (a6198bb4)
265
+
266
+
267
+ ```
268
+ Merge pull request #761 from petems/MAINT-show_error_from_docker
269
+
270
+ (MAINT) Show error from docker
271
+ ```
272
+ * (BKR-113) Add pkg commands for FreeBSD (efb39f8e)
273
+
274
+ * (BKR-113) Add FreeBSD host class (e288f713)
275
+
276
+
277
+ ```
278
+ (BKR-113) Add FreeBSD host class
279
+
280
+ * Also add to supported platforms
281
+ * Main change is location of Puppet data under `/usr/local/etc` rather than `/etc/`
282
+ ```
283
+ * (BKR-162) Fix ezbake version string extraction (3b1bf59b)
284
+
285
+
286
+ ```
287
+ (BKR-162) Fix ezbake version string extraction
288
+
289
+ This previously used 'echo -n', which is not a universally available
290
+ feature of echo. When running with an OS X host, this caused the string
291
+ to look like "-n PACKAGE-1.2.3\n", which caused cascading failures in
292
+ the code that uses this data. printf is a more portable replacement.
293
+ ```
294
+ * (BKR-161) Beaker tagging improvements (da9fe1ed)
295
+
296
+
297
+ ```
298
+ (BKR-161) Beaker tagging improvements
299
+
300
+ - Use JOB_NAME for 'project' tag default if it exists
301
+ - Set 'beaker_version' tag in vmpooler hypervisor
302
+ ```
303
+ * (MAINT) Updates spec to detect error string (58d7a031)
304
+
305
+ * (MAINT) Changes error message to help debugging (2d9bc305)
306
+
307
+
308
+ ```
309
+ (MAINT) Changes error message to help debugging
310
+
311
+ * Changes the wording to say it was not connectable rather than found
312
+ * Adds error string to help debugging the issue
313
+ ```
314
+ * (MAINT) Adds non-cygwin block for copy_module_to (8e5cdd0c)
315
+
316
+ ### <a name = "beaker2.8.0">beaker2.8.0 - 26 Mar, 2015 (2d25d06d)
317
+
318
+ * (HISTORY) update beaker history for gem release 2.8.0 (2d25d06d)
80
319
 
81
320
  * (GEM) update beaker version to 2.8.0 (f320c276)
82
321
 
data/Rakefile CHANGED
@@ -2,6 +2,10 @@ require 'open3'
2
2
 
3
3
  task :default => [ 'test:spec' ]
4
4
 
5
+ task :test do
6
+ Rake::Task['test:spec'].invoke
7
+ end
8
+
5
9
  task :spec do
6
10
  Rake::Task['test:spec'].invoke
7
11
  end
@@ -29,7 +29,6 @@ Gem::Specification.new do |s|
29
29
  s.add_development_dependency 'yard'
30
30
  s.add_development_dependency 'markdown'
31
31
  s.add_development_dependency 'thin'
32
- s.add_development_dependency 'gitlab-grit'
33
32
 
34
33
  # Run time dependencies
35
34
  s.add_runtime_dependency 'minitest', '~> 5.4'
@@ -169,7 +169,7 @@ module Beaker
169
169
 
170
170
  load 'ezbake.rb'
171
171
  ezbake = EZBake::Config
172
- ezbake[:package_version] = `echo -n $(rake pl:print_build_param[ref] | tail -n 1)`
172
+ ezbake[:package_version] = `printf $(rake pl:print_build_param[ref] | tail -n 1)`
173
173
  EZBakeUtils.config = ezbake
174
174
  end
175
175
  end
@@ -13,7 +13,7 @@ module Beaker
13
13
  # * the module {Beaker::DSL::Wrappers} the provides convenience methods for {Beaker::DSL::Command} creation
14
14
  module ModuleUtils
15
15
 
16
- # The directories in the module directory that will not be scp-ed to the test system when using
16
+ # The directories in the module directory that will not be scp-ed to the test system when using
17
17
  # `copy_module_to`
18
18
  PUPPET_MODULE_INSTALL_IGNORE = ['.bundle', '.git', '.idea', '.vagrant', '.vendor', 'vendor', 'acceptance',
19
19
  'bundle', 'spec', 'tests', 'log']
@@ -123,22 +123,24 @@ module Beaker
123
123
 
124
124
  opts[:protocol] ||= 'scp'
125
125
  case opts[:protocol]
126
- when 'scp'
127
- #move to the host
128
- scp_to host, source_path, target_module_dir, {:ignore => ignore_list}
129
- #rename to the selected module name, if not correct
130
- cur_path = File.join(target_module_dir, source_name)
131
- cur_path = File.join(target_module_dir, source_name)
132
- new_path = File.join(target_module_dir, module_name)
133
- if cur_path != new_path
134
- # NOTE: this will need to be updated to handle powershell only windows SUTs
126
+ when 'scp'
127
+ #move to the host
128
+ scp_to host, source_path, target_module_dir, {:ignore => ignore_list}
129
+ #rename to the selected module name, if not correct
130
+ cur_path = File.join(target_module_dir, source_name)
131
+ new_path = File.join(target_module_dir, module_name)
132
+ if (cur_path != new_path)
133
+ if host.is_cygwin?
135
134
  on host, "mv #{cur_path} #{new_path}"
135
+ else
136
+ on host, "move /y #{cur_path} #{new_path}"
136
137
  end
137
- when 'rsync'
138
- rsync_to host, source, File.join(target_module_dir, module_name), {:ignore => ignore_list}
139
- else
140
- logger.debug "Unsupported transfer protocol, returning nil"
141
- nil
138
+ end
139
+ when 'rsync'
140
+ rsync_to host, source, File.join(target_module_dir, module_name), {:ignore => ignore_list}
141
+ else
142
+ logger.debug "Unsupported transfer protocol, returning nil"
143
+ nil
142
144
  end
143
145
  end
144
146
  end
@@ -551,7 +551,7 @@ module Beaker
551
551
  platform_configs_dir = File.join(repo_configs_dir, variant)
552
552
 
553
553
  # some of the uses of dev_builds_url below can't include protocol info,
554
- # pluse this opens up possibility of switching the behavior on provided
554
+ # plus this opens up possibility of switching the behavior on provided
555
555
  # url type
556
556
  _, protocol, hostname = options[:dev_builds_url].partition /.*:\/\//
557
557
  dev_builds_url = protocol + hostname
@@ -583,10 +583,16 @@ module Beaker
583
583
  repo_filename,
584
584
  platform_configs_dir)
585
585
 
586
- link = "%s/%s/%s/repos/%s/%s%s/products/%s/" %
586
+ link = "%s/%s/%s/repos/%s/%s%s/PC1/%s/" %
587
587
  [ dev_builds_url, package_name, build_version, variant,
588
588
  fedora_prefix, version, arch ]
589
589
 
590
+ if not link_exists?( link )
591
+ link = "%s/%s/%s/repos/%s/%s%s/products/%s/" %
592
+ [ dev_builds_url, package_name, build_version, variant,
593
+ fedora_prefix, version, arch ]
594
+ end
595
+
590
596
  if not link_exists?( link )
591
597
  link = "%s/%s/%s/repos/%s/%s%s/devel/%s/" %
592
598
  [ dev_builds_url, package_name, build_version, variant,
@@ -626,8 +632,13 @@ module Beaker
626
632
  scp_to host, list, config_dir
627
633
  scp_to host, repo_dir, "/root/#{package_name}"
628
634
 
635
+ pc1_check = on( host,
636
+ "[[ -d /root/#{package_name}/#{codename}/PC1 ]]",
637
+ :acceptable_exit_codes => [0,1] )
638
+
639
+ repo_name = pc1_check.exit_code == 0 ? 'PC1' : 'main'
629
640
  search = "deb\\s\\+http:\\/\\/#{hostname}.*$"
630
- replace = "deb file:\\/\\/\\/root\\/#{package_name}\\/#{codename} #{codename} main"
641
+ replace = "deb file:\\/\\/\\/root\\/#{package_name}\\/#{codename} #{codename} #{repo_name}"
631
642
  sed_command = "sed -i 's/#{search}/#{replace}/'"
632
643
  find_and_sed = "find #{config_dir} -name \"*.list\" -exec #{sed_command} {} \\;"
633
644
 
@@ -716,6 +727,16 @@ module Beaker
716
727
  end
717
728
  end
718
729
 
730
+ # This method will install a pem file certifcate on a windows host
731
+ #
732
+ # @param [Host] host A host object
733
+ # @param [String] cert_name The name of the pem file
734
+ # @param [String] cert The contents of the certificate
735
+ #
736
+ def install_cert_on_windows(host, cert_name, cert)
737
+ create_remote_file(host, "C:\\Windows\\Temp\\#{cert_name}.pem", cert)
738
+ on host, "certutil -v -addstore Root C:\\Windows\\Temp\\#{cert_name}.pem"
739
+ end
719
740
  end
720
741
  end
721
742
  end
@@ -39,6 +39,8 @@ module Beaker
39
39
  Aix::Host.new name, options
40
40
  when /osx/
41
41
  Mac::Host.new name, options
42
+ when /freebsd/
43
+ FreeBSD::Host.new name, options
42
44
  else
43
45
  Unix::Host.new name, options
44
46
  end
@@ -394,10 +396,19 @@ module Beaker
394
396
  unless options[:silent]
395
397
  # What?
396
398
  result.log(@logger)
399
+ if !options[:expect_connection_failure] && !result.exit_code
400
+ # no exit code was collected, so the stream failed
401
+ raise CommandFailure, "Host '#{self}' connection failure running:\n #{cmdline}\nLast #{@options[:trace_limit]} lines of output were:\n#{result.formatted_output(@options[:trace_limit])}"
402
+
403
+ end
404
+ if options[:expect_connection_failure] && result.exit_code
405
+ # should have had a connection failure, but didn't
406
+ raise CommandFailure, "Host '#{self}' should have resulted in a connection failure running:\n #{cmdline}\nLast #{@options[:trace_limit]} lines of output were:\n#{result.formatted_output(@options[:trace_limit])}"
407
+ end
397
408
  # No, TestCase has the knowledge about whether its failed, checking acceptable
398
409
  # exit codes at the host level and then raising...
399
410
  # is it necessary to break execution??
400
- if !options[:accept_all_exit_codes] && !result.exit_code_in?(Array(options[:acceptable_exit_codes] || 0))
411
+ if !options[:accept_all_exit_codes] && !result.exit_code_in?(Array(options[:acceptable_exit_codes] || [0, nil]))
401
412
  raise CommandFailure, "Host '#{self}' exited with #{result.exit_code} running:\n #{cmdline}\nLast #{@options[:trace_limit]} lines of output were:\n#{result.formatted_output(@options[:trace_limit])}"
402
413
  end
403
414
  end
@@ -595,7 +606,14 @@ module Beaker
595
606
 
596
607
  end
597
608
 
598
- [ 'windows', 'pswindows', 'unix', 'aix', 'mac' ].each do |lib|
609
+ [
610
+ 'windows',
611
+ 'pswindows',
612
+ 'unix',
613
+ 'aix',
614
+ 'mac',
615
+ 'freebsd',
616
+ ].each do |lib|
599
617
  require "beaker/host/#{lib}"
600
618
  end
601
619
  end
@@ -0,0 +1,31 @@
1
+ [ 'host', 'command_factory' ].each do |lib|
2
+ require "beaker/#{lib}"
3
+ end
4
+
5
+ module FreeBSD
6
+ class Host < Unix::Host
7
+
8
+ def self.foss_defaults
9
+ h = Beaker::Options::OptionsHash.new
10
+ h.merge({
11
+ 'user' => 'root',
12
+ 'group' => 'puppet',
13
+ 'puppetserver-confdir' => '/etc/puppetserver/conf.d',
14
+ 'puppetservice' => 'puppetmaster',
15
+ 'puppetpath' => '/usr/local/etc/puppet/modules',
16
+ 'puppetvardir' => '/var/lib/puppet',
17
+ 'puppetbin' => '/usr/bin/puppet',
18
+ 'puppetbindir' => '/usr/bin',
19
+ 'hieralibdir' => '/opt/puppet-git-repos/hiera/lib',
20
+ 'hierapuppetlibdir' => '/opt/puppet-git-repos/hiera-puppet/lib',
21
+ 'hierabindir' => '/opt/puppet-git-repos/hiera/bin',
22
+ 'hieradatadir' => '/usr/local/etc/puppet/modules/hieradata',
23
+ 'hieraconf' => '/usr/local/etc/puppet/modules/hiera.yaml',
24
+ 'distmoduledir' => '/usr/local/etc/puppet/modules',
25
+ 'sitemoduledir' => '/usr/share/puppet/modules',
26
+ 'pathseparator' => ':',
27
+ })
28
+ end
29
+ end
30
+
31
+ end
@@ -32,6 +32,10 @@ module Unix::Pkg
32
32
  result = exec(Beaker::Command.new("pkg info #{name}"), :acceptable_exit_codes => (0...127))
33
33
  when /solaris-10/
34
34
  result = exec(Beaker::Command.new("pkginfo #{name}"), :acceptable_exit_codes => (0...127))
35
+ when /freebsd-9/
36
+ result = exec(Beaker::Command.new("pkg_info #{name}"), :acceptable_exit_codes => (0...127))
37
+ when /freebsd-10/
38
+ result = exec(Beaker::Command.new("pkg info #{name}"), :acceptable_exit_codes => (0...127))
35
39
  else
36
40
  raise "Package #{name} cannot be queried on #{self}"
37
41
  end
@@ -70,6 +74,10 @@ module Unix::Pkg
70
74
  execute("pkg #{cmdline_args} install #{name}")
71
75
  when /solaris-10/
72
76
  execute("pkgutil -i -y #{cmdline_args} #{name}")
77
+ when /freebsd-9/
78
+ execute("pkg_add -fr #{cmdline_args} #{name}")
79
+ when /freebsd-10/
80
+ execute("pkg #{cmdline_args} install #{name}")
73
81
  else
74
82
  raise "Package #{name} cannot be installed on #{self}"
75
83
  end
@@ -200,4 +208,4 @@ module Unix::Pkg
200
208
  raise "Package repo cannot be deployed on #{self}; the platform is not supported"
201
209
  end
202
210
  end
203
- end
211
+ end
@@ -313,15 +313,18 @@ module Beaker
313
313
  end
314
314
  end
315
315
 
316
- #Update /etc/hosts to make it possible for each provided host to reach each other host by name.
317
- #Assumes that each provided host has host[:ip] set.
316
+ # Update /etc/hosts to make it possible for each provided host to reach each other host by name.
317
+ # Assumes that each provided host has host[:ip] set; in the instance where a provider sets
318
+ # host['ip'] to an address which facilitates access to the host externally, but the actual host
319
+ # addresses differ from this, we check first for the presence of a host['vm_ip'] key first,
320
+ # and use that if present.
318
321
  # @param [Host, Array<Host>] hosts An array of hosts to act upon
319
322
  # @param [Hash{Symbol=>String}] opts Options to alter execution.
320
323
  # @option opts [Beaker::Logger] :logger A {Beaker::Logger} object
321
324
  def hack_etc_hosts hosts, opts
322
325
  etc_hosts = "127.0.0.1\tlocalhost localhost.localdomain\n"
323
326
  hosts.each do |host|
324
- etc_hosts += "#{host['ip'].to_s}\t#{host[:vmhostname] || host.name}\n"
327
+ etc_hosts += "#{host['vm_ip'] || host['ip'].to_s}\t#{host[:vmhostname] || host.name}\n"
325
328
  end
326
329
  hosts.each do |host|
327
330
  set_etc_hosts(host, etc_hosts)
@@ -16,7 +16,7 @@ module Beaker
16
16
  begin
17
17
  ::Docker.validate_version!
18
18
  rescue Excon::Errors::SocketError => e
19
- raise "Docker instance not found.\nif you are on OSX, you might not have Boot2Docker setup correctly\nCheck your DOCKER_HOST variable has been set"
19
+ raise "Docker instance not connectable.\nError was: #{e}\nIf you are on OSX, you might not have Boot2Docker setup correctly\nCheck your DOCKER_HOST variable has been set"
20
20
  end
21
21
 
22
22
  # Pass on all the logging from docker-api to the beaker logger instance
@@ -64,7 +64,12 @@ module Beaker
64
64
  @logger.debug("node available as ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@#{ip} -p #{port}")
65
65
  host['docker_container'] = container
66
66
  host['docker_image'] = image
67
+ host['vm_ip'] = container.json["NetworkSettings"]["IPAddress"].to_s
68
+
67
69
  end
70
+
71
+ hack_etc_hosts @hosts, @options
72
+
68
73
  end
69
74
 
70
75
  def cleanup
@@ -111,6 +111,7 @@ module Beaker
111
111
  @logger.notify 'Tagging vmpooler VMs'
112
112
 
113
113
  tags = {
114
+ 'beaker_version' => Beaker::Version::STRING,
114
115
  'jenkins_build_url' => @options[:jenkins_build_url],
115
116
  'department' => @options[:department],
116
117
  'project' => @options[:project],
@@ -26,7 +26,16 @@ module Beaker
26
26
  @machines = {}
27
27
  @hypervisors = nil
28
28
 
29
- @options[:log_prefix] = File.basename(@options[:hosts_file], '.yml') unless @options[:log_prefix]
29
+ # user provided prefix has top priority
30
+ if not @options[:log_prefix]
31
+ # name it after the hosts file
32
+ if @options[:hosts_file]
33
+ @options[:log_prefix] = File.basename(@options[:hosts_file], '.yml')
34
+ else
35
+ #here be the default
36
+ @options[:log_prefix] = @options[:default_log_prefix]
37
+ end
38
+ end
30
39
  @options[:timestamp] = Time.now unless @options.has_key?(:timestamp)
31
40
  @options[:xml_dated_dir] = Beaker::Logger.generate_dated_log_folder(@options[:xml_dir], @options[:log_prefix], @options[:timestamp])
32
41
  @options[:log_dated_dir] = Beaker::Logger.generate_dated_log_folder(@options[:log_dir], @options[:log_prefix], @options[:timestamp])
@@ -11,9 +11,12 @@ module Beaker
11
11
  # us to define multiple environment variables for the same
12
12
  # configuration value. They are checked in the order they are arrayed
13
13
  # so that preferred and "fallback" values work as expected.
14
+ #
15
+ # 'JOB_NAME' and 'BUILD_URL' envs are supplied by Jenkins
16
+ # https://wiki.jenkins-ci.org/display/JENKINS/Building+a+software+project
14
17
  ENVIRONMENT_SPEC = {
15
18
  :home => 'HOME',
16
- :project => ['BEAKER_PROJECT', 'BEAKER_project'],
19
+ :project => ['BEAKER_PROJECT', 'BEAKER_project', 'JOB_NAME'],
17
20
  :department => ['BEAKER_DEPARTMENT', 'BEAKER_department'],
18
21
  :jenkins_build_url => ['BEAKER_BUILD_URL', 'BUILD_URL'],
19
22
  :created_by => ['BEAKER_CREATED_BY'],
@@ -134,6 +137,7 @@ module Beaker
134
137
  :xml_dir => 'junit',
135
138
  :xml_file => 'beaker_junit.xml',
136
139
  :xml_stylesheet => 'junit.xsl',
140
+ :default_log_prefix => 'beaker_logs',
137
141
  :log_dir => 'log',
138
142
  :log_sut_event => 'sut.log',
139
143
  :color => true,
@@ -3,7 +3,7 @@ module Beaker
3
3
  # all String methods while adding several platform-specific use cases.
4
4
  class Platform < String
5
5
  # Supported platforms
6
- PLATFORMS = /^(osx|centos|fedora|debian|oracle|redhat|scientific|sles|ubuntu|windows|solaris|aix|el|eos|cumulus)\-.+\-.+$/
6
+ PLATFORMS = /^(freebsd|osx|centos|fedora|debian|oracle|redhat|scientific|sles|ubuntu|windows|solaris|aix|el|eos|cumulus)\-.+\-.+$/
7
7
 
8
8
  # Platform version numbers vs. codenames conversion hash
9
9
  PLATFORM_VERSION_CODES =
@@ -37,7 +37,7 @@ module Beaker
37
37
  end
38
38
 
39
39
  def log(logger)
40
- logger.debug "Exited: #{exit_code}" unless exit_code == 0
40
+ logger.debug "Exited: #{exit_code}" unless exit_code == 0 or !exit_code
41
41
  end
42
42
 
43
43
  def formatted_output(limit=10)
@@ -18,6 +18,7 @@ module Beaker
18
18
  Errno::ENETUNREACH,
19
19
  Net::SSH::Disconnect,
20
20
  Net::SSH::AuthenticationFailed,
21
+ IOError,
21
22
  ]
22
23
 
23
24
  def initialize hostname, user = nil, ssh_opts = {}, options = {}
@@ -34,38 +35,47 @@ module Beaker
34
35
  connection
35
36
  end
36
37
 
38
+ # connect to the host
37
39
  def connect
38
40
  try = 1
39
41
  last_wait = 0
40
42
  wait = 1
41
43
  @ssh ||= begin
44
+ @logger.debug "Attempting ssh connection to #{@hostname}, user: #{@user}, opts: #{@ssh_opts}"
42
45
  Net::SSH.start(@hostname, @user, @ssh_opts)
43
46
  rescue *RETRYABLE_EXCEPTIONS => e
44
47
  if try <= 11
45
- @logger.warn "Try #{try} -- Host #{@hostname} unreachable: #{e.message}"
48
+ @logger.warn "Try #{try} -- Host #{@hostname} unreachable: #{e.class.name} - #{e.message}"
46
49
  @logger.warn "Trying again in #{wait} seconds"
47
50
  sleep wait
48
51
  (last_wait, wait) = wait, last_wait + wait
49
52
  try += 1
50
53
  retry
51
54
  else
52
- # why is the logger not passed into this class?
53
55
  @logger.error "Failed to connect to #{@hostname}"
54
56
  raise
55
57
  end
56
58
  end
57
- @logger.debug "Created ssh connection to #{@hostname}, user: #{@user}, opts: #{@ssh_opts}"
58
- self
59
59
  end
60
60
 
61
61
  # closes this SshConnection
62
62
  def close
63
63
  begin
64
- @ssh.close if @ssh
65
- rescue
64
+ if @ssh and not @ssh.closed?
65
+ @ssh.close
66
+ else
67
+ @logger.warn("ssh.close: connection is already closed, no action needed")
68
+ end
69
+ rescue *RETRYABLE_EXCEPTIONS => e
70
+ @logger.warn "Attemped ssh.close, (caught #{e.class.name} - #{e.message})."
71
+ rescue => e
72
+ @logger.warn "ssh.close threw unexpected Error: #{e.class.name} - #{e.message}. Shutting down, and re-raising error below"
66
73
  @ssh.shutdown!
74
+ raise e
75
+ ensure
76
+ @ssh = nil
77
+ @logger.warn("ssh connection to #{@hostname} has been terminated")
67
78
  end
68
- @ssh = nil
69
79
  end
70
80
 
71
81
  def try_to_execute command, options = {}, stdout_callback = nil,
@@ -93,7 +103,13 @@ module Beaker
93
103
 
94
104
  # Process SSH activity until we stop doing that - which is when our
95
105
  # channel is finished with...
96
- @ssh.loop
106
+ begin
107
+ @ssh.loop
108
+ rescue *RETRYABLE_EXCEPTIONS => e
109
+ # this would indicate that the connection failed post execution, since the channel exec was successful
110
+ @logger.warn "ssh channel on #{@hostname} received exception post command execution #{e.class.name} - #{e.message}"
111
+ close
112
+ end
97
113
 
98
114
  result.finalize!
99
115
  @logger.last_result = result
@@ -102,15 +118,21 @@ module Beaker
102
118
 
103
119
  def execute command, options = {}, stdout_callback = nil,
104
120
  stderr_callback = stdout_callback
105
- attempt = true
121
+ try = 1
122
+ wait = 1
123
+ last_wait = 0
106
124
  begin
125
+ # ensure that we have a current connection object
126
+ connect
107
127
  result = try_to_execute(command, options, stdout_callback, stderr_callback)
108
128
  rescue *RETRYABLE_EXCEPTIONS => e
109
- if attempt
110
- attempt = false
111
- @logger.error "Command execution failed, attempting to reconnect to #{@hostname}"
129
+ if try < 11
130
+ sleep wait
131
+ (last_wait, wait) = wait, last_wait + wait
132
+ try += 1
133
+ @logger.error "Command execution '#{@hostname}$ #{command}' failed (#{e.class.name} - #{e.message})"
112
134
  close
113
- connect
135
+ @logger.debug "Preparing to retry: closed ssh object"
114
136
  retry
115
137
  else
116
138
  raise
@@ -1,5 +1,5 @@
1
1
  module Beaker
2
2
  module Version
3
- STRING = '2.8.0'
3
+ STRING = '2.9.0'
4
4
  end
5
5
  end
@@ -118,6 +118,7 @@ describe ClassMixedWithDSLInstallUtils do
118
118
  it{
119
119
  host = double("host")
120
120
  allow( host ).to receive(:[]).with('distmoduledir').and_return('/etc/puppetlabs/puppet/modules')
121
+ allow( host ).to receive(:is_cygwin?).and_return(true)
121
122
  result = double
122
123
  stdout = target.split('/')[0..-2].join('/') + "\n"
123
124
  allow( result ).to receive(:stdout).and_return( stdout )
@@ -167,12 +168,30 @@ describe ClassMixedWithDSLInstallUtils do
167
168
  allow( subject ).to receive( :build_ignore_list ).and_return( [] )
168
169
  allow( subject ).to receive( :parse_for_modulename ).and_return( [nil, 'modulename'] )
169
170
  allow( subject ).to receive( :on ).and_return( double.as_null_object )
170
- hosts = [{}, {}]
171
171
 
172
- expect( subject ).to receive( :scp_to ).twice
172
+ expect( subject ).to receive( :scp_to ).exactly(4).times
173
173
  subject.copy_module_to( hosts )
174
174
  end
175
175
  end
176
+
177
+ describe 'non-cygwin windows' do
178
+ it 'should have different commands than cygwin' do
179
+ host = double("host")
180
+ allow( host ).to receive(:[]).with('platform').and_return('windows')
181
+ allow( host ).to receive(:[]).with('distmoduledir').and_return('C:\\ProgramData\\PuppetLabs\\puppet\\etc\\modules')
182
+ allow( host ).to receive(:is_cygwin?).and_return(false)
183
+
184
+ result = double
185
+ allow( result ).to receive(:stdout).and_return( 'C:\\ProgramData\\PuppetLabs\\puppet\\etc\\modules' )
186
+
187
+ expect( subject ).to receive(:on).with(host, "echo C:\\ProgramData\\PuppetLabs\\puppet\\etc\\modules" ).and_return( result )
188
+
189
+ expect( subject ).to receive(:scp_to).with(host, "/opt/testmodule2", "C:\\ProgramData\\PuppetLabs\\puppet\\etc\\modules", {:ignore => ignore_list})
190
+ expect( subject ).to receive(:on).with(host, 'move /y C:\\ProgramData\\PuppetLabs\\puppet\\etc\\modules/testmodule2 C:\\ProgramData\\PuppetLabs\\puppet\\etc\\modules/testmodule')
191
+
192
+ subject.copy_module_to(host, {:module_name => 'testmodule', :source => '/opt/testmodule2'})
193
+ end
194
+ end
176
195
  end
177
196
 
178
197
  describe 'split_author_modulename' do
@@ -344,18 +344,10 @@ describe ClassMixedWithDSLInstallUtils do
344
344
  end
345
345
 
346
346
  RSpec.shared_examples "install-dev-repo" do
347
- let( :repo_config ) { "repoconfig" }
348
- let( :repo_dir ) { "repodir" }
349
-
350
- before do
351
- allow(subject).to receive(:fetch_http_file) { repo_config }
352
- allow(subject).to receive(:fetch_http_dir) { repo_dir }
353
- allow(subject).to receive(:on).with(host, "apt-get update") { }
354
- allow(subject).to receive(:options) { opts }
355
- allow(subject).to receive(:link_exists?) { true }
356
- end
357
347
 
358
348
  it "scp's files to SUT then modifies them with find-and-sed 2-hit combo" do
349
+ allow(rez).to receive(:exit_code) { 0 }
350
+ allow(subject).to receive(:link_exists?).and_return(true)
359
351
  expect(subject).to receive(:on).with( host, /^mkdir -p .*$/ ).ordered
360
352
  expect(subject).to receive(:scp_to).with( host, repo_config, /.*/ ).ordered
361
353
  expect(subject).to receive(:scp_to).with( host, repo_dir, /.*/ ).ordered
@@ -382,19 +374,72 @@ describe ClassMixedWithDSLInstallUtils do
382
374
  subject.install_puppetlabs_dev_repo host, package_name, package_version
383
375
  }.to raise_error(RuntimeError, /No repository installation step for/)
384
376
  end
385
-
386
377
  end
387
378
 
388
- describe "When host is a debian-like platform" do
389
- let( :platform ) { Beaker::Platform.new('debian-7-i386') }
390
- include_examples "install-dev-repo"
391
- end
379
+ describe 'When on supported platforms' do
380
+ # These are not factored into the `before` block above because they
381
+ # are expectations in the share examples, but aren't interesting
382
+ # beyond those basic tests
383
+ def stub_uninteresting_portions_of_install_puppetlabs_dev_repo!
384
+ allow(subject).to receive(:on).with( host, /^mkdir -p .*$/ ).ordered
385
+ allow(subject).to receive(:scp_to).with( host, repo_config, /.*/ ).ordered
386
+ allow(subject).to receive(:scp_to).with( host, repo_dir, /.*/ ).ordered
387
+ end
392
388
 
393
- describe "When host is a redhat-like platform" do
394
- let( :platform ) { Beaker::Platform.new('el-7-i386') }
395
- include_examples "install-dev-repo"
396
- end
389
+ let( :repo_config ) { "repoconfig" }
390
+ let( :repo_dir ) { "repodir" }
391
+ let( :rez ) { double }
392
+
393
+ before do
394
+ allow(subject).to receive(:fetch_http_file) { repo_config }
395
+ allow(subject).to receive(:fetch_http_dir) { repo_dir }
396
+ allow(subject).to receive(:on).with(host, "apt-get update") { }
397
+ allow(subject).to receive(:options) { opts }
398
+ allow(subject).to receive(:on).with( host, /^.* -d .*/, {:acceptable_exit_codes =>[0,1]} ).and_return(rez)
399
+ end
400
+
401
+ describe "that are debian-like" do
402
+ let( :platform ) { Beaker::Platform.new('debian-7-i386') }
403
+ before { allow(subject).to receive(:link_exists?).and_return(true) }
404
+
405
+ include_examples "install-dev-repo"
397
406
 
407
+ it 'sets up the PC1 repository if that was downloaded' do
408
+ allow(rez).to receive(:exit_code) { 0 }
409
+
410
+ stub_uninteresting_portions_of_install_puppetlabs_dev_repo!
411
+
412
+ expect(subject).to receive(:on).with( host, /^find .* sed .*PC1.*/ )
413
+ subject.install_puppetlabs_dev_repo host, package_name, package_version
414
+ end
415
+
416
+ it 'sets up the main repository if that was downloaded' do
417
+ allow(rez).to receive(:exit_code) { 1 }
418
+
419
+ stub_uninteresting_portions_of_install_puppetlabs_dev_repo!
420
+
421
+ expect(subject).to receive(:on).with( host, /^find .* sed .*main.*/ )
422
+ subject.install_puppetlabs_dev_repo host, package_name, package_version
423
+ end
424
+
425
+ end
426
+
427
+ describe "that are redhat-like" do
428
+ let( :platform ) { Beaker::Platform.new('el-7-i386') }
429
+ include_examples "install-dev-repo"
430
+
431
+ it 'downloads PC1, products, or devel repo -- in that order' do
432
+ allow(subject).to receive(:on).with( host, /^find .* sed .*/ )
433
+ stub_uninteresting_portions_of_install_puppetlabs_dev_repo!
434
+
435
+ expect(subject).to receive(:link_exists?).with(/.*PC1.*/).and_return( false )
436
+ expect(subject).to receive(:link_exists?).with(/.*products.*/).and_return( false )
437
+ expect(subject).to receive(:link_exists?).with(/.*devel.*/).and_return( true )
438
+
439
+ subject.install_puppetlabs_dev_repo host, package_name, package_version
440
+ end
441
+ end
442
+ end
398
443
  end
399
444
 
400
445
  describe '#install_packages_from_local_dev_repo' do
@@ -518,6 +563,52 @@ describe ClassMixedWithDSLInstallUtils do
518
563
 
519
564
  subject.install_puppetagent_dev_repo( host, opts )
520
565
  end
566
+ end
521
567
 
568
+ describe '#install_cert_on_windows' do
569
+ before do
570
+ subject.stub(:on).and_return(Beaker::Result.new({},''))
571
+ end
572
+
573
+ context 'on windows' do
574
+ let(:platform) { 'windows-2008R2-amd64' }
575
+ let(:host) { make_host('testbox.test.local', :platform => 'windows-2008R2-amd64') }
576
+
577
+ it 'should install all 3 certs' do
578
+ cert = 'geotrust_global_ca'
579
+ content = <<-EOM
580
+ -----BEGIN CERTIFICATE-----
581
+ MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
582
+ MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
583
+ YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
584
+ EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
585
+ R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
586
+ 9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
587
+ fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
588
+ iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
589
+ 1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
590
+ bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
591
+ MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
592
+ ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
593
+ uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
594
+ Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
595
+ tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
596
+ PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
597
+ hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
598
+ 5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
599
+ -----END CERTIFICATE-----
600
+ EOM
601
+
602
+ expect(subject).to receive(:create_remote_file) do |host, file_path, file_content|
603
+ expect(file_path).to eq("C:\\Windows\\Temp\\#{cert}.pem")
604
+ end
605
+
606
+ expect(subject).to receive(:on) do |host, command|
607
+ expect(command).to eq("certutil -v -addstore Root C:\\Windows\\Temp\\#{cert}.pem")
608
+ end
609
+
610
+ subject.install_cert_on_windows(host, cert, content)
611
+ end
612
+ end
522
613
  end
523
614
  end
@@ -78,7 +78,8 @@ module Beaker
78
78
  allow( ::Docker ).to receive(:validate_version!).and_raise(Excon::Errors::SocketError.new( StandardError.new('oops') ))
79
79
  end
80
80
  it 'should fail when docker not present' do
81
- expect { docker }.to raise_error(RuntimeError, /Docker instance not found/)
81
+ expect { docker }.to raise_error(RuntimeError, /Docker instance not connectable./)
82
+ expect { docker }.to raise_error(RuntimeError, /Error was: oops/)
82
83
  end
83
84
  end
84
85
 
@@ -198,6 +199,15 @@ module Beaker
198
199
 
199
200
  end
200
201
 
202
+ it "should generate a new /etc/hosts file referencing each host" do
203
+ ENV['DOCKER_HOST'] = nil
204
+ docker.provision
205
+ hosts.each do |host|
206
+ expect( docker ).to receive( :set_etc_hosts ).with( host, "127.0.0.1\tlocalhost localhost.localdomain\n192.0.2.1\tvm1\n192.0.2.1\tvm2\n192.0.2.1\tvm3\n" ).once
207
+ end
208
+ docker.hack_etc_hosts( hosts, options )
209
+ end
210
+
201
211
  it 'should record the image and container for later' do
202
212
  docker.provision
203
213
 
@@ -11,7 +11,9 @@ module Beaker
11
11
  make_opts.merge({
12
12
  'logger' => double().as_null_object,
13
13
  :logger_sut => mock_provisioning_logger,
14
- :log_prefix => 'log_prefix_dummy'
14
+ :log_prefix => @log_prefix,
15
+ :hosts_file => @hosts_file,
16
+ :default_log_prefix => 'hello_default',
15
17
  })
16
18
  }
17
19
  let( :network_manager ) { NetworkManager.new(options, options[:logger]) }
@@ -19,6 +21,10 @@ module Beaker
19
21
  let( :host ) { hosts[0] }
20
22
 
21
23
  describe '#log_sut_event' do
24
+ before :each do
25
+ @log_prefix = 'log_prefix_dummy'
26
+ @hosts_file = 'dummy_hosts'
27
+ end
22
28
 
23
29
  it 'creates the correct content for an event' do
24
30
  log_line = network_manager.log_sut_event host, true
@@ -54,5 +60,29 @@ module Beaker
54
60
  expect{ nm.log_sut_event(host, true) }.to raise_error(ArgumentError)
55
61
  end
56
62
  end
63
+
64
+ it 'uses user defined log prefix if it is provided' do
65
+ @log_prefix = 'dummy_log_prefix'
66
+ @hosts_file = 'dummy_hosts'
67
+ nm = network_manager
68
+ cur_prefix = options[:log_prefix]
69
+ expect(cur_prefix).to be === @log_prefix
70
+ end
71
+
72
+ it 'uses host based log prefix, when there is not user defined log prefix' do
73
+ @log_prefix = nil
74
+ @hosts_file = 'dummy_hosts'
75
+ nm = network_manager
76
+ cur_prefix = options[:log_prefix]
77
+ expect(cur_prefix).to be === @hosts_file
78
+ end
79
+
80
+ it 'uses default log prefix, when there is no user defined and no host file' do
81
+ @log_prefix = nil
82
+ @hosts_file = nil
83
+ nm = network_manager
84
+ cur_prefix = options[:log_prefix]
85
+ expect(cur_prefix).to be === 'hello_default'
86
+ end
57
87
  end
58
- end
88
+ end
@@ -9,6 +9,10 @@ module Beaker
9
9
  let( :options ) { { :logger => double('logger').as_null_object } }
10
10
  subject(:connection) { SshConnection.new host, user, ssh_opts, options }
11
11
 
12
+ before :each do
13
+ allow( subject ).to receive(:sleep)
14
+ end
15
+
12
16
  it 'self.connect creates connects and returns a proxy for that connection' do
13
17
  # grrr
14
18
  expect( Net::SSH ).to receive(:start).with( host, user, ssh_opts )
@@ -27,34 +31,42 @@ module Beaker
27
31
  connection.connect
28
32
  end
29
33
 
30
- it 'close runs ssh close' do
31
- mock_ssh = Object.new
32
- expect( Net::SSH ).to receive( :start ).with( host, user, ssh_opts) { mock_ssh }
33
- connection.connect
34
+ describe '#close' do
34
35
 
35
- expect( mock_ssh ).to receive( :close ).once
36
- connection.close
37
- end
36
+ it 'runs ssh close' do
37
+ mock_ssh = Object.new
38
+ expect( Net::SSH ).to receive( :start ).with( host, user, ssh_opts) { mock_ssh }
39
+ connection.connect
38
40
 
39
- it 'close sets the @ssh variable to nil' do
40
- mock_ssh = Object.new
41
- expect( Net::SSH ).to receive( :start ).with( host, user, ssh_opts) { mock_ssh }
42
- connection.connect
41
+ allow( mock_ssh).to receive( :closed? ).once.and_return(false)
42
+ expect( mock_ssh ).to receive( :close ).once
43
+ connection.close
44
+ end
43
45
 
44
- expect( mock_ssh ).to receive( :close ).once
45
- connection.close
46
+ it 'sets the @ssh variable to nil' do
47
+ mock_ssh = Object.new
48
+ expect( Net::SSH ).to receive( :start ).with( host, user, ssh_opts) { mock_ssh }
49
+ connection.connect
46
50
 
47
- expect( connection.instance_variable_get(:@ssh) ).to be_nil
48
- end
51
+ allow( mock_ssh).to receive( :closed? ).once.and_return(false)
52
+ expect( mock_ssh ).to receive( :close ).once
53
+ connection.close
49
54
 
50
- it 'close calls ssh shutdown if ssh close fails' do
51
- mock_ssh = Object.new
52
- allow( mock_ssh ).to receive( :close ) { raise Error }
53
- expect( Net::SSH ).to receive( :start ).with( host, user, ssh_opts) { mock_ssh }
54
- connection.connect
55
+ expect( connection.instance_variable_get(:@ssh) ).to be_nil
56
+ end
57
+
58
+ it 'calls ssh shutdown & re-raises if ssh close fails with an unexpected Error' do
59
+ mock_ssh = Object.new
60
+ allow( mock_ssh ).to receive( :close ) { raise StandardError }
61
+ expect( Net::SSH ).to receive( :start ).with( host, user, ssh_opts) { mock_ssh }
62
+ connection.connect
63
+
64
+ allow( mock_ssh).to receive( :closed? ).once.and_return(false)
65
+ expect( mock_ssh ).to receive( :shutdown! ).once
66
+ expect{ connection.close }.to raise_error(StandardError)
67
+ expect( connection.instance_variable_get(:@ssh) ).to be_nil
68
+ end
55
69
 
56
- expect( mock_ssh ).to receive( :shutdown! ).once
57
- connection.close
58
70
  end
59
71
 
60
72
  describe '#execute' do
@@ -1,3 +1,4 @@
1
+ require 'simplecov'
1
2
  require 'beaker'
2
3
  require 'fakefs/spec_helpers'
3
4
  require 'mocks'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: beaker
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.8.0
4
+ version: 2.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppetlabs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-26 00:00:00.000000000 Z
11
+ date: 2015-04-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -136,20 +136,6 @@ dependencies:
136
136
  - - ! '>='
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
- - !ruby/object:Gem::Dependency
140
- name: gitlab-grit
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - ! '>='
144
- - !ruby/object:Gem::Version
145
- version: '0'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - ! '>='
151
- - !ruby/object:Gem::Version
152
- version: '0'
153
139
  - !ruby/object:Gem::Dependency
154
140
  name: minitest
155
141
  requirement: !ruby/object:Gem::Requirement
@@ -397,7 +383,6 @@ files:
397
383
  - beaker.gemspec
398
384
  - bin/beaker
399
385
  - ext/completion/beaker-completion.bash
400
- - history.rb
401
386
  - lib/beaker.rb
402
387
  - lib/beaker/answers.rb
403
388
  - lib/beaker/answers/version20.rb
@@ -435,6 +420,7 @@ files:
435
420
  - lib/beaker/host/aix/file.rb
436
421
  - lib/beaker/host/aix/group.rb
437
422
  - lib/beaker/host/aix/user.rb
423
+ - lib/beaker/host/freebsd.rb
438
424
  - lib/beaker/host/mac.rb
439
425
  - lib/beaker/host/mac/group.rb
440
426
  - lib/beaker/host/mac/user.rb
data/history.rb DELETED
@@ -1,60 +0,0 @@
1
- # Generates a HISTORY.md file for your repo based on tags and commits, defaults to history for
2
- # master branch but can generate history for specified branch
3
- #
4
- # Requires: gem install gitlab-grit
5
- # Usage: ruby history.rb /your/repo/directory
6
- #
7
- # Based on https://coderwall.com/p/99mjcg
8
-
9
- require 'grit'
10
-
11
- if ARGV.size < 1
12
- p "Usage: ruby history.rb /your/repo/directory branch(defaults to master)"
13
- exit
14
- end
15
-
16
- output_file = 'HISTORY.md'
17
- repo_dir = ARGV[0]
18
- branch = ARGV[1] || 'master'
19
- output = "# #{File.basename(File.absolute_path(repo_dir))} - History\n"
20
-
21
- repo = Grit::Repo.new(repo_dir)
22
- head = Grit::Tag.new(repo.commits(branch).first.sha, repo, repo.commits(branch).first.id)
23
- tags = repo.tags + [head]
24
- tags.sort! {|x,y| y.commit.authored_date <=> x.commit.authored_date}
25
-
26
- output << "## Tags\n"
27
- tags.each do |tag|
28
- tag_name = tag.name
29
- if tag == tags.first
30
- tag_name = 'LATEST'
31
- end
32
- output << "* [#{tag_name} - #{tag.commit.authored_date.strftime("%-d %b, %Y")} (#{tag.commit.sha[0,8]})](##{tag_name})\n"
33
- end
34
-
35
- output << "\n## Details\n"
36
- tagcount = 0
37
- tags.each do |tag|
38
- tag_name = tag.name
39
- if tag == tags.first
40
- tag_name = 'LATEST'
41
- end
42
- output << "### <a name = \"#{tag_name}\">#{tag_name} - #{tag.commit.authored_date.strftime("%-d %b, %Y")} (#{tag.commit.sha[0,8]})\n\n"
43
- if (tagcount != tags.size - 1)
44
- commit_set = repo.commits_between(tags[tagcount + 1].name, tag.name)
45
- commit_set.sort! {|x,y| y.authored_date <=> x.authored_date }
46
- commit_set.each do |c|
47
- output << "* #{c.short_message} (#{c.sha[0,8]})\n\n"
48
- if c.short_message != c.message
49
- output << "\n```\n#{c.message.gsub(/```/, "\n")}\n```\n"
50
- end
51
- end
52
- else
53
- output << "* Initial release.\n"
54
- end
55
- tagcount += 1
56
- end
57
-
58
- File.open(output_file, 'w') { |f| f.write(output) }
59
-
60
- puts "success, output sent to #{output_file}"