puppet 4.6.1-x86-mingw32 → 4.6.2-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

@@ -521,7 +521,7 @@ module Puppet::Functions
521
521
  @type_parser.parse(t, loader)
522
522
  end
523
523
 
524
- if from != to
524
+ if from == 0 || from != to
525
525
  # :optional and/or :repeated parameters are present.
526
526
  mapped_types << from
527
527
  mapped_types << to
@@ -126,15 +126,12 @@ Puppet::Functions.create_function(:'defined', Puppet::Functions::InternalFunctio
126
126
  end
127
127
  when Puppet::Resource
128
128
  # Find instance of given resource type and title that is in the catalog
129
- scope.compiler.findresource(val.type, val.title)
129
+ scope.compiler.findresource(val.resource_type, val.title)
130
130
 
131
131
  when Puppet::Pops::Types::PResourceType
132
132
  raise ArgumentError, 'The given resource type is a reference to all kind of types' if val.type_name.nil?
133
- if val.title.nil?
134
- Puppet::Pops::Evaluator::Runtime3ResourceSupport.find_resource_type(scope, val.type_name)
135
- else
136
- scope.compiler.findresource(val.type_name, val.title)
137
- end
133
+ type = Puppet::Pops::Evaluator::Runtime3ResourceSupport.find_resource_type(scope, val.type_name)
134
+ val.title.nil? ? type : scope.compiler.findresource(type, val.title)
138
135
 
139
136
  when Puppet::Pops::Types::PHostClassType
140
137
  raise ArgumentError, 'The given class type is a reference to all classes' if val.class_name.nil?
@@ -17,12 +17,34 @@ class Puppet::Parser::EnvironmentCompiler < Puppet::Parser::Compiler
17
17
 
18
18
  def initialize(node, options = {})
19
19
  super
20
- add_function_overrides
20
+ @overridden_functions = {}
21
21
  end
22
22
 
23
23
  def add_function_overrides
24
- hiera_include = proc { Puppet.debug "Ignoring hiera_include() during environment catalog compilation" }
25
- loaders.puppet_system_loader.add_entry(:function, 'hiera_include', hiera_include, nil)
24
+ add_function_override('hiera_include', proc { Puppet.debug "Ignoring hiera_include() during environment catalog compilation" })
25
+ end
26
+
27
+ def add_function_override(func_name, override)
28
+ typed_name = Puppet::Pops::Loader::TypedName.new(:function, func_name)
29
+ loader = loaders.puppet_system_loader
30
+
31
+ # Remove and preserve existing entry. A `nil` is also preserved to indicate
32
+ # an override that didn't replace a loaded function.
33
+ entry = loader.get_entry(typed_name)
34
+ existing = entry.nil? ? nil : entry.value
35
+ loader.remove_entry(typed_name) unless existing.nil?
36
+ @overridden_functions[typed_name] = existing
37
+
38
+ # Add the override to the loader
39
+ loader.set_entry(typed_name, override)
40
+ end
41
+
42
+ def remove_function_overrides
43
+ loader = loaders.puppet_system_loader
44
+ @overridden_functions.each_pair do |typed_name, overridden|
45
+ loader.remove_entry(typed_name)
46
+ loader.set_entry(typed_name, overridden) unless overridden.nil?
47
+ end
26
48
  end
27
49
 
28
50
  def add_catalog_validators
@@ -32,38 +54,43 @@ class Puppet::Parser::EnvironmentCompiler < Puppet::Parser::Compiler
32
54
  end
33
55
 
34
56
  def compile
35
- Puppet.override(@context_overrides, "For compiling environment catalog #{environment.name}") do
36
- @catalog.environment_instance = environment
57
+ add_function_overrides
58
+ begin
59
+ Puppet.override(@context_overrides, "For compiling environment catalog #{environment.name}") do
60
+ @catalog.environment_instance = environment
37
61
 
38
- Puppet::Util::Profiler.profile("Env Compile: Created settings scope", [:compiler, :create_settings_scope]) { create_settings_scope }
62
+ Puppet::Util::Profiler.profile("Env Compile: Created settings scope", [:compiler, :create_settings_scope]) { create_settings_scope }
39
63
 
40
- activate_binder
64
+ activate_binder
41
65
 
42
- Puppet::Util::Profiler.profile("Env Compile: Evaluated main", [:compiler, :evaluate_main]) { evaluate_main }
66
+ Puppet::Util::Profiler.profile("Env Compile: Evaluated main", [:compiler, :evaluate_main]) { evaluate_main }
43
67
 
44
- Puppet::Util::Profiler.profile("Env Compile: Evaluated site", [:compiler, :evaluate_site]) { evaluate_site }
68
+ Puppet::Util::Profiler.profile("Env Compile: Evaluated site", [:compiler, :evaluate_site]) { evaluate_site }
45
69
 
46
- Puppet::Util::Profiler.profile("Env Compile: Evaluated application instances", [:compiler, :evaluate_applications]) { evaluate_applications }
70
+ Puppet::Util::Profiler.profile("Env Compile: Evaluated application instances", [:compiler, :evaluate_applications]) { evaluate_applications }
47
71
 
48
- Puppet::Util::Profiler.profile("Env Compile: Prune", [:compiler, :prune_catalog]) { prune_catalog }
72
+ Puppet::Util::Profiler.profile("Env Compile: Prune", [:compiler, :prune_catalog]) { prune_catalog }
49
73
 
50
- Puppet::Util::Profiler.profile("Env Compile: Validate Catalog pre-finish", [:compiler, :validate_pre_finish]) do
51
- validate_catalog(CatalogValidator::PRE_FINISH)
52
- end
74
+ Puppet::Util::Profiler.profile("Env Compile: Validate Catalog pre-finish", [:compiler, :validate_pre_finish]) do
75
+ validate_catalog(CatalogValidator::PRE_FINISH)
76
+ end
53
77
 
54
- Puppet::Util::Profiler.profile("Env Compile: Finished catalog", [:compiler, :finish_catalog]) { finish }
78
+ Puppet::Util::Profiler.profile("Env Compile: Finished catalog", [:compiler, :finish_catalog]) { finish }
55
79
 
56
- fail_on_unevaluated
80
+ fail_on_unevaluated
57
81
 
58
- Puppet::Util::Profiler.profile("Env Compile: Validate Catalog final", [:compiler, :validate_final]) do
59
- validate_catalog(CatalogValidator::FINAL)
60
- end
82
+ Puppet::Util::Profiler.profile("Env Compile: Validate Catalog final", [:compiler, :validate_final]) do
83
+ validate_catalog(CatalogValidator::FINAL)
84
+ end
61
85
 
62
- if block_given?
63
- yield @catalog
64
- else
65
- @catalog
86
+ if block_given?
87
+ yield @catalog
88
+ else
89
+ @catalog
90
+ end
66
91
  end
92
+ ensure
93
+ remove_function_overrides
67
94
  end
68
95
  end
69
96
 
@@ -77,7 +77,7 @@ class Puppet::Parser::Resource < Puppet::Resource
77
77
  elsif resource_type.nil?
78
78
  self.fail "Cannot find definition #{type}"
79
79
  else
80
- finish(false) # Call finish but do not validate
80
+ finish_evaluation() # do not finish completely (as that destroys Sensitive data)
81
81
  resource_type.evaluate_code(self)
82
82
  end
83
83
  end
@@ -94,8 +94,18 @@ class Puppet::Parser::Resource < Puppet::Resource
94
94
  end
95
95
  end
96
96
 
97
- # Do any finishing work on this object, called before evaluation or
98
- # before storage/translation. The method does nothing the second time
97
+ # Finish the evaluation by assigning defaults and scope tags
98
+ # @api private
99
+ #
100
+ def finish_evaluation
101
+ return if @evaluation_finished
102
+ add_defaults
103
+ add_scope_tags
104
+ @evaluation_finished = true
105
+ end
106
+
107
+ # Do any finishing work on this object, called before
108
+ # storage/translation. The method does nothing the second time
99
109
  # it is called on the same resource.
100
110
  #
101
111
  # @param do_validate [Boolean] true if validation should be performed
@@ -104,8 +114,7 @@ class Puppet::Parser::Resource < Puppet::Resource
104
114
  def finish(do_validate = true)
105
115
  return if finished?
106
116
  @finished = true
107
- add_defaults
108
- add_scope_tags
117
+ finish_evaluation
109
118
  replace_sensitive_data
110
119
  validate if do_validate
111
120
  end
@@ -41,8 +41,8 @@ class Closure < CallableSignature
41
41
 
42
42
  # Call closure with argument assignment by name
43
43
  def call_by_name(args_hash, enforce_parameters)
44
+ closure_scope = enclosing_scope
44
45
  if enforce_parameters
45
- closure_scope = enclosing_scope
46
46
  # Push a temporary parameter scope used while resolving the parameter defaults
47
47
  closure_scope.with_parameter_scope(closure_name, parameter_names) do |param_scope|
48
48
  # Assign all non-nil values, even those that represent non-existent paramaters.
@@ -65,7 +65,7 @@ class Closure < CallableSignature
65
65
  Types::TypeMismatchDescriber.validate_parameters(closure_name, params_struct, args_hash)
66
66
  end
67
67
 
68
- @evaluator.evaluate_block_with_bindings(enclosing_scope, args_hash, @model.body)
68
+ @evaluator.evaluate_block_with_bindings(closure_scope, args_hash, @model.body)
69
69
  end
70
70
 
71
71
  def parameters
@@ -44,7 +44,7 @@ class Puppet::Pops::Evaluator::Collectors::ExportedCollector < Puppet::Pops::Eva
44
44
  found_resources = found.map {|x| x.is_a?(Puppet::Parser::Resource) ? x : x.to_resource(@scope)}
45
45
 
46
46
  found_resources.each do |item|
47
- if existing = @scope.findresource(item.type, item.title)
47
+ if existing = @scope.findresource(item.resource_type, item.title)
48
48
  unless existing.collector_id == item.collector_id
49
49
  raise Puppet::ParseError,
50
50
  "A duplicate resource was found while collecting exported resources, with the type and title #{item.ref}"
@@ -138,8 +138,9 @@ class Runtime3Converter
138
138
  # due to Puppet::Resource's idiosyncratic behavior where some references must be
139
139
  # absolute and others cannot be.
140
140
  # Thus there is no need to call scope.resolve_type_and_titles to do dynamic lookup.
141
-
142
- Puppet::Resource.new(*catalog_type_to_split_type_title(o))
141
+ t, title = catalog_type_to_split_type_title(o)
142
+ t = Runtime3ResourceSupport.find_resource_type(scope, t) unless t == 'class' || t == 'node'
143
+ Puppet::Resource.new(t, title)
143
144
  end
144
145
  alias :convert2_PCatalogEntryType :convert_PCatalogEntryType
145
146
 
@@ -203,6 +203,7 @@ module Runtime3Support
203
203
  else
204
204
  # transform into the wonderful String representation in 3x
205
205
  type, title = Runtime3Converter.instance.catalog_type_to_split_type_title(source)
206
+ type = Runtime3ResourceSupport.find_resource_type(scope, type) unless type == 'class' || type == 'node'
206
207
  source_resource = Puppet::Resource.new(type, title)
207
208
  end
208
209
  if target.is_a?(Collectors::AbstractCollector)
@@ -211,6 +212,7 @@ module Runtime3Support
211
212
  else
212
213
  # transform into the wonderful String representation in 3x
213
214
  type, title = Runtime3Converter.instance.catalog_type_to_split_type_title(target)
215
+ type = Runtime3ResourceSupport.find_resource_type(scope, type) unless type == 'class' || type == 'node'
214
216
  target_resource = Puppet::Resource.new(type, title)
215
217
  end
216
218
  # Add the relationship to the compiler for later evaluation.
@@ -343,8 +345,9 @@ module Runtime3Support
343
345
  unless r.is_a?(Types::PResourceType) && r.type_name != 'class'
344
346
  fail(Issues::ILLEGAL_OVERRIDEN_TYPE, o, {:actual => r} )
345
347
  end
348
+ t = Runtime3ResourceSupport.find_resource_type(scope, r.type_name)
346
349
  resource = Puppet::Parser::Resource.new(
347
- r.type_name, r.title,
350
+ t, r.title,
348
351
  :parameters => evaluated_parameters,
349
352
  :file => file,
350
353
  :line => line,
@@ -82,6 +82,14 @@ class BaseLoader < Loader
82
82
  set_entry(TypedName.new(type, name), value, origin)
83
83
  end
84
84
 
85
+ # @api private
86
+ #
87
+ def remove_entry(typed_name)
88
+ unless @named_values.delete(typed_name).nil?
89
+ @last_result = nil unless @last_result.nil? || typed_name != @last_result.typed_name
90
+ end
91
+ end
92
+
85
93
  # Promotes an already created entry (typically from another loader) to this loader
86
94
  #
87
95
  # @api private
@@ -63,7 +63,7 @@ class Runtime3TypeLoader < BaseLoader
63
63
  #
64
64
  def find_impl(typed_name)
65
65
  name = typed_name.name
66
- te = StaticLoader::BUILTIN_TYPE_NAMES_LC.include?(name) ? nil : @resource_3x_loader.find(typed_name)
66
+ te = StaticLoader::BUILTIN_TYPE_NAMES_LC.include?(name) ? nil : @resource_3x_loader.load_typed(typed_name)
67
67
  if te.nil? || te.value.nil?
68
68
  # Look for Puppet::Type
69
69
  value = Puppet::Type.type(name) unless typed_name.qualified?
@@ -53,6 +53,11 @@ class ResourceTypeImpl
53
53
  )
54
54
  end
55
55
 
56
+ def eql?(other)
57
+ other.is_a?(Puppet::CompilableResourceType) && @name == other.name
58
+ end
59
+ alias == eql?
60
+
56
61
  # Compares this type against the given _other_ (type) and returns -1, 0, or +1 depending on the order.
57
62
  # @param other [Object] the object to compare against (produces nil, if not kind of Type}
58
63
  # @return [-1, 0, +1, nil] produces -1 if this type is before the given _other_ type, 0 if equals, and 1 if after.
@@ -138,7 +143,7 @@ class ResourceTypeImpl
138
143
  when 0
139
144
  # TechDebt: The case of specifying title patterns when having no name vars is unspecified behavior in puppet
140
145
  # Here it is silently ignored.
141
- []
146
+ nil
142
147
  when 1
143
148
  if @title_pattners_hash.nil?
144
149
  [ [ /(.*)/m, [ [@key_attributes.first] ] ] ]
@@ -166,6 +171,10 @@ class ResourceTypeImpl
166
171
  false
167
172
  end
168
173
 
174
+ def is_capability?
175
+ false
176
+ end
177
+
169
178
  # Answers if the parameter name is a parameter/attribute of this type
170
179
  # This is part of the Puppet::Type API
171
180
  # Check if used when compiling (it is triggered in an apply)
@@ -367,7 +367,8 @@ class Puppet::Property < Puppet::Parameter
367
367
  rescue => detail
368
368
  # Certain operations may fail, but we don't want to fail the transaction if we can
369
369
  # avoid it
370
- Puppet.log_exception(detail, "Unknown failure comparing values #{should} and #{is} using insync? on type: #{self.resource.ref} property: #{self.name}", { :level => :info })
370
+ msg = "Unknown failure using insync_values? on type: #{self.resource.ref} / property: #{self.name} to compare values #{should} and #{is}"
371
+ Puppet.info(msg)
371
372
 
372
373
  # Return nil, ie. unknown
373
374
  nil
@@ -226,12 +226,12 @@ class Puppet::Resource
226
226
 
227
227
  src.to_hash.each do |p, v|
228
228
  if v.is_a?(Puppet::Resource)
229
- v = Puppet::Resource.new(v.type, v.title)
229
+ v = v.copy_as_resource
230
230
  elsif v.is_a?(Array)
231
231
  # flatten resource references arrays
232
232
  v = v.flatten if v.flatten.find { |av| av.is_a?(Puppet::Resource) }
233
233
  v = v.collect do |av|
234
- av = Puppet::Resource.new(av.type, av.title) if av.is_a?(Puppet::Resource)
234
+ av = av.copy_as_resource if av.is_a?(Puppet::Resource)
235
235
  av
236
236
  end
237
237
  end
@@ -258,7 +258,7 @@ class Puppet::Resource
258
258
  #
259
259
  # TODO: Further optimizations should be possible as the "type juggling" is
260
260
  # not needed when the type implementation is known.
261
- #
261
+ #
262
262
  if type.is_a?(Puppet::CompilableResourceType) || type.is_a?(Puppet::Resource::Type)
263
263
  # set the resource type implementation
264
264
  self.resource_type = type
@@ -274,25 +274,27 @@ class Puppet::Resource
274
274
 
275
275
  @type, @title = self.class.type_and_title(type, title)
276
276
 
277
- if params = attributes[:parameters]
278
- extract_parameters(params)
277
+ rt = resource_type
278
+
279
+ if strict? && rt.nil?
280
+ if self.class?
281
+ raise ArgumentError, "Could not find declared class #{title}"
282
+ else
283
+ raise ArgumentError, "Invalid resource type #{type}"
284
+ end
279
285
  end
280
286
 
281
- if resource_type && resource_type.respond_to?(:deprecate_params)
282
- resource_type.deprecate_params(title, attributes[:parameters])
287
+ params = attributes[:parameters]
288
+ unless params.nil? || params.empty?
289
+ extract_parameters(params)
290
+ if rt && rt.respond_to?(:deprecate_params)
291
+ rt.deprecate_params(title, params)
292
+ end
283
293
  end
284
294
 
285
295
  tag(self.type)
286
296
  tag_if_valid(self.title)
287
297
  end
288
-
289
- if strict? and ! resource_type
290
- if self.class?
291
- raise ArgumentError, "Could not find declared class #{title}"
292
- else
293
- raise ArgumentError, "Invalid resource type #{type}"
294
- end
295
- end
296
298
  end
297
299
 
298
300
  def ref
@@ -350,15 +350,18 @@ class Puppet::Resource::Catalog < Puppet::Graph::SimpleGraph
350
350
 
351
351
  # Look a resource up by its reference (e.g., File[/etc/passwd]).
352
352
  def resource(type, title = nil)
353
- type, title = Puppet::Resource.type_and_title(type, title)
354
- title_key = [type, title.to_s]
353
+ # Retain type if it's a type
354
+ type_name = type.is_a?(Puppet::CompilableResourceType) || type.is_a?(Puppet::Resource::Type) ? type.name : type
355
+ type_name, title = Puppet::Resource.type_and_title(type_name, title)
356
+ type = type_name if type.is_a?(String)
357
+ title_key = [type_name, title.to_s]
355
358
  result = @resource_table[title_key]
356
359
  if result.nil?
357
360
  # an instance has to be created in order to construct the unique key used when
358
361
  # searching for aliases.
359
362
  unless @aliases.empty? && !Puppet[:app_management]
360
363
  res = Puppet::Resource.new(type, title, { :environment => @environment_instance })
361
- result = @resource_table[[type, res.uniqueness_key].flatten]
364
+ result = @resource_table[[type_name, res.uniqueness_key].flatten]
362
365
  end
363
366
 
364
367
  if result.nil? && Puppet[:app_management]
@@ -427,7 +427,15 @@ class Puppet::Resource::Type
427
427
  # Validate that all parameters given to the resource are correct
428
428
  # @param resource [Puppet::Resource] the resource to validate
429
429
  def validate_resource(resource)
430
- validate_resource_hash(resource, Hash[resource.parameters.map { |name, value| [name.to_s, value.value] }])
430
+ # Since Sensitive values have special encoding (in a separate parameter) an unwrapped sensitive value must be
431
+ # recreated as a Sensitive in order to perform correct type checking.
432
+ sensitives = Set.new(resource.sensitive_parameters)
433
+ validate_resource_hash(resource,
434
+ Hash[resource.parameters.map do |name, value|
435
+ value_to_validate = sensitives.include?(name) ? Puppet::Pops::Types::PSensitiveType::Sensitive.new(value.value) : value.value
436
+ [name.to_s, value_to_validate]
437
+ end
438
+ ])
431
439
  end
432
440
 
433
441
  # Check whether a given argument is valid.
@@ -71,6 +71,17 @@ Puppet::Type.newtype(:component) do
71
71
  reference.to_s
72
72
  end
73
73
 
74
+ # Overrides the default implementation to do nothing.
75
+ # This type contains data from class/define parameters, but does
76
+ # not have actual parameters or properties at the Type level. We can
77
+ # simply ignore anything flagged as sensitive here, since any
78
+ # contained resources will handle that sensitivity themselves. There
79
+ # is no risk of this information leaking into reports, since no
80
+ # Component instances survive the graph transmutation.
81
+ #
82
+ def set_sensitive_parameters(sensitive_parameters)
83
+ end
84
+
74
85
  private
75
86
 
76
87
  attr_reader :reference
@@ -7,7 +7,7 @@
7
7
 
8
8
 
9
9
  module Puppet
10
- PUPPETVERSION = '4.6.1'
10
+ PUPPETVERSION = '4.6.2'
11
11
 
12
12
  ##
13
13
  # version is a public API method intended to always provide a fast and
@@ -1,5 +1,6 @@
1
1
  require 'spec_helper'
2
2
  require 'puppet_spec/files'
3
+ require 'puppet_spec/compiler'
3
4
 
4
5
  describe "apply" do
5
6
  include PuppetSpec::Files
@@ -25,6 +26,112 @@ describe "apply" do
25
26
  expect(Puppet::FileSystem.exist?(file_to_create)).to be_truthy
26
27
  expect(File.read(file_to_create)).to eq("my stuff")
27
28
  end
29
+
30
+ context 'from environment with a pcore defined resource type' do
31
+ include PuppetSpec::Compiler
32
+
33
+ let!(:envdir) { tmpdir('environments') }
34
+ let(:env_name) { 'spec' }
35
+ let(:dir_structure) {
36
+ {
37
+ '.resource_types' => {
38
+ 'applytest.pp' => <<-CODE
39
+ Puppet::Resource::ResourceType3.new(
40
+ 'applytest',
41
+ [Puppet::Resource::Param.new(String, 'message')],
42
+ [Puppet::Resource::Param.new(String, 'name', true)])
43
+ CODE
44
+ },
45
+ 'modules' => {
46
+ 'amod' => {
47
+ 'lib' => {
48
+ 'puppet' => {
49
+ 'type' => { 'applytest.rb' => <<-CODE
50
+ Puppet::Type.newtype(:applytest) do
51
+ newproperty(:message) do
52
+ def sync
53
+ Puppet.send(@resource[:loglevel], self.should)
54
+ end
55
+
56
+ def retrieve
57
+ :absent
58
+ end
59
+
60
+ def insync?(is)
61
+ false
62
+ end
63
+
64
+ defaultto { @resource[:name] }
65
+ end
66
+
67
+ newparam(:name) do
68
+ desc "An arbitrary tag for your own reference; the name of the message."
69
+ Puppet.notice('the Puppet::Type says hello')
70
+ isnamevar
71
+ end
72
+ end
73
+ CODE
74
+ }
75
+ }
76
+ }
77
+ }
78
+ }
79
+ }
80
+ }
81
+
82
+ let(:environments) { Puppet::Environments::Directories.new(envdir, []) }
83
+ let(:env) { Puppet::Node::Environment.create(:'spec', [File.join(envdir, 'spec', 'modules')]) }
84
+ let(:node) { Puppet::Node.new('test', :environment => env) }
85
+ around(:each) do |example|
86
+ Puppet::Type.rmtype(:applytest)
87
+ Puppet[:environment] = env_name
88
+ dir_contained_in(envdir, env_name => dir_structure)
89
+ Puppet.override(:environments => environments, :current_environment => env) do
90
+ example.run
91
+ end
92
+ end
93
+
94
+ it 'does not load the pcore type' do
95
+ catalog = compile_to_catalog('applytest { "applytest was here":}', node)
96
+ apply = Puppet::Application[:apply]
97
+ apply.options[:catalog] = file_containing('manifest', catalog.to_pson)
98
+
99
+ Puppet[:environmentpath] = envdir
100
+ Puppet::Pops::Loader::Runtime3TypeLoader.any_instance.expects(:find).never
101
+ expect { apply.run }.to have_printed(/the Puppet::Type says hello.*applytest was here/m)
102
+ end
103
+
104
+ # Test just to verify that the Pcore Resource Type and not the Ruby one is produced when the catalog is produced
105
+ it 'loads pcore resource type instead of ruby resource type during compile' do
106
+ Puppet[:code] = 'applytest { "applytest was here": }'
107
+ compiler = Puppet::Parser::Compiler.new(node)
108
+ tn = Puppet::Pops::Loader::TypedName.new(:resource_type_pp, 'applytest')
109
+ rt = Puppet::Pops::Resource::ResourceTypeImpl.new('applytest', [Puppet::Pops::Resource::Param.new(String, 'message')], [Puppet::Pops::Resource::Param.new(String, 'name', true)])
110
+
111
+ compiler.loaders.runtime3_type_loader.instance_variable_get(:@resource_3x_loader).expects(:set_entry).once.with(tn, rt, is_a(String))
112
+ .returns(Puppet::Pops::Loader::Loader::NamedEntry.new(tn, rt, nil))
113
+ expect { compiler.compile }.not_to have_printed(/the Puppet::Type says hello/)
114
+ end
115
+
116
+ it "does not fail when pcore type is loaded twice" do
117
+ Puppet[:code] = 'applytest { xyz: alias => aptest }; Resource[applytest]'
118
+ compiler = Puppet::Parser::Compiler.new(node)
119
+ expect { compiler.compile }.not_to raise_error
120
+ end
121
+
122
+ it "does not load the ruby type when using function 'defined()' on a loaded resource that is missing from the catalog" do
123
+ # Ensure that the Resource[applytest,foo] is loaded'
124
+ eval_and_collect_notices('applytest { xyz: }', node)
125
+
126
+ # Ensure that:
127
+ # a) The catalog contains aliases (using a name for the abc resource ensures this)
128
+ # b) That Resource[applytest,xyz] is not defined in the catalog (although it's loaded)
129
+ # c) That this doesn't trigger a load of the Puppet::Type
130
+ notices = eval_and_collect_notices('applytest { abc: name => some_alias }; notice(defined(Resource[applytest,xyz]))', node)
131
+ expect(notices).to include('false')
132
+ expect(notices).not_to include('the Puppet::Type says hello')
133
+ end
134
+ end
28
135
  end
29
136
 
30
137
  it "applies a given file even when a directory environment is specified" do