rspec-puppet 3.0.0 → 4.0.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.
@@ -12,12 +12,6 @@ module RSpec::Puppet
12
12
  # executing RSpec context. When a setting is specified both in the global configuration and in
13
13
  # the example group, the setting in the example group is preferred.
14
14
  #
15
- # @example Configuring a Puppet setting from a global RSpec configuration value
16
- # RSpec.configure do |config|
17
- # config.parser = "future"
18
- # end
19
- # # => Puppet[:parser] will be future
20
- #
21
15
  # @example Configuring a Puppet setting from within an RSpec example group
22
16
  # RSpec.describe 'my_module::my_class', :type => :class do
23
17
  # let(:module_path) { "/Users/luke/modules" }
@@ -42,6 +36,19 @@ module RSpec::Puppet
42
36
  # @param example_group [RSpec::Core::ExampleGroup] The RSpec context to use for local settings
43
37
  # @return [void]
44
38
  def setup_puppet(example_group)
39
+ case RSpec.configuration.facter_implementation.to_sym
40
+ when :rspec
41
+ # Lazily instantiate FacterTestImpl here to optimize memory
42
+ # allocation, as the proc will only be called if FacterImpl is unset
43
+ set_facter_impl(proc { RSpec::Puppet::FacterTestImpl.new })
44
+ when :facter
45
+ set_facter_impl(Facter)
46
+ else
47
+ raise "Unsupported facter_implementation '#{RSpec.configuration.facter_implementation}'"
48
+ end
49
+
50
+ Puppet.runtime[:facter] = FacterImpl
51
+
45
52
  settings = settings_map.map do |puppet_setting, rspec_setting|
46
53
  [puppet_setting, get_setting(example_group, rspec_setting)]
47
54
  end.flatten
@@ -56,82 +63,14 @@ module RSpec::Puppet
56
63
  end
57
64
  end
58
65
 
59
- if Puppet.settings.respond_to?(:initialize_app_defaults)
60
- Puppet.settings.initialize_app_defaults(settings_hash)
66
+ Puppet.settings.initialize_app_defaults(settings_hash)
61
67
 
62
- # Forcefully apply the environmentpath setting instead of relying on
63
- # the application defaults as Puppet::Test::TestHelper automatically
64
- # sets this value as well, overriding our application default
65
- Puppet.settings[:environmentpath] = settings_hash[:environmentpath] if settings_hash.key?(:environmentpath)
66
- else
67
- # Set settings the old way for Puppet 2.x, because that's how
68
- # they're defaulted in that version of Puppet::Test::TestHelper and
69
- # we won't be able to override them otherwise.
70
- settings_hash.each do |setting, value|
71
- Puppet.settings[setting] = value
72
- end
73
- end
68
+ # Forcefully apply the environmentpath setting instead of relying on
69
+ # the application defaults as Puppet::Test::TestHelper automatically
70
+ # sets this value as well, overriding our application default
71
+ Puppet.settings[:environmentpath] = settings_hash[:environmentpath] if settings_hash.key?(:environmentpath)
74
72
 
75
73
  @environment_name = example_group.environment
76
- end
77
-
78
- def get_setting(example_group, rspec_setting)
79
- if example_group.respond_to?(rspec_setting)
80
- example_group.send(rspec_setting)
81
- else
82
- RSpec.configuration.send(rspec_setting)
83
- end
84
- end
85
-
86
- def catalog(node, exported)
87
- if exported
88
- # Use the compiler directly to skip the filtering done by the indirector
89
- Puppet::Parser::Compiler.compile(node).filter { |r| !r.exported? }
90
- else
91
- Puppet::Resource::Catalog.indirection.find(node.name, use_node: node)
92
- end
93
- end
94
-
95
- def current_environment
96
- Puppet::Node::Environment.new(@environment_name)
97
- end
98
-
99
- def settings_map
100
- [
101
- %i[modulepath module_path],
102
- %i[config config],
103
- %i[confdir confdir]
104
- ]
105
- end
106
-
107
- def modulepath
108
- Puppet[:modulepath].split(File::PATH_SEPARATOR)
109
- end
110
-
111
- # @return [String, nil] The path to the Puppet manifest if it is present and set, nil otherwise.
112
- def manifest
113
- Puppet[:manifest]
114
- end
115
- end
116
-
117
- class Adapter40 < Base
118
- #
119
- # @api private
120
- #
121
- # Set the FacterImpl constant to the given Facter implementation or noop
122
- # if the constant is already set. If a proc is given, it will only be
123
- # called if FacterImpl is not defined.
124
- #
125
- # @param impl [Object, Proc] An object or a proc that implements the Facter API
126
- def set_facter_impl(impl)
127
- return if defined?(FacterImpl)
128
-
129
- impl = impl.call if impl.is_a?(Proc)
130
- Object.send(:const_set, :FacterImpl, impl)
131
- end
132
-
133
- def setup_puppet(example_group)
134
- super
135
74
 
