rspec-puppet 2.0.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 3b7f69bbaf69b20087bd1bddd03664873dbc4c4e
4
- data.tar.gz: a8cde11764645b5d98eae77faeb74eaa88473efd
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NGRlMzY5NDE4OWNiN2Y2MTViMzE3YTA4N2MwMDJkN2FiNjljMjg1Mw==
5
+ data.tar.gz: !binary |-
6
+ MWExYmViYmQ5Y2RiN2E4ZjU2ZWRjODc1MTg4NmExN2VkYzI1ZmQxZg==
5
7
  SHA512:
6
- metadata.gz: 1814a868083211d2c3ed2066055619f2d1d89398a28b59558eebb34005f3c82cda9fcd8601933d4b04533584ac78a6e59c165b9f4ecb268631c608269fe84c28
7
- data.tar.gz: dbbb6480b731081f8776ca1da05e3ebd7a73db5ab7edf32667f3d7b18770ed910281aa934bce89d68c688df6b4d709ef516d5021a7c18011355b0b052f1ae9dc
8
+ metadata.gz: !binary |-
9
+ YzIzNjc1NzRmOTlmODU2Yjc5MGVhYTAxZTkzZjc2Mjc3Zjc5MmVhNzg2MWE1
10
+ ZDJkNDNiM2U3YWNjYTlmMTY4ZDZmYTc1NDE1MzNlZDVkNThiOWI4NDU3M2Q2
11
+ ZjJkZmMxMTJkMGU1NWYzZTUzMDRlZDY2MmFiODg0ODg2YWFiYzU=
12
+ data.tar.gz: !binary |-
13
+ MDNkNTU4MGYyNWYzZDUwYWRjM2I5MWZiMDgxYzE5NTE5YjJmYTY1NzVhYTYw
14
+ MzE0YmQxNDk2NzgzNDI1MGY3YmJmNWZjZmZlZmQwZTI2YjkyZWI1OGE3ZWY5
15
+ ZjI3Zjc3ZmQwZDI4N2Q1MDRkY2NhNDJjNmYxZmZhNzI4OGRkZjM=
@@ -0,0 +1,42 @@
1
+ # Change Log
2
+ All notable changes to this project will be documented in this file. This
3
+ project adheres to [Semantic Versioning](http://semver.org/).
4
+
5
+ ## [2.1.0] - 2015-04-21
6
+ ### Added
7
+ - Puppet 4 support
8
+ - Ability to set `environment` in a let block
9
+ - Better function failure messages
10
+
11
+ ### Fixed
12
+ - Filter fixtures from coverage reports
13
+ - Fix functions accidentally modifying rspec function arguments
14
+ - Restructured TravisCI matrix (NB: Puppet 2.6 is no longer tested)
15
+
16
+ ## [2.0.1] - 2015-03-12
17
+ ### Fixed
18
+ - Allow RSpec 2 to still be used
19
+
20
+ ## [2.0.0] - 2014-12-02
21
+ ### Changed
22
+ - `subject` is now a lambda to enable catching compilation failures.
23
+
24
+ ### Added
25
+ - Ability to use RSpec 3
26
+ - Hiera integration
27
+ - Coverage reports
28
+ - Ability to test on the future parser
29
+ - Function tests now have a catalogue
30
+ - Add array of references support to Relationship matchers `that_requires`,
31
+ `that_comes_before`, `that_notifies`, and `that_subscribes_to`
32
+
33
+ ### Fixed
34
+ - Better error messaging and handling for parameters (`nil` and friends) and
35
+ dependency cycles
36
+
37
+ ## 1.0.1 and earlier
38
+ For changelog of versions 1.0.1 and earlier, see http://rspec-puppet.com/changelog/
39
+
40
+ [2.1.0]: https://github.com/rodjek/rspec-puppet/compare/v2.0.1...v2.1.0
41
+ [2.0.1]: https://github.com/rodjek/rspec-puppet/compare/v2.0.0...v2.0.1
42
+ [2.0.0]: https://github.com/rodjek/rspec-puppet/compare/v1.0.1...v2.0.0
data/README.md CHANGED
@@ -260,6 +260,15 @@ you can specify this as follows
260
260
  let(:node) { 'testhost.example.com' }
261
261
  ```
262
262
 
263
+ #### Specifying the environment name
264
+
265
+ If the manifest you're testing expects to evaluate the environment name,
266
+ you can specify this as follows
267
+
268
+ ```ruby
269
+ let(:environment) { 'production' }
270
+ ```
271
+
263
272
  #### Specifying the facts that should be available to your manifest
264
273
 
265
274
  By default, the test environment contains no facts for your manifest to use.
@@ -14,6 +14,7 @@ rescue LoadError
14
14
  end
15
15
 
16
16
  RSpec.configure do |c|
17
+ c.add_setting :environmentpath, :default => '/etc/puppetlabs/code/environments'
17
18
  c.add_setting :module_path, :default => '/etc/puppet/modules'
18
19
  c.add_setting :manifest_dir, :default => nil
19
20
  c.add_setting :manifest, :default => nil
@@ -5,7 +5,8 @@ module RSpec::Puppet
5
5
 
6
6
  class << self
7
7
  extend Forwardable
8
- def_delegators :instance, :add, :cover!, :report!, :filters
8
+ def_delegators(:instance, :add, :cover!, :report!,
9
+ :filters, :add_filter, :add_from_catalog)
9
10
  end
10
11
 
11
12
  include Singleton
@@ -21,6 +22,41 @@ module RSpec::Puppet
21
22
  end
22
23
  end
23
24
 
25
+ def add_filter(type, title)
26
+ @filters << "#{type.capitalize}[#{title.capitalize}]"
27
+ end
28
+
29
+ # add all resources from catalog declared in module test_module
30
+ def add_from_catalog(catalog, test_module)
31
+ catalog.to_a.each do |resource|
32
+ # check filters
33
+ next if @filters.include?(resource.to_s)
34
+ if resource.type == 'Class'
35
+ # if the resource is a class, make sure the class belongs to
36
+ # module test_module
37
+ module_name = resource.title.split('::').first.downcase
38
+ next if module_name != test_module
39
+ elsif resource.file
40
+ # otherwise, the source file should be available, so make
41
+ # sure the manifest declaring the resource is in
42
+ # test_module's directory tree or the site manifest(s)
43
+ if Puppet.version.to_f >= 4.0
44
+ paths = [
45
+ (Pathname.new(Puppet[:environmentpath]) + 'fixtures' + test_module + 'manifests').to_s,
46
+ (Pathname.new(Puppet[:environmentpath]) + 'fixtures' + 'manifests' + 'site.pp').to_s
47
+ ]
48
+ else
49
+ paths = Puppet[:modulepath].split(File::PATH_SEPARATOR).map do |dir|
50
+ (Pathname.new(dir) + test_module + 'manifests').to_s
51
+ end
52
+ paths << Puppet[:manifest]
53
+ end
54
+ next unless paths.any? { |path| resource.file.include?(path) }
55
+ end
56
+ add(resource)
57
+ end
58
+ end
59
+
24
60
  def filtered?(resource)
25
61
  filters.include?(resource.to_s)
26
62
  end
@@ -11,11 +11,22 @@ module RSpec::Puppet
11
11
 
12
12
  node_name = nodename(:function)
13
13
 
14
+ if Puppet.version.to_f >= 4.0
15
+ env = Puppet::Node::Environment.create(environment, [File.join(Puppet[:environmentpath],'fixtures','modules')], File.join(Puppet[:environmentpath],'fixtures','manifests'))
16
+ loader = Puppet::Pops::Loaders.new(env)
17
+ func = loader.private_environment_loader.load(:function,function_name)
18
+ return func if func
19
+ end
20
+
14
21
  function_scope = scope(compiler, node_name)
15
22
 
16
23
  # Return the method instance for the function. This can be used with
17
24
  # method.call
18
- return nil unless Puppet::Parser::Functions.function(function_name)
25
+ if env
26
+ return nil unless Puppet::Parser::Functions.function(function_name,env)
27
+ else
28
+ return nil unless Puppet::Parser::Functions.function(function_name)
29
+ end
19
30
  FileUtils.rm_rf(vardir) if File.directory?(vardir)
20
31
  function_scope.method("function_#{function_name}".intern)
21
32
  end
@@ -92,7 +92,7 @@ module RSpec::Puppet
92
92
  end
93
93
 
94
94
  expected.keys.all? do |key|
95
- check(expected[key], actual[key.to_s])
95
+ check(expected[key], actual[key])
96
96
  end
97
97
  end
98
98
 
@@ -4,9 +4,17 @@ module RSpec::Puppet
4
4
  def matches?(func_obj)
5
5
  @func_obj = func_obj
6
6
  if @params
7
- @func = lambda { func_obj.call(@params) }
7
+ if Puppet.version.to_f >= 4.0 and ! @func_obj.respond_to?(:receiver)
8
+ @func = lambda { func_obj.call({}, *@params) }
9
+ else
10
+ @func = lambda { func_obj.call(@params) }
11
+ end
8
12
  else
9
- @func = lambda { func_obj.call }
13
+ if Puppet.version.to_f >= 4.0 and ! @func_obj.respond_to?(:receiver)
14
+ @func = lambda { func_obj.call({}) }
15
+ else
16
+ @func = lambda { func_obj.call }
17
+ end
10
18
  end
11
19
 
12
20
  unless @expected_error.nil?
@@ -15,6 +23,7 @@ module RSpec::Puppet
15
23
  @func.call
16
24
  rescue Exception => e
17
25
  @actual_error = e.class
26
+ @actual_error_message = e.to_s
18
27
  if e.is_a?(@expected_error)
19
28
  case @expected_error_message
20
29
  when nil
@@ -49,6 +58,9 @@ module RSpec::Puppet
49
58
 
50
59
  def with_params(*params)
51
60
  @params = params
61
+ # stringify immediately to protect us from the params being changed by
62
+ # the subject, e.g. with params.shift
63
+ @func_args = @params.inspect[1..-2]
52
64
  self
53
65
  end
54
66
 
@@ -95,11 +107,15 @@ module RSpec::Puppet
95
107
 
96
108
  private
97
109
  def func_name
98
- @func_name ||= @func_obj.name.to_s.gsub(/^function_/, '')
110
+ if Puppet.version.to_f >= 4.0 and ! @func_ob and ! @func_obj.respond_to?(:receiver)
111
+ @func_name ||= @func_obj.class.name
112
+ else
113
+ @func_name ||= @func_obj.name.to_s.gsub(/^function_/, '')
114
+ end
99
115
  end
100
116
 
101
117
  def func_params
102
- @func_args ||= @params.inspect[1..-2]
118
+ @func_args
103
119
  end
104
120
 
105
121
  def failure_message_generic(type, func_obj)
@@ -113,6 +129,19 @@ module RSpec::Puppet
113
129
  end
114
130
  elsif @expected_error
115
131
  message << "have raised #{@expected_error.inspect}"
132
+ if @expected_error_message
133
+ message << " matching #{@expected_error_message.inspect}"
134
+ end
135
+ if type == :should
136
+ if @actual_error
137
+ message << " instead of raising #{@actual_error.inspect}"
138
+ if @expected_error_message
139
+ message << "(#{@actual_error_message})"
140
+ end
141
+ elsif @actual_return
142
+ message << " instead of returning #{@actual_return.inspect}"
143
+ end
144
+ end
116
145
  else
117
146
  message << "have run successfully"
118
147
  end
@@ -1,4 +1,7 @@
1
1
  require 'puppet'
2
+ if Puppet.version.to_f >= 4.0
3
+ require 'puppet/pops'
4
+ end
2
5
  require 'fileutils'
3
6
 
4
7
  module RSpec::Puppet
@@ -7,37 +7,37 @@ module RSpec::Puppet
7
7
  lambda { catalogue }
8
8
  end
9
9
 
10
+ def environment
11
+ 'rp_env'
12
+ end
13
+
10
14
  def load_catalogue(type)
11
15
  vardir = setup_puppet
12
16
 
13
- if Puppet[:parser] == 'future'
14
- code = [pre_cond, test_manifest(type)].join("\n")
17
+ if Puppet.version.to_f >= 4.0 or Puppet[:parser] == 'future'
18
+ code = [pre_cond, test_manifest(type)].compact.join("\n")
15
19
  else
16
- code = [import_str, pre_cond, test_manifest(type)].join("\n")
20
+ code = [import_str, pre_cond, test_manifest(type)].compact.join("\n")
17
21
  end
18
22
 
19
23
  node_name = nodename(type)
20
24
 
21
25
  catalogue = build_catalog(node_name, facts_hash(node_name), code)
22
26
 
23
- RSpec::Puppet::Coverage.filters << "#{type.to_s.capitalize}[#{self.class.description.capitalize}]"
24
-
25
- catalogue.to_a.each do |resource|
26
- RSpec::Puppet::Coverage.add(resource)
27
- end
27
+ test_module = class_name.split('::').first
28
+ RSpec::Puppet::Coverage.add_filter(type.to_s, self.class.description)
29
+ RSpec::Puppet::Coverage.add_from_catalog(catalogue, test_module)
28
30
 
29
31
  FileUtils.rm_rf(vardir) if File.directory?(vardir)
30
32
  catalogue
31
33
  end
32
34
 
33
35
  def import_str
34
- klass_name = self.class.top_level_description.downcase
35
-
36
36
  if File.exists?(File.join(Puppet[:modulepath], 'manifests', 'init.pp'))
37
37
  path_to_manifest = File.join([
38
38
  Puppet[:modulepath],
39
39
  'manifests',
40
- klass_name.split('::')[1..-1]
40
+ class_name.split('::')[1..-1]
41
41
  ].flatten)
42
42
  import_str = [
43
43
  "import '#{Puppet[:modulepath]}/manifests/init.pp'",
@@ -54,22 +54,20 @@ module RSpec::Puppet
54
54
  end
55
55
 
56
56
  def test_manifest(type)
57
- klass_name = self.class.top_level_description.downcase
58
-
59
57
  if type == :class
60
58
  if !self.respond_to?(:params) || params == {}
61
- "include #{klass_name}"
59
+ "include #{class_name}"
62
60
  else
63
- "class { '#{klass_name}': #{param_str} }"
61
+ "class { '#{class_name}': #{param_str} }"
64
62
  end
65
63
  elsif type == :define
66
64
  if self.respond_to? :params
67
- "#{klass_name} { '#{title}': #{param_str} }"
65
+ "#{class_name} { '#{title}': #{param_str} }"
68
66
  else
69
- "#{klass_name} { '#{title}': }"
67
+ "#{class_name} { '#{title}': }"
70
68
  end
71
69
  elsif type == :host
72
- ""
70
+ nil
73
71
  end
74
72
  end
75
73
 
@@ -78,27 +76,30 @@ module RSpec::Puppet
78
76
  if [:class, :define, :function].include? type
79
77
  Puppet[:certname]
80
78
  else
81
- self.class.top_level_description.downcase
79
+ class_name
82
80
  end
83
81
  end
84
82
 
83
+ def class_name
84
+ self.class.top_level_description.downcase
85
+ end
85
86
 
86
87
  def pre_cond
87
88
  if self.respond_to?(:pre_condition) && !pre_condition.nil?
88
89
  if pre_condition.is_a? Array
89
- pre_condition.join("\n")
90
+ pre_condition.compact.join("\n")
90
91
  else
91
92
  pre_condition
92
93
  end
93
94
  else
94
- ''
95
+ nil
95
96
  end
96
97
  end
97
98
 
98
99
  def facts_hash(node)
99
100
  facts_val = {
100
101
  'clientversion' => Puppet::PUPPETVERSION,
101
- 'environment' => 'production',
102
+ 'environment' => environment,
102
103
  'hostname' => node.split('.').first,
103
104
  'fqdn' => node,
104
105
  'domain' => node.split('.', 2).last,
@@ -124,16 +125,26 @@ module RSpec::Puppet
124
125
  vardir = Dir.mktmpdir
125
126
  Puppet[:vardir] = vardir
126
127
 
127
- [
128
- [:modulepath, :module_path],
129
- [:manifestdir, :manifest_dir],
130
- [:manifest, :manifest],
131
- [:templatedir, :template_dir],
132
- [:config, :config],
133
- [:confdir, :confdir],
134
- [:hiera_config, :hiera_config],
135
- [:parser, :parser],
136
- ].each do |a, b|
128
+ if Puppet.version.to_f >= 4.0
129
+ settings = [
130
+ [:environmentpath, :environmentpath],
131
+ [:config, :config],
132
+ [:confdir, :confdir],
133
+ [:hiera_config, :hiera_config],
134
+ ]
135
+ else
136
+ settings = [
137
+ [:modulepath, :module_path],
138
+ [:manifestdir, :manifest_dir],
139
+ [:manifest, :manifest],
140
+ [:templatedir, :template_dir],
141
+ [:config, :config],
142
+ [:confdir, :confdir],
143
+ [:hiera_config, :hiera_config],
144
+ [:parser, :parser],
145
+ ]
146
+ end
147
+ settings.each do |a,b|
137
148
  value = self.respond_to?(b) ? self.send(b) : RSpec.configuration.send(b)
138
149
  begin
139
150
  Puppet[a] = value
@@ -142,6 +153,7 @@ module RSpec::Puppet
142
153
  end
143
154
  end
144
155
 
156
+ # This line is wrong. libdir should never be more than a single path
145
157
  Puppet[:libdir] = Dir["#{Puppet[:modulepath]}/*/lib"].entries.join(File::PATH_SEPARATOR)
146
158
  vardir
147
159
  end
@@ -158,6 +170,16 @@ module RSpec::Puppet
158
170
  # trying to be compatible with 2.7 as well as 2.6
159
171
  if Puppet::Resource::Catalog.respond_to? :find
160
172
  Puppet::Resource::Catalog.find(node_obj.name, :use_node => node_obj)
173
+ elsif Puppet.version.to_f >= 4.0
174
+ env = Puppet::Node::Environment.create(
175
+ environment,
176
+ [File.join(Puppet[:environmentpath],'fixtures','modules')],
177
+ File.join(Puppet[:environmentpath],'fixtures','manifests'))
178
+ loader = Puppet::Environments::Static.new(env)
179
+ Puppet.override({:environments => loader}, 'fixtures') do
180
+ node_obj.environment = env
181
+ Puppet::Resource::Catalog.indirection.find(node_obj.name, :use_node => node_obj)
182
+ end
161
183
  else
162
184
  Puppet::Resource::Catalog.indirection.find(node_obj.name, :use_node => node_obj)
163
185
  end
@@ -199,7 +221,14 @@ module RSpec::Puppet
199
221
  end
200
222
 
201
223
  def build_node(name, opts = {})
202
- node_environment = Puppet::Node::Environment.new('test')
224
+ if Puppet.version.to_f >= 4.0
225
+ node_environment = Puppet::Node::Environment.create(
226
+ environment,
227
+ [File.join(Puppet[:environmentpath],'fixtures','modules')],
228
+ File.join(Puppet[:environmentpath],'fixtures','manifests'))
229
+ else
230
+ node_environment = Puppet::Node::Environment.new(environment)
231
+ end
203
232
  opts.merge!({:environment => node_environment})
204
233
  Puppet::Node.new(name, opts)
205
234
  end
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-puppet
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Sharpe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-13 00:00:00.000000000 Z
11
+ date: 2015-04-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - ! '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - ! '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  description: RSpec tests for your Puppet manifests
@@ -31,6 +31,7 @@ executables:
31
31
  extensions: []
32
32
  extra_rdoc_files: []
33
33
  files:
34
+ - CHANGELOG.md
34
35
  - README.md
35
36
  - bin/rspec-puppet-init
36
37
  - lib/rspec-puppet.rb
@@ -61,18 +62,19 @@ require_paths:
61
62
  - lib
62
63
  required_ruby_version: !ruby/object:Gem::Requirement
63
64
  requirements:
64
- - - ">="
65
+ - - ! '>='
65
66
  - !ruby/object:Gem::Version
66
67
  version: '0'
67
68
  required_rubygems_version: !ruby/object:Gem::Requirement
68
69
  requirements:
69
- - - ">="
70
+ - - ! '>='
70
71
  - !ruby/object:Gem::Version
71
72
  version: '0'
72
73
  requirements: []
73
74
  rubyforge_project:
74
- rubygems_version: 2.2.2
75
+ rubygems_version: 2.4.5
75
76
  signing_key:
76
77
  specification_version: 4
77
78
  summary: RSpec tests for your Puppet manifests
78
79
  test_files: []
80
+ has_rdoc: