rspec-puppet 2.5.0 → 2.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![Build Status](https://travis-ci.org/rodjek/rspec-puppet.
|
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
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
|