136
75
  modulepath = if (rspec_modulepath = RSpec.configuration.module_path)
137
76
  rspec_modulepath.split(File::PATH_SEPARATOR)
@@ -162,19 +101,18 @@ module RSpec::Puppet
162
101
  {
163
102
  environments: loader,
164
103
  current_environment: env,
165
- loaders: (Puppet::Pops::Loaders.new(env) if Gem::Version.new(Puppet.version) >= Gem::Version.new('6.0.0'))
104
+ loaders: Puppet::Pops::Loaders.new(env)
166
105
  },
167
106
  'Setup rspec-puppet environments'
168
107
  )
169
108
  end
170
109
 
171
- def settings_map
172
- super.push(
173
- %i[environmentpath environmentpath],
174
- %i[hiera_config hiera_config],
175
- %i[strict_variables strict_variables],
176
- %i[manifest manifest]
177
- )
110
+ def get_setting(example_group, rspec_setting)
111
+ if example_group.respond_to?(rspec_setting)
112
+ example_group.send(rspec_setting)
113
+ else
114
+ RSpec.configuration.send(rspec_setting)
115
+ end
178
116
  end
179
117
 
180
118
  def catalog(node, exported)
@@ -182,10 +120,36 @@ module RSpec::Puppet
182
120
  # Override $::environment to workaround PUP-5835, where Puppet otherwise
183
121
  # stores a symbol for the parameter
184
122
  if node.parameters['environment'] != node.parameters['environment'].to_s
185
- node.parameters['environment'] =
186
- current_environment.name.to_s
123
+ node.parameters['environment'] = current_environment.name.to_s
187
124
  end
188
- super
125
+
126
+ catalog = if exported
127
+ # Use the compiler directly to skip the filtering done by the indirector
128
+ Puppet::Parser::Compiler.compile(node).filter { |r| !r.exported? }
129
+ else
130
+ Puppet::Resource::Catalog.indirection.find(node.name, use_node: node)
131
+ end
132
+
133
+ Puppet::Pops::Evaluator::DeferredResolver.resolve_and_replace(node.facts, catalog)
134
+
135
+ catalog
136
+ end
137
+
138
+ def current_environment
139
+ Puppet::Node::Environment.new(@environment_name)
140
+ end
141
+
142
+ def settings_map
143
+ [
144
+ %i[modulepath module_path],
145
+ %i[basemodulepath basemodulepath],
146
+ %i[config config],
147
+ %i[confdir confdir],
148
+ %i[environmentpath environmentpath],
149
+ %i[hiera_config hiera_config],
150
+ %i[strict_variables strict_variables],
151
+ %i[vendormoduledir vendormoduledir]
152
+ ]
189
153
  end
190
154
 
191
155
  def current_environment
@@ -196,9 +160,6 @@ module RSpec::Puppet
196
160
  current_environment.modulepath
197
161
  end
198
162
 
199
- # Puppet 4.0 specially handles environments that don't have a manifest set, so we check for the no manifest value
200
- # and return nil when it is set.
201
- #
202
163
  # @return [String, nil] The path to the Puppet manifest if it is present and set, nil otherwise.
203
164
  def manifest
204
165
  m = current_environment.manifest
@@ -208,144 +169,25 @@ module RSpec::Puppet
208
169
  m
209
170
  end
210
171
  end
