Skip to content

Commit 378b656

Browse files
Jeff McCunezaphod42
authored andcommitted
(PUP-3351) Evaluate ENC classes in the correct order
Without this patch classes declared from an ENC are evaluated in the wrong order. This is a problem because classes declared without parameters are evaluated prior to classes with parameters which causes an Error: Duplicate declaration when the classes with parameters are evaluated. According to the code comments for the `evaluate_node_classes` method, the expected behavior is that classes with an empty set of parameters will not conflict with classes that have declared parameters.
1 parent 766cce7 commit 378b656

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

lib/puppet/parser/compiler.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,10 @@ def evaluate_node_classes
187187
classes_without_params = @node.classes
188188
end
189189

190-
evaluate_classes(classes_without_params, @node_scope || topscope)
191-
190+
# (PUP-3351) Avoid "Duplicate declaration" errors by evaluating classes
191+
# with params prior to classes without params.
192192
evaluate_classes(classes_with_params, @node_scope || topscope)
193+
evaluate_classes(classes_without_params, @node_scope || topscope)
193194
end
194195

195196
# Evaluate each specified class in turn. If there are any classes we can't

spec/unit/parser/compiler_spec.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,36 @@ def add_resource(name, parent = nil)
422422
@compiler.catalog.should be_vertex(resource)
423423
end
424424

425+
context 'and evaluating classes declared from an ENC' do
426+
# Expected sequence of class evaluation
427+
let(:seq) { sequence('partitioned_node_classes') }
428+
# class { [c1, c0]: p1 => v1 }
429+
let(:param_classes) do
430+
{ 'c1' => { 'p1' => 'v1' }, 'c0' => { 'p1' => 'v1' } }
431+
end
432+
# include 'c2'
433+
let(:plain_classes) { { 'c2' => {} } }
434+
435+
let(:classes) { param_classes.merge(plain_classes) }
436+
437+
before :each do
438+
# Stub _except_ evaluate_node_classes
439+
compile_stub(:evaluate_node_classes)
440+
end
441+
442+
it 'then evaluates classes declared with parameters before plain classes' do
443+
@node.stubs(:classes).returns(classes)
444+
445+
[param_classes, plain_classes.keys].each do |partition|
446+
@compiler.expects(:evaluate_classes).
447+
with(partition, @compiler.topscope).
448+
in_sequence(seq)
449+
end
450+
451+
@compiler.compile
452+
end
453+
end
454+
425455
it "should fail to add resources that conflict with existing resources" do
426456
path = make_absolute("/foo")
427457
file1 = resource(:file, path)

0 commit comments

Comments
 (0)