rspec-puppet 2.7.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,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: fe98cc153715d0f4a7ea74302e22db11b27f256b
4
- data.tar.gz: 0ff2d613a201b5b50779674bc126904555203c66
2
+ SHA256:
3
+ metadata.gz: 420f47c99ab3190a3e97c2b172e694694a5d997a56e70366bd168c8338c21fb9
4
+ data.tar.gz: 21f2d247e5169ba70e490d6b9c66fc8542a1c3c1cd99d1e5895a1322a9cfac1b
5
5
  SHA512:
6
- metadata.gz: 24db31229795fcfd326243a0b2fc20a17c78b6ee772f28092f9afd917534a3dd307d688c3934ef590c857027944c6fc9432baea652c7c4ecfbd40e563eb89dd1
7
- data.tar.gz: 50fa9b5882460e10e4148c4b78372b3f366178738fe5fa92dfee522e8b4811a5378156623e0f6d13e030c912f9a5560d6f4051e0cd7aa7a249c59600a55fe20f
6
+ metadata.gz: a5b2ef185120131a07fc6e063a7ee2d2cb191db8a765bb5cdda1fce92081547c4d0aea83b386faaf1d20e8051d51d84ba05facc5f9deb74f3aecdeea67798b86
7
+ data.tar.gz: 4714dac2b13e5a4eb44a8c965a61e08cc7e2ded172271ea61f85bfae22d43f51dde5d609f0a1d3515844fb5924b48ad8441fbb071eef267c0af6f886c0e21c9c
data/CHANGELOG.md CHANGED
@@ -2,6 +2,113 @@
2
2
  All notable changes to this project will be documented in this file. This