211
- end
212
-
213
- class Adapter4X < Adapter40
214
- def setup_puppet(example_group)
215
- super
216
-
217
- set_facter_impl(Facter)
218
- end
219
-
220
- def settings_map
221
- super.push(
222
- %i[trusted_server_facts trusted_server_facts]
223
- )
224
- end
225
- end
226
172
 
227
- class Adapter6X < Adapter40
228
- #
229
173
  # @api private
230
174
  #
231
- # Check to see if Facter runtime implementations are supported in the
232
- # current Puppet version
175
+ # Set the FacterImpl constant to the given Facter implementation or noop
176
+ # if the constant is already set. If a proc is given, it will only be
177
+ # called if FacterImpl is not defined.
233
178
  #
234
- # @return [Boolean] true if runtime implementations are supported
235
- def supports_facter_runtime?
236
- unless defined?(@supports_facter_runtime)
237
- begin
238
- Puppet.runtime[:facter]
239
- @supports_facter_runtime = true
240
- rescue StandardError
241
- @supports_facter_runtime = false
242
- end
243
- end
244
-
245
- @supports_facter_runtime
246
- end
247
-
248
- def setup_puppet(example_group)
249
- case RSpec.configuration.facter_implementation.to_sym
250
- when :rspec
251
- if supports_facter_runtime?
252
- # Lazily instantiate FacterTestImpl here to optimize memory
253
- # allocation, as the proc will only be called if FacterImpl is unset
254
- set_facter_impl(proc { RSpec::Puppet::FacterTestImpl.new })
255
- Puppet.runtime[:facter] = FacterImpl
256
- else
257
- warn "Facter runtime implementations are not supported in Puppet #{Puppet.version}, continuing with facter_implementation 'facter'"
258
- RSpec.configuration.facter_implementation = :facter
259
- set_facter_impl(Facter)
260
- end
261
- when :facter
262
- set_facter_impl(Facter)
263
- else
264
- raise "Unsupported facter_implementation '#{RSpec.configuration.facter_implementation}'"
265
- end
266
-
267
- super
268
- end
269
-
270
- def settings_map
271
- super.push(
272
- %i[basemodulepath basemodulepath],
273
- %i[vendormoduledir vendormoduledir]
274
- )
275
- end
276
-
277
- def catalog(node, _exported)
278
- super.tap do |c|
279
- Puppet::Pops::Evaluator::DeferredResolver.resolve_and_replace(node.facts, c)
280
- end
281
- end
282
- end
283
-
284
- class Adapter30 < Base
285
- def settings_map
286
- super.push(
287
- %i[manifestdir manifest_dir],
288
- %i[manifest manifest],
289
- %i[templatedir template_dir],
290
- %i[hiera_config hiera_config]
291
- )
292
- end
293
- end
294
-
295
- class Adapter32 < Adapter30
296
- def settings_map
297
- super.push(
298
- %i[parser parser]
299
- )
300
- end
301
- end
302
-
303
- class Adapter33 < Adapter32
304
- def settings_map
305
- super.push(
306
- %i[ordering ordering],
307
- %i[stringify_facts stringify_facts]
308
- )
309
- end
310
- end
311
-
312
- class Adapter34 < Adapter33
313
- def settings_map
314
- super.push(
315
- %i[trusted_node_data trusted_node_data]
316
- )
317
- end
318
- end
319
-
320
- class Adapter35 < Adapter34
321
- def settings_map
322
- super.push(
323
- %i[strict_variables strict_variables]
324
- )
325
- end
326
- end
179
+ # @param impl [Object, Proc] An object or a proc that implements the Facter API
180
+ def set_facter_impl(impl)
181
+ return if defined?(FacterImpl)
327
182
 
328
- class Adapter27 < Base
329
- def settings_map
330
- super.push(
331
- %i[manifestdir manifest_dir],
332
- %i[manifest manifest],
333
- %i[templatedir template_dir]
334
- )
183
+ impl = impl.call if impl.is_a?(Proc)
184
+ Object.send(:const_set, :FacterImpl, impl)
335
185
  end
336
186
  end
337
187
 
338
188
  def self.get
