rspec-puppet 0.0.9 → 0.1.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/README.md +118 -14
- data/lib/rspec-puppet/example.rb +5 -0
- data/lib/rspec-puppet/example/class_example_group.rb +1 -1
- data/lib/rspec-puppet/example/define_example_group.rb +1 -1
- data/lib/rspec-puppet/example/function_example_group.rb +17 -0
- data/lib/rspec-puppet/matchers.rb +1 -0
- data/lib/rspec-puppet/matchers/create_generic.rb +2 -2
- data/lib/rspec-puppet/matchers/create_resource.rb +1 -1
- data/lib/rspec-puppet/matchers/include_class.rb +1 -1
- data/lib/rspec-puppet/matchers/run.rb +76 -0
- data/rspec-puppet.gemspec +4 -1
- data/spec/functions/split_spec.rb +11 -0
- metadata +7 -4
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# RSpec tests for your Puppet manifests
|
1
|
+
# RSpec tests for your Puppet manifests & modules
|
2
2
|
|
3
3
|
## Installation
|
4
4
|
|
@@ -24,14 +24,18 @@ structure and naming convention.
|
|
24
24
|
| +-- <class_name>_spec.rb
|
25
25
|
|
|
26
26
|
+-- defines
|
27
|
+
| |
|
28
|
+
| +-- <define_name>_spec.rb
|
29
|
+
|
|
30
|
+
+-- functions
|
27
31
|
|
|
28
|
-
+-- <
|
32
|
+
+-- <function_name>_spec.rb
|
29
33
|
|
30
34
|
## Example groups
|
31
35
|
|
32
36
|
If you use the above directory structure, your examples will automatically be
|
33
|
-
placed in the correct groups and have access to the custom matchers. If you
|
34
|
-
choose not to
|
37
|
+
placed in the correct groups and have access to the custom matchers. *If you
|
38
|
+
choose not to*, you can force the examples into the required groups as follows.
|
35
39
|
|
36
40
|
```ruby
|
37
41
|
describe 'myclass', :type => :class do
|
@@ -41,11 +45,17 @@ end
|
|
41
45
|
describe 'mydefine', :type => :define do
|
42
46
|
...
|
43
47
|
end
|
48
|
+
|
49
|
+
describe 'myfunction', :type => :puppet_function do
|
50
|
+
...
|
51
|
+
end
|
44
52
|
```
|
45
53
|
|
46
|
-
##
|
54
|
+
## Defined Types & Classes
|
55
|
+
|
56
|
+
### Matchers
|
47
57
|
|
48
|
-
|
58
|
+
#### Checking if a class has been included
|
49
59
|
|
50
60
|
You can test if a class has been included in the catalogue with the
|
51
61
|
`include_class` matcher. It takes the class name as a string as its only
|
@@ -55,7 +65,7 @@ argument
|
|
55
65
|
it { should include_class('foo') }
|
56
66
|
```
|
57
67
|
|
58
|
-
|
68
|
+
#### Checking if a resource exists
|
59
69
|
|
60
70
|
You can test if a resource exists in the catalogue with the generic
|
61
71
|
`contain_<resource type>` matcher.
|
@@ -85,9 +95,9 @@ generic `without_<parameter>` chains.
|
|
85
95
|
it { should contain_file('/foo/bar').without_mode }
|
86
96
|
```
|
87
97
|
|
88
|
-
|
98
|
+
### Writing tests
|
89
99
|
|
90
|
-
|
100
|
+
#### Basic test structure
|
91
101
|
|
92
102
|
To test that
|
93
103
|
|
@@ -112,19 +122,19 @@ describe 'sysctl' do
|
|
112
122
|
end
|
113
123
|
```
|
114
124
|
|
115
|
-
|
125
|
+
#### Specifying the title of a resource
|
116
126
|
|
117
127
|
```ruby
|
118
128
|
let(:title) { 'foo' }
|
119
129
|
```
|
120
130
|
|
121
|
-
|
131
|
+
#### Specifying the parameters to pass to a resources or parametised class
|
122
132
|
|
123
133
|
```ruby
|
124
134
|
let(:params) { {:ensure => 'present', ...} }
|
125
135
|
```
|
126
136
|
|
127
|
-
|
137
|
+
#### Specifying the FQDN of the test node
|
128
138
|
|
129
139
|
If the manifest you're testing expects to run on host with a particular name,
|
130
140
|
you can specify this as follows
|
@@ -133,7 +143,7 @@ you can specify this as follows
|
|
133
143
|
let(:node) { 'testhost.example.com' }
|
134
144
|
```
|
135
145
|
|
136
|
-
|
146
|
+
#### Specifying the facts that should be available to your manifest
|
137
147
|
|
138
148
|
By default, the test environment contains no facts for your manifest to use.
|
139
149
|
You can set them with a hash
|
@@ -142,7 +152,7 @@ You can set them with a hash
|
|
142
152
|
let(:facts) { {:operatingsystem => 'Debian', :kernel => 'Linux', ...} }
|
143
153
|
```
|
144
154
|
|
145
|
-
|
155
|
+
#### Specifying the path to find your modules
|
146
156
|
|
147
157
|
I recommend setting a default module path by adding the following code to your
|
148
158
|
`spec_helper.rb`
|
@@ -158,3 +168,97 @@ However, if you want to specify it in each example, you can do so
|
|
158
168
|
```ruby
|
159
169
|
let(:module_path) { '/path/to/your/module/dir' }
|
160
170
|
```
|
171
|
+
|
172
|
+
## Functions
|
173
|
+
|
174
|
+
### Matchers
|
175
|
+
|
176
|
+
All of the standard RSpec matchers are available for you to use when testing
|
177
|
+
Puppet functions.
|
178
|
+
|
179
|
+
```ruby
|
180
|
+
it 'should be able to do something' do
|
181
|
+
subject.call('foo') == 'bar'
|
182
|
+
end
|
183
|
+
```
|
184
|
+
|
185
|
+
For your convenience though, a `run` matcher exists to provide easier to
|
186
|
+
understand test cases.
|
187
|
+
|
188
|
+
```ruby
|
189
|
+
it { should run.with_params('foo').and_return('bar') }
|
190
|
+
```
|
191
|
+
|
192
|
+
### Writing tests
|
193
|
+
|
194
|
+
#### Basic test structure
|
195
|
+
|
196
|
+
```ruby
|
197
|
+
require 'spec_helper'
|
198
|
+
|
199
|
+
describe '<function name>' do
|
200
|
+
...
|
201
|
+
end
|
202
|
+
```
|
203
|
+
|
204
|
+
#### Specifying the name of the function to test
|
205
|
+
|
206
|
+
The name of the function must be provided in the top level description, e.g.
|
207
|
+
|
208
|
+
```ruby
|
209
|
+
describe 'split' do
|
210
|
+
```
|
211
|
+
|
212
|
+
#### Specifying the arguments to pass to the function
|
213
|
+
|
214
|
+
You can specify the arguments to pass to your function during the test(s) using
|
215
|
+
either the `with_params` chain method in the `run` matcher
|
216
|
+
|
217
|
+
```ruby
|
218
|
+
it { should run.with_params('foo', 'bar', ['baz']) }
|
219
|
+
```
|
220
|
+
|
221
|
+
Or by using the `call` method on the subject directly
|
222
|
+
|
223
|
+
```ruby
|
224
|
+
it 'something' do
|
225
|
+
subject.call('foo', 'bar', ['baz'])
|
226
|
+
end
|
227
|
+
```
|
228
|
+
|
229
|
+
#### Testing the results of the function
|
230
|
+
|
231
|
+
You can test the result of a function (if it produces one) using either the
|
232
|
+
`and_returns` chain method in the `run` matcher
|
233
|
+
|
234
|
+
```ruby
|
235
|
+
it { should run.with_params('foo').and_return('bar') }
|
236
|
+
```
|
237
|
+
|
238
|
+
Or by using any of the existing RSpec matchers on the subject directly
|
239
|
+
|
240
|
+
```ruby
|
241
|
+
it 'something' do
|
242
|
+
subject.call('foo') == 'bar'
|
243
|
+
subject.call('baz').should be_an Array
|
244
|
+
end
|
245
|
+
```
|
246
|
+
|
247
|
+
#### Testing the errors thrown by the function
|
248
|
+
|
249
|
+
You can test whether the function throws an exception using either the
|
250
|
+
`and_raises_error` chain method in the `run` matcher
|
251
|
+
|
252
|
+
```ruby
|
253
|
+
it { should run.with_params('a', 'b').and_raise_error(Puppet::ParseError) }
|
254
|
+
it { should_not run.with_params('a').and_raise_error(Puppet::ParseError) }
|
255
|
+
```
|
256
|
+
|
257
|
+
Or by using the existing `raises_error` RSpec matcher
|
258
|
+
|
259
|
+
```ruby
|
260
|
+
it 'something' do
|
261
|
+
expect { subject.call('a', 'b') }.should raise_error(Puppet::ParseError)
|
262
|
+
expect { subject.call('a') }.should_not raise_error(Puppet::ParseError)
|
263
|
+
end
|
264
|
+
```
|
data/lib/rspec-puppet/example.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'rspec-puppet/support'
|
2
2
|
require 'rspec-puppet/example/define_example_group'
|
3
3
|
require 'rspec-puppet/example/class_example_group'
|
4
|
+
require 'rspec-puppet/example/function_example_group'
|
4
5
|
|
5
6
|
RSpec::configure do |c|
|
6
7
|
def c.escaped_path(*parts)
|
@@ -14,4 +15,8 @@ RSpec::configure do |c|
|
|
14
15
|
c.include RSpec::Puppet::ClassExampleGroup, :type => :class, :example_group => {
|
15
16
|
:file_path => c.escaped_path(%w[spec classes])
|
16
17
|
}
|
18
|
+
|
19
|
+
c.include RSpec::Puppet::FunctionExampleGroup, :type => :puppet_function, :example_group => {
|
20
|
+
:file_path => c.escaped_path(%w[spec functions])
|
21
|
+
}
|
17
22
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module RSpec::Puppet
|
2
|
+
module FunctionExampleGroup
|
3
|
+
include RSpec::Puppet::FunctionMatchers
|
4
|
+
|
5
|
+
def subject
|
6
|
+
function_name = self.class.top_level_description.downcase
|
7
|
+
|
8
|
+
Puppet[:modulepath] = self.respond_to?(:module_path) ? module_path : RSpec.configuration.module_path
|
9
|
+
Puppet[:libdir] = Dir["#{Puppet[:modulepath]}/*/lib"].entries.join(File::PATH_SEPARATOR)
|
10
|
+
Puppet::Parser::Functions.autoloader.loadall
|
11
|
+
|
12
|
+
scope = Puppet::Parser::Scope.new
|
13
|
+
|
14
|
+
scope.method "function_#{function_name}".to_sym
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module RSpec::Puppet
|
2
|
-
module
|
2
|
+
module ManifestMatchers
|
3
3
|
class CreateGeneric
|
4
4
|
def initialize(*args, &block)
|
5
5
|
@exp_resource_type = args.shift.to_s.gsub(/^(create|contain)_/, '')
|
@@ -76,7 +76,7 @@ module RSpec::Puppet
|
|
76
76
|
end
|
77
77
|
|
78
78
|
def method_missing(method, *args, &block)
|
79
|
-
return RSpec::Puppet::
|
79
|
+
return RSpec::Puppet::ManifestMatchers::CreateGeneric.new(method, *args, &block) if method.to_s =~ /^(create|contain)_/
|
80
80
|
super
|
81
81
|
end
|
82
82
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module RSpec::Puppet
|
2
|
+
module FunctionMatchers
|
3
|
+
extend RSpec::Matchers::DSL
|
4
|
+
|
5
|
+
matcher :run do
|
6
|
+
match do |func_obj|
|
7
|
+
if @params
|
8
|
+
@func = lambda { func_obj.call(@params) }
|
9
|
+
else
|
10
|
+
@func = lambda { func_obj.call }
|
11
|
+
end
|
12
|
+
|
13
|
+
if @expected_error
|
14
|
+
begin
|
15
|
+
@func.call
|
16
|
+
rescue @expected_error
|
17
|
+
#XXX check error string here
|
18
|
+
true
|
19
|
+
rescue
|
20
|
+
false
|
21
|
+
end
|
22
|
+
else
|
23
|
+
if @expected_return
|
24
|
+
@func.call == @expected_return
|
25
|
+
else
|
26
|
+
begin
|
27
|
+
@func.call
|
28
|
+
rescue
|
29
|
+
false
|
30
|
+
end
|
31
|
+
true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
chain :with_params do |*params|
|
37
|
+
@params = params
|
38
|
+
end
|
39
|
+
|
40
|
+
chain :and_return do |value|
|
41
|
+
@expected_return = value
|
42
|
+
end
|
43
|
+
|
44
|
+
# XXX support error string and regexp
|
45
|
+
chain :and_raise_error do |value|
|
46
|
+
@expected_error = value
|
47
|
+
end
|
48
|
+
|
49
|
+
failure_message_for_should do |func_obj|
|
50
|
+
func_name = func_obj.name.gsub(/^function_/, '')
|
51
|
+
func_params = @params.inspect[1..-2]
|
52
|
+
|
53
|
+
if @expected_return
|
54
|
+
"expected #{func_name}(#{func_params}) to have returned #{@expected_return.inspect} instead of #{@func.call.inspect}"
|
55
|
+
elsif @expected_error
|
56
|
+
"expected #{func_name}(#{func_params}) to have raised #{@expected_error.inspect}"
|
57
|
+
else
|
58
|
+
"expected #{func_name}(#{func_params}) to have run successfully"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
failure_message_for_should_not do |func_obj|
|
63
|
+
func_name = func_obj.name.gsub(/^function_/, '')
|
64
|
+
func_params = @params.inspect[1..-2]
|
65
|
+
|
66
|
+
if @expected_return
|
67
|
+
"expected #{func_name}(#{func_params}) to not have returned #{@expected_return.inspect}"
|
68
|
+
elsif @expected_error
|
69
|
+
"expected #{func_name}(#{func_params}) to not have raised #{@expected_error.inspect}"
|
70
|
+
else
|
71
|
+
"expected #{func_name}(#{func_params}) to not have run successfully"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/rspec-puppet.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'rspec-puppet'
|
3
|
-
s.version = '0.0
|
3
|
+
s.version = '0.1.0'
|
4
4
|
s.homepage = 'https://github.com/rodjek/rspec-puppet/'
|
5
5
|
s.summary = 'RSpec tests for your Puppet manifests'
|
6
6
|
s.description = 'RSpec tests for your Puppet manifests'
|
@@ -8,10 +8,12 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.files = [
|
9
9
|
'lib/rspec-puppet/example/class_example_group.rb',
|
10
10
|
'lib/rspec-puppet/example/define_example_group.rb',
|
11
|
+
'lib/rspec-puppet/example/function_example_group.rb',
|
11
12
|
'lib/rspec-puppet/example.rb',
|
12
13
|
'lib/rspec-puppet/matchers/create_generic.rb',
|
13
14
|
'lib/rspec-puppet/matchers/create_resource.rb',
|
14
15
|
'lib/rspec-puppet/matchers/include_class.rb',
|
16
|
+
'lib/rspec-puppet/matchers/run.rb',
|
15
17
|
'lib/rspec-puppet/matchers.rb',
|
16
18
|
'lib/rspec-puppet/support.rb',
|
17
19
|
'lib/rspec-puppet.rb',
|
@@ -25,6 +27,7 @@ Gem::Specification.new do |s|
|
|
25
27
|
'spec/defines/sysctl_spec.rb',
|
26
28
|
'spec/fixtures/boolean/manifests/init.pp',
|
27
29
|
'spec/fixtures/sysctl/manifests/init.pp',
|
30
|
+
'spec/functions/split_spec.rb',
|
28
31
|
'spec/spec_helper.rb',
|
29
32
|
]
|
30
33
|
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'split' do
|
4
|
+
it { should run.with_params('aoeu', 'o').and_return(['a', 'eu']) }
|
5
|
+
it { should run.with_params('foo').and_raise_error(Puppet::ParseError) }
|
6
|
+
it { should_not run.with_params('foo').and_raise_error(Puppet::DevError) }
|
7
|
+
|
8
|
+
it 'something' do
|
9
|
+
expect { subject.call('foo') }.should raise_error(Puppet::ParseError)
|
10
|
+
end
|
11
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-puppet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 0.0.9
|
10
|
+
version: 0.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Tim Sharpe
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-11-03 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: rspec
|
@@ -42,10 +42,12 @@ extra_rdoc_files: []
|
|
42
42
|
files:
|
43
43
|
- lib/rspec-puppet/example/class_example_group.rb
|
44
44
|
- lib/rspec-puppet/example/define_example_group.rb
|
45
|
+
- lib/rspec-puppet/example/function_example_group.rb
|
45
46
|
- lib/rspec-puppet/example.rb
|
46
47
|
- lib/rspec-puppet/matchers/create_generic.rb
|
47
48
|
- lib/rspec-puppet/matchers/create_resource.rb
|
48
49
|
- lib/rspec-puppet/matchers/include_class.rb
|
50
|
+
- lib/rspec-puppet/matchers/run.rb
|
49
51
|
- lib/rspec-puppet/matchers.rb
|
50
52
|
- lib/rspec-puppet/support.rb
|
51
53
|
- lib/rspec-puppet.rb
|
@@ -59,6 +61,7 @@ files:
|
|
59
61
|
- spec/defines/sysctl_spec.rb
|
60
62
|
- spec/fixtures/boolean/manifests/init.pp
|
61
63
|
- spec/fixtures/sysctl/manifests/init.pp
|
64
|
+
- spec/functions/split_spec.rb
|
62
65
|
- spec/spec_helper.rb
|
63
66
|
homepage: https://github.com/rodjek/rspec-puppet/
|
64
67
|
licenses: []
|