Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Bug/2.7.x/8174 incorrect warning about deprecated scoping #673

Merged
merged 3 commits into from about 2 years ago

2 participants

Andrew Parker Jeff Weiss
Andrew Parker
Collaborator

ActiveRecord installed a parent() method that seems to have wreaked
havoc on the inheritance traversing code in the variable lookup code.
This uses a new method that achieves the same end, but doesn't rely as
much on the duck typing (responds to :parent) of the resource.

In addition tests have been added for node inheritance to ensure that
that inheritance heirarchy is followed as we expect. Also tests that
tried to fake out things and now have incorrect assumptions have been
changed to make fewer assumptions about how the system works.

Andrew Parker Fixing problem caused by activerecord
ActiveRecord installed a parent() method that seems to have wreaked
havoc on the inheritance traversing code in the variable lookup code.
This uses a new method that achieves the same end, but doesn't rely as
much on the duck typing (responds to :parent) of the resource.

In addition tests have been added for node inheritance to ensure that
that inheritance heirarchy is followed as we expect. Also tests that
tried to fake out things and now have incorrect assumptions have been
changed to make fewer assumptions about how the system works.
2d3cc63
Jeff Weiss
Owner

D'oh.. just noticed I added the comments to the commit, not the pull request... moving...

Jeff Weiss jeffweiss commented on the diff April 14, 2012
lib/puppet/parser/scope.rb
@@ -241,7 +241,7 @@ def twoscope_lookupvar(name, options = {})
241 241
     table = ephemeral?(name) ? @ephemeral.last : @symtable
242 242
     if name =~ /^(.*)::(.+)$/
243 243
       begin
244  
-        qualified_scope($1).twoscope_lookupvar($2,options.merge({:origin => nil}))
  244
+        qualified_scope($1).twoscope_lookupvar($2, options.merge({:origin => nil}))
1
Jeff Weiss Owner
jeffweiss added a note April 14, 2012

Thanks for adding the space... it drove @pcarlisle and me nuts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Jeff Weiss jeffweiss commented on the diff April 14, 2012
lib/puppet/parser/scope.rb
@@ -250,10 +250,10 @@ def twoscope_lookupvar(name, options = {})
250 250
     # If the value is present and either we are top/node scope or originating scope...
251 251
     elsif (ephemeral_include?(name) or table.include?(name)) and (compiler and self == compiler.topscope or (self.resource and self.resource.type == "Node") or self == options[:origin])
252 252
       table[name]
253  
-    elsif resource and resource.resource_type and resource.resource_type.respond_to?("parent") and parent_type = resource.resource_type.parent
  253
+    elsif resource and resource.type == "Class" and parent_type = resource.resource_type.parent
2
Jeff Weiss Owner
jeffweiss added a note April 14, 2012

Would it make sense to add some information within the resource that lets us know if it can have a scope? That way if/when we have something other than Class that has a scope, this code will work properly?

Andrew Parker Collaborator
zaphod42 added a note April 16, 2012

This is central to the issue that this bug is part of, namely how messed up how concept of scope and variable lookup is. My next task is to work out some other oddities related to scope ($::var can never refer to a var defined in a node and so there is no qualified name for those vars).

I'll have to figure out what resource actually is here in order to add anything to it :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
spec/unit/parser/functions/create_resources_spec.rb
@@ -2,18 +2,17 @@
2 2
 require 'spec_helper'
3 3
 
4 4
 describe 'function for dynamically creating resources' do
  5
+  def compile_to_catalog(string)
  6
+    Puppet[:code] = string
  7
+    Puppet::Parser::Compiler.compile(Puppet::Node.new('foonode'))
  8
+  end
1
Jeff Weiss Owner
jeffweiss added a note April 14, 2012

Does it make sense to move this to a compiler spec helper? it seems like this is valuable enough to use in other places.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
spec/unit/parser/functions/create_resources_spec.rb
((10 lines not shown))
50 44
     it 'empty hash should not cause resources to be added' do
51  
-      @scope.function_create_resources(['file', {}])
52  
-      @compiler.catalog.resources.size == 1
  45
+      catalog = compile_to_catalog("create_resources('file', {})")
  46
+      catalog.resources.size.should == 3
2
Jeff Weiss Owner
jeffweiss added a note April 14, 2012

Wait, why should the size be 3? We're creating one resource and expecting that it's not being added. That seems a bit magical.
Do we have a test that specifies that by default we expect the catalog to have 3 implicit resources? And if we do, what are they?
If we have an implicit size for the one added, I'd like to see it moved out to a var somewhere @implicit_resources_size perhaps.

Also, if we're checking size, we should have a test that checks the size of the catalog resources after one gets added, @implicit_resources_size + 1.

Andrew Parker Collaborator
zaphod42 added a note April 16, 2012

A much better assertion is that there is no File resource. Depending on some magic number just doesn't strike me as the right thing here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
added some commits April 16, 2012
Andrew Parker Cleaner test for create_resources doing nothing
Better expresses that a create_resources with an empty hash is the same
as doing nothing in the catalog at all
d67711d
Andrew Parker Removed duplication of compiling a catalog
Created a PuppetSpec::Compiler module for helping out testing things
that want to compile some code to a catalog
0d9e852
Jeff Weiss
Owner

Running spec & unit tests in minimal gemset now

Jeff Weiss
Owner

Passed w/ minimal gemset, starting full gemset tests

Jeff Weiss jeffweiss merged commit 0d9e852 into from April 16, 2012
Jeff Weiss jeffweiss closed this April 16, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 3 unique commits by 1 author.

Apr 13, 2012
Andrew Parker Fixing problem caused by activerecord
ActiveRecord installed a parent() method that seems to have wreaked
havoc on the inheritance traversing code in the variable lookup code.
This uses a new method that achieves the same end, but doesn't rely as
much on the duck typing (responds to :parent) of the resource.

In addition tests have been added for node inheritance to ensure that
that inheritance heirarchy is followed as we expect. Also tests that
tried to fake out things and now have incorrect assumptions have been
changed to make fewer assumptions about how the system works.
2d3cc63
Apr 16, 2012
Andrew Parker Cleaner test for create_resources doing nothing
Better expresses that a create_resources with an empty hash is the same
as doing nothing in the catalog at all
d67711d
Andrew Parker Removed duplication of compiling a catalog
Created a PuppetSpec::Compiler module for helping out testing things
that want to compile some code to a catalog
0d9e852
This page is out of date. Refresh to see the latest.
6  lib/puppet/parser/scope.rb
@@ -241,7 +241,7 @@ def twoscope_lookupvar(name, options = {})
241 241
     table = ephemeral?(name) ? @ephemeral.last : @symtable
242 242
     if name =~ /^(.*)::(.+)$/
243 243
       begin
244  
-        qualified_scope($1).twoscope_lookupvar($2,options.merge({:origin => nil}))
  244
+        qualified_scope($1).twoscope_lookupvar($2, options.merge({:origin => nil}))
245 245
       rescue RuntimeError => e
246 246
         location = (options[:file] && options[:line]) ? " at #{options[:file]}:#{options[:line]}" : ''
247 247
         warning "Could not look up qualified variable '#{name}'; #{e.message}#{location}"
@@ -250,10 +250,10 @@ def twoscope_lookupvar(name, options = {})
250 250
     # If the value is present and either we are top/node scope or originating scope...
251 251
     elsif (ephemeral_include?(name) or table.include?(name)) and (compiler and self == compiler.topscope or (self.resource and self.resource.type == "Node") or self == options[:origin])
252 252
       table[name]
253  
-    elsif resource and resource.resource_type and resource.resource_type.respond_to?("parent") and parent_type = resource.resource_type.parent
  253
+    elsif resource and resource.type == "Class" and parent_type = resource.resource_type.parent
254 254
       class_scope(parent_type).twoscope_lookupvar(name,options.merge({:origin => nil}))
255 255
     elsif parent
256  
-      parent.twoscope_lookupvar(name,options)
  256
+      parent.twoscope_lookupvar(name, options)
257 257
     else
258 258
       :undefined
259 259
     end
6  spec/lib/puppet_spec/compiler.rb
... ...
@@ -0,0 +1,6 @@
  1
+module PuppetSpec::Compiler
  2
+  def compile_to_catalog(string)
  3
+    Puppet[:code] = string
  4
+    Puppet::Parser::Compiler.compile(Puppet::Node.new('foonode'))
  5
+  end
  6
+end
200  spec/unit/parser/functions/create_resources_spec.rb
... ...
@@ -1,19 +1,16 @@
1 1
 require 'puppet'
2 2
 require 'spec_helper'
  3
