diff options
author | Luke Kanies <luke@madstop.com> | 2007-09-17 15:21:44 -0700 |
---|---|---|
committer | Luke Kanies <luke@madstop.com> | 2007-09-17 15:21:44 -0700 |
commit | 9fa2628a844c75b8f554f283dfece01667f20594 (patch) | |
tree | 7c1b57c56879b2b083063895bae6423f2b94dc9c | |
parent | b3c8cdb67d9a423a1d14764f1e58f677d7ef8d41 (diff) | |
download | puppet-9fa2628a844c75b8f554f283dfece01667f20594.tar.gz puppet-9fa2628a844c75b8f554f283dfece01667f20594.tar.xz puppet-9fa2628a844c75b8f554f283dfece01667f20594.zip |
This is basically another intermediate commit. I feel like
I've gone too far down the rabbit hole to turn back now, but the
code is clearly getting more centralized around the Configuration
class, which is the goal.
Things are currently a bit muddy between recursion, dynamic resource
generation, transactions, and the configuration, and I don't expect
to be able to clear it up much until we rewrite all of the tests
for the Transaction class, since that is when we'll actually be
setting its behaviour.
At this point, Files (which are currently the only resources that
generate other resources) are responsible for adding their edges
to the relationship graph. This puts them knowing more than I would
like about how the relationship graph works, but it'll have to do for now.
There are still failing tests, but files seem to work again. Now to
go through the rest of the tests and make them work.
43 files changed, 536 insertions, 917 deletions
diff --git a/bin/puppet b/bin/puppet index 36f0fcd62..9520492a2 100755 --- a/bin/puppet +++ b/bin/puppet @@ -194,8 +194,8 @@ begin if Puppet[:parseonly] exit(0) end - client.getconfig - client.apply + config = client.getconfig + config.apply rescue => detail if detail.is_a?(XMLRPC::FaultException) $stderr.puts detail.message diff --git a/ext/module_puppet b/ext/module_puppet index cb03b6ef2..194f3fa09 100755 --- a/ext/module_puppet +++ b/ext/module_puppet @@ -191,8 +191,8 @@ if parseonly end begin - client.getconfig - client.apply + config = client.getconfig + config.apply rescue => detail Puppet.err detail exit(1) diff --git a/lib/puppet/dsl.rb b/lib/puppet/dsl.rb index 795358e83..3696cd9ee 100644 --- a/lib/puppet/dsl.rb +++ b/lib/puppet/dsl.rb @@ -67,11 +67,8 @@ module Puppet def apply bucket = export() - objects = bucket.to_type - master = Puppet::Network::Client.master.new :Master => "whatever" - master.objects = objects - - master.apply + configuration = bucket.to_configuration + configuration.apply end def export diff --git a/lib/puppet/metatype/closure.rb b/lib/puppet/metatype/closure.rb index efb4712c6..727bc6884 100644 --- a/lib/puppet/metatype/closure.rb +++ b/lib/puppet/metatype/closure.rb @@ -1,19 +1,6 @@ class Puppet::Type attr_writer :implicit - def self.implicitcreate(hash) - unless hash.include?(:implicit) - hash[:implicit] = true - end - if obj = self.create(hash) - obj.implicit = true - - return obj - else - return nil - end - end - # Is this type's name isomorphic with the object? That is, if the # name conflicts, does it necessarily mean that the objects conflict? # Defaults to true. diff --git a/lib/puppet/metatype/container.rb b/lib/puppet/metatype/container.rb index 7c44a7def..7bbccf8a0 100644 --- a/lib/puppet/metatype/container.rb +++ b/lib/puppet/metatype/container.rb @@ -14,14 +14,6 @@ class Puppet::Type self.class.depthfirst? end - def parent=(parent) - if self.parentof?(parent) - devfail "%s[%s] is already the parent of %s[%s]" % - [self.class.name, self.title, parent.class.name, parent.title] - end - @parent = parent - end - # Add a hook for testing for recursion. def parentof?(child) if (self == child) diff --git a/lib/puppet/metatype/instances.rb b/lib/puppet/metatype/instances.rb index f6c2fdd34..4fd72e85c 100644 --- a/lib/puppet/metatype/instances.rb +++ b/lib/puppet/metatype/instances.rb @@ -79,8 +79,7 @@ class Puppet::Type end # Force users to call this, so that we can merge objects if - # necessary. FIXME This method should be responsible for most of the - # error handling. + # necessary. def self.create(args) # Don't modify the original hash; instead, create a duplicate and modify it. # We have to dup and use the ! so that it stays a TransObject if it is @@ -308,8 +307,8 @@ class Puppet::Type # Create the path for logging and such. def pathbuilder - if defined? @parent and @parent - [@parent.pathbuilder, self.ref].flatten + if p = parent + [p.pathbuilder, self.ref].flatten else [self.ref] end diff --git a/lib/puppet/network/handler/resource.rb b/lib/puppet/network/handler/resource.rb index ac29dce53..7709b85fe 100755 --- a/lib/puppet/network/handler/resource.rb +++ b/lib/puppet/network/handler/resource.rb @@ -39,21 +39,14 @@ class Puppet::Network::Handler end end - component = bucket.to_type - - # Create a client, but specify the remote machine as the server - # because the class requires it, even though it's unused - client = Puppet::Network::Client.client(:Master).new(:Master => client||"localhost") - - # Set the objects - client.objects = component + config = bucket.to_configuration # And then apply the configuration. This way we're reusing all # the code in there. It should probably just be separated out, though. - transaction = client.apply + transaction = config.apply # And then clean up - component.remove + config.clear(true) # It'd be nice to return some kind of report, but... at this point # we have no such facility. diff --git a/lib/puppet/node/configuration.rb b/lib/puppet/node/configuration.rb index 9cd23926e..c882e0ee1 100644 --- a/lib/puppet/node/configuration.rb +++ b/lib/puppet/node/configuration.rb @@ -35,20 +35,22 @@ class Puppet::Node::Configuration < Puppet::PGraph tag(*classes) end - # Add a resource to our graph and to our resource table. - def add_resource(resource) - unless resource.respond_to?(:ref) - raise ArgumentError, "Can only add objects that respond to :ref" - end + # Add one or more resources to our graph and to our resource table. + def add_resource(*resources) + resources.each do |resource| + unless resource.respond_to?(:ref) + raise ArgumentError, "Can only add objects that respond to :ref" + end - ref = resource.ref - if @resource_table.include?(ref) - raise ArgumentError, "Resource %s is already defined" % ref - else - @resource_table[ref] = resource + ref = resource.ref + if @resource_table.include?(ref) + raise ArgumentError, "Resource %s is already defined" % ref + else + @resource_table[ref] = resource + end + resource.configuration = self + add_vertex!(resource) end - resource.configuration = self - add_vertex!(resource) end # Apply our configuration to the local host. @@ -58,6 +60,8 @@ class Puppet::Node::Configuration < Puppet::PGraph transaction.addtimes :config_retrieval => @retrieval_duration + @applying = true + begin transaction.evaluate rescue Puppet::Error => detail @@ -83,22 +87,62 @@ class Puppet::Node::Configuration < Puppet::PGraph return transaction ensure + @applying = false + cleanup() if defined? transaction and transaction transaction.cleanup end end + + # Are we in the middle of applying the configuration? + def applying? + @applying + end def clear(remove_resources = true) super() # We have to do this so that the resources clean themselves up. @resource_table.values.each { |resource| resource.remove } if remove_resources @resource_table.clear + + if defined?(@relationship_graph) and @relationship_graph + @relationship_graph.clear(false) + @relationship_graph = nil + end end def classes @classes.dup end + # Create an implicit resource, meaning that it will lose out + # to any explicitly defined resources. This method often returns + # nil. + def create_implicit_resource(type, options) + unless options.include?(:implicit) + options[:implicit] = true + end + if resource = create_resource(type, options) + resource.implicit = true + + return resource + else + return nil + end + end + + # Create a new resource and register it in the configuration. + def create_resource(type, options) + unless klass = Puppet::Type.type(type) + raise ArgumentError, "Unknown resource type %s" % type + end + return unless resource = klass.create(options) + + @transient_resources << resource if applying? + add_resource(resource) + resource + end + # Make sure we support the requested extraction format. def extraction_format=(value) unless respond_to?("extract_to_%s" % value) @@ -174,6 +218,12 @@ class Puppet::Node::Configuration < Puppet::PGraph # Make sure all of our resources are "finished". def finalize @resource_table.values.each { |resource| resource.finish } + + write_graph(:resources) + end + + def host_config? + host_config || false end def initialize(name = nil) @@ -183,20 +233,76 @@ class Puppet::Node::Configuration < Puppet::PGraph @tags = [] @classes = [] @resource_table = {} + @transient_resources = [] + @applying = false if block_given? yield(self) finalize() end end + + # Create a graph of all of the relationships in our configuration. + def relationship_graph + unless defined? @relationship_graph and @relationship_graph + relationships = self.class.new + + # First create the dependency graph + self.vertices.each do |vertex| + relationships.add_resource vertex + vertex.builddepends.each do |edge| + relationships.add_edge!(edge) + end + end + + # Lastly, add in any autorequires + relationships.vertices.each do |vertex| + vertex.autorequire.each do |edge| + unless relationships.edge?(edge) + unless relationships.edge?(edge.target, edge.source) + vertex.debug "Autorequiring %s" % [edge.source] + relationships.add_edge!(edge) + else + vertex.debug "Skipping automatic relationship with %s" % (edge.source == vertex ? edge.target : edge.source) + end + end + end + end + + relationships.write_graph(:relationships) + + # Then splice in the container information + relationships.splice!(self, Puppet::Type::Component) + + relationships.write_graph(:expanded_relationships) + @relationship_graph = relationships + end + @relationship_graph + end - # Look a resource up by its reference (e.g., File[/etc/passwd]). - def resource(ref) - @resource_table[ref] + # Remove the resource from our configuration. Notice that we also call + # 'remove' on the resource, at least until resource classes no longer maintain + # references to the resource instances. + def remove_resource(*resources) + resources.each do |resource| + @resource_table.delete(resource.ref) if @resource_table.include?(resource.ref) + remove_vertex!(resource) if vertex?(resource) + resource.remove + end end - def host_config? - host_config || false + # Look a resource up by its reference (e.g., File[/etc/passwd]). + def resource(type, title = nil) + if title + ref = "%s[%s]" % [type.to_s.capitalize, title] + else + ref = type + end + if resource = @resource_table[ref] + return resource + elsif defined?(@relationship_graph) and @relationship_graph + @relationship_graph.resource(ref) + end end # Add a tag. @@ -217,4 +323,28 @@ class Puppet::Node::Configuration < Puppet::PGraph def tags @tags.dup end + + # Produce the graph files if requested. + def write_graph(name) + # We only want to graph the main host configuration. + return unless host_config? + + return unless Puppet[:graph] + + Puppet.config.use(:graphing) + + file = File.join(Puppet[:graphdir], "%s.dot" % name.to_s) + File.open(file, "w") { |f| + f.puts to_dot("name" => name.to_s.capitalize) + } + end + + private + + def cleanup + unless @transient_resources.empty? + remove_resource(*@transient_resources) + @transient_resources.clear + end + end end diff --git a/lib/puppet/reports/store.rb b/lib/puppet/reports/store.rb index 8d6e11379..d51f50372 100644 --- a/lib/puppet/reports/store.rb +++ b/lib/puppet/reports/store.rb @@ -13,7 +13,7 @@ Puppet::Network::Handler.report.newreport(:store, :useyaml => true) do def mkclientdir(client, dir) config = Puppet::Util::Config.new config.setdefaults("reportclient-#{client}", - "clientdir-#{client}" => { :default => dir, + "client-#{client}-dir" => { :default => dir, :mode => 0750, :desc => "Client dir for %s" % client, :owner => Puppet[:user], diff --git a/lib/puppet/transaction.rb b/lib/puppet/transaction.rb index 0d81b1e63..43889927c 100644 --- a/lib/puppet/transaction.rb +++ b/lib/puppet/transaction.rb @@ -7,7 +7,7 @@ require 'puppet/propertychange' module Puppet class Transaction attr_accessor :component, :configuration, :ignoreschedules - attr_accessor :relgraph, :sorted_resources, :configurator + attr_accessor :sorted_resources, :configurator # The report, once generated. attr_reader :report @@ -32,7 +32,7 @@ class Transaction # dependencies, then don't delete it unless it's implicit or the # dependency is itself being deleted. if resource.purging? and resource.deleting? - if deps = @relgraph.dependents(resource) and ! deps.empty? and deps.detect { |d| ! d.deleting? } + if deps = relationship_graph.dependents(resource) and ! deps.empty? and deps.detect { |d| ! d.deleting? } resource.warning "%s still depend%s on me -- not purging" % [deps.collect { |r| r.ref }.join(","), deps.length > 1 ? "":"s"] return false @@ -144,12 +144,7 @@ class Transaction # contained resources might never get cleaned up. def cleanup if defined? @generated - @generated.each do |resource| - resource.remove - end - end - if defined? @relgraph - @relgraph.clear + relationship_graph.remove_resource(*@generated) end end @@ -164,10 +159,11 @@ class Transaction else edge = [resource, gen_child] end - unless @relgraph.edge?(edge[1], edge[0]) - @relgraph.add_edge!(*edge) + relationship_graph.add_resource(gen_child) unless relationship_graph.resource(gen_child.ref) + + unless relationship_graph.edge?(edge[1], edge[0]) + relationship_graph.add_edge!(*edge) else - @relgraph.add_vertex!(gen_child) resource.debug "Skipping automatic relationship to %s" % gen_child end end @@ -198,7 +194,8 @@ class Transaction children.each do |child| child.finish # Make sure that the vertex is in the relationship graph. - @relgraph.add_vertex!(child) + relationship_graph.add_resource(child) unless relationship_graph.resource(child.ref) + child.configuration = relationship_graph end @generated += children return children @@ -271,7 +268,7 @@ class Transaction # Collect the targets of any subscriptions to those events. We pass # the parent resource in so it will override the source in the events, # since eval_generated children can't have direct relationships. - @relgraph.matching_edges(events, resource).each do |edge| + relationship_graph.matching_edges(events, resource).each do |edge| edge = edge.dup label = edge.label label[:event] = events.collect { |e| e.event } @@ -289,8 +286,6 @@ class Transaction def evaluate @count = 0 - graph(@configuration, :resources) - # Start logging. Puppet::Util::Log.newdestination(@report) @@ -320,6 +315,7 @@ class Transaction Puppet.debug "Finishing transaction %s with %s changes" % [self.object_id, @count] + @events = allevents allevents end @@ -339,7 +335,7 @@ class Transaction # enough to check the immediate dependencies, which is why we use # a tree from the reversed graph. skip = false - deps = @relgraph.dependencies(resource) + deps = relationship_graph.dependencies(resource) deps.each do |dep| if fails = failed?(dep) resource.notice "Dependency %s[%s] has %s failures" % @@ -375,7 +371,8 @@ class Transaction end made.uniq! made.each do |res| - @configuration.add_vertex!(res) + @configuration.add_resource(res) + res.configuration = configuration newlist << res @generated << res res.finish @@ -416,21 +413,6 @@ class Transaction return @report end - # Produce the graph files if requested. - def graph(gr, name) - # We only want to graph the main host configuration. - return unless @configuration.host_config? - - return unless Puppet[:graph] - - Puppet.config.use(:graphing) - - file = File.join(Puppet[:graphdir], "%s.dot" % name.to_s) - File.open(file, "w") { |f| - f.puts gr.to_dot("name" => name.to_s.capitalize) - } - end - # Should we ignore tags? def ignore_tags? ! @configuration.host_config? @@ -514,48 +496,13 @@ class Transaction # Now add any dynamically generated resources generate() - - # Create a relationship graph from our resource graph - @relgraph = relationship_graph # This will throw an error if there are cycles in the graph. - @sorted_resources = @relgraph.topsort + @sorted_resources = relationship_graph.topsort end - - # Create a graph of all of the relationships in our resource graph. - def relationship_graph - graph = Puppet::PGraph.new - - # First create the dependency graph - @configuration.vertices.each do |vertex| - graph.add_vertex!(vertex) - vertex.builddepends.each do |edge| - graph.add_edge!(edge) - end - end - - # Lastly, add in any autorequires - graph.vertices.each do |vertex| - vertex.autorequire.each do |edge| - unless graph.edge?(edge) - unless graph.edge?(edge.target, edge.source) - vertex.debug "Autorequiring %s" % [edge.source] - graph.add_edge!(edge) - else - vertex.debug "Skipping automatic relationship with %s" % (edge.source == vertex ? edge.target : edge.source) - end - end - end - end - - graph(graph, :relationships) - - # Then splice in the container information - graph.splice!(@configuration, Puppet::Type::Component) - graph(graph, :expanded_relationships) - - return graph + def relationship_graph + configuration.relationship_graph end # Send off the transaction report. @@ -621,7 +568,7 @@ class Transaction end # FIXME This won't work right now. - @relgraph.matching_edges(events).each do |edge| + relationship_graph.matching_edges(events).each do |edge| @targets[edge.target] << edge end diff --git a/lib/puppet/transportable.rb b/lib/puppet/transportable.rb index e4cde6e37..ecd179ed7 100644 --- a/lib/puppet/transportable.rb +++ b/lib/puppet/transportable.rb @@ -174,12 +174,7 @@ module Puppet end end - str = nil - if self.top - str = "%s" - else - str = "#{@keyword} #{@type} {\n%s\n}" - end + str = "#{@keyword} #{@name} {\n%s\n}" str % @children.collect { |child| child.to_manifest }.collect { |str| diff --git a/lib/puppet/type.rb b/lib/puppet/type.rb index 03f571d4a..1db435224 100644 --- a/lib/puppet/type.rb +++ b/lib/puppet/type.rb @@ -312,6 +312,19 @@ class Type return self[:name] end + # Look up our parent in the configuration, if we have one. + def parent + return nil unless configuration + + # We should never have more than one parent, so let's just ignore + # it if we happen to. + if parents = configuration.adjacent(self, :direction => :in) + return parents.shift + else + return nil + end + end + # Return the "type[name]" style reference. def ref "%s[%s]" % [self.class.name.to_s.capitalize, self.title] diff --git a/lib/puppet/type/component.rb b/lib/puppet/type/component.rb index 1615abad8..1eadeb060 100644 --- a/lib/puppet/type/component.rb +++ b/lib/puppet/type/component.rb @@ -163,8 +163,8 @@ Puppet::Type.newtype(:component) do else myname = self.title end - if self.parent - return [@parent.pathbuilder, myname] + if p = self.parent + return [p.pathbuilder, myname] else return [myname] end @@ -215,24 +215,6 @@ Puppet::Type.newtype(:component) do end } end - - # Convert to a graph object with all of the container info. - def to_graph - graph = Puppet::PGraph.new - - delver = proc do |obj| - obj.each do |child| - graph.add_edge!(obj, child) - if child.is_a?(self.class) - delver.call(child) - end - end - end - - delver.call(self) - - return graph - end def to_s if self.title =~ /\[/ @@ -242,5 +224,3 @@ Puppet::Type.newtype(:component) do end end end - -# $Id$ diff --git a/lib/puppet/type/pfile.rb b/lib/puppet/type/pfile.rb index 99b5a7435..da345e5d6 100644 --- a/lib/puppet/type/pfile.rb +++ b/lib/puppet/type/pfile.rb @@ -574,6 +574,9 @@ module Puppet # Create a new file or directory object as a child to the current # object. def newchild(path, local, hash = {}) + unless configuration + raise Puppet::DevError, "File recursion cannot happen without a configuration" + end # make local copy of arguments args = symbolize_options(@arghash) @@ -608,13 +611,12 @@ module Puppet } child = nil - klass = self.class # The child might already exist because 'localrecurse' runs # before 'sourcerecurse'. I could push the override stuff into # a separate method or something, but the work is the same other # than this last bit, so it doesn't really make sense. - if child = klass[path] + if child = configuration.resource(:file, path) unless child.parent.object_id == self.object_id self.debug "Not managing more explicit file %s" % path @@ -640,12 +642,7 @@ module Puppet #notice "Creating new file with args %s" % args.inspect args[:parent] = self begin - child = klass.implicitcreate(args) - - # implicit creation can return nil - if child.nil? - return nil - end + return nil unless child = configuration.create_implicit_resource(:file, args) rescue Puppet::Error => detail self.notice( "Cannot manage: %s" % @@ -661,6 +658,7 @@ module Puppet self.debug args.inspect child = nil end + configuration.relationship_graph.add_edge! self, child end return child end @@ -695,9 +693,7 @@ module Puppet # files. def recurse # are we at the end of the recursion? - unless self.recurse? - return - end + return unless self.recurse? recurse = self[:recurse] # we might have a string, rather than a number diff --git a/lib/puppet/util/config.rb b/lib/puppet/util/config.rb index 5875f141b..3988b3fe0 100644 --- a/lib/puppet/util/config.rb +++ b/lib/puppet/util/config.rb @@ -555,9 +555,9 @@ class Puppet::Util::Config end # Convert our list of objects into a component that can be applied. - def to_component + def to_configuration transport = self.to_transportable - return transport.to_type + return transport.to_configuration end # Convert our list of objects into a configuration file. @@ -615,10 +615,7 @@ Generated on #{Time.now}. end sections.each do |section| obj = section_to_transportable(section, done) - #puts obj.to_manifest - #puts "%s: %s" % [section, obj.inspect] topbucket.push obj - #topbucket.push section_to_transportable(section, done) end topbucket @@ -1109,6 +1106,11 @@ Generated on #{Time.now}. # Set the type appropriately. Yep, a hack. This supports either naming # the variable 'dir', or adding a slash at the end. def munge(value) + # If it's not a fully qualified path... + if value.is_a?(String) and value !~ /^\$/ and value !~ /^\// + # Make it one + value = File.join(Dir.getwd, value) + end if value.to_s =~ /\/$/ @type = :directory return value.sub(/\/$/, '') @@ -1131,9 +1133,6 @@ Generated on #{Time.now}. end # Convert the object to a TransObject instance. - # FIXME There's no dependency system in place right now; if you use - # a section that requires another section, there's nothing done to - # correct that for you, at the moment. def to_transportable type = self.type return nil unless type @@ -1142,9 +1141,6 @@ Generated on #{Time.now}. objects = [] path = self.value - unless path =~ /^#{File::SEPARATOR}/ - path = File.join(Dir.getwd, path) - end # Skip plain files that don't exist, since we won't be managing them anyway. return nil unless self.name.to_s =~ /dir$/ or File.exist?(path) diff --git a/lib/puppet/util/graph.rb b/lib/puppet/util/graph.rb deleted file mode 100644 index e51b8e25a..000000000 --- a/lib/puppet/util/graph.rb +++ /dev/null @@ -1,39 +0,0 @@ -# Created by Luke Kanies on 2006-11-16. -# Copyright (c) 2006. All rights reserved. - -require 'puppet' -require 'puppet/pgraph' - -# A module that handles the small amount of graph stuff in Puppet. -module Puppet::Util::Graph - # Make a graph where each of our children gets converted to - # the receiving end of an edge. Call the same thing on all - # of our children, optionally using a block - def to_graph(graph = nil, &block) - # Allow our calling function to send in a graph, so that we - # can call this recursively with one graph. - graph ||= Puppet::PGraph.new - - self.each do |child| - unless block_given? and ! yield(child) - graph.add_edge!(self, child) - - if graph.cyclic? - raise Puppet::Error, "%s created a cyclic graph" % self - end - - if child.respond_to?(:to_graph) - child.to_graph(graph, &block) - end - end - end - - if graph.cyclic? - raise Puppet::Error, "%s created a cyclic graph" % self - end - - graph - end -end - -# $Id$ diff --git a/spec/unit/node/configuration.rb b/spec/unit/node/configuration.rb index 071afc041..ecf311948 100755 --- a/spec/unit/node/configuration.rb +++ b/spec/unit/node/configuration.rb @@ -142,6 +142,12 @@ describe Puppet::Node::Configuration, " when functioning as a resource container @dupe = stub 'resource3', :ref => "Me[you]", :configuration= => nil end + it "should provide a method to add one or more resources" do + @config.add_resource @one, @two + @config.resource(@one.ref).should equal(@one) + @config.resource(@two.ref).should equal(@two) + end + it "should make all vertices available by resource reference" do @config.add_resource(@one) @config.resource(@one.ref).should equal(@one) @@ -187,6 +193,24 @@ describe Puppet::Node::Configuration, " when functioning as a resource container @one.expects(:configuration=).with(@config) @config.add_resource @one end + + it "should be able to find resources by reference" do + @config.add_resource @one + @config.resource(@one.ref).should equal(@one) + end + + it "should be able to find resources by reference or by type/title tuple" do + @config.add_resource @one + @config.resource("me", "you").should equal(@one) + end + + it "should have a mechanism for removing resources" do + @config.add_resource @one + @one.expects :remove + @config.remove_resource(@one) + @config.resource(@one.ref).should be_nil + @config.vertex?(@one).should be_false + end end module ApplyingConfigurations @@ -296,3 +320,132 @@ describe Puppet::Node::Configuration, " when applying non-host configurations" d after { Puppet.config.clear } end + +describe Puppet::Node::Configuration, " when creating a relationship graph" do + before do + @config = Puppet::Node::Configuration.new("host") + @compone = Puppet::Type::Component.create :name => "one" + @comptwo = Puppet::Type::Component.create :name => "two", :require => ["class", "one"] + @file = Puppet::Type.type(:file) + @one = @file.create :path => "/one" + @two = @file.create :path => "/two" + @config.add_edge! @compone, @one + @config.add_edge! @comptwo, @two + + @three = @file.create :path => "/three" + @four = @file.create :path => "/four", :require => ["file", "/three"] + @config.add_resource @compone, @comptwo, @one, @two, @three, @four + @relationships = @config.relationship_graph + end + + it "should be able to create a resource graph" do + @relationships.should be_instance_of(Puppet::Node::Configuration) + end + + it "should not have any components" do + @relationships.vertices.find { |r| r.instance_of?(Puppet::Type::Component) }.should be_nil + end + + it "should have all non-component resources from the configuration" do + # The failures print out too much info, so i just do a class comparison + @relationships.resource(@one.ref).should be_instance_of(@one.class) + @relationships.resource(@three.ref).should be_instance_of(@three.class) + end + + it "should have all resource relationships set as edges" do + @relationships.edge?(@three, @four).should be_true + end + + it "should copy component relationships to all contained resources" do + @relationships.edge?(@one, @two).should be_true + end + + it "should get removed when the configuration is cleaned up" do + @relationships.expects(:clear).with(false) + @config.clear + @config.instance_variable_get("@relationship_graph").should be_nil + end + + it "should create a new relationship graph after clearing the old one" do + @relationships.expects(:clear).with(false) + @config.clear + @config.relationship_graph.should be_instance_of(Puppet::Node::Configuration) + end + + it "should look up resources in the relationship graph if not found in the main configuration" do + five = stub 'five', :ref => "File[five]", :configuration= => nil + @relationships.add_resource five + @config.resource(five.ref).should equal(five) + end + + it "should provide a method to create additional resources that also registers the resource" do + args = {:name => "/yay", :ensure => :file} + resource = stub 'file', :ref => "File[/yay]", :configuration= => @config + Puppet::Type.type(:file).expects(:create).with(args).returns(resource) + @config.create_resource :file, args + @config.resource("File[/yay]").should equal(resource) + end + + it "should provide a mechanism for creating implicit resources" do + args = {:name => "/yay", :ensure => :file} + resource = stub 'file', :ref => "File[/yay]", :configuration= => @config + Puppet::Type.type(:file).expects(:create).with(args).returns(resource) + resource.expects(:implicit=).with(true) + @config.create_implicit_resource :file, args + @config.resource("File[/yay]").should equal(resource) + end + + it "should remove resources created mid-transaction" do + args = {:name => "/yay", :ensure => :file} + resource = stub 'file', :ref => "File[/yay]", :configuration= => @config + @transaction = mock 'transaction' + Puppet::Transaction.stubs(:new).returns(@transaction) + @transaction.stubs(:evaluate) + @transaction.stubs(:cleanup) + @transaction.stubs(:addtimes) + Puppet::Type.type(:file).expects(:create).with(args).returns(resource) + resource.expects :remove + @config.apply do |trans| + @config.create_resource :file, args + @config.resource("File[/yay]").should equal(resource) + end + @config.resource("File[/yay]").should be_nil + end + + after do + Puppet::Type.allclear + end +end + +describe Puppet::Node::Configuration, " when writing dot files" do + before do + @config = Puppet::Node::Configuration.new("host") + @name = :test + @file = File.join(Puppet[:graphdir], @name.to_s + ".dot") + end + it "should only write when it is a host configuration" do + File.expects(:open).with(@file).never + @config.host_config = false + Puppet[:graph] = true + @config.write_graph(@name) + end + + it "should only write when graphing is enabled" do + File.expects(:open).with(@file).never + @config.host_config = true + Puppet[:graph] = false + @config.write_graph(@name) + end + + it "should write a dot file based on the passed name" do + File.expects(:open).with(@file, "w").yields(stub("file", :puts => nil)) + @config.expects(:to_dot).with("name" => @name.to_s.capitalize) + @config.host_config = true + Puppet[:graph] = true + @config.write_graph(@name) + end + + after do + Puppet.config.clear + end +end diff --git a/spec/unit/ral/type.rb b/spec/unit/ral/type.rb new file mode 100755 index 000000000..c8bf8c9b4 --- /dev/null +++ b/spec/unit/ral/type.rb @@ -0,0 +1,25 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../spec_helper' + +describe Puppet::Type, " when in a configuration" do + before do + @configuration = Puppet::Node::Configuration.new + @container = Puppet::Type.type(:component).create(:name => "container") + @one = Puppet::Type.type(:file).create(:path => "/file/one") + @two = Puppet::Type.type(:file).create(:path => "/file/two") + @configuration.add_resource @container + @configuration.add_resource @one + @configuration.add_resource @two + @configuration.add_edge! @container, @one + @configuration.add_edge! @container, @two + end + + it "should have no parent if there is no in edge" do + @container.parent.should be_nil + end + + it "should set its parent to its in edge" do + @one.parent.ref.should equal(@container.ref) + end +end diff --git a/spec/unit/util/config.rb b/spec/unit/util/config.rb index ff9e28d3b..353bc2bcb 100755 --- a/spec/unit/util/config.rb +++ b/spec/unit/util/config.rb @@ -500,9 +500,7 @@ describe Puppet::Util::Config, " when being used to manage the host machine" do file.should be_nil end - it "should be able to turn the current configuration into a parseable manifest" do - pending "Not converted from test/unit yet" - end + it "should be able to turn the current configuration into a parseable manifest" it "should convert octal numbers correctly when producing a manifest" @@ -520,4 +518,16 @@ describe Puppet::Util::Config, " when being used to manage the host machine" do Dir.expects(:mkdir).with("/maindir") @config.use(:main) end + + it "should convert all relative paths to fully-qualified paths (#795)" do + @config[:myfile] = "unqualified" + dir = Dir.getwd + @config[:myfile].should == File.join(dir, "unqualified") + end + + it "should support a method for re-using all currently used sections" do + Dir.expects(:mkdir).with(@config[:otherdir], 0755).times(2) + @config.use(:other) + @config.reuse + end end diff --git a/test/lib/puppettest/parsertesting.rb b/test/lib/puppettest/parsertesting.rb index c4bd7dc2b..62fa7213e 100644 --- a/test/lib/puppettest/parsertesting.rb +++ b/test/lib/puppettest/parsertesting.rb @@ -308,17 +308,17 @@ module PuppetTest::ParserTesting ) } - config = nil + trans = nil assert_nothing_raised { - config = interp.compile(mknode) + trans = interp.compile(mknode) } - comp = nil + config = nil assert_nothing_raised { - comp = config.extract.to_type + config = trans.extract.to_configuration } - assert_apply(comp) + config.apply files.each do |file| assert(FileTest.exists?(file), "Did not create %s" % file) diff --git a/test/network/handler/master.rb b/test/network/handler/master.rb index 9749c7bdf..df946fa33 100755 --- a/test/network/handler/master.rb +++ b/test/network/handler/master.rb @@ -76,9 +76,10 @@ class TestMaster < Test::Unit::TestCase "Client is incorrectly up to date") Puppet.config.use(:main) + config = nil assert_nothing_raised { - client.getconfig - client.apply + config = client.getconfig + config.apply } # Now it should be up to date @@ -113,8 +114,8 @@ class TestMaster < Test::Unit::TestCase # Retrieve and apply the new config assert_nothing_raised { - client.getconfig - client.apply + config = client.getconfig + config.apply } assert(client.fresh?(facts), "Client is not up to date") diff --git a/test/other/dsl.rb b/test/other/dsl.rb index f1fd1a1e9..59610cd0f 100755 --- a/test/other/dsl.rb +++ b/test/other/dsl.rb @@ -214,5 +214,3 @@ class TestDSL < Test::Unit::TestCase assert_instance_of(Puppet::Parser::Resource, file) end end - -# $Id$ diff --git a/test/other/events.rb b/test/other/events.rb index 802a701a3..b67ea05a1 100755 --- a/test/other/events.rb +++ b/test/other/events.rb @@ -23,7 +23,7 @@ class TestEvents < Test::Unit::TestCase :subscribe => [[file.class.name, file.name]] ) - comp = newcomp("eventtesting", file, exec) + comp = mk_configuration("eventtesting", file, exec) trans = assert_events([:file_created, :triggered], comp) @@ -44,56 +44,16 @@ class TestEvents < Test::Unit::TestCase ) - comp = Puppet.type(:component).create( - :name => "eventtesting" - ) - comp.push exec - trans = comp.evaluate - events = nil - assert_nothing_raised { - events = trans.evaluate - } + config = mk_configuration + config.add_resource file + config.add_resource exec + trans = config.apply - assert_equal(1, events.length) + assert_equal(1, trans.events.length) assert_equal(0, trans.triggered?(exec, :refresh)) end - # Verify that one component can subscribe to another component and the "right" - # thing happens - def test_ladderrequire - comps = {} - objects = {} - fname = tempfile() - file = Puppet.type(:file).create( - :name => tempfile(), - :ensure => "file" - ) - - exec = Puppet.type(:exec).create( - :name => "touch %s" % fname, - :path => "/usr/bin:/bin", - :refreshonly => true - ) - - fcomp = newcomp(file) - ecomp = newcomp(exec) - comp = newcomp("laddercomp", fcomp, ecomp) - - ecomp[:subscribe] = [[fcomp.class.name, fcomp.name]] - - comp.finalize - - trans = comp.evaluate - events = nil - assert_nothing_raised { - events = trans.evaluate - } - - assert(FileTest.exists?(fname), "#{fname} does not exist") - #assert_equal(events.length, trans.triggered?(objects[:b], :refresh)) - end - def test_multiplerefreshes files = [] @@ -115,7 +75,7 @@ class TestEvents < Test::Unit::TestCase ["file", f.name] } - comp = newcomp(exec, *files) + comp = mk_configuration(exec, *files) assert_apply(comp) assert(FileTest.exists?(fname), "Exec file did not get created") @@ -147,17 +107,16 @@ class TestEvents < Test::Unit::TestCase ) execs = [exec1, exec2, exec3] - comp = newcomp(exec1,exec2,exec3) + config = mk_configuration(exec1,exec2,exec3) - trans = comp.evaluate - execs.each do |e| assert(trans.resources.vertex?(e), "%s is not in graph" % e.title) end + trans = Puppet::Transaction.new(config) + execs.each do |e| assert(config.vertex?(e), "%s is not in graph" % e.title) end trans.prepare - execs.each do |e| assert(trans.relgraph.vertex?(e), "%s is not in relgraph" % e.title) end - reverse = trans.relgraph.reversal + execs.each do |e| assert(config.vertex?(e), "%s is not in relgraph" % e.title) end + reverse = trans.relationship_graph.reversal execs.each do |e| assert(reverse.vertex?(e), "%s is not in reversed graph" % e.title) end - - assert_apply(comp) + config.apply assert(FileTest.exists?(file), "File does not exist") diff --git a/test/other/overrides.rb b/test/other/overrides.rb index 2bc443980..9a7c4b8ba 100755 --- a/test/other/overrides.rb +++ b/test/other/overrides.rb @@ -90,12 +90,10 @@ class TestOverrides < Test::Unit::TestCase } } - comp = newcomp("overrides", baseobj) - children.each { |child| comp.push child } + config = mk_configuration(baseobj, *children) assert_nothing_raised("Could not eval component") { - trans = comp.evaluate - trans.evaluate + config.apply } files.each { |path, mode| diff --git a/test/other/relationships.rb b/test/other/relationships.rb index a5c9db5dc..f463b4e5a 100755 --- a/test/other/relationships.rb +++ b/test/other/relationships.rb @@ -174,7 +174,7 @@ class TestRelationships < Test::Unit::TestCase # Now make sure that these relationships are added to the transaction's # relgraph - trans = Puppet::Transaction.new(newcomp(file, exec)) + trans = Puppet::Transaction.new(mk_configuration(file, exec)) assert_nothing_raised do trans.evaluate end diff --git a/test/other/report.rb b/test/other/report.rb index c59881f72..7499c51e2 100755 --- a/test/other/report.rb +++ b/test/other/report.rb @@ -26,16 +26,10 @@ class TestReports < Test::Unit::TestCase ) end - comp = newcomp(*objects) - - trans = nil - assert_nothing_raised("Failed to create transaction") { - trans = comp.evaluate - } - - assert_nothing_raised("Failed to evaluate transaction") { - trans.evaluate - } + config = mk_configuration(*objects) + # So the report works out. + config.retrieval_duration = 0.001 + trans = config.apply return trans.generate_report end diff --git a/test/other/transactions.rb b/test/other/transactions.rb index 833ead662..ecf0361fd 100755 --- a/test/other/transactions.rb +++ b/test/other/transactions.rb @@ -293,11 +293,13 @@ class TestTransactions < Test::Unit::TestCase file[:check] = check file[:group] = @groups[0] - assert_apply(file) + config = mk_configuration(file) + config.apply + config.clear(false) @@tmpfiles << execfile - component = mk_configuration("both",file,exec) + config.add_resource exec # 'subscribe' expects an array of arrays exec[:subscribe] = [[file.class.name,file.name]] @@ -315,7 +317,8 @@ class TestTransactions < Test::Unit::TestCase file[:mode] = "755" } - trans = assert_events([:file_changed, :triggered], component) + trans = assert_events([:file_changed, :triggered], config) + config.clear(false) assert(FileTest.exists?(execfile), "Execfile does not exist") File.unlink(execfile) @@ -323,7 +326,7 @@ class TestTransactions < Test::Unit::TestCase file[:group] = @groups[1] } - trans = assert_events([:file_changed, :triggered], component) + trans = assert_events([:file_changed, :triggered], config) assert(FileTest.exists?(execfile), "Execfile does not exist") end @@ -526,8 +529,8 @@ class TestTransactions < Test::Unit::TestCase assert_nothing_raised do graph = trans.relationship_graph end - - assert_instance_of(Puppet::PGraph, graph, + + assert_instance_of(Puppet::Node::Configuration, graph, "Did not get relationship graph") # Make sure all of the components are gone @@ -642,13 +645,13 @@ class TestTransactions < Test::Unit::TestCase end ya = type["ya"] assert(ya, "Did not generate ya") - assert(trans.relgraph.vertex?(ya), + assert(trans.relationship_graph.vertex?(ya), "Did not add ya to rel_graph") # Now make sure the appropriate relationships were added - assert(trans.relgraph.edge?(yay, ya), + assert(trans.relationship_graph.edge?(yay, ya), "parent was not required by child") - assert(! trans.relgraph.edge?(ya, rah), + assert(! trans.relationship_graph.edge?(ya, rah), "generated child ya inherited depencency on rah") # Now make sure it in turn eval_generates appropriately @@ -659,7 +662,7 @@ class TestTransactions < Test::Unit::TestCase %w{y}.each do |name| res = type[name] assert(res, "Did not generate %s" % name) - assert(trans.relgraph.vertex?(res), + assert(trans.relationship_graph.vertex?(res), "Did not add %s to rel_graph" % name) assert($finished.include?("y"), "y was not finished") end @@ -667,7 +670,7 @@ class TestTransactions < Test::Unit::TestCase assert_nothing_raised("failed to eval_generate with nil response") do trans.eval_resource(type["y"]) end - assert(trans.relgraph.edge?(yay, ya), "no edge was created for ya => yay") + assert(trans.relationship_graph.edge?(yay, ya), "no edge was created for ya => yay") assert_nothing_raised("failed to apply rah") do trans.eval_resource(rah) @@ -675,15 +678,15 @@ class TestTransactions < Test::Unit::TestCase ra = type["ra"] assert(ra, "Did not generate ra") - assert(trans.relgraph.vertex?(ra), + assert(trans.relationship_graph.vertex?(ra), "Did not add ra to rel_graph" % name) assert($finished.include?("ra"), "y was not finished") # Now make sure this generated resource has the same relationships as # the generating resource - assert(! trans.relgraph.edge?(yay, ra), + assert(! trans.relationship_graph.edge?(yay, ra), "rah passed its dependencies on to its children") - assert(! trans.relgraph.edge?(ya, ra), + assert(! trans.relationship_graph.edge?(ya, ra), "children have a direct relationship") # Now make sure that cleanup gets rid of those generated types. @@ -692,7 +695,7 @@ class TestTransactions < Test::Unit::TestCase end %w{ya ra y r}.each do |name| - assert(!trans.relgraph.vertex?(type[name]), + assert(!trans.relationship_graph.vertex?(type[name]), "Generated vertex %s was not removed from graph" % name) assert_nil(type[name], "Generated vertex %s was not removed from class" % name) @@ -878,32 +881,6 @@ class TestTransactions < Test::Unit::TestCase assert(trans.triggered?(c, :refresh), "Transaction did not store the trigger") end - - def test_graph - Puppet.config.use(:main) - # Make a graph - graph = Puppet::Node::Configuration.new - graph.host_config = true - graph.add_edge!("a", "b") - - # Create our transaction - trans = Puppet::Transaction.new(graph) - - assert_nothing_raised do - trans.graph(graph, :testing) - end - - dotfile = File.join(Puppet[:graphdir], "testing.dot") - assert(! FileTest.exists?(dotfile), "Enabled graphing even tho disabled") - - # Now enable graphing - Puppet[:graph] = true - - assert_nothing_raised do - trans.graph(graph, :testing) - end - assert(FileTest.exists?(dotfile), "Did not create graph.") - end def test_set_target file = Puppet::Type.newfile(:path => tempfile(), :content => "yay") @@ -1032,7 +1009,7 @@ class TestTransactions < Test::Unit::TestCase trans.prepare end - graph = trans.relgraph + graph = trans.relationship_graph assert(graph.edge?(before, after), "did not create manual relationship %s" % str) assert(! graph.edge?(after, before), "created automatic relationship %s" % str) end diff --git a/test/ral/manager/type.rb b/test/ral/manager/type.rb index 534c35759..4f2db4805 100755 --- a/test/ral/manager/type.rb +++ b/test/ral/manager/type.rb @@ -174,7 +174,7 @@ class TestType < Test::Unit::TestCase ) } - comp = newcomp(twoobj, oneobj) + comp = mk_configuration(twoobj, oneobj) assert_nothing_raised { comp.finalize @@ -732,12 +732,22 @@ class TestType < Test::Unit::TestCase end def test_path + config = mk_configuration + # Check that our paths are built correctly. Just pick a random, "normal" type. type = Puppet::Type.type(:exec) mk = Proc.new do |i, hash| hash[:title] = "exec%s" % i hash[:command] = "/bin/echo" - type.create(hash) + if parent = hash[:parent] + hash.delete(:parent) + end + res = type.create(hash) + config.add_resource res + if parent + config.add_edge!(parent, res) + end + res end exec = mk.call(1, {}) @@ -745,25 +755,31 @@ class TestType < Test::Unit::TestCase assert_equal("/Exec[exec1]", exec.path) comp = Puppet::Type.newcomponent :title => "My[component]", :type => "Yay" + config.add_resource comp exec = mk.call(2, :parent => comp) assert_equal("/My[component]/Exec[exec2]", exec.path) comp = Puppet::Type.newcomponent :name => "Other[thing]" + config.add_resource comp exec = mk.call(3, :parent => comp) assert_equal("/Other[thing]/Exec[exec3]", exec.path) comp = Puppet::Type.newcomponent :type => "server", :name => "server" + config.add_resource comp exec = mk.call(4, :parent => comp) assert_equal("/server/Exec[exec4]", exec.path) comp = Puppet::Type.newcomponent :type => "whatever", :name => "class[main]" + config.add_resource comp exec = mk.call(5, :parent => comp) assert_equal("//Exec[exec5]", exec.path) - comp = Puppet::Type.newcomponent :type => "yay", :name => "Good[bad]", :parent => comp - exec = mk.call(6, :parent => comp) + newcomp = Puppet::Type.newcomponent :type => "yay", :name => "Good[bad]" + config.add_resource newcomp + config.add_edge! comp, newcomp + exec = mk.call(6, :parent => newcomp) assert_equal("//Good[bad]/Exec[exec6]", exec.path) end diff --git a/test/ral/providers/service.rb b/test/ral/providers/service.rb index d21298162..5a4a6c1c2 100755 --- a/test/ral/providers/service.rb +++ b/test/ral/providers/service.rb @@ -54,7 +54,7 @@ class TestLocalService < Test::Unit::TestCase service.retrieve } - comp = newcomp("servicetst", service) + comp = mk_configuration("servicetst", service) service[:ensure] = :running Puppet.info "Starting %s" % service.name @@ -105,7 +105,7 @@ class TestLocalService < Test::Unit::TestCase service.retrieve } - comp = newcomp("servicetst", service) + comp = mk_configuration("servicetst", service) service[:enable] = true Puppet.info "Enabling %s" % service.name diff --git a/test/ral/types/basic.rb b/test/ral/types/basic.rb index 5d09a5183..2802f3440 100755 --- a/test/ral/types/basic.rb +++ b/test/ral/types/basic.rb @@ -35,12 +35,9 @@ class TestBasic < Test::Unit::TestCase :path => ENV["PATH"] ) } - assert_nothing_raised() { - @component.push( - @configfile, - @command - ) - } + @config = mk_configuration(@component, @configfile, @command) + @config.add_edge! @component, @configfile + @config.add_edge! @component, @command end def teardown @@ -86,5 +83,3 @@ class TestBasic < Test::Unit::TestCase } end end - -# $Id$ diff --git a/test/ral/types/component.rb b/test/ral/types/component.rb deleted file mode 100755 index 06c32dd01..000000000 --- a/test/ral/types/component.rb +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/env ruby - -$:.unshift("../../lib") if __FILE__ =~ /\.rb$/ - -require 'puppettest' -require 'puppettest/support/resources' - -# $Id$ - -class TestComponent < Test::Unit::TestCase - include PuppetTest - include PuppetTest::Support::Resources - def setup - super - @@used = {} - @type = Puppet::Type::Component - @file = Puppet::Type.type(:file) - end - - def randnum(limit) - num = nil - looped = 0 - loop do - looped += 1 - if looped > 2000 - raise "Reached limit of looping" - break - end - num = rand(limit) - unless @@used.include?(num) - @@used[num] = true - break - end - end - - num - end - - def mkfile(num = nil) - unless num - num = randnum(1000) - end - name = tempfile() + num.to_s - - file = Puppet.type(:file).create( - :path => name, - :checksum => "md5" - ) - @@tmpfiles << name - file - end - - def mkcomp - Puppet.type(:component).create(:name => "component_" + randnum(1000).to_s) - end - - def mkrandcomp(numfiles, numdivs) - comp = mkcomp - hash = {} - found = 0 - - divs = {} - - numdivs.times { |i| - num = i + 2 - divs[num] = nil - } - while found < numfiles - num = randnum(numfiles) - found += 1 - f = mkfile(num) - hash[f.name] = f - reqd = [] - divs.each { |n,obj| - if rand(50) % n == 0 - if obj - unless reqd.include?(obj.object_id) - f[:require] = [[obj.class.name, obj.name]] - reqd << obj.object_id - end - end - end - - divs[n] = f - } - end - - hash.each { |name, obj| - comp.push obj - } - - comp.finalize - comp - end - - def test_to_graph - one, two, middle, top = mktree - - graph = nil - assert_nothing_raised do - graph = top.to_graph - end - - assert(graph.is_a?(Puppet::PGraph), "result is not a pgraph") - - [one, two, middle, top].each do |comp| - comp.each do |child| - assert(graph.edge?(comp, child), - "Did not create edge from %s => %s" % [comp.name, child.name]) - end - end - end -end diff --git a/test/ral/types/cron.rb b/test/ral/types/cron.rb index 7b2e770f0..1695befac 100755 --- a/test/ral/types/cron.rb +++ b/test/ral/types/cron.rb @@ -94,7 +94,7 @@ class TestCron < Test::Unit::TestCase text = obj.read name = cron.name - comp = newcomp(name, cron) + comp = mk_configuration(name, cron) assert_events([:cron_created], comp) cron.provider.class.prefetch @@ -157,7 +157,7 @@ class TestCron < Test::Unit::TestCase def test_makeandretrievecron %w{storeandretrieve a-name another-name more_naming SomeName}.each do |name| cron = mkcron(name) - comp = newcomp(name, cron) + comp = mk_configuration(name, cron) trans = assert_events([:cron_created], comp, name) cron.provider.class.prefetch diff --git a/test/ral/types/exec.rb b/test/ral/types/exec.rb index ede6361cd..0c7cc1d90 100755 --- a/test/ral/types/exec.rb +++ b/test/ral/types/exec.rb @@ -179,7 +179,7 @@ class TestExec < Test::Unit::TestCase ) } - comp = newcomp("createstest", exec) + comp = mk_configuration("createstest", exec) assert_events([:executed_command], comp, "creates") assert_events([], comp, "creates") end @@ -202,7 +202,7 @@ class TestExec < Test::Unit::TestCase :require => [:file, oexe] ) - comp = newcomp("Testing", file, exec) + comp = mk_configuration("Testing", file, exec) assert_events([:file_created, :executed_command], comp) end @@ -299,7 +299,7 @@ class TestExec < Test::Unit::TestCase :path => ENV['PATH'] ) } - comp = newcomp(exec) + comp = mk_configuration(exec) assert_events([:executed_command], comp) assert_events([:executed_command], comp) @@ -344,7 +344,7 @@ class TestExec < Test::Unit::TestCase exec = Puppet.type(:exec).create(args) } - comp = newcomp("usertest", exec) + comp = mk_configuration("usertest", exec) assert_events([:executed_command], comp, "usertest") assert(FileTest.exists?(file), "File does not exist") @@ -425,7 +425,7 @@ class TestExec < Test::Unit::TestCase ) } - comp = newcomp(file, exec) + comp = mk_configuration(file, exec) comp.finalize assert_events([:executed_command, :file_changed], comp) diff --git a/test/ral/types/file.rb b/test/ral/types/file.rb index f3e1a562d..47fb87afd 100755 --- a/test/ral/types/file.rb +++ b/test/ral/types/file.rb @@ -122,7 +122,7 @@ class TestFile < Test::Unit::TestCase ) } - comp = newcomp("createusertest", file) + comp = mk_configuration("createusertest", file) assert_events([:file_created], comp) end @@ -397,6 +397,8 @@ class TestFile < Test::Unit::TestCase events = assert_apply(file) + assert(events) + assert(! events.include?(:file_changed), "File incorrectly changed") assert_events([], file) @@ -493,6 +495,7 @@ class TestFile < Test::Unit::TestCase # Create a test directory path = tempfile() dir = @file.create :path => path, :mode => 0755, :recurse => true + config = mk_configuration(dir) Dir.mkdir(path) @@ -673,6 +676,7 @@ class TestFile < Test::Unit::TestCase :check => %w{owner mode group} ) } + mk_configuration dir children = nil @@ -754,6 +758,7 @@ class TestFile < Test::Unit::TestCase :check => %w{owner mode group} ) } + mk_configuration dir assert_nothing_raised { dir.eval_generate @@ -796,6 +801,7 @@ class TestFile < Test::Unit::TestCase :check => %w{mode owner group} ) } + mk_configuration dirobj assert_nothing_raised { dirobj.eval_generate @@ -884,7 +890,7 @@ class TestFile < Test::Unit::TestCase ) } - comp = newcomp("yay", file) + comp = mk_configuration("yay", file) comp.finalize assert_apply(comp) #assert_events([:directory_created], comp) @@ -1274,26 +1280,29 @@ class TestFile < Test::Unit::TestCase lfobj = Puppet::Type.newfile( :title => "localfile", :path => localfile, - :content => "rahtest" + :content => "rahtest", + :backup => false ) + Puppet[:evaltrace] = true destobj = Puppet::Type.newfile(:title => "destdir", :path => destdir, :source => sourcedir, + :backup => false, :recurse => true) - comp = newcomp(lfobj, destobj) - assert_apply(comp) + config = mk_configuration(lfobj, destobj) + config.apply assert(FileTest.exists?(dsourcefile), "File did not get copied") assert(FileTest.exists?(localfile), "File did not get created") assert(FileTest.exists?(purgee), "File got prematurely purged") assert_nothing_raised { destobj[:purge] = true } - assert_apply(comp) + config.apply - assert(FileTest.exists?(dsourcefile), "Source file got purged") assert(FileTest.exists?(localfile), "Local file got purged") + assert(FileTest.exists?(dsourcefile), "Source file got purged") assert(! FileTest.exists?(purgee), "File did not get purged") end @@ -1333,7 +1342,7 @@ class TestFile < Test::Unit::TestCase group = Puppet.type(:group).create( :name => "pptestg" ) - comp = newcomp(user, group, home) + comp = mk_configuration(user, group, home) } # Now make sure we get a relationship for each of these @@ -1629,6 +1638,7 @@ class TestFile < Test::Unit::TestCase file = File.join(dir, "file") File.open(file, "w") { |f| f.puts "" } obj = Puppet::Type.newfile :path => dir, :recurse => true, :mode => 0755 + mk_configuration obj assert_equal("/%s" % obj.ref, obj.path) @@ -1739,14 +1749,17 @@ class TestFile < Test::Unit::TestCase File.open(file, "w") { |f| f.puts "yay" } File.chmod(0644, file) obj = Puppet::Type.newfile(:path => dir, :mode => 0750, :recurse => "2") + config = mk_configuration(obj) children = nil assert_nothing_raised("Failure when recursing") do children = obj.eval_generate end + config.add_resource(*children) assert(obj.class[subdir], "did not create subdir object") children.each do |c| assert_nothing_raised("Failure when recursing on %s" % c) do + c.configuration = config others = c.eval_generate end end @@ -1780,6 +1793,7 @@ class TestFile < Test::Unit::TestCase obj = Puppet::Type.newfile(:path => dir, :ensure => :directory, :recurse => true) + config = mk_configuration(obj) children = nil assert_nothing_raised do children = obj.eval_generate diff --git a/test/ral/types/file/target.rb b/test/ral/types/file/target.rb index 1e62f07ac..c4597cedf 100755 --- a/test/ral/types/file/target.rb +++ b/test/ral/types/file/target.rb @@ -44,6 +44,7 @@ class TestFileTarget < Test::Unit::TestCase def test_linkrecurse dest = tempfile() link = @file.create :path => tempfile(), :recurse => true, :ensure => dest + mk_configuration link ret = nil @@ -317,9 +318,8 @@ class TestFileTarget < Test::Unit::TestCase :source => dirs["source"], :recurse => true ) - - - trans = assert_apply(obj) + config = mk_configuration obj + config.apply newfile = File.join(dirs["target"], "sourcefile") diff --git a/test/ral/types/fileignoresource.rb b/test/ral/types/fileignoresource.rb index fa01aecdc..153946770 100755 --- a/test/ral/types/fileignoresource.rb +++ b/test/ral/types/fileignoresource.rb @@ -73,19 +73,8 @@ class TestFileIgnoreSources < Test::Unit::TestCase ) } - #make a component and adds the file - comp = Puppet.type(:component).create( - :name => "component" - ) - comp.push tofile - - #make, evaluate transaction and sync the component - assert_nothing_raised { - trans = comp.evaluate - } - assert_nothing_raised { - trans.evaluate - } + config = mk_configuration(tofile) + config.apply #topath should exist as a directory with sourcedir as a directory @@ -150,19 +139,8 @@ class TestFileIgnoreSources < Test::Unit::TestCase ) } - #make a component and adds the file - comp = Puppet.type(:component).create( - :name => "component" - ) - comp.push tofile - - #make, evaluate transaction and sync the component - assert_nothing_raised { - trans = comp.evaluate - } - assert_nothing_raised { - trans.evaluate - } + config = mk_configuration(tofile) + config.apply #topath should exist as a directory with sourcedir as a directory @@ -170,6 +148,7 @@ class TestFileIgnoreSources < Test::Unit::TestCase assert(FileTest.exists?(File.join(topath,sourcefile1))) assert(FileTest.exists?(File.join(topath,subdir))) assert(FileTest.exists?(File.join(File.join(topath,subdir),sourcefile1))) + #This file should not assert(!(FileTest.exists?(File.join(topath,sourcefile2)))) assert(!(FileTest.exists?(File.join(topath,subdir2)))) @@ -235,19 +214,8 @@ class TestFileIgnoreSources < Test::Unit::TestCase ) } - #make a component and adds the file - comp = Puppet.type(:component).create( - :name => "component" - ) - comp.push tofile - - #make, evaluate transaction and sync the component - assert_nothing_raised { - trans = comp.evaluate - } - assert_nothing_raised { - trans.evaluate - } + config = mk_configuration(tofile) + config.apply #topath should exist as a directory with sourcedir as a directory @@ -273,5 +241,3 @@ class TestFileIgnoreSources < Test::Unit::TestCase end end - -# $Id$ diff --git a/test/ral/types/filesources.rb b/test/ral/types/filesources.rb index b257fd935..046d46c1e 100755 --- a/test/ral/types/filesources.rb +++ b/test/ral/types/filesources.rb @@ -62,6 +62,7 @@ class TestFileSources < Test::Unit::TestCase :name => path ) } + config = mk_configuration(file) child = nil assert_nothing_raised { child = file.newchild("childtest", true) @@ -275,6 +276,7 @@ class TestFileSources < Test::Unit::TestCase # The sourcerecurse method will only ever get called when we're # recursing, so we go ahead and set it. obj = Puppet::Type.newfile :source => source, :path => dest, :recurse => true + config = mk_configuration(obj) result = nil sourced = nil @@ -577,51 +579,6 @@ class TestFileSources < Test::Unit::TestCase } end - def test_networkSourcesWithoutService - server = nil - - Puppet[:autosign] = true - Puppet[:masterport] = 8765 - - serverpid = nil - assert_nothing_raised() { - server = Puppet::Network::Server::WEBrick.new( - :Handlers => { - :CA => {}, # so that certs autogenerate - } - ) - - } - serverpid = fork { - assert_nothing_raised() { - #trap(:INT) { server.shutdown; Kernel.exit! } - trap(:INT) { server.shutdown } - server.start - } - } - @@tmppids << serverpid - - sleep(1) - - name = File.join(tmpdir(), "nosourcefile") - file = Puppet.type(:file).create( - :source => "puppet://localhost/dist/file", - :name => name - ) - - assert_nothing_raised { - file.retrieve - } - - comp = newcomp("nosource", file) - - assert_nothing_raised { - comp.evaluate - } - - assert(!FileTest.exists?(name), "File with no source exists anyway") - end - def test_unmountedNetworkSources server = nil mounts = { @@ -669,11 +626,8 @@ class TestFileSources < Test::Unit::TestCase file.retrieve } - comp = newcomp("nosource", file) - - assert_nothing_raised { - comp.evaluate - } + comp = mk_configuration(file) + comp.apply assert(!FileTest.exists?(name), "File with no source exists anyway") end @@ -722,7 +676,7 @@ class TestFileSources < Test::Unit::TestCase ) } - comp = newcomp(file) + comp = mk_configuration(file) assert_events([:file_created], comp) assert(File.exists?(to), "File does not exist") @@ -808,9 +762,8 @@ class TestFileSources < Test::Unit::TestCase trans = nil assert_nothing_raised { file[:links] = :manage - comp = newcomp(file) - trans = comp.evaluate - trans.evaluate + comp = mk_configuration(file) + trans = comp.apply } assert(trans.failed?(file), "Object did not fail to copy links") diff --git a/test/ral/types/group.rb b/test/ral/types/group.rb index 9870d533a..5189c63a1 100755 --- a/test/ral/types/group.rb +++ b/test/ral/types/group.rb @@ -65,7 +65,7 @@ class TestGroup < Test::Unit::TestCase def attrtest_ensure(group) group[:ensure] = :absent - comp = newcomp("ensuretest", group) + comp = mk_configuration("ensuretest", group) assert_apply(comp) assert_equal(:absent, group.provider.ensure, "Group is still present") group[:ensure] = :present @@ -91,7 +91,7 @@ class TestGroup < Test::Unit::TestCase assert_equal(15, group.should(:gid), "Did not convert gid to number") - comp = newcomp(group) + comp = mk_configuration(group) trans = assert_events([:group_modified], comp, "group") assert_equal(15, group.provider.gid, "GID was not changed") diff --git a/test/ral/types/tidy.rb b/test/ral/types/tidy.rb index b8d576b9a..8fada1adb 100755 --- a/test/ral/types/tidy.rb +++ b/test/ral/types/tidy.rb @@ -55,7 +55,7 @@ class TestTidy < Test::Unit::TestCase assert_nothing_raised { link = newlink(:target => source, :recurse => true) } - comp = newcomp("linktest",link) + comp = mk_configuration("linktest",link) cycle(comp) path = link.name diff --git a/test/ral/types/user.rb b/test/ral/types/user.rb index 121ac9cf0..9b24cc74a 100755 --- a/test/ral/types/user.rb +++ b/test/ral/types/user.rb @@ -82,7 +82,7 @@ class TestUser < Test::Unit::TestCase old = user.provider.ensure user[:ensure] = :absent - comp = newcomp("ensuretest", user) + comp = mk_configuration("ensuretest", user) assert_apply(user) assert(!user.provider.exists?, "User is still present") user[:ensure] = :present @@ -102,7 +102,7 @@ class TestUser < Test::Unit::TestCase old = user.provider.comment user[:comment] = "A different comment" - comp = newcomp("commenttest", user) + comp = mk_configuration("commenttest", user) trans = assert_events([:user_changed], comp, "user") @@ -117,7 +117,7 @@ class TestUser < Test::Unit::TestCase def attrtest_home(user) obj = nil - comp = newcomp("hometest", user) + comp = mk_configuration("hometest", user) old = user.provider.home user[:home] = old @@ -137,7 +137,7 @@ class TestUser < Test::Unit::TestCase def attrtest_shell(user) old = user.provider.shell - comp = newcomp("shelltest", user) + comp = mk_configuration("shelltest", user) user[:shell] = old @@ -167,7 +167,7 @@ class TestUser < Test::Unit::TestCase def attrtest_gid(user) obj = nil old = user.provider.gid - comp = newcomp("gidtest", user) + comp = mk_configuration("gidtest", user) user.retrieve @@ -216,7 +216,7 @@ class TestUser < Test::Unit::TestCase def attrtest_uid(user) obj = nil - comp = newcomp("uidtest", user) + comp = mk_configuration("uidtest", user) user.provider.uid = 1 @@ -387,7 +387,7 @@ class TestUser < Test::Unit::TestCase ogroup = Puppet.type(:group).create( :name => "yayness" ) - comp = newcomp(user, group, home, ogroup) + comp = mk_configuration(user, group, home, ogroup) } rels = nil @@ -404,7 +404,7 @@ class TestUser < Test::Unit::TestCase user = mkuser(name) - comp = newcomp("usercomp", user) + comp = mk_configuration("usercomp", user) trans = assert_events([:user_created], comp, "user") @@ -424,7 +424,7 @@ class TestUser < Test::Unit::TestCase assert(! user.provider.exists?, "User %s is present" % name) - comp = newcomp("usercomp", user) + comp = mk_configuration("usercomp", user) trans = assert_events([:user_created], comp, "user") diff --git a/test/util/config.rb b/test/util/config.rb index f99ad54b4..cbd02b4f9 100755 --- a/test/util/config.rb +++ b/test/util/config.rb @@ -59,57 +59,6 @@ class TestConfig < Test::Unit::TestCase } end - # #795 - when --config=relative, we want to fully expand file paths. - def test_relative_paths_when_to_transportable - config = mkconfig - config.setdefaults :yay, :transtest => ["/what/ever", "yo"] - file = config.element(:transtest) - - # Now override it with a relative path name - config[:transtest] = "here" - - should = File.join(Dir.getwd, "here") - - object = file.to_transportable[0] - assert_equal(should, object.name, "Did not translate relative pathnames to full path names") - end - - def test_to_manifest - set_configs - manifest = nil - assert_nothing_raised("Could not convert to a manifest") { - manifest = @config.to_manifest - } - - Puppet[:parseonly] = true - - interp = nil - assert_nothing_raised do - interp = mkinterp :Code => manifest, :UseNodes => false - end - - trans = nil - node = Puppet::Node.new("node") - assert_nothing_raised do - trans = interp.compile(node) - end - assert_nothing_raised("Could not instantiate objects") { - trans.extract.to_type - } - end - - def test_to_comp - set_configs - comp = nil - assert_nothing_raised("Could not convert to a component") { - comp = @config.to_component - } - - assert_nothing_raised("Could not retrieve component") { - comp.retrieve - } - end - def test_to_config set_configs @@ -668,91 +617,6 @@ yay = /a/path assert_equal("/my/file", @config[:b], "Values are not equal") end - def test_reuse - c = mkconfig - - file = tempfile() - section = "testing" - assert_nothing_raised { - @config.setdefaults(section, - :myfile => {:default => file, :create => true, :desc => "yay"} - ) - } - - assert_nothing_raised("Could not use a section") { - @config.use(section) - } - - assert(FileTest.exists?(file), "Did not create file") - - assert(! Puppet::Type.type(:file)[file], "File obj still exists") - - File.unlink(file) - - @config.reuse - assert(FileTest.exists?(file), "Did not create file") - end - - def test_mkusers - c = mkconfig - - file = tempfile() - section = "testing" - assert_nothing_raised { - @config.setdefaults(section, - :mkusers => [false, "yay"], - :myfile => { - :default => file, - :owner => "pptest", - :group => "pptest", - :desc => "yay", - :create => true - } - ) - } - - comp = nil - assert_nothing_raised { - comp = @config.to_component - } - - [:user, :group].each do |type| - # The objects might get created internally by Puppet::Util; just - # make sure they're not being managed - if obj = Puppet.type(type)["pptest"] - assert(! obj.managed?, "%s objectis managed" % type) - end - end - comp.each { |o| o.remove } - - @config[:mkusers] = true - - assert_nothing_raised { - @config.to_component - } - - user = Puppet.type(:user)["pptest"] - assert(user, "User object did not get created") - assert(user.managed?, "User object is not managed.") - assert(user.should(:comment), "user does not have a comment set") - - group = Puppet.type(:group)["pptest"] - assert(group, "Group object did not get created") - assert(group.managed?, - "Group object is not managed." - ) - - if Process.uid == 0 - cleanup do - user[:ensure] = :absent - group[:ensure] = :absent - assert_apply(user, group) - end - - assert_apply(user, group) - end - end - def test_notmanagingdev c = mkconfig path = "/dev/testing" @@ -764,11 +628,9 @@ yay = /a/path } ) - assert_nothing_raised { - @config.to_component - } + config = @config.to_configuration - assert(! Puppet.type(:file)["/dev/testing"], "Created dev file") + assert(! config.resource(:file, "/dev/testing"), "Created dev file") end def test_groupsetting @@ -1119,12 +981,12 @@ yay = /a/path # Now enable it so they'll be added config[:mkusers] = true - comp = config.to_component + comp = config.to_configuration - Puppet::Type.type(:user).each do |u| + comp.vertices.find_all { |r| r.class.name == :user }.each do |u| assert(u.name != "root", "Tried to manage root user") end - Puppet::Type.type(:group).each do |u| + comp.vertices.find_all { |r| r.class.name == :group }.each do |u| assert(u.name != "root", "Tried to manage root group") assert(u.name != "wheel", "Tried to manage wheel group") end diff --git a/test/util/fact_store.rb b/test/util/fact_store.rb deleted file mode 100755 index 5b04d1374..000000000 --- a/test/util/fact_store.rb +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env ruby -# -# Created by Luke Kanies on 2007-05-02. -# Copyright (c) 2007. All rights reserved. - -$:.unshift("../lib").unshift("../../lib") if __FILE__ =~ /\.rb$/ - -require 'puppettest' -require 'puppet/util/fact_store' - -class TestFactStore < Test::Unit::TestCase - include PuppetTest - - def test_new_fact_store - klass = nil - assert_nothing_raised("Could not create fact store") do - klass = Puppet::Util::FactStore.newstore(:yay) do - end - end - - assert_equal(klass, Puppet::Util::FactStore.store(:yay), "Did not get created store back by name") - end - - def test_yaml_store - yaml = Puppet::Util::FactStore.store(:yaml) - assert(yaml, "Could not retrieve yaml store") - - name = "node" - facts = {"a" => :b, :c => "d", :e => :f, "g" => "h"} - - store = nil - assert_nothing_raised("Could not create YAML store instance") do - store = yaml.new - end - - assert_nothing_raised("Could not store host facts") do - store.set(name, facts) - end - - dir = Puppet[:yamlfactdir] - - file = File.join(dir, name + ".yaml") - assert(FileTest.exists?(file), "Did not create yaml file for node") - - text = File.read(file) - newfacts = nil - assert_nothing_raised("Could not deserialize yaml") do - newfacts = YAML::load(text) - end - - # Don't directly compare the hashes, because there might be extra - # data stored in the client hash - facts.each do |var, value| - assert_equal(value, newfacts[var], "Value for %s changed during storage" % var) - end - - # Now make sure the facts get retrieved correctly - assert_nothing_raised("Could not retrieve facts") do - newfacts = store.get(name) - end - - # Now make sure the hashes are equal, since internal facts should not be returned. - assert_equal(facts, newfacts, "Retrieved facts are not equal") - end -end - -# $Id$ diff --git a/test/util/graph.rb b/test/util/graph.rb deleted file mode 100755 index 875fd0ec3..000000000 --- a/test/util/graph.rb +++ /dev/null @@ -1,108 +0,0 @@ -#!/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' -require 'puppet/util/graph' - -class TestUtilGraph < Test::Unit::TestCase - include PuppetTest - include PuppetTest::Graph - - def test_to_graph - children = %w{a b c d} - list = Container.new("yay", children) - - graph = nil - assert_nothing_raised do - graph = list.to_graph - end - - assert(graph.vertices.include?(list), "wtf?") - - ([list] + children).each do |thing| - assert(graph.vertex?(thing), "%s is not a vertex" % thing) - end - children.each do |child| - assert(graph.edge?(list, child), - "%s/%s was not added as an edge" % ["yay", child]) - end - end - - def test_recursive_to_graph - one, two, three, middle, top = build_tree - - graph = nil - assert_nothing_raised do - graph = top.to_graph - end - - (%w{a b c d e f g h} + [one, two, middle, top]).each do |v| - assert(graph.vertex?(v), "%s is not a vertex" % v) - end - - [one, two, middle, top].each do |con| - con.each do |child| - assert(graph.edge?(con, child), "%s/%s is not an edge" % [con, child]) - end - end - - # Now make sure we correctly retrieve the leaves from each container - {top => %w{a b c d e f g h i j}, - one => %w{a b}, - two => %w{c d}, - three => %w{i j}, - middle => %w{c d e f}}.each do |cont, list| - leaves = nil - assert_nothing_raised do - leaves = graph.leaves(cont) - end - leaves = leaves.sort - assert_equal(list.sort, leaves.sort, - "Got incorrect leaf list for %s" % cont.name) - %w{a b c d e f g h}.each do |letter| - unless list.include?(letter) - assert(!leaves.include?(letter), - "incorrectly got %s as a leaf of %s" % - [letter, cont.to_s]) - end - end - end - end - - def test_to_graph_with_block - middle = Container.new "middle", ["c", "d", 3, 4] - top = Container.new "top", ["a", "b", middle, 1, 2] - - graph = nil - assert_nothing_raised() { - graph = top.to_graph { |c| c.is_a?(String) or c.is_a?(Container) } - } - - %w{a b c d}.each do |child| - assert(graph.vertex?(child), "%s was not added as a vertex" % child) - end - - [1, 2, 3, 4].each do |child| - assert(! graph.vertex?(child), "%s is a vertex" % child) - end - end - - def test_cyclic_graphs - one = Container.new "one", %w{a b} - two = Container.new "two", %w{c d} - - one.push(two) - two.push(one) - - assert_raise(Puppet::Error, "did not fail on cyclic graph") do - one.to_graph - end - end -end - -# $Id$ |