Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Use puppetlabs_spec_helper to test parser functions

Without this patch applied rspec-puppet reaches deep inside of Puppet
and uses an unsupported and private interface to obtain functions and
scope instances.  This is a problem because Puppet Labs considers
internal classes such as Puppet::Parser::Scope as private and internal.

We change these classes without warning and this is a maintenance issue
for third party testing tools.

This patch fixes this maintenance problem by using the compatibility
layer implemented in the puppetlabs_spec_helper.  When we change the
internal behavior of private classes such as Puppet::Parser::Scope,
we'll update the spec helper module methods to provide a version
agnostic way to get instances of these internal objects.

As an example, a supported way to get a scope instance is:

    PuppetlabsSpec::PuppetInternals.scope

Instead of the private and unsupported method of:

    Puppet::Parser::Scope.new

This patch introduces a Gem dependency onto the puppetlabs_spec_helper
gem.
  • Loading branch information...
commit e6b88cff4f63d07c96698a220791825623a465a2 1 parent 8d4c964
Jeff McCune jeffmccune authored
Showing with 16 additions and 5 deletions.
  1. +1 −0  Gemfile
  2. +15 −5 lib/rspec-puppet/example/function_example_group.rb
1  Gemfile
View
@@ -6,3 +6,4 @@ rspecversion = ENV.key?('RSPEC_VERSION') ? "= #{ENV['RSPEC_VERSION']}" : ['>= 2.
gem 'rake'
gem 'rspec', rspecversion
gem 'puppet', puppetversion
+gem 'puppetlabs_spec_helper'
20 lib/rspec-puppet/example/function_example_group.rb
View
@@ -1,13 +1,15 @@
+require 'puppetlabs_spec_helper/puppetlabs_spec/puppet_internals'
+
module RSpec::Puppet
module FunctionExampleGroup
include RSpec::Puppet::FunctionMatchers
+ PuppetInternals = PuppetlabsSpec::PuppetInternals
def subject
function_name = self.class.top_level_description.downcase
Puppet[:modulepath] = self.respond_to?(:module_path) ? module_path : RSpec.configuration.module_path
Puppet[:libdir] = Dir["#{Puppet[:modulepath]}/*/lib"].entries.join(File::PATH_SEPARATOR)
- Puppet::Parser::Functions.autoloader.loadall
# if we specify a pre_condition, we should ensure that we compile that code
# into a catalog that is accessible from the scope where the function is called
@@ -23,20 +25,28 @@ def subject
# we need to get a compiler, b/c we can attach that to a scope
@compiler = build_compiler(nodename, facts_val)
else
- @compiler = nil
+ @compiler = PuppetInternals.compiler
end
- scope = Puppet::Parser::Scope.new(:compiler => @compiler)
+ scope = PuppetInternals.scope(:compiler => @compiler)
- scope.method "function_#{function_name}".to_sym
+ # Return the method instance for the function. This can be used with
+ # method.call
+ method = PuppetInternals.function_method(function_name, :scope => scope)
end
def compiler
@compiler
end
+
# get a compiler with an attached compiled catalog
def build_compiler(node_name, fact_values)
- compiler = Puppet::Parser::Compiler.new(Puppet::Node.new(node_name, :parameters => fact_values))
+ node_options = {
+ :name => node_name,
+ :options => { :parameters => fact_values },
+ }
+ node = PuppetInternals.node(node_options)
+ compiler = PuppetInternals.compiler(:node => node)
compiler.compile
compiler
end
Please sign in to comment.
Something went wrong with that request. Please try again.