diff --git a/lib/puppet/pops/evaluator/deferred_resolver.rb b/lib/puppet/pops/evaluator/deferred_resolver.rb index ace0400dff..27a72a7059 100644 --- a/lib/puppet/pops/evaluator/deferred_resolver.rb +++ b/lib/puppet/pops/evaluator/deferred_resolver.rb @@ -48,7 +48,10 @@ def self.resolve_and_replace(facts, catalog, environment = catalog.environment_i # # Server facts are always about the local node's version etc. # @scope.set_server_facts(node.server_facts) - resolver.resolve_futures(catalog) + # Must be wrapped in with_context_overrides to ensure global_scope is valid for Puppet-language functions + compiler.with_context_overrides do + resolver.resolve_futures(catalog) + end nil end diff --git a/spec/unit/pops/evaluator/deferred_resolver_spec.rb b/spec/unit/pops/evaluator/deferred_resolver_spec.rb index 4cb98cc798..f55c75d228 100644 --- a/spec/unit/pops/evaluator/deferred_resolver_spec.rb +++ b/spec/unit/pops/evaluator/deferred_resolver_spec.rb @@ -1,5 +1,6 @@ require 'spec_helper' require 'puppet_spec/compiler' +require 'puppet_spec/files' Puppet::Type.newtype(:test_deferred) do newparam(:name) @@ -8,8 +9,14 @@ describe Puppet::Pops::Evaluator::DeferredResolver do include PuppetSpec::Compiler + include PuppetSpec::Files - let(:environment) { Puppet::Node::Environment.create(:testing, []) } + let(:env_dir) do + dir_containing('testing', 'modules' => { + 'testmod' => { 'functions' => { 'test.pp' => 'function testmod::test($x) { "Got: ${x}" }' } } + }) + end + let(:environment) { Puppet::Node::Environment.create(:testing, [File.join(env_dir, 'modules')]) } let(:facts) { Puppet::Node::Facts.new('node.example.com') } def compile_and_resolve_catalog(code, preprocess = false) @@ -95,4 +102,14 @@ def compile_and_resolve_catalog(code, preprocess = false) resource = catalog.resource(:test_deferred, 'deferred') expect(resource.sensitive_parameters).to eq([:value]) end + + it 'resolves deferred values that call Puppet language functions' do + catalog = compile_and_resolve_catalog(<<~END, true) + notify { "deferred": + message => Deferred("testmod::test", ["hello"]) + } + END + + expect(catalog.resource(:notify, 'deferred')[:message]).to eq('Got: hello') + end end