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.

Files changed (55) hide show
  1. data/CHANGELOG +31 -0
  2. data/bin/puppetd +2 -1
  3. data/conf/redhat/puppet.spec +9 -6
  4. data/conf/redhat/server.init +4 -5
  5. data/examples/code/mac_dscl.pp +28 -0
  6. data/examples/code/mac_dscl_revert.pp +26 -0
  7. data/examples/code/mac_netinfo.pp +5 -0
  8. data/examples/code/mac_pkgdmg.pp +7 -0
  9. data/ext/puppet-test +69 -2
  10. data/lib/puppet.rb +2 -2
  11. data/lib/puppet/configuration.rb +5 -1
  12. data/lib/puppet/network/server/mongrel.rb +3 -3
  13. data/lib/puppet/parser/ast.rb +2 -2
  14. data/lib/puppet/parser/ast/component.rb +3 -3
  15. data/lib/puppet/parser/ast/node.rb +2 -2
  16. data/lib/puppet/parser/collector.rb +2 -2
  17. data/lib/puppet/parser/interpreter.rb +38 -215
  18. data/lib/puppet/parser/parser.rb +11 -228
  19. data/lib/puppet/parser/parser_support.rb +447 -0
  20. data/lib/puppet/parser/resource/param.rb +2 -2
  21. data/lib/puppet/provider.rb +5 -3
  22. data/lib/puppet/provider/cron/crontab.rb +22 -9
  23. data/lib/puppet/provider/group/directoryservice.rb +23 -0
  24. data/lib/puppet/provider/interface/redhat.rb +251 -0
  25. data/lib/puppet/provider/interface/sunos.rb +116 -0
  26. data/lib/puppet/provider/mount.rb +4 -1
  27. data/lib/puppet/provider/nameservice/directoryservice.rb +341 -0
  28. data/lib/puppet/provider/package/dpkg.rb +2 -2
  29. data/lib/puppet/provider/package/openbsd.rb +2 -2
  30. data/lib/puppet/provider/package/rpm.rb +2 -4
  31. data/lib/puppet/provider/package/sun.rb +2 -2
  32. data/lib/puppet/provider/parsedfile.rb +32 -29
  33. data/lib/puppet/provider/user/directoryservice.rb +116 -0
  34. data/lib/puppet/rails/host.rb +1 -1
  35. data/lib/puppet/reference/configuration.rb +7 -4
  36. data/lib/puppet/type/interface.rb +57 -0
  37. data/lib/puppet/type/pfile/group.rb +2 -2
  38. data/lib/puppet/util/config.rb +10 -3
  39. data/lib/puppet/util/fileparsing.rb +2 -2
  40. data/test/language/ast/hostclass.rb +1 -17
  41. data/test/language/interpreter.rb +18 -388
  42. data/test/language/node.rb +8 -8
  43. data/test/language/parser.rb +444 -45
  44. data/test/lib/puppettest/parsertesting.rb +2 -2
  45. data/test/lib/puppettest/support/collection.rb +2 -2
  46. data/test/network/server/mongrel_test.rb +24 -3
  47. data/test/rails/collection.rb +34 -1
  48. data/test/ral/providers/cron/crontab.rb +198 -40
  49. data/test/ral/providers/mount/parsed.rb +69 -46
  50. data/test/ral/providers/parsedfile.rb +20 -28
  51. data/test/ral/types/cron.rb +20 -24
  52. data/test/ral/types/interface.rb +40 -0
  53. data/test/ral/types/package.rb +6 -2
  54. data/test/util/config.rb +106 -30
  55. metadata +14 -2
@@ -61,29 +61,29 @@ class TestParser < Test::Unit::TestCase
61
61
  end
62
62
  interp = nil
63
63
  code ||= "node #{hostnames.join(", ")} { }"
64
- assert_nothing_raised {
65
- interp = mkinterp :Code => code
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
- interp.send(:parsefiles)
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(interp.nodesearch(name),
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
- interp = mkinterp :Code => "node #{hostname} { }"
86
- interp.send(:parsefiles)
86
+ parser.parse
87
87
  }
88
88
  end
89
89
 
@@ -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 => parser.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
- assert_instance_of(AST::ASTArray, ret)
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(interp.findclass("", "myclass"), "Could not find myclass")
390
- assert(interp.findclass("", "myclass::other"), "Could not find myclass::other")
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 = interp.findclass("", "container::deep::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 = interp.findclass("", "container::one")
405
+ sub = parser.classes["container::one"]
407
406
  assert(sub, "Could not find one")
408
- assert_equal("container::deep::sub", sub.parentobj.classname)
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
- assert_nil(out)
426
- assert_nil(parser.interp.findclass("", ""))
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.interp.clear
428
+ parser.initvars
431
429
  assert_nothing_raised do
432
430
  out = parser.parse "Exec { path => '/usr/bin:/usr/sbin' }"
433
- assert_instance_of(AST::ASTArray, out)
434
- assert_equal("", parser.interp.findclass("", "").classname)
435
- assert_equal("", parser.interp.findclass("", "").namespace)
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
- assert_equal("/tmp/testing", ret[0].title.value)
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
- assert_instance_of(AST::ResourceDef, ret[0])
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
- assert_instance_of(AST::ASTArray, ret)
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 = scope.interp.newclass ""
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
- check.call(ret[0])
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(interp.finddefine("", "one::two"), "Could not find one::two with no namespace")
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
- children = result.children
776
- assert_instance_of(AST::VarDef, result.children[0])
777
- assert_instance_of(AST::Undef, result.children[0].value)
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 2522 2007-05-17 21:43:51Z luke $
1180
+ # $Id: parser.rb 2742 2007-08-03 23:49:53Z luke $