1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
#! /usr/bin/env ruby
require 'spec_helper'
require 'puppet_spec/compiler'
describe "when using function data provider" do
include PuppetSpec::Compiler
# There is a fully configured environment in fixtures in this location
let(:environmentpath) { parent_fixture('environments') }
around(:each) do |example|
# Initialize settings to get a full compile as close as possible to a real
# environment load
Puppet.settings.initialize_global_settings
# Initialize loaders based on the environmentpath. It does not work to
# just set the setting environmentpath for some reason - this achieves the same:
# - first a loader is created, loading directory environments from the fixture (there is
# one such environment, 'production', which will be loaded since the node references this
# environment by name).
# - secondly, the created env loader is set as 'environments' in the puppet context.
#
loader = Puppet::Environments::Directories.new(environmentpath, [])
Puppet.override(:environments => loader) do
example.run
end
end
# The environment configured in the fixture has one module called 'abc'. Its class abc, includes
# a class called 'def'. This class has three parameters test1, test2, and test3 and it creates
# three notify with name set to the value of the three parameters.
#
# Since the abc class does not provide any parameter values to its def class, it attempts to
# get them from data lookup. The fixture has an environment that is configured to load data from
# a function called environment::data, this data sets test1, and test2.
# The module 'abc' is configured to get data by calling the function abc::data(), this function
# returns data for all three parameters test1-test3, now with the prefix 'module'.
#
# The result should be that the data set in the environment wins over those set in the
# module.
#
it 'gets data from module and environment functions and combines them with env having higher precedence' do
Puppet[:code] = 'include abc'
node = Puppet::Node.new("testnode", :facts => Puppet::Node::Facts.new("facts", {}), :environment => 'production')
compiler = Puppet::Parser::Compiler.new(node)
catalog = compiler.compile()
resources_created_in_fixture = ["Notify[env_test1]", "Notify[env_test2]", "Notify[module_test3]", "Notify[env_test2-ipl]"]
expect(resources_in(catalog)).to include(*resources_created_in_fixture)
end
it 'gets data from module having a puppet function delivering module data' do
Puppet[:code] = 'include xyz'
node = Puppet::Node.new("testnode", :facts => Puppet::Node::Facts.new("facts", {}), :environment => 'production')
compiler = Puppet::Parser::Compiler.new(node)
catalog = compiler.compile()
resources_created_in_fixture = ["Notify[env_test1]", "Notify[env_test2]", "Notify[module_test3]"]
expect(resources_in(catalog)).to include(*resources_created_in_fixture)
end
it 'gets data from puppet function delivering environment data' do
Puppet[:code] = <<-CODE
function environment::data() {
{ 'cls::test1' => 'env_puppet1',
'cls::test2' => 'env_puppet2'
}
}
class cls ($test1, $test2) {
notify { $test1: }
notify { $test2: }
}
include cls
CODE
node = Puppet::Node.new('testnode', :facts => Puppet::Node::Facts.new('facts', {}), :environment => 'production')
catalog = Puppet::Parser::Compiler.new(node).compile
expect(resources_in(catalog)).to include('Notify[env_puppet1]', 'Notify[env_puppet2]')
end
it 'raises an error if the environment data function does not return a hash' do
Puppet[:code] = 'include abc'
# find the loaders to patch with faulty function
node = Puppet::Node.new("testnode", :facts => Puppet::Node::Facts.new("facts", {}), :environment => 'production')
compiler = Puppet::Parser::Compiler.new(node)
loaders = compiler.loaders()
env_loader = loaders.private_environment_loader()
f = Puppet::Functions.create_function('environment::data') do
def data()
'this is not a hash'
end
end
env_loader.add_entry(:function, 'environment::data', f.new(compiler.topscope, env_loader), nil)
expect do
compiler.compile()
end.to raise_error(/Value returned from deprecated API function 'environment::data' has wrong type/)
end
it 'raises an error if the module data function does not return a hash' do
Puppet[:code] = 'include abc'
# find the loaders to patch with faulty function
node = Puppet::Node.new("testnode", :facts => Puppet::Node::Facts.new("facts", {}), :environment => 'production')
compiler = Puppet::Parser::Compiler.new(node)
loaders = compiler.loaders()
module_loader = loaders.public_loader_for_module('abc')
f = Puppet::Functions.create_function('abc::data') do
def data()
'this is not a hash'
end
end
module_loader.add_entry(:function, 'abc::data', f.new(compiler.topscope, module_loader), nil)
expect do
compiler.compile()
end.to raise_error(/Value returned from deprecated API function 'abc::data' has wrong type/)
end
def parent_fixture(dir_name)
File.absolute_path(File.join(my_fixture_dir(), "../#{dir_name}"))
end
def resources_in(catalog)
catalog.resources.map(&:ref)
end
end
|