voxpupuli-acceptance 0.1.1 → 1.0.1
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,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a4af7213db70ec8ff38b6c3210f221161309ce55aacad5fc2edceda47acad4c8
|
4
|
+
data.tar.gz: 9837dce3ad8410384caa6d75d275e2ca8bbbcf706c556cf67c3c19c18314e67e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f3f0acefd724b135d00a073c4587c09467e952e1e147796d50189319639ed5fa4de34afd6f0d7b55e441dbbf575badb9634c539c285492c05ecd791ef376c450
|
7
|
+
data.tar.gz: 8b17e3c63d05c963bc37a9d8dac23e105b8d726518f7ffb8898875fc3dff14cce0e861f9170b26aa41901718b0abff45e089230813ca2fd67dfd744664062372
|
@@ -0,0 +1,21 @@
|
|
1
|
+
shared_examples 'an idempotent resource' do |host|
|
2
|
+
host ||= default
|
3
|
+
|
4
|
+
it 'applies with no errors' do
|
5
|
+
apply_manifest_on(host, manifest, catch_failures: true)
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'applies a second time without changes' do
|
9
|
+
apply_manifest_on(host, manifest, catch_changes: true)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
shared_examples 'the example' do |name, host|
|
14
|
+
include_examples 'an idempotent resource', host do
|
15
|
+
let(:manifest) do
|
16
|
+
path = File.join(Dir.pwd, 'examples', name)
|
17
|
+
raise Exception, "Example '#{path}' does not exist" unless File.exist?(path)
|
18
|
+
File.read(path)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Voxpupuli
|
2
|
+
module Acceptance
|
3
|
+
class Facts
|
4
|
+
ENV_VAR_PREFIX = 'BEAKER_FACTER_'
|
5
|
+
FACT_FILE = '/etc/facter/facts.d/voxpupuli-acceptance-env.json'
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def beaker_facts_from_env
|
9
|
+
facts = {}
|
10
|
+
|
11
|
+
ENV.each do |var, value|
|
12
|
+
next unless var.start_with?(ENV_VAR_PREFIX)
|
13
|
+
|
14
|
+
fact = var.sub(ENV_VAR_PREFIX, '').downcase
|
15
|
+
facts[fact] = value
|
16
|
+
end
|
17
|
+
|
18
|
+
facts
|
19
|
+
end
|
20
|
+
|
21
|
+
def write_beaker_facts_on(hosts)
|
22
|
+
beaker_facts = beaker_facts_from_env
|
23
|
+
|
24
|
+
if beaker_facts.any?
|
25
|
+
require 'json'
|
26
|
+
on(hosts, "mkdir -p #{File.dirname(FACT_FILE)} && cat <<VOXPUPULI_BEAKER_ENV_VARS > #{FACT_FILE}\n#{beaker_facts.to_json}\nVOXPUPULI_BEAKER_ENV_VARS")
|
27
|
+
else
|
28
|
+
on(hosts, "rm -f #{FACT_FILE}")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
require 'puppet/modulebuilder'
|
3
|
+
|
4
|
+
module Voxpupuli
|
5
|
+
module Acceptance
|
6
|
+
class Fixtures
|
7
|
+
class << self
|
8
|
+
# Install fixture modules on the given hosts
|
9
|
+
#
|
10
|
+
# @param [Host, Array<Host>, String, Symbol] hosts
|
11
|
+
# The beaker hosts to run on
|
12
|
+
# @param [Array<String>, String] modulepath
|
13
|
+
# A modulepath as Puppet uses it. Typically spec/fixtures/modules
|
14
|
+
# @param [Logger, nil] logger
|
15
|
+
# An optional logger
|
16
|
+
def install_fixture_modules_on(hosts, modulepath, logger = nil)
|
17
|
+
Dir.mktmpdir do |destination|
|
18
|
+
modules = build_modules(modulepath, destination, logger)
|
19
|
+
|
20
|
+
install_modules_on(hosts, modules, logger)
|
21
|
+
end
|
22
|
+
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
|
26
|
+
# Build modules in the given sources.
|
27
|
+
#
|
28
|
+
# @param [Array<String>, String] modulepath
|
29
|
+
# A modulepath as Puppet uses it
|
30
|
+
# @param [String] destination
|
31
|
+
# The target directory to build modules into
|
32
|
+
# @param [Logger, nil] logger
|
33
|
+
# An optional logger
|
34
|
+
#
|
35
|
+
# @return [Hash<String=>String>]
|
36
|
+
# A mapping of module names and the path to their tarball
|
37
|
+
def build_modules(modulepath, destination, logger = nil)
|
38
|
+
modulepath = [modulepath] if modulepath.is_a?(String)
|
39
|
+
|
40
|
+
modules = {}
|
41
|
+
|
42
|
+
modulepath.each do |dir|
|
43
|
+
Dir[File.join(dir, '*', 'metadata.json')].each do |metadata|
|
44
|
+
path = File.dirname(metadata)
|
45
|
+
name = File.basename(path)
|
46
|
+
next if modules.include?(name)
|
47
|
+
|
48
|
+
builder = Puppet::Modulebuilder::Builder.new(File.realpath(path), destination, logger)
|
49
|
+
|
50
|
+
unless valid_directory_name?(name, builder.metadata['name'])
|
51
|
+
warning = "Directory name of #{path} doesn't match metadata name #{builder.metadata['name']}"
|
52
|
+
if logger
|
53
|
+
logger.warn(warning)
|
54
|
+
else
|
55
|
+
STDERR.puts(warning)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
modules[name] = builder.build
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
modules
|
64
|
+
end
|
65
|
+
|
66
|
+
# Install modules on a number of hosts
|
67
|
+
#
|
68
|
+
# This is done by iterating over every host. On that host a temporary
|
69
|
+
# directory is created. Each module is copied there and installed by
|
70
|
+
# force.
|
71
|
+
#
|
72
|
+
# @param [Host, Array<Host>, String, Symbol] hosts
|
73
|
+
# The beaker hosts to run on
|
74
|
+
# @param [Hash<String=>String>] modules
|
75
|
+
# A mapping between module names and their tarball
|
76
|
+
# @param [Logger, nil] logger
|
77
|
+
# An optional logger
|
78
|
+
def install_modules_on(hosts, modules, logger = nil)
|
79
|
+
hosts.each do |host|
|
80
|
+
logger.debug("Installing modules on #{host}") if logger
|
81
|
+
|
82
|
+
temp_dir_on(host) do |target_dir|
|
83
|
+
modules.each do |name, source_path|
|
84
|
+
target_file = File.join(target_dir, File.basename(source_path))
|
85
|
+
logger.debug("Copying module #{name} from #{source_path} to #{target_file}") if logger
|
86
|
+
|
87
|
+
scp_to(host, source_path, target_file)
|
88
|
+
on host, puppet("module install --force --ignore-dependencies '#{target_file}'")
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
nil
|
94
|
+
end
|
95
|
+
|
96
|
+
# Create a temporay directory on the host, similar to Dir.mktmpdir but
|
97
|
+
# on a remote host.
|
98
|
+
#
|
99
|
+
# @example
|
100
|
+
# temp_dir_on(host) { |dir| puts dir }
|
101
|
+
#
|
102
|
+
# @param [Host, String, Symbol] host
|
103
|
+
# The beaker host to run on
|
104
|
+
def temp_dir_on(host, &block)
|
105
|
+
result = on host, "mktemp -d"
|
106
|
+
raise "Could not create directory" unless result.success?
|
107
|
+
|
108
|
+
dir = result.stdout.strip
|
109
|
+
|
110
|
+
begin
|
111
|
+
yield dir
|
112
|
+
ensure
|
113
|
+
on host, "rm -rf #{dir}"
|
114
|
+
end
|
115
|
+
|
116
|
+
nil
|
117
|
+
end
|
118
|
+
|
119
|
+
# Validate a directory name matches its metadata name.
|
120
|
+
#
|
121
|
+
# This is useful to detect misconfigurations in fixture set ups.
|
122
|
+
#
|
123
|
+
# @example
|
124
|
+
# assert valid_directory_name?('tftp', 'theforeman-tftp')
|
125
|
+
# @example
|
126
|
+
# refute valid_directory_name?('puppet-tftp', 'theforeman-tftp')
|
127
|
+
#
|
128
|
+
# @param [String] directory_name
|
129
|
+
# Name of the directory. Not the full path
|
130
|
+
# @param [String] metadata_name
|
131
|
+
# Name as it shows up in the metadata. It is normalized and accepts
|
132
|
+
# both / and - as separators.
|
133
|
+
#
|
134
|
+
# @return [Boolean] Wether the directory name is valid with the given
|
135
|
+
# metadata name
|
136
|
+
def valid_directory_name?(directory_name, metadata_name)
|
137
|
+
normalized = metadata_name.tr('/', '-').split('-').last
|
138
|
+
normalized == directory_name
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -1,14 +1,25 @@
|
|
1
|
-
|
1
|
+
require_relative 'examples'
|
2
|
+
|
3
|
+
def configure_beaker(modules: :metadata, &block)
|
2
4
|
ENV['PUPPET_INSTALL_TYPE'] ||= 'agent'
|
3
5
|
ENV['BEAKER_PUPPET_COLLECTION'] ||= 'puppet6'
|
4
6
|
ENV['BEAKER_debug'] ||= 'true'
|
5
7
|
ENV['BEAKER_HYPERVISOR'] ||= 'docker'
|
6
8
|
|
9
|
+
# On Ruby 3 this doesn't appear to matter but on Ruby 2 beaker-hiera must be
|
10
|
+
# included before beaker-rspec so Beaker::DSL is final
|
11
|
+
require 'beaker-hiera'
|
7
12
|
require 'beaker-rspec'
|
8
13
|
require 'beaker-puppet'
|
9
14
|
require 'beaker/puppet_install_helper'
|
10
|
-
|
11
|
-
|
15
|
+
|
16
|
+
case modules
|
17
|
+
when :metadata
|
18
|
+
require 'beaker/module_install_helper'
|
19
|
+
$module_source_dir = get_module_source_directory caller
|
20
|
+
when :fixtures
|
21
|
+
require_relative 'fixtures'
|
22
|
+
end
|
12
23
|
|
13
24
|
run_puppet_install_helper unless ENV['BEAKER_provision'] == 'no'
|
14
25
|
|
@@ -18,14 +29,56 @@ def configure_beaker(&block)
|
|
18
29
|
|
19
30
|
# Configure all nodes in nodeset
|
20
31
|
c.before :suite do
|
21
|
-
|
22
|
-
|
32
|
+
case modules
|
33
|
+
when :metadata
|
34
|
+
install_module
|
35
|
+
install_module_dependencies
|
36
|
+
when :fixtures
|
37
|
+
fixture_modules = File.join(Dir.pwd, 'spec', 'fixtures', 'modules')
|
38
|
+
Voxpupuli::Acceptance::Fixtures.install_fixture_modules_on(hosts, fixture_modules)
|
39
|
+
end
|
23
40
|
|
24
|
-
if
|
25
|
-
|
26
|
-
|
41
|
+
if RSpec.configuration.suite_configure_facts_from_env
|
42
|
+
require_relative 'facts'
|
43
|
+
Voxpupuli::Acceptance::Facts.write_beaker_facts_on(hosts)
|
44
|
+
end
|
45
|
+
|
46
|
+
if RSpec.configuration.suite_hiera?
|
47
|
+
hiera_data_dir = RSpec.configuration.suite_hiera_data_dir
|
48
|
+
|
49
|
+
if Dir.exist?(hiera_data_dir)
|
50
|
+
write_hiera_config_on(hosts, RSpec.configuration.suite_hiera_hierachy)
|
51
|
+
copy_hiera_data_to(hosts, hiera_data_dir)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
local_setup = RSpec.configuration.setup_acceptance_node
|
56
|
+
hosts.each do |host|
|
57
|
+
yield host if block
|
58
|
+
|
59
|
+
if local_setup && File.exist?(local_setup)
|
60
|
+
puts "Configuring #{host} by applying #{local_setup}"
|
61
|
+
apply_manifest_on(host, File.read(local_setup), catch_failures: true)
|
27
62
|
end
|
28
63
|
end
|
29
64
|
end
|
30
65
|
end
|
31
66
|
end
|
67
|
+
|
68
|
+
RSpec.configure do |c|
|
69
|
+
# Fact handling
|
70
|
+
c.add_setting :suite_configure_facts_from_env, default: true
|
71
|
+
|
72
|
+
# Hiera settings
|
73
|
+
c.add_setting :suite_hiera, default: true
|
74
|
+
c.add_setting :suite_hiera_data_dir, default: File.join('spec', 'acceptance', 'hieradata')
|
75
|
+
c.add_setting :suite_hiera_hierachy, default: [
|
76
|
+
'fqdn/%{fqdn}.yaml',
|
77
|
+
'os/%{os.family}/%{os.release.major}.yaml',
|
78
|
+
'os/%{os.family}.yaml',
|
79
|
+
'common.yaml',
|
80
|
+
]
|
81
|
+
|
82
|
+
# Node setup
|
83
|
+
c.add_setting :setup_acceptance_node, default: File.join('spec', 'setup_acceptance_node.pp')
|
84
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: voxpupuli-acceptance
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vox Pupuli
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-07-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bcrypt_pbkdf
|
@@ -31,6 +31,12 @@ dependencies:
|
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 4.2.0
|
34
|
+
- - "!="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 4.22.0
|
37
|
+
- - "!="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 4.23.0
|
34
40
|
type: :runtime
|
35
41
|
prerelease: false
|
36
42
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -38,6 +44,12 @@ dependencies:
|
|
38
44
|
- - ">="
|
39
45
|
- !ruby/object:Gem::Version
|
40
46
|
version: 4.2.0
|
47
|
+
- - "!="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: 4.22.0
|
50
|
+
- - "!="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 4.23.0
|
41
53
|
- !ruby/object:Gem::Dependency
|
42
54
|
name: beaker-docker
|
43
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +64,20 @@ dependencies:
|
|
52
64
|
- - ">="
|
53
65
|
- !ruby/object:Gem::Version
|
54
66
|
version: '0'
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: beaker-hiera
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - "~>"
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0.4'
|
74
|
+
type: :runtime
|
75
|
+
prerelease: false
|
76
|
+
version_requirements: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - "~>"
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0.4'
|
55
81
|
- !ruby/object:Gem::Dependency
|
56
82
|
name: beaker-hostgenerator
|
57
83
|
requirement: !ruby/object:Gem::Requirement
|
@@ -150,6 +176,34 @@ dependencies:
|
|
150
176
|
- - ">="
|
151
177
|
- !ruby/object:Gem::Version
|
152
178
|
version: '0'
|
179
|
+
- !ruby/object:Gem::Dependency
|
180
|
+
name: puppet-modulebuilder
|
181
|
+
requirement: !ruby/object:Gem::Requirement
|
182
|
+
requirements:
|
183
|
+
- - "~>"
|
184
|
+
- !ruby/object:Gem::Version
|
185
|
+
version: '0.1'
|
186
|
+
type: :runtime
|
187
|
+
prerelease: false
|
188
|
+
version_requirements: !ruby/object:Gem::Requirement
|
189
|
+
requirements:
|
190
|
+
- - "~>"
|
191
|
+
- !ruby/object:Gem::Version
|
192
|
+
version: '0.1'
|
193
|
+
- !ruby/object:Gem::Dependency
|
194
|
+
name: rake
|
195
|
+
requirement: !ruby/object:Gem::Requirement
|
196
|
+
requirements:
|
197
|
+
- - ">="
|
198
|
+
- !ruby/object:Gem::Version
|
199
|
+
version: '0'
|
200
|
+
type: :runtime
|
201
|
+
prerelease: false
|
202
|
+
version_requirements: !ruby/object:Gem::Requirement
|
203
|
+
requirements:
|
204
|
+
- - ">="
|
205
|
+
- !ruby/object:Gem::Version
|
206
|
+
version: '0'
|
153
207
|
- !ruby/object:Gem::Dependency
|
154
208
|
name: rbnacl
|
155
209
|
requirement: !ruby/object:Gem::Requirement
|
@@ -215,8 +269,12 @@ extensions: []
|
|
215
269
|
extra_rdoc_files: []
|
216
270
|
files:
|
217
271
|
- lib/voxpupuli/acceptance.rb
|
272
|
+
- lib/voxpupuli/acceptance/examples.rb
|
273
|
+
- lib/voxpupuli/acceptance/facts.rb
|
274
|
+
- lib/voxpupuli/acceptance/fixtures.rb
|
275
|
+
- lib/voxpupuli/acceptance/rake.rb
|
218
276
|
- lib/voxpupuli/acceptance/spec_helper_acceptance.rb
|
219
|
-
homepage:
|
277
|
+
homepage: https://github.com/voxpupuli/voxpupuli-acceptance
|
220
278
|
licenses:
|
221
279
|
- Apache-2.0
|
222
280
|
metadata: {}
|
@@ -228,15 +286,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
228
286
|
requirements:
|
229
287
|
- - ">="
|
230
288
|
- !ruby/object:Gem::Version
|
231
|
-
version: '
|
289
|
+
version: '2.4'
|
290
|
+
- - "<"
|
291
|
+
- !ruby/object:Gem::Version
|
292
|
+
version: '4'
|
232
293
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
233
294
|
requirements:
|
234
295
|
- - ">="
|
235
296
|
- !ruby/object:Gem::Version
|
236
297
|
version: '0'
|
237
298
|
requirements: []
|
238
|
-
|
239
|
-
rubygems_version: 2.7.10
|
299
|
+
rubygems_version: 3.1.6
|
240
300
|
signing_key:
|
241
301
|
specification_version: 4
|
242
302
|
summary: Helpers for acceptance testing Vox Pupuli modules
|