rspec-puppet 2.5.0 → 2.6.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.
- data/CHANGELOG.md +86 -0
- data/README.md +317 -34
- data/lib/rspec-puppet/adapters.rb +38 -30
- data/lib/rspec-puppet/coverage.rb +31 -6
- data/lib/rspec-puppet/example/function_example_group.rb +53 -8
- data/lib/rspec-puppet/example/type_alias_example_group.rb +14 -0
- data/lib/rspec-puppet/example.rb +16 -33
- data/lib/rspec-puppet/matchers/allow_value.rb +45 -0
- data/lib/rspec-puppet/matchers/compile.rb +7 -0
- data/lib/rspec-puppet/matchers/create_generic.rb +54 -13
- data/lib/rspec-puppet/matchers/parameter_matcher.rb +2 -2
- data/lib/rspec-puppet/matchers/run.rb +6 -1
- data/lib/rspec-puppet/matchers.rb +1 -0
- data/lib/rspec-puppet/monkey_patches.rb +162 -0
- data/lib/rspec-puppet/setup.rb +47 -26
- data/lib/rspec-puppet/spec_helper.rb +4 -3
- data/lib/rspec-puppet/support.rb +183 -34
- data/lib/rspec-puppet.rb +18 -0
- metadata +35 -28
- checksums.yaml +0 -7
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,92 @@
|
|
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.6.0]
|
6
|
+
|
7
|
+
The Windows parity release. rspec-puppet now officially supports Windows. A lot
|
8
|
+
of work has been put in to support cross-platform tests, so that you can now
|
9
|
+
test your Windows manifests on \*nix, and your \*nix manifests on Windows.
|
10
|
+
|
11
|
+
### Changed
|
12
|
+
|
13
|
+
* Puppet settings are now applied as application overrides, allowing users to
|
14
|
+
call `Puppet.settings` directly to make changes to settings without them
|
15
|
+
getting clobbered by rspec-puppet.
|
16
|
+
* Improved support for setting up the `spec/fixtures/modules` link on Windows
|
17
|
+
by using directory junctions instead of symlinks, removing the need for
|
18
|
+
Administrator access.
|
19
|
+
* When testing for the absence of a parameter on a resource, the error message
|
20
|
+
now contains the value(s) of the parameter(s) that should be undefined.
|
21
|
+
* When testing a defined type, the defined type being tested is no longer part
|
22
|
+
of the coverage report.
|
23
|
+
* The cached catalogue will now be invalidated when hiera-puppet-helper users
|
24
|
+
change their `hiera_data` value.
|
25
|
+
* Multiple instances of a defined type can now be tested at once by providing
|
26
|
+
an array of strings with `let(:title)`.
|
27
|
+
* Explicitly specifying the type of an example group (`:type => :class`) now
|
28
|
+
takes precedence over the type inferred from the spec file's location.
|
29
|
+
* The manifest specified in `RSpec.configuration.manifest` (path to `site.pp`
|
30
|
+
for Puppet < 4.x) is now imported if specified on Puppet >= 4.x.
|
31
|
+
* Puppet functions called when testing a Puppet function now get executed in
|
32
|
+
the same scope as parent function.
|
33
|
+
|
34
|
+
### Added
|
35
|
+
|
36
|
+
* The module is now automatically linked into `spec/fixtures/modules` at the
|
37
|
+
start of the rspec-puppet run.
|
38
|
+
* CI testing of PRs on Windows via Appveyor.
|
39
|
+
* Support for setting node parameters (mocking the behaviour of an ENC or
|
40
|
+
Puppet Enterprise Console) using `let(:node_params)`.
|
41
|
+
* Support for injecting Puppet code at the end of the test code using
|
42
|
+
`let(:post_condition)`.
|
43
|
+
* Resource coverage reports for `host` specs.
|
44
|
+
* Puppet functions that take a lambda as a parameter can now be tested by
|
45
|
+
chaining `with_lambda` to the `run` matcher.
|
46
|
+
* Facts and trusted facts are now available when testing Puppet functions.
|
47
|
+
* Hiera configuration can now be specified when testing Puppet functions using
|
48
|
+
`let(:hiera_config)`.
|
49
|
+
* Trusted facts (`$trusted[]`) can now be specified in
|
50
|
+
`RSpec.configuration.default_trusted_facts` or by `let(:trusted_facts)`.
|
51
|
+
* `:default` is now a supported parameter value when passed in by
|
52
|
+
`let(:params)`.
|
53
|
+
* Support for testing Puppet data type aliases.
|
54
|
+
|
55
|
+
### Fixed
|
56
|
+
|
57
|
+
* Facts generated from the node name (as set by `let(:node)`) now take
|
58
|
+
precedence over the values specified in `RSpec.configuration.default_facts`
|
59
|
+
or by `let(:facts)`.
|
60
|
+
* Only fact names will now be converted to lowercase, not the fact values.
|
61
|
+
* Matchers now support resources where the namevar has a different value to
|
62
|
+
the title.
|
63
|
+
* Resources created outside of the module being tested by functions like
|
64
|
+
`create_resources` or `ensure_package` are no longer present in the coverage
|
65
|
+
report from Puppet 4.6 onwards.
|
66
|
+
* Guards have been put in place to prevent the possibility of rspec-puppet
|
67
|
+
getting stuck in an infinite recursion when testing the relationships
|
68
|
+
between resources.
|
69
|
+
* A full `spec/spec_helper.rb` file is now written out by `rspec-puppet-init`
|
70
|
+
to fix the `fixture_path` issue on new modules.
|
71
|
+
* The namevar of a resources is no longer taken into account when testing the
|
72
|
+
exact parameters of the resource with `only_with`.
|
73
|
+
* Minimum resource coverage check for RSpec <= 3.2.
|
74
|
+
* Resource parameters that take a hash as their value will no longer have that
|
75
|
+
hash converted into an array.
|
76
|
+
* Testing the value of a parameter with a Proc that returns `nil` now works as
|
77
|
+
expected.
|
78
|
+
* When testing Puppet functions, the function name is no longer automatically
|
79
|
+
coverted to lowercase.
|
80
|
+
* The value of `$::environment` is now forced to be a string as expected for
|
81
|
+
Puppet 4.0 - 4.3.
|
82
|
+
* app\_management is no longer enabled by rspec-puppet for Puppet >= 5.0 as it
|
83
|
+
is already enabled by default.
|
84
|
+
* Failing to provide parameters when testing an application now raises the
|
85
|
+
correct exception (`ArgumentError`).
|
86
|
+
* Ruby symbols in nested hashes or arrays are now converted into strings when
|
87
|
+
passed in by `let(:params)`.
|
88
|
+
* Namespaced resources are now correctly capitalised when being added to the
|
89
|
+
resource coverage filter.
|
90
|
+
|
5
91
|
## [2.5.0]
|
6
92
|
|
7
93
|
Headline features are app management, nested hashes in params, and testing for "internal" functions.
|
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# RSpec tests for your Puppet manifests & modules
|
2
|
-
[](https://travis-ci.org/rodjek/rspec-puppet)
|
3
3
|
[](https://coveralls.io/r/rodjek/rspec-puppet?branch=master)
|
4
4
|
|
5
5
|
## Installation
|
@@ -14,44 +14,209 @@
|
|
14
14
|
|
15
15
|
When you start out on a new module, run `rspec-puppet-init` to create the necessary files to configure rspec-puppet for your module's tests.
|
16
16
|
|
17
|
+
## Configure manifests for Puppet 4
|
18
|
+
|
19
|
+
With Puppet 3, the manifest is set to `$manifestdir/site.pp`. However Puppet 4 defaults to an empty value. In order to test manifests you will need to set appropriate settings.
|
20
|
+
|
21
|
+
Puppet configuration reference for `manifest` can be found online:
|
22
|
+
|
23
|
+
* Puppet 3: https://docs.puppet.com/puppet/3.8/reference/configuration.html#manifest
|
24
|
+
* Puppet 4: https://docs.puppet.com/puppet/4.8/reference/configuration.html#manifest
|
25
|
+
|
26
|
+
Configuration is typically done in a `spec/spec_helper.rb` file which each of your spec will require. Example code:
|
27
|
+
```ruby
|
28
|
+
# /spec
|
29
|
+
base_dir = File.dirname(File.expand_path(__FILE__))
|
30
|
+
|
31
|
+
RSpec.configure do |c|
|
32
|
+
c.module_path = File.join(base_dir, 'fixtures', 'modules')
|
33
|
+
c.manifest_dir = File.join(base_dir, 'fixtures', 'manifests')
|
34
|
+
c.manifest = File.join(base_dir, 'fixtures', 'manifests', 'site.pp')
|
35
|
+
c.environmentpath = File.join(Dir.pwd, 'spec')
|
36
|
+
|
37
|
+
# Coverage generation
|
38
|
+
c.after(:suite) do
|
39
|
+
RSpec::Puppet::Coverage.report!
|
40
|
+
end
|
41
|
+
end
|
42
|
+
```
|
43
|
+
|
44
|
+
## Configuration
|
45
|
+
|
46
|
+
rspec-puppet can be configured by modifying the `RSpec.configure` block in your
|
47
|
+
`spec/spec_helper.rb` file.
|
48
|
+
|
49
|
+
```
|
50
|
+
RSpec.configure do |c|
|
51
|
+
c.<config option> = <value>
|
52
|
+
end
|
53
|
+
```
|
54
|
+
|
55
|
+
#### manifest\_dir
|
56
|
+
Type | Default | Puppet Version(s)
|
57
|
+
------ | -------- | -----------------
|
58
|
+
String | Required | 2.x, 3.x
|
59
|
+
|
60
|
+
The path to the directory containing your basic manifests like `site.pp`.
|
61
|
+
|
62
|
+
#### module\_path
|
63
|
+
Type | Default | Puppet Version(s)
|
64
|
+
------ | -------- | -----------------
|
65
|
+
String | Required | 2.x, 3.x, 4.x
|
66
|
+
|
67
|
+
The path to the directory containing your Puppet modules.
|
68
|
+
|
69
|
+
#### default\_facts
|
70
|
+
Type | Default | Puppet Version(s)
|
71
|
+
---- | ------- | -----------------
|
72
|
+
Hash | `{}` | 2.x, 3.x, 4.x
|
73
|
+
|
74
|
+
A hash of default facts that should be used for all the tests.
|
75
|
+
|
76
|
+
#### hiera\_config
|
77
|
+
Type | Default | Puppet Version(s)
|
78
|
+
------ | ------------- | -----------------
|
79
|
+
String | `"/dev/null"` | 3.x, 4.x
|
80
|
+
|
81
|
+
The path to your `hiera.yaml` file (if used).
|
82
|
+
|
83
|
+
#### default\_node\_params
|
84
|
+
Type | Default | Puppet Version(s)
|
85
|
+
---- | ------- | -----------------
|
86
|
+
Hash | `{}` | 4.x
|
87
|
+
|
88
|
+
A hash of default node parameters that should be used for all the tests.
|
89
|
+
|
90
|
+
#### default\_trusted\_facts
|
91
|
+
Type | Default | Puppet Version(s)
|
92
|
+
---- | ------- | -----------------
|
93
|
+
Hash | `{}` | 4.x
|
94
|
+
|
95
|
+
A hash of default trusted facts that should be used for all the tests
|
96
|
+
(available in the manifests as the `$trusted` hash). In order to use this, the
|
97
|
+
`trusted_node_data` setting must be set to `true`.
|
98
|
+
|
99
|
+
#### trusted\_node\_data
|
100
|
+
Type | Default | Puppet Version(s)
|
101
|
+
------- | ------- | -----------------
|
102
|
+
Boolean | `false` | 3.x, 4.x
|
103
|
+
|
104
|
+
Configures rspec-puppet to use the `$trusted` hash when compiling the
|
105
|
+
catalogues.
|
106
|
+
|
107
|
+
#### confdir
|
108
|
+
Type | Default | Puppet Version(s)
|
109
|
+
------ | --------------- | -----------------
|
110
|
+
String | `"/etc/puppet"` | 2.x, 3.x, 4.x
|
111
|
+
|
112
|
+
The path to the main Puppet configuration directory.
|
113
|
+
|
114
|
+
#### config
|
115
|
+
Type | Default | Puppet Version(s)
|
116
|
+
------ | ---------------------- | -----------------
|
117
|
+
String | Puppet's default value | 2.x, 3.x, 4.x
|
118
|
+
|
119
|
+
The path to `puppet.conf`.
|
120
|
+
|
121
|
+
#### manifest
|
122
|
+
Type | Default | Puppet Version(s)
|
123
|
+
------ | ---------------------- | -----------------
|
124
|
+
String | Puppet's default value | 2.x, 3.x
|
125
|
+
|
126
|
+
The entry-point manifest for Puppet, usually `$manifest_dir/site.pp`.
|
127
|
+
|
128
|
+
#### template\_dir
|
129
|
+
Type | Default | Puppet Version(s)
|
130
|
+
------ | ------- | -----------------
|
131
|
+
String | `nil` | 2.x, 3.x
|
132
|
+
|
133
|
+
The path to the directory that Puppet should search for templates that are
|
134
|
+
stored outside of modules.
|
135
|
+
|
136
|
+
#### environmentpath
|
137
|
+
Type | Default | Puppet Version(s)
|
138
|
+
------ | ------------------------------------- | -----------------
|
139
|
+
String | `"/etc/puppetlabs/code/environments"` | 4.x
|
140
|
+
|
141
|
+
The search path for environment directories.
|
142
|
+
|
143
|
+
#### parser
|
144
|
+
Type | Default | Puppet Version(s)
|
145
|
+
------ | ----------- | -----------------
|
146
|
+
String | `"current"` | 3.x
|
147
|
+
|
148
|
+
This switches between the 3.x (`current`) and 4.x (`future`) parsers.
|
149
|
+
|
150
|
+
#### ordering
|
151
|
+
Type | Default | Puppet Version(s)
|
152
|
+
------ | -------------- | -----------------
|
153
|
+
String | `"title-hash"` | 3.x, 4.x
|
154
|
+
|
155
|
+
How unrelated resources should be ordered when applying a catalogue.
|
156
|
+
* `manifest` - Use the order in which the resources are declared in the
|
157
|
+
manifest.
|
158
|
+
* `title-hash` - Order the resources randomly, but in a consistent manner
|
159
|
+
across runs (the order will only change if the manifest changes).
|
160
|
+
* `random` - Order the resources randomly.
|
161
|
+
|
162
|
+
#### strict\_variables
|
163
|
+
Type | Default | Puppet Version(s)
|
164
|
+
------- | ------- | -----------------
|
165
|
+
Boolean | `false` | 3.x, 4.x
|
166
|
+
|
167
|
+
Makes Puppet raise an error when it tries to reference a variable that hasn't
|
168
|
+
been defined (not including variables that have been explicitly set to
|
169
|
+
`undef`).
|
170
|
+
|
171
|
+
#### stringify\_facts
|
172
|
+
Type | Default | Puppet Version(s)
|
173
|
+
------- | ------- | -----------------
|
174
|
+
Boolean | `true` | 3.x, 4.x
|
175
|
+
|
176
|
+
Makes rspec-puppet coerce all the fact values into strings (matching the
|
177
|
+
behaviour of older versions of Puppet).
|
178
|
+
|
179
|
+
#### enable\_pathname\_stubbing
|
180
|
+
Type | Default | Puppet Version(s)
|
181
|
+
------- | ------- | -----------------
|
182
|
+
Boolean |`false` | 2.x, 3.x, 4.x
|
183
|
+
|
184
|
+
Configures rspec-puppet to stub out `Pathname#absolute?` with it's own
|
185
|
+
implementation. This should only be enabled if you're running into an issue
|
186
|
+
running cross-platform tests where you have Ruby code (types, providers,
|
187
|
+
functions, etc) that use `Pathname#absolute?`.
|
188
|
+
|
17
189
|
## Naming conventions
|
18
190
|
|
19
191
|
For clarity and consistency, I recommend that you use the following directory
|
20
192
|
structure and naming convention.
|
21
193
|
|
22
|
-
module
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
+-- types
|
49
|
-
| |
|
50
|
-
| +-- <type_name>_spec.rb
|
51
|
-
|
|
52
|
-
+-- hosts
|
53
|
-
|
|
54
|
-
+-- <host_name>_spec.rb
|
194
|
+
module/
|
195
|
+
├── manifests/
|
196
|
+
├── lib/
|
197
|
+
└── spec/
|
198
|
+
├── spec_helper.rb
|
199
|
+
│
|
200
|
+
├── classes/
|
201
|
+
│ └── <class_name>_spec.rb
|
202
|
+
│
|
203
|
+
├── defines/
|
204
|
+
│ └── <define_name>_spec.rb
|
205
|
+
│
|
206
|
+
├── applications/
|
207
|
+
│ └── <application_name>_spec.rb
|
208
|
+
│
|
209
|
+
├── functions/
|
210
|
+
│ └── <function_name>_spec.rb
|
211
|
+
│
|
212
|
+
├── types/
|
213
|
+
│ └── <type_name>_spec.rb
|
214
|
+
│
|
215
|
+
├── type_aliases/
|
216
|
+
│ └── <type_alias_name>_spec.rb
|
217
|
+
│
|
218
|
+
└── hosts/
|
219
|
+
└── <host_name>_spec.rb
|
55
220
|
|
56
221
|
## Example groups
|
57
222
|
|
@@ -80,6 +245,10 @@ describe 'mytype', :type => :type do
|
|
80
245
|
...
|
81
246
|
end
|
82
247
|
|
248
|
+
describe 'My::TypeAlias', :type => :type_alias do
|
249
|
+
...
|
250
|
+
end
|
251
|
+
|
83
252
|
describe 'myhost.example.com', :type => :host do
|
84
253
|
...
|
85
254
|
end
|
@@ -327,6 +496,20 @@ When testing custom types, the `be_valid_type` matcher provides a range of expec
|
|
327
496
|
* `with_features(<feature_list>)`: check that the specified features are available
|
328
497
|
* `with_set_attributes(<param_value_hash>)`: check that the specified attributes are set
|
329
498
|
|
499
|
+
#### Type alias matchers
|
500
|
+
|
501
|
+
When testing type aliases, the `allow_value` and `allow_values` matchers are used to check if the
|
502
|
+
alias accepts particular values or not:
|
503
|
+
|
504
|
+
|
505
|
+
```ruby
|
506
|
+
describe 'MyModule::Shape' do
|
507
|
+
it { is_expected.to allow_value('square') }
|
508
|
+
it { is_expected.to allow_values('circle', 'triangle') }
|
509
|
+
it { is_expected.not_to allow_value('blue') }
|
510
|
+
end
|
511
|
+
```
|
512
|
+
|
330
513
|
### Writing tests
|
331
514
|
|
332
515
|
#### Basic test structure
|
@@ -449,6 +632,61 @@ end
|
|
449
632
|
Any facts you provide with `let(:facts)` in a spec will automatically be merged on top
|
450
633
|
of the default facts.
|
451
634
|
|
635
|
+
#### Specifying top-scope variables that should be available to your manifest
|
636
|
+
|
637
|
+
You can create top-scope variables much in the same way as an ENC.
|
638
|
+
|
639
|
+
|
640
|
+
```ruby
|
641
|
+
let(:node_params) { { :hostgroup => 'webservers', :rack => 'KK04', :status => 'maintenance' } }
|
642
|
+
```
|
643
|
+
|
644
|
+
You can also create a set of default top-scope variables provided to all specs in your spec_helper:
|
645
|
+
|
646
|
+
``` ruby
|
647
|
+
RSpec.configure do |c|
|
648
|
+
c.default_node_params = {
|
649
|
+
:owner => 'itprod',
|
650
|
+
:site => 'ams4',
|
651
|
+
:status => 'live'
|
652
|
+
}
|
653
|
+
end
|
654
|
+
```
|
655
|
+
|
656
|
+
**NOTE** Setting top-scope variables is not supported in Puppet < 3.0.
|
657
|
+
|
658
|
+
#### Specifying extra code to load (pre-conditions)
|
659
|
+
|
660
|
+
If the manifest being tested relies on another class or variables to be set, these can be added via
|
661
|
+
a pre-condition. This code will be evaluated before the tested class.
|
662
|
+
|
663
|
+
```ruby
|
664
|
+
let(:pre_condition) { 'include other_class' }
|
665
|
+
```
|
666
|
+
|
667
|
+
This may be useful when testing classes that are modular, e.g. testing `apache::mod::foo` which
|
668
|
+
relies on a top-level `apache` class being included first.
|
669
|
+
|
670
|
+
The value may be a raw string to be inserted into the Puppet manifest, or an array of strings
|
671
|
+
(manifest fragments) that will be concatenated.
|
672
|
+
|
673
|
+
#### Specifying extra code to load (post-conditions)
|
674
|
+
|
675
|
+
In some cases, you may need to ensure that the code that you are testing comes
|
676
|
+
**before** another set of code. Similar to the `:pre_condition` hook, you can add
|
677
|
+
a `:post_condition` hook that will ensure that the added code is evaluated
|
678
|
+
**after** the tested class.
|
679
|
+
|
680
|
+
```ruby
|
681
|
+
let(:post_condition) { 'include other_class' }
|
682
|
+
```
|
683
|
+
|
684
|
+
This may be useful when testing classes that are modular, e.g. testing class
|
685
|
+
`do_strange_things::to_the_catalog` which must come before class ``foo``.
|
686
|
+
|
687
|
+
The value may be a raw string to be inserted into the Puppet manifest, or an
|
688
|
+
array of strings (manifest fragments) that will be concatenated.
|
689
|
+
|
452
690
|
#### Specifying the path to find your modules
|
453
691
|
|
454
692
|
I recommend setting a default module path by adding the following code to your
|
@@ -466,6 +704,31 @@ However, if you want to specify it in each example, you can do so
|
|
466
704
|
let(:module_path) { '/path/to/your/module/dir' }
|
467
705
|
```
|
468
706
|
|
707
|
+
#### Specifying trusted facts
|
708
|
+
|
709
|
+
When testing with Puppet >= 4.3 the trusted facts hash will have the standard trusted fact keys
|
710
|
+
(certname, domain, and hostname) populated based on the node name (as set with `:node`).
|
711
|
+
|
712
|
+
By default, the test environment contains no custom trusted facts (as usually obtained
|
713
|
+
from certificate extensions) and found in the `extensions` key. If you need to test against
|
714
|
+
specific custom certificate extensions you can set those with a hash. The hash will then
|
715
|
+
be available in `$trusted['extensions']`
|
716
|
+
|
717
|
+
```ruby
|
718
|
+
let(:trusted_facts) { {'pp_uuid' => 'ED803750-E3C7-44F5-BB08-41A04433FE2E', '1.3.6.1.4.1.34380.1.2.1' => 'ssl-termination'} }
|
719
|
+
```
|
720
|
+
|
721
|
+
You can also create a set of default certificate extensions provided to all specs in your spec_helper:
|
722
|
+
|
723
|
+
```ruby
|
724
|
+
RSpec.configure do |c|
|
725
|
+
c.default_trusted_facts = {
|
726
|
+
'pp_uuid' => 'ED803750-E3C7-44F5-BB08-41A04433FE2E',
|
727
|
+
'1.3.6.1.4.1.34380.1.2.1' => 'ssl-termination'
|
728
|
+
}
|
729
|
+
end
|
730
|
+
```
|
731
|
+
|
469
732
|
#### Testing Exported Resources
|
470
733
|
|
471
734
|
You can test if a resource was exported from the catalogue by using the
|
@@ -584,6 +847,16 @@ it 'something' do
|
|
584
847
|
end
|
585
848
|
```
|
586
849
|
|
850
|
+
#### Passing lambdas to the function
|
851
|
+
|
852
|
+
A lambda (block) can be passed to functions that support either a required or
|
853
|
+
optional lambda by passing a block to the `with_lambda` chain method in the
|
854
|
+
`run` matcher.
|
855
|
+
|
856
|
+
```ruby
|
857
|
+
it { is_expected.to run.with_lambda { |x| x * 2 }
|
858
|
+
```
|
859
|
+
|
587
860
|
#### Testing the results of the function
|
588
861
|
|
589
862
|
You can test the result of a function (if it produces one) using either the
|
@@ -709,6 +982,9 @@ spec/fixtures/hiera/hiera.yaml
|
|
709
982
|
- common
|
710
983
|
```
|
711
984
|
|
985
|
+
**Please note:** In-module hiera data depends on having a correct metadata.json file. It is
|
986
|
+
strongly recommended that you use [metadata-json-lint](https://github.com/voxpupuli/metadata-json-lint)
|
987
|
+
to automatically check your metadata.json file before running rspec.
|
712
988
|
|
713
989
|
## Producing coverage reports
|
714
990
|
|
@@ -737,6 +1013,13 @@ RSpec.configure do |c|
|
|
737
1013
|
end
|
738
1014
|
```
|
739
1015
|
|
1016
|
+
Resources declared outside of the module being tested (i.e. forge dependencies)
|
1017
|
+
are automatically removed from the coverage report. There is one exception for
|
1018
|
+
this though: **prior to Puppet 4.6.0**, resources created by functions
|
1019
|
+
(create\_resources(), ensure\_package(), etc) did not have the required
|
1020
|
+
information in them to determine which manifest they came from and so can not
|
1021
|
+
be excluded from the coverage report.
|
1022
|
+
|
740
1023
|
## Related projects
|
741
1024
|
|
742
1025
|
* [puppetlabs_spec_helper](https://github.com/puppetlabs/puppetlabs_spec_helper): shared spec helpers to setup puppet
|
@@ -2,19 +2,8 @@ module RSpec::Puppet
|
|
2
2
|
module Adapters
|
3
3
|
|
4
4
|
class Base
|
5
|
-
# Set up all Puppet settings applicable for this Puppet version
|
6
|
-
#
|
7
|
-
# @param example_group [RSpec::Core::ExampleGroup] The RSpec context to use for local settings
|
8
|
-
# @return [void]
|
9
|
-
def setup_puppet(example_group)
|
10
|
-
settings_map.each do |puppet_setting, rspec_setting|
|
11
|
-
set_setting(example_group, puppet_setting, rspec_setting)
|
12
|
-
end
|
13
|
-
@environment_name = example_group.environment
|
14
|
-
end
|
15
|
-
|
16
|
-
# Set up a specific Puppet setting.
|
17
|
-
# configuration setting.
|
5
|
+
# Set up all Puppet settings applicable for this Puppet version as
|
6
|
+
# application defaults.
|
18
7
|
#
|
19
8
|
# Puppet setting values can be taken from the global RSpec configuration, or from the currently
|
20
9
|
# executing RSpec context. When a setting is specified both in the global configuration and in
|
@@ -48,21 +37,36 @@ module RSpec::Puppet
|
|
48
37
|
# end
|
49
38
|
#
|
50
39
|
# @param example_group [RSpec::Core::ExampleGroup] The RSpec context to use for local settings
|
51
|
-
# @param puppet_setting [Symbol] The name of the Puppet setting to configure
|
52
|
-
# @param rspec_setting [Symbol] The name of the RSpec context specific or global setting to use
|
53
40
|
# @return [void]
|
54
|
-
def
|
55
|
-
|
56
|
-
|
41
|
+
def setup_puppet(example_group)
|
42
|
+
settings = settings_map.map do |puppet_setting, rspec_setting|
|
43
|
+
[puppet_setting, get_setting(example_group, rspec_setting)]
|
44
|
+
end.flatten
|
45
|
+
default_hash = {:confdir => '/dev/null', :vardir => '/dev/null' }
|
46
|
+
if defined?(Puppet::Test::TestHelper) && Puppet::Test::TestHelper.respond_to?(:app_defaults_for_tests, true)
|
47
|
+
default_hash.merge!(Puppet::Test::TestHelper.send(:app_defaults_for_tests))
|
48
|
+
end
|
49
|
+
settings_hash = default_hash.merge(Hash[*settings])
|
50
|
+
|
51
|
+
if Puppet.settings.respond_to?(:initialize_app_defaults)
|
52
|
+
Puppet.settings.initialize_app_defaults(settings_hash)
|
57
53
|
else
|
58
|
-
|
54
|
+
# Set settings the old way for Puppet 2.x, because that's how
|
55
|
+
# they're defaulted in that version of Puppet::Test::TestHelper and
|
56
|
+
# we won't be able to override them otherwise.
|
57
|
+
settings_hash.each do |setting, value|
|
58
|
+
Puppet.settings[setting] = value
|
59
|
+
end
|
59
60
|
end
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
61
|
+
|
62
|
+
@environment_name = example_group.environment
|
63
|
+
end
|
64
|
+
|
65
|
+
def get_setting(example_group, rspec_setting)
|
66
|
+
if example_group.respond_to?(rspec_setting)
|
67
|
+
example_group.send(rspec_setting)
|
68
|
+
else
|
69
|
+
RSpec.configuration.send(rspec_setting)
|
66
70
|
end
|
67
71
|
end
|
68
72
|
|
@@ -140,11 +144,15 @@ module RSpec::Puppet
|
|
140
144
|
[:environmentpath, :environmentpath],
|
141
145
|
[:hiera_config, :hiera_config],
|
142
146
|
[:strict_variables, :strict_variables],
|
147
|
+
[:manifest, :manifest],
|
143
148
|
])
|
144
149
|
end
|
145
150
|
|
146
151
|
def catalog(node, exported)
|
147
152
|
node.environment = current_environment
|
153
|
+
# Override $::environment to workaround PUP-5835, where Puppet otherwise
|
154
|
+
# stores a symbol for the parameter
|
155
|
+
node.parameters['environment'] = current_environment.name.to_s if node.parameters['environment'] != node.parameters['environment'].to_s
|
148
156
|
super
|
149
157
|
end
|
150
158
|
|
@@ -198,15 +206,15 @@ module RSpec::Puppet
|
|
198
206
|
|
199
207
|
def self.get
|
200
208
|
[
|
201
|
-
[4.0, Adapter4X],
|
202
|
-
[3.0, Adapter3X],
|
203
|
-
[2.7, Adapter27]
|
209
|
+
['4.0', Adapter4X],
|
210
|
+
['3.0', Adapter3X],
|
211
|
+
['2.7', Adapter27]
|
204
212
|
].each do |(version, klass)|
|
205
|
-
if Puppet.version
|
213
|
+
if Puppet::Util::Package.versioncmp(Puppet.version, version) >= 0
|
206
214
|
return klass.new
|
207
215
|
end
|
208
216
|
end
|
209
|
-
raise "Puppet version #{Puppet.version
|
217
|
+
raise "Puppet version #{Puppet.version} is not supported."
|
210
218
|
end
|
211
219
|
end
|
212
220
|
end
|
@@ -1,3 +1,14 @@
|
|
1
|
+
unless defined?(RSpec::Core::NullReporter)
|
2
|
+
module RSpec::Core
|
3
|
+
class NullReporter
|
4
|
+
def self.method_missing(*)
|
5
|
+
# ignore
|
6
|
+
end
|
7
|
+
private_class_method :method_missing
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
1
12
|
module RSpec::Puppet
|
2
13
|
class Coverage
|
3
14
|
|
@@ -6,7 +17,8 @@ module RSpec::Puppet
|
|
6
17
|
class << self
|
7
18
|
extend Forwardable
|
8
19
|
def_delegators(:instance, :add, :cover!, :report!,
|
9
|
-
:filters, :add_filter, :add_from_catalog
|
20
|
+
:filters, :add_filter, :add_from_catalog,
|
21
|
+
:results)
|
10
22
|
|
11
23
|
attr_writer :instance
|
12
24
|
|
@@ -17,7 +29,7 @@ module RSpec::Puppet
|
|
17
29
|
|
18
30
|
def initialize
|
19
31
|
@collection = {}
|
20
|
-
@filters = ['Stage[main]', 'Class[Settings]', 'Class[main]']
|
32
|
+
@filters = ['Stage[main]', 'Class[Settings]', 'Class[main]', 'Node[default]']
|
21
33
|
end
|
22
34
|
|
23
35
|
def add(resource)
|
@@ -27,12 +39,21 @@ module RSpec::Puppet
|
|
27
39
|
end
|
28
40
|
|
29
41
|
def add_filter(type, title)
|
30
|
-
|
42
|
+
def capitalize_name(name)
|
43
|
+
name.split('::').map { |subtitle| subtitle.capitalize }.join('::')
|
44
|
+
end
|
45
|
+
|
46
|
+
type = capitalize_name(type)
|
47
|
+
if type == 'Class'
|
48
|
+
title = capitalize_name(title)
|
49
|
+
end
|
50
|
+
|
51
|
+
@filters << "#{type}[#{title}]"
|
31
52
|
end
|
32
53
|
|
33
54
|
# add all resources from catalog declared in module test_module
|
34
55
|
def add_from_catalog(catalog, test_module)
|
35
|
-
coverable_resources = catalog.to_a.
|
56
|
+
coverable_resources = catalog.to_a.reject { |resource| !test_module.nil? && filter_resource?(resource, test_module) }
|
36
57
|
coverable_resources.each do |resource|
|
37
58
|
add(resource)
|
38
59
|
end
|
@@ -82,8 +103,12 @@ module RSpec::Puppet
|
|
82
103
|
coverage_results = coverage_test.example("Must be at least #{coverage_desired}% of code coverage") {
|
83
104
|
expect( coverage_actual.to_f ).to be >= coverage_desired.to_f
|
84
105
|
}
|
85
|
-
coverage_test.run
|
86
|
-
passed = coverage_results.execution_result.status
|
106
|
+
coverage_test.run(RSpec::Core::NullReporter)
|
107
|
+
passed = if coverage_results.execution_result.respond_to? :status then
|
108
|
+
coverage_results.execution_result.status == :passed
|
109
|
+
else
|
110
|
+
coverage_results.execution_result[:status] == 'passed'
|
111
|
+
end
|
87
112
|
|
88
113
|
RSpec.configuration.reporter.example_failed coverage_results unless passed
|
89
114
|
else
|