3
3
  project adheres to [Semantic Versioning](http://semver.org/).
4
4
 
5
+ ## [2.9.0]
6
+
7
+ ### Added
8
+ * Allow users to disable app_management for Puppet 4
9
+ * Added support for regexp arguments to Sensitive
10
+ * Handle all auto*, not just autorequire
11
+ * Set up loaders so that 4.x functions resolve properly
12
+
13
+ ## [2.8.0]
14
+
15
+ ### Breaking Changes
16
+ * As of the 2.8.0 release, the `rspec-puppet` project no longer guarantees compatibility
17
+ with Puppet 2.x or 3.x (running under Ruby 1.8.7) or Puppet 4.x (running under Ruby 1.9.3).
18
+ * This release adds support for the [`Sensitive`](https://puppet.com/docs/puppet/latest/lang_data_sensitive.html)
19
+ data type, however existing tests that were expecting `String` content may need to be updated
20
+ to wrap the expected value in the new `sensitive` helper:
21
+
22
+ ```ruby
23
+ # Old
24
+ it { is_expected.to contain_file('/etc/mysecret.conf').with_content("top secret\n") }
25
+
26
+ # New
27
+ it { is_expected.to contain_file('/etc/mysecret.conf').with_content(sensitive("top secret\n")) }
28
+ ```
29
+
30
+ ### Added
31
+ * Added support for [trusted external fact data](https://github.com/rodjek/rspec-puppet#specifying-trusted-external-data).
32
+ * Added the ability to exclude resources from the coverage report calculations using a regular expression.
33
+ (See [documentation](https://rspec-puppet.com/documentation/coverage/#excluded-resources) for an example.
34
+ * Added `have_unique_values_for_all` matcher to assert a specific resource parameter value is unique across
35
+ the entire catalogue.
36
+ (See [documentation](https://rspec-puppet.com/documentation/classes/#test-resource-parameter-values-for-uniqueness).)
37
+ * Added ability to customize module-layer Hiera configuration via new settings. See
38
+ [documentation](https://rspec-puppet.com/documentation/configuration/#disable_module_hiera) for details.
39
+
40
+ ### Changed
41
+ * `RSpec::Puppet::Cache` now evicts least recently used entries when it reaches max size.
42
+ * `rspec-puppet`'s implementation of `match_manifests` will no longer look in `init.pp` for class
43
+ declarations if a manifest file exactly matching the class name exists.
44
+
45
+ ### Fixed
46
+ * Resolved compatibility issues with Ruby 2.7.x and added Ruby 2.7.x to the test matrix.
47
+ * Resolved issues calculating coverage and reporting results when there are 0 tested resources.
48
+ * Resolved compatibility issue with `rspec-expectations` 3.10.0.
49
+
50
+ ## [2.7.10]
51
+
52
+ ### Fixed
53
+ * Fix issues with removal of `default_env` method in Puppet 6.17.0.
54
+
55
+ ## [2.7.9]
56
+
57
+ This release had unintended breaking changes and was withdrawn.
58
+
59
+ ## [2.7.8]
60
+
61
+ ### Fixed
62
+ * Fix cross-platform testing for Puppet >= 6.9.0 when there is no `ipaddress6`
63
+ fact defined.
64
+
65
+ ## [2.7.7]
66
+
67
+ ### Fixed
68
+ * Fix the support for rspec-expectations >= 3.8.5.
69
+
70
+ ### Changed
71
+ * Remove the rspec-expectations dependency limit introduced in 2.7.6.
72
+
73
+ ## [2.7.6]
74
+
75
+ ### Changed
76
+ * Limit rspec-expectations dependency to < 3.8.5 due to an incompatible
77
+ change.
78
+
79
+ ## [2.7.5]
80
+
81
+ ### Fixed
82
+ * Minor refactor to prevent the fix introduced in 2.7.4 from raising
83
+ a deprecation warning on latest RSpec.
84
+
85
+ ## [2.7.4]
86
+
87
+ ### Fixed
88
+ * Fix the resource coverage test so that rspec will exit non-zero if the
89
+ desired coverage is not met.
90
+
91
+ ## [2.7.3]
92
+
93
+ ### Fixed
94
+ * Puppet 6 deferred functions are now evaluated and resolved as part of the
95
+ catalogue compilation process.
96
+ * If running with parallel\_tests, the resources that are filtered out of the
97
+ resource coverage report are now taken into account when merging the final
98
+ report, fixing false negative results that can occur.
99
+
100
+ ## [2.7.2]
101
+
102
+ ### Changed
103
+ * Reverted the change introduced in 2.7.0 that reencoded resource parameter
104
+ values to modify their line endings.
105
+
106
+ ## [2.7.1]
107
+
108
+ ### Fixed
109
+ * Fixed a bug that prevented the platform pretending/stubbing logic from being
110
+ temporarily disabled when loading Ruby code.
111
+
5
112
  ## [2.7.0]
6
113
 
7
114
  ### Changed
@@ -447,7 +554,36 @@ Thanks to Adrien Thebo, Alex Harvey, Brian, Dan Bode, Dominic Cleal, Javier Pala
447
554
  ## 1.0.1 and earlier
448
555
  For changelog of versions 1.0.1 and earlier, see http://rspec-puppet.com/changelog/
449
556
 
450
- [2.x]: https://github.com/rodjek/rspec-puppet/compare/v2.5.0...master
557
+ [2.x]: https://github.com/rodjek/rspec-puppet/compare/v2.9.0...master
558
+ [2.9.0]: https://github.com/rodjek/rspec-puppet/compare/v2.8.0...v2.9.0
559
+ [2.8.0]: https://github.com/rodjek/rspec-puppet/compare/v2.7.10...v2.8.0
560
+ [2.7.10]: https://github.com/rodjek/rspec-puppet/compare/v2.7.9...v2.7.10
561
+ [2.7.9]: https://github.com/rodjek/rspec-puppet/compare/v2.7.8...v2.7.9
562
+ [2.7.8]: https://github.com/rodjek/rspec-puppet/compare/v2.7.7...v2.7.8
563
+ [2.7.7]: https://github.com/rodjek/rspec-puppet/compare/v2.7.6...v2.7.7
564
+ [2.7.6]: https://github.com/rodjek/rspec-puppet/compare/v2.7.5...v2.7.6
565
+ [2.7.5]: https://github.com/rodjek/rspec-puppet/compare/v2.7.4...v2.7.5
566
+ [2.7.4]: https://github.com/rodjek/rspec-puppet/compare/v2.7.3...v2.7.4
567
+ [2.7.3]: https://github.com/rodjek/rspec-puppet/compare/v2.7.2...v2.7.3
568
+ [2.7.2]: https://github.com/rodjek/rspec-puppet/compare/v2.7.1...v2.7.2
569
+ [2.7.1]: https://github.com/rodjek/rspec-puppet/compare/v2.7.0...v2.7.1
570
+ [2.7.0]: https://github.com/rodjek/rspec-puppet/compare/v2.6.15...v2.7.0
571
+ [2.6.15]: https://github.com/rodjek/rspec-puppet/compare/v2.6.14...v2.6.15
572
+ [2.6.14]: https://github.com/rodjek/rspec-puppet/compare/v2.6.13...v2.6.14
573
+ [2.6.13]: https://github.com/rodjek/rspec-puppet/compare/v2.6.12...v2.6.13
574
+ [2.6.12]: https://github.com/rodjek/rspec-puppet/compare/v2.6.11...v2.6.12
575
+ [2.6.11]: https://github.com/rodjek/rspec-puppet/compare/v2.6.10...v2.6.11
576
+ [2.6.10]: https://github.com/rodjek/rspec-puppet/compare/v2.6.9...v2.6.10
577
+ [2.6.9]: https://github.com/rodjek/rspec-puppet/compare/v2.6.8...v2.6.9
578
+ [2.6.8]: https://github.com/rodjek/rspec-puppet/compare/v2.6.7...v2.6.8
579
+ [2.6.7]: https://github.com/rodjek/rspec-puppet/compare/v2.6.6...v2.6.7
580
+ [2.6.6]: https://github.com/rodjek/rspec-puppet/compare/v2.6.5...v2.6.6
581
+ [2.6.5]: https://github.com/rodjek/rspec-puppet/compare/v2.6.4...v2.6.5
582
+ [2.6.4]: https://github.com/rodjek/rspec-puppet/compare/v2.6.3...v2.6.4
583
+ [2.6.3]: https://github.com/rodjek/rspec-puppet/compare/v2.6.2...v2.6.3
584
+ [2.6.2]: https://github.com/rodjek/rspec-puppet/compare/v2.6.1...v2.6.2
585
+ [2.6.1]: https://github.com/rodjek/rspec-puppet/compare/v2.6.0...v2.6.1
586
+ [2.6.0]: https://github.com/rodjek/rspec-puppet/compare/2.5.0...v2.6.0
451
587
  [2.5.0]: https://github.com/rodjek/rspec-puppet/compare/v2.4.0...v2.5.0
452
588
  [2.4.0]: https://github.com/rodjek/rspec-puppet/compare/v2.3.2...v2.4.0
453
589
  [2.3.2]: https://github.com/rodjek/rspec-puppet/compare/v2.3.1...v2.3.2
data/README.md CHANGED
@@ -2,6 +2,20 @@
2
2
  [![Build Status](https://travis-ci.org/rodjek/rspec-puppet.svg?branch=master)](https://travis-ci.org/rodjek/rspec-puppet)
3
3
  [![Coverage Status](https://coveralls.io/repos/rodjek/rspec-puppet/badge.svg?branch=master)](https://coveralls.io/r/rodjek/rspec-puppet?branch=master)
4
4
 
5
+ #### Table of Contents
6
+
7
+ * [Installation](#installation)
8
+ * [Starting out with a new module](#starting-out-with-a-new-module)
9
+ * [Configure manifests for Puppet 4](#configure-manifests-for-puppet-4)
10
+ * [Configuration](#configuration)
11
+ * [Naming conventions](#naming-conventions)
12
+ * [Example groups](#example-groups)
13
+ * [Defined Types, Classes & Applications](#defined-types-classes--applications)
14
+ * [Functions](#functions)
15
+ * [Hiera integration](#hiera-integration)
16
+ * [Producing coverage reports](#producing-coverage-reports)
17
+ * [Related projects](#related-projects)
18
+
5
19
  ## Installation
6
20
 
7
21
  gem install rspec-puppet
@@ -759,6 +773,30 @@ RSpec.configure do |c|
759
773
  end
760
774
  ```
761
775
 
776
+ #### Specifying trusted external data
777
+
778
+ When testing with Puppet >= 6.14, the trusted facts hash will have an additional `external`
779
+ key for trusted external data.
780
+
781
+ By default, the test environment contains no trusted external data (as usually obtained from
782
+ trusted external commands and found in the `external` key). If you need to test against specific
783
+ trusted external data you can set those with a hash. The hash will then be available in
784
+ `$trusted['external']`
785
+
786
+ ```ruby
787
+ let(:trusted_external_data) { {'foo' => 'bar'} }
788
+ ```
789
+
790
+ You can also create a set of default trusted external data provided to all specs in your spec_helper:
791
+
792
+ ```ruby
793
+ RSpec.configure do |c|
794
+ c.default_trusted_external_data = {
795
+ 'foo' => 'bar'
796
+ }
797
+ end
798
+ ```
799
+
762
800
  #### Testing Exported Resources
763
801
 
764
802
  You can test if a resource was exported from the catalogue by using the
@@ -829,7 +867,7 @@ Puppet functions.
829
867
 
830
868
  ```ruby
831
869
  it 'should be able to do something' do
832
- subject.call(['foo']) == 'bar'
870
+ subject.execute('foo') == 'bar'
833
871
  end
834
872
  ```
835
873
 
@@ -869,11 +907,11 @@ either the `with_params` chain method in the `run` matcher
869
907
  it { is_expected.to run.with_params('foo', 'bar', ['baz']) }
870
908
  ```
871
909
 
872
- Or by using the `call` method on the subject directly
910
+ Or by using the `execute` method on the subject directly
873
911
 
874
912
  ```ruby
875
913
  it 'something' do
876
- subject.call(['foo', 'bar', ['baz']])
914
+ subject.execute('foo', 'bar', ['baz'])
877
915
  end
878
916
  ```
879
917
 
@@ -900,8 +938,8 @@ Or by using any of the existing RSpec matchers on the subject directly
900
938
 
901
939
  ```ruby
902
940
  it 'something' do
903
- subject.call(['foo']) == 'bar'
904
- subject.call(['baz']).should be_an Array
941
+ subject.execute('foo') == 'bar'
942
+ subject.execute('baz').should be_an Array
905
943
  end
906
944
  ```
907
945
 
@@ -919,8 +957,8 @@ Or by using the existing `raises_error` RSpec matcher
919
957
 
920
958
  ```ruby
921
959
  it 'something' do
922
- expect { subject.call(['a', 'b']) }.should raise_error(Puppet::ParseError)
923
- expect { subject.call(['a']) }.should_not raise_error(Puppet::ParseError)
960
+ expect { subject.execute('a', 'b') }.should raise_error(Puppet::ParseError)
961
+ expect { subject.execute('a') }.should_not raise_error(Puppet::ParseError)
924
962
  end
925
963
  ```
926
964
 
@@ -139,7 +139,8 @@ module RSpec::Puppet
139
139
  Puppet.push_context(
140
140
  {
141
141
  :environments => loader,
142
- :current_environment => env
142
+ :current_environment => env,
143
+ :loaders => (Puppet::Pops::Loaders.new(env) if Gem::Version.new(Puppet.version) >= Gem::Version.new('6.0.0')),
143
144
  },
144
145
  "Setup rspec-puppet environments"
145
146
  )
@@ -199,6 +200,12 @@ module RSpec::Puppet
199
200
  [:vendormoduledir, :vendormoduledir],
200
201
  ])
201
202
  end
203
+
204
+ def catalog(node, _exported)
205
+ super.tap do |c|
206
+ Puppet::Pops::Evaluator::DeferredResolver.resolve_and_replace(node.facts, c)
207
+ end
208
+ end
202
209
  end
203
210
 
204
211
  class Adapter30 < Base
@@ -11,12 +11,17 @@ module RSpec::Puppet
11
11
  end
12
12
 
13
13
  def get(*args, &blk)
14
- # decouple the hash key from whatever the blk might do to it
15
14
  key = Marshal.load(Marshal.dump(args))
16
- if !@cache.has_key? key
17
- @cache[key] = (blk || @default_proc).call(*args)
18
- @lra << key
15
+ if @cache.has_key?(key)
16
+ # Cache hit
17
+ # move that entry last to make it "most recenty used"
18
+ @lra.insert(-1, @lra.delete_at(@lra.index(args)))
19
+ else
20
+ # Cache miss
21
+ # Ensure room by evicting least recently used if no space left
19
22
  expire!
23
+ @cache[args] = (blk || @default_proc).call(*args)
24
+ @lra << args
20
25
  end
21
26
 
22
27
  @cache[key]
@@ -25,8 +30,8 @@ module RSpec::Puppet
25
30
  private
26
31
 
27
32
  def expire!
28
- expired = @lra.slice!(0, @lra.size - MAX_ENTRIES)
29
- expired.each { |key| @cache.delete(key) } if expired
33
+ # delete one entry (the oldest) when there is no room in cache
34
+ @cache.delete(@lra.shift) if @cache.size == MAX_ENTRIES
30
35
  end
31
36
  end
32
37
  end
@@ -17,13 +17,25 @@ end
17
17
  module RSpec::Puppet
18
18
  class Coverage
19
19
 
20
- attr_accessor :filters
20
+ attr_accessor :filters, :filters_regex
21
21
 
22
22
  class << self
23
23
  extend Forwardable
24
- def_delegators(:instance, :add, :cover!, :report!,
25
- :filters, :add_filter, :add_from_catalog,
26
- :results)
24
+
25
+ delegated_methods = [
26
+ :instance,
27
+ :add,
28
+ :cover!,
29
+ :report!,
30
+ :filters,
31
+ :filters_regex,
32
+ :add_filter,
33
+ :add_filter_regex,
34
+ :add_from_catalog,
35
+ :results,
36
+ ]
37
+
38
+ def_delegators(*delegated_methods)
27
39
 
28
40
  attr_writer :instance
29
41
 
@@ -35,10 +47,17 @@ module RSpec::Puppet
35
47
  def initialize
36
48
  @collection = {}
37
49
  @filters = ['Stage[main]', 'Class[Settings]', 'Class[main]', 'Node[default]']
50
+ @filters_regex = []
38
51
  end
39
52
 
40
53
  def save_results
41
54
  slug = "#{Digest::MD5.hexdigest(Dir.pwd)}-#{Process.pid}"
55
+ File.open(File.join(Dir.tmpdir, "rspec-puppet-filter-#{slug}"), 'w+') do |f|
56
+ f.puts @filters.to_json
57
+ end
58
+ File.open(File.join(Dir.tmpdir, "rspec-puppet-filter_regex-#{slug}"), 'w+') do |f|
59
+ f.puts @filters_regex.to_json
60
+ end
42
61
  File.open(File.join(Dir.tmpdir, "rspec-puppet-coverage-#{slug}"), 'w+') do |f|
43
62
  f.puts @collection.to_json
44
63
  end
@@ -52,6 +71,21 @@ module RSpec::Puppet
52
71
  end
53
72
  end
54
73
 
74
+ def merge_filters
75
+ pattern = File.join(Dir.tmpdir, "rspec-puppet-filter-#{Digest::MD5.hexdigest(Dir.pwd)}-*")
76
+ regex_filter_pattern = File.join(Dir.tmpdir, "rspec-puppet-filter_regex-#{Digest::MD5.hexdigest(Dir.pwd)}-*")
77
+
78
+ Dir[pattern].each do |result_file|
79
+ load_filters(result_file)
80
+ FileUtils.rm(result_file)
81
+ end
82
+
83
+ Dir[regex_filter_pattern].each do |result_file|
84
+ load_filters_regex(result_file)
85
+ FileUtils.rm(result_file)
86
+ end
87
+ end
88
+
55
89
  def load_results(path)
56
90
  saved_results = JSON.parse(File.read(path))
57
91
  saved_results.each do |resource, data|
@@ -60,6 +94,23 @@ module RSpec::Puppet
60
94
  end
61
95
  end
62
96
 
97
+ def load_filters(path)
98
+ saved_filters = JSON.parse(File.read(path))
99
+ saved_filters.each do |resource|
100
+ @filters << resource
101
+ @collection.delete(resource) if @collection.key?(resource)
102
+ end
103
+ end
104
+
105
+ def load_filters_regex(path)
106
+ saved_regex_filters = JSON.parse(File.read(path))
107
+ saved_regex_filters.each do |pattern|
108
+ regex = Regexp.new(pattern)
109
+ @filters_regex << regex
110
+ @collection.delete_if { |resource, _| resource =~ regex }
111
+ end
112
+ end
113
+
63
114
  def add(resource)
64
115
  if !exists?(resource) && !filtered?(resource)
65
116
  @collection[resource.to_s] = ResourceWrapper.new(resource)
@@ -67,11 +118,8 @@ module RSpec::Puppet
67
118
  end
68
119
 
69
120
  def add_filter(type, title)
70
- def capitalize_name(name)
71
- name.split('::').map { |subtitle| subtitle.capitalize }.join('::')
72
- end
73
-
74
121
  type = capitalize_name(type)
122
+
75
123
  if type == 'Class'
76
124
  title = capitalize_name(title)
77
125
  end
@@ -79,6 +127,34 @@ module RSpec::Puppet
79
127
  @filters << "#{type}[#{title}]"
80
128
  end
81
129
 
130
+ def add_filter_regex(type, pattern)
131
+ raise ArgumentError.new('pattern argument must be a Regexp') unless pattern.is_a?(Regexp)
132
+
133
+ type = capitalize_name(type)
134
+
135
+ # avoid recompiling the regular expression during processing
136
+ src = pattern.source
137
+
138
+ # switch from anchors to wildcards since it is embedded into a larger pattern
139
+ src = if src.start_with?('\\A', '^')
140
+ src.gsub(/\A(?:\\A|\^)/, '')
141
+ else
142
+ # no anchor at the start
143
+ ".*#{src}"
144
+ end
145
+
146
+ # match an even number of backslashes before the anchor - this indicates that the anchor was not escaped
147
+ # note the necessity for the negative lookbehind `(?<!)` to assert that there is no backslash before this
148
+ src = if src.match(/(?<!\\)(\\\\)*(?:\\[zZ]|\$)\z/)
149
+ src.gsub(/(?:\\[zZ]|\$)\z/, '')
150
+ else
151
+ # no anchor at the end
152
+ "#{src}.*"
153
+ end
154
+
155
+ @filters_regex << /\A#{Regexp.escape(type)}\[#{src}\]\z/
156
+ end
157
+
82
158
  # add all resources from catalog declared in module test_module
83
159
  def add_from_catalog(catalog, test_module)
84
160
  coverable_resources = catalog.to_a.reject { |resource| !test_module.nil? && filter_resource?(resource, test_module) }
@@ -88,7 +164,10 @@ module RSpec::Puppet
88
164
  end
89
165
 
90
166
  def filtered?(resource)
91
- filters.include?(resource.to_s)
167
+ return true if filters.include?(resource.to_s)
168
+ return true if filters_regex.any? { |f| resource.to_s =~ f }
169
+
170
+ false
92
171
  end
93
172
 
94
173
  def cover!(resource)
@@ -117,13 +196,16 @@ module RSpec::Puppet
117
196
  end
118
197
 
119
198
  def run_report(coverage_desired = nil)
120
- merge_results if ENV['TEST_ENV_NUMBER']
199
+ if parallel_tests?
200
+ merge_filters
201
+ merge_results
202
+ end
121
203
 
122
204
  report = results
123
205
 
124
206
  coverage_test(coverage_desired, report)
125
207
 
126
- puts report[:text]
208
+ puts "\n\nCoverage Report:\n\n#{report[:text]}"
127
209
  end
128
210
 
129
211
  def coverage_test(coverage_desired, report)
@@ -137,6 +219,17 @@ module RSpec::Puppet
137
219
  end
138
220
  coverage_test.run(RSpec.configuration.reporter)
139
221
 
222
+ status = if coverage_results.execution_result.respond_to?(:status)
223
+ coverage_results.execution_result.status
224
+ else
225
+ coverage_results.execution_result[:status]
226
+ end
227
+
228
+ if status == :failed
229
+ RSpec.world.non_example_failure = true
230
+ RSpec.world.wants_to_quit = true
231
+ end
232
+
140
233
  # This is not available on RSpec 2.x
141
234
  if coverage_results.execution_result.respond_to?(:pending_message)
142
235
  coverage_results.execution_result.pending_message = report[:text]
@@ -154,7 +247,9 @@ module RSpec::Puppet
154
247
  report[:total] = @collection.size
155
248
  report[:touched] = @collection.count { |_, resource| resource.touched? }
156
249
  report[:untouched] = report[:total] - report[:touched]
157
- report[:coverage] = "%5.2f" % ((report[:touched].to_f / report[:total].to_f) * 100)
250
+
251
+ coverage = report[:total].to_f > 0 ? ((report[:touched].to_f / report[:total].to_f) * 100) : 100.0
252
+ report[:coverage] = "%5.2f" % coverage
158
253
 
159
254
  report[:resources] = Hash[*@collection.map do |name, wrapper|
160
255
  [name, wrapper.to_hash]
@@ -193,7 +288,7 @@ module RSpec::Puppet
193
288
  # @param test_module [String] The name of the module under test
194
289
  # @return [true, false]
195
290
  def filter_resource?(resource, test_module)
196
- if @filters.include?(resource.to_s)
291
+ if filtered?(resource)
197
292
  return true
198
293
  end
199
294
 
@@ -234,6 +329,10 @@ module RSpec::Puppet
234
329
  !find(resource).nil?
235
330
  end
236
331
 
332
+ def capitalize_name(name)
333
+ name.split('::').map { |subtitle| subtitle.capitalize }.join('::')
334
+ end
335
+
237
336
  class ResourceWrapper
238
337
  attr_reader :resource
239
338
 
@@ -34,6 +34,14 @@ module RSpec::Puppet
34
34
  def failure_message_when_negated
35
35
  "expected that the type alias would not " + description + " but it does"
36
36
  end
37
+
38
+ def supports_block_expectations
39
+ true
40
+ end
41
+
42
+ def supports_value_expectations
43
+ true
44
+ end
37
45
  end
38
46
 
39
47
  def allow_value(*values)
@@ -78,6 +78,14 @@ module RSpec::Puppet
78
78
  end
79
79
  end
80
80
 
81
+ def supports_block_expectations
82
+ true
83
+ end
84
+
85
+ def supports_value_expectations
86
+ true
87
+ end
88
+
81
89
  private
82
90
  def missing_dependencies?
83
91
  retval = false
@@ -7,13 +7,15 @@ module RSpec::Puppet
7
7
  'Stage[main]',
8
8
  ].freeze
9
9
 
10
+ attr_reader :resource_type
11
+
10
12
  def initialize(type, count, *method)
11
13
  if type.nil?
12
14
  @type = method[0].to_s.gsub(/^have_(.+)_resource_count$/, '\1')
13
15
  else
14
16
  @type = type
15
17
  end
16
- @referenced_type = referenced_type(@type)
18
+ @resource_type = referenced_type(@type)
17
19
  @expected_number = count.to_i
18
20
  end
19
21
 
@@ -30,7 +32,7 @@ module RSpec::Puppet
30
32
  end
31
33
  else
32
34
  resources.count do |res|
33
- res.type == @referenced_type
35
+ res.type == @resource_type
34
36
  end
35
37
  end
36
38
 
@@ -45,7 +47,7 @@ module RSpec::Puppet
45
47
  desc << "#{@expected_number == 1 ? "class" : "classes" }"
46
48
  else
47
49
  unless @type == "resource"
48
- desc << "#{@referenced_type}"
50
+ desc << "#{@resource_type}"
49
51
  end
50
52
  desc << "#{@expected_number == 1 ? "resource" : "resources" }"
51
53
  end
@@ -61,6 +63,14 @@ module RSpec::Puppet
61
63
  "expected that the catalogue would not " + description + " but it does"
62
64
  end
63
65
 
66
+ def supports_block_expectations
67
+ true
68
+ end
69
+
70
+ def supports_value_expectations
71
+ true
72
+ end
73
+
64
74
  private
65
75
 
66
76
  def referenced_type(type)
@@ -89,6 +89,11 @@ module RSpec::Puppet
89
89
  else
90
90
  RSpec::Puppet::Coverage.cover!(resource)
91
91
  rsrc_hsh = resource.to_hash
92
+ if resource.respond_to?(:sensitive_parameters)
93
+ resource.sensitive_parameters.each do |s_param|
94
+ rsrc_hsh[s_param] = ::Puppet::Pops::Types::PSensitiveType::Sensitive.new(rsrc_hsh[s_param])
95
+ end
96
+ end
92
97
 
93
98
  if resource.builtin_type?
94
99
  namevar = resource.resource_type.key_attributes.first.to_s
@@ -177,6 +182,14 @@ module RSpec::Puppet
177
182
  true
178
183
  end
179
184
 
185
+ def supports_block_expectations
186
+ true
187
+ end
188
+
189
+ def supports_value_expectations
190
+ true
191
+ end
192
+
180
193
  def expected
181
194
  @errors.map {|e| e.expected if e.respond_to?(:expected)}.compact.join("\n\n")
182
195
  end
@@ -294,14 +307,17 @@ module RSpec::Puppet
294
307
  end
295
308
  end
296
309
 
297
- # Add autorequires if any
298
- if type == :require and resource.resource_type.respond_to? :eachautorequire
299
- resource.resource_type.eachautorequire do |t, b|
300
- Array(resource.to_ral.instance_eval(&b)).each do |dep|
301
- res = "#{t.to_s.capitalize}[#{dep}]"
302
- if r = relationship_refs(res, type, visited)
303
- results << res
304
- results << r
310
+ # Add auto* (autorequire etc) if any
311
+ if [:before, :notify, :require, :subscribe].include?(type)
312
+ func = "eachauto#{type}".to_sym
313
+ if resource.resource_type.respond_to?(func)
314
+ resource.resource_type.send(func) do |t, b|
315
+ Array(resource.to_ral.instance_eval(&b)).each do |dep|
316
+ res = "#{t.to_s.capitalize}[#{dep}]"
317
+ if r = relationship_refs(res, type, visited)
318
+ results << res
319
+ results << r
320
+ end
305
321
  end
306
322
  end
307
323
  end
@@ -4,7 +4,7 @@ module RSpec::Puppet
4
4
 
5
5
  matcher :include_class do |expected_class|
6
6
  match do |catalogue|
7
- RSpec.deprecate(:include_class, :replacement => :contain_class)
7
+ RSpec.deprecate('include_class()', :replacement => 'contain_class()')
8
8
  catalogue.call.classes.include?(expected_class)
9
9
  end
10
10
 
@@ -22,6 +22,13 @@ module RSpec::Puppet
22
22
  end
23
23
  end
24
24
 
25
+ def supports_block_expectations
26
+ true
27
+ end
28
+
29
+ def supports_value_expectations
30
+ true
31
+ end
25
32
  end
26
33
 
27
34
  end
@@ -21,10 +21,7 @@ module RSpec::Puppet
21
21
  #
22
22
  # @return [true, false]
23
23
  def matches?(resource)
24
-
25
- @resource = resource
26
-
27
- actual = @resource[@parameter]
24
+ actual = resource[@parameter]
28
25
  expected = @value
29
26
 
30
27
  # Puppet flattens an array with a single value into just the value and
@@ -65,6 +62,8 @@ module RSpec::Puppet
65
62
  check_hash(expected, actual)
66
63
  when Array
67
64
  check_array(expected, actual)
65
+ when RSpec::Puppet::Sensitive
66
+ expected == actual
68
67
  else
69
68
  check_string(expected, actual)
70
69
  end
@@ -78,7 +77,7 @@ module RSpec::Puppet
78
77
  end
79
78
 
80
79
  def check_regexp(expected, actual)
81
- !!(munge_line_endings(actual.to_s).match expected) == @should_match
80
+ !!(actual.to_s.match expected) == @should_match
82
81
  end
83
82
 
84
83
  # Ensure that two hashes have the same number of keys, and that for each
@@ -119,17 +118,7 @@ module RSpec::Puppet
119
118
  end
120
119
 
121
120
  def check_string(expected, actual)
122
- (expected.to_s == munge_line_endings(actual.to_s)) == @should_match
123
- end
124
-
125
- def munge_line_endings(value)
126
- return value unless value.respond_to?(:encode)
127
-
128
- if Puppet::Util::Platform.windows?
129
- value.encode(:crlf_newline => true)
130
- else
131
- value.encode(:universal_newline => true)
132
- end
121
+ (expected.to_s == actual.to_s) == @should_match
133
122
  end
134
123
  end
135
124
  end
@@ -0,0 +1,23 @@
1
+ module RSpec::Puppet
2
+ module GenericMatchers
3
+ # Due to significant code base depending on the
4
+ #
5
+ # is_expected.to raise_error Puppet::Error
6
+ #
7
+ # syntax, and removal of this syntax from RSpec, extend RSpec's built-in
8
+ # `raise_error` matcher to accept a value target, e.g. a subject defined
9
+ # as a lambda, e.g.:
10
+ #
11
+ # subject(:catalogue) { lambda { load_catalogue } }
12
+ #
13
+ class RaiseError < RSpec::Matchers::BuiltIn::RaiseError
14
+ def supports_value_expectations?
15
+ true
16
+ end
17
+ end
18
+
19
+ def raise_error(error=defined?(RSpec::Matchers::BuiltIn::RaiseError::UndefinedValue) ? RSpec::Matchers::BuiltIn::RaiseError::UndefinedValue : nil, message=nil, &block)
20
+ RaiseError.new(error, message, &block)
21
+ end
22
+ end
23
+ end
@@ -104,6 +104,14 @@ module RSpec::Puppet
104
104
  end
105
105
  end
106
106
 
107
+ def supports_block_expectations
108
+ true
109
+ end
110
+
111
+ def supports_value_expectations
112
+ true
113
+ end
114
+
107
115
  private
108
116
  def func_name
109
117
  @func_obj.func_name
@@ -52,9 +52,6 @@ module RSpec::Puppet
52
52
  self
53
53
  end
54
54
 
55
- #def with_autorequires(autorequires))
56
- #end
57
-
58
55
  #
59
56
  # this is the method that drives all of the validation
60
57
  #
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSpec
4
+ module Puppet
5
+ module ManifestMatchers
6
+ extend RSpec::Matchers::DSL
7
+
8
+ matcher :have_unique_values_for_all do |type, attribute|
9
+ match do |catalogue|
10
+ catalogue.call.resources.select { |rsrc| rsrc.type == type.capitalize }
11
+ .group_by { |rsrc| rsrc[attribute.to_sym] }
12
+ .all? { |_, group| group.size == 1 }
13
+ end
14
+
15
+ description do
16
+ "have unique attribute values for #{type.capitalize}[#{attribute.to_sym}]"
17
+ end
18
+
19
+ if RSpec::Version::STRING < '3'
20
+ failure_message_for_should do |_actual|
21
+ "expected that the catalogue would have no duplicate values for #{type.capitalize}[#{attribute.to_sym}]"
22
+ end
23
+ else
24
+ failure_message do |_actual|
25
+ "expected that the catalogue would have no duplicate values for #{type.capitalize}[#{attribute.to_sym}]"
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -6,3 +6,5 @@ require 'rspec-puppet/matchers/count_generic'
6
6
  require 'rspec-puppet/matchers/dynamic_matchers'
7
7
  require 'rspec-puppet/matchers/type_matchers'
8
8
  require 'rspec-puppet/matchers/allow_value'
9
+ require 'rspec-puppet/matchers/raise_error'
10
+ require 'rspec-puppet/matchers/unique_values'
@@ -132,6 +132,16 @@ module Puppet
132
132
  end
133
133
 
134
134
  module Util
135
+ # Fix for removal of default_env function
136
+ # Bug: https://github.com/rodjek/rspec-puppet/issues/796
137
+ # Upstream: https://github.com/puppetlabs/puppet/commit/94df3c1a3992d89b2d7d5db8a70373c135bdd86b
138
+ if !respond_to?(:default_env)
139
+ def default_env()
140
+ DEFAULT_ENV
141
+ end
142
+ module_function :default_env
143
+ end
144
+
135
145
  if respond_to?(:get_env)
136
146
  alias :old_get_env :get_env
137
147
  module_function :old_get_env
@@ -213,7 +223,7 @@ module Puppet
213
223
  end
214
224
 
215
225
  class Autoload
216
- if singleton_class.respond_to?(:load_file)
226
+ if respond_to?(:load_file)
217
227
  singleton_class.send(:alias_method, :old_load_file, :load_file)
218
228
 
219
229
  def self.load_file(*args)
@@ -258,6 +268,40 @@ module Puppet
258
268
  end
259
269
  end
260
270
  end
271
+
272
+ if Puppet::Util::Package.versioncmp(Puppet.version, '4.9.0') >= 0
273
+ class Module
274
+ old_hiera_conf_file = instance_method(:hiera_conf_file)
275
+ define_method(:hiera_conf_file) do
276
+ if RSpec::Puppet.rspec_puppet_example?
277
+ if RSpec.configuration.disable_module_hiera
278
+ return nil
279
+ elsif RSpec.configuration.fixture_hiera_configs.key?(name)
280
+ config = RSpec.configuration.fixture_hiera_configs[name]
281
+ config = File.absolute_path(config, path) unless config.nil?
282
+ return config
283
+ elsif RSpec.configuration.use_fixture_spec_hiera
284
+ config = RSpec::Puppet.current_example.fixture_spec_hiera_conf(self)
285
+ return config unless config.nil? && RSpec.configuration.fallback_to_default_hiera
286
+ end
287
+ end
288
+ old_hiera_conf_file.bind(self).call
289
+ end
290
+ end
291
+
292
+ class Pops::Lookup::ModuleDataProvider
293
+ old_configuration_path = instance_method(:configuration_path)
294
+ define_method(:configuration_path) do |lookup_invocation|
295
+ if RSpec::Puppet.rspec_puppet_example?
296
+ env = lookup_invocation.scope.environment
297
+ mod = env.module(module_name)
298
+ raise Puppet::DataBinding::LookupError, _("Environment '%{env}', cannot find module '%{module_name}'") % { :env => env.name, :module_name => module_name } unless mod
299
+ return Pathname.new(mod.hiera_conf_file)
300
+ end
301
+ old_configuration_path.bind(self).call(lookup_invocation)
302
+ end
303
+ end
304
+ end
261
305
  end
262
306
 
263
307
  class Pathname
@@ -292,6 +336,24 @@ class Pathname
292
336
  end
293
337
  end
294
338
 
339
+ # Puppet loads init.pp, then foo.pp, to find class "mod::foo". If
340
+ # class "mod" has been mocked using pre_condition when testing
341
+ # "mod::foo", this causes duplicate declaration for "mod".
342
+ # This monkey patch only loads "init.pp" if "foo.pp" does not exist.
343
+ class Puppet::Module
344
+ if [:match_manifests, 'match_manifests'].any? { |r| instance_methods.include?(r) }
345
+ old_match_manifests = instance_method(:match_manifests)
346
+
347
+ define_method(:match_manifests) do |rest|
348
+ result = old_match_manifests.bind(self).call(rest)
349
+ if result.length > 1 && File.basename(result[0]) == 'init.pp'
350
+ result.shift
351
+ end
352
+ result
353
+ end
354
+ end
355
+ end
356
+
295
357
  # Prevent the File type from munging paths (which uses File.expand_path to
296
358
  # normalise paths, which does very bad things to *nix paths on Windows.
297
359
  file_path_munge = Puppet::Type.type(:file).paramclass(:path).instance_method(:unsafe_munge)
@@ -0,0 +1,51 @@
1
+ module RSpec::Puppet
2
+ if defined?(::Puppet::Pops::Types::PSensitiveType::Sensitive)
3
+ # A wrapper representing Sensitive data type, eg. in class params.
4
+ class Sensitive < ::Puppet::Pops::Types::PSensitiveType::Sensitive
5
+ # Create a new Sensitive object
6
+ # @param [Object] value to wrap
7
+ def initialize(value)
8
+ @value = value
9
+ end
10
+
11
+ # @return the wrapped value
12
+ def unwrap
13
+ @value
14
+ end
15
+
16
+ # @return true
17
+ def sensitive?
18
+ true
19
+ end
20
+
21
+ # @return inspect of the wrapped value, inside Sensitive()
22
+ def inspect
23
+ "Sensitive(#{@value.inspect})"
24
+ end
25
+
26
+ # Check for equality with another value.
27
+ # If compared to Puppet Sensitive type, it compares the wrapped values.
28
+
29
+ # @param other [#unwrap, Object] value to compare to
30
+ def == other
31
+ if other.respond_to? :unwrap
32
+ if unwrap.kind_of?(Regexp)
33
+ return unwrap =~ other.unwrap
34
+ else
35
+ return unwrap == other.unwrap
36
+ end
37
+ else
38
+ super
39
+ end
40
+ end
41
+ end
42
+ else
43
+ #:nocov:
44
+ class Sensitive
45
+ def initialize(value)
46
+ raise 'The use of the Sensitive data type is not supported by this Puppet version'
47
+ end
48
+ end
49
+ #:nocov:
50
+ end
51
+ end
@@ -1,10 +1,14 @@
1
1
  require 'rspec-puppet/cache'
2
2
  require 'rspec-puppet/adapters'
3
3
  require 'rspec-puppet/raw_string'
4
+ require 'rspec-puppet/sensitive'
4
5
 
5
6
  module RSpec::Puppet
6
7
  module Support
8
+ include GenericMatchers
9
+
7
10
  @@cache = RSpec::Puppet::Cache.new
11
+ @@fixture_hiera_configs = Hash.new { |h, k| h[k] = nil }
8
12
 
9
13
  def subject
10
14
  lambda { catalogue }
@@ -84,10 +88,29 @@ module RSpec::Puppet
84
88
  hiera_config_value = self.respond_to?(:hiera_config) ? hiera_config : nil
85
89
  hiera_data_value = self.respond_to?(:hiera_data) ? hiera_data : nil
86
90
 
91
+ rspec_config_values = [
92
+ :trusted_server_facts,
93
+ :disable_module_hiera,
94
+ :use_fixture_spec_hiera,
95
+ :fixture_hiera_configs,
96
+ :fallback_to_default_hiera,
97
+ ].map { |setting| RSpec.configuration.send(setting) }
98
+
87
99
  build_facts = facts_hash(node_name)
88
- catalogue = build_catalog(node_name, build_facts, trusted_facts_hash(node_name), hiera_config_value,
89
- build_code(type, manifest_opts), exported, node_params_hash, hiera_data_value,
90
- RSpec.configuration.trusted_server_facts)
100
+ catalogue = build_catalog(
101
+ nodename: node_name,
102
+ facts_val: build_facts,
103
+ trusted_facts_val: trusted_facts_hash(node_name),
104
+ hiera_config_val: hiera_config_value,
105
+ code: build_code(type, manifest_opts),
106
+ exported: exported,
107
+ node_params: node_params_hash,
108
+ trusted_external_data: trusted_external_data_hash,
109
+ ignored_cache_params: {
110
+ hiera_data_value: hiera_data_value,
111
+ rspec_config_values: rspec_config_values,
112
+ }
113
+ )
91
114
 
92
115
  test_module = type == :host ? nil : class_name.split('::').first
93
116
  if type == :define
@@ -129,13 +152,18 @@ module RSpec::Puppet
129
152
  end
130
153
 
131
154
  def site_pp_str
132
- site_pp_str = ''
133
- filepath = adapter.manifest
134
-
135
- if (!filepath.nil?) && File.file?(filepath)
136
- site_pp_str = File.open(filepath).read
155
+ return '' unless (path = adapter.manifest)
156
+
157
+ if File.file?(path)
158
+ File.read(path)
159
+ elsif File.directory?(path)
160
+ # Read and concatenate all .pp files.
161
+ Dir[File.join(path, '*.pp')].sort.map do |f|
162
+ File.read(f)
163
+ end.join("\n")
164
+ else
165
+ ''
137
166
  end
138
- site_pp_str
139
167
  end
140
168
 
141
169
  def test_manifest(type, opts = {})
@@ -219,10 +247,11 @@ module RSpec::Puppet
219
247
  }
220
248
 
221
249
  node_facts = {
222
- 'hostname' => node.split('.').first,
223
- 'fqdn' => node,
224
- 'domain' => node.split('.', 2).last,
225
- 'clientcert' => node,
250
+ 'hostname' => node.split('.').first,
251
+ 'fqdn' => node,
252
+ 'domain' => node.split('.', 2).last,
253
+ 'clientcert' => node,
254
+ 'ipaddress6' => 'FE80:0000:0000:0000:AAAA:AAAA:AAAA',
226
255
  }
227
256
 
228
257
  networking_facts = {
@@ -285,6 +314,19 @@ module RSpec::Puppet
285
314
  extensions
286
315
  end
287
316
 
317
+ def trusted_external_data_hash
318
+ return {} unless Puppet::Util::Package.versioncmp(Puppet.version, '6.14.0') >= 0
319
+
320
+ external_data = {}
321
+
322
+ if RSpec.configuration.default_trusted_external_data.any?
323
+ external_data.merge!(munge_facts(RSpec.configuration.default_trusted_external_data))
324
+ end
325
+
326
+ external_data.merge!(munge_facts(trusted_external_data)) if self.respond_to?(:trusted_external_data)
327
+ external_data
328
+ end
329
+
288
330
  def server_facts_hash
289
331
  server_facts = {}
290
332
 
@@ -350,7 +392,7 @@ module RSpec::Puppet
350
392
 
351
393
  # Enable app_management by default for Puppet versions that support it
352
394
  if Puppet::Util::Package.versioncmp(Puppet.version, '4.3.0') >= 0 && Puppet.version.to_i < 5
353
- Puppet[:app_management] = true
395
+ Puppet[:app_management] = ENV.include?('PUPPET_NOAPP_MANAGMENT') ? false : true
354
396
  end
355
397
 
356
398
  adapter.modulepath.map do |d|
@@ -372,6 +414,29 @@ module RSpec::Puppet
372
414
  end
373
415
 
374
416
  def build_catalog_without_cache(nodename, facts_val, trusted_facts_val, hiera_config_val, code, exported, node_params, *_)
417
+ build_catalog_without_cache_v2({
418
+ nodename: nodename,
419
+ facts_val: facts_val,
420
+ trusted_facts_val: trusted_facts_val,
421
+ hiera_config_val: hiera_config_val,
422
+ code: code,
423
+ exported: exported,
424
+ node_params: node_params,
425
+ trusted_external: {},
426
+ })
427
+ end
428
+
429
+ def build_catalog_without_cache_v2(
430
+ nodename: nil,
431
+ facts_val: nil,
432
+ trusted_facts_val: nil,
433
+ hiera_config_val: nil,
434
+ code: nil,
435
+ exported: nil,
436
+ node_params: nil,
437
+ trusted_external_data: nil,
438
+ ignored_cache_params: {}
439
+ )
375
440
 
376
441
  # If we're going to rebuild the catalog, we should clear the cached instance
377
442
  # of Hiera that Puppet is using. This opens the possibility of the catalog
@@ -393,10 +458,14 @@ module RSpec::Puppet
393
458
 
394
459
  node_obj = Puppet::Node.new(nodename, { :parameters => node_params, :facts => node_facts })
395
460
 
461
+ trusted_info = ['remote', nodename, trusted_facts_val]
462
+ if Puppet::Util::Package.versioncmp(Puppet.version, '6.14.0') >= 0
463
+ trusted_info.push(trusted_external_data)
464
+ end
396
465
  if Puppet::Util::Package.versioncmp(Puppet.version, '4.3.0') >= 0
397
466
  Puppet.push_context(
398
467
  {
399
- :trusted_information => Puppet::Context::TrustedInformation.new('remote', nodename, trusted_facts_val)
468
+ :trusted_information => Puppet::Context::TrustedInformation.new(*trusted_info)
400
469
  },
401
470
  "Context for spec trusted hash"
402
471
  )
@@ -415,7 +484,11 @@ module RSpec::Puppet
415
484
 
416
485
  def build_catalog(*args)
417
486
  @@cache.get(*args) do |*args|
418
- build_catalog_without_cache(*args)
487
+ if args.length == 1 && args.first.is_a?(Hash)
488
+ build_catalog_without_cache_v2(args.first)
489
+ else
490
+ build_catalog_without_cache(*args)
491
+ end
419
492
  end
420
493
  end
421
494
 
@@ -432,8 +505,7 @@ module RSpec::Puppet
432
505
  end
433
506
 
434
507
  def escape_special_chars(string)
435
- string.gsub!(/\$/, "\\$")
436
- string
508
+ string.gsub(/\$/, "\\$")
437
509
  end
438
510
 
439
511
  def rspec_compatibility
@@ -444,6 +516,23 @@ module RSpec::Puppet
444
516
  end
445
517
  end
446
518
 
519
+ def fixture_spec_hiera_conf(mod)
520
+ return @@fixture_hiera_configs[mod.name] if @@fixture_hiera_configs.key?(mod.name)
521
+
522
+ path = Pathname.new(mod.path)
523
+ if path.join('spec').exist?
524
+ path.join('spec').find do |file|
525
+ Find.prune if %w[modules work-dir].any? do |dir|
526
+ file.relative_path_from(path).to_s.start_with?("spec/fixtures/#{dir}")
527
+ end
528
+ if file.basename.to_s.eql?(Puppet::Pops::Lookup::HieraConfig::CONFIG_FILE_NAME)
529
+ return @@fixture_hiera_configs[mod.name] = file.to_s
530
+ end
531
+ end
532
+ end
533
+ @@fixture_hiera_configs[mod.name]
534
+ end
535
+
447
536
  # Helper to return a resource/node reference, so it gets translated in params to a raw string
448
537
  # without quotes.
449
538
  #
@@ -454,6 +543,14 @@ module RSpec::Puppet
454
543
  return RSpec::Puppet::RawString.new("#{type}['#{title}']")
455
544
  end
456
545
 
546
+ # Helper to return value wrapped in Sensitive type.
547
+ #
548
+ # @param [Object] value to wrap
549
+ # @return [RSpec::Puppet::Sensitive] a new Sensitive wrapper with the new value
550
+ def sensitive(value)
551
+ return RSpec::Puppet::Sensitive.new(value)
552
+ end
553
+
457
554
  # @!attribute [r] adapter
458
555
  # @api private
459
556
  # @return [Class < RSpec::Puppet::Adapters::Base]
data/lib/rspec-puppet.rb CHANGED
@@ -42,6 +42,7 @@ RSpec.configure do |c|
42
42
  c.add_setting :default_facts, :default => {}
43
43
  c.add_setting :default_node_params, :default => {}
44
44
  c.add_setting :default_trusted_facts, :default => {}
45
+ c.add_setting :default_trusted_external_data, :default => {}
45
46
  c.add_setting :hiera_config, :default => Puppet::Util::Platform.actually_windows? ? 'c:/nul/' : '/dev/null'
46
47
  c.add_setting :parser, :default => 'current'
47
48
  c.add_setting :trusted_node_data, :default => false
@@ -54,6 +55,10 @@ RSpec.configure do |c|
54
55
  c.add_setting :platform, :default => Puppet::Util::Platform.actual_platform
55
56
  c.add_setting :vendormoduledir, :default => Puppet::Util::Platform.actually_windows? ? 'c:/nul/' : '/dev/null'
56
57
  c.add_setting :basemodulepath, :default => Puppet::Util::Platform.actually_windows? ? 'c:/nul/' : '/dev/null'
58
+ c.add_setting :disable_module_hiera, :default => false
59
+ c.add_setting :fixture_hiera_configs, :default => {}
60
+ c.add_setting :use_fixture_spec_hiera, :default => false
61
+ c.add_setting :fallback_to_default_hiera, :default => true
57
62
 
58
63
  c.instance_eval do
59
64
  def trusted_server_facts
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-puppet
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.0
4
+ version: 2.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Sharpe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-02 00:00:00.000000000 Z
11
+ date: 2021-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -57,14 +57,17 @@ files:
57
57
  - lib/rspec-puppet/matchers/dynamic_matchers.rb
58
58
  - lib/rspec-puppet/matchers/include_class.rb
59
59
  - lib/rspec-puppet/matchers/parameter_matcher.rb
60
+ - lib/rspec-puppet/matchers/raise_error.rb
60
61
  - lib/rspec-puppet/matchers/run.rb
61
62
  - lib/rspec-puppet/matchers/type_matchers.rb
63
+ - lib/rspec-puppet/matchers/unique_values.rb
62
64
  - lib/rspec-puppet/monkey_patches.rb
63
65
  - lib/rspec-puppet/monkey_patches/win32/registry.rb
64
66
  - lib/rspec-puppet/monkey_patches/win32/taskscheduler.rb
65
67
  - lib/rspec-puppet/monkey_patches/windows/taskschedulerconstants.rb
66
68
  - lib/rspec-puppet/rake_task.rb
67
69
  - lib/rspec-puppet/raw_string.rb
70
+ - lib/rspec-puppet/sensitive.rb
68
71
  - lib/rspec-puppet/setup.rb
69
72
  - lib/rspec-puppet/spec_helper.rb
70
73
  - lib/rspec-puppet/support.rb
@@ -88,8 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
91
  - !ruby/object:Gem::Version
89
92
  version: '0'
90
93
  requirements: []
91
- rubyforge_project:
92
- rubygems_version: 2.6.14.1
94
+ rubygems_version: 3.2.5
93
95
  signing_key:
94
96
  specification_version: 4
95
97
  summary: RSpec tests for your Puppet manifests