puppetlabs_spec_helper 5.0.0 → 6.0.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 +4 -4
- data/.rubocop.yml +13 -514
- data/README.md +2 -2
- data/lib/puppetlabs_spec_helper/module_spec_helper.rb +10 -9
- data/lib/puppetlabs_spec_helper/puppet_spec_helper.rb +1 -3
- data/lib/puppetlabs_spec_helper/puppetlabs_spec/files.rb +42 -42
- data/lib/puppetlabs_spec_helper/puppetlabs_spec/fixtures.rb +39 -41
- data/lib/puppetlabs_spec_helper/puppetlabs_spec/puppet_internals.rb +34 -32
- data/lib/puppetlabs_spec_helper/rake_tasks.rb +19 -23
- data/lib/puppetlabs_spec_helper/tasks/check_symlinks.rb +41 -37
- data/lib/puppetlabs_spec_helper/tasks/fixtures.rb +343 -353
- data/lib/puppetlabs_spec_helper/version.rb +1 -1
- data/spec/acceptance/smoke_spec.rb +1 -1
- data/spec/spec_helper.rb +2 -2
- data/spec/unit/puppetlabs_spec_helper/tasks/check_symlinks_spec.rb +17 -17
- data/spec/unit/puppetlabs_spec_helper/tasks/check_test_file_spec.rb +4 -4
- data/spec/unit/puppetlabs_spec_helper/tasks/{fixtures_spec.rb → fixture_helpers_spec.rb} +33 -33
- data/spec/watchr.rb +3 -5
- metadata +30 -12
|
@@ -1,61 +1,61 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# rubocop:disable Style/GlobalVars # TODO: investigate the use of instance variables
|
|
4
|
-
|
|
5
3
|
require 'fileutils'
|
|
6
4
|
require 'tempfile'
|
|
7
5
|
require 'pathname'
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
module
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
module PuppetlabsSpec
|
|
8
|
+
# A support module for testing files.
|
|
9
|
+
module Files
|
|
10
|
+
# This code exists only to support tests that run as root, pretty much.
|
|
11
|
+
# Once they have finally been eliminated this can all go... --daniel 2011-04-08
|
|
12
|
+
def self.in_tmp(path)
|
|
13
|
+
tempdir = Dir.tmpdir
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
Pathname.new(path).ascend do |dir|
|
|
16
|
+
return true if File.identical?(tempdir, dir)
|
|
17
|
+
end
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
false
|
|
20
|
+
end
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
def self.cleanup
|
|
23
|
+
$global_tempfiles ||= []
|
|
24
|
+
while (path = $global_tempfiles.pop)
|
|
25
|
+
raise "Not deleting tmpfile #{path} outside regular tmpdir" unless in_tmp(path)
|
|
27
26
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
begin
|
|
28
|
+
FileUtils.rm_r path, secure: true
|
|
29
|
+
rescue Errno::ENOENT
|
|
30
|
+
# nothing to do
|
|
31
|
+
end
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
|
-
end
|
|
35
34
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
def make_absolute(path)
|
|
36
|
+
path = File.expand_path(path)
|
|
37
|
+
path[0] = 'c' if Puppet.features.microsoft_windows?
|
|
38
|
+
path
|
|
39
|
+
end
|
|
41
40
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
def tmpfilename(name)
|
|
42
|
+
# Generate a temporary file, just for the name...
|
|
43
|
+
source = Tempfile.new(name)
|
|
44
|
+
path = source.path
|
|
45
|
+
source.close!
|
|
47
46
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
# ...record it for cleanup,
|
|
48
|
+
$global_tempfiles ||= []
|
|
49
|
+
$global_tempfiles << File.expand_path(path)
|
|
51
50
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
# ...and bam.
|
|
52
|
+
path
|
|
53
|
+
end
|
|
55
54
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
def tmpdir(name)
|
|
56
|
+
path = tmpfilename(name)
|
|
57
|
+
FileUtils.mkdir_p(path)
|
|
58
|
+
path
|
|
59
|
+
end
|
|
60
60
|
end
|
|
61
61
|
end
|
|
@@ -1,53 +1,51 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
# Returns the path to your relative fixture dir. So if your spec test is
|
|
13
|
-
# <project>/spec/unit/facter/foo_spec.rb then your relative dir will be
|
|
14
|
-
# <project>/spec/fixture/unit/facter/foo
|
|
15
|
-
def my_fixture_dir
|
|
16
|
-
callers = caller
|
|
17
|
-
while (line = callers.shift)
|
|
18
|
-
next unless (found = line.match(%r{/spec/(.*)_spec\.rb:}))
|
|
19
|
-
|
|
20
|
-
return fixtures(found[1])
|
|
3
|
+
module PuppetlabsSpec
|
|
4
|
+
# This module provides some helper methods to assist with fixtures. It's
|
|
5
|
+
# methods are designed to help when you have a conforming fixture layout so we
|
|
6
|
+
# get project consistency.
|
|
7
|
+
module Fixtures
|
|
8
|
+
# Returns the joined path of the global FIXTURE_DIR plus any path given to it
|
|
9
|
+
def fixtures(*rest)
|
|
10
|
+
File.join(PuppetlabsSpec::FIXTURE_DIR, *rest)
|
|
21
11
|
end
|
|
22
|
-
raise "sorry, I couldn't work out your path from the caller stack!"
|
|
23
|
-
end
|
|
24
12
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
13
|
+
# Returns the path to your relative fixture dir. So if your spec test is
|
|
14
|
+
# <project>/spec/unit/facter/foo_spec.rb then your relative dir will be
|
|
15
|
+
# <project>/spec/fixture/unit/facter/foo
|
|
16
|
+
def my_fixture_dir
|
|
17
|
+
callers = caller
|
|
18
|
+
while (line = callers.shift)
|
|
19
|
+
next unless (found = line.match(%r{/spec/(.*)_spec\.rb:}))
|
|
20
|
+
|
|
21
|
+
return fixtures(found[1])
|
|
22
|
+
end
|
|
23
|
+
raise "sorry, I couldn't work out your path from the caller stack!"
|
|
31
24
|
end
|
|
32
25
|
|
|
33
|
-
file
|
|
34
|
-
|
|
26
|
+
# Given a name, returns the full path of a file from your relative fixture
|
|
27
|
+
# dir as returned by my_fixture_dir.
|
|
28
|
+
def my_fixture(name)
|
|
29
|
+
file = File.join(my_fixture_dir, name)
|
|
30
|
+
raise "fixture '#{name}' for #{my_fixture_dir} is not readable" unless File.readable? file
|
|
35
31
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def my_fixture_read(name)
|
|
39
|
-
File.read(my_fixture(name))
|
|
40
|
-
end
|
|
32
|
+
file
|
|
33
|
+
end
|
|
41
34
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if files.empty?
|
|
47
|
-
raise "fixture '#{glob}' for #{my_fixture_dir} had no files!"
|
|
35
|
+
# Return the contents of the file using read when given a name. Uses
|
|
36
|
+
# my_fixture to work out the relative path.
|
|
37
|
+
def my_fixture_read(name)
|
|
38
|
+
File.read(my_fixture(name))
|
|
48
39
|
end
|
|
49
40
|
|
|
50
|
-
block
|
|
51
|
-
|
|
41
|
+
# Provides a block mechanism for iterating across the files in your fixture
|
|
42
|
+
# area.
|
|
43
|
+
def my_fixtures(glob = '*', flags = 0, &block)
|
|
44
|
+
files = Dir.glob(File.join(my_fixture_dir, glob), flags)
|
|
45
|
+
raise "fixture '#{glob}' for #{my_fixture_dir} had no files!" if files.empty?
|
|
46
|
+
|
|
47
|
+
block && files.each(&block)
|
|
48
|
+
files
|
|
49
|
+
end
|
|
52
50
|
end
|
|
53
51
|
end
|
|
@@ -4,41 +4,43 @@
|
|
|
4
4
|
# 'puppetlabs_spec_helper/puppet_spec_helper' library
|
|
5
5
|
require 'puppetlabs_spec_helper/puppet_spec_helper'
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
#
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
7
|
+
module PuppetlabsSpec
|
|
8
|
+
# PuppetInternals provides a set of methods that interface
|
|
9
|
+
# with internal puppet implementations.
|
|
10
|
+
module PuppetInternals
|
|
11
|
+
def resource(parts = {})
|
|
12
|
+
resource_type = parts[:type] || :hostclass
|
|
13
|
+
resource_name = parts[:name] || 'testing'
|
|
14
|
+
Puppet::Resource::Type.new(resource_type, resource_name)
|
|
15
|
+
end
|
|
16
|
+
module_function :resource
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
def compiler(parts = {})
|
|
19
|
+
compiler_node = parts[:node] || node
|
|
20
|
+
Puppet::Parser::Compiler.new(compiler_node)
|
|
21
|
+
end
|
|
22
|
+
module_function :compiler
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
def node(parts = {})
|
|
25
|
+
node_name = parts[:name] || 'testinghost'
|
|
26
|
+
options = parts[:options] || {}
|
|
27
|
+
node_environment = Puppet::Node::Environment.create(parts[:environment] || 'test', [])
|
|
28
|
+
options[:environment] = node_environment
|
|
29
|
+
Puppet::Node.new(node_name, options)
|
|
30
|
+
end
|
|
31
|
+
module_function :node
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
33
|
+
# Return a method instance for a given function. This is primarily useful
|
|
34
|
+
# for rspec-puppet
|
|
35
|
+
def function_method(name, parts = {})
|
|
36
|
+
scope = parts[:scope] || scope()
|
|
37
|
+
# Ensure the method instance is defined by side-effect of checking if it
|
|
38
|
+
# exists. This is a hack, but at least it's a hidden hack and not an
|
|
39
|
+
# exposed hack.
|
|
40
|
+
return nil unless Puppet::Parser::Functions.function(name)
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
scope.method("function_#{name}".to_sym)
|
|
43
|
+
end
|
|
44
|
+
module_function :function_method
|
|
42
45
|
end
|
|
43
|
-
module_function :function_method
|
|
44
46
|
end
|
|
@@ -112,7 +112,7 @@ task :parallel_spec_standalone do |_t, args|
|
|
|
112
112
|
else
|
|
113
113
|
|
|
114
114
|
args = ['-t', 'rspec']
|
|
115
|
-
args.push('--').concat(ENV['CI_SPEC_OPTIONS'].strip.split
|
|
115
|
+
args.push('--').concat(ENV['CI_SPEC_OPTIONS'].strip.split).push('--') unless ENV['CI_SPEC_OPTIONS'].nil? || ENV['CI_SPEC_OPTIONS'].strip.empty?
|
|
116
116
|
args.concat(Rake::FileList[pattern].to_a)
|
|
117
117
|
|
|
118
118
|
ParallelTests::CLI.new.run(args)
|
|
@@ -165,14 +165,14 @@ PuppetLint.configuration.ignore_paths << 'spec/**/*.pp'
|
|
|
165
165
|
PuppetLint.configuration.ignore_paths << 'tests/**/*.pp'
|
|
166
166
|
PuppetLint.configuration.ignore_paths << 'types/**/*.pp'
|
|
167
167
|
PuppetLint.configuration.ignore_paths << 'vendor/**/*.pp'
|
|
168
|
-
puppet_lint_disable_checks = [
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
168
|
+
puppet_lint_disable_checks = %w[
|
|
169
|
+
80chars
|
|
170
|
+
140chars
|
|
171
|
+
class_inherits_from_params_class
|
|
172
|
+
class_parameter_defaults
|
|
173
|
+
disable_autoloader_layout
|
|
174
|
+
documentation
|
|
175
|
+
single_quote_string_with_variables
|
|
176
176
|
]
|
|
177
177
|
|
|
178
178
|
puppet_lint_disable_checks.each do |check|
|
|
@@ -227,7 +227,7 @@ task :compute_dev_version do
|
|
|
227
227
|
version = modinfo['version']
|
|
228
228
|
elsif File.exist?('Modulefile')
|
|
229
229
|
modfile = File.read('Modulefile')
|
|
230
|
-
version = modfile.match(
|
|
230
|
+
version = modfile.match(/\nversion +['"](.*)['"]/)[1]
|
|
231
231
|
else
|
|
232
232
|
raise 'Could not find a metadata.json or Modulefile! Cannot compute dev version without one or the other!'
|
|
233
233
|
end
|
|
@@ -239,11 +239,11 @@ task :compute_dev_version do
|
|
|
239
239
|
# If the branch is a release branch we append an 'r' into the new_version,
|
|
240
240
|
# this is due to the release branch buildID conflicting with main branch when trying to push to the staging forge.
|
|
241
241
|
# More info can be found at https://tickets.puppetlabs.com/browse/FM-6170
|
|
242
|
-
new_version = if (build = ENV
|
|
242
|
+
new_version = if (build = ENV.fetch('BUILD_NUMBER', nil))
|
|
243
243
|
if branch.eql? 'release'
|
|
244
|
-
'%s-%s%04d-%s'
|
|
244
|
+
format('%s-%s%04d-%s', version, 'r', build, sha) # legacy support code
|
|
245
245
|
else
|
|
246
|
-
'%s-%04d-%s'
|
|
246
|
+
format('%s-%04d-%s', version, build, sha) # legacy support code
|
|
247
247
|
end
|
|
248
248
|
else
|
|
249
249
|
"#{version}-#{sha}"
|
|
@@ -321,9 +321,7 @@ begin
|
|
|
321
321
|
# Use Rubocop's Github Actions formatter if possible
|
|
322
322
|
if ENV['GITHUB_ACTIONS'] == 'true'
|
|
323
323
|
rubocop_spec = Gem::Specification.find_by_name('rubocop')
|
|
324
|
-
if Gem::Version.new(rubocop_spec.version) >= Gem::Version.new('1.2')
|
|
325
|
-
task.formatters << 'github'
|
|
326
|
-
end
|
|
324
|
+
task.formatters << 'github' if Gem::Version.new(rubocop_spec.version) >= Gem::Version.new('1.2')
|
|
327
325
|
end
|
|
328
326
|
end
|
|
329
327
|
rescue LoadError
|
|
@@ -365,9 +363,7 @@ def create_gch_task(changelog_user = nil, changelog_project = nil, changelog_sin
|
|
|
365
363
|
# rubocop:enable Lint/NestedMethodDefinition
|
|
366
364
|
|
|
367
365
|
GitHubChangelogGenerator::RakeTask.new :changelog do |config|
|
|
368
|
-
if ENV['CHANGELOG_GITHUB_TOKEN'].nil?
|
|
369
|
-
raise "Set CHANGELOG_GITHUB_TOKEN environment variable eg 'export CHANGELOG_GITHUB_TOKEN=valid_token_here'"
|
|
370
|
-
end
|
|
366
|
+
raise "Set CHANGELOG_GITHUB_TOKEN environment variable eg 'export CHANGELOG_GITHUB_TOKEN=valid_token_here'" if ENV['CHANGELOG_GITHUB_TOKEN'].nil?
|
|
371
367
|
|
|
372
368
|
config.user = changelog_user || changelog_user_from_metadata
|
|
373
369
|
config.project = changelog_project || changelog_project_from_metadata
|
|
@@ -383,16 +379,16 @@ def create_gch_task(changelog_user = nil, changelog_project = nil, changelog_sin
|
|
|
383
379
|
config.configure_sections = {
|
|
384
380
|
'Changed' => {
|
|
385
381
|
'prefix' => '### Changed',
|
|
386
|
-
'labels' => ['backwards-incompatible']
|
|
382
|
+
'labels' => ['backwards-incompatible']
|
|
387
383
|
},
|
|
388
384
|
'Added' => {
|
|
389
385
|
'prefix' => '### Added',
|
|
390
|
-
'labels' => [
|
|
386
|
+
'labels' => %w[feature enhancement]
|
|
391
387
|
},
|
|
392
388
|
'Fixed' => {
|
|
393
389
|
'prefix' => '### Fixed',
|
|
394
|
-
'labels' => ['bugfix']
|
|
395
|
-
}
|
|
390
|
+
'labels' => ['bugfix']
|
|
391
|
+
}
|
|
396
392
|
}
|
|
397
393
|
end
|
|
398
394
|
else
|
|
@@ -2,48 +2,52 @@
|
|
|
2
2
|
|
|
3
3
|
require 'pathspec'
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
5
|
+
module PuppetlabsSpecHelper
|
|
6
|
+
module Tasks
|
|
7
|
+
# Helpers for validating symlinks.
|
|
8
|
+
class CheckSymlinks
|
|
9
|
+
DEFAULT_IGNORED = [
|
|
10
|
+
'/.git/',
|
|
11
|
+
'/.bundle/',
|
|
12
|
+
'/vendor/'
|
|
13
|
+
].freeze
|
|
14
|
+
|
|
15
|
+
IGNORE_LIST_FILES = [
|
|
16
|
+
'.pdkignore',
|
|
17
|
+
'.gitignore'
|
|
18
|
+
].freeze
|
|
19
|
+
|
|
20
|
+
def check(dir = Dir.pwd)
|
|
21
|
+
dir = Pathname.new(dir) unless dir.is_a?(Pathname)
|
|
22
|
+
results = []
|
|
23
|
+
|
|
24
|
+
dir.each_child(true) do |child|
|
|
25
|
+
next if ignored?(child.to_s)
|
|
26
|
+
|
|
27
|
+
if child.symlink?
|
|
28
|
+
results << child
|
|
29
|
+
elsif child.directory? && child.basename.to_s !~ /^(\.git|\.?bundle)$/
|
|
30
|
+
results.concat(check(child))
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
results
|
|
29
35
|
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
results
|
|
33
|
-
end
|
|
34
36
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
def ignored?(path)
|
|
38
|
+
path = "#{path}/" if File.directory?(path)
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
!ignore_pathspec.match_paths([path], Dir.pwd).empty?
|
|
41
|
+
end
|
|
40
42
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
def ignore_pathspec
|
|
44
|
+
@ignore_pathspec ||= PathSpec.new(DEFAULT_IGNORED).tap do |pathspec|
|
|
45
|
+
IGNORE_LIST_FILES.each do |f|
|
|
46
|
+
next unless File.file?(f) && File.readable?(f)
|
|
45
47
|
|
|
46
|
-
|
|
48
|
+
File.open(f, 'r') { |fd| pathspec.add(fd) }
|
|
49
|
+
end
|
|
50
|
+
end
|
|
47
51
|
end
|
|
48
52
|
end
|
|
49
53
|
end
|