339
189
  [
340
- ['6.0', Adapter6X],
341
- ['4.1', Adapter4X],
342
- ['4.0', Adapter40],
343
- ['3.5', Adapter35],
344
- ['3.4', Adapter34],
345
- ['3.3', Adapter33],
346
- ['3.2', Adapter32],
347
- ['3.0', Adapter30],
348
- ['2.7', Adapter27]
190
+ ['7.11', Base]
349
191
  ].each do |(version, klass)|
350
192
  return klass.new if Puppet::Util::Package.versioncmp(Puppet.version, version) >= 0
351
193
  end
@@ -10,7 +10,7 @@ module RSpec::Puppet::Consts
10
10
  windows: {
11
11
  'File::PATH_SEPARATOR' => ';',
12
12
  'File::ALT_SEPARATOR' => '\\',
13
- 'Pathname::SEPARATOR_PAT' => /[#{Regexp.quote("\\")}#{Regexp.quote('/')}]/
13
+ 'Pathname::SEPARATOR_PAT' => /[#{Regexp.quote('\\')}#{Regexp.quote('/')}]/
14
14
  }
15
15
  }.freeze
16
16
 
@@ -88,19 +88,17 @@ module RSpec::Puppet
88
88
  with_vardir do
89
89
  env = adapter.current_environment
90
90
 
91
- if Puppet.version.to_f >= 4.0
92
- context_overrides = compiler.context_overrides
93
- func = nil
94
- loaders = Puppet.lookup(:loaders)
95
- Puppet.override(context_overrides, 'rspec-test scope') do
96
- func = V4FunctionWrapper.new(function_name,
97
- loaders.private_environment_loader.load(:function, function_name), context_overrides)
98
- @scope = context_overrides[:global_scope]
99
- end
100
-
101
- return func if func.func
91
+ context_overrides = compiler.context_overrides
92
+ func = nil
93
+ loaders = Puppet.lookup(:loaders)
94
+ Puppet.override(context_overrides, 'rspec-test scope') do
95
+ func = V4FunctionWrapper.new(function_name,
96
+ loaders.private_environment_loader.load(:function, function_name), context_overrides)
97
+ @scope = context_overrides[:global_scope]
102
98
  end
103
99
 
100
+ return func if func.func
101
+
104
102
  if Puppet::Parser::Functions.function(function_name)
105
103
  V3FunctionWrapper.new(function_name, scope.method("function_#{function_name}".intern))
106
104
  end
@@ -157,46 +155,28 @@ module RSpec::Puppet
157
155
 
158
156
  node = build_node(node_name, node_options)
159
157
 
160
- if Puppet::Util::Package.versioncmp(Puppet.version, '4.3.0') >= 0
161
- Puppet.push_context(
162
- {
163
- trusted_information: Puppet::Context::TrustedInformation.new('remote', node_name, trusted_values)
164
- },
165
- 'Context for spec trusted hash'
166
- )
167
- end
158
+ Puppet.push_context(
159
+ {
160
+ trusted_information: Puppet::Context::TrustedInformation.new('remote', node_name, trusted_values)
161
+ },
162
+ 'Context for spec trusted hash'
163
+ )
168
164
 
169
165
  compiler = Puppet::Parser::Compiler.new(node)
170
166
  compiler.compile
171
- if Puppet::Util::Package.versioncmp(Puppet.version, '4.0.0') >= 0
172
- loaders = Puppet::Pops::Loaders.new(adapter.current_environment)
173
- Puppet.push_context(
174
- {
175
- loaders: loaders,
176
- global_scope: compiler.context_overrides[:global_scope]
177
- },
178
- 'set globals'
179
- )
180
- end
167
+ loaders = Puppet::Pops::Loaders.new(adapter.current_environment)
168
+ Puppet.push_context(
169
+ {
170
+ loaders: loaders,
171
+ global_scope: compiler.context_overrides[:global_scope]
172
+ },
173
+ 'set globals'
174
+ )
181
175
  compiler
182
176
  end
183
177
 
184
- def build_scope(compiler, node_name)
185
- if Puppet.version.to_f >= 4.0
186
- return compiler.context_overrides[:global_scope]
187
- elsif /^2\.[67]/.match?(Puppet.version)
188
- # loadall should only be necessary prior to 3.x
189
- # Please note, loadall needs to happen first when creating a scope, otherwise
190
- # you might receive undefined method `function_*' errors
191
- Puppet::Parser::Functions.autoloader.loadall
192
- scope = Puppet::Parser::Scope.new(compiler: compiler)
193
- else
194
- scope = Puppet::Parser::Scope.new(compiler)
195
- end
196
-
197
- scope.source = Puppet::Resource::Type.new(:node, node_name)
198
- scope.parent = compiler.topscope
199
- scope
178
+ def build_scope(compiler, _node_name)
179
+ compiler.context_overrides[:global_scope]
200
180
  end
201
181
 
202
182
  def build_node(name, opts = {})
@@ -8,7 +8,6 @@ require 'rspec-puppet/example/host_example_group'
8
8
  require 'rspec-puppet/example/type_example_group'
9
9
  require 'rspec-puppet/example/type_alias_example_group'
10
10
  require 'rspec-puppet/example/provider_example_group'
11
- require 'rspec-puppet/example/application_example_group'
12
11
 
13
12
  RSpec.configure do |c|
14
13
  def c.rspec_puppet_include(group, type, file_path)
@@ -25,7 +24,6 @@ RSpec.configure do |c|
25
24
  c.rspec_puppet_include RSpec::Puppet::TypeExampleGroup, :type, %w[spec types]
26
25
  c.rspec_puppet_include RSpec::Puppet::TypeAliasExampleGroup, :type_alias, %w[spec type_aliases]
27
26
  c.rspec_puppet_include RSpec::Puppet::ProviderExampleGroup, :provider, %w[spec providers]
28
- c.rspec_puppet_include RSpec::Puppet::ApplicationExampleGroup, :application, %w[spec applications]
29
27
 
30
28
  # Hook for each example group type to remove any caches or instance variables, since they will remain
31
29
  # and cause a memory leak. Can't be assigned per type by :file_path, so check for its presence.
@@ -96,7 +96,7 @@ module RSpec::Puppet
96
96
  vertex.each do |param, value|
97
97
  next unless %i[require subscribe notify before].include? param
98
98
 
99
- value = Array[value] unless value.is_a? Array
99
+ value = [value] unless value.is_a? Array
100
100
  value.each do |val|
101
101
  retval = true if val.is_a?(Puppet::Resource) && !resource_exists?(val, vertex)
102
102
  end
@@ -290,7 +290,7 @@ module RSpec::Puppet
290
290
 
291
291
  visited << resource.object_id
292
292
 
293
- Array[resource[type]].flatten.compact.each do |r|
293
+ [resource[type]].flatten.compact.each do |r|
294
294
  results << canonicalize_resource_ref(r)
295
295
  results << relationship_refs(r, type, visited)
296
296
 
@@ -26,8 +26,8 @@ module RSpec::Puppet
26
26
  end
27
27
 
28
28
  module TypeMatchers
29
- def method_missing(method, *args, &block)
30
- return RSpec::Puppet::TypeMatchers::CreateGeneric.new(method, *args, &block) if method == :be_valid_type
29
+ def method_missing(method, ...)
30
+ return RSpec::Puppet::TypeMatchers::CreateGeneric.new(method, ...) if method == :be_valid_type
31
31
 
32
32
  super
33
33
  end
@@ -11,16 +11,11 @@ end
11
11
 
12
12
  class RSpec::Puppet::EventListener
13
13
  def self.example_started(example)
14
- if rspec3?
15
- @rspec_puppet_example = example.example.example_group.ancestors.include?(RSpec::Puppet::Support)
16
- @current_example = example.example
17
- if !@current_example.respond_to?(:environment) && @current_example.respond_to?(:example_group_instance)
18
- @current_example = @current_example.example_group_instance
19
- end
20
- else
21
- @rspec_puppet_example = example.example_group.ancestors.include?(RSpec::Puppet::Support)
22
- @current_example = example
23
- end
14
+ @rspec_puppet_example = example.example.example_group.ancestors.include?(RSpec::Puppet::Support)
15
+ @current_example = example.example
16
+ return unless !@current_example.respond_to?(:environment) && @current_example.respond_to?(:example_group_instance)
17
+
18
+ @current_example = @current_example.example_group_instance
24
19
  end
25
20
 
26
21
  def self.example_passed(_example)
@@ -39,12 +34,6 @@ class RSpec::Puppet::EventListener
39
34
  @rspec_puppet_example || false
40
35
  end
41
36
 
42
- def self.rspec3?
43
- @rspec3 = defined?(RSpec::Core::Notifications) if @rspec3.nil?
44
-
45
- @rspec3
46
- end
47
-
48
37
  class << self
49
38
  attr_reader :current_example
50
39
  end
@@ -267,42 +256,40 @@ module Puppet
267
256
  end
268
257
  end
269
258
 
270
- if Puppet::Util::Package.versioncmp(Puppet.version, '4.9.0') >= 0
271
- class Module
272
- old_hiera_conf_file = instance_method(:hiera_conf_file)
273
- define_method(:hiera_conf_file) do
274
- if RSpec::Puppet.rspec_puppet_example?
275
- if RSpec.configuration.disable_module_hiera
276
- return nil
277
- elsif RSpec.configuration.fixture_hiera_configs.key?(name)
278
- config = RSpec.configuration.fixture_hiera_configs[name]
279
- config = File.absolute_path(config, path) unless config.nil?
280
- return config
281
- elsif RSpec.configuration.use_fixture_spec_hiera
282
- config = RSpec::Puppet.current_example.fixture_spec_hiera_conf(self)
283
- return config unless config.nil? && RSpec.configuration.fallback_to_default_hiera
284
- end
259
+ class Module
260
+ old_hiera_conf_file = instance_method(:hiera_conf_file)
261
+ define_method(:hiera_conf_file) do
262
+ if RSpec::Puppet.rspec_puppet_example?
263
+ if RSpec.configuration.disable_module_hiera
264
+ return nil
265
+ elsif RSpec.configuration.fixture_hiera_configs.key?(name)
266
+ config = RSpec.configuration.fixture_hiera_configs[name]
267
+ config = File.absolute_path(config, path) unless config.nil?
268
+ return config
269
+ elsif RSpec.configuration.use_fixture_spec_hiera
270
+ config = RSpec::Puppet.current_example.fixture_spec_hiera_conf(self)
271
+ return config unless config.nil? && RSpec.configuration.fallback_to_default_hiera
285
272
  end
286
- old_hiera_conf_file.bind_call(self)
287
273
  end
274
+ old_hiera_conf_file.bind_call(self)
288
275
  end
276
+ end
289
277
 
290
- class Pops::Lookup::ModuleDataProvider
291
- old_configuration_path = instance_method(:configuration_path)
292
- define_method(:configuration_path) do |lookup_invocation|
293
- if RSpec::Puppet.rspec_puppet_example?
294
- env = lookup_invocation.scope.environment
295
- mod = env.module(module_name)
296
- unless mod
297
- raise Puppet::DataBinding::LookupError,
298
- format(_("Environment '%<env>s', cannot find module '%<module_name>s'"), env: env.name,
299
- module_name: module_name)
300
- end
301
-
302
- return Pathname.new(mod.hiera_conf_file)
278
+ class Pops::Lookup::ModuleDataProvider
279
+ old_configuration_path = instance_method(:configuration_path)
280
+ define_method(:configuration_path) do |lookup_invocation|
281
+ if RSpec::Puppet.rspec_puppet_example?
282
+ env = lookup_invocation.scope.environment
283
+ mod = env.module(module_name)
284
+ unless mod
285
+ raise Puppet::DataBinding::LookupError,
286
+ format(_("Environment '%<env>s', cannot find module '%<module_name>s'"), env: env.name,
287
+ module_name: module_name)
303
288
  end
304
- old_configuration_path.bind_call(self, lookup_invocation)
289
+
290
+ return Pathname.new(mod.hiera_conf_file)
305
291
  end
292
+ old_configuration_path.bind_call(self, lookup_invocation)
306
293
  end
307
294
  end
308
295
  end