#!/usr/bin/env ruby $:.unshift("../lib").unshift("../../lib") if __FILE__ =~ /\.rb$/ require 'puppet/rails' require 'puppettest' require 'puppettest/parsertesting' require 'puppettest/resourcetesting' require 'puppettest/railstesting' class TestCollector < Test::Unit::TestCase include PuppetTest include PuppetTest::ParserTesting include PuppetTest::ResourceTesting include PuppetTest::RailsTesting Parser = Puppet::Parser AST = Parser::AST def setup super Puppet[:trace] = false @interp, @scope, @source = mkclassframing end # Test just collecting a specific resource. This is used by the 'realize' # function, and it's much faster than iterating over all of the resources. def test_collect_resource # Make a collector coll = nil assert_nothing_raised do coll = Puppet::Parser::Collector.new(@scope, "file", nil, nil, :virtual) end # Now set the resource in the collector assert_nothing_raised do coll.resources = ["File[/tmp/virtual1]", "File[/tmp/virtual3]"] end @scope.newcollection(coll) # Evaluate the collector and make sure it doesn't fail with no resources # found yet assert_nothing_raised("Resource collection with no results failed") do assert_equal(false, coll.evaluate) end # Make a couple of virtual resources one = mkresource(:type => "file", :title => "/tmp/virtual1", :virtual => true, :params => {:owner => "root"}) two = mkresource(:type => "file", :title => "/tmp/virtual2", :virtual => true, :params => {:owner => "root"}) @scope.setresource one @scope.setresource two # Now run the collector again and make sure it finds our resource assert_nothing_raised do assert_equal([one], coll.evaluate, "did not find resource") end # And make sure the resource is no longer virtual assert(! one.virtual?, "Resource is still virtual") # But the other still is assert(two.virtual?, "Resource got realized") # Make sure that the collection is still there assert(@scope.collections.include?(coll), "collection was deleted too soon") # Now add our third resource three = mkresource(:type => "file", :title => "/tmp/virtual3", :virtual => true, :params => {:owner => "root"}) @scope.setresource three # Run the collection assert_nothing_raised do assert_equal([three], coll.evaluate, "did not find resource") end assert(! three.virtual?, "three is still virtual") # And make sure that the collection got deleted from the scope's list assert(@scope.collections.empty?, "collection was not deleted") end def test_virtual # Make a virtual resource virtual = mkresource(:type => "file", :title => "/tmp/virtual", :virtual => true, :params => {:owner => "root"}) @scope.setresource virtual # And a non-virtual real = mkresource(:type => "file", :title => "/tmp/real", :params => {:owner => "root"}) @scope.setresource real # Now make a collector coll = nil # Make a fake query code = proc do |res| true end assert_nothing_raised do coll = Puppet::Parser::Collector.new(@scope, "file", nil, code, :virtual) end # Set it in our scope @scope.newcollection(coll) # Make sure it's in the collections assert(@scope.collections.include?(coll), "collection was not added") # And try to collect the virtual resources. ret = nil assert_nothing_raised do ret = coll.collect_virtual end assert_equal([virtual], ret) # Now make sure evaluate does the right thing. assert_nothing_raised do ret = coll.evaluate end # And make sure our virtual object is no longer virtual assert(! virtual.virtual?, "Virtual object did not get realized") # Now make a new collector of a different type and make sure it # finds nothing. assert_nothing_raised do coll = Puppet::Parser::Collector.new(@scope, "exec", nil, nil, :virtual) end # Remark this as virtual virtual.virtual = true assert_nothing_raised do ret = coll.evaluate end assert_equal(false, ret) end if Puppet.features.rails? def test_collect_exported railsinit # Set a hostname @scope.host = Facter.value(:hostname) # make an exported resource exported = mkresource(:type => "file", :title => "/tmp/exported", :exported => true, :params => {:owner => "root"}) @scope.setresource exported assert(exported.exported?, "Object was not marked exported") assert(exported.virtual?, "Object was not marked virtual") # And a non-exported real = mkresource(:type => "file", :title => "/tmp/real", :params => {:owner => "root"}) @scope.setresource real # Now make a collector coll = nil assert_nothing_raised do coll = Puppet::Parser::Collector.new(@scope, "file", nil, nil, :exported) end # Set it in our scope @scope.newcollection(coll) # Make sure it's in the collections assert_equal([coll], @scope.collections) # And try to collect the virtual resources. ret = nil assert_nothing_raised do ret = coll.collect_exported end assert_equal([exported], ret) # Now make sure evaluate does the right thing. assert_nothing_raised do ret = coll.evaluate end # Make sure that the collection does not find the resource on the # next run. ret = nil assert_nothing_raised do ret = coll.collect_exported end assert(ret.empty?, "Exported resource was collected on the second run") # And make sure our exported object is no longer exported assert(! exported.virtual?, "Virtual object did not get realized") # But it should still be marked exported. assert(exported.exported?, "Resource got un-exported") # Now make a new collector of a different type and make sure it # finds nothing. assert_nothing_raised do coll = Puppet::Parser::Collector.new(@scope, "exec", nil, nil, :exported) end # Remark this as virtual exported.virtual = true assert_nothing_raised do ret = coll.evaluate end assert(! ret, "got resources back") # Now create a whole new scope and make sure we can actually retrieve # the resource from the database, not just from the scope. # First create a host object and store our resource in it. # Now collect our facts facts = {} Facter.each do |fact, value| facts[fact] = value end # Now try storing our crap # Remark this as exported exported.exported = true host = Puppet::Rails::Host.store( :resources => [exported], :facts => facts, :name => facts["hostname"] ) assert(host, "did not get rails host") host.save # And make sure it's in there newres = host.resources.find_by_restype_and_title_and_exported("file", "/tmp/exported", true) assert(newres, "Did not find resource in db") interp, scope, source = mkclassframing scope.host = "two" # Now make a collector coll = nil assert_nothing_raised do coll = Puppet::Parser::Collector.new(scope, "file", nil, nil, :exported) end # Set it in our scope scope.newcollection(coll) # Make sure it's in the collections assert_equal([coll], scope.collections) # And try to collect the virtual resources. ret = nil assert_nothing_raised do ret = coll.collect_exported end assert_equal(["/tmp/exported"], ret.collect { |f| f.title }) # Make sure we can evaluate the same collection multiple times and # that later collections do nothing assert_nothing_raised("Collection found same resource twice") do ret = coll.evaluate end end def test_collection_conflicts railsinit # First make a railshost we can conflict with host = Puppet::Rails::Host.new(:name => "myhost") host.resources.build(:title => "/tmp/conflicttest", :restype => "file", :exported => true) host.save # Now make a normal resource normal = mkresource(:type => "file", :title => "/tmp/conflicttest", :params => {:owner => "root"}) @scope.setresource normal @scope.host = "otherhost" # Now make a collector coll = nil assert_nothing_raised do coll = Puppet::Parser::Collector.new(@scope, "file", nil, nil, :exported) end # And try to collect the virtual resources. assert_raise(Puppet::ParseError) do ret = coll.collect_exported end end # Make sure we do not collect resources from the host we're on def test_no_resources_from_me railsinit # Make our configuration host = Puppet::Rails::Host.new(:name => "myhost") host.resources.build(:title => "/tmp/hosttest", :type => "file", :exported => true) host.save @scope.host = "myhost" # Now make a collector coll = nil assert_nothing_raised do coll = Puppet::Parser::Collector.new(@scope, "file", nil, nil, :exported) end # And make sure we get nada back ret = nil assert_nothing_raised do ret = coll.collect_exported end assert(ret.empty?, "Found exports from our own host") end end # Collections that specify resources should be deleted when they succeed, # but others should remain until the very end. def test_normal_collections_remain # Make a collector coll = nil assert_nothing_raised do coll = Puppet::Parser::Collector.new(@scope, "file", nil, nil, :virtual) end @scope.newcollection(coll) # run the collection and make sure it doesn't get deleted, since it # didn't return anything assert_nothing_raised do assert_equal(false, coll.evaluate, "Evaluate returned incorrect value") end assert_equal([coll], @scope.collections, "Collection was deleted") # Make a resource one = mkresource(:type => "file", :title => "/tmp/virtual1", :virtual => true, :params => {:owner => "root"}) @scope.setresource one # Now perform the collection again, and it should still be there assert_nothing_raised do assert_equal([one], coll.evaluate, "Evaluate returned incorrect value") end assert_equal([coll], @scope.collections, "Collection was deleted") assert_equal(false, one.virtual?, "One was not realized") end end # $Id: collector.rb 2213 2007-02-18 05:58:27Z luke $