+require 'puppet_spec/compiler'
3 4
 
4 5
 describe 'function for dynamically creating resources' do
  6
+  include PuppetSpec::Compiler
5 7
 
6  
-  def get_scope
7  
-    @topscope = Puppet::Parser::Scope.new
8  
-    # This is necessary so we don't try to use the compiler to discover our parent.
9  
-    @topscope.parent = nil
  8
+  before :each do
10 9
     @scope = Puppet::Parser::Scope.new
11 10
     @scope.compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("floppy", :environment => 'production'))
12  
-    @scope.parent = @topscope
  11
+    @topscope = @scope.compiler.topscope
13 12
     @compiler = @scope.compiler
14  
-  end
15  
-  before :each do
16  
-    get_scope
  13
+    @scope.parent = @topscope
17 14
     Puppet::Parser::Functions.function(:create_resources)
18 15
   end
19 16
 
@@ -32,6 +29,7 @@ def get_scope
32 29
       @scope.function_create_resources(['notify', {'test'=>{}}])
33 30
     end
34 31
   end
  32
+
35 33
   describe 'when the caller supplies a name parameter' do
36 34
     it 'should set the resource name to the value provided' do
37 35
       Puppet::Parser::Resource.any_instance.expects(:set_parameter).with(:name, 'user_supplied').once
@@ -41,131 +39,165 @@ def get_scope
41 39
   end
42 40
 
43 41
   describe 'when creating native types' do
44  
-    before :each do
45  
-      Puppet[:code]='notify{test:}'
46  
-      get_scope
47  
-      @scope.resource=Puppet::Parser::Resource.new('class', 't', :scope => @scope)
48  
-    end
49  
-
50 42
     it 'empty hash should not cause resources to be added' do
51  
-      @scope.function_create_resources(['file', {}])
52  
-      @compiler.catalog.resources.size == 1
  43
+      noop_catalog = compile_to_catalog("create_resources('file', {})")
  44
+      empty_catalog = compile_to_catalog("")
  45
+      noop_catalog.resources.size.should == empty_catalog.resources.size
53 46
     end
  47
+
54 48
     it 'should be able to add' do
55  
-      @scope.function_create_resources(['file', {'/etc/foo'=>{'ensure'=>'present'}}])
56  
-      @compiler.catalog.resource(:file, "/etc/foo")['ensure'].should == 'present'
  49
+      catalog = compile_to_catalog("create_resources('file', {'/etc/foo'=>{'ensure'=>'present'}})")
  50
+      catalog.resource(:file, "/etc/foo")['ensure'].should == 'present'
57 51
     end
  52
+
58 53
     it 'should accept multiple types' do
59  
-      type_hash = {}
60  
-      type_hash['foo'] = {'message' => 'one'}
61  
-      type_hash['bar'] = {'message' => 'two'}
62  
-      @scope.function_create_resources(['notify', type_hash])
63  
-      @compiler.catalog.resource(:notify, "foo")['message'].should == 'one'
64  
-      @compiler.catalog.resource(:notify, "bar")['message'].should == 'two'
  54
+      catalog = compile_to_catalog("create_resources('notify', {'foo'=>{'message'=>'one'}, 'bar'=>{'message'=>'two'}})")
  55
+      catalog.resource(:notify, "foo")['message'].should == 'one'
  56
+      catalog.resource(:notify, "bar")['message'].should == 'two'
65 57
     end
  58
+
66 59
     it 'should fail to add non-existing type' do
67 60
       expect { @scope.function_create_resources(['create-resource-foo', {}]) }.should raise_error(ArgumentError, 'could not create resource of unknown type create-resource-foo')
68 61
     end
  62
+
69 63
     it 'should be able to add edges' do
70  
-      @scope.function_create_resources(['notify', {'foo'=>{'require' => 'Notify[test]'}}])
71  
-      @scope.compiler.compile
72  
-      rg = @scope.compiler.catalog.to_ral.relationship_graph
  64
+      catalog = compile_to_catalog("notify { test: }\n create_resources('notify', {'foo'=>{'require'=>'Notify[test]'}})")
  65
+      rg = catalog.to_ral.relationship_graph
73 66
       test  = rg.vertices.find { |v| v.title == 'test' }
74 67
       foo   = rg.vertices.find { |v| v.title == 'foo' }
75 68
       test.should be
