Skip to content

Commit 65bcabd

Browse files
committed
(PUP-11725) Turn on strict mode by default
To start moving towards enabling strict mode by default, in PUP-11689 strict_variables was turned on. This commit continues that by setting strict to default to error instead of warning. Additionally, rspec tests that failed after the change were updated. I came across some unexpected behavior after setting strict to error so I set those tests to pending and created a ticket, PUP-11751, so those could be looked into later.
1 parent fa0250e commit 65bcabd

21 files changed

+151
-57
lines changed

Diff for: lib/puppet/defaults.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ def self.initialize_default_settings!(settings)
188188
",
189189
},
190190
:strict => {
191-
:default => :warning,
191+
:default => :error,
192192
:type => :symbolic_enum,
193193
:values => [:off, :warning, :error],
194194
:desc => "The strictness level of puppet. Allowed values are:

Diff for: spec/integration/application/apply_spec.rb

+20
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ class mod {
203203
end
204204

205205
it 'can apply the catalog' do
206+
Puppet[:strict] = :warning
206207
catalog = compile_to_catalog('include mod', node)
207208

208209
Puppet[:environment] = env_name
@@ -212,6 +213,20 @@ class mod {
212213
apply.run
213214
}.to output(%r{Notify\[The Street 23\]/message: defined 'message' as 'The Street 23'}).to_stdout
214215
end
216+
217+
it 'can apply the catalog with no warning' do
218+
pending("See PUP-11751")
219+
Puppet[:strict] = :warning
220+
logs = []
221+
Puppet::Util::Log.with_destination(Puppet::Test::LogCollector.new(logs)) do
222+
catalog = compile_to_catalog('include mod', node)
223+
Puppet[:environment] = env_name
224+
apply.command_line.args = ['--catalog', file_containing('manifest', catalog.to_json)]
225+
apply.run
226+
end
227+
# expected to have no warnings
228+
expect(logs.select { |log| log.level == :warning }.map { |log| log.message }).to be_empty
229+
end
215230
end
216231

217232
it "raises if the environment directory does not exist" do
@@ -438,6 +453,11 @@ def bogus()
438453
end
439454

440455
context 'and the file is not serialized with rich_data' do
456+
# do not want to stub out behavior in tests
457+
before :each do
458+
Puppet[:strict] = :warning
459+
end
460+
441461
it 'will notify a string that is the result of Regexp#inspect (from Runtime3xConverter)' do
442462
catalog = compile_to_catalog(execute, node)
443463
apply.command_line.args = ['--catalog', file_containing('manifest', catalog.to_json)]

Diff for: spec/integration/parser/compiler_spec.rb

+5-5
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ class c inherits b { notify { hi: } }
158158
it 'makes $settings::strict available as string' do
159159
node = Puppet::Node.new("testing")
160160
catalog = compile_to_catalog(<<-MANIFEST, node)
161-
notify { 'test': message => $settings::strict == 'warning' }
161+
notify { 'test': message => $settings::strict == 'error' }
162162
MANIFEST
163163
expect(catalog).to have_resource("Notify[test]").with_parameter(:message, true)
164164
end
@@ -174,7 +174,7 @@ class c inherits b { notify { hi: } }
174174
it 'makes all server settings available as $settings::all_local hash' do
175175
node = Puppet::Node.new("testing")
176176
catalog = compile_to_catalog(<<-MANIFEST, node)
177-
notify { 'test': message => $settings::all_local['strict'] == 'warning' }
177+
notify { 'test': message => $settings::all_local['strict'] == 'error' }
178178
MANIFEST
179179
expect(catalog).to have_resource("Notify[test]").with_parameter(:message, true)
180180
end
@@ -694,7 +694,7 @@ class a { $_a = 10}
694694
end
695695

696696
it 'a missing variable as default causes an evaluation error' do
697-
# when strict variables not on
697+
# strict mode on by default for 8.x
698698
expect {
699699
compile_to_catalog(<<-MANIFEST)
700700
class a ($b=$x) { notify {test: message=>"yes ${undef == $b}" } }
@@ -703,9 +703,9 @@ class a ($b=$x) { notify {test: message=>"yes ${undef == $b}" } }
703703
}.to raise_error(/Evaluation Error: Unknown variable: 'x'/)
704704
end
705705

706-
it 'a missing variable as default value becomes undef when strict_variables is off' do
707-
# strict variables on by default for 8.x
706+
it 'a missing variable as default value becomes undef when strict mode is off' do
708707
Puppet[:strict_variables] = false
708+
Puppet[:strict] = :warning
709709
catalog = compile_to_catalog(<<-MANIFEST)
710710
class a ($b=$x) { notify {test: message=>"yes ${undef == $b}" } }
711711
include a

Diff for: spec/integration/parser/conditionals_spec.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,9 @@
6868
end
6969

7070
it "evaluates undefined variables as false" do
71-
# strict_variables is off so behavior this test is trying to check isn't stubbed out
71+
# strict mode is off so behavior this test is trying to check isn't stubbed out
7272
Puppet[:strict_variables] = false
73+
Puppet[:strict] = :warning
7374
catalog = compile_to_catalog(<<-CODE)
7475
if $undef_var {
7576
} else {

Diff for: spec/integration/parser/scope_spec.rb

+4-2
Original file line numberDiff line numberDiff line change
@@ -276,8 +276,9 @@ class a inherits parent { }
276276

277277
['a:.b', '::a::b'].each do |ref|
278278
it "does not resolve a qualified name on the form #{ref} against top scope" do
279-
# strict_variables is off so behavior this test is trying to check isn't stubbed out
279+
# strict mode is off so behavior this test is trying to check isn't stubbed out
280280
Puppet[:strict_variables] = false
281+
Puppet[:strict] = :warning
281282
expect_the_message_not_to_be("from topscope") do <<-"MANIFEST"
282283
class c {
283284
notify { 'something': message => "$#{ref}" }
@@ -299,8 +300,9 @@ class a inherits parent { }
299300

300301
['a:.b', '::a::b'].each do |ref|
301302
it "does not resolve a qualified name on the form #{ref} against node scope" do
302-
# strict_variables is off so behavior this test is trying to check isn't stubbed out
303+
# strict mode is off so behavior this test is trying to check isn't stubbed out
303304
Puppet[:strict_variables] = false
305+
Puppet[:strict] = :warning
304306
expect_the_message_not_to_be("from node") do <<-MANIFEST
305307
class c {
306308
notify { 'something': message => "$a::b" }

Diff for: spec/unit/application/lookup_spec.rb

+5-1
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,9 @@ def run_lookup(lookup)
503503
include PuppetSpec::Files
504504

505505
it "is unaffected by global variables unless '--compile' is used" do
506+
# strict mode is off so behavior this test is trying to check isn't stubbed out
507+
Puppet[:strict_variables] = false
508+
Puppet[:strict] = :warning
506509
lookup.options[:node] = node
507510
lookup.options[:render_as] = :s
508511
allow(lookup.command_line).to receive(:args).and_return(['c'])
@@ -673,8 +676,9 @@ def run_lookup(lookup)
673676
let(:node) { Puppet::Node.new("testnode", :facts => facts, :environment => 'puppet_func_provider') }
674677

675678
it "works OK in the absense of '--compile'" do
676-
# strict_variables is off so behavior this test is trying to check isn't stubbed out
679+
# strict mode is off so behavior this test is trying to check isn't stubbed out
677680
Puppet[:strict_variables] = false
681+
Puppet[:strict] = :warning
678682
lookup.options[:node] = node
679683
allow(lookup.command_line).to receive(:args).and_return(['c'])
680684
lookup.options[:render_as] = :s

Diff for: spec/unit/application/resource_spec.rb

+22-13
Original file line numberDiff line numberDiff line change
@@ -129,22 +129,24 @@
129129
end
130130

131131
describe "when printing output" do
132-
it "should not emit puppet class tags when printing yaml" do
133-
Puppet::Type.newtype(:stringify) do
134-
ensurable
135-
newparam(:name, isnamevar: true)
136-
newproperty(:string)
137-
end
132+
Puppet::Type.newtype(:stringify) do
133+
ensurable
134+
newparam(:name, isnamevar: true)
135+
newproperty(:string)
136+
end
138137

139-
Puppet::Type.type(:stringify).provide(:stringify) do
140-
def exists?
141-
true
142-
end
138+
Puppet::Type.type(:stringify).provide(:stringify) do
139+
def exists?
140+
true
141+
end
143142

144-
def string
145-
Puppet::Util::Execution::ProcessOutput.new('test', 0)
146-
end
143+
def string
144+
Puppet::Util::Execution::ProcessOutput.new('test', 0)
147145
end
146+
end
147+
148+
it "should not emit puppet class tags when printing yaml when strict mode is off" do
149+
Puppet[:strict] = :warning
148150

149151
@resource_app.options[:to_yaml] = true
150152
allow(@resource_app.command_line).to receive(:args).and_return(['stringify', 'hello', 'ensure=present', 'string=asd'])
@@ -158,6 +160,13 @@ def string
158160
expect { @resource_app.main }.not_to raise_error
159161
end
160162

163+
it "should raise an error when printing yaml by default" do
164+
@resource_app.options[:to_yaml] = true
165+
allow(@resource_app.command_line).to receive(:args).and_return(['stringify', 'hello', 'ensure=present', 'string=asd'])
166+
expect { @resource_app.main }.to raise_error( Puppet::PreformattedError,
167+
/Stringify\[hello\]\['string'\] contains a Puppet::Util::Execution::ProcessOutput value. It will be converted to the String 'test'/)
168+
end
169+
161170
it "should ensure all values to be printed are in the external encoding" do
162171
resources = [
163172
Puppet::Type.type(:user).new(:name => "\u2603".force_encoding(Encoding::UTF_8)).to_resource,

Diff for: spec/unit/data_providers/hiera_data_provider_spec.rb

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ def compile(environment, code = nil)
3535
node = Puppet::Node.new("testnode", :facts => facts, :environment => environment)
3636
compiler = Puppet::Parser::Compiler.new(node)
3737
compiler.topscope['domain'] = 'example.com'
38+
compiler.topscope['my_fact'] = 'server3'
3839
block_given? ? compiler.compile { |catalog| yield(compiler); catalog } : compiler.compile
3940
end
4041

@@ -164,6 +165,7 @@ def extract_notifications(catalog)
164165
expect(extract_notifications(compiler.compile)).to include('server2')
165166

166167
compiler = Puppet::Parser::Compiler.new(node)
168+
compiler.topscope['my_fact'] = 'server3'
167169
expect(extract_notifications(compiler.compile)).to include('In name.yaml')
168170
end
169171

Diff for: spec/unit/functions/epp_spec.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@
2222
expect { eval_template("<%= $kryptonite == undef %>")}.to raise_error(/Evaluation Error: Unknown variable: 'kryptonite'./)
2323
end
2424

25-
it "get nil accessing a variable that does not exist when strict_variables is off" do
25+
it "get nil accessing a variable that does not exist when strict mode is off" do
2626
Puppet[:strict_variables] = false
27+
Puppet[:strict] = :warning
2728
expect(eval_template("<%= $kryptonite == undef %>")).to eq("true")
2829
end
2930

Diff for: spec/unit/functions/inline_epp_spec.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@
2020
expect { eval_template("<%= $kryptonite == undef %>")}.to raise_error(/Evaluation Error: Unknown variable: 'kryptonite'./)
2121
end
2222

23-
it "get nil accessing a variable that does not exist when strict_variables is off" do
23+
it "get nil accessing a variable that does not exist when strict mode is off" do
2424
Puppet[:strict_variables] = false
25+
Puppet[:strict] = :warning
2526
expect(eval_template("<%= $kryptonite == undef %>")).to eq("true")
2627
end
2728

Diff for: spec/unit/functions/lookup_spec.rb

+33-20
Original file line numberDiff line numberDiff line change
@@ -573,9 +573,11 @@ def explain(key, options = {})
573573
it 'reloads the configuration if interpolated values change' do
574574
Puppet[:log_level] = 'debug'
575575
collect_notices("notice('success')") do |scope|
576+
scope['var'] = {}
576577
expect(lookup_func.call(scope, 'y')).to eql('value y from x')
577-
scope['var'] = { 'sub' => '_d' }
578-
expect(lookup_func.call(scope, 'y')).to eql('value y from x_d')
578+
nested_scope = scope.compiler.newscope(scope)
579+
nested_scope['var'] = { 'sub' => '_d' }
580+
expect(lookup_func.call(nested_scope, 'y')).to eql('value y from x_d')
579581
nested_scope = scope.compiler.newscope(scope)
580582
nested_scope['var'] = { 'sub' => '_e' }
581583
expect(lookup_func.call(nested_scope, 'y')).to eql('value y from x_e')
@@ -602,15 +604,10 @@ def explain(key, options = {})
602604
context 'using global variable reference' do
603605
let(:data_path) { 'x%{::var.sub}.yaml' }
604606

605-
it 'reloads the configuration if interpolated that was previously undefined, gets defined' do
606-
Puppet[:log_level] = 'debug'
607+
it 'raises an error when reloads the configuration if interpolating undefined values' do
607608
collect_notices("notice('success')") do |scope|
608-
expect(lookup_func.call(scope, 'y')).to eql('value y from x')
609-
scope['var'] = { 'sub' => '_d' }
610-
expect(lookup_func.call(scope, 'y')).to eql('value y from x_d')
609+
expect { lookup_func.call(scope, 'y') }.to raise_error(/Undefined variable '::var'/)
611610
end
612-
expect(notices).to eql(['success'])
613-
expect(debugs.any? { |m| m =~ /Hiera configuration recreated due to change of scope variables used in interpolation expressions/ }).to be_truthy
614611
end
615612

616613
it 'does not reload the configuration if value changes locally' do
@@ -726,10 +723,13 @@ def explain(key, options = {})
726723
it 'interpolates both key and value"' do
727724
Puppet[:log_level] = 'debug'
728725
collect_notices("notice('success')") do |scope|
726+
scope['key'] = ''
727+
scope['value'] = ''
729728
expect(lookup_func.call(scope, 'a')).to eql({'' => 'the '})
730-
scope['key'] = 'a_key'
731-
scope['value'] = 'interpolated value'
732-
expect(lookup_func.call(scope, 'a')).to eql({'a_key' => 'the interpolated value'})
729+
nested_scope = scope.compiler.newscope(scope)
730+
nested_scope['key'] = 'a_key'
731+
nested_scope['value'] = 'interpolated value'
732+
expect(lookup_func.call(nested_scope, 'a')).to eql({'a_key' => 'the interpolated value'})
733733
end
734734
expect(notices).to eql(['success'])
735735
end
@@ -783,15 +783,26 @@ def explain(key, options = {})
783783
context 'that contains a legal yaml that is not a hash' do
784784
let(:common_yaml) { "- A list\n- of things" }
785785

786-
it 'fails with a "did not find"' do
786+
it 'fails with a "invalid yaml hash"' do
787787
expect { lookup('a') }.to raise_error do |e|
788-
expect(e.message).to match(/did not find a value for the name 'a'/)
788+
expect(e.message).to match(/spec\/data\/common.yaml: file does not contain a valid yaml hash/)
789789
end
790790
end
791791

792-
it 'logs a warning that the file does not contain a hash' do
793-
expect { lookup('a') }.to raise_error(Puppet::DataBinding::LookupError)
794-
expect(warnings).to include(/spec\/data\/common.yaml: file does not contain a valid yaml hash/)
792+
context 'when strict mode is off' do
793+
before :each do
794+
Puppet[:strict] = :warning
795+
end
796+
it 'fails with a "did not find"' do
797+
expect { lookup('a') }.to raise_error do |e|
798+
expect(e.message).to match(/did not find a value for the name 'a'/)
799+
end
800+
end
801+
802+
it 'logs a warning that the file does not contain a hash' do
803+
expect { lookup('a') }.to raise_error(Puppet::DataBinding::LookupError)
804+
expect(warnings).to include(/spec\/data\/common.yaml: file does not contain a valid yaml hash/)
805+
end
795806
end
796807
end
797808

@@ -2412,6 +2423,7 @@ def uri_test_func(options, context)
24122423
end
24132424

24142425
it 'defaults are used when data is not found in scope interpolations' do
2426+
pending('See PUP-11751')
24152427
expect(lookup('mod_a::interpolate_scope_xd', { 'default_values_hash' => defaults })).to eql('-- value scope_xd (from default) --')
24162428
end
24172429

@@ -2449,15 +2461,16 @@ def uri_test_func(options, context)
24492461
expect(lookup('mod_a::interpolate_scope')).to eql('-- scope scalar value --')
24502462
end
24512463

2452-
it 'interpolates not found in scope as empty string' do
2453-
expect(lookup('mod_a::interpolate_scope_not_found')).to eql('-- --')
2464+
it 'raises an error when trying to interpolate not found in scope' do
2465+
expect { lookup('mod_a::interpolate_scope_not_found')
2466+
}.to raise_error(/Evaluation Error: Error while evaluating a Function Call, Undefined variable 'scope_nope';/)
24542467
end
24552468

24562469
it 'interpolates dotted key from scope' do
24572470
expect(lookup('mod_a::interpolate_scope_dig')).to eql('-- scope hash a --')
24582471
end
24592472

2460-
it 'treates interpolated dotted key but not found in scope as empty string' do
2473+
it 'treats interpolated dotted key but not found in scope as empty string' do
24612474
expect(lookup('mod_a::interpolate_scope_dig_not_found')).to eql('-- --')
24622475
end
24632476

Diff for: spec/unit/functions/return_spec.rb

+3-1
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919
end
2020

2121
it 'with undef value as function result when not given an argument' do
22-
# strict_variables is off so behavior this test is trying to check isn't stubbed out
22+
# strict mode is off so behavior this test is trying to check isn't stubbed out
2323
Puppet[:strict_variables] = false
24+
Puppet[:strict] = :warning
25+
2426
expect(compile_to_catalog(<<-CODE)).to have_resource('Notify[xy]')
2527
function please_return() {
2628
[1,2,3].map |$x| { if $x == 1 { return() } 200 }

Diff for: spec/unit/hiera/scope_spec.rb

+6-1
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,15 @@
1616
end
1717

1818
describe "#[]" do
19-
it "should return nil when no value is found" do
19+
it "should return nil when no value is found and strict mode is off" do
20+
Puppet[:strict] = :warning
2021
expect(scope["foo"]).to eq(nil)
2122
end
2223

24+
it "should raise error by default when no value is found" do
25+
expect { scope["foo"] }.to raise_error(/Undefined variable 'foo'/)
26+
end
27+
2328
it "should treat '' as nil" do
2429
real["foo"] = ""
2530

Diff for: spec/unit/module_spec.rb

+2-6
Original file line numberDiff line numberDiff line change
@@ -773,12 +773,14 @@
773773
end
774774

775775
it "should not have metadata if it has a metadata file and its data is empty" do
776+
Puppet[:strict] = :warning
776777
allow(File).to receive(:read).with(mymod_metadata, {:encoding => 'utf-8'}).and_return("")
777778

778779
expect(mymod).not_to be_has_metadata
779780
end
780781

781782
it "should not have metadata if has a metadata file and its data is invalid" do
783+
Puppet[:strict] = :warning
782784
allow(File).to receive(:read).with(mymod_metadata, {:encoding => 'utf-8'}).and_return("This is some invalid json.\n")
783785
expect(mymod).not_to be_has_metadata
784786
end
@@ -799,12 +801,6 @@
799801
Puppet::Module.new("yay", "/path", double("env"))
800802
end
801803

802-
it "should tolerate failure to parse" do
803-
allow(File).to receive(:read).with(mymod_metadata, {:encoding => 'utf-8'}).and_return(my_fixture('trailing-comma.json'))
804-
805-
expect(mymod.has_metadata?).to be_falsey
806-
end
807-
808804
describe 'when --strict is warning' do
809805
before :each do
810806
Puppet[:strict] = :warning

0 commit comments

Comments
 (0)