diff options
| author | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2006-12-01 04:11:11 +0000 |
|---|---|---|
| committer | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2006-12-01 04:11:11 +0000 |
| commit | f3a0c488b884b59df790fce0192dd1a2d735ad7c (patch) | |
| tree | 2efc2f2398d9ed2df6a8cb72a0db9ee01035433f /test | |
| parent | a7354d0e3bd77625de9da5f5846bfefbc6d88121 (diff) | |
| download | puppet-f3a0c488b884b59df790fce0192dd1a2d735ad7c.tar.gz puppet-f3a0c488b884b59df790fce0192dd1a2d735ad7c.tar.xz puppet-f3a0c488b884b59df790fce0192dd1a2d735ad7c.zip | |
Most of the graphing work is now done. I have also added the generator work in transactions, but I need to migrate files to using it. Until that migration is done, files will not work correctly for many cases.
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@1896 980ebf18-57e1-0310-9a29-db15c13687c0
Diffstat (limited to 'test')
| -rwxr-xr-x | test/lib/puppettest/support/resources.rb | 37 | ||||
| -rwxr-xr-x | test/other/overrides.rb | 10 | ||||
| -rw-r--r-- | test/other/pgraph.rb | 41 | ||||
| -rwxr-xr-x | test/other/relationships.rb | 216 | ||||
| -rwxr-xr-x | test/other/transactions.rb | 136 | ||||
| -rwxr-xr-x | test/types/component.rb | 30 | ||||
| -rwxr-xr-x | test/types/manager.rb | 44 | ||||
| -rwxr-xr-x | test/types/type.rb | 49 |
8 files changed, 402 insertions, 161 deletions
diff --git a/test/lib/puppettest/support/resources.rb b/test/lib/puppettest/support/resources.rb new file mode 100755 index 000000000..45d89c5fb --- /dev/null +++ b/test/lib/puppettest/support/resources.rb @@ -0,0 +1,37 @@ +#!/usr/bin/env ruby +# +# Created by Luke A. Kanies on 2006-11-29. +# Copyright (c) 2006. All rights reserved. + +module PuppetTest::Support::Resources + def treefile(name) + Puppet::Type.type(:file).create :path => "/tmp/#{name}", :mode => 0755 + end + + def treecomp(name) + Puppet::Type::Component.create :name => name, :type => "yay" + end + + def treenode(name, *children) + comp = treecomp name + children.each do |c| + if c.is_a?(String) + comp.push treefile(c) + else + comp.push c + end + end + return comp + end + + def mktree + one = treenode("one", "a", "b") + two = treenode("two", "c", "d") + middle = treenode("middle", "e", "f", two) + top = treenode("top", "g", "h", middle, one) + + return one, two, middle, top + end +end + +# $Id$
\ No newline at end of file diff --git a/test/other/overrides.rb b/test/other/overrides.rb index e25670291..2bc443980 100755 --- a/test/other/overrides.rb +++ b/test/other/overrides.rb @@ -27,6 +27,7 @@ class TestOverrides < Test::Unit::TestCase basefile = File.join(basedir, "file") assert_nothing_raised("Could not create base obj") { baseobj = Puppet.type(:file).create( + :title => "base", :path => basedir, :recurse => true, :mode => "755" @@ -38,23 +39,20 @@ class TestOverrides < Test::Unit::TestCase subfile = File.join(subdir, "file") assert_nothing_raised("Could not create sub obj") { subobj = Puppet.type(:file).create( + :title => "sub", :path => subdir, :recurse => true, :mode => "644" ) } - comp = newcomp("overrides", baseobj, subobj) - assert_nothing_raised("Could not eval component") { - trans = comp.evaluate - trans.evaluate - } + assert_apply(baseobj, subobj) assert(File.stat(basefile).mode & 007777 == 0755) assert(File.stat(subfile).mode & 007777 == 0644) end - def test_zdeepoverride + def test_deepoverride basedir = File.join(tmpdir(), "deepoverridetesting") mksubdirs(basedir, 10) diff --git a/test/other/pgraph.rb b/test/other/pgraph.rb index c3baa7722..adf290b34 100644 --- a/test/other/pgraph.rb +++ b/test/other/pgraph.rb @@ -12,24 +12,31 @@ class TestPGraph < Test::Unit::TestCase include PuppetTest include PuppetTest::Graph - def test_collect_targets + Edge = Puppet::Relationship + + def test_matching_edges graph = Puppet::PGraph.new event = Puppet::Event.new(:source => "a", :event => :yay) none = Puppet::Event.new(:source => "a", :event => :NONE) - graph.add_edge!("a", "b", :event => :yay) + 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(["b"], graph.collect_targets([event])) + assert_equal([edges["a/b"]], graph.matching_edges([event])) # Make sure we get nothing with a different event - assert_equal([], graph.collect_targets([none])) + assert_equal([], graph.matching_edges([none])) # Set up multiple targets and make sure we get them all back - graph.add_edge!("a", "c", :event => :yay) - assert_equal(["b", "c"].sort, graph.collect_targets([event]).sort) - assert_equal([], graph.collect_targets([none])) + 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 @@ -49,6 +56,9 @@ class TestPGraph < Test::Unit::TestCase one, two, middle, top = build_tree 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 @@ -57,7 +67,7 @@ class TestPGraph < Test::Unit::TestCase end {one => two, "f" => "c", "h" => middle}.each do |source, target| - deps.add_edge!(source, target) + deps.add_edge!(source, target, :callback => :refresh) end deps.to_jpg("deps-before") @@ -66,11 +76,26 @@ class TestPGraph < Test::Unit::TestCase assert(! deps.cyclic?, "Created a cyclic graph") + # 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.to_jpg("deps-after") + + deps.edges.each do |edge| + assert_equal({:callback => :refresh}, edge.label, + "Label was not copied on splice") + end end end diff --git a/test/other/relationships.rb b/test/other/relationships.rb index 893ef1ff4..e9c1d1c9c 100755 --- a/test/other/relationships.rb +++ b/test/other/relationships.rb @@ -15,37 +15,141 @@ class TestRelationships < Test::Unit::TestCase ) } end + + def check_relationship(sources, targets, out, refresher) + if out + deps = sources.builddepends + sources = [sources] + else + deps = targets.builddepends + targets = [targets] + end + assert_instance_of(Array, deps) + assert(! deps.empty?, "Did not receive any relationships") + + deps.each do |edge| + assert_instance_of(Puppet::Relationship, edge) + end + + sources.each do |source| + targets.each do |target| + edge = deps.find { |e| e.source == source and e.target == target } + assert(edge, "Could not find edge for %s => %s" % + [source.ref, target.ref]) + + if refresher + assert_equal(:ALL_EVENTS, edge.event) + assert_equal(:refresh, edge.callback) + else + assert_equal(:NONE, edge.event) + assert_nil(edge.callback, "Got a callback with no events") + end + end + end + end - def test_simplerel - file1 = newfile() - file2 = newfile() - assert_nothing_raised { - file1[:require] = [file2.class.name, file2.name] - } - - comp = newcomp(file1, file2) - comp.finalize - deps = [] - assert_nothing_raised { - file1.eachdependency { |obj| - deps << obj - } - } - - assert_equal(1, deps.length, "Did not get dependency") - - assert_nothing_raised { - file1.unsubscribe(file2) - } - - deps = [] - assert_nothing_raised { - file1.eachdependency { |obj| - deps << obj - } - } - - assert_equal(0, deps.length, "Still have dependency") + # Make sure our various metaparams work correctly. We're just checking + # here whether they correctly set up the callbacks and the direction of + # the relationship. + def test_relationship_metaparams + out = {:require => false, :subscribe => false, + :notify => true, :before => true} + refreshers = [:subscribe, :notify] + [:require, :subscribe, :notify, :before].each do |param| + # Create three files to generate our events and three + # execs to receive them + files = [] + execs = [] + 3.times do |i| + files << Puppet::Type.newfile( + :title => "file#{i}", + :path => tempfile(), + :ensure => :file + ) + + path = tempfile() + execs << Puppet::Type.newexec( + :title => "notifytest#{i}", + :path => "/usr/bin:/bin", + :command => "touch #{path}", + :refreshonly => true + ) + end + + # Add our first relationship + if out[param] + files[0][param] = execs[0] + sources = files[0] + targets = [execs[0]] + else + execs[0][param] = files[0] + sources = [files[0]] + targets = execs[0] + end + check_relationship(sources, targets, out[param], refreshers.include?(param)) + + # Now add another relationship + if out[param] + files[0][param] = execs[1] + targets << execs[1] + assert_equal(targets.collect { |t| [t.class.name, t.title]}, + files[0][param], "Incorrect target list") + else + execs[0][param] = files[1] + sources << files[1] + assert_equal(sources.collect { |t| [t.class.name, t.title]}, + execs[0][param], "Incorrect source list") + end + check_relationship(sources, targets, out[param], refreshers.include?(param)) + + Puppet::Type.allclear + end + end + + def test_store_relationship + file = Puppet::Type.newfile :path => tempfile(), :mode => 0755 + execs = [] + 3.times do |i| + execs << Puppet::Type.newexec(:title => "yay#{i}", :command => "/bin/echo yay") + end + + # First try it with one object, specified as a reference and an array + result = nil + [execs[0], [:exec, "yay0"], ["exec", "yay0"]].each do |target| + assert_nothing_raised do + result = file.send(:store_relationship, :require, target) + end + + assert_equal([[:exec, "yay0"]], result) + end + + # Now try it with multiple objects + symbols = execs.collect { |e| [e.class.name, e.title] } + strings = execs.collect { |e| [e.class.name.to_s, e.title] } + [execs, symbols, strings].each do |target| + assert_nothing_raised do + result = file.send(:store_relationship, :require, target) + end + + assert_equal(symbols, result) + end + + # Make sure we can mix it up, even though this shouldn't happen + assert_nothing_raised do + result = file.send(:store_relationship, :require, [execs[0], [execs[1].class.name, execs[1].title]]) + end + + assert_equal([[:exec, "yay0"], [:exec, "yay1"]], result) + + # Finally, make sure that new results get added to old. The only way + # to get rid of relationships is to delete the parameter. + file[:require] = execs[0] + + assert_nothing_raised do + result = file.send(:store_relationship, :require, [execs[1], execs[2]]) + end + + assert_equal(symbols, result) end def test_newsub @@ -107,33 +211,31 @@ class TestRelationships < Test::Unit::TestCase assert(! sub.match?(:ALL_EVENTS), "ALL_EVENTS matched") assert(! sub.match?(:NONE), "matched :NONE") end - - def test_deletingsubs - file1 = newfile() - file2 = newfile() - - file1[:subscribe] = [:file, file2.name] - - comp = newcomp(file1, file2) - comp.finalize - - assert(file1.requires?(file2)) - - assert_nothing_raised { - file1.unsubscribe(file2) - } - assert(!file1.requires?(file2)) - - # Now readd it, so we can use 'remove' - file1[:subscribe] = [:file, file2.name] - comp.finalize - - assert_nothing_raised { - file1.remove - } - - assert(!comp.include?(file1)) - assert(!file2.subscribesto?(file1)) + + def test_autorequire + # We know that execs autorequire their cwd, so we'll use that + path = tempfile() + + file = Puppet::Type.newfile(:title => "myfile", :path => path, + :ensure => :directory) + exec = Puppet::Type.newexec(:title => "myexec", :cwd => path, + :command => "/bin/echo") + + reqs = nil + assert_nothing_raised do + reqs = exec.autorequire + end + assert_equal([Puppet::Relationship[file, exec]], reqs) + + # Now make sure that these relationships are added to the transaction's + # relgraph + trans = Puppet::Transaction.new(newcomp(file, exec)) + assert_nothing_raised do + trans.evaluate + end + + graph = trans.relgraph + assert(graph.edge?(file, exec), "autorequire edge was not created") end end diff --git a/test/other/transactions.rb b/test/other/transactions.rb index 985e9a0c5..c143b3a0c 100755 --- a/test/other/transactions.rb +++ b/test/other/transactions.rb @@ -4,11 +4,13 @@ $:.unshift("../lib").unshift("../../lib") if __FILE__ =~ /\.rb$/ require 'puppet' require 'puppettest' +require 'puppettest/support/resources' # $Id$ class TestTransactions < Test::Unit::TestCase include PuppetTest::FileTesting + include PuppetTest::Support::Resources def test_reports path1 = tempfile() @@ -59,6 +61,10 @@ class TestTransactions < Test::Unit::TestCase type = Puppet::Type.newtype(name) do newparam(:name) {} end + + cleanup do + Puppet::Type.rmtype(name) + end # Now create a provider type.provide(:prefetch) do @@ -69,10 +75,9 @@ class TestTransactions < Test::Unit::TestCase # Now create an instance inst = type.create :name => "yay" - - + # Create a transaction - trans = Puppet::Transaction.new([inst]) + trans = Puppet::Transaction.new(newcomp(inst)) # Make sure prefetch works assert_nothing_raised do @@ -94,7 +99,7 @@ class TestTransactions < Test::Unit::TestCase path = tempfile() firstpath = tempfile() secondpath = tempfile() - file = Puppet::Type.newfile(:path => path, :content => "yayness") + file = Puppet::Type.newfile(:title => "file", :path => path, :content => "yayness") first = Puppet::Type.newexec(:title => "first", :command => "/bin/echo first > #{firstpath}", :subscribe => [:file, path], @@ -299,7 +304,9 @@ class TestTransactions < Test::Unit::TestCase assert(FileTest.exists?(execfile), "Execfile does not exist") end - def test_refreshAcrossTwoComponents + # Verify that one component requiring another causes the contained + # resources in the requiring component to get refreshed. + def test_refresh_across_two_components transaction = nil file = newfile() execfile = File.join(tmpdir(), "exectestingness2") @@ -318,7 +325,7 @@ class TestTransactions < Test::Unit::TestCase # 'subscribe' expects an array of arrays #component[:require] = [[file.class.name,file.name]] - ecomp[:subscribe] = [[fcomp.class.name,fcomp.name]] + ecomp[:subscribe] = fcomp exec[:refreshonly] = true trans = assert_events([], component) @@ -329,7 +336,6 @@ class TestTransactions < Test::Unit::TestCase } trans = assert_events([:file_changed, :file_changed, :triggered], component) - end # Make sure that multiple subscriptions get triggered. @@ -386,7 +392,7 @@ class TestTransactions < Test::Unit::TestCase end # Make sure that unscheduled and untagged objects still respond to events - def test_unscheduledanduntaggedresponse + def test_unscheduled_and_untagged_response Puppet::Type.type(:schedule).mkdefaultschedules Puppet[:ignoreschedules] = false file = Puppet.type(:file).create( @@ -444,21 +450,127 @@ class TestTransactions < Test::Unit::TestCase :title => "mkdir" ) - file = Puppet::Type.type(:file).create( + file1 = Puppet::Type.type(:file).create( + :title => "file1", :path => tempfile(), - :require => ["exec", "mkdir"], + :require => exec, :ensure => :file ) - comp = newcomp(exec, file) + file2 = Puppet::Type.type(:file).create( + :title => "file2", + :path => tempfile(), + :require => file1, + :ensure => :file + ) + + comp = newcomp(exec, file1, file2) comp.finalize assert_apply(comp) - assert(! FileTest.exists?(file[:path]), + assert(! FileTest.exists?(file1[:path]), "File got created even tho its dependency failed") + assert(! FileTest.exists?(file2[:path]), + "File got created even tho its deep dependency failed") + end + end + + def f(n) + Puppet::Type.type(:file)["/tmp/#{n.to_s}"] + end + + def test_relationship_graph + one, two, middle, top = mktree + + {one => two, "f" => "c", "h" => middle}.each do |source, target| + if source.is_a?(String) + source = f(source) + end + if target.is_a?(String) + target = f(target) + end + target[:require] = source + end + + trans = Puppet::Transaction.new(top) + + graph = nil + assert_nothing_raised do + graph = trans.relationship_graph + end + + assert_instance_of(Puppet::PGraph, graph, + "Did not get relationship graph") + + # Make sure all of the components are gone + comps = graph.vertices.find_all { |v| v.is_a?(Puppet::Type::Component)} + assert(comps.empty?, "Deps graph still contains components") + + # It must be reversed because of how topsort works + sorted = graph.topsort.reverse + + # Now make sure the appropriate edges are there and are in the right order + assert(graph.dependencies(f(:f)).include?(f(:c)), + "c not marked a dep of f") + assert(sorted.index(f(:c)) < sorted.index(f(:f)), + "c is not before f") + + one.each do |o| + two.each do |t| + assert(graph.dependencies(o).include?(t), + "%s not marked a dep of %s" % [t.ref, o.ref]) + assert(sorted.index(t) < sorted.index(o), + "%s is not before %s" % [t.ref, o.ref]) + end + end + + trans.resources.leaves(middle).each do |child| + assert(graph.dependencies(f(:h)).include?(child), + "%s not marked a dep of h" % [child.ref]) + assert(sorted.index(child) < sorted.index(f(:h)), + "%s is not before h" % child.ref) + end + + # Lastly, make sure our 'g' vertex made it into the relationship + # graph, since it's not involved in any relationships. + assert(graph.vertex?(f(:g)), + "Lost vertexes with no relations") + + graph.to_jpg("normal_relations") end + + def test_generate + # Create a bogus type that generates new instances with shorter + Puppet::Type.newtype(:generator) do + newparam(:name, :namevar => true) + + def generate + ret = [] + if title.length > 1 + ret << self.class.create(:title => title[0..-2]) + end + ret + end + end + cleanup do + Puppet::Type.rmtype(:generator) + end + + yay = Puppet::Type.newgenerator :title => "yay" + rah = Puppet::Type.newgenerator :title => "rah" + comp = newcomp(yay, rah) + trans = comp.evaluate + + assert_nothing_raised do + trans.generate + end + + %w{ya ra y r}.each do |name| + assert(trans.resources.vertex?(Puppet::Type.type(:generator)[name]), + "Generated %s was not a vertex" % name) + end end end diff --git a/test/types/component.rb b/test/types/component.rb index 28d6748a0..3fdc7bfe2 100755 --- a/test/types/component.rb +++ b/test/types/component.rb @@ -4,6 +4,7 @@ $:.unshift("../lib").unshift("../../lib") if __FILE__ =~ /\.rb$/ require 'puppet' require 'puppettest' +require 'puppettest/support/resources' # $Id$ @@ -105,35 +106,6 @@ class TestComponent < Test::Unit::TestCase } } end - - def treefile(name) - @file.create :path => "/tmp/#{name}", :mode => 0755 - end - - def treecomp(name) - @type.create :name => name, :type => "yay" - end - - def treenode(name, *children) - comp = treecomp name - children.each do |c| - if c.is_a?(String) - comp.push treefile(c) - else - comp.push c - end - end - return comp - end - - def mktree - one = treenode("one", "a", "b") - two = treenode("two", "c", "d") - middle = treenode("middle", "e", "f", two) - top = treenode("top", "g", "h", middle, one) - - return one, two, middle, top - end def test_to_graph one, two, middle, top = mktree diff --git a/test/types/manager.rb b/test/types/manager.rb new file mode 100755 index 000000000..f4353c128 --- /dev/null +++ b/test/types/manager.rb @@ -0,0 +1,44 @@ +#!/usr/bin/env ruby +# +# Created by Luke A. Kanies on 2006-11-29. +# Copyright (c) 2006. All rights reserved. + +$:.unshift("../lib").unshift("../../lib") if __FILE__ =~ /\.rb$/ + +require 'puppet' +require 'puppettest' + +class TestTypeManager < Test::Unit::TestCase + include PuppetTest + + class FakeManager + extend Puppet::MetaType::Manager + def self.clear + @types = {} + end + end + + def teardown + super + FakeManager.clear + end + + # Make sure we can remove defined types + def test_rmtype + assert_nothing_raised { + FakeManager.newtype :testing do + newparam(:name, :namevar => true) + end + } + assert(FakeManager.type(:testing), "Did not get fake type") + + assert_nothing_raised do + FakeManager.rmtype(:testing) + end + + assert_nil(FakeManager.type(:testing), "Type was not removed") + assert(! defined?(FakeManager::Testing), "Constant was not removed") + end +end + +# $Id$
\ No newline at end of file diff --git a/test/types/type.rb b/test/types/type.rb index 4be929ae9..821a9524b 100755 --- a/test/types/type.rb +++ b/test/types/type.rb @@ -411,55 +411,6 @@ end "newparam method got replaced by newtype") end - def test_notify_metaparam - file = Puppet::Type.newfile( - :path => tempfile(), - :notify => ["exec", "notifytest"], - :ensure => :file - ) - - path = tempfile() - exec = Puppet::Type.newexec( - :title => "notifytest", - :path => "/usr/bin:/bin", - :command => "touch #{path}", - :refreshonly => true - ) - - assert_apply(file, exec) - - assert(exec.requires?(file), - "Notify did not correctly set up the requirement chain.") - - assert(FileTest.exists?(path), - "Exec path did not get created.") - end - - def test_before_metaparam - file = Puppet::Type.newfile( - :path => tempfile(), - :before => ["exec", "beforetest"], - :content => "yaytest" - ) - - path = tempfile() - exec = Puppet::Type.newexec( - :title => "beforetest", - :command => "/bin/cp #{file[:path]} #{path}" - ) - - assert_apply(file, exec) - - assert(exec.requires?(file), - "Before did not correctly set up the requirement chain.") - - assert(FileTest.exists?(path), - "Exec path did not get created.") - - assert_equal("yaytest", File.read(path), - "Exec did not correctly copy file.") - end - def test_newstate_options # Create a type with a fake provider providerclass = Class.new do |
