puppet 3.7.5 → 3.8.1
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.
- checksums.yaml +4 -4
- data/ext/build_defaults.yaml +5 -5
- data/lib/hiera/puppet_function.rb +15 -4
- data/lib/puppet.rb +5 -2
- data/lib/puppet/application/agent.rb +5 -0
- data/lib/puppet/application/apply.rb +5 -0
- data/lib/puppet/application/device.rb +8 -3
- data/lib/puppet/application/master.rb +5 -0
- data/lib/puppet/defaults.rb +8 -0
- data/lib/puppet/error.rb +27 -1
- data/lib/puppet/file_system.rb +13 -0
- data/lib/puppet/file_system/file19windows.rb +8 -0
- data/lib/puppet/file_system/file_impl.rb +4 -0
- data/lib/puppet/file_system/memory_impl.rb +4 -0
- data/lib/puppet/functions.rb +25 -3
- data/lib/puppet/functions/defined.rb +130 -0
- data/lib/puppet/functions/hiera_include.rb +1 -1
- data/lib/puppet/node/environment.rb +4 -0
- data/lib/puppet/parser/compiler.rb +5 -2
- data/lib/puppet/parser/functions/defined.rb +26 -1
- data/lib/puppet/parser/functions/file.rb +3 -1
- data/lib/puppet/parser/templatewrapper.rb +2 -1
- data/lib/puppet/pops.rb +5 -0
- data/lib/puppet/pops/evaluator/access_operator.rb +25 -5
- data/lib/puppet/pops/evaluator/collector_transformer.rb +1 -11
- data/lib/puppet/pops/evaluator/compare_operator.rb +43 -0
- data/lib/puppet/pops/evaluator/evaluator_impl.rb +43 -28
- data/lib/puppet/pops/evaluator/runtime3_support.rb +9 -5
- data/lib/puppet/pops/functions/dispatch.rb +6 -1
- data/lib/puppet/pops/issue_reporter.rb +42 -16
- data/lib/puppet/pops/issues.rb +96 -0
- data/lib/puppet/pops/loader/module_loaders.rb +3 -1
- data/lib/puppet/pops/loaders.rb +6 -4
- data/lib/puppet/pops/migration/migration_checker.rb +45 -0
- data/lib/puppet/pops/model/factory.rb +1 -1
- data/lib/puppet/pops/model/model_meta.rb +1 -1
- data/lib/puppet/pops/parser/egrammar.ra +1 -1
- data/lib/puppet/pops/parser/eparser.rb +1 -1
- data/lib/puppet/pops/parser/epp_support.rb +18 -9
- data/lib/puppet/pops/parser/evaluating_parser.rb +7 -1
- data/lib/puppet/pops/parser/heredoc_support.rb +12 -11
- data/lib/puppet/pops/parser/interpolation_support.rb +7 -1
- data/lib/puppet/pops/parser/lexer2.rb +8 -8
- data/lib/puppet/pops/parser/lexer_support.rb +46 -20
- data/lib/puppet/pops/parser/parser_support.rb +11 -14
- data/lib/puppet/pops/parser/slurp_support.rb +22 -6
- data/lib/puppet/pops/types/type_calculator.rb +156 -55
- data/lib/puppet/pops/types/type_factory.rb +67 -14
- data/lib/puppet/pops/types/type_parser.rb +22 -13
- data/lib/puppet/pops/types/types.rb +21 -3
- data/lib/puppet/pops/types/types_meta.rb +13 -2
- data/lib/puppet/pops/validation.rb +25 -2
- data/lib/puppet/pops/validation/checker4_0.rb +25 -5
- data/lib/puppet/provider/group/windows_adsi.rb +18 -6
- data/lib/puppet/provider/mount/parsed.rb +145 -2
- data/lib/puppet/provider/package/pip.rb +4 -5
- data/lib/puppet/provider/package/zypper.rb +17 -7
- data/lib/puppet/provider/scheduled_task/win32_taskscheduler.rb +35 -10
- data/lib/puppet/provider/service/init.rb +7 -0
- data/lib/puppet/provider/user/windows_adsi.rb +8 -1
- data/lib/puppet/provider/zpool/zpool.rb +7 -2
- data/lib/puppet/resource.rb +1 -1
- data/lib/puppet/type/group.rb +1 -1
- data/lib/puppet/type/mount.rb +14 -3
- data/lib/puppet/type/scheduled_task.rb +21 -6
- data/lib/puppet/util/log.rb +50 -8
- data/lib/puppet/util/log/destinations.rb +23 -2
- data/lib/puppet/util/logging.rb +37 -1
- data/lib/puppet/util/windows/adsi.rb +36 -11
- data/lib/puppet/version.rb +1 -1
- data/spec/fixtures/unit/provider/mount/parsed/aix.filesystems +93 -85
- data/spec/fixtures/unit/provider/mount/parsed/aix.mount +11 -7
- data/spec/integration/parser/collector_spec.rb +7 -0
- data/spec/integration/parser/future_compiler_spec.rb +9 -0
- data/spec/integration/parser/resource_expressions_spec.rb +3 -0
- data/spec/unit/file_system_spec.rb +38 -0
- data/spec/unit/functions/defined_spec.rb +291 -0
- data/spec/unit/functions/hiera_spec.rb +8 -6
- data/spec/unit/functions4_spec.rb +97 -2
- data/spec/unit/parser/functions/file_spec.rb +8 -2
- data/spec/unit/parser/functions/template_spec.rb +1 -1
- data/spec/unit/parser/templatewrapper_spec.rb +1 -1
- data/spec/unit/pops/evaluator/access_ops_spec.rb +19 -0
- data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +61 -8
- data/spec/unit/pops/issues_spec.rb +16 -16
- data/spec/unit/pops/loaders/module_loaders_spec.rb +5 -0
- data/spec/unit/pops/migration_spec.rb +180 -0
- data/spec/unit/pops/parser/lexer2_spec.rb +152 -1
- data/spec/unit/pops/parser/parse_heredoc_spec.rb +26 -0
- data/spec/unit/pops/transformer/transform_calls_spec.rb +1 -1
- data/spec/unit/pops/types/type_calculator_spec.rb +204 -11
- data/spec/unit/pops/validation_spec.rb +66 -0
- data/spec/unit/provider/group/windows_adsi_spec.rb +65 -1
- data/spec/unit/provider/mount/parsed_spec.rb +31 -5
- data/spec/unit/provider/package/pip_spec.rb +19 -7
- data/spec/unit/provider/package/zypper_spec.rb +25 -14
- data/spec/unit/provider/scheduled_task/win32_taskscheduler_spec.rb +312 -70
- data/spec/unit/provider/service/base_spec.rb +42 -31
- data/spec/unit/provider/service/freebsd_spec.rb +1 -0
- data/spec/unit/provider/service/gentoo_spec.rb +1 -0
- data/spec/unit/provider/service/init_spec.rb +18 -0
- data/spec/unit/provider/service/openbsd_spec.rb +1 -0
- data/spec/unit/provider/service/redhat_spec.rb +1 -0
- data/spec/unit/provider/user/windows_adsi_spec.rb +21 -0
- data/spec/unit/provider/zpool/zpool_spec.rb +47 -10
- data/spec/unit/util/log_spec.rb +113 -0
- data/spec/unit/util/windows/adsi_spec.rb +106 -26
- metadata +10 -2
@@ -15,7 +15,7 @@ describe "the 'file' function" do
|
|
15
15
|
|
16
16
|
def with_file_content(content)
|
17
17
|
path = tmpfile('file-function')
|
18
|
-
file = File.new(path, '
|
18
|
+
file = File.new(path, 'wb')
|
19
19
|
file.sync = true
|
20
20
|
file.print content
|
21
21
|
yield path
|
@@ -23,7 +23,13 @@ describe "the 'file' function" do
|
|
23
23
|
|
24
24
|
it "should read a file" do
|
25
25
|
with_file_content('file content') do |name|
|
26
|
-
scope.function_file([name]).
|
26
|
+
expect(scope.function_file([name])).to eq("file content")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should read a file keeping line endings intact" do
|
31
|
+
with_file_content("file content\r\n") do |name|
|
32
|
+
expect(scope.function_file([name])).to eq("file content\r\n")
|
27
33
|
end
|
28
34
|
end
|
29
35
|
|
@@ -82,7 +82,7 @@ describe "the template function" do
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def eval_template(content)
|
85
|
-
|
85
|
+
Puppet::FileSystem.stubs(:read_preserve_line_endings).with("template").returns(content)
|
86
86
|
Puppet::Parser::Files.stubs(:find_template).returns("template")
|
87
87
|
scope.function_template(['template'])
|
88
88
|
end
|
@@ -111,7 +111,7 @@ describe Puppet::Parser::TemplateWrapper do
|
|
111
111
|
Puppet::Parser::Files.stubs(:find_template).
|
112
112
|
with(name, anything()).
|
113
113
|
returns(full_name)
|
114
|
-
|
114
|
+
Puppet::FileSystem.stubs(:read_preserve_line_endings).with(full_name).returns(contents)
|
115
115
|
|
116
116
|
full_name
|
117
117
|
end
|
@@ -400,6 +400,25 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl/AccessOperator' do
|
|
400
400
|
expect {evaluate(expr)}.to raise_error(/Resource not found: File\['x'\]/)
|
401
401
|
end
|
402
402
|
|
403
|
+
# NotUndef Type
|
404
|
+
#
|
405
|
+
it 'produces a NotUndef instance' do
|
406
|
+
type_expr = fqr('NotUndef')
|
407
|
+
expect(evaluate(type_expr)).to eql(Puppet::Pops::Types::TypeFactory.not_undef())
|
408
|
+
end
|
409
|
+
|
410
|
+
it 'produces a NotUndef instance with contained type' do
|
411
|
+
type_expr = fqr('NotUndef')[fqr('Integer')]
|
412
|
+
tf = Puppet::Pops::Types::TypeFactory
|
413
|
+
expect(evaluate(type_expr)).to eql(tf.not_undef(tf.integer))
|
414
|
+
end
|
415
|
+
|
416
|
+
it 'produces a NotUndef instance with String type when given a literal String' do
|
417
|
+
type_expr = fqr('NotUndef')[literal('hey')]
|
418
|
+
tf = Puppet::Pops::Types::TypeFactory
|
419
|
+
expect(evaluate(type_expr)).to eql(tf.not_undef(tf.string('hey')))
|
420
|
+
end
|
421
|
+
|
403
422
|
# Type Type
|
404
423
|
#
|
405
424
|
it 'creates a Type instance when applied to a Type' do
|
@@ -78,6 +78,9 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
|
|
78
78
|
"[1,2,3] != [1,2,3]" => false,
|
79
79
|
"[1,2,3][2]" => 3,
|
80
80
|
"[1,2,3] + [4,5]" => [1,2,3,4,5],
|
81
|
+
"[1,2,3, *[4,5]]" => [1,2,3,4,5],
|
82
|
+
"[1,2,3, (*[4,5])]" => [1,2,3,4,5],
|
83
|
+
"[1,2,3, ((*[4,5]))]" => [1,2,3,4,5],
|
81
84
|
"[1,2,3] + [[4,5]]" => [1,2,3,[4,5]],
|
82
85
|
"[1,2,3] + 4" => [1,2,3,4],
|
83
86
|
"[1,2,3] << [4,5]" => [1,2,3,[4,5]],
|
@@ -235,6 +238,8 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
|
|
235
238
|
"$x = Pattern['a.*'] a =~ $x" => true,
|
236
239
|
"1 =~ Integer" => true,
|
237
240
|
"1 !~ Integer" => false,
|
241
|
+
"undef =~ NotUndef" => false,
|
242
|
+
"undef !~ NotUndef" => true,
|
238
243
|
"[1,2,3] =~ Array[Integer[1,10]]" => true,
|
239
244
|
}.each do |source, result|
|
240
245
|
it "should parse and evaluate the expression '#{source}' to #{result}" do
|
@@ -316,7 +321,7 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
|
|
316
321
|
end
|
317
322
|
|
318
323
|
{
|
319
|
-
'Any' => ['Data', 'Scalar', 'Numeric', 'Integer', 'Float', 'Boolean', 'String', 'Pattern', 'Collection',
|
324
|
+
'Any' => ['NotUndef', 'Data', 'Scalar', 'Numeric', 'Integer', 'Float', 'Boolean', 'String', 'Pattern', 'Collection',
|
320
325
|
'Array', 'Hash', 'CatalogEntry', 'Resource', 'Class', 'Undef', 'File', 'NotYetKnownResourceType'],
|
321
326
|
|
322
327
|
# Note, Data > Collection is false (so not included)
|
@@ -473,6 +478,7 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
|
|
473
478
|
"unless false {5}" => 5,
|
474
479
|
"unless true {5}" => nil,
|
475
480
|
"unless true {2} else {5}" => 5,
|
481
|
+
"unless true {} else {5}" => 5,
|
476
482
|
"$a = if true {5} $a" => 5,
|
477
483
|
"$a = if false {5} $a" => nil,
|
478
484
|
"$a = if false {2} else {5} $a" => 5,
|
@@ -510,12 +516,31 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
|
|
510
516
|
"case ringo {
|
511
517
|
*[paul, john, ringo, george] : { 'beatle' } }" => 'beatle',
|
512
518
|
|
519
|
+
"case ringo {
|
520
|
+
(*[paul, john, ringo, george]) : { 'beatle' } }" => 'beatle',
|
521
|
+
|
513
522
|
"case undef {
|
514
523
|
undef : { 'yes' } }" => 'yes',
|
515
524
|
|
516
525
|
"case undef {
|
517
526
|
*undef : { 'no' }
|
518
527
|
default :{ 'yes' }}" => 'yes',
|
528
|
+
|
529
|
+
"case [green, 2, whatever] {
|
530
|
+
[/ee/, Integer[0,10], default] : { 'yes' }
|
531
|
+
default :{ 'no' }}" => 'yes',
|
532
|
+
|
533
|
+
"case [green, 2, whatever] {
|
534
|
+
default :{ 'no' }
|
535
|
+
[/ee/, Integer[0,10], default] : { 'yes' }}" => 'yes',
|
536
|
+
|
537
|
+
"case {a=>1, b=>2, whatever=>3, extra => ignored} {
|
538
|
+
{ a => Integer[0,5],
|
539
|
+
b => Integer[0,5],
|
540
|
+
whatever => default
|
541
|
+
} : { 'yes' }
|
542
|
+
default : { 'no' }}" => 'yes',
|
543
|
+
|
519
544
|
}.each do |source, result|
|
520
545
|
it "should parse and evaluate the expression '#{source}' to #{result}" do
|
521
546
|
parser.evaluate_string(scope, source, __FILE__).should == result
|
@@ -532,8 +557,22 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
|
|
532
557
|
"'banana' ? { /.*(ana).*/ => $1 }" => 'ana',
|
533
558
|
"[2] ? { Array[String] => yes, Array => yes}" => 'yes',
|
534
559
|
"ringo ? *[paul, john, ringo, george] => 'beatle'" => 'beatle',
|
560
|
+
"ringo ? (*[paul, john, ringo, george]) => 'beatle'"=> 'beatle',
|
535
561
|
"undef ? undef => 'yes'" => 'yes',
|
536
562
|
"undef ? {*undef => 'no', default => 'yes'}" => 'yes',
|
563
|
+
|
564
|
+
"[green, 2, whatever] ? {
|
565
|
+
[/ee/, Integer[0,10], default
|
566
|
+
] => 'yes',
|
567
|
+
default => 'no'}" => 'yes',
|
568
|
+
|
569
|
+
"{a=>1, b=>2, whatever=>3, extra => ignored} ?
|
570
|
+
{{ a => Integer[0,5],
|
571
|
+
b => Integer[0,5],
|
572
|
+
whatever => default
|
573
|
+
} => 'yes',
|
574
|
+
default => 'no' }" => 'yes',
|
575
|
+
|
537
576
|
}.each do |source, result|
|
538
577
|
it "should parse and evaluate the expression '#{source}' to #{result}" do
|
539
578
|
parser.evaluate_string(scope, source, __FILE__).should == result
|
@@ -700,6 +739,8 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
|
|
700
739
|
"'abc'[x]" => "The value 'x' cannot be converted to Numeric",
|
701
740
|
"'abc'[1.0]" => "A String[] cannot use Float where Integer is expected",
|
702
741
|
"'abc'[1,2,3]" => "String supports [] with one or two arguments. Got 3",
|
742
|
+
"NotUndef[0]" => 'NotUndef-Type[] argument must be a Type or a String. Got Fixnum',
|
743
|
+
"NotUndef[a,b]" => 'NotUndef-Type[] accepts 0 to 1 arguments. Got 2',
|
703
744
|
"Resource[0]" => 'First argument to Resource[] must be a resource type or a String. Got Integer',
|
704
745
|
"Resource[a, 0]" => 'Error creating type specialization of a Resource-Type, Cannot use Integer where a resource title String is expected',
|
705
746
|
"File[0]" => 'Error creating type specialization of a File-Type, Cannot use Integer where a resource title String is expected',
|
@@ -899,6 +940,8 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
|
|
899
940
|
'sprintf( "x%iy", $a )' => "x10y",
|
900
941
|
# unfolds
|
901
942
|
'sprintf( *["x%iy", $a] )' => "x10y",
|
943
|
+
'( *["x%iy", $a] ).sprintf' => "x10y",
|
944
|
+
'((*["x%iy", $a])).sprintf' => "x10y",
|
902
945
|
'"x%iy".sprintf( $a )' => "x10y",
|
903
946
|
'$b.reduce |$memo,$x| { $memo + $x }' => 6,
|
904
947
|
'reduce($b) |$memo,$x| { $memo + $x }' => 6,
|
@@ -1099,7 +1142,7 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
|
|
1099
1142
|
end
|
1100
1143
|
|
1101
1144
|
it "a lex error should be raised for '$foo::::bar'" do
|
1102
|
-
expect { parser.evaluate_string(scope, "$foo::::bar") }.to raise_error(Puppet::
|
1145
|
+
expect { parser.evaluate_string(scope, "$foo::::bar") }.to raise_error(Puppet::ParseErrorWithIssue, /Illegal fully qualified name at line 1:7/)
|
1103
1146
|
end
|
1104
1147
|
|
1105
1148
|
{ '$a = $0' => nil,
|
@@ -1238,6 +1281,16 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
|
|
1238
1281
|
parser.evaluate_string(scope, src).should == "Hello Fjodor"
|
1239
1282
|
end
|
1240
1283
|
|
1284
|
+
it "parses interpolated heredoc expression with escapes" do
|
1285
|
+
src = <<-CODE
|
1286
|
+
$name = 'Fjodor'
|
1287
|
+
@("END")
|
1288
|
+
Hello\\ \\$name
|
1289
|
+
|- END
|
1290
|
+
CODE
|
1291
|
+
parser.evaluate_string(scope, src).should == "Hello\\ \\Fjodor"
|
1292
|
+
end
|
1293
|
+
|
1241
1294
|
end
|
1242
1295
|
context "Handles Deprecations and Discontinuations" do
|
1243
1296
|
it 'of import statements' do
|
@@ -1266,14 +1319,14 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
|
|
1266
1319
|
end
|
1267
1320
|
|
1268
1321
|
it 'for non r-value producing define' do
|
1269
|
-
Puppet.expects(:
|
1270
|
-
Puppet.expects(:
|
1322
|
+
Puppet::Util::Log.expects(:create).with(has_entries(:level => :err, :message => "Invalid use of expression. A 'define' expression does not produce a value", :line => 1, :pos => 6))
|
1323
|
+
Puppet::Util::Log.expects(:create).with(has_entries(:level => :err, :message => 'Classes, definitions, and nodes may only appear at toplevel or inside other classes', :line => 1, :pos => 6))
|
1271
1324
|
expect { parser.parse_string("$a = define foo { }", nil) }.to raise_error(/2 errors/)
|
1272
1325
|
end
|
1273
1326
|
|
1274
1327
|
it 'for non r-value producing class' do
|
1275
|
-
Puppet.expects(:
|
1276
|
-
Puppet.expects(:
|
1328
|
+
Puppet::Util::Log.expects(:create).with(has_entries(:level => :err, :message => 'Invalid use of expression. A Host Class Definition does not produce a value', :line => 1, :pos => 6))
|
1329
|
+
Puppet::Util::Log.expects(:create).with(has_entries(:level => :err, :message => 'Classes, definitions, and nodes may only appear at toplevel or inside other classes', :line => 1, :pos => 6))
|
1277
1330
|
expect { parser.parse_string("$a = class foo { }", nil) }.to raise_error(/2 errors/)
|
1278
1331
|
end
|
1279
1332
|
|
@@ -1287,8 +1340,8 @@ describe 'Puppet::Pops::Evaluator::EvaluatorImpl' do
|
|
1287
1340
|
end
|
1288
1341
|
|
1289
1342
|
it 'for multiple errors with a summary exception' do
|
1290
|
-
Puppet.expects(:
|
1291
|
-
Puppet.expects(:
|
1343
|
+
Puppet::Util::Log.expects(:create).with(has_entries(:level => :err, :message => 'Invalid use of expression. A Node Definition does not produce a value', :line => 1, :pos => 6))
|
1344
|
+
Puppet::Util::Log.expects(:create).with(has_entries(:level => :err, :message => 'Classes, definitions, and nodes may only appear at toplevel or inside other classes', :line => 1, :pos => 6))
|
1292
1345
|
expect { parser.parse_string("$a = node x { }",nil) }.to raise_error(/2 errors/)
|
1293
1346
|
end
|
1294
1347
|
|
@@ -62,19 +62,19 @@ describe "Puppet::Pops::IssueReporter" do
|
|
62
62
|
end
|
63
63
|
|
64
64
|
it "emits warnings if told to emit them" do
|
65
|
-
Puppet.expects(:
|
65
|
+
Puppet::Log.expects(:create).twice.with(has_entries(:level => :warning, :message => regexp_matches(/warning1|deprecation1/)))
|
66
66
|
Puppet::Pops::IssueReporter.assert_and_report(acceptor, { :emit_warnings => true })
|
67
67
|
end
|
68
68
|
|
69
69
|
it "does not emit warnings if not told to emit them" do
|
70
|
-
Puppet.expects(:
|
70
|
+
Puppet::Log.expects(:create).never
|
71
71
|
Puppet::Pops::IssueReporter.assert_and_report(acceptor, {})
|
72
72
|
end
|
73
73
|
|
74
74
|
it "emits no warnings if :max_warnings is 0" do
|
75
75
|
acceptor.accept( warning(2) )
|
76
76
|
Puppet[:max_warnings] = 0
|
77
|
-
Puppet.expects(:
|
77
|
+
Puppet::Log.expects(:create).once.with(has_entries(:level => :warning, :message => regexp_matches(/deprecation1/)))
|
78
78
|
Puppet::Pops::IssueReporter.assert_and_report(acceptor, { :emit_warnings => true })
|
79
79
|
end
|
80
80
|
|
@@ -82,20 +82,20 @@ describe "Puppet::Pops::IssueReporter" do
|
|
82
82
|
acceptor.accept( warning(2) )
|
83
83
|
acceptor.accept( warning(3) )
|
84
84
|
Puppet[:max_warnings] = 1
|
85
|
-
Puppet.expects(:
|
85
|
+
Puppet::Log.expects(:create).twice.with(has_entries(:level => :warning, :message => regexp_matches(/warning1|deprecation1/)))
|
86
86
|
Puppet::Pops::IssueReporter.assert_and_report(acceptor, { :emit_warnings => true })
|
87
87
|
end
|
88
88
|
|
89
89
|
it "does not emit more deprecations warnings than the max deprecation warnings" do
|
90
90
|
acceptor.accept( deprecation(2) )
|
91
91
|
Puppet[:max_deprecations] = 0
|
92
|
-
Puppet.expects(:
|
92
|
+
Puppet::Log.expects(:create).once.with(has_entries(:level => :warning, :message => regexp_matches(/warning1/)))
|
93
93
|
Puppet::Pops::IssueReporter.assert_and_report(acceptor, { :emit_warnings => true })
|
94
94
|
end
|
95
95
|
|
96
96
|
it "does not emit deprecation warnings, but does emit regular warnings if disable_warnings includes deprecations" do
|
97
97
|
Puppet[:disable_warnings] = 'deprecations'
|
98
|
-
Puppet.expects(:
|
98
|
+
Puppet::Log.expects(:create).once.with(has_entries(:level => :warning, :message => regexp_matches(/warning1/)))
|
99
99
|
Puppet::Pops::IssueReporter.assert_and_report(acceptor, { :emit_warnings => true })
|
100
100
|
end
|
101
101
|
end
|
@@ -103,7 +103,7 @@ describe "Puppet::Pops::IssueReporter" do
|
|
103
103
|
context "given errors" do
|
104
104
|
it "logs nothing, but raises the given :message if :emit_errors is repressing error logging" do
|
105
105
|
acceptor.accept( error(1) )
|
106
|
-
Puppet.expects(:
|
106
|
+
Puppet::Log.expects(:create).never
|
107
107
|
expect do
|
108
108
|
Puppet::Pops::IssueReporter.assert_and_report(acceptor, { :emit_errors => false, :message => 'special'})
|
109
109
|
end.to raise_error(Puppet::ParseError, 'special')
|
@@ -111,7 +111,7 @@ describe "Puppet::Pops::IssueReporter" do
|
|
111
111
|
|
112
112
|
it "prefixes :message if a single error is raised" do
|
113
113
|
acceptor.accept( error(1) )
|
114
|
-
Puppet.expects(:
|
114
|
+
Puppet::Log.expects(:create).never
|
115
115
|
expect do
|
116
116
|
Puppet::Pops::IssueReporter.assert_and_report(acceptor, { :message => 'special'})
|
117
117
|
end.to raise_error(Puppet::ParseError, /special error1/)
|
@@ -119,7 +119,7 @@ describe "Puppet::Pops::IssueReporter" do
|
|
119
119
|
|
120
120
|
it "logs nothing and raises immediately if there is only one error" do
|
121
121
|
acceptor.accept( error(1) )
|
122
|
-
Puppet.expects(:
|
122
|
+
Puppet::Log.expects(:create).never
|
123
123
|
expect do
|
124
124
|
Puppet::Pops::IssueReporter.assert_and_report(acceptor, { })
|
125
125
|
end.to raise_error(Puppet::ParseError, /error1/)
|
@@ -129,7 +129,7 @@ describe "Puppet::Pops::IssueReporter" do
|
|
129
129
|
acceptor.accept( error(1) )
|
130
130
|
acceptor.accept( error(2) )
|
131
131
|
Puppet[:max_errors] = 0
|
132
|
-
Puppet.expects(:
|
132
|
+
Puppet::Log.expects(:create).never
|
133
133
|
expect do
|
134
134
|
Puppet::Pops::IssueReporter.assert_and_report(acceptor, { })
|
135
135
|
end.to raise_error(Puppet::ParseError, /error1/)
|
@@ -138,7 +138,7 @@ describe "Puppet::Pops::IssueReporter" do
|
|
138
138
|
it "logs the :message if there is more than one allowed error" do
|
139
139
|
acceptor.accept( error(1) )
|
140
140
|
acceptor.accept( error(2) )
|
141
|
-
Puppet.expects(:
|
141
|
+
Puppet::Log.expects(:create).times(3).with(has_entries(:level => :err, :message => regexp_matches(/error1|error2|special/)))
|
142
142
|
expect do
|
143
143
|
Puppet::Pops::IssueReporter.assert_and_report(acceptor, { :message => 'special'})
|
144
144
|
end.to raise_error(Puppet::ParseError, /Giving up/)
|
@@ -149,7 +149,7 @@ describe "Puppet::Pops::IssueReporter" do
|
|
149
149
|
acceptor.accept( error(2) )
|
150
150
|
acceptor.accept( error(3) )
|
151
151
|
Puppet[:max_errors] = 2
|
152
|
-
Puppet.expects(:
|
152
|
+
Puppet::Log.expects(:create).times(2).with(has_entries(:level => :err, :message => regexp_matches(/error1|error2/)))
|
153
153
|
expect do
|
154
154
|
Puppet::Pops::IssueReporter.assert_and_report(acceptor, { })
|
155
155
|
end.to raise_error(Puppet::ParseError, /3 errors.*Giving up/)
|
@@ -160,7 +160,7 @@ describe "Puppet::Pops::IssueReporter" do
|
|
160
160
|
acceptor.accept( error(2) )
|
161
161
|
acceptor.accept( error(3) )
|
162
162
|
Puppet[:max_errors] = 4
|
163
|
-
Puppet.expects(:
|
163
|
+
Puppet::Log.expects(:create).times(3).with(has_entries(:level => :err, :message => regexp_matches(/error[123]/)))
|
164
164
|
expect do
|
165
165
|
Puppet::Pops::IssueReporter.assert_and_report(acceptor, { })
|
166
166
|
end.to raise_error(Puppet::ParseError, /3 errors.*Giving up/)
|
@@ -170,7 +170,7 @@ describe "Puppet::Pops::IssueReporter" do
|
|
170
170
|
acceptor.accept( error(1) )
|
171
171
|
acceptor.accept( error(2) )
|
172
172
|
Puppet[:disable_warnings] = 'deprecations'
|
173
|
-
Puppet.expects(:
|
173
|
+
Puppet::Log.expects(:create).times(2).with(has_entries(:level => :err, :message => regexp_matches(/error1|error2/)))
|
174
174
|
expect do
|
175
175
|
Puppet::Pops::IssueReporter.assert_and_report(acceptor, { })
|
176
176
|
end.to raise_error(Puppet::ParseError, /Giving up/)
|
@@ -186,8 +186,8 @@ describe "Puppet::Pops::IssueReporter" do
|
|
186
186
|
acceptor.accept( error(3) )
|
187
187
|
acceptor.accept( deprecation(1) )
|
188
188
|
Puppet[:max_errors] = 2
|
189
|
-
Puppet.expects(:
|
190
|
-
Puppet.expects(:
|
189
|
+
Puppet::Log.expects(:create).twice.with(has_entries(:level => :warning, :message => regexp_matches(/warning1|deprecation1/)))
|
190
|
+
Puppet::Log.expects(:create).twice.with(has_entries(:level => :err, :message => regexp_matches(/error[123]/)))
|
191
191
|
expect do
|
192
192
|
Puppet::Pops::IssueReporter.assert_and_report(acceptor, { :emit_warnings => true })
|
193
193
|
end.to raise_error(Puppet::ParseError, /3 errors.*2 warnings.*Giving up/)
|
@@ -57,6 +57,11 @@ describe 'FileBased module loader' do
|
|
57
57
|
expect(function.is_a?(Puppet::Functions::Function)).to eq(true)
|
58
58
|
end
|
59
59
|
|
60
|
+
it 'system loader has itself as private loader' do
|
61
|
+
module_loader = Puppet::Pops::Loader::ModuleLoaders.system_loader_from(static_loader, loaders)
|
62
|
+
expect(module_loader.private_loader).to be(module_loader)
|
63
|
+
end
|
64
|
+
|
60
65
|
it 'makes parent loader win over entries in child' do
|
61
66
|
module_dir = dir_containing('testmodule', {
|
62
67
|
'lib' => { 'puppet' => { 'functions' => { 'testmodule' => {
|
@@ -0,0 +1,180 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'puppet/pops'
|
4
|
+
require 'puppet/pops/evaluator/evaluator_impl'
|
5
|
+
require 'puppet/loaders'
|
6
|
+
require 'puppet_spec/pops'
|
7
|
+
require 'puppet_spec/scope'
|
8
|
+
require 'puppet/parser/e4_parser_adapter'
|
9
|
+
|
10
|
+
describe 'Puppet::Pops::MigrationMigrationChecker' do
|
11
|
+
include PuppetSpec::Pops
|
12
|
+
include PuppetSpec::Scope
|
13
|
+
before(:each) do
|
14
|
+
Puppet[:strict_variables] = true
|
15
|
+
|
16
|
+
# These must be set since the 3x logic switches some behaviors on these even if the tests explicitly
|
17
|
+
# use the 4x parser and evaluator.
|
18
|
+
#
|
19
|
+
Puppet[:parser] = 'future'
|
20
|
+
|
21
|
+
# Puppetx cannot be loaded until the correct parser has been set (injector is turned off otherwise)
|
22
|
+
require 'puppetx'
|
23
|
+
|
24
|
+
# Tests needs a known configuration of node/scope/compiler since it parses and evaluates
|
25
|
+
# snippets as the compiler will evaluate them, butwithout the overhead of compiling a complete
|
26
|
+
# catalog for each tested expression.
|
27
|
+
#
|
28
|
+
@parser = Puppet::Pops::Parser::EvaluatingParser.new
|
29
|
+
@node = Puppet::Node.new('node.example.com')
|
30
|
+
@node.environment = Puppet::Node::Environment.create(:testing, [])
|
31
|
+
@compiler = Puppet::Parser::Compiler.new(@node)
|
32
|
+
@scope = Puppet::Parser::Scope.new(@compiler)
|
33
|
+
@scope.source = Puppet::Resource::Type.new(:node, 'node.example.com')
|
34
|
+
@scope.parent = @compiler.topscope
|
35
|
+
end
|
36
|
+
|
37
|
+
let(:scope) { @scope }
|
38
|
+
|
39
|
+
describe "when there is no MigrationChecker in the PuppetContext" do
|
40
|
+
it "a null implementation of the MigrationChecker gets created (once per impl that needs one)" do
|
41
|
+
migration_checker = Puppet::Pops::Migration::MigrationChecker.new()
|
42
|
+
Puppet::Pops::Migration::MigrationChecker.expects(:new).at_least_once.returns(migration_checker)
|
43
|
+
Puppet::Pops::Parser::EvaluatingParser.new.evaluate_string(scope, "1", __FILE__).should == 1
|
44
|
+
Puppet::Pops::Migration::MigrationChecker.unstub(:new)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "when there is a MigrationChecker in the Puppet Context" do
|
49
|
+
it "does not create any MigrationChecker instances when parsing and evaluating" do
|
50
|
+
migration_checker = mock()
|
51
|
+
Puppet::Pops::Migration::MigrationChecker.expects(:new).never
|
52
|
+
Puppet.override({:migration_checker => migration_checker}, "test-context") do
|
53
|
+
Puppet::Pops::Parser::EvaluatingParser.new.evaluate_string(scope, "true", __FILE__)
|
54
|
+
end
|
55
|
+
Puppet::Pops::Migration::MigrationChecker.unstub(:new)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "when validating parsed code" do
|
60
|
+
it "is called for each integer" do
|
61
|
+
migration_checker = mock()
|
62
|
+
migration_checker.expects(:report_ambiguous_integer).times(3)
|
63
|
+
Puppet.override({:migration_checker => migration_checker}, "migration-context") do
|
64
|
+
Puppet::Pops::Parser::EvaluatingParser.new.evaluate_string(scope, "$a = [1,2,3]", __FILE__)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
it "is called for each float" do
|
69
|
+
migration_checker = mock()
|
70
|
+
migration_checker.expects(:report_ambiguous_float).times(3)
|
71
|
+
Puppet.override({:migration_checker => migration_checker}, "migration-context") do
|
72
|
+
Puppet::Pops::Parser::EvaluatingParser.new.evaluate_string(scope, "$a = [1.0,2.0,3.1415]", __FILE__)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it "last expressions in blocks are checked" do
|
77
|
+
migration_checker = mock()
|
78
|
+
migration_checker.expects(:report_array_last_in_block).twice # the program itself is a block too
|
79
|
+
Puppet.override({:migration_checker => migration_checker}, "migration-context") do
|
80
|
+
Puppet::Pops::Parser::EvaluatingParser.new.evaluate_string(scope, "$b = {} if true { $a = $b [false] }", __FILE__)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "when evaluating code" do
|
87
|
+
it "is called for boolean coercion of String" do
|
88
|
+
migration_checker = mock()
|
89
|
+
migration_checker.expects(:report_empty_string_true).times(2)
|
90
|
+
Puppet.override({:migration_checker => migration_checker}, "migration-context") do
|
91
|
+
Puppet::Pops::Parser::EvaluatingParser.new.evaluate_string(scope, "$a = ('a' and '')", __FILE__)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context "with a case expression" do
|
96
|
+
it "the test expression is checked for UC_bareword" do
|
97
|
+
migration_checker = mock()
|
98
|
+
migration_checker.expects(:report_uc_bareword_type).once
|
99
|
+
migration_checker.expects(:report_option_type_mismatch).once
|
100
|
+
Puppet.override({:migration_checker => migration_checker}, "migration-context") do
|
101
|
+
Puppet::Pops::Parser::EvaluatingParser.new.evaluate_string(scope, "case Foo { 'Foo': {}}", __FILE__)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
it "all case options are checked for UC_bareword" do
|
106
|
+
migration_checker = mock()
|
107
|
+
migration_checker.expects(:report_uc_bareword_type).times(4)
|
108
|
+
migration_checker.expects(:report_option_type_mismatch).times(4)
|
109
|
+
Puppet.override({:migration_checker => migration_checker}, "migration-context") do
|
110
|
+
Puppet::Pops::Parser::EvaluatingParser.new.evaluate_string(scope,
|
111
|
+
"case true { Foo, Bar: {} Fee, 'not': {}}", __FILE__)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context "with a selector expression" do
|
117
|
+
it "the test expression is checked for UC_bareword" do
|
118
|
+
migration_checker = mock()
|
119
|
+
migration_checker.expects(:report_uc_bareword_type).once
|
120
|
+
Puppet.override({:migration_checker => migration_checker}, "migration-context") do
|
121
|
+
Puppet::Pops::Parser::EvaluatingParser.new.evaluate_string(scope, "Foo ? { default => false}", __FILE__)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
it "all options are checked for UC_bareword" do
|
126
|
+
migration_checker = mock()
|
127
|
+
migration_checker.expects(:report_uc_bareword_type).times(3)
|
128
|
+
migration_checker.expects(:report_option_type_mismatch).times(3)
|
129
|
+
Puppet.override({:migration_checker => migration_checker}, "migration-context") do
|
130
|
+
Puppet::Pops::Parser::EvaluatingParser.new.evaluate_string(scope,
|
131
|
+
"true ? { Foo => false, Bar => false, 'not' => false, default => true}", __FILE__)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context "with a comparison of" do
|
137
|
+
['==', '!=', ].each do |operator|
|
138
|
+
it "'a' #{operator} 'b'" do
|
139
|
+
migration_checker = mock()
|
140
|
+
migration_checker.expects(:report_uc_bareword_type).twice
|
141
|
+
migration_checker.expects(:report_equality_type_mismatch).once
|
142
|
+
Puppet.override({:migration_checker => migration_checker}, "migration-context") do
|
143
|
+
Puppet::Pops::Parser::EvaluatingParser.new.evaluate_string(scope, "'a' #{operator} 'b'", __FILE__)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
['<', '>', '<=', '>='].each do |operator|
|
149
|
+
it "'a' #{operator} 'b'" do
|
150
|
+
migration_checker = mock()
|
151
|
+
migration_checker.expects(:report_uc_bareword_type).twice
|
152
|
+
Puppet.override({:migration_checker => migration_checker}, "migration-context") do
|
153
|
+
Puppet::Pops::Parser::EvaluatingParser.new.evaluate_string(scope, "'a' #{operator} 'b'", __FILE__)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
['=~', '!~'].each do |operator|
|
159
|
+
it "'a' #{operator} /.*/" do
|
160
|
+
migration_checker = mock()
|
161
|
+
migration_checker.expects(:report_uc_bareword_type).once
|
162
|
+
Puppet.override({:migration_checker => migration_checker}, "migration-context") do
|
163
|
+
Puppet::Pops::Parser::EvaluatingParser.new.evaluate_string(scope, "'a' #{operator} /.*/", __FILE__)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context "with an in operator" do
|
170
|
+
it "'a' in [true,false]" do
|
171
|
+
migration_checker = mock()
|
172
|
+
migration_checker.expects(:report_uc_bareword_type).once
|
173
|
+
migration_checker.expects(:report_in_expression).once
|
174
|
+
Puppet.override({:migration_checker => migration_checker}, "migration-context") do
|
175
|
+
Puppet::Pops::Parser::EvaluatingParser.new.evaluate_string(scope, "'a' in [true, false]", __FILE__)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|