summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/puppet/pgraph.rb19
-rw-r--r--lib/puppet/transaction.rb5
-rwxr-xr-xtest/other/pgraph.rb97
-rwxr-xr-xtest/other/transactions.rb2
4 files changed, 96 insertions, 27 deletions
diff --git a/lib/puppet/pgraph.rb b/lib/puppet/pgraph.rb
index af8e720cb..fe55533d9 100644
--- a/lib/puppet/pgraph.rb
+++ b/lib/puppet/pgraph.rb
@@ -1,5 +1,3 @@
-#!/usr/bin/env ruby
-#
# Created by Luke A. Kanies on 2006-11-24.
# Copyright (c) 2006. All rights reserved.
@@ -51,8 +49,7 @@ class Puppet::PGraph < GRATR::Digraph
end
# Fail in a somewhat informative way if the graph has become cyclic.
- def check_cycle
- sorted = topsort()
+ def check_cycle(sorted)
return true if sorted.size == size()
bad = []
@@ -120,20 +117,19 @@ class Puppet::PGraph < GRATR::Digraph
# This creates direct relationships where there were previously
# indirect relationships through the containers.
def splice!(other, type)
- vertices.find_all { |v| v.is_a?(type) }.each do |vertex|
+ vertices.find_all { |v| v.is_a?(type) }.each do |container|
# Get the list of children from the other graph.
- #children = other.adjacent(vertex, :direction => :out)
- children = other.leaves(vertex)
+ children = other.adjacent(container, :direction => :out)
# Just remove the container if it's empty.
if children.empty?
- remove_vertex!(vertex)
+ remove_vertex!(container)
next
end
# First create new edges for each of the :in edges
[:in, :out].each do |dir|
- adjacent(vertex, :direction => dir, :type => :edges).each do |edge|
+ adjacent(container, :direction => dir, :type => :edges).each do |edge|
children.each do |child|
if dir == :in
s = edge.source
@@ -160,9 +156,12 @@ class Puppet::PGraph < GRATR::Digraph
[s, t]
end
end
+
+ # Now get rid of the edge, so remove_vertex! works correctly.
+ remove_edge!(edge)
end
end
- remove_vertex!(vertex)
+ remove_vertex!(container)
end
end
diff --git a/lib/puppet/transaction.rb b/lib/puppet/transaction.rb
index 43ee135a6..2a83ea630 100644
--- a/lib/puppet/transaction.rb
+++ b/lib/puppet/transaction.rb
@@ -474,6 +474,9 @@ class Transaction
@relgraph = relationship_graph
@sorted_resources = @relgraph.topsort
+
+ # Now make sure no cycles crept into our graph.
+ @relgraph.check_cycle(@sorted_resources)
end
# Create a graph of all of the relationships in our resource graph.
@@ -507,8 +510,6 @@ class Transaction
# Then splice in the container information
graph.splice!(@resources, Puppet::Type::Component)
- graph.check_cycle
-
graph(graph, :expanded_relationships)
return graph
diff --git a/test/other/pgraph.rb b/test/other/pgraph.rb
index e28decebb..b61241087 100755
--- a/test/other/pgraph.rb
+++ b/test/other/pgraph.rb
@@ -75,37 +75,33 @@ class TestPGraph < Test::Unit::TestCase
empty = Container.new("empty", [])
# Also, add an empty container to top
top.push empty
-
+
contgraph = top.to_graph
-
+
# Now add a couple of child files, so that we can test whether all
# containers get spliced, rather than just components.
-
+
# Now make a dependency graph
deps = Puppet::PGraph.new
-
+
contgraph.vertices.each do |v|
deps.add_vertex(v)
end
-
+
# We have to specify a relationship to our empty container, else it
# never makes it into the dep graph in the first place.
- #{one => two, three => [middle, two, "c"], "f" => "c", "h" => middle, "c" => empty}.each do |source, targets|
{one => two, "f" => "c", "h" => middle, "c" => empty}.each do |source, target|
deps.add_edge!(source, target, :callback => :refresh)
end
-
- #num = 6
- #contgraph.to_jpg(File.expand_path("~/tmp/graphs"), "containers#{num}")
- #contgraph.reversal.to_jpg(File.expand_path("~/tmp/graphs"), "reversal#{num}")
- #deps.to_jpg(File.expand_path("~/tmp/graphs"), "relationships#{num}")
+ #contgraph.to_jpg(File.expand_path("~/Desktop/pics"), "main")
+ #deps.to_jpg(File.expand_path("~/Desktop/pics"), "before")
assert_nothing_raised { deps.splice!(contgraph, Container) }
- #deps.to_jpg(File.expand_path("~/tmp/graphs"), "after_relationships#{num}")
assert(! deps.cyclic?, "Created a cyclic graph")
# Make sure there are no container objects remaining
+ #deps.to_jpg(File.expand_path("~/Desktop/pics"), "after")
c = deps.vertices.find_all { |v| v.is_a?(Container) }
assert(c.empty?, "Still have containers %s" % c.inspect)
@@ -206,15 +202,88 @@ class TestPGraph < Test::Unit::TestCase
if result
assert_raise(Puppet::Error, "%s did not fail" % hash.inspect) do
- graph.check_cycle
+ graph.check_cycle(graph.topsort)
end
else
assert_nothing_raised("%s failed" % hash.inspect) do
- graph.check_cycle
+ graph.check_cycle(graph.topsort)
end
end
end
end
+
+ # This isn't really a unit test, it's just a way to do some graphing with
+ # tons of relationships so we can see how it performs.
+ def disabled_test_lots_of_relationships
+ containers = Puppet::PGraph.new
+ relationships = Puppet::PGraph.new
+ labels = %w{a b c d e}
+ conts = {}
+ vertices = {}
+ labels.each do |label|
+ vertices[label] = []
+ end
+ num = 100
+ num.times do |i|
+ labels.each do |label|
+ vertices[label] << ("%s%s" % [label, i])
+ end
+ end
+ labels.each do |label|
+ conts[label] = Container.new(label, vertices[label])
+ end
+
+ conts.each do |label, cont|
+ cont.each do |child|
+ containers.add_edge!(cont, child)
+ end
+ end
+ prev = nil
+ labels.inject(nil) do |prev, label|
+ if prev
+ containers.add_edge!(conts[prev], conts[label])
+ end
+ label
+ end
+
+ containers.to_jpg(File.expand_path("~/Desktop/pics/lots"), "start")
+
+ # Now create the relationship graph
+
+ # Make everything in both b and c require d1
+ %w{b c}.each do |label|
+ conts[label].each do |v|
+ relationships.add_edge!(v, "d1")
+ #relationships.add_edge!(v, conts["d"])
+ end
+ end
+
+ # Make most in b also require the appropriate thing in c
+ conts["b"].each do |v|
+ i = v.split('')[1]
+
+ relationships.add_edge!(v, "c%s" % i)
+ end
+
+ # And make d1 require most of e
+ num.times do |i|
+ relationships.add_edge!("d1", "e%s" % i)
+ end
+
+ containers.vertices.each do |v|
+ relationships.add_vertex!(v)
+ end
+ relationships.to_jpg(File.expand_path("~/Desktop/pics/lots"), "relationships")
+
+ time = Benchmark.realtime do
+ relationships.splice!(containers, Container)
+ end
+ relationships.to_jpg(File.expand_path("~/Desktop/pics/lots"), "final")
+ puts time
+ time = Benchmark.realtime do
+ relationships.topsort
+ end
+ end
end
# $Id$
diff --git a/test/other/transactions.rb b/test/other/transactions.rb
index e90952a70..3129116e7 100755
--- a/test/other/transactions.rb
+++ b/test/other/transactions.rb
@@ -1000,7 +1000,7 @@ class TestTransactions < Test::Unit::TestCase
trans = newcomp(one, two).evaluate
assert_raise(Puppet::Error) do
- trans.relationship_graph
+ trans.prepare
end
end