76 69
       foo.should be
77 70
       rg.path_between(test,foo).should be
78 71
     end
  72
+
79 73
     it 'should account for default values' do
80  
-      @scope.function_create_resources(['file', {'/etc/foo'=>{'ensure'=>'present'}, '/etc/baz'=>{'group'=>'food'}}, {'group' => 'bar'}])
81  
-      @compiler.catalog.resource(:file, "/etc/foo")['group'].should == 'bar'
82  
-      @compiler.catalog.resource(:file, "/etc/baz")['group'].should == 'food'
  74
+      catalog = compile_to_catalog("create_resources('file', {'/etc/foo'=>{'ensure'=>'present'}, '/etc/baz'=>{'group'=>'food'}}, {'group' => 'bar'})")
  75
+      catalog.resource(:file, "/etc/foo")['group'].should == 'bar'
  76
+      catalog.resource(:file, "/etc/baz")['group'].should == 'food'
83 77
     end
84 78
   end
85 79
   describe 'when dynamically creating resource types' do
86  
-    before :each do 
87  
-      Puppet[:code]=
88  
-'define foocreateresource($one){notify{$name: message => $one}}
89  
-notify{test:}
90  
-'
91  
-      get_scope
92  
-      @scope.resource=Puppet::Parser::Resource.new('class', 't', :scope => @scope)
93  
-      Puppet::Parser::Functions.function(:create_resources)
94  
-    end
95 80
     it 'should be able to create defined resoure types' do
96  
-      @scope.function_create_resources(['foocreateresource', {'blah'=>{'one'=>'two'}}])
97  
-      # still have to compile for this to work...
98  
-      # I am not sure if this constraint ruins the tests
99  
-      @scope.compiler.compile
100  
-      @compiler.catalog.resource(:notify, "blah")['message'].should == 'two'
  81
+      catalog = compile_to_catalog(<<-MANIFEST)
  82
+        define foocreateresource($one) {
  83
+          notify { $name: message => $one }
  84
+        }
  85
+        
  86
+        create_resources('foocreateresource', {'blah'=>{'one'=>'two'}})
  87
+      MANIFEST
  88
+      catalog.resource(:notify, "blah")['message'].should == 'two'
101 89
     end
  90
+
102 91
     it 'should fail if defines are missing params' do
103  
-      @scope.function_create_resources(['foocreateresource', {'blah'=>{}}])
104  
-      expect { @scope.compiler.compile }.should raise_error(Puppet::ParseError, 'Must pass one to Foocreateresource[blah] at line 1')
  92
+      expect { 
  93
+        compile_to_catalog(<<-MANIFEST)
  94
+          define foocreateresource($one) {
  95
+            notify { $name: message => $one }
  96
+          }
  97
+          
  98
+          create_resources('foocreateresource', {'blah'=>{}})
  99
+        MANIFEST
  100
+      }.should raise_error(Puppet::Error, 'Must pass one to Foocreateresource[blah] at line 1 on node foonode')
105 101
     end
  102
+
106 103
     it 'should be able to add multiple defines' do
107  
-      hash = {}
108  
-      hash['blah'] = {'one' => 'two'}
109  
-      hash['blaz'] = {'one' => 'three'}
110  
-      @scope.function_create_resources(['foocreateresource', hash])
111  
-      # still have to compile for this to work...
112  
-      # I am not sure if this constraint ruins the tests
113  
-      @scope.compiler.compile
114  
-      @compiler.catalog.resource(:notify, "blah")['message'].should == 'two'
115  
-      @compiler.catalog.resource(:notify, "blaz")['message'].should == 'three'
  104
+      catalog = compile_to_catalog(<<-MANIFEST)
  105
+        define foocreateresource($one) {
  106
+          notify { $name: message => $one }
  107
+        }
  108
+        
  109
+        create_resources('foocreateresource', {'blah'=>{'one'=>'two'}, 'blaz'=>{'one'=>'three'}})
  110
+      MANIFEST
  111
+
  112
+      catalog.resource(:notify, "blah")['message'].should == 'two'
  113
+      catalog.resource(:notify, "blaz")['message'].should == 'three'
116 114
     end
  115
+
117 116
     it 'should be able to add edges' do
118  
-      @scope.function_create_resources(['foocreateresource', {'blah'=>{'one'=>'two', 'require' => 'Notify[test]'}}])
119  
-      @scope.compiler.compile
120  
-      rg = @scope.compiler.catalog.to_ral.relationship_graph
  117
