rspec-puppet 3.0.0 → 4.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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