rspec-puppet 0.0.9 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|