beaker 3.1.0 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|