beaker 3.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/acceptance/tests/base/dsl/helpers/hocon_helpers_test.rb +94 -0
- data/bin/beaker +1 -1
- data/docs/how_to/use_hocon_helpers.md +37 -0
- data/docs/tutorials/installation.md +1 -1
- data/lib/beaker/cli.rb +9 -3
- data/lib/beaker/dsl/helpers.rb +2 -1
- data/lib/beaker/dsl/helpers/hocon_helpers.rb +93 -0
- data/lib/beaker/host/freebsd/pkg.rb +29 -5
- data/lib/beaker/host_prebuilt_steps.rb +20 -4
- data/lib/beaker/hypervisor/vmpooler.rb +8 -7
- data/lib/beaker/options/options_hash.rb +8 -0
- data/lib/beaker/options/parser.rb +1 -1
- data/lib/beaker/shared.rb +2 -1
- data/lib/beaker/shared/subcommands_util.rb +37 -0
- data/lib/beaker/version.rb +1 -1
- data/spec/beaker/host/freebsd/pkg_spec.rb +57 -11
- data/spec/beaker/options/parser_spec.rb +17 -3
- data/spec/beaker/shared/subcommands_util_spec.rb +33 -0
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MjE0N2NkNzU1MGYxNjdiNDYwOWI1YjQ0YjA4Mzc2ODg1N2Q4MDliNg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
M2FlZTM0YmJmNGUxMDViYTEzNjVmNDZiZjA5YjkxNTE1ZWUzYjdmMQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MTg2MDM3Yzg5ZmZhY2RjMGU3MTlmM2ZlNzU2MTA3MzY5MGVhMjQwMzdkZWRi
|
10
|
+
ZWE0M2JiYmU3ZWM3MWZlZDExYzMxOGZmMDI0MmM5N2UxYzUwMzRkMjNkNjA2
|
11
|
+
NGJkMzg1NWU2MWM4Y2QxZTM1NTgyNjczN2MxNDVlNzg2ODZlNDg=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NTMzZGE4MDZjZjJjNjU2NTM3NDVkNTg5NTE3YWNjZWMwMWYwZDU5MTlhZjg3
|
14
|
+
ZjdlOTcyZDQyOTVmODNlYTYwODA2ODk3ZTQzN2ViYjRlYjYzODVmY2IwZDYw
|
15
|
+
NjBiMjYyYjVmM2UzZjM5YjdjNzgxOTQzMzY2YzhjODUwNmZhODQ=
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'hocon/config_value_factory'
|
2
|
+
|
3
|
+
test_name 'Hocon Helpers Test' do
|
4
|
+
|
5
|
+
hocon_filename = 'hocon.conf'
|
6
|
+
step 'setup : create hocon file to play with' do
|
7
|
+
hocon_content = <<-END
|
8
|
+
{
|
9
|
+
setting1 : "value1",
|
10
|
+
setting2 : 2,
|
11
|
+
setting3 : False
|
12
|
+
}
|
13
|
+
END
|
14
|
+
create_remote_file(hosts, hocon_filename, hocon_content)
|
15
|
+
end
|
16
|
+
|
17
|
+
step '#hocon_file_read : reads doc' do
|
18
|
+
doc = hocon_file_read_on(hosts[0], hocon_filename)
|
19
|
+
assert(doc.has_value?('setting2'))
|
20
|
+
end
|
21
|
+
|
22
|
+
step '#hocon_file_edit_on : set_value and verify it exists' do
|
23
|
+
hocon_file_edit_on(hosts, hocon_filename) do |host, doc|
|
24
|
+
doc2 = doc.set_value('c', '[4, 5]')
|
25
|
+
|
26
|
+
assert(doc2.has_value?('c'), 'Should have inserted "c" value!')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
step '#hocon_file_edit_on : testing failure modes' do
|
31
|
+
def test_filename_failure(filename)
|
32
|
+
begin
|
33
|
+
hocon_file_edit_on(hosts, filename) do |_, _|
|
34
|
+
fail('block should not run in failure mode')
|
35
|
+
end
|
36
|
+
fail('execution should not continue in failure mode')
|
37
|
+
rescue ArgumentError => e
|
38
|
+
assert(e.to_s =~ /requires a filename/)
|
39
|
+
else
|
40
|
+
fail('No exception raised in failure mode')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
step 'filename is nil' do
|
45
|
+
test_filename_failure(nil)
|
46
|
+
end
|
47
|
+
|
48
|
+
step 'filename is empty string' do
|
49
|
+
test_filename_failure('')
|
50
|
+
end
|
51
|
+
|
52
|
+
step 'no block given' do
|
53
|
+
begin
|
54
|
+
hocon_file_edit_on(hosts, hocon_filename)
|
55
|
+
fail('execution should not continue in failure mode')
|
56
|
+
rescue ArgumentError => e
|
57
|
+
assert(e.to_s =~ /No block was provided/)
|
58
|
+
else
|
59
|
+
fail('No exception raised in failure mode')
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
step '#hocon_file_edit_on : verify saving workflow' do
|
65
|
+
step '#hocon_file_edit_on : set_value and save' do
|
66
|
+
hocon_file_edit_on(hosts, hocon_filename) do |host, doc|
|
67
|
+
doc2 = doc.set_value('a.b', '[1, 2, 3, 4, 5]')
|
68
|
+
create_remote_file(host, hocon_filename, doc2.render)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
step '#hocon_file_edit_on : independently read value to verify save' do
|
73
|
+
hocon_file_edit_on(hosts, hocon_filename) do |host, doc|
|
74
|
+
msg_fail = 'Should have saved "a.b" value inserted in previous step'
|
75
|
+
assert(doc.has_value?('a.b'), msg_fail)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
step '#hocon_file_edit_in_place_on : verify auto-saving workflow' do
|
81
|
+
step '#hocon_file_edit_in_place_on : set_value and save' do
|
82
|
+
hocon_file_edit_in_place_on(hosts, hocon_filename) do |host, doc|
|
83
|
+
doc.set_value('c.d', '[6, 2, 73, 4, 45]')
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
step '#hocon_file_edit_in_place_on : verify save' do
|
88
|
+
hocon_file_edit_on(hosts, hocon_filename) do |host, doc|
|
89
|
+
msg_fail = 'Should have saved "c.d" value inserted in previous step'
|
90
|
+
assert(doc.has_value?('c.d'), msg_fail)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/bin/beaker
CHANGED
@@ -0,0 +1,37 @@
|
|
1
|
+
# How-to Use Hocon Helpers
|
2
|
+
|
3
|
+
Beaker provides a few convenience methods to help you use the
|
4
|
+
[HOCON](https://github.com/typesafehub/config/blob/master/HOCON.md)
|
5
|
+
configuration file format in your testing. This doc will give you an overview of
|
6
|
+
what each method does, but if you'd like more in-depth information, please
|
7
|
+
checkout our
|
8
|
+
[Hocon Helpers Rubydocs](http://www.rubydoc.info/github/puppetlabs/beaker/Beaker/DSL/Helpers/HoconHelpers).
|
9
|
+
|
10
|
+
# #hocon_file_read_on
|
11
|
+
|
12
|
+
If you'd just like to read the contents of a HOCON file from a System Under Test
|
13
|
+
(SUT), this is the method for you. Note that you will get back a
|
14
|
+
[ConfigValueFactory object](https://github.com/puppetlabs/ruby-hocon#basic-usage)
|
15
|
+
like in the other helper methods here.
|
16
|
+
|
17
|
+
# #hocon_file_edit_in_place_on
|
18
|
+
|
19
|
+
This method is specifically for editing a file on a SUT and saving it in-place,
|
20
|
+
meaning it'll save your changes in the place of the original file you read from.
|
21
|
+
|
22
|
+
The special thing to take note of here is that the Proc you pass to this method
|
23
|
+
will need to return the doc that you'd like saved in order for saving to work as
|
24
|
+
specified.
|
25
|
+
|
26
|
+
# #hocon_file_edit_on
|
27
|
+
|
28
|
+
This method is our generic open-ended method for editing a file from a SUT. This
|
29
|
+
is the most flexible method, doing nothing but providing you with the contents
|
30
|
+
of the file to edit yourself.
|
31
|
+
|
32
|
+
This does not save the file edited. Our recommendation is to use the
|
33
|
+
[`create_remote_file` method](http://www.rubydoc.info/github/puppetlabs/beaker/Beaker/DSL/Helpers/HostHelpers#create_remote_file-instance_method),
|
34
|
+
as shown in the
|
35
|
+
[Rubydocs example](http://www.rubydoc.info/github/puppetlabs/beaker/Beaker/DSL/Helpers/HoconHelpers#hocon_file_edit_on-instance_method)
|
36
|
+
if you'd like to save. This allows us to have more flexibility to do things such
|
37
|
+
as moving the edited file to back up or version your changes.
|
@@ -4,7 +4,7 @@ In most cases, beaker is running on a system separate from the SUT; we will comm
|
|
4
4
|
|
5
5
|
## Beaker Requirements
|
6
6
|
|
7
|
-
* Ruby
|
7
|
+
* Ruby >= 2.2.5
|
8
8
|
* libxml2, libxslt (needed for the [Nokogiri](http://nokogiri.org/tutorials/installing_nokogiri.html) gem)
|
9
9
|
* g++ (needed for the [unf_ext](http://rubydoc.info/gems/unf_ext/) gem)
|
10
10
|
* curl (needed for some DSL functions to be able to execute successfully)
|
data/lib/beaker/cli.rb
CHANGED
@@ -31,9 +31,15 @@ module Beaker
|
|
31
31
|
@execute = false
|
32
32
|
return
|
33
33
|
end
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
|
35
|
+
if Beaker::Shared::SubcommandsUtil::write_config?
|
36
|
+
@options.dump_to_file(Beaker::Shared::SubcommandsUtil::CONFIG_PATH)
|
37
|
+
else
|
38
|
+
@logger.info("Beaker!")
|
39
|
+
@logger.info(beaker_version_string)
|
40
|
+
@logger.info(@options.dump)
|
41
|
+
end
|
42
|
+
|
37
43
|
if @options[:parse_only]
|
38
44
|
@execute = false
|
39
45
|
return
|
data/lib/beaker/dsl/helpers.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
-
[ 'facter', 'host', 'puppet', 'test', 'tk', 'web' ].each do |lib|
|
2
|
+
[ 'facter', 'host', 'puppet', 'test', 'tk', 'web', 'hocon' ].each do |lib|
|
3
3
|
require "beaker/dsl/helpers/#{lib}_helpers"
|
4
4
|
end
|
5
5
|
|
@@ -29,6 +29,7 @@ module Beaker
|
|
29
29
|
include Beaker::DSL::Helpers::TestHelpers
|
30
30
|
include Beaker::DSL::Helpers::TKHelpers
|
31
31
|
include Beaker::DSL::Helpers::WebHelpers
|
32
|
+
include Beaker::DSL::Helpers::HoconHelpers
|
32
33
|
include Beaker::DSL::Helpers::Hiera
|
33
34
|
end
|
34
35
|
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'hocon/parser/config_document_factory'
|
3
|
+
require 'hocon/config_value_factory'
|
4
|
+
|
5
|
+
module Beaker
|
6
|
+
module DSL
|
7
|
+
module Helpers
|
8
|
+
# Convenience methods for modifying and reading Hocon configs
|
9
|
+
#
|
10
|
+
# @note For usage guides for these methods, check these sources:
|
11
|
+
# - {https://github.com/puppetlabs/beaker/tree/master/docs/how_to/use_hocon_helpers.md Beaker docs}.
|
12
|
+
# - Beaker acceptance tests in +acceptance/tests/base/dsl/helpers/hocon_helpers_test.rb+
|
13
|
+
module HoconHelpers
|
14
|
+
|
15
|
+
# Reads the given hocon file from a SUT
|
16
|
+
#
|
17
|
+
# @param [Host] host Host to get hocon file from.
|
18
|
+
# @param [String] filename Name of the hocon file to get
|
19
|
+
#
|
20
|
+
# @raise ArgumentError if arguments are missing or incorrect
|
21
|
+
# @return [Hocon::ConfigValueFactory] parsed hocon file
|
22
|
+
def hocon_file_read_on(host, filename)
|
23
|
+
if filename.nil? || filename.empty?
|
24
|
+
raise ArgumentError, '#hocon_file_edit_on requires a filename'
|
25
|
+
end
|
26
|
+
file_contents = on(host, "cat #{filename}").stdout
|
27
|
+
Hocon::Parser::ConfigDocumentFactory.parse_string(file_contents)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Grabs the given hocon file from a SUT, allowing you to edit the file
|
31
|
+
# just like you would a local one in the passed block.
|
32
|
+
#
|
33
|
+
# @note This method does not save the hocon file after editing. Our
|
34
|
+
# recommended workflow for that is included in our example. If you'd
|
35
|
+
# rather just save a file in-place on a SUT, then
|
36
|
+
# {#hocon_file_edit_in_place_on} is a better method to use.
|
37
|
+
#
|
38
|
+
# @example Editing a value & saving as a new file
|
39
|
+
# hocon_file_edit_on(hosts, 'hocon.conf') do |host, doc|
|
40
|
+
# doc2 = doc.set_value('a.b', '[1, 2, 3, 4, 5]')
|
41
|
+
# create_remote_file(host, 'hocon_latest.conf', doc2.render)
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# @param [Host,Array<Host>] hosts Host (or an array of hosts) to
|
45
|
+
# edit the hocon file on.
|
46
|
+
# @param [String] filename Name of the file to edit.
|
47
|
+
# @param [Proc] block Code to edit the hocon file.
|
48
|
+
#
|
49
|
+
# @yield [Host] Currently executing host.
|
50
|
+
# @yield [Hocon::ConfigValueFactory] Doc to edit. Refer to
|
51
|
+
# {https://github.com/puppetlabs/ruby-hocon#basic-usage Hocon's basic usage doc}
|
52
|
+
# for info on how to use this object.
|
53
|
+
#
|
54
|
+
# @raise ArgumentError if arguments are missing or incorrect.
|
55
|
+
# @return nil
|
56
|
+
def hocon_file_edit_on(hosts, filename, &block)
|
57
|
+
if not block_given?
|
58
|
+
msg = 'DSL method `hocon_file_edit_on` provides a given block'
|
59
|
+
msg << ' a hocon file to edit. No block was provided.'
|
60
|
+
raise ArgumentError, msg
|
61
|
+
end
|
62
|
+
block_on hosts, {} do | host |
|
63
|
+
doc = hocon_file_read_on(host, filename)
|
64
|
+
yield host, doc
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Grabs the given hocon file from a SUT, allowing you to edit the file
|
69
|
+
# and have those edits saved in-place of the file on the SUT.
|
70
|
+
#
|
71
|
+
# @note that a the crucial difference between this & {#hocon_file_edit_on}
|
72
|
+
# is that your Proc will need to return the
|
73
|
+
# {#hocon_file_edit_on Hocon::ConfigValueFactory doc}
|
74
|
+
# you want saved for the in-place save to work correctly.
|
75
|
+
#
|
76
|
+
# @note for info about parameters, please checkout {#hocon_file_edit_on}.
|
77
|
+
#
|
78
|
+
# @example setting an attribute & saving
|
79
|
+
# hocon_file_edit_in_place_on(hosts, hocon_filename) do |host, doc|
|
80
|
+
# doc.set_value('c.d', '[6, 2, 73, 4, 45]')
|
81
|
+
# end
|
82
|
+
#
|
83
|
+
def hocon_file_edit_in_place_on(hosts, filename, &block)
|
84
|
+
hocon_file_edit_on(hosts, filename) do |host, doc|
|
85
|
+
content_doc = yield host, doc
|
86
|
+
create_remote_file(host, filename, content_doc.render)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -1,13 +1,37 @@
|
|
1
1
|
module FreeBSD::Pkg
|
2
2
|
include Beaker::CommandFactory
|
3
3
|
|
4
|
-
def
|
5
|
-
|
6
|
-
|
4
|
+
def pkg_info_pattern(package)
|
5
|
+
# This seemingly restrictive pattern prevents false positives...
|
6
|
+
"^#{package}-[0-9][0-9a-zA-Z_\\.,]*$"
|
7
7
|
end
|
8
8
|
|
9
|
-
def
|
10
|
-
|
9
|
+
def check_pkgng_sh
|
10
|
+
'TMPDIR=/dev/null ASSUME_ALWAYS_YES=1 PACKAGESITE=file:///nonexist ' \
|
11
|
+
'pkg info -x "pkg(-devel)?\\$" > /dev/null 2>&1'
|
11
12
|
end
|
12
13
|
|
14
|
+
def pkgng_active?(opts = {})
|
15
|
+
opts = {:accept_all_exit_codes => true}.merge(opts)
|
16
|
+
execute("/bin/sh -c '#{check_pkgng_sh}'", opts) { |r| r }.exit_code == 0
|
17
|
+
end
|
18
|
+
|
19
|
+
def install_package(package, cmdline_args = nil, opts = {})
|
20
|
+
cmd = if pkgng_active?
|
21
|
+
"pkg install #{cmdline_args || '-y'} #{package}"
|
22
|
+
else
|
23
|
+
"pkg_add #{cmdline_args || '-r'} #{package}"
|
24
|
+
end
|
25
|
+
execute(cmd, opts) { |result| result }
|
26
|
+
end
|
27
|
+
|
28
|
+
def check_for_package(package, opts = {})
|
29
|
+
opts = {:accept_all_exit_codes => true}.merge(opts)
|
30
|
+
cmd = if pkgng_active?
|
31
|
+
"pkg info #{package}"
|
32
|
+
else
|
33
|
+
"pkg_info -Ix '#{pkg_info_pattern(package)}'"
|
34
|
+
end
|
35
|
+
execute(cmd, opts) { |result| result }.exit_code == 0
|
36
|
+
end
|
13
37
|
end
|
@@ -13,7 +13,7 @@ module Beaker
|
|
13
13
|
SLEEPWAIT = 5
|
14
14
|
TRIES = 5
|
15
15
|
UNIX_PACKAGES = ['curl', 'ntpdate']
|
16
|
-
FREEBSD_PACKAGES = ['curl', 'perl5']
|
16
|
+
FREEBSD_PACKAGES = ['curl', 'perl5|perl']
|
17
17
|
OPENBSD_PACKAGES = ['curl']
|
18
18
|
WINDOWS_PACKAGES = ['curl']
|
19
19
|
PSWINDOWS_PACKAGES = []
|
@@ -127,11 +127,27 @@ module Beaker
|
|
127
127
|
# @param [Host] host Host to act on
|
128
128
|
# @param [Array<String>] package_list List of package names to install
|
129
129
|
def check_and_install_packages_if_needed host, package_list
|
130
|
-
package_list.each do |
|
131
|
-
|
132
|
-
|
130
|
+
package_list.each do |string|
|
131
|
+
alternatives = string.split('|')
|
132
|
+
next if alternatives.any? { |pkg| host.check_for_package pkg }
|
133
|
+
install_one_of_packages host, alternatives
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# Installs one of alternative packages (first available)
|
138
|
+
#
|
139
|
+
# @param [Host] host Host to act on
|
140
|
+
# @param [Array<String>] packages List of package names (alternatives).
|
141
|
+
def install_one_of_packages host, packages
|
142
|
+
error = nil
|
143
|
+
packages.each do |pkg|
|
144
|
+
begin
|
145
|
+
return host.install_package pkg
|
146
|
+
rescue Beaker::Host::CommandFailure => e
|
147
|
+
error = e
|
133
148
|
end
|
134
149
|
end
|
150
|
+
raise error
|
135
151
|
end
|
136
152
|
|
137
153
|
#Install a set of authorized keys using {HostPrebuiltSteps::ROOT_KEYS_SCRIPT}. This is a
|
@@ -81,13 +81,14 @@ module Beaker
|
|
81
81
|
# @return [Hash] Tag hash
|
82
82
|
def add_tags(host)
|
83
83
|
host[:host_tags].merge(
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
84
|
+
'beaker_version' => Beaker::Version::STRING,
|
85
|
+
'jenkins_build_url' => @options[:jenkins_build_url],
|
86
|
+
'department' => @options[:department],
|
87
|
+
'project' => @options[:project],
|
88
|
+
'created_by' => @options[:created_by],
|
89
|
+
'name' => host.name,
|
90
|
+
'roles' => host.host_hash[:roles].join(', ')
|
91
|
+
)
|
91
92
|
end
|
92
93
|
|
93
94
|
# Get host info hash from parsed json response
|
@@ -38,6 +38,14 @@ module Beaker
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
+
def dump_to_file(output_file)
|
42
|
+
dirname = File.dirname(output_file)
|
43
|
+
unless File.directory?(dirname)
|
44
|
+
FileUtils.mkdir_p(dirname)
|
45
|
+
end
|
46
|
+
File.open(output_file, 'w+') { |f| f.write(dump) }
|
47
|
+
end
|
48
|
+
|
41
49
|
end
|
42
50
|
end
|
43
51
|
end
|
@@ -224,7 +224,7 @@ module Beaker
|
|
224
224
|
# @raise [ArgumentError] if a hosts file is generated, but it can't
|
225
225
|
# be read by the HostsFileParser
|
226
226
|
def parse_hosts_options
|
227
|
-
if File.exists?(@options[:hosts_file])
|
227
|
+
if @options[:hosts_file].nil? || File.exists?(@options[:hosts_file])
|
228
228
|
#read the hosts file that contains the node configuration and hypervisor info
|
229
229
|
return Beaker::Options::HostsFileParser.parse_hosts_file(@options[:hosts_file])
|
230
230
|
end
|
data/lib/beaker/shared.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
[ 'repetition', 'error_handler', 'host_manager', 'timed', 'semvar', 'options_resolver' ].each do |lib|
|
1
|
+
[ 'repetition', 'error_handler', 'host_manager', 'timed', 'semvar', 'options_resolver', 'subcommands_util' ].each do |lib|
|
2
2
|
require "beaker/shared/#{lib}"
|
3
3
|
end
|
4
4
|
module Beaker
|
@@ -9,6 +9,7 @@ module Beaker
|
|
9
9
|
include Beaker::Shared::Timed
|
10
10
|
include Beaker::Shared::Semvar
|
11
11
|
include Beaker::Shared::OptionsResolver
|
12
|
+
include Beaker::Shared::SubcommandsUtil
|
12
13
|
end
|
13
14
|
end
|
14
15
|
include Beaker::Shared
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Beaker
|
2
|
+
module Shared
|
3
|
+
# Methods used in execution of Subcommands
|
4
|
+
# - should we write the config?
|
5
|
+
# - reset ARGV
|
6
|
+
# - execute Beaker
|
7
|
+
module SubcommandsUtil
|
8
|
+
CONFIG_PATH = ".beaker/config"
|
9
|
+
|
10
|
+
@@write_config = false
|
11
|
+
|
12
|
+
def self.write_config=( val )
|
13
|
+
@@write_config = val
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.write_config?
|
17
|
+
@@write_config
|
18
|
+
end
|
19
|
+
|
20
|
+
# Reset ARGV to contain the arguments determined by a specific subcommand
|
21
|
+
# @param [Array<String>] args the arguments determined by a specific subcommand
|
22
|
+
def reset_argv(args)
|
23
|
+
ARGV.clear
|
24
|
+
args.each do |arg|
|
25
|
+
ARGV << arg
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Update ARGV and call Beaker
|
30
|
+
# @param [Array<String>] args the arguments determined by a specific subcommand
|
31
|
+
def execute_beaker(*args)
|
32
|
+
reset_argv(args)
|
33
|
+
Beaker::CLI.new.execute!
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/beaker/version.rb
CHANGED
@@ -27,25 +27,71 @@ module Beaker
|
|
27
27
|
let (:opts) { @opts || {} }
|
28
28
|
let (:logger) { double( 'logger' ).as_null_object }
|
29
29
|
let (:instance) { FreeBSDPkgTest.new(opts, logger) }
|
30
|
+
let(:cond) do
|
31
|
+
'TMPDIR=/dev/null ASSUME_ALWAYS_YES=1 PACKAGESITE=file:///nonexist pkg info -x "pkg(-devel)?\\$" > /dev/null 2>&1'
|
32
|
+
end
|
30
33
|
|
31
|
-
context "
|
32
|
-
|
33
|
-
|
34
|
-
expect( Beaker::Command ).to receive(:new).with('pkg install -y rsync', [], {:prepend_cmds=>nil, :cmdexe=>false}).and_return('')
|
35
|
-
expect( instance ).to receive(:exec).with('', {}).and_return(generate_result("hello", {:exit_code => 0}))
|
36
|
-
instance.install_package('rsync')
|
34
|
+
context "pkg_info_patten" do
|
35
|
+
it "returns correct patterns" do
|
36
|
+
expect( instance.pkg_info_pattern('rsync') ).to eq '^rsync-[0-9][0-9a-zA-Z_\\.,]*$'
|
37
37
|
end
|
38
|
+
end
|
38
39
|
|
40
|
+
context "check_pkgng_sh" do
|
41
|
+
it { expect( instance.check_pkgng_sh ).to eq cond }
|
39
42
|
end
|
40
43
|
|
41
|
-
context "
|
44
|
+
context "pkgng_active?" do
|
45
|
+
it "returns true if pkgng is available" do
|
46
|
+
expect( instance ).to receive(:check_pkgng_sh).once.and_return("do you have pkgng?")
|
47
|
+
expect( Beaker::Command ).to receive(:new).with("/bin/sh -c 'do you have pkgng?'", [], {:prepend_cmds=>nil, :cmdexe=>false}).and_return('')
|
48
|
+
expect( instance ).to receive(:exec).with('',{:accept_all_exit_codes => true}).and_return(generate_result("hello", {:exit_code => 0}))
|
49
|
+
expect( instance.pkgng_active? ).to be true
|
50
|
+
end
|
51
|
+
it "returns false if pkgng is unavailable" do
|
52
|
+
expect( instance ).to receive(:check_pkgng_sh).once.and_return("do you have pkgng?")
|
53
|
+
expect( Beaker::Command ).to receive(:new).with("/bin/sh -c 'do you have pkgng?'", [], {:prepend_cmds=>nil, :cmdexe=>false}).and_return('')
|
54
|
+
expect( instance ).to receive(:exec).with('',{:accept_all_exit_codes => true}).and_return(generate_result("hello", {:exit_code => 127}))
|
55
|
+
expect( instance.pkgng_active? ).to be false
|
56
|
+
end
|
57
|
+
end
|
42
58
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
59
|
+
context "install_package" do
|
60
|
+
context "without pkgng" do
|
61
|
+
it "runs the correct install command" do
|
62
|
+
expect( instance ).to receive(:pkgng_active?).once.and_return(false)
|
63
|
+
expect( Beaker::Command ).to receive(:new).with("pkg_add -r rsync", [], {:prepend_cmds=>nil, :cmdexe=>false}).and_return('')
|
64
|
+
expect( instance ).to receive(:exec).with('', {}).and_return(generate_result("hello", {:exit_code => 0}))
|
65
|
+
instance.install_package('rsync')
|
66
|
+
end
|
47
67
|
end
|
68
|
+
context "with pkgng" do
|
69
|
+
it "runs the correct install command" do
|
70
|
+
expect( instance ).to receive(:pkgng_active?).once.and_return(true)
|
71
|
+
expect( Beaker::Command ).to receive(:new).with("pkg install -y rsync", [], {:prepend_cmds=>nil, :cmdexe=>false}).and_return('')
|
72
|
+
expect( instance ).to receive(:exec).with('', {}).and_return(generate_result("hello", {:exit_code => 0}))
|
73
|
+
instance.install_package('rsync')
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
48
77
|
|
78
|
+
context "check_for_package" do
|
79
|
+
context "without pkgng" do
|
80
|
+
it "runs the correct checking command" do
|
81
|
+
expect( instance ).to receive(:pkgng_active?).once.and_return(false)
|
82
|
+
expect( Beaker::Command ).to receive(:new).with("pkg_info -Ix '^rsync-[0-9][0-9a-zA-Z_\\.,]*$'", [], {:prepend_cmds=>nil, :cmdexe=>false}).and_return('')
|
83
|
+
expect( instance ).to receive(:exec).with('', {:accept_all_exit_codes => true}).and_return(generate_result("hello", {:exit_code => 0}))
|
84
|
+
instance.check_for_package('rsync')
|
85
|
+
end
|
86
|
+
end
|
87
|
+
context "with pkgng" do
|
88
|
+
it "runs the correct checking command" do
|
89
|
+
expect( instance ).to receive(:pkgng_active?).once.and_return(true)
|
90
|
+
expect( Beaker::Command ).to receive(:new).with("pkg info rsync", [], {:prepend_cmds=>nil, :cmdexe=>false}).and_return('')
|
91
|
+
expect( instance ).to receive(:exec).with('', {:accept_all_exit_codes => true}).and_return(generate_result("hello", {:exit_code => 0}))
|
92
|
+
instance.check_for_package('rsync')
|
93
|
+
end
|
94
|
+
end
|
49
95
|
end
|
50
96
|
|
51
97
|
end
|
@@ -246,7 +246,9 @@ module Beaker
|
|
246
246
|
end
|
247
247
|
|
248
248
|
it 'calls beaker-hostgenerator to get hosts information' do
|
249
|
-
parser.instance_variable_set( :@options, {
|
249
|
+
parser.instance_variable_set( :@options, {
|
250
|
+
:hosts_file => 'notafile.yml'
|
251
|
+
} )
|
250
252
|
allow( Beaker::Options::HostsFileParser ).to receive(
|
251
253
|
:parse_hosts_file
|
252
254
|
).and_raise( Errno::ENOENT )
|
@@ -266,7 +268,9 @@ module Beaker
|
|
266
268
|
end
|
267
269
|
|
268
270
|
it 'sets the :hosts_file_generated flag to signal others when needed' do
|
269
|
-
options_test = {
|
271
|
+
options_test = {
|
272
|
+
:hosts_file => 'not_a_file.yml'
|
273
|
+
}
|
270
274
|
parser.instance_variable_set( :@options, options_test )
|
271
275
|
allow( Beaker::Options::HostsFileParser ).to receive(
|
272
276
|
:parse_hosts_file
|
@@ -284,7 +288,9 @@ module Beaker
|
|
284
288
|
end
|
285
289
|
|
286
290
|
it 'beaker-hostgenerator failures trigger nice prints & a rethrow' do
|
287
|
-
options_test = {
|
291
|
+
options_test = {
|
292
|
+
:hosts_file => 'not_a_file.yml'
|
293
|
+
}
|
288
294
|
parser.instance_variable_set( :@options, options_test )
|
289
295
|
allow( Beaker::Options::HostsFileParser ).to receive(
|
290
296
|
:parse_hosts_file
|
@@ -309,6 +315,14 @@ module Beaker
|
|
309
315
|
parser.parse_hosts_options
|
310
316
|
}.to raise_error( BeakerHostGenerator::Exceptions::InvalidNodeSpecError )
|
311
317
|
end
|
318
|
+
|
319
|
+
it 'can be passed a nil hosts file and get the default hash back' do
|
320
|
+
parser.instance_variable_set( :@options, {} )
|
321
|
+
|
322
|
+
host_options = parser.parse_hosts_options
|
323
|
+
expect(host_options[:HOSTS]).to be === {}
|
324
|
+
|
325
|
+
end
|
312
326
|
end
|
313
327
|
|
314
328
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Beaker
|
4
|
+
module Shared
|
5
|
+
describe SubcommandsUtil do
|
6
|
+
|
7
|
+
let(:cli) {
|
8
|
+
double("cli")
|
9
|
+
}
|
10
|
+
|
11
|
+
describe 'reset_argv' do
|
12
|
+
it "resets argv" do
|
13
|
+
args = ["test1", "test2"]
|
14
|
+
expect(ARGV).to receive(:clear).exactly(1).times
|
15
|
+
subject.reset_argv(args)
|
16
|
+
expect(ARGV[0]).to eq(args[0])
|
17
|
+
expect(ARGV[1]).to eq(args[1])
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'execute_beaker' do
|
22
|
+
it "executes beaker with arguments" do
|
23
|
+
allow(cli).to receive(:execute!).and_return(true)
|
24
|
+
allow(Beaker::CLI).to receive(:new).and_return(cli)
|
25
|
+
expect(subject).to receive(:reset_argv).exactly(1).times
|
26
|
+
expect(cli).to receive(:execute!).exactly(1).times
|
27
|
+
subject.execute_beaker(['args'])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
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: 3.
|
4
|
+
version: 3.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Puppetlabs
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-10-
|
11
|
+
date: 2016-10-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -460,6 +460,7 @@ files:
|
|
460
460
|
- acceptance/pre_suite/puppet_pkg/install.rb
|
461
461
|
- acceptance/tests/base/README.md
|
462
462
|
- acceptance/tests/base/dsl/helpers/configuration_test.rb
|
463
|
+
- acceptance/tests/base/dsl/helpers/hocon_helpers_test.rb
|
463
464
|
- acceptance/tests/base/dsl/helpers/host_helpers/add_system32_hosts_entry_test.rb
|
464
465
|
- acceptance/tests/base/dsl/helpers/host_helpers/archive_file_from_test.rb
|
465
466
|
- acceptance/tests/base/dsl/helpers/host_helpers/backup_the_file_test.rb
|
@@ -539,6 +540,7 @@ files:
|
|
539
540
|
- docs/how_to/test_arbitrary_beaker_versions.md
|
540
541
|
- docs/how_to/the_beaker_dsl.md
|
541
542
|
- docs/how_to/upgrade_from_2_to_3.md
|
543
|
+
- docs/how_to/use_hocon_helpers.md
|
542
544
|
- docs/how_to/use_user_password_authentication.md
|
543
545
|
- docs/how_to/write_a_beaker_test_for_a_module.md
|
544
546
|
- docs/tutorials/README.md
|
@@ -559,6 +561,7 @@ files:
|
|
559
561
|
- lib/beaker/dsl/assertions.rb
|
560
562
|
- lib/beaker/dsl/helpers.rb
|
561
563
|
- lib/beaker/dsl/helpers/facter_helpers.rb
|
564
|
+
- lib/beaker/dsl/helpers/hocon_helpers.rb
|
562
565
|
- lib/beaker/dsl/helpers/host_helpers.rb
|
563
566
|
- lib/beaker/dsl/helpers/puppet_helpers.rb
|
564
567
|
- lib/beaker/dsl/helpers/test_helpers.rb
|
@@ -654,6 +657,7 @@ files:
|
|
654
657
|
- lib/beaker/shared/options_resolver.rb
|
655
658
|
- lib/beaker/shared/repetition.rb
|
656
659
|
- lib/beaker/shared/semvar.rb
|
660
|
+
- lib/beaker/shared/subcommands_util.rb
|
657
661
|
- lib/beaker/shared/timed.rb
|
658
662
|
- lib/beaker/ssh_connection.rb
|
659
663
|
- lib/beaker/tasks/quick_start.rb
|
@@ -742,6 +746,7 @@ files:
|
|
742
746
|
- spec/beaker/shared/options_resolver_spec.rb
|
743
747
|
- spec/beaker/shared/repetition_spec.rb
|
744
748
|
- spec/beaker/shared/semvar_spec.rb
|
749
|
+
- spec/beaker/shared/subcommands_util_spec.rb
|
745
750
|
- spec/beaker/ssh_connection_spec.rb
|
746
751
|
- spec/beaker/test_case_spec.rb
|
747
752
|
- spec/beaker/test_suite_spec.rb
|