rspec-puppet 2.7.10 → 2.11.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/CHANGELOG.md +97 -10
- data/README.md +52 -0
- data/lib/rspec-puppet/adapters.rb +61 -1
- data/lib/rspec-puppet/cache.rb +11 -6
- data/lib/rspec-puppet/coverage.rb +79 -13
- data/lib/rspec-puppet/facter_impl.rb +49 -0
- data/lib/rspec-puppet/matchers/count_generic.rb +5 -3
- data/lib/rspec-puppet/matchers/create_generic.rb +16 -8
- data/lib/rspec-puppet/matchers/include_class.rb +1 -1
- data/lib/rspec-puppet/matchers/parameter_matcher.rb +3 -4
- data/lib/rspec-puppet/matchers/raise_error.rb +2 -2
- data/lib/rspec-puppet/matchers/type_matchers.rb +0 -3
- data/lib/rspec-puppet/matchers/unique_values.rb +31 -0
- data/lib/rspec-puppet/matchers.rb +1 -0
- data/lib/rspec-puppet/monkey_patches.rb +52 -0
- data/lib/rspec-puppet/sensitive.rb +51 -0
- data/lib/rspec-puppet/support.rb +102 -13
- data/lib/rspec-puppet.rb +6 -0
- metadata +16 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7a8f890c54b412a4d326895c3c3cd0ecae65f915049c69b9cb75c0a5c2811365
|
4
|
+
data.tar.gz: 39407acdeb509d98797e23cdcb7e71c378d89186039538fba4cc25c6c1eb0bf1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1105e0778581b90855d2d43511b1016cd0193fb088c0b4fbe7bf8de4947e3043a6a005bf1894fed0ac9fbdf87b283b9075997f47c2530ba82038db9c23d43e2f
|
7
|
+
data.tar.gz: 719205730a4e0f4bd0b17378872e134de10eedf3e623f9584aaf85577665033ea36d393d5a3619a0b5eb9fd091530bc6071d394291d7d48094aad11d00836585
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,62 @@
|
|
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.11.0]
|
6
|
+
|
7
|
+
### Added
|
8
|
+
* Add setting to use custom Facter implementation ([GH-16](https://github.com/puppetlabs/rspec-puppet/pull/16))
|
9
|
+
|
10
|
+
## [2.10.0]
|
11
|
+
The release sees rspec-puppet move into the puppetlabs namespace
|
12
|
+
|
13
|
+
### Added
|
14
|
+
* Add ruby 3 support ([GH-11](https://github.com/puppetlabs/rspec-puppet/pull/11))
|
15
|
+
|
16
|
+
## [2.9.0]
|
17
|
+
|
18
|
+
### Added
|
19
|
+
* Allow users to disable app_management for Puppet 4
|
20
|
+
* Added support for regexp arguments to Sensitive
|
21
|
+
* Handle all auto*, not just autorequire
|
22
|
+
* Set up loaders so that 4.x functions resolve properly
|
23
|
+
|
24
|
+
## [2.8.0]
|
25
|
+
|
26
|
+
### Breaking Changes
|
27
|
+
* As of the 2.8.0 release, the `rspec-puppet` project no longer guarantees compatibility
|
28
|
+
with Puppet 2.x or 3.x (running under Ruby 1.8.7) or Puppet 4.x (running under Ruby 1.9.3).
|
29
|
+
* This release adds support for the [`Sensitive`](https://puppet.com/docs/puppet/latest/lang_data_sensitive.html)
|
30
|
+
data type, however existing tests that were expecting `String` content may need to be updated
|
31
|
+
to wrap the expected value in the new `sensitive` helper:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
# Old
|
35
|
+
it { is_expected.to contain_file('/etc/mysecret.conf').with_content("top secret\n") }
|
36
|
+
|
37
|
+
# New
|
38
|
+
it { is_expected.to contain_file('/etc/mysecret.conf').with_content(sensitive("top secret\n")) }
|
39
|
+
```
|
40
|
+
|
41
|
+
### Added
|
42
|
+
* Added support for [trusted external fact data](https://github.com/puppetlabs/rspec-puppet#specifying-trusted-external-data).
|
43
|
+
* Added the ability to exclude resources from the coverage report calculations using a regular expression.
|
44
|
+
(See [documentation](https://rspec-puppet.com/documentation/coverage/#excluded-resources) for an example.
|
45
|
+
* Added `have_unique_values_for_all` matcher to assert a specific resource parameter value is unique across
|
46
|
+
the entire catalogue.
|
47
|
+
(See [documentation](https://rspec-puppet.com/documentation/classes/#test-resource-parameter-values-for-uniqueness).)
|
48
|
+
* Added ability to customize module-layer Hiera configuration via new settings. See
|
49
|
+
[documentation](https://rspec-puppet.com/documentation/configuration/#disable_module_hiera) for details.
|
50
|
+
|
51
|
+
### Changed
|
52
|
+
* `RSpec::Puppet::Cache` now evicts least recently used entries when it reaches max size.
|
53
|
+
* `rspec-puppet`'s implementation of `match_manifests` will no longer look in `init.pp` for class
|
54
|
+
declarations if a manifest file exactly matching the class name exists.
|
55
|
+
|
56
|
+
### Fixed
|
57
|
+
* Resolved compatibility issues with Ruby 2.7.x and added Ruby 2.7.x to the test matrix.
|
58
|
+
* Resolved issues calculating coverage and reporting results when there are 0 tested resources.
|
59
|
+
* Resolved compatibility issue with `rspec-expectations` 3.10.0.
|
60
|
+
|
5
61
|
## [2.7.10]
|
6
62
|
|
7
63
|
### Fixed
|
@@ -509,13 +565,44 @@ Thanks to Adrien Thebo, Alex Harvey, Brian, Dan Bode, Dominic Cleal, Javier Pala
|
|
509
565
|
## 1.0.1 and earlier
|
510
566
|
For changelog of versions 1.0.1 and earlier, see http://rspec-puppet.com/changelog/
|
511
567
|
|
512
|
-
[2.x]: https://github.com/
|
513
|
-
[2.
|
514
|
-
[2.
|
515
|
-
[2.
|
516
|
-
[2.
|
517
|
-
[2.
|
518
|
-
[2.
|
519
|
-
[2.
|
520
|
-
[2.
|
521
|
-
[2.
|
568
|
+
[2.x]: https://github.com/puppetlabs/rspec-puppet/compare/v2.11.0...master
|
569
|
+
[2.11.0]: https://github.com/puppetlabs/rspec-puppet/compare/v2.10.0...v2.11.0
|
570
|
+
[2.10.0]: https://github.com/puppetlabs/rspec-puppet/compare/v2.9.0...v2.10.0
|
571
|
+
[2.9.0]: https://github.com/puppetlabs/rspec-puppet/compare/v2.8.0...v2.9.0
|
572
|
+
[2.8.0]: https://github.com/puppetlabs/rspec-puppet/compare/v2.7.10...v2.8.0
|
573
|
+
[2.7.10]: https://github.com/puppetlabs/rspec-puppet/compare/v2.7.9...v2.7.10
|
574
|
+
[2.7.9]: https://github.com/puppetlabs/rspec-puppet/compare/v2.7.8...v2.7.9
|
575
|
+
[2.7.8]: https://github.com/puppetlabs/rspec-puppet/compare/v2.7.7...v2.7.8
|
576
|
+
[2.7.7]: https://github.com/puppetlabs/rspec-puppet/compare/v2.7.6...v2.7.7
|
577
|
+
[2.7.6]: https://github.com/puppetlabs/rspec-puppet/compare/v2.7.5...v2.7.6
|
578
|
+
[2.7.5]: https://github.com/puppetlabs/rspec-puppet/compare/v2.7.4...v2.7.5
|
579
|
+
[2.7.4]: https://github.com/puppetlabs/rspec-puppet/compare/v2.7.3...v2.7.4
|
580
|
+
[2.7.3]: https://github.com/puppetlabs/rspec-puppet/compare/v2.7.2...v2.7.3
|
581
|
+
[2.7.2]: https://github.com/puppetlabs/rspec-puppet/compare/v2.7.1...v2.7.2
|
582
|
+
[2.7.1]: https://github.com/puppetlabs/rspec-puppet/compare/v2.7.0...v2.7.1
|
583
|
+
[2.7.0]: https://github.com/puppetlabs/rspec-puppet/compare/v2.6.15...v2.7.0
|
584
|
+
[2.6.15]: https://github.com/puppetlabs/rspec-puppet/compare/v2.6.14...v2.6.15
|
585
|
+
[2.6.14]: https://github.com/puppetlabs/rspec-puppet/compare/v2.6.13...v2.6.14
|
586
|
+
[2.6.13]: https://github.com/puppetlabs/rspec-puppet/compare/v2.6.12...v2.6.13
|
587
|
+
[2.6.12]: https://github.com/puppetlabs/rspec-puppet/compare/v2.6.11...v2.6.12
|
588
|
+
[2.6.11]: https://github.com/puppetlabs/rspec-puppet/compare/v2.6.10...v2.6.11
|
589
|
+
[2.6.10]: https://github.com/puppetlabs/rspec-puppet/compare/v2.6.9...v2.6.10
|
590
|
+
[2.6.9]: https://github.com/puppetlabs/rspec-puppet/compare/v2.6.8...v2.6.9
|
591
|
+
[2.6.8]: https://github.com/puppetlabs/rspec-puppet/compare/v2.6.7...v2.6.8
|
592
|
+
[2.6.7]: https://github.com/puppetlabs/rspec-puppet/compare/v2.6.6...v2.6.7
|
593
|
+
[2.6.6]: https://github.com/puppetlabs/rspec-puppet/compare/v2.6.5...v2.6.6
|
594
|
+
[2.6.5]: https://github.com/puppetlabs/rspec-puppet/compare/v2.6.4...v2.6.5
|
595
|
+
[2.6.4]: https://github.com/puppetlabs/rspec-puppet/compare/v2.6.3...v2.6.4
|
596
|
+
[2.6.3]: https://github.com/puppetlabs/rspec-puppet/compare/v2.6.2...v2.6.3
|
597
|
+
[2.6.2]: https://github.com/puppetlabs/rspec-puppet/compare/v2.6.1...v2.6.2
|
598
|
+
[2.6.1]: https://github.com/puppetlabs/rspec-puppet/compare/v2.6.0...v2.6.1
|
599
|
+
[2.6.0]: https://github.com/puppetlabs/rspec-puppet/compare/2.5.0...v2.6.0
|
600
|
+
[2.5.0]: https://github.com/puppetlabs/rspec-puppet/compare/v2.4.0...v2.5.0
|
601
|
+
[2.4.0]: https://github.com/puppetlabs/rspec-puppet/compare/v2.3.2...v2.4.0
|
602
|
+
[2.3.2]: https://github.com/puppetlabs/rspec-puppet/compare/v2.3.1...v2.3.2
|
603
|
+
[2.3.1]: https://github.com/puppetlabs/rspec-puppet/compare/v2.3.0...v2.3.1
|
604
|
+
[2.3.0]: https://github.com/puppetlabs/rspec-puppet/compare/v2.2.0...v2.3.0
|
605
|
+
[2.2.0]: https://github.com/puppetlabs/rspec-puppet/compare/v2.1.0...v2.2.0
|
606
|
+
[2.1.0]: https://github.com/puppetlabs/rspec-puppet/compare/v2.0.1...v2.1.0
|
607
|
+
[2.0.1]: https://github.com/puppetlabs/rspec-puppet/compare/v2.0.0...v2.0.1
|
608
|
+
[2.0.0]: https://github.com/puppetlabs/rspec-puppet/compare/v1.0.1...v2.0.0
|
data/README.md
CHANGED
@@ -2,6 +2,20 @@
|
|
2
2
|
[](https://travis-ci.org/rodjek/rspec-puppet)
|
3
3
|
[](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
|
@@ -216,6 +230,20 @@ In some circumstances (e.g. where your nodename/certname is not the same as
|
|
216
230
|
your FQDN), this behaviour is undesirable and can be disabled by changing this
|
217
231
|
setting to `false`.
|
218
232
|
|
233
|
+
#### facter\_implementation
|
234
|
+
Type | Default | Puppet Version(s)
|
235
|
+
------- | -------- | -----------------
|
236
|
+
String | `facter` | 6.25+, 7.12+
|
237
|
+
|
238
|
+
Configures rspec-puppet to use a specific Facter implementation for running
|
239
|
+
unit tests. If the `rspec` implementation is set and Puppet does not support
|
240
|
+
it, rspec-puppet will warn and fall back to the `facter` implementation.
|
241
|
+
Setting an unsupported option will make rspec-puppet raise an error.
|
242
|
+
|
243
|
+
* `facter` - Use the default implementation, honoring the Facter version specified in the Gemfile
|
244
|
+
* `rspec` - Use a custom hash-based implementation of Facter defined in
|
245
|
+
rspec-puppet (this provides a considerable gain in speed if tests are run with Facter 4)
|
246
|
+
|
219
247
|
## Naming conventions
|
220
248
|
|
221
249
|
For clarity and consistency, I recommend that you use the following directory
|
@@ -759,6 +787,30 @@ RSpec.configure do |c|
|
|
759
787
|
end
|
760
788
|
```
|
761
789
|
|
790
|
+
#### Specifying trusted external data
|
791
|
+
|
792
|
+
When testing with Puppet >= 6.14, the trusted facts hash will have an additional `external`
|
793
|
+
key for trusted external data.
|
794
|
+
|
795
|
+
By default, the test environment contains no trusted external data (as usually obtained from
|
796
|
+
trusted external commands and found in the `external` key). If you need to test against specific
|
797
|
+
trusted external data you can set those with a hash. The hash will then be available in
|
798
|
+
`$trusted['external']`
|
799
|
+
|
800
|
+
```ruby
|
801
|
+
let(:trusted_external_data) { {'foo' => 'bar'} }
|
802
|
+
```
|
803
|
+
|
804
|
+
You can also create a set of default trusted external data provided to all specs in your spec_helper:
|
805
|
+
|
806
|
+
```ruby
|
807
|
+
RSpec.configure do |c|
|
808
|
+
c.default_trusted_external_data = {
|
809
|
+
'foo' => 'bar'
|
810
|
+
}
|
811
|
+
end
|
812
|
+
```
|
813
|
+
|
762
814
|
#### Testing Exported Resources
|
763
815
|
|
764
816
|
You can test if a resource was exported from the catalogue by using the
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'rspec-puppet/facter_impl'
|
2
|
+
|
1
3
|
module RSpec::Puppet
|
2
4
|
module Adapters
|
3
5
|
|
@@ -108,6 +110,17 @@ module RSpec::Puppet
|
|
108
110
|
end
|
109
111
|
|
110
112
|
class Adapter40 < Base
|
113
|
+
#
|
114
|
+
# @api private
|
115
|
+
#
|
116
|
+
# Set the FacterImpl constant to the given Facter implementation.
|
117
|
+
# The method noops if the constant is already set
|
118
|
+
#
|
119
|
+
# @param impl [Object]
|
120
|
+
def set_facter_impl(impl)
|
121
|
+
Object.send(:const_set, :FacterImpl, impl) unless defined? FacterImpl
|
122
|
+
end
|
123
|
+
|
111
124
|
def setup_puppet(example_group)
|
112
125
|
super
|
113
126
|
|
@@ -139,7 +152,8 @@ module RSpec::Puppet
|
|
139
152
|
Puppet.push_context(
|
140
153
|
{
|
141
154
|
:environments => loader,
|
142
|
-
:current_environment => env
|
155
|
+
:current_environment => env,
|
156
|
+
:loaders => (Puppet::Pops::Loaders.new(env) if Gem::Version.new(Puppet.version) >= Gem::Version.new('6.0.0')),
|
143
157
|
},
|
144
158
|
"Setup rspec-puppet environments"
|
145
159
|
)
|
@@ -185,6 +199,12 @@ module RSpec::Puppet
|
|
185
199
|
end
|
186
200
|
|
187
201
|
class Adapter4X < Adapter40
|
202
|
+
def setup_puppet(example_group)
|
203
|
+
super
|
204
|
+
|
205
|
+
set_facter_impl(Facter)
|
206
|
+
end
|
207
|
+
|
188
208
|
def settings_map
|
189
209
|
super.concat([
|
190
210
|
[:trusted_server_facts, :trusted_server_facts]
|
@@ -193,6 +213,46 @@ module RSpec::Puppet
|
|
193
213
|
end
|
194
214
|
|
195
215
|
class Adapter6X < Adapter40
|
216
|
+
#
|
217
|
+
# @api private
|
218
|
+
#
|
219
|
+
# Check to see if Facter runtime implementations are supported in the
|
220
|
+
# current Puppet version
|
221
|
+
#
|
222
|
+
# @return [Boolean] true if runtime implementations are supported
|
223
|
+
def supports_facter_runtime?
|
224
|
+
unless defined?(@supports_facter_runtime)
|
225
|
+
begin
|
226
|
+
Puppet.runtime[:facter]
|
227
|
+
@supports_facter_runtime = true
|
228
|
+
rescue
|
229
|
+
@supports_facter_runtime = false
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
@supports_facter_runtime
|
234
|
+
end
|
235
|
+
|
236
|
+
def setup_puppet(example_group)
|
237
|
+
case RSpec.configuration.facter_implementation.to_sym
|
238
|
+
when :rspec
|
239
|
+
if supports_facter_runtime?
|
240
|
+
Puppet.runtime[:facter] = proc { RSpec::Puppet::FacterTestImpl.new }
|
241
|
+
set_facter_impl(Puppet.runtime[:facter])
|
242
|
+
else
|
243
|
+
warn "Facter runtime implementations are not supported in Puppet #{Puppet.version}, continuing with facter_implementation 'facter'"
|
244
|
+
RSpec.configuration.facter_implementation = 'facter'
|
245
|
+
set_facter_impl(Facter)
|
246
|
+
end
|
247
|
+
when :facter
|
248
|
+
set_facter_impl(Facter)
|
249
|
+
else
|
250
|
+
raise "Unsupported facter_implementation '#{RSpec.configuration.facter_implementation}'"
|
251
|
+
end
|
252
|
+
|
253
|
+
super
|
254
|
+
end
|
255
|
+
|
196
256
|
def settings_map
|
197
257
|
super.concat([
|
198
258
|
[:basemodulepath, :basemodulepath],
|
data/lib/rspec-puppet/cache.rb
CHANGED
@@ -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
|
17
|
-
|
18
|
-
|
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
|
-
|
29
|
-
|
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
|
-
|
25
|
-
|
26
|
-
|
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,6 +47,7 @@ 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
|
@@ -42,6 +55,9 @@ module RSpec::Puppet
|
|
42
55
|
File.open(File.join(Dir.tmpdir, "rspec-puppet-filter-#{slug}"), 'w+') do |f|
|
43
56
|
f.puts @filters.to_json
|
44
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
|
45
61
|
File.open(File.join(Dir.tmpdir, "rspec-puppet-coverage-#{slug}"), 'w+') do |f|
|
46
62
|
f.puts @collection.to_json
|
47
63
|
end
|
@@ -57,10 +73,17 @@ module RSpec::Puppet
|
|
57
73
|
|
58
74
|
def merge_filters
|
59
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
|
+
|
60
78
|
Dir[pattern].each do |result_file|
|
61
79
|
load_filters(result_file)
|
62
80
|
FileUtils.rm(result_file)
|
63
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
|
64
87
|
end
|
65
88
|
|
66
89
|
def load_results(path)
|
@@ -79,6 +102,15 @@ module RSpec::Puppet
|
|
79
102
|
end
|
80
103
|
end
|
81
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
|
+
|
82
114
|
def add(resource)
|
83
115
|
if !exists?(resource) && !filtered?(resource)
|
84
116
|
@collection[resource.to_s] = ResourceWrapper.new(resource)
|
@@ -86,11 +118,8 @@ module RSpec::Puppet
|
|
86
118
|
end
|
87
119
|
|
88
120
|
def add_filter(type, title)
|
89
|
-
def capitalize_name(name)
|
90
|
-
name.split('::').map { |subtitle| subtitle.capitalize }.join('::')
|
91
|
-
end
|
92
|
-
|
93
121
|
type = capitalize_name(type)
|
122
|
+
|
94
123
|
if type == 'Class'
|
95
124
|
title = capitalize_name(title)
|
96
125
|
end
|
@@ -98,6 +127,34 @@ module RSpec::Puppet
|
|
98
127
|
@filters << "#{type}[#{title}]"
|
99
128
|
end
|
100
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
|
+
|
101
158
|
# add all resources from catalog declared in module test_module
|
102
159
|
def add_from_catalog(catalog, test_module)
|
103
160
|
coverable_resources = catalog.to_a.reject { |resource| !test_module.nil? && filter_resource?(resource, test_module) }
|
@@ -107,7 +164,10 @@ module RSpec::Puppet
|
|
107
164
|
end
|
108
165
|
|
109
166
|
def filtered?(resource)
|
110
|
-
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
|
111
171
|
end
|
112
172
|
|
113
173
|
def cover!(resource)
|
@@ -136,7 +196,7 @@ module RSpec::Puppet
|
|
136
196
|
end
|
137
197
|
|
138
198
|
def run_report(coverage_desired = nil)
|
139
|
-
if
|
199
|
+
if parallel_tests?
|
140
200
|
merge_filters
|
141
201
|
merge_results
|
142
202
|
end
|
@@ -145,7 +205,7 @@ module RSpec::Puppet
|
|
145
205
|
|
146
206
|
coverage_test(coverage_desired, report)
|
147
207
|
|
148
|
-
puts report[:text]
|
208
|
+
puts "\n\nCoverage Report:\n\n#{report[:text]}"
|
149
209
|
end
|
150
210
|
|
151
211
|
def coverage_test(coverage_desired, report)
|
@@ -187,7 +247,9 @@ module RSpec::Puppet
|
|
187
247
|
report[:total] = @collection.size
|
188
248
|
report[:touched] = @collection.count { |_, resource| resource.touched? }
|
189
249
|
report[:untouched] = report[:total] - report[:touched]
|
190
|
-
|
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
|
191
253
|
|
192
254
|
report[:resources] = Hash[*@collection.map do |name, wrapper|
|
193
255
|
[name, wrapper.to_hash]
|
@@ -226,7 +288,7 @@ module RSpec::Puppet
|
|
226
288
|
# @param test_module [String] The name of the module under test
|
227
289
|
# @return [true, false]
|
228
290
|
def filter_resource?(resource, test_module)
|
229
|
-
if
|
291
|
+
if filtered?(resource)
|
230
292
|
return true
|
231
293
|
end
|
232
294
|
|
@@ -267,6 +329,10 @@ module RSpec::Puppet
|
|
267
329
|
!find(resource).nil?
|
268
330
|
end
|
269
331
|
|
332
|
+
def capitalize_name(name)
|
333
|
+
name.split('::').map { |subtitle| subtitle.capitalize }.join('::')
|
334
|
+
end
|
335
|
+
|
270
336
|
class ResourceWrapper
|
271
337
|
attr_reader :resource
|
272
338
|
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module RSpec::Puppet
|
2
|
+
|
3
|
+
# Implements a simple hash-based version of Facter to be used in module tests
|
4
|
+
# that use rspec-puppet.
|
5
|
+
class FacterTestImpl
|
6
|
+
def initialize
|
7
|
+
@facts = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def value(fact_name)
|
11
|
+
@facts[fact_name.to_s]
|
12
|
+
end
|
13
|
+
|
14
|
+
def clear
|
15
|
+
@facts.clear
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_hash
|
19
|
+
@facts
|
20
|
+
end
|
21
|
+
|
22
|
+
def add(name, options = {}, &block)
|
23
|
+
raise 'Facter.add expects a block' unless block_given?
|
24
|
+
@facts[name.to_s] = instance_eval(&block)
|
25
|
+
end
|
26
|
+
|
27
|
+
# noop methods
|
28
|
+
def debugging(arg); end
|
29
|
+
|
30
|
+
def reset; end
|
31
|
+
|
32
|
+
def search(*paths); end
|
33
|
+
|
34
|
+
def setup_logging; end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def setcode(string = nil, &block)
|
39
|
+
if block_given?
|
40
|
+
value = block.call
|
41
|
+
else
|
42
|
+
value = string
|
43
|
+
end
|
44
|
+
|
45
|
+
value
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
@@ -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
|
-
@
|
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 == @
|
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 << "#{@
|
50
|
+
desc << "#{@resource_type}"
|
49
51
|
end
|
50
52
|
desc << "#{@expected_number == 1 ? "resource" : "resources" }"
|
51
53
|
end
|
@@ -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
|
@@ -302,14 +307,17 @@ module RSpec::Puppet
|
|
302
307
|
end
|
303
308
|
end
|
304
309
|
|
305
|
-
# Add
|
306
|
-
if
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
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
|
313
321
|
end
|
314
322
|
end
|
315
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(
|
7
|
+
RSpec.deprecate('include_class()', :replacement => 'contain_class()')
|
8
8
|
catalogue.call.classes.include?(expected_class)
|
9
9
|
end
|
10
10
|
|
@@ -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
|
@@ -16,8 +16,8 @@ module RSpec::Puppet
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
def raise_error(
|
20
|
-
RaiseError.new(
|
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
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -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
|
@@ -268,6 +268,40 @@ module Puppet
|
|
268
268
|
end
|
269
269
|
end
|
270
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
|
271
305
|
end
|
272
306
|
|
273
307
|
class Pathname
|
@@ -302,6 +336,24 @@ class Pathname
|
|
302
336
|
end
|
303
337
|
end
|
304
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
|
+
|
305
357
|
# Prevent the File type from munging paths (which uses File.expand_path to
|
306
358
|
# normalise paths, which does very bad things to *nix paths on Windows.
|
307
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
|
data/lib/rspec-puppet/support.rb
CHANGED
@@ -1,12 +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
|
7
8
|
include GenericMatchers
|
8
9
|
|
9
10
|
@@cache = RSpec::Puppet::Cache.new
|
11
|
+
@@fixture_hiera_configs = Hash.new { |h, k| h[k] = nil }
|
10
12
|
|
11
13
|
def subject
|
12
14
|
lambda { catalogue }
|
@@ -86,10 +88,29 @@ module RSpec::Puppet
|
|
86
88
|
hiera_config_value = self.respond_to?(:hiera_config) ? hiera_config : nil
|
87
89
|
hiera_data_value = self.respond_to?(:hiera_data) ? hiera_data : nil
|
88
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
|
+
|
89
99
|
build_facts = facts_hash(node_name)
|
90
|
-
catalogue = build_catalog(
|
91
|
-
|
92
|
-
|
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
|
+
)
|
93
114
|
|
94
115
|
test_module = type == :host ? nil : class_name.split('::').first
|
95
116
|
if type == :define
|
@@ -293,6 +314,19 @@ module RSpec::Puppet
|
|
293
314
|
extensions
|
294
315
|
end
|
295
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
|
+
|
296
330
|
def server_facts_hash
|
297
331
|
server_facts = {}
|
298
332
|
|
@@ -303,7 +337,7 @@ module RSpec::Puppet
|
|
303
337
|
{"servername" => "fqdn",
|
304
338
|
"serverip" => "ipaddress"
|
305
339
|
}.each do |var, fact|
|
306
|
-
if value =
|
340
|
+
if value = FacterImpl.value(fact)
|
307
341
|
server_facts[var] = value
|
308
342
|
else
|
309
343
|
warn "Could not retrieve fact #{fact}"
|
@@ -311,8 +345,8 @@ module RSpec::Puppet
|
|
311
345
|
end
|
312
346
|
|
313
347
|
if server_facts["servername"].nil?
|
314
|
-
host =
|
315
|
-
if domain =
|
348
|
+
host = FacterImpl.value(:hostname)
|
349
|
+
if domain = FacterImpl.value(:domain)
|
316
350
|
server_facts["servername"] = [host, domain].join(".")
|
317
351
|
else
|
318
352
|
server_facts["servername"] = host
|
@@ -358,7 +392,7 @@ module RSpec::Puppet
|
|
358
392
|
|
359
393
|
# Enable app_management by default for Puppet versions that support it
|
360
394
|
if Puppet::Util::Package.versioncmp(Puppet.version, '4.3.0') >= 0 && Puppet.version.to_i < 5
|
361
|
-
Puppet[:app_management] = true
|
395
|
+
Puppet[:app_management] = ENV.include?('PUPPET_NOAPP_MANAGMENT') ? false : true
|
362
396
|
end
|
363
397
|
|
364
398
|
adapter.modulepath.map do |d|
|
@@ -380,6 +414,29 @@ module RSpec::Puppet
|
|
380
414
|
end
|
381
415
|
|
382
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
|
+
)
|
383
440
|
|
384
441
|
# If we're going to rebuild the catalog, we should clear the cached instance
|
385
442
|
# of Hiera that Puppet is using. This opens the possibility of the catalog
|
@@ -401,10 +458,14 @@ module RSpec::Puppet
|
|
401
458
|
|
402
459
|
node_obj = Puppet::Node.new(nodename, { :parameters => node_params, :facts => node_facts })
|
403
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
|
404
465
|
if Puppet::Util::Package.versioncmp(Puppet.version, '4.3.0') >= 0
|
405
466
|
Puppet.push_context(
|
406
467
|
{
|
407
|
-
:trusted_information => Puppet::Context::TrustedInformation.new(
|
468
|
+
:trusted_information => Puppet::Context::TrustedInformation.new(*trusted_info)
|
408
469
|
},
|
409
470
|
"Context for spec trusted hash"
|
410
471
|
)
|
@@ -417,13 +478,17 @@ module RSpec::Puppet
|
|
417
478
|
|
418
479
|
def stub_facts!(facts)
|
419
480
|
Puppet.settings[:autosign] = false if Puppet.settings.include? :autosign
|
420
|
-
|
421
|
-
facts.each { |k, v|
|
481
|
+
FacterImpl.clear
|
482
|
+
facts.each { |k, v| FacterImpl.add(k, :weight => 999) { setcode { v } } }
|
422
483
|
end
|
423
484
|
|
424
485
|
def build_catalog(*args)
|
425
486
|
@@cache.get(*args) do |*args|
|
426
|
-
|
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
|
427
492
|
end
|
428
493
|
end
|
429
494
|
|
@@ -440,8 +505,7 @@ module RSpec::Puppet
|
|
440
505
|
end
|
441
506
|
|
442
507
|
def escape_special_chars(string)
|
443
|
-
string.gsub
|
444
|
-
string
|
508
|
+
string.gsub(/\$/, "\\$")
|
445
509
|
end
|
446
510
|
|
447
511
|
def rspec_compatibility
|
@@ -452,6 +516,23 @@ module RSpec::Puppet
|
|
452
516
|
end
|
453
517
|
end
|
454
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
|
+
|
455
536
|
# Helper to return a resource/node reference, so it gets translated in params to a raw string
|
456
537
|
# without quotes.
|
457
538
|
#
|
@@ -462,6 +543,14 @@ module RSpec::Puppet
|
|
462
543
|
return RSpec::Puppet::RawString.new("#{type}['#{title}']")
|
463
544
|
end
|
464
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
|
+
|
465
554
|
# @!attribute [r] adapter
|
466
555
|
# @api private
|
467
556
|
# @return [Class < RSpec::Puppet::Adapters::Base]
|
data/lib/rspec-puppet.rb
CHANGED
@@ -42,6 +42,8 @@ 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 => {}
|
46
|
+
c.add_setting :facter_implementation, :default => 'facter'
|
45
47
|
c.add_setting :hiera_config, :default => Puppet::Util::Platform.actually_windows? ? 'c:/nul/' : '/dev/null'
|
46
48
|
c.add_setting :parser, :default => 'current'
|
47
49
|
c.add_setting :trusted_node_data, :default => false
|
@@ -54,6 +56,10 @@ RSpec.configure do |c|
|
|
54
56
|
c.add_setting :platform, :default => Puppet::Util::Platform.actual_platform
|
55
57
|
c.add_setting :vendormoduledir, :default => Puppet::Util::Platform.actually_windows? ? 'c:/nul/' : '/dev/null'
|
56
58
|
c.add_setting :basemodulepath, :default => Puppet::Util::Platform.actually_windows? ? 'c:/nul/' : '/dev/null'
|
59
|
+
c.add_setting :disable_module_hiera, :default => false
|
60
|
+
c.add_setting :fixture_hiera_configs, :default => {}
|
61
|
+
c.add_setting :use_fixture_spec_hiera, :default => false
|
62
|
+
c.add_setting :fallback_to_default_hiera, :default => true
|
57
63
|
|
58
64
|
c.instance_eval do
|
59
65
|
def trusted_server_facts
|
metadata
CHANGED
@@ -1,14 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-puppet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Sharpe
|
8
|
-
|
8
|
+
- Puppet, Inc.
|
9
|
+
- Community Contributors
|
10
|
+
autorequire:
|
9
11
|
bindir: bin
|
10
12
|
cert_chain: []
|
11
|
-
date:
|
13
|
+
date: 2021-11-10 00:00:00.000000000 Z
|
12
14
|
dependencies:
|
13
15
|
- !ruby/object:Gem::Dependency
|
14
16
|
name: rspec
|
@@ -25,7 +27,9 @@ dependencies:
|
|
25
27
|
- !ruby/object:Gem::Version
|
26
28
|
version: '0'
|
27
29
|
description: RSpec tests for your Puppet manifests
|
28
|
-
email:
|
30
|
+
email:
|
31
|
+
- tim@sharpe.id.au
|
32
|
+
- modules-team@puppet.com
|
29
33
|
executables:
|
30
34
|
- rspec-puppet-init
|
31
35
|
extensions: []
|
@@ -49,6 +53,7 @@ files:
|
|
49
53
|
- lib/rspec-puppet/example/provider_example_group.rb
|
50
54
|
- lib/rspec-puppet/example/type_alias_example_group.rb
|
51
55
|
- lib/rspec-puppet/example/type_example_group.rb
|
56
|
+
- lib/rspec-puppet/facter_impl.rb
|
52
57
|
- lib/rspec-puppet/matchers.rb
|
53
58
|
- lib/rspec-puppet/matchers/allow_value.rb
|
54
59
|
- lib/rspec-puppet/matchers/compile.rb
|
@@ -60,21 +65,23 @@ files:
|
|
60
65
|
- lib/rspec-puppet/matchers/raise_error.rb
|
61
66
|
- lib/rspec-puppet/matchers/run.rb
|
62
67
|
- lib/rspec-puppet/matchers/type_matchers.rb
|
68
|
+
- lib/rspec-puppet/matchers/unique_values.rb
|
63
69
|
- lib/rspec-puppet/monkey_patches.rb
|
64
70
|
- lib/rspec-puppet/monkey_patches/win32/registry.rb
|
65
71
|
- lib/rspec-puppet/monkey_patches/win32/taskscheduler.rb
|
66
72
|
- lib/rspec-puppet/monkey_patches/windows/taskschedulerconstants.rb
|
67
73
|
- lib/rspec-puppet/rake_task.rb
|
68
74
|
- lib/rspec-puppet/raw_string.rb
|
75
|
+
- lib/rspec-puppet/sensitive.rb
|
69
76
|
- lib/rspec-puppet/setup.rb
|
70
77
|
- lib/rspec-puppet/spec_helper.rb
|
71
78
|
- lib/rspec-puppet/support.rb
|
72
79
|
- lib/rspec-puppet/tasks/release_test.rb
|
73
|
-
homepage: https://github.com/
|
80
|
+
homepage: https://github.com/puppetlabs/rspec-puppet/
|
74
81
|
licenses:
|
75
82
|
- MIT
|
76
83
|
metadata: {}
|
77
|
-
post_install_message:
|
84
|
+
post_install_message:
|
78
85
|
rdoc_options: []
|
79
86
|
require_paths:
|
80
87
|
- lib
|
@@ -89,8 +96,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
89
96
|
- !ruby/object:Gem::Version
|
90
97
|
version: '0'
|
91
98
|
requirements: []
|
92
|
-
|
93
|
-
|
99
|
+
rubyforge_project:
|
100
|
+
rubygems_version: 2.7.6.2
|
101
|
+
signing_key:
|
94
102
|
specification_version: 4
|
95
103
|
summary: RSpec tests for your Puppet manifests
|
96
104
|
test_files: []
|