1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
|
#!/usr/bin/env ruby
#
# Created by Luke Kanies on 2006-11-16.
# Copyright (c) 2006. All rights reserved.
$:.unshift("../lib").unshift("../../lib") if __FILE__ =~ /\.rb$/
require 'puppettest'
require 'puppettest/graph'
class TestPGraph < Test::Unit::TestCase
include PuppetTest
include PuppetTest::Graph
Edge = Puppet::Relationship
def test_clear
graph = Puppet::PGraph.new
graph.add_edge!("a", "b")
graph.add_vertex! "c"
assert_nothing_raised do
graph.clear
end
assert(graph.vertices.empty?, "Still have vertices after clear")
assert(graph.edges.empty?, "still have edges after clear")
end
def test_matching_edges
graph = Puppet::PGraph.new
event = Puppet::Event.new(:source => "a", :event => :yay)
none = Puppet::Event.new(:source => "a", :event => :NONE)
edges = {}
edges["a/b"] = Edge["a", "b", {:event => :yay, :callback => :refresh}]
edges["a/c"] = Edge["a", "c", {:event => :yay, :callback => :refresh}]
graph.add_edge!(edges["a/b"])
# Try it for the trivial case of one target and a matching event
assert_equal([edges["a/b"]], graph.matching_edges([event]))
# Make sure we get nothing with a different event
assert_equal([], graph.matching_edges([none]))
# Set up multiple targets and make sure we get them all back
graph.add_edge!(edges["a/c"])
assert_equal([edges["a/b"], edges["a/c"]].sort, graph.matching_edges([event]).sort)
assert_equal([], graph.matching_edges([none]))
end
def test_dependencies
graph = Puppet::PGraph.new
graph.add_edge!("a", "b")
graph.add_edge!("a", "c")
graph.add_edge!("b", "d")
assert_equal(%w{b c d}.sort, graph.dependents("a").sort)
assert_equal(%w{d}.sort, graph.dependents("b").sort)
assert_equal([].sort, graph.dependents("c").sort)
assert_equal(%w{a b}, graph.dependencies("d").sort)
assert_equal(%w{a}, graph.dependencies("b").sort)
assert_equal(%w{a}, graph.dependencies("c").sort)
assert_equal([], graph.dependencies("a").sort)
end
# Test that we can take a containment graph and rearrange it by dependencies
def test_splice
one, two, three, middle, top = build_tree
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}")
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
c = deps.vertices.find_all { |v| v.is_a?(Container) }
assert(c.empty?, "Still have containers %s" % c.inspect)
# Now make sure the containers got spliced correctly.
contgraph.leaves(middle).each do |leaf|
assert(deps.edge?("h", leaf), "no edge for h => %s" % leaf)
end
one.each do |oobj|
two.each do |tobj|
assert(deps.edge?(oobj, tobj), "no %s => %s edge" % [oobj, tobj])
end
end
nons = deps.vertices.find_all { |v| ! v.is_a?(String) }
assert(nons.empty?,
"still contain non-strings %s" % nons.inspect)
deps.edges.each do |edge|
assert_equal({:callback => :refresh}, edge.label,
"Label was not copied for %s => %s" % [edge.source, edge.target])
end
# Now add some relationships to three, but only add labels to one of
# the relationships.
# Add a simple, label-less relationship
deps.add_edge!(two, three)
assert_nothing_raised { deps.splice!(contgraph, Container) }
# And make sure it stuck, with no labels.
assert_equal({}, deps.edge_label("c", "i"),
"label was created for c => i")
# Now add some edges with labels, in a way that should overwrite
deps.add_edge!("c", three, {:callback => :refresh})
assert_nothing_raised { deps.splice!(contgraph, Container) }
# And make sure the label got copied.
assert_equal({:callback => :refresh}, deps.edge_label("c", "i"),
"label was not copied for c => i")
# Lastly, add some new label-less edges and make sure the label stays.
deps.add_edge!(middle, three)
assert_nothing_raised { deps.splice!(contgraph, Container) }
assert_equal({:callback => :refresh}, deps.edge_label("c", "i"),
"label was lost for c => i")
# Now make sure the 'three' edges all have the label we've used.
# Note that this will not work when we support more than one type of
# subscription.
three.each do |child|
edge = deps.edge_class.new("c", child)
assert(deps.edge?(edge), "no c => %s edge" % child)
assert_equal({:callback => :refresh}, deps[edge],
"label was not retained for c => %s" % child)
end
end
def test_copy_label
graph = Puppet::PGraph.new
# First make an edge with no label
graph.add_edge!(:a, :b)
assert_nil(graph.edge_label(:a, :b), "Created a label")
# Now try to copy an empty label in.
graph.copy_label(:a, :b, {})
# It should just do nothing, since we copied an empty label.
assert_nil(graph.edge_label(:a, :b), "Created a label")
# Now copy in a real label.
graph.copy_label(:a, :b, {:callback => :yay})
assert_equal({:callback => :yay},
graph.edge_label(:a, :b), "Did not copy label")
# Now copy in a nil label
graph.copy_label(:a, :b, nil)
assert_equal({:callback => :yay},
graph.edge_label(:a, :b), "lost label")
# And an empty one.
graph.copy_label(:a, :b, {})
assert_equal({:callback => :yay},
graph.edge_label(:a, :b), "lost label")
end
def test_check_cycle
{
{:a => :b, :b => :a} => true,
{:a => :b, :b => :c, :c => :a} => true,
{:a => :b, :b => :c} => false,
}.each do |hash, result|
graph = Puppet::PGraph.new
hash.each do |a,b|
graph.add_edge!(a, b)
end
if result
assert_raise(Puppet::Error, "%s did not fail" % hash.inspect) do
graph.check_cycle
end
else
assert_nothing_raised("%s failed" % hash.inspect) do
graph.check_cycle
end
end
end
end
end
# $Id$
|