puppet 0.23.1 → 0.23.2
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.
- data/CHANGELOG +31 -0
- data/bin/puppetd +2 -1
- data/conf/redhat/puppet.spec +9 -6
- data/conf/redhat/server.init +4 -5
- data/examples/code/mac_dscl.pp +28 -0
- data/examples/code/mac_dscl_revert.pp +26 -0
- data/examples/code/mac_netinfo.pp +5 -0
- data/examples/code/mac_pkgdmg.pp +7 -0
- data/ext/puppet-test +69 -2
- data/lib/puppet.rb +2 -2
- data/lib/puppet/configuration.rb +5 -1
- data/lib/puppet/network/server/mongrel.rb +3 -3
- data/lib/puppet/parser/ast.rb +2 -2
- data/lib/puppet/parser/ast/component.rb +3 -3
- data/lib/puppet/parser/ast/node.rb +2 -2
- data/lib/puppet/parser/collector.rb +2 -2
- data/lib/puppet/parser/interpreter.rb +38 -215
- data/lib/puppet/parser/parser.rb +11 -228
- data/lib/puppet/parser/parser_support.rb +447 -0
- data/lib/puppet/parser/resource/param.rb +2 -2
- data/lib/puppet/provider.rb +5 -3
- data/lib/puppet/provider/cron/crontab.rb +22 -9
- data/lib/puppet/provider/group/directoryservice.rb +23 -0
- data/lib/puppet/provider/interface/redhat.rb +251 -0
- data/lib/puppet/provider/interface/sunos.rb +116 -0
- data/lib/puppet/provider/mount.rb +4 -1
- data/lib/puppet/provider/nameservice/directoryservice.rb +341 -0
- data/lib/puppet/provider/package/dpkg.rb +2 -2
- data/lib/puppet/provider/package/openbsd.rb +2 -2
- data/lib/puppet/provider/package/rpm.rb +2 -4
- data/lib/puppet/provider/package/sun.rb +2 -2
- data/lib/puppet/provider/parsedfile.rb +32 -29
- data/lib/puppet/provider/user/directoryservice.rb +116 -0
- data/lib/puppet/rails/host.rb +1 -1
- data/lib/puppet/reference/configuration.rb +7 -4
- data/lib/puppet/type/interface.rb +57 -0
- data/lib/puppet/type/pfile/group.rb +2 -2
- data/lib/puppet/util/config.rb +10 -3
- data/lib/puppet/util/fileparsing.rb +2 -2
- data/test/language/ast/hostclass.rb +1 -17
- data/test/language/interpreter.rb +18 -388
- data/test/language/node.rb +8 -8
- data/test/language/parser.rb +444 -45
- data/test/lib/puppettest/parsertesting.rb +2 -2
- data/test/lib/puppettest/support/collection.rb +2 -2
- data/test/network/server/mongrel_test.rb +24 -3
- data/test/rails/collection.rb +34 -1
- data/test/ral/providers/cron/crontab.rb +198 -40
- data/test/ral/providers/mount/parsed.rb +69 -46
- data/test/ral/providers/parsedfile.rb +20 -28
- data/test/ral/types/cron.rb +20 -24
- data/test/ral/types/interface.rb +40 -0
- data/test/ral/types/package.rb +6 -2
- data/test/util/config.rb +106 -30
- metadata +14 -2
data/test/language/node.rb
CHANGED
@@ -61,29 +61,29 @@ class TestParser < Test::Unit::TestCase
|
|
61
61
|
end
|
62
62
|
interp = nil
|
63
63
|
code ||= "node #{hostnames.join(", ")} { }"
|
64
|
-
|
65
|
-
|
66
|
-
}
|
64
|
+
parser = mkparser
|
65
|
+
parser.string = code
|
67
66
|
# Strip quotes
|
68
67
|
hostnames.map! { |s| s.sub(/^['"](.*)['"]$/, "\\1") }
|
69
68
|
|
70
69
|
# parse
|
71
|
-
assert_nothing_raised {
|
72
|
-
|
70
|
+
assert_nothing_raised("Could not parse '%s'" % code) {
|
71
|
+
parser.parse
|
73
72
|
}
|
74
73
|
|
75
74
|
# Now make sure we can look up each of the names
|
76
75
|
hostnames.each do |name|
|
77
|
-
assert(
|
76
|
+
assert(parser.findnode(name),
|
78
77
|
"Could not find node %s" % name.inspect)
|
79
78
|
end
|
80
79
|
end
|
81
80
|
|
82
81
|
def check_nonparseable(hostname)
|
83
82
|
interp = nil
|
83
|
+
parser = mkparser
|
84
|
+
parser.string = "node #{hostname} { }"
|
84
85
|
assert_raise(Puppet::DevError, Puppet::ParseError, "#{hostname} passed") {
|
85
|
-
|
86
|
-
interp.send(:parsefiles)
|
86
|
+
parser.parse
|
87
87
|
}
|
88
88
|
end
|
89
89
|
|
data/test/language/parser.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
$:.unshift("../lib").unshift("../../lib") if __FILE__ =~ /\.rb$/
|
4
4
|
|
5
|
+
require 'mocha'
|
5
6
|
require 'puppet'
|
6
7
|
require 'puppet/parser/parser'
|
7
8
|
require 'puppettest'
|
@@ -37,12 +38,13 @@ class TestParser < Test::Unit::TestCase
|
|
37
38
|
def test_failers
|
38
39
|
failers { |file|
|
39
40
|
parser = mkparser
|
41
|
+
interp = mkinterp
|
40
42
|
Puppet.debug("parsing failer %s" % file) if __FILE__ == $0
|
41
43
|
assert_raise(Puppet::ParseError) {
|
42
44
|
parser.file = file
|
43
45
|
ast = parser.parse
|
44
|
-
scope = mkscope :interp =>
|
45
|
-
ast.evaluate :scope => scope
|
46
|
+
scope = mkscope :interp => interp
|
47
|
+
ast.classes[""].evaluate :scope => scope
|
46
48
|
}
|
47
49
|
Puppet::Type.allclear
|
48
50
|
}
|
@@ -275,9 +277,7 @@ class TestParser < Test::Unit::TestCase
|
|
275
277
|
ret = parser.parse
|
276
278
|
}
|
277
279
|
|
278
|
-
|
279
|
-
|
280
|
-
ret.each do |obj|
|
280
|
+
ret.classes[""].code.each do |obj|
|
281
281
|
assert_instance_of(AST::Collection, obj)
|
282
282
|
end
|
283
283
|
end
|
@@ -368,12 +368,13 @@ file { "/tmp/yayness":
|
|
368
368
|
str1 = %{if true { #{exec.call("true")} }}
|
369
369
|
ret = nil
|
370
370
|
assert_nothing_raised {
|
371
|
-
ret = parser.parse(str1)[0]
|
371
|
+
ret = parser.parse(str1).classes[""].code[0]
|
372
372
|
}
|
373
373
|
assert_instance_of(Puppet::Parser::AST::IfStatement, ret)
|
374
|
+
parser.clear
|
374
375
|
str2 = %{if true { #{exec.call("true")} } else { #{exec.call("false")} }}
|
375
376
|
assert_nothing_raised {
|
376
|
-
ret = parser.parse(str2)[0]
|
377
|
+
ret = parser.parse(str2).classes[""].code[0]
|
377
378
|
}
|
378
379
|
assert_instance_of(Puppet::Parser::AST::IfStatement, ret)
|
379
380
|
assert_instance_of(Puppet::Parser::AST::Else, ret.else)
|
@@ -381,13 +382,12 @@ file { "/tmp/yayness":
|
|
381
382
|
|
382
383
|
def test_hostclass
|
383
384
|
parser = mkparser
|
384
|
-
interp = parser.interp
|
385
385
|
|
386
386
|
assert_nothing_raised {
|
387
387
|
parser.parse %{class myclass { class other {} }}
|
388
388
|
}
|
389
|
-
assert(
|
390
|
-
assert(
|
389
|
+
assert(parser.classes["myclass"], "Could not find myclass")
|
390
|
+
assert(parser.classes["myclass::other"], "Could not find myclass::other")
|
391
391
|
|
392
392
|
assert_nothing_raised {
|
393
393
|
parser.parse "class base {}
|
@@ -395,17 +395,16 @@ file { "/tmp/yayness":
|
|
395
395
|
class deep::sub inherits base {}
|
396
396
|
}"
|
397
397
|
}
|
398
|
-
sub =
|
398
|
+
sub = parser.classes["container::deep::sub"]
|
399
399
|
assert(sub, "Could not find sub")
|
400
|
-
assert_equal("base", sub.parentobj.classname)
|
401
400
|
|
402
401
|
# Now try it with a parent class being a fq class
|
403
402
|
assert_nothing_raised {
|
404
403
|
parser.parse "class container::one inherits container::deep::sub {}"
|
405
404
|
}
|
406
|
-
sub =
|
405
|
+
sub = parser.classes["container::one"]
|
407
406
|
assert(sub, "Could not find one")
|
408
|
-
assert_equal("container::deep::sub", sub.
|
407
|
+
assert_equal("container::deep::sub", sub.parentclass)
|
409
408
|
|
410
409
|
# Finally, try including a qualified class
|
411
410
|
assert_nothing_raised("Could not include fully qualified class") {
|
@@ -415,25 +414,23 @@ file { "/tmp/yayness":
|
|
415
414
|
|
416
415
|
def test_topnamespace
|
417
416
|
parser = mkparser
|
418
|
-
parser.interp.clear
|
419
417
|
|
420
418
|
# Make sure we put the top-level code into a class called "" in
|
421
419
|
# the "" namespace
|
422
420
|
assert_nothing_raised do
|
423
421
|
out = parser.parse ""
|
424
422
|
|
425
|
-
|
426
|
-
assert_nil(parser.
|
423
|
+
assert_instance_of(Puppet::Parser::Parser::ASTSet, out)
|
424
|
+
assert_nil(parser.classes[""], "Got a 'main' class when we had no code")
|
427
425
|
end
|
428
426
|
|
429
427
|
# Now try something a touch more complicated
|
430
|
-
parser.
|
428
|
+
parser.initvars
|
431
429
|
assert_nothing_raised do
|
432
430
|
out = parser.parse "Exec { path => '/usr/bin:/usr/sbin' }"
|
433
|
-
assert_instance_of(
|
434
|
-
assert_equal("", parser.
|
435
|
-
assert_equal("", parser.
|
436
|
-
assert_equal(out.object_id, parser.interp.findclass("", "").code.object_id)
|
431
|
+
assert_instance_of(Puppet::Parser::Parser::ASTSet, out)
|
432
|
+
assert_equal("", parser.classes[""].classname)
|
433
|
+
assert_equal("", parser.classes[""].namespace)
|
437
434
|
end
|
438
435
|
end
|
439
436
|
|
@@ -476,18 +473,19 @@ file { "/tmp/yayness":
|
|
476
473
|
ret = parser.parse("#{at}file { '/tmp/testing': owner => root }")
|
477
474
|
end
|
478
475
|
|
479
|
-
|
476
|
+
assert_instance_of(AST::ASTArray, ret.classes[""].code)
|
477
|
+
resdef = ret.classes[""].code[0]
|
478
|
+
assert_instance_of(AST::ResourceDef, resdef)
|
479
|
+
assert_equal("/tmp/testing", resdef.title.value)
|
480
480
|
# We always get an astarray back, so...
|
481
|
-
|
482
|
-
check.call(ret[0], "simple resource")
|
481
|
+
check.call(resdef, "simple resource")
|
483
482
|
|
484
483
|
# Now let's try it with multiple resources in the same spec
|
485
484
|
assert_nothing_raised do
|
486
485
|
ret = parser.parse("#{at}file { ['/tmp/1', '/tmp/2']: owner => root }")
|
487
486
|
end
|
488
487
|
|
489
|
-
|
490
|
-
ret.each do |res|
|
488
|
+
ret.classes[""].each do |res|
|
491
489
|
assert_instance_of(AST::ResourceDef, res)
|
492
490
|
check.call(res, "multiresource")
|
493
491
|
end
|
@@ -495,11 +493,11 @@ file { "/tmp/yayness":
|
|
495
493
|
# Now evaluate these
|
496
494
|
scope = mkscope
|
497
495
|
|
498
|
-
klass =
|
496
|
+
klass = parser.newclass ""
|
499
497
|
scope.source = klass
|
500
498
|
|
501
499
|
assert_nothing_raised do
|
502
|
-
ret.evaluate :scope => scope
|
500
|
+
ret.classes[""].evaluate :scope => scope
|
503
501
|
end
|
504
502
|
|
505
503
|
# Make sure we can find both of them
|
@@ -527,16 +525,14 @@ file { "/tmp/yayness":
|
|
527
525
|
arrow = "<<||>>"
|
528
526
|
end
|
529
527
|
|
530
|
-
check = proc do |coll|
|
531
|
-
assert_instance_of(AST::Collection, coll)
|
532
|
-
assert_equal(form, coll.form)
|
533
|
-
end
|
534
|
-
|
535
528
|
ret = nil
|
536
529
|
assert_nothing_raised do
|
537
530
|
ret = parser.parse("File #{arrow}")
|
538
531
|
end
|
539
|
-
|
532
|
+
|
533
|
+
coll = ret.classes[""].code[0]
|
534
|
+
assert_instance_of(AST::Collection, coll)
|
535
|
+
assert_equal(form, coll.form)
|
540
536
|
end
|
541
537
|
end
|
542
538
|
|
@@ -548,7 +544,7 @@ file { "/tmp/yayness":
|
|
548
544
|
|
549
545
|
res = nil
|
550
546
|
assert_nothing_raised do
|
551
|
-
res = parser.parse(str)[0]
|
547
|
+
res = parser.parse(str).classes[""].code[0]
|
552
548
|
end
|
553
549
|
|
554
550
|
assert_instance_of(AST::Collection, res)
|
@@ -571,7 +567,7 @@ file { "/tmp/yayness":
|
|
571
567
|
|
572
568
|
res = nil
|
573
569
|
assert_nothing_raised do
|
574
|
-
res = parser.parse(str)[0]
|
570
|
+
res = parser.parse(str).classes[""].code[0]
|
575
571
|
end
|
576
572
|
|
577
573
|
assert_instance_of(AST::Collection, res)
|
@@ -595,7 +591,7 @@ file { "/tmp/yayness":
|
|
595
591
|
|
596
592
|
res = nil
|
597
593
|
assert_nothing_raised("Could not parse '#{test}'") do
|
598
|
-
res = parser.parse(str)[0]
|
594
|
+
res = parser.parse(str).classes[""].code[0]
|
599
595
|
end
|
600
596
|
|
601
597
|
assert_instance_of(AST::Collection, res)
|
@@ -634,13 +630,11 @@ file { "/tmp/yayness":
|
|
634
630
|
|
635
631
|
def test_fully_qualified_definitions
|
636
632
|
parser = mkparser
|
637
|
-
interp = parser.interp
|
638
633
|
|
639
634
|
assert_nothing_raised("Could not parse fully-qualified definition") {
|
640
635
|
parser.parse %{define one::two { }}
|
641
636
|
}
|
642
|
-
assert(
|
643
|
-
assert(interp.finddefine("one", "two"), "Could not find two in namespace one")
|
637
|
+
assert(parser.definitions["one::two"], "Could not find one::two with no namespace")
|
644
638
|
|
645
639
|
# Now try using the definition
|
646
640
|
assert_nothing_raised("Could not parse fully-qualified definition usage") {
|
@@ -772,10 +766,415 @@ file { "/tmp/yayness":
|
|
772
766
|
result = parser.parse %{$variable = undef}
|
773
767
|
}
|
774
768
|
|
775
|
-
|
776
|
-
|
777
|
-
assert_instance_of(AST::
|
769
|
+
main = result.classes[""].code
|
770
|
+
children = main.children
|
771
|
+
assert_instance_of(AST::VarDef, main.children[0])
|
772
|
+
assert_instance_of(AST::Undef, main.children[0].value)
|
773
|
+
end
|
774
|
+
|
775
|
+
# Prompted by #729 -- parsing should not modify the interpreter.
|
776
|
+
def test_parse
|
777
|
+
parser = mkparser
|
778
|
+
|
779
|
+
str = "file { '/tmp/yay': ensure => file }\nclass yay {}\nnode foo {}\ndefine bar {}\n"
|
780
|
+
result = nil
|
781
|
+
assert_nothing_raised("Could not parse") do
|
782
|
+
result = parser.parse(str)
|
783
|
+
end
|
784
|
+
assert_instance_of(Puppet::Parser::Parser::ASTSet, result, "Did not get a ASTSet back from parsing")
|
785
|
+
|
786
|
+
assert_instance_of(AST::HostClass, result.classes["yay"], "Did not create 'yay' class")
|
787
|
+
assert_instance_of(AST::HostClass, result.classes[""], "Did not create main class")
|
788
|
+
assert_instance_of(AST::Component, result.definitions["bar"], "Did not create 'bar' definition")
|
789
|
+
assert_instance_of(AST::Node, result.nodes["foo"], "Did not create 'foo' node")
|
790
|
+
end
|
791
|
+
|
792
|
+
# Make sure our node gets added to the node table.
|
793
|
+
def test_newnode
|
794
|
+
parser = mkparser
|
795
|
+
|
796
|
+
# First just try calling it directly
|
797
|
+
assert_nothing_raised {
|
798
|
+
parser.newnode("mynode", :code => :yay)
|
799
|
+
}
|
800
|
+
|
801
|
+
assert_equal(:yay, parser.nodes["mynode"].code)
|
802
|
+
|
803
|
+
# Now make sure that trying to redefine it throws an error.
|
804
|
+
assert_raise(Puppet::ParseError) {
|
805
|
+
parser.newnode("mynode", {})
|
806
|
+
}
|
807
|
+
|
808
|
+
# Now try one with no code
|
809
|
+
assert_nothing_raised {
|
810
|
+
parser.newnode("simplenode", :parent => :foo)
|
811
|
+
}
|
812
|
+
|
813
|
+
# Now define the parent node
|
814
|
+
parser.newnode(:foo)
|
815
|
+
|
816
|
+
# And make sure we get things back correctly
|
817
|
+
assert_equal(:foo, parser.nodes["simplenode"].parentclass)
|
818
|
+
assert_nil(parser.nodes["simplenode"].code)
|
819
|
+
|
820
|
+
# Now make sure that trying to redefine it throws an error.
|
821
|
+
assert_raise(Puppet::ParseError) {
|
822
|
+
parser.newnode("mynode", {})
|
823
|
+
}
|
824
|
+
|
825
|
+
# Test multiple names
|
826
|
+
names = ["one", "two", "three"]
|
827
|
+
assert_nothing_raised {
|
828
|
+
parser.newnode(names, {:code => :yay, :parent => :foo})
|
829
|
+
}
|
830
|
+
|
831
|
+
names.each do |name|
|
832
|
+
assert_equal(:yay, parser.nodes[name].code)
|
833
|
+
assert_equal(:foo, parser.nodes[name].parentclass)
|
834
|
+
# Now make sure that trying to redefine it throws an error.
|
835
|
+
assert_raise(Puppet::ParseError) {
|
836
|
+
parser.newnode(name, {})
|
837
|
+
}
|
838
|
+
end
|
839
|
+
end
|
840
|
+
|
841
|
+
def test_newdefine
|
842
|
+
parser = mkparser
|
843
|
+
|
844
|
+
assert_nothing_raised {
|
845
|
+
parser.newdefine("mydefine", :code => :yay,
|
846
|
+
:arguments => ["a", stringobj("b")])
|
847
|
+
}
|
848
|
+
|
849
|
+
mydefine = parser.definitions["mydefine"]
|
850
|
+
assert(mydefine, "Could not find definition")
|
851
|
+
assert_equal("", mydefine.namespace)
|
852
|
+
assert_equal("mydefine", mydefine.classname)
|
853
|
+
|
854
|
+
assert_raise(Puppet::ParseError) do
|
855
|
+
parser.newdefine("mydefine", :code => :yay,
|
856
|
+
:arguments => ["a", stringobj("b")])
|
857
|
+
end
|
858
|
+
|
859
|
+
# Now define the same thing in a different scope
|
860
|
+
assert_nothing_raised {
|
861
|
+
parser.newdefine("other::mydefine", :code => :other,
|
862
|
+
:arguments => ["a", stringobj("b")])
|
863
|
+
}
|
864
|
+
other = parser.definitions["other::mydefine"]
|
865
|
+
assert(other, "Could not find definition")
|
866
|
+
assert(parser.definitions["other::mydefine"],
|
867
|
+
"Could not find other::mydefine")
|
868
|
+
assert_equal(:other, other.code)
|
869
|
+
assert_equal("other", other.namespace)
|
870
|
+
assert_equal("other::mydefine", other.classname)
|
871
|
+
end
|
872
|
+
|
873
|
+
def test_newclass
|
874
|
+
parser = mkparser
|
875
|
+
|
876
|
+
mkcode = proc do |ary|
|
877
|
+
classes = ary.collect do |string|
|
878
|
+
AST::FlatString.new(:value => string)
|
879
|
+
end
|
880
|
+
AST::ASTArray.new(:children => classes)
|
881
|
+
end
|
882
|
+
|
883
|
+
scope = Puppet::Parser::Scope.new(:interp => mkinterp)
|
884
|
+
|
885
|
+
# First make sure that code is being appended
|
886
|
+
code = mkcode.call(%w{original code})
|
887
|
+
|
888
|
+
klass = nil
|
889
|
+
assert_nothing_raised {
|
890
|
+
klass = parser.newclass("myclass", :code => code)
|
891
|
+
}
|
892
|
+
|
893
|
+
assert(klass, "Did not return class")
|
894
|
+
|
895
|
+
assert(parser.classes["myclass"], "Could not find definition")
|
896
|
+
assert_equal("myclass", parser.classes["myclass"].classname)
|
897
|
+
assert_equal(%w{original code},
|
898
|
+
parser.classes["myclass"].code.evaluate(:scope => scope))
|
899
|
+
|
900
|
+
# Newclass behaves differently than the others -- it just appends
|
901
|
+
# the code to the existing class.
|
902
|
+
code = mkcode.call(%w{something new})
|
903
|
+
assert_nothing_raised do
|
904
|
+
klass = parser.newclass("myclass", :code => code)
|
905
|
+
end
|
906
|
+
assert(klass, "Did not return class when appending")
|
907
|
+
assert_equal(%w{original code something new},
|
908
|
+
parser.classes["myclass"].code.evaluate(:scope => scope))
|
909
|
+
|
910
|
+
# Now create the same class name in a different scope
|
911
|
+
assert_nothing_raised {
|
912
|
+
klass = parser.newclass("other::myclass",
|
913
|
+
:code => mkcode.call(%w{something diff}))
|
914
|
+
}
|
915
|
+
assert(klass, "Did not return class")
|
916
|
+
other = parser.classes["other::myclass"]
|
917
|
+
assert(other, "Could not find class")
|
918
|
+
assert_equal("other::myclass", other.classname)
|
919
|
+
assert_equal("other::myclass", other.namespace)
|
920
|
+
assert_equal(%w{something diff},
|
921
|
+
other.code.evaluate(:scope => scope))
|
922
|
+
|
923
|
+
# Make sure newclass deals correctly with nodes with no code
|
924
|
+
klass = parser.newclass("nocode")
|
925
|
+
assert(klass, "Did not return class")
|
926
|
+
|
927
|
+
assert_nothing_raised do
|
928
|
+
klass = parser.newclass("nocode", :code => mkcode.call(%w{yay test}))
|
929
|
+
end
|
930
|
+
assert(klass, "Did not return class with no code")
|
931
|
+
assert_equal(%w{yay test},
|
932
|
+
parser.classes["nocode"].code.evaluate(:scope => scope))
|
933
|
+
|
934
|
+
# Then try merging something into nothing
|
935
|
+
parser.newclass("nocode2", :code => mkcode.call(%w{foo test}))
|
936
|
+
assert(klass, "Did not return class with no code")
|
937
|
+
|
938
|
+
assert_nothing_raised do
|
939
|
+
klass = parser.newclass("nocode2")
|
940
|
+
end
|
941
|
+
assert(klass, "Did not return class with no code")
|
942
|
+
assert_equal(%w{foo test},
|
943
|
+
parser.classes["nocode2"].code.evaluate(:scope => scope))
|
944
|
+
|
945
|
+
# And lastly, nothing and nothing
|
946
|
+
klass = parser.newclass("nocode3")
|
947
|
+
assert(klass, "Did not return class with no code")
|
948
|
+
|
949
|
+
assert_nothing_raised do
|
950
|
+
klass = parser.newclass("nocode3")
|
951
|
+
end
|
952
|
+
assert(klass, "Did not return class with no code")
|
953
|
+
assert_nil(parser.classes["nocode3"].code)
|
954
|
+
end
|
955
|
+
|
956
|
+
# Make sure you can't have classes and defines with the same name in the
|
957
|
+
# same scope.
|
958
|
+
def test_classes_beat_defines
|
959
|
+
parser = mkparser
|
960
|
+
|
961
|
+
assert_nothing_raised {
|
962
|
+
parser.newclass("yay::funtest")
|
963
|
+
}
|
964
|
+
|
965
|
+
assert_raise(Puppet::ParseError) do
|
966
|
+
parser.newdefine("yay::funtest")
|
967
|
+
end
|
968
|
+
|
969
|
+
assert_nothing_raised {
|
970
|
+
parser.newdefine("yay::yaytest")
|
971
|
+
}
|
972
|
+
|
973
|
+
assert_raise(Puppet::ParseError) do
|
974
|
+
parser.newclass("yay::yaytest")
|
975
|
+
end
|
976
|
+
end
|
977
|
+
|
978
|
+
def test_namesplit
|
979
|
+
parser = mkparser
|
980
|
+
|
981
|
+
assert_nothing_raised do
|
982
|
+
{"base::sub" => %w{base sub},
|
983
|
+
"main" => ["", "main"],
|
984
|
+
"one::two::three::four" => ["one::two::three", "four"],
|
985
|
+
}.each do |name, ary|
|
986
|
+
result = parser.namesplit(name)
|
987
|
+
assert_equal(ary, result, "%s split to %s" % [name, result])
|
988
|
+
end
|
989
|
+
end
|
990
|
+
end
|
991
|
+
|
992
|
+
# Now make sure we get appropriate behaviour with parent class conflicts.
|
993
|
+
def test_newclass_parentage
|
994
|
+
parser = mkparser
|
995
|
+
parser.newclass("base1")
|
996
|
+
parser.newclass("one::two::three")
|
997
|
+
|
998
|
+
# First create it with no parentclass.
|
999
|
+
assert_nothing_raised {
|
1000
|
+
parser.newclass("sub")
|
1001
|
+
}
|
1002
|
+
assert(parser.classes["sub"], "Could not find definition")
|
1003
|
+
assert_nil(parser.classes["sub"].parentclass)
|
1004
|
+
|
1005
|
+
# Make sure we can't set the parent class to ourself.
|
1006
|
+
assert_raise(Puppet::ParseError) {
|
1007
|
+
parser.newclass("sub", :parent => "sub")
|
1008
|
+
}
|
1009
|
+
|
1010
|
+
# Now create another one, with a parentclass.
|
1011
|
+
assert_nothing_raised {
|
1012
|
+
parser.newclass("sub", :parent => "base1")
|
1013
|
+
}
|
1014
|
+
|
1015
|
+
# Make sure we get the right parent class, and make sure it's not an object.
|
1016
|
+
assert_equal("base1",
|
1017
|
+
parser.classes["sub"].parentclass)
|
1018
|
+
|
1019
|
+
# Now make sure we get a failure if we try to conflict.
|
1020
|
+
assert_raise(Puppet::ParseError) {
|
1021
|
+
parser.newclass("sub", :parent => "one::two::three")
|
1022
|
+
}
|
1023
|
+
|
1024
|
+
# Make sure that failure didn't screw us up in any way.
|
1025
|
+
assert_equal("base1",
|
1026
|
+
parser.classes["sub"].parentclass)
|
1027
|
+
# But make sure we can create a class with a fq parent
|
1028
|
+
assert_nothing_raised {
|
1029
|
+
parser.newclass("another", :parent => "one::two::three")
|
1030
|
+
}
|
1031
|
+
assert_equal("one::two::three",
|
1032
|
+
parser.classes["another"].parentclass)
|
1033
|
+
|
1034
|
+
end
|
1035
|
+
|
1036
|
+
def test_fqfind
|
1037
|
+
parser = mkparser
|
1038
|
+
|
1039
|
+
table = {}
|
1040
|
+
# Define a bunch of things.
|
1041
|
+
%w{a c a::b a::b::c a::c a::b::c::d a::b::c::d::e::f c::d}.each do |string|
|
1042
|
+
table[string] = string
|
1043
|
+
end
|
1044
|
+
|
1045
|
+
check = proc do |namespace, hash|
|
1046
|
+
hash.each do |thing, result|
|
1047
|
+
assert_equal(result, parser.fqfind(namespace, thing, table),
|
1048
|
+
"Could not find %s in %s" % [thing, namespace])
|
1049
|
+
end
|
1050
|
+
end
|
1051
|
+
|
1052
|
+
# Now let's do some test lookups.
|
1053
|
+
|
1054
|
+
# First do something really simple
|
1055
|
+
check.call "a", "b" => "a::b", "b::c" => "a::b::c", "d" => nil, "::c" => "c"
|
1056
|
+
|
1057
|
+
check.call "a::b", "c" => "a::b::c", "b" => "a::b", "a" => "a"
|
1058
|
+
|
1059
|
+
check.call "a::b::c::d::e", "c" => "a::b::c", "::c" => "c",
|
1060
|
+
"c::d" => "a::b::c::d", "::c::d" => "c::d"
|
1061
|
+
|
1062
|
+
check.call "", "a" => "a", "a::c" => "a::c"
|
1063
|
+
end
|
1064
|
+
|
1065
|
+
# Setup a module.
|
1066
|
+
def mk_module(name, files = {})
|
1067
|
+
mdir = File.join(@dir, name)
|
1068
|
+
mandir = File.join(mdir, "manifests")
|
1069
|
+
FileUtils.mkdir_p mandir
|
1070
|
+
|
1071
|
+
if defs = files[:define]
|
1072
|
+
files.delete(:define)
|
1073
|
+
end
|
1074
|
+
Dir.chdir(mandir) do
|
1075
|
+
files.each do |file, classes|
|
1076
|
+
File.open("%s.pp" % file, "w") do |f|
|
1077
|
+
classes.each { |klass|
|
1078
|
+
if defs
|
1079
|
+
f.puts "define %s {}" % klass
|
1080
|
+
else
|
1081
|
+
f.puts "class %s {}" % klass
|
1082
|
+
end
|
1083
|
+
}
|
1084
|
+
end
|
1085
|
+
end
|
1086
|
+
end
|
1087
|
+
end
|
1088
|
+
|
1089
|
+
# #596 - make sure classes and definitions load automatically if they're in modules, so we don't have to manually load each one.
|
1090
|
+
def test_module_autoloading
|
1091
|
+
@dir = tempfile
|
1092
|
+
Puppet[:modulepath] = @dir
|
1093
|
+
|
1094
|
+
FileUtils.mkdir_p @dir
|
1095
|
+
|
1096
|
+
parser = mkparser
|
1097
|
+
|
1098
|
+
# Make sure we fail like normal for actually missing classes
|
1099
|
+
assert_nil(parser.findclass("", "nosuchclass"), "Did not return nil on missing classes")
|
1100
|
+
|
1101
|
+
# test the simple case -- the module class itself
|
1102
|
+
name = "simple"
|
1103
|
+
mk_module(name, :init => [name])
|
1104
|
+
|
1105
|
+
# Try to load the module automatically now
|
1106
|
+
klass = parser.findclass("", name)
|
1107
|
+
assert_instance_of(AST::HostClass, klass, "Did not autoload class from module init file")
|
1108
|
+
assert_equal(name, klass.classname, "Incorrect class was returned")
|
1109
|
+
|
1110
|
+
# Try loading the simple module when we're in something other than the base namespace.
|
1111
|
+
parser = mkparser
|
1112
|
+
klass = parser.findclass("something::else", name)
|
1113
|
+
assert_instance_of(AST::HostClass, klass, "Did not autoload class from module init file")
|
1114
|
+
assert_equal(name, klass.classname, "Incorrect class was returned")
|
1115
|
+
|
1116
|
+
# Now try it with a definition as the base file
|
1117
|
+
name = "simpdef"
|
1118
|
+
mk_module(name, :define => true, :init => [name])
|
1119
|
+
|
1120
|
+
klass = parser.finddefine("", name)
|
1121
|
+
assert_instance_of(AST::Component, klass, "Did not autoload class from module init file")
|
1122
|
+
assert_equal(name, klass.classname, "Incorrect class was returned")
|
1123
|
+
|
1124
|
+
# Now try it with namespace classes where both classes are in the init file
|
1125
|
+
parser = mkparser
|
1126
|
+
modname = "both"
|
1127
|
+
name = "sub"
|
1128
|
+
mk_module(modname, :init => %w{both both::sub})
|
1129
|
+
|
1130
|
+
# First try it with a namespace
|
1131
|
+
klass = parser.findclass("both", name)
|
1132
|
+
assert_instance_of(AST::HostClass, klass, "Did not autoload sub class from module init file with a namespace")
|
1133
|
+
assert_equal("both::sub", klass.classname, "Incorrect class was returned")
|
1134
|
+
|
1135
|
+
# Now try it using the fully qualified name
|
1136
|
+
parser = mkparser
|
1137
|
+
klass = parser.findclass("", "both::sub")
|
1138
|
+
assert_instance_of(AST::HostClass, klass, "Did not autoload sub class from module init file with no namespace")
|
1139
|
+
assert_equal("both::sub", klass.classname, "Incorrect class was returned")
|
1140
|
+
|
1141
|
+
|
1142
|
+
# Now try it with the class in a different file
|
1143
|
+
parser = mkparser
|
1144
|
+
modname = "separate"
|
1145
|
+
name = "sub"
|
1146
|
+
mk_module(modname, :init => %w{separate}, :sub => %w{separate::sub})
|
1147
|
+
|
1148
|
+
# First try it with a namespace
|
1149
|
+
klass = parser.findclass("separate", name)
|
1150
|
+
assert_instance_of(AST::HostClass, klass, "Did not autoload sub class from separate file with a namespace")
|
1151
|
+
assert_equal("separate::sub", klass.classname, "Incorrect class was returned")
|
1152
|
+
|
1153
|
+
# Now try it using the fully qualified name
|
1154
|
+
parser = mkparser
|
1155
|
+
klass = parser.findclass("", "separate::sub")
|
1156
|
+
assert_instance_of(AST::HostClass, klass, "Did not autoload sub class from separate file with no namespace")
|
1157
|
+
assert_equal("separate::sub", klass.classname, "Incorrect class was returned")
|
1158
|
+
|
1159
|
+
# Now make sure we don't get a failure when there's no module file
|
1160
|
+
parser = mkparser
|
1161
|
+
modname = "alone"
|
1162
|
+
name = "sub"
|
1163
|
+
mk_module(modname, :sub => %w{alone::sub})
|
1164
|
+
|
1165
|
+
# First try it with a namespace
|
1166
|
+
assert_nothing_raised("Could not autoload file when module file is missing") do
|
1167
|
+
klass = parser.findclass("alone", name)
|
1168
|
+
end
|
1169
|
+
assert_instance_of(AST::HostClass, klass, "Did not autoload sub class from alone file with a namespace")
|
1170
|
+
assert_equal("alone::sub", klass.classname, "Incorrect class was returned")
|
1171
|
+
|
1172
|
+
# Now try it using the fully qualified name
|
1173
|
+
parser = mkparser
|
1174
|
+
klass = parser.findclass("", "alone::sub")
|
1175
|
+
assert_instance_of(AST::HostClass, klass, "Did not autoload sub class from alone file with no namespace")
|
1176
|
+
assert_equal("alone::sub", klass.classname, "Incorrect class was returned")
|
778
1177
|
end
|
779
1178
|
end
|
780
1179
|
|
781
|
-
# $Id: parser.rb
|
1180
|
+
# $Id: parser.rb 2742 2007-08-03 23:49:53Z luke $
|