+      catalog = compile_to_catalog(<<-MANIFEST)
  118
+        define foocreateresource($one) {
  119
+          notify { $name: message => $one }
  120
+        }
  121
+
  122
+        notify { test: }
  123
+        
  124
+        create_resources('foocreateresource', {'blah'=>{'one'=>'two', 'require' => 'Notify[test]'}})
  125
+      MANIFEST
  126
+
  127
+      rg = catalog.to_ral.relationship_graph
121 128
       test = rg.vertices.find { |v| v.title == 'test' }
122 129
       blah = rg.vertices.find { |v| v.title == 'blah' }
123 130
       test.should be
124 131
       blah.should be
125  
-      # (Yoda speak like we do)
126 132
       rg.path_between(test,blah).should be
127  
-      @compiler.catalog.resource(:notify, "blah")['message'].should == 'two'
  133
+      catalog.resource(:notify, "blah")['message'].should == 'two'
128 134
     end
  135
+
129 136
     it 'should account for default values' do
130  
-      @scope.function_create_resources(['foocreateresource', {'blah'=>{}}, {'one' => 'two'}])
131  
-      @scope.compiler.compile
132  
-      @compiler.catalog.resource(:notify, "blah")['message'].should == 'two'
  137
+      catalog = compile_to_catalog(<<-MANIFEST)
  138
+        define foocreateresource($one) {
  139
+          notify { $name: message => $one }
  140
+        }
  141
+
  142
+        create_resources('foocreateresource', {'blah'=>{}}, {'one' => 'two'})
  143
+      MANIFEST
  144
+
  145
+      catalog.resource(:notify, "blah")['message'].should == 'two'
133 146
     end
134 147
   end
  148
+
135 149
   describe 'when creating classes' do
136  
-    before :each do
137  
-      Puppet[:code]=
138  
-'class bar($one){notify{test: message => $one}}
139  
-notify{tester:}
140  
-'
141  
-      get_scope
142  
-      @scope.resource=Puppet::Parser::Resource.new('class', 't', :scope => @scope)
143  
-      Puppet::Parser::Functions.function(:create_resources)
144  
-    end
145 150
     it 'should be able to create classes' do
146  
-      @scope.function_create_resources(['class', {'bar'=>{'one'=>'two'}}])
147  
-      @scope.compiler.compile
148  
-      @compiler.catalog.resource(:notify, "test")['message'].should == 'two'
149  
-      @compiler.catalog.resource(:class, "bar").should_not be_nil
  151
+      catalog = compile_to_catalog(<<-MANIFEST)
  152
+        class bar($one) {
  153
+          notify { test: message => $one }
  154
+        }
  155
+
  156
+        create_resources('class', {'bar'=>{'one'=>'two'}})
  157
+      MANIFEST
  158
+
  159
+      catalog.resource(:notify, "test")['message'].should == 'two'
  160
+      catalog.resource(:class, "bar").should_not be_nil
150 161
     end
  162
+
151 163
     it 'should fail to create non-existing classes' do
152  
-      expect { @scope.function_create_resources(['class', {'blah'=>{'one'=>'two'}}]) }.should raise_error(ArgumentError ,'could not find hostclass blah')
  164
+      expect {
  165
+        compile_to_catalog(<<-MANIFEST)
  166
+          create_resources('class', {'blah'=>{'one'=>'two'}})
  167
+        MANIFEST
  168
+      }.should raise_error(Puppet::Error ,'could not find hostclass blah at line 1 on node foonode')
153 169
     end
  170
+
154 171
     it 'should be able to add edges' do
155  
-      @scope.function_create_resources(['class', {'bar'=>{'one'=>'two', 'require' => 'Notify[tester]'}}])
156  
-      @scope.compiler.compile
157  
-      rg = @scope.compiler.catalog.to_ral.relationship_graph
  172
+      catalog = compile_to_catalog(<<-MANIFEST)
  173
+        class bar($one) {
  174
+          notify { test: message => $one }
  175
+        }
  176
+
  177
+        notify { tester: }
  178
+
  179
+        create_resources('class', {'bar'=>{'one'=>'two', 'require' => 'Notify[tester]'}})
  180
+      MANIFEST
  181
+
  182
