[Pkg-puppet-devel] [facter] 171/352: (FACT-237) Add directed graph for handling dependencies
Stig Sandbeck Mathisen
ssm at debian.org
Sun Apr 6 22:21:42 UTC 2014
This is an automated email from the git hooks/post-receive script.
ssm pushed a commit to branch master
in repository facter.
commit 3431c2dda7e3e0d75d46e58f34b8b8c6335f9601
Author: Adrien Thebo <git at somethingsinistral.net>
Date: Tue Jan 7 13:58:11 2014 -0800
(FACT-237) Add directed graph for handling dependencies
---
lib/facter/core/directed_graph.rb | 45 ++++++++++++++++++++
spec/unit/core/directed_graph_spec.rb | 79 +++++++++++++++++++++++++++++++++++
2 files changed, 124 insertions(+)
diff --git a/lib/facter/core/directed_graph.rb b/lib/facter/core/directed_graph.rb
new file mode 100644
index 0000000..bbdd5db
--- /dev/null
+++ b/lib/facter/core/directed_graph.rb
@@ -0,0 +1,45 @@
+require 'set'
+
+module Facter
+ module Core
+ class DirectedGraph < Hash
+ include TSort
+
+ def acyclic?
+ cycles.empty?
+ end
+
+ def cycles
+ cycles = []
+ each_strongly_connected_component do |component|
+ cycles << component if component.size > 1
+ end
+ cycles
+ end
+
+ alias tsort_each_node each_key
+
+ def tsort_each_child(node)
+ fetch(node, []).each do |child|
+ yield child
+ end
+ end
+
+ def tsort
+ missing = Set.new(self.values.flatten) - Set.new(self.keys)
+
+ if not missing.empty?
+ raise MissingVertex, "Cannot sort elements; cannot depend on missing elements #{missing.to_a}"
+ end
+
+ super
+
+ rescue TSort::Cyclic
+ raise CycleError, "Cannot sort elements; found the following cycles: #{cycles.inspect}"
+ end
+
+ class CycleError < StandardError; end
+ class MissingVertex < StandardError; end
+ end
+ end
+end
diff --git a/spec/unit/core/directed_graph_spec.rb b/spec/unit/core/directed_graph_spec.rb
new file mode 100644
index 0000000..1b68237
--- /dev/null
+++ b/spec/unit/core/directed_graph_spec.rb
@@ -0,0 +1,79 @@
+require 'spec_helper'
+require 'facter/core/directed_graph'
+
+describe Facter::Core::DirectedGraph do
+ subject(:graph) { described_class.new }
+
+ describe "detecting cycles" do
+ it "is acyclic if the graph is empty" do
+ expect(graph).to be_acyclic
+ end
+
+ it "is acyclic if the graph has no edges" do
+ graph[:one] = []
+ graph[:two] = []
+
+ expect(graph).to be_acyclic
+ end
+
+ it "is acyclic if a vertex has an edge to itself" do
+ graph[:one] = [:one]
+ expect(graph).to be_acyclic
+ end
+
+ it "is acyclic if there are no loops in the graph" do
+ graph[:one] = [:two, :three]
+ graph[:two] = [:four]
+ graph[:three] = [:four]
+ graph[:four] = []
+
+ expect(graph).to be_acyclic
+ end
+
+ it "is cyclic if there is a loop in the graph" do
+ graph[:one] = [:two]
+ graph[:two] = [:one]
+ expect(graph).to_not be_acyclic
+ end
+
+ it "can return the cycles in the graph" do
+ graph[:one] = [:two]
+ graph[:two] = [:one]
+
+ graph[:three] = [:four]
+ graph[:four] = [:three]
+
+ first_cycle = graph.cycles.find { |cycle| cycle.include? :one }
+ second_cycle = graph.cycles.find { |cycle| cycle.include? :three }
+
+ expect(first_cycle).to include :two
+ expect(second_cycle).to include :four
+ end
+ end
+
+ describe "sorting" do
+ it "returns the vertices in topologically sorted order" do
+ graph[:one] = [:two, :three]
+ graph[:two] = [:three]
+ graph[:three] = []
+ expect(graph.tsort).to eq [:three, :two, :one]
+ end
+
+ it "raises an error if there is a cycle in the graph" do
+ graph[:one] = [:two]
+ graph[:two] = [:one]
+
+ expect {
+ graph.tsort
+ }.to raise_error(Facter::Core::DirectedGraph::CycleError, /found the following cycles:/)
+ end
+
+ it "raises an error if there is an edge to a non-existent vertex" do
+ graph[:one] = [:two, :three]
+ graph[:two] = [:three]
+ expect {
+ graph.tsort
+ }.to raise_error(Facter::Core::DirectedGraph::MissingVertex, /missing elements.*three/)
+ end
+ end
+end
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-puppet/facter.git
More information about the Pkg-puppet-devel
mailing list