513
522
"File got created even tho its deep dependency failed")
517
def test_relationship_graph
520
config.meta_def(:f) do |name|
521
self.resource("File[%s]" % name)
524
{"one" => "two", "File[f]" => "File[c]", "File[h]" => "middle"}.each do |source_ref, target_ref|
525
source = config.resource(source_ref) or raise "Missing %s" % source_ref
526
target = config.resource(target_ref) or raise "Missing %s" % target_ref
527
target[:require] = source
530
trans = Puppet::Transaction.new(config)
533
assert_nothing_raised do
534
graph = trans.relationship_graph
537
assert_instance_of(Puppet::Node::Catalog, graph,
538
"Did not get relationship graph")
540
# Make sure all of the components are gone
541
comps = graph.vertices.find_all { |v| v.is_a?(Puppet::Type::Component)}
542
assert(comps.empty?, "Deps graph still contains components %s" %
543
comps.collect { |c| c.ref }.join(","))
545
assert_equal([], comps, "Deps graph still contains components")
547
# It must be reversed because of how topsort works
548
sorted = graph.topsort.reverse
550
# Now make sure the appropriate edges are there and are in the right order
551
assert(graph.dependents(config.f(:f)).include?(config.f(:c)),
552
"c not marked a dep of f")
553
assert(sorted.index(config.f(:c)) < sorted.index(config.f(:f)),
556
config.resource("one").each do |o|
557
config.resource("two").each do |t|
558
assert(graph.dependents(o).include?(t),
559
"%s not marked a dep of %s" % [t.ref, o.ref])
560
assert(sorted.index(t) < sorted.index(o),
561
"%s is not before %s" % [t.ref, o.ref])
565
trans.catalog.leaves(config.resource("middle")).each do |child|
566
assert(graph.dependents(config.f(:h)).include?(child),
567
"%s not marked a dep of h" % [child.ref])
568
assert(sorted.index(child) < sorted.index(config.f(:h)),
569
"%s is not before h" % child.ref)
572
# Lastly, make sure our 'g' vertex made it into the relationship
573
# graph, since it's not involved in any relationships.
574
assert(graph.vertex?(config.f(:g)),
575
"Lost vertexes with no relations")
577
# Now make the reversal graph and make sure all of the vertices made it into that
578
reverse = graph.reversal
579
%w{a b c d e f g h}.each do |letter|
580
file = config.f(letter)
581
assert(reverse.vertex?(file), "%s did not make it into reversal" % letter)
585
# Test pre-evaluation generation
591
ret << self.class.create(:title => title[0..-2])
599
yay = Puppet::Type.newgenerator :title => "yay"
600
rah = Puppet::Type.newgenerator :title => "rah"
601
config = mk_catalog(yay, rah)
602
trans = Puppet::Transaction.new(config)
604
assert_nothing_raised do
608
%w{ya ra y r}.each do |name|
609
assert(trans.catalog.vertex?(Puppet::Type.type(:generator)[name]),
610
"Generated %s was not a vertex" % name)
611
assert($finished.include?(name), "%s was not finished" % name)
614
# Now make sure that cleanup gets rid of those generated types.
615
assert_nothing_raised do
619
%w{ya ra y r}.each do |name|
620
assert(!trans.catalog.vertex?(Puppet::Type.type(:generator)[name]),
621
"Generated vertex %s was not removed from graph" % name)
622
assert_nil(Puppet::Type.type(:generator)[name],
623
"Generated vertex %s was not removed from class" % name)
627
# Test mid-evaluation generation.
628
def test_eval_generate
630
cleanup { $evaluated = nil }
631
type = mkreducer() do
633
$evaluated << self.title
638
yay = Puppet::Type.newgenerator :title => "yay"
639
rah = Puppet::Type.newgenerator :title => "rah", :subscribe => yay
640
config = mk_catalog(yay, rah)
641
trans = Puppet::Transaction.new(config)
645
# Now apply the resources, and make sure they appropriately generate
647
assert_nothing_raised("failed to apply yay") do
648
trans.eval_resource(yay)
651
assert(ya, "Did not generate ya")
652
assert(trans.relationship_graph.vertex?(ya),
653
"Did not add ya to rel_graph")
655
# Now make sure the appropriate relationships were added
656
assert(trans.relationship_graph.edge?(yay, ya),
657
"parent was not required by child")
658
assert(! trans.relationship_graph.edge?(ya, rah),
659
"generated child ya inherited depencency on rah")
661
# Now make sure it in turn eval_generates appropriately
662
assert_nothing_raised("failed to apply yay") do
663
trans.eval_resource(type["ya"])
668
assert(res, "Did not generate %s" % name)
669
assert(trans.relationship_graph.vertex?(res),
670
"Did not add %s to rel_graph" % name)
671
assert($finished.include?("y"), "y was not finished")
674
assert_nothing_raised("failed to eval_generate with nil response") do
675
trans.eval_resource(type["y"])
677
assert(trans.relationship_graph.edge?(yay, ya), "no edge was created for ya => yay")
679
assert_nothing_raised("failed to apply rah") do
680
trans.eval_resource(rah)
684
assert(ra, "Did not generate ra")
685
assert(trans.relationship_graph.vertex?(ra),
686
"Did not add ra to rel_graph" % name)
687
assert($finished.include?("ra"), "y was not finished")
689
# Now make sure this generated resource has the same relationships as
690
# the generating resource
691
assert(! trans.relationship_graph.edge?(yay, ra),
692
"rah passed its dependencies on to its children")
693
assert(! trans.relationship_graph.edge?(ya, ra),
694
"children have a direct relationship")
696
# Now make sure that cleanup gets rid of those generated types.
697
assert_nothing_raised do
701
%w{ya ra y r}.each do |name|
702
assert(!trans.relationship_graph.vertex?(type[name]),
703
"Generated vertex %s was not removed from graph" % name)
704
assert_nil(type[name],
705
"Generated vertex %s was not removed from class" % name)
708
# Now, start over and make sure that everything gets evaluated.
709
trans = Puppet::Transaction.new(config)
711
assert_nothing_raised do
715
assert_equal(%w{yay ya y rah ra r}, $evaluated,
716
"Not all resources were evaluated or not in the right order")
719
526
# We need to generate resources before we prefetch them, else generated
720
527
# resources that require prefetching don't work.
912
719
assert(trans.triggered?(c, :refresh),
913
720
"Transaction did not store the trigger")
916
723
def test_set_target
917
file = Puppet::Type.type(:file).create(:path => tempfile(), :content => "yay")
918
exec1 = Puppet::Type.type(:exec).create :command => "/bin/echo exec1"
919
exec2 = Puppet::Type.type(:exec).create :command => "/bin/echo exec2"
724
file = Puppet::Type.type(:file).new(:path => tempfile(), :content => "yay")
725
exec1 = Puppet::Type.type(:exec).new :command => "/bin/echo exec1"
726
exec2 = Puppet::Type.type(:exec).new :command => "/bin/echo exec2"
920
727
trans = Puppet::Transaction.new(mk_catalog(file, exec1, exec2))
922
729
# First try it with an edge that has no callback
923
730
edge = Puppet::Relationship.new(file, exec1)
924
731
assert_nothing_raised { trans.set_trigger(edge) }
925
732
assert(! trans.targeted?(exec1), "edge with no callback resulted in a target")
927
734
# Now with an edge that has an unsupported callback
928
735
edge = Puppet::Relationship.new(file, exec1, :callback => :nosuchmethod, :event => :ALL_EVENTS)
929
736
assert_nothing_raised { trans.set_trigger(edge) }
930
737
assert(! trans.targeted?(exec1), "edge with invalid callback resulted in a target")
932
739
# Lastly, with an edge with a supported callback
933
740
edge = Puppet::Relationship.new(file, exec1, :callback => :refresh, :event => :ALL_EVENTS)
934
741
assert_nothing_raised { trans.set_trigger(edge) }
935
742
assert(trans.targeted?(exec1), "edge with valid callback did not result in a target")
938
745
# Testing #401 -- transactions are calling refresh() on classes that don't support it.
939
746
def test_callback_availability
1005
816
cleanup { Puppet::Type.rmtype(:refresher)}
1007
obj = type.create(:name => "yay", :testing => "cool")
818
obj = type.new(:name => "yay", :testing => "cool")
1009
820
assert(! obj.insync?(obj.retrieve), "fake object is already in sync")
1011
822
# Now make sure it gets refreshed when the change happens
1012
823
assert_apply(obj)
1013
824
assert(obj.refreshed, "object was not refreshed during transaction")
1017
828
def test_explicit_dependencies_beat_automatic
1018
829
# Create a couple of different resource sets that have automatic relationships and make sure the manual relationships win
1020
831
# First users and groups
1021
group = Puppet::Type.type(:group).create(:name => nonrootgroup.name, :ensure => :present)
1022
user = Puppet::Type.type(:user).create(:name => nonrootuser.name, :ensure => :present, :gid => group.title)
832
group = Puppet::Type.type(:group).new(:name => nonrootgroup.name, :ensure => :present)
833
user = Puppet::Type.type(:user).new(:name => nonrootuser.name, :ensure => :present, :gid => group.title)
1024
835
# Now add the explicit relationship
1025
836
group[:require] = user
1026
837
rels[group] = user
1029
840
f = File.join(d, "file")
1030
file = Puppet::Type.type(:file).create(:path => f, :content => "yay")
1031
dir = Puppet::Type.type(:file).create(:path => d, :ensure => :directory, :require => file)
841
file = Puppet::Type.type(:file).new(:path => f, :content => "yay")
842
dir = Puppet::Type.type(:file).new(:path => d, :ensure => :directory, :require => file)
1033
844
rels[dir] = file
1034
845
rels.each do |after, before|
1035
846
config = mk_catalog(before, after)
1036
847
trans = Puppet::Transaction.new(config)
1037
848
str = "from %s to %s" % [before, after]
1039
850
assert_nothing_raised("Failed to create graph %s" % str) do
1043
854
graph = trans.relationship_graph
1044
855
assert(graph.edge?(before, after), "did not create manual relationship %s" % str)
1045
856
assert(! graph.edge?(after, before), "created automatic relationship %s" % str)