+      rg = catalog.to_ral.relationship_graph
158 183
       test   = rg.vertices.find { |v| v.title == 'test' }
159 184
       tester = rg.vertices.find { |v| v.title == 'tester' }
160 185
       test.should be
161 186
       tester.should be
162 187
       rg.path_between(tester,test).should be
163 188
     end
  189
+
164 190
     it 'should account for default values' do
165  
-      @scope.function_create_resources(['class', {'bar'=>{}}, {'one' => 'two'}])
166  
-      @scope.compiler.compile
167  
-      @compiler.catalog.resource(:notify, "test")['message'].should == 'two'
168  
-      @compiler.catalog.resource(:class, "bar").should_not be_nil
  191
+      catalog = compile_to_catalog(<<-MANIFEST)
  192
+        class bar($one) {
  193
+          notify { test: message => $one }
  194
+        }
  195
+
  196
+        create_resources('class', {'bar'=>{}}, {'one' => 'two'})
  197
+      MANIFEST
  198
+
  199
+      catalog.resource(:notify, "test")['message'].should == 'two'
  200
+      catalog.resource(:class, "bar").should_not be_nil
169 201
     end
170 202
   end
171 203
 end
56  spec/unit/parser/scope_spec.rb
... ...
@@ -1,9 +1,9 @@
1 1
 #!/usr/bin/env rspec
2 2
 require 'spec_helper'
  3
+require 'puppet_spec/compiler'
3 4
 
4 5
 describe Puppet::Parser::Scope do
5 6
   before :each do
6  
-    # This is necessary so we don't try to use the compiler to discover our parent.
7 7
     @scope = Puppet::Parser::Scope.new
8 8
     @scope.compiler = Puppet::Parser::Compiler.new(Puppet::Node.new("foo"))
9 9
     @scope.source = Puppet::Resource::Type.new(:node, :foo)
@@ -215,11 +215,10 @@ def create_class_scope(name)
215 215
   end
216 216
 
217 217
   describe "when mixing inheritence and inclusion" do
218  
-    let(:catalog) { Puppet::Parser::Compiler.compile(Puppet::Node.new('foonode')) }
  218
+    include PuppetSpec::Compiler
219 219
 
220 220
     def expect_the_message_to_be(message) 
221  
-      Puppet[:code] = yield
222  
-      catalog = Puppet::Parser::Compiler.compile(Puppet::Node.new('foonode'))
  221
+      catalog = compile_to_catalog(yield)
223 222
       catalog.resource('Notify', 'something')[:message].should == message
224 223
     end
225 224
 
@@ -290,6 +289,55 @@ class baz {
290 289
         Puppet.expects(:deprecation_warning).never
291 290
       end
292 291
 
  292
+      it "finds value define in the inherited node" do
  293
+        expect_the_message_to_be('parent_msg') do <<-MANIFEST
  294
+            $var = "top_msg"
  295
+            node parent {
  296
+              $var = "parent_msg"
  297
+            }
  298
+            node default inherits parent {
  299
+              include foo
  300
+            }
  301
+            class foo {
  302
+              notify { 'something': message => $var, }
  303
+            }
  304
+          MANIFEST
  305
+        end
  306
+      end
  307
+
  308
+      it "finds top scope when the class is included before the node defines the var" do
  309
+        expect_the_message_to_be('top_msg') do <<-MANIFEST
  310
+            $var = "top_msg"
  311
+            node parent {
  312
+              include foo
  313
+            }
  314
+            node default inherits parent {
  315
+              $var = "default_msg"
  316
+            }
  317
+            class foo {
  318
+              notify { 'something': message => $var, }
  319
+            }
  320
+          MANIFEST
  321
+        end
  322
+      end
  323
+
  324
+      it "finds top scope when the class is included before the node defines the var" do
  325
+        expect_the_message_to_be('top_msg') do <<-MANIFEST
  326
+            $var = "top_msg"
  327
+            node parent {
  328
+              include foo
  329
+            }
  330
+            node default inherits parent {
  331
+              $var = "default_msg"
  332
+            }
  333
+            class foo {
  334
+              notify { 'something': message => $var, }
  335
+            }
  336
+          MANIFEST
  337
+        end
  338
+      end
  339
+
  340
+
293 341
       it "should find values in its local scope" do
294 342
         expect_the_message_to_be('local_msg') do <<-MANIFEST
295 343
             node default {
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.