diff --git a/test/language/snippets.rb b/test/language/snippets.rb index 45137f917..ccf8a3576 100755 --- a/test/language/snippets.rb +++ b/test/language/snippets.rb @@ -1,573 +1,523 @@ #!/usr/bin/env ruby $:.unshift("../lib").unshift("../../lib") if __FILE__ =~ /\.rb$/ require 'puppet' require 'puppet/parser/interpreter' require 'puppet/parser/parser' require 'puppet/client' require 'puppet/server' require 'puppettest' class TestSnippets < Test::Unit::TestCase include PuppetTest include ObjectSpace def self.snippetdir PuppetTest.datadir "snippets" end def snippet(name) File.join(self.class.snippetdir, name) end def file2ast(file) parser = Puppet::Parser::Parser.new() parser.file = file ast = parser.parse return ast end def snippet2ast(text) parser = Puppet::Parser::Parser.new() parser.string = text ast = parser.parse return ast end def client args = { :Listen => false } Puppet::Client.new(args) end def ast2scope(ast) interp = Puppet::Parser::Interpreter.new( :ast => ast, :client => client() ) scope = Puppet::Parser::Scope.new() ast.evaluate(scope) return scope end def scope2objs(scope) objs = scope.to_trans end def snippet2scope(snippet) ast = snippet2ast(snippet) scope = ast2scope(ast) end def snippet2objs(snippet) ast = snippet2ast(snippet) scope = ast2scope(ast) objs = scope2objs(scope) end def states(type) states = type.validstates end def metaparams(type) mparams = [] Puppet::Type.eachmetaparam { |param| mparams.push param } mparams end def params(type) params = [] type.parameters.each { |name,state| params.push name } params end def randthing(thing,type) list = self.send(thing,type) list[rand(list.length)] end def randeach(type) [:states, :metaparams, :params].collect { |thing| randthing(thing,type) } end @@snippets = { true => [ %{File { mode => 755 }} ], } def disabled_test_defaults Puppet::Type.eachtype { |type| next if type.name == :puppet or type.name == :component rands = randeach(type) name = type.name.to_s.capitalize [0..1, 0..2].each { |range| params = rands[range] paramstr = params.collect { |param| "%s => fake" % param }.join(", ") str = "%s { %s }" % [name, paramstr] scope = nil assert_nothing_raised { scope = snippet2scope(str) } defaults = nil assert_nothing_raised { defaults = scope.lookupdefaults(name) } p defaults params.each { |param| puts "%s => '%s'" % [name,param] assert(defaults.include?(param)) } } } end # this is here in case no tests get defined; otherwise we get a warning def test_nothing end - def snippet_filecreate(trans) + def snippet_filecreate %w{a b c d}.each { |letter| file = "/tmp/create%stest" % letter Puppet.info "testing %s" % file assert(Puppet.type(:file)[file], "File %s does not exist" % file) assert(FileTest.exists?(file)) @@tmpfiles << file } %w{a b}.each { |letter| file = "/tmp/create%stest" % letter assert(File.stat(file).mode & 007777 == 0755) } - - assert_nothing_raised { - trans.rollback - } - %w{a b c d}.each { |letter| - file = "/tmp/create%stest" % letter - assert(! FileTest.exists?(file), "File %s still exists" % file) - } end - def snippet_simpledefaults(trans) + def snippet_simpledefaults file = "/tmp/defaulttest" @@tmpfiles << file assert(FileTest.exists?(file), "File %s does not exist" % file) assert(File.stat(file).mode & 007777 == 0755) - - assert_nothing_raised { - trans.rollback - } - assert(! FileTest.exists?(file), "%s still exists" % file) end - def snippet_simpleselector(trans) + def snippet_simpleselector files = %w{a b c d}.collect { |letter| "/tmp/snippetselect%stest" % letter } @@tmpfiles += files files.each { |file| assert(FileTest.exists?(file), "File %s does not exist" % file) assert(File.stat(file).mode & 007777 == 0755, "File %s is the incorrect mode" % file) @@tmpfiles << file } - - assert_nothing_raised { - trans.rollback - } - files.each { |file| - assert(! FileTest.exists?(file), "%s still exists" % file) - } end - def snippet_classpathtest(trans) + def snippet_classpathtest file = "/tmp/classtest" @@tmpfiles << file assert(FileTest.exists?(file)) obj = nil assert_nothing_raised { obj = Puppet.type(:file)[file] } assert_nothing_raised { assert_equal( "//testing/component[componentname]/file=/tmp/classtest", obj.path) #Puppet.err obj.path } - - assert_nothing_raised { - trans.rollback - } - assert(! FileTest.exists?(file), "%s still exists" % file) end - def snippet_argumentdefaults(trans) + def snippet_argumentdefaults file1 = "/tmp/argumenttest1" file2 = "/tmp/argumenttest2" @@tmpfiles << file1 @@tmpfiles << file2 assert(FileTest.exists?(file1)) assert(File.stat(file1).mode & 007777 == 0755) assert(FileTest.exists?(file2)) assert(File.stat(file2).mode & 007777 == 0644) end - def snippet_casestatement(trans) + def snippet_casestatement files = %w{ /tmp/existsfile /tmp/existsfile2 /tmp/existsfile3 /tmp/existsfile4 /tmp/existsfile5 } files.each { |file| assert(FileTest.exists?(file), "File %s is missing" % file) assert(File.stat(file).mode & 007777 == 0755, "File %s is not 755" % file) } - - assert_nothing_raised { - trans.rollback - } end - def snippet_implicititeration(trans) + def snippet_implicititeration files = %w{a b c d e f g h}.collect { |l| "/tmp/iteration%stest" % l } files.each { |file| @@tmpfiles << file assert(FileTest.exists?(file), "File %s does not exist" % file) assert(File.stat(file).mode & 007777 == 0755, "File %s is not 755" % file) } - - assert_nothing_raised { - trans.rollback - } - - files.each { |file| - assert(! FileTest.exists?(file), "file %s still exists" % file) - } end - def snippet_multipleinstances(trans) + def snippet_multipleinstances files = %w{a b c}.collect { |l| "/tmp/multipleinstances%s" % l } files.each { |file| @@tmpfiles << file assert(FileTest.exists?(file), "File %s does not exist" % file) assert(File.stat(file).mode & 007777 == 0755, "File %s is not 755" % file) } - - assert_nothing_raised { - trans.rollback - } - - files.each { |file| - assert(! FileTest.exists?(file), "file %s still exists" % file) - } end - def snippet_namevartest(trans) + def snippet_namevartest file = "/tmp/testfiletest" dir = "/tmp/testdirtest" @@tmpfiles << file @@tmpfiles << dir assert(FileTest.file?(file), "File %s does not exist" % file) assert(FileTest.directory?(dir), "Directory %s does not exist" % dir) end - def snippet_scopetest(trans) + def snippet_scopetest file = "/tmp/scopetest" @@tmpfiles << file assert(FileTest.file?(file), "File %s does not exist" % file) assert(File.stat(file).mode & 007777 == 0755, "File %s is not 755" % file) end - def snippet_failmissingexecpath(trans) + def snippet_failmissingexecpath file = "/tmp/exectesting1" execfile = "/tmp/execdisttesting" @@tmpfiles << file @@tmpfiles << execfile assert(!FileTest.exists?(execfile), "File %s exists" % execfile) end - def snippet_selectorvalues(trans) + def snippet_selectorvalues nums = %w{1 2 3 4 5} files = nums.collect { |n| "/tmp/selectorvalues%s" % n } files.each { |f| @@tmpfiles << f assert(FileTest.exists?(f), "File %s does not exist" % f) assert(File.stat(f).mode & 007777 == 0755, "File %s is not 755" % f) } end - def snippet_singleselector(trans) + def snippet_singleselector nums = %w{1 2 3} files = nums.collect { |n| "/tmp/singleselector%s" % n } files.each { |f| @@tmpfiles << f assert(FileTest.exists?(f), "File %s does not exist" % f) assert(File.stat(f).mode & 007777 == 0755, "File %s is not 755" % f) } end - def snippet_falsevalues(trans) + def snippet_falsevalues file = "/tmp/falsevaluesfalse" @@tmpfiles << file assert(FileTest.exists?(file), "File %s does not exist" % file) end - def disabled_snippet_classargtest(trans) + def disabled_snippet_classargtest [1,2].each { |num| file = "/tmp/classargtest%s" % num @@tmpfiles << file assert(FileTest.file?(file), "File %s does not exist" % file) assert(File.stat(file).mode & 007777 == 0755, "File %s is not 755" % file) } end - def snippet_classheirarchy(trans) + def snippet_classheirarchy [1,2,3].each { |num| file = "/tmp/classheir%s" % num @@tmpfiles << file assert(FileTest.file?(file), "File %s does not exist" % file) assert(File.stat(file).mode & 007777 == 0755, "File %s is not 755" % file) } end - def snippet_singleary(trans) + def snippet_singleary [1,2,3,4].each { |num| file = "/tmp/singleary%s" % num @@tmpfiles << file assert(FileTest.file?(file), "File %s does not exist" % file) } end - def snippet_classincludes(trans) + def snippet_classincludes [1,2,3].each { |num| file = "/tmp/classincludes%s" % num @@tmpfiles << file assert(FileTest.file?(file), "File %s does not exist" % file) assert(File.stat(file).mode & 007777 == 0755, "File %s is not 755" % file) } end - def snippet_componentmetaparams(trans) + def snippet_componentmetaparams ["/tmp/component1", "/tmp/component2"].each { |file| assert(FileTest.file?(file), "File %s does not exist" % file) } end - def snippet_aliastest(trans) + def snippet_aliastest %w{/tmp/aliastest /tmp/aliastest2 /tmp/aliastest3}.each { |file| assert(FileTest.file?(file), "File %s does not exist" % file) } end - def snippet_singlequote(trans) + def snippet_singlequote { 1 => 'a $quote', 2 => 'some "\yayness\"' }.each { |count, str| path = "/tmp/singlequote%s" % count assert(FileTest.exists?(path), "File %s is missing" % path) text = File.read(path) assert_equal(str, text) } end # There's no way to actually retrieve the list of classes from the # transaction. - def snippet_tag(trans) + def snippet_tag @@tmpfiles << "/tmp/settestingness" end # Make sure that set tags are correctly in place, yo. - def snippet_tagged(trans) + def snippet_tagged tags = {"testing" => true, "yayness" => false, "both" => false, "bothtrue" => true, "define" => true} tags.each do |tag, retval| @@tmpfiles << "/tmp/tagged#{tag}true" @@tmpfiles << "/tmp/tagged#{tag}false" assert(FileTest.exists?("/tmp/tagged#{tag}#{retval.to_s}"), "'tagged' did not return %s with %s" % [retval, tag]) end end - def snippet_defineoverrides(trans) + def snippet_defineoverrides file = "/tmp/defineoverrides1" assert(FileTest.exists?(file), "File does not exist") assert_equal(0755, filemode(file)) end - def snippet_deepclassheirarchy(trans) + def snippet_deepclassheirarchy 5.times { |i| i += 1 file = "/tmp/deepclassheir%s" % i assert(FileTest.exists?(file), "File %s does not exist" % file) } end - def snippet_emptyclass(trans) + def snippet_emptyclass # There's nothing to check other than that it works end - def snippet_emptyexec(trans) + def snippet_emptyexec assert(FileTest.exists?("/tmp/emptyexectest"), "Empty exec was ignored") @@tmpfiles << "/tmp/emptyexextest" end - def snippet_multisubs(trans) + def snippet_multisubs path = "/tmp/multisubtest" assert(FileTest.exists?(path), "Did not create file") assert_equal("sub2", File.read(path), "sub2 did not override content") assert_equal(0755, filemode(path), "sub1 did not override mode") end - def snippet_collection(trans) + def snippet_collection assert(FileTest.exists?("/tmp/colltest1"), "Did not collect file") assert(! FileTest.exists?("/tmp/colltest2"), "Incorrectly collected file") end - def snippet_virtualresources(trans) + def snippet_virtualresources %w{1 2 3 4}.each do |num| assert(FileTest.exists?("/tmp/virtualtest#{num}"), "Did not collect file #{num}") end end - def disabled_snippet_dirchmod(trans) + def disabled_snippet_dirchmod dirs = %w{a b}.collect { |letter| "/tmp/dirchmodtest%s" % letter } @@tmpfiles << dirs dirs.each { |dir| assert(FileTest.directory?(dir)) } assert(File.stat("/tmp/dirchmodtesta").mode & 007777 == 0755) assert(File.stat("/tmp/dirchmodtestb").mode & 007777 == 0700) - - assert_nothing_raised { - trans.rollback - } end # Iterate across each of the snippets and create a test. Dir.entries(snippetdir).sort.each { |file| next if file =~ /^\./ mname = "snippet_" + file.sub(/\.pp$/, '') if self.method_defined?(mname) #eval("alias %s %s" % [testname, mname]) testname = ("test_" + mname).intern self.send(:define_method, testname) { # first parse the file server = Puppet::Server::Master.new( :Manifest => snippet(file), :Local => true ) client = Puppet::Client::MasterClient.new( :Master => server, :Cache => false ) assert(client.local) assert_nothing_raised { client.getconfig() } client = Puppet::Client::MasterClient.new( :Master => server, :Cache => false ) assert(client.local) # Now do it again Puppet::Type.allclear assert_nothing_raised { client.getconfig() } - trans = nil assert_nothing_raised { trans = client.apply() } Puppet::Type.eachtype { |type| type.each { |obj| # don't worry about this for now #unless obj.name == "puppet[top]" or # obj.is_a?(Puppet.type(:schedule)) # assert(obj.parent, "%s has no parent" % obj.name) #end assert(obj.name) if obj.is_a?(Puppet.type(:file)) @@tmpfiles << obj[:path] end } } assert_nothing_raised { - self.send(mname, trans) + self.send(mname) } client.clear } mname = mname.intern end } end # $Id$ diff --git a/test/lib/puppettest/support/assertions.rb b/test/lib/puppettest/support/assertions.rb index ac3baf4df..75056b0db 100644 --- a/test/lib/puppettest/support/assertions.rb +++ b/test/lib/puppettest/support/assertions.rb @@ -1,93 +1,94 @@ require 'puppettest' require 'fileutils' module PuppetTest def assert_uid_gid(uid, gid, filename) flunk "Must be uid 0 to run these tests" unless Process.uid == 0 fork do Puppet::SUIDManager.gid = gid Puppet::SUIDManager.uid = uid # FIXME: use the tempfile method from puppettest.rb system("mkfifo "+filename) f = File.open(filename, "w") f << "#{Puppet::SUIDManager.uid}\n#{Puppet::SUIDManager.gid}\n" yield if block_given? end # avoid a race. true while !File.exists? filename f = File.open(filename, "r") a = f.readlines assert_equal(uid, a[0].chomp.to_i, "UID was incorrect") assert_equal(gid, a[1].chomp.to_i, "GID was incorrect") FileUtils.rm(filename) end def assert_rollback_events(events, trans, msg = nil) run_events(:rollback, events, trans, msg) end def assert_events(events, *items) trans = nil comp = nil msg = nil unless events.is_a? Array raise Puppet::DevError, "Incorrect call of assert_events" end if items[-1].is_a? String msg = items.pop end remove_comp = false # They either passed a comp or a list of items. if items[0].is_a? Puppet.type(:component) comp = items.shift else comp = newcomp(items[0].title, *items) remove_comp = true end msg ||= comp.title assert_nothing_raised("Component %s failed" % [msg]) { trans = comp.evaluate } run_events(:evaluate, trans, events, msg) if remove_comp Puppet.type(:component).delete(comp) end return trans end # A simpler method that just applies what we have. def assert_apply(*objects) if objects[0].is_a?(Puppet.type(:component)) comp = objects.shift unless objects.empty? objects.each { |o| comp.push o } end else comp = newcomp(*objects) end trans = nil assert_nothing_raised("Failed to create transaction") { trans = comp.evaluate } events = nil assert_nothing_raised("Failed to evaluate transaction") { events = trans.evaluate.collect { |e| e.event } } + trans.cleanup Puppet.type(:component).delete(comp) events end end # $Id$ diff --git a/test/providers/parsedfile.rb b/test/providers/parsedfile.rb index e4c68dd0c..252bf26b2 100755 --- a/test/providers/parsedfile.rb +++ b/test/providers/parsedfile.rb @@ -1,601 +1,602 @@ #!/usr/bin/env ruby $:.unshift("../lib").unshift("../../lib") if __FILE__ =~ /\.rb$/ require 'puppettest' require 'puppettest/fileparsing' require 'puppet' +require 'puppet/filetype' require 'puppet/provider/parsedfile' require 'facter' class TestParsedFile < Test::Unit::TestCase include PuppetTest include PuppetTest::FileParsing - Puppet::Type.newtype(:parsedfiletype) do + Puppet::Type.newtype(:testparsedfiletype) do ensurable newstate(:one) do newvalue(:a) newvalue(:b) end newstate(:two) do newvalue(:c) newvalue(:d) end newparam(:name) do end newparam(:target) do defaultto { @parent.class.defaultprovider.default_target } end end # A simple block to skip the complexity of a full transaction. def apply(model) [:one, :two, :ensure].each do |st| Puppet.info "Setting %s: %s => %s" % [model[:name], st, model.should(st)] model.provider.send(st.to_s + "=", model.should(st)) end end def mkmodel(name, options = {}) options[:one] ||= "a" options[:two] ||= "c" options[:name] ||= name model = @type.create(options) end def mkprovider(name = :parsed) @provider = @type.provide(name, :parent => Puppet::Provider::ParsedFile, :filetype => :ram) do record_line name, :fields => %w{name one two} end end def setup super - @type = Puppet::Type.type(:parsedfiletype) + @type = Puppet::Type.type(:testparsedfiletype) end def teardown if defined? @provider @type.unprovide(@provider.name) @provider = nil end super end def test_create_provider assert_nothing_raised do mkprovider end end def test_model_attributes prov = nil assert_nothing_raised do prov = mkprovider end [:one, :two, :name].each do |attr| assert(prov.method_defined?(attr), "Did not define %s" % attr) end # Now make sure they stay around - fakemodel = fakemodel(:parsedfiletype, "yay") + fakemodel = fakemodel(:testparsedfiletype, "yay") file = prov.new(fakemodel) assert_nothing_raised do file.name = :yayness end # The provider converts to strings assert_equal(:yayness, file.name) end def test_filetype prov = mkprovider flat = Puppet::FileType.filetype(:flat) ram = Puppet::FileType.filetype(:ram) assert_nothing_raised do prov.filetype = :flat end assert_equal(flat, prov.filetype) assert_nothing_raised do prov.filetype = ram end assert_equal(ram, prov.filetype) end # Make sure we correctly create a new filetype object, but only when # necessary. def test_fileobject prov = mkprovider path = tempfile() obj = nil assert_nothing_raised do obj = prov.target_object(path) end # The default filetype is 'ram' assert_instance_of(Puppet::FileType.filetype(:ram), obj) newobj = nil assert_nothing_raised do newobj = prov.target_object(path) end assert_equal(obj, newobj, "did not reuse file object") # now make sure clear does the right thing assert_nothing_raised do prov.clear end assert_nothing_raised do newobj = prov.target_object(path) end assert(obj != newobj, "did not reuse file object") end def test_retrieve prov = mkprovider prov.filetype = :ram # Override the parse method with our own prov.meta_def(:parse) do |text| return [text] end path = :yayness file = prov.target_object(path) text = "a test" file.write(text) ret = nil assert_nothing_raised do ret = prov.retrieve(path) end assert_equal([text], ret) # Now set the text to nil and make sure we get an empty array file.write(nil) assert_nothing_raised do ret = prov.retrieve(path) end assert_equal([], ret) # And the empty string should return an empty array file.write("") assert_nothing_raised do ret = prov.retrieve(path) end assert_equal([], ret) end # Verify that prefetch will parse the file, create any necessary instances, # and set the 'is' values appropriately. def test_prefetch prov = mkprovider prov.filetype = :ram prov.default_target = :default # Create a couple of demo files prov.target_object(:file1).write "bill b c" prov.target_object(:file2).write "jill b d" prov.target_object(:default).write "will b d" # Create some models for some of those demo files model = mkmodel "bill", :target => :file1 default = mkmodel "will", :target => :default assert_nothing_raised do prov.prefetch end # Make sure we prefetched our models. assert_equal("b", model.provider.one) assert_equal("b", default.provider.one) assert_equal("d", default.provider.two) # Now list all of them and make sure we get everything back hashes = nil assert_nothing_raised do hashes = prov.list end names = nil assert_nothing_raised do names = prov.list_by_name end %w{bill jill will}.each do |name| assert(hashes.find { |r| r[:name] == name}, "Did not return %s in list" % name) assert(names.include?(name), "Did not return %s in list_by_name" % name) end end # Make sure we can correctly prefetch on a target. def test_prefetch_target prov = mkprovider prov.filetype = :ram target = :yayness prov.target_object(target).write "yay b d" model = mkmodel "yay", :target => :yayness assert_nothing_raised do prov.prefetch_target(:yayness) end # Now make sure we correctly got the hash mprov = model.provider assert_equal("b", mprov.one) assert_equal("d", mprov.two) end def test_prefetch_match prov = mkprovider prov.meta_def(:match) do |record| # Look for matches on :one self.model.find do |m| m.should(:one).to_s == record[:one].to_s end end prov.filetype = :ram target = :yayness prov.target_object(target).write "foo b d" model = mkmodel "yay", :target => :yayness, :one => "b" assert_nothing_raised do prov.prefetch_target(:yayness) end # Now make sure we correctly got the hash mprov = model.provider assert_equal("yay", model[:name]) assert_equal("b", mprov.one) assert_equal("d", mprov.two) end # We need to test that we're retrieving files from all three locations: # from any existing target_objects, from the default file location, and # from any existing model instances. def test_targets prov = mkprovider files = {} # Set the default target default = tempfile() files[:default] = default prov.default_target = default # Create a file object inmem = tempfile() files[:inmemory] = inmem prov.target_object(inmem).write("inmem yay ness") # Lastly, create a model mtarget = tempfile() files[:models] = mtarget model = mkmodel "yay", :target => mtarget assert(model[:target], "Did not get a value for target") list = nil assert_nothing_raised do list = prov.targets end files.each do |name, file| assert(list.include?(file), "Provider did not find %s file" % name) end end # Make sure that flushing behaves correctly. This is what actually writes # the data out to disk. def test_flush prov = mkprovider prov.filetype = :ram prov.default_target = :yayness # Create some models. one = mkmodel "one", :one => "a", :two => "c", :target => :yayness two = mkmodel "two", :one => "b", :two => "d", :target => :yayness # Write out a file with different data. prov.target_object(:yayness).write "one b d\ntwo a c" prov.prefetch # Apply and flush the first model. assert_nothing_raised do apply(one) end assert_nothing_raised { one.flush } # Make sure it changed our file assert_equal(:a, one.provider.one) assert_equal(:c, one.provider.two) # And make sure it's right on disk assert(prov.target_object(:yayness).read.include?("one a c"), "Did not write out correct data") # Make sure the second model has not been modified assert_equal("a", two.provider.one, "Two was flushed early") assert_equal("c", two.provider.two, "Two was flushed early") # And on disk assert(prov.target_object(:yayness).read.include?("two a c"), "Wrote out other model") # Now fetch the data again and make sure we're still right assert_nothing_raised { prov.prefetch } assert_equal("a", one.provider.one) assert_equal("a", two.provider.one) # Now flush the second model and make sure it goes well assert_nothing_raised { apply(two) } assert_nothing_raised { two.flush } assert_equal(:b, two.provider.one) end def test_creating_file prov = mkprovider prov.clear prov.default_target = :basic model = mkmodel "yay", :target => :basic, :one => "a", :two => "c" assert_equal(:present, model.should(:ensure)) apply(model) assert_nothing_raised do model.flush end assert(prov.target_object(:basic).read.include?("yay a c"), "Did not create file") # Make a change model.provider.one = "b" # Flush it assert_nothing_raised do model.flush end # And make sure our model doesn't appear twice in the file. assert_equal("yay b c\n", prov.target_object(:basic).read) end # Make sure a record can switch targets. def test_switching_targets prov = mkprovider prov.filetype = :ram prov.default_target = :first # Make three models, one for each target and one to switch first = mkmodel "first", :target => :first second = mkmodel "second", :target => :second mover = mkmodel "mover", :target => :first [first, second, mover].each do |m| assert_nothing_raised("Could not apply %s" % m[:name]) do apply(m) end end # Flush. [first, second, mover].each do |m| assert_nothing_raised do m.flush end end check = proc do |target, name| assert(prov.target_object(target).read.include?("%s a c" % name), "Did not sync %s" % name) end # Make sure the data is there check.call(:first, :first) check.call(:second, :second) check.call(:first, :mover) # Now change the target for the mover mover[:target] = :second # Apply it assert_nothing_raised do apply(mover) end # Flush assert_nothing_raised do mover.flush end # Make sure the data is there check.call(:first, :first) check.call(:second, :second) check.call(:second, :mover) # And make sure the mover is no longer in the first file assert(prov.target_object(:first) !~ /mover/, "Mover was not removed from first file") end # Make sure that 'ensure' correctly calls 'sync' on all states. def test_ensure prov = mkprovider prov.filetype = :ram prov.default_target = :first # Make two models, one that starts on disk and one that doesn't ondisk = mkmodel "ondisk", :target => :first notdisk = mkmodel "notdisk", :target => :first prov.target_object(:first).write "ondisk a c\n" prov.prefetch assert_equal(:present, notdisk.should(:ensure), "Did not get default ensure value") # Try creating the object assert_nothing_raised { notdisk.provider.create() } # Now make sure all of the data is copied over correctly. notdisk.class.validstates.each do |state| assert_equal(notdisk.should(state), notdisk.provider.state_hash[state], "%s was not copied over during creation" % state) end # Flush it to disk and make sure it got copied down assert_nothing_raised do notdisk.flush end assert(prov.target_object(:first).read =~ /^notdisk/, "Did not write out object to disk") assert(prov.target_object(:first).read =~ /^ondisk/, "Lost object on disk") # Make sure our on-disk model behaves appropriately. assert_equal(:present, ondisk.provider.ensure) # Now destroy the object assert_nothing_raised { notdisk.provider.destroy() } assert_nothing_raised { notdisk.flush } # And make sure it's no longer present assert(prov.target_object(:first).read !~ /^notdisk/, "Did not remove thing from disk") assert(prov.target_object(:first).read =~ /^ondisk/, "Lost object on disk") assert_equal(:present, ondisk.provider.ensure) end def test_absent_fields prov = @type.provide(:record, :parent => Puppet::Provider::ParsedFile) do record_line :record, :fields => %w{name one two}, :separator => "\s" end cleanup { @type.unprovide(:record) } records = prov.parse("a d") line = records.find { |r| r[:name] == "a" } assert(line, "Could not find line") assert_equal(:absent, line[:one], "field one was not set to absent") end # This test is because in x2puppet I was having problems where multiple # retrievals somehow destroyed the 'is' values. def test_value_retrieval prov = mkprovider prov.default_target = :yayness prov.target_object(:yayness).write "bill a c\njill b d" - list = Puppet::Type.type(:parsedfiletype).list + list = @type.list bill = list.find { |r| r[:name] == "bill" } jill = list.find { |r| r[:name] == "jill" } assert(bill, "Could not find bill") assert(jill, "Could not find jill") prov = bill.provider 4.times do |i| assert(prov.one, "Did not get a value for 'one' on try %s" % (i + 1)) end # First make sure we can retrieve values multiple times from the # provider assert(bill.is(:one), "Bill does not have a value for 'one'") assert(bill.is(:one), "Bill does not have a value for 'one' on second try") assert_nothing_raised do bill.retrieve end assert(bill.is(:one), "bill's value for 'one' disappeared") end # Make sure that creating a new model finds existing records in memory def test_initialize_finds_records prov = mkprovider prov.default_target = :yayness prov.target_object(:yayness).write "bill a c\njill b d" prov.prefetch # Now make a model bill = nil assert_nothing_raised do - bill = Puppet::Type.type(:parsedfiletype).create :name => "bill" + bill = @type.create :name => "bill" end assert_equal("a", bill.provider.one, "Record was not found in memory") end # Make sure invalid fields always show up as insync def test_invalid_fields prov = @type.provide(:test, :parent => Puppet::Provider::ParsedFile, :filetype => :ram, :default_target => :yayness) do record_line :test, :fields => %w{name two} end cleanup do @type.unprovide(:test) end bill = nil assert_nothing_raised do - bill = Puppet::Type.type(:parsedfiletype).create :name => "bill", + bill = @type.create :name => "bill", :one => "a", :two => "c" end assert_apply(bill) prov.prefetch assert_nothing_raised do bill.retrieve end assert(bill.insync?, "An invalid field marked the record out of sync") end end # $Id$ diff --git a/test/types/user.rb b/test/types/user.rb index 958434fa5..41231a687 100755 --- a/test/types/user.rb +++ b/test/types/user.rb @@ -1,451 +1,451 @@ #!/usr/bin/env ruby $:.unshift("../lib").unshift("../../lib") if __FILE__ =~ /\.rb$/ require 'etc' require 'puppet/type' require 'puppettest' class TestUser < Test::Unit::TestCase include PuppetTest p = Puppet::Type.type(:user).provide :fake, :parent => PuppetTest::FakeProvider do @name = :fake apimethods def create @ensure = :present @model.eachstate do |state| next if state.name == :ensure state.sync end end def delete @ensure = :absent @model.eachstate do |state| send(state.name.to_s + "=", :absent) end end def exists? if defined? @ensure and @ensure == :present true else false end end end FakeUserProvider = p @@fakeproviders[:group] = p def findshell(old = nil) %w{/bin/sh /bin/bash /sbin/sh /bin/ksh /bin/zsh /bin/csh /bin/tcsh /usr/bin/sh /usr/bin/bash /usr/bin/ksh /usr/bin/zsh /usr/bin/csh /usr/bin/tcsh}.find { |shell| if old FileTest.exists?(shell) and shell != old else FileTest.exists?(shell) end } end def setup super Puppet::Type.type(:user).defaultprovider = FakeUserProvider end def teardown Puppet::Type.type(:user).defaultprovider = nil super end def mkuser(name) user = nil assert_nothing_raised { user = Puppet.type(:user).create( :name => name, :comment => "Puppet Testing User", :gid => Puppet::SUIDManager.gid, :shell => findshell(), :home => "/home/%s" % name ) } assert(user, "Did not create user") return user end def attrtest_ensure(user) old = user.provider.ensure user[:ensure] = :absent comp = newcomp("ensuretest", user) assert_apply(user) assert(!user.provider.exists?, "User is still present") user[:ensure] = :present assert_events([:user_created], comp) assert(user.provider.exists?, "User is absent") user[:ensure] = :absent trans = assert_events([:user_removed], comp) assert_rollback_events(trans, [:user_created], "user") user[:ensure] = old assert_apply(user) end def attrtest_comment(user) user.retrieve old = user.provider.comment user[:comment] = "A different comment" comp = newcomp("commenttest", user) trans = assert_events([:user_changed], comp, "user") assert_equal("A different comment", user.provider.comment, "Comment was not changed") assert_rollback_events(trans, [:user_changed], "user") assert_equal(old, user.provider.comment, "Comment was not reverted") end def attrtest_home(user) obj = nil comp = newcomp("hometest", user) old = user.provider.home user[:home] = old trans = assert_events([], comp, "user") user[:home] = "/tmp" trans = assert_events([:user_changed], comp, "user") assert_equal("/tmp", user.provider.home, "Home was not changed") assert_rollback_events(trans, [:user_changed], "user") assert_equal(old, user.provider.home, "Home was not reverted") end def attrtest_shell(user) old = user.provider.shell comp = newcomp("shelltest", user) user[:shell] = old trans = assert_events([], comp, "user") newshell = findshell(old) unless newshell $stderr.puts "Cannot find alternate shell; skipping shell test" return end user[:shell] = newshell trans = assert_events([:user_changed], comp, "user") user.retrieve assert_equal(newshell, user.provider.shell, "Shell was not changed") assert_rollback_events(trans, [:user_changed], "user") user.retrieve assert_equal(old, user.provider.shell, "Shell was not reverted") end def attrtest_gid(user) obj = nil old = user.provider.gid comp = newcomp("gidtest", user) user.retrieve user[:gid] = old trans = assert_events([], comp, "user") newgid = %w{nogroup nobody staff users daemon}.find { |gid| begin group = Etc.getgrnam(gid) rescue ArgumentError => detail next end - old != group.gid + old != group.gid and group.gid > 0 } unless newgid $stderr.puts "Cannot find alternate group; skipping gid test" return end # first test by name assert_nothing_raised("Failed to specify group by name") { user[:gid] = newgid } trans = assert_events([:user_changed], comp, "user") # then by id newgid = Etc.getgrnam(newgid).gid - assert_nothing_raised("Failed to specify group by id") { + assert_nothing_raised("Failed to specify group by id for %s" % newgid) { user[:gid] = newgid } user.retrieve assert_events([], comp, "user") assert_equal(newgid, user.provider.gid, "GID was not changed") assert_rollback_events(trans, [:user_changed], "user") assert_equal(old, user.provider.gid, "GID was not reverted") end def attrtest_uid(user) obj = nil comp = newcomp("uidtest", user) user.provider.uid = 1 old = 1 newuid = 1 while true newuid += 1 if newuid - old > 1000 $stderr.puts "Could not find extra test UID" return end begin newuser = Etc.getpwuid(newuid) rescue ArgumentError => detail break end end assert_nothing_raised("Failed to change user id") { user[:uid] = newuid } trans = assert_events([:user_changed], comp, "user") assert_equal(newuid, user.provider.uid, "UID was not changed") assert_rollback_events(trans, [:user_changed], "user") assert_equal(old, user.provider.uid, "UID was not reverted") end def attrtest_groups(user) Etc.setgrent max = 0 while group = Etc.getgrent if group.gid > max and group.gid < 5000 max = group.gid end end groups = [] main = [] extra = [] 5.times do |i| i += 1 name = "pptstgr%s" % i groups << name if i < 3 main << name else extra << name end end assert(user[:membership] == :minimum, "Membership did not default correctly") assert_nothing_raised { user.retrieve } # Now add some of them to our user assert_nothing_raised { user[:groups] = extra } assert_nothing_raised { user.retrieve } assert_instance_of(String, user.state(:groups).should) # Some tests to verify that groups work correctly startig from nothing # Remove our user user[:ensure] = :absent assert_apply(user) assert_nothing_raised do user.retrieve end # And add it again user[:ensure] = :present assert_apply(user) # Make sure that the groups are a string, not an array assert(user.provider.groups.is_a?(String), "Incorrectly passed an array to groups") user.retrieve assert(user.state(:groups).is, "Did not retrieve group list") list = user.state(:groups).is assert_equal(extra.sort, list.sort, "Group list is not equal") # Now set to our main list of groups assert_nothing_raised { user[:groups] = main } assert_equal((main + extra).sort, user.state(:groups).should.split(",").sort) assert_nothing_raised { user.retrieve } assert(!user.insync?, "User is incorrectly in sync") assert_apply(user) assert_nothing_raised { user.retrieve } # We're not managing inclusively, so it should keep the old group # memberships and add the new ones list = user.state(:groups).is assert_equal((main + extra).sort, list.sort, "Group list is not equal") assert_nothing_raised { user[:membership] = :inclusive } assert_nothing_raised { user.retrieve } assert(!user.insync?, "User is incorrectly in sync") assert_events([:user_changed], user) assert_nothing_raised { user.retrieve } list = user.state(:groups).is assert_equal(main.sort, list.sort, "Group list is not equal") # Set the values a bit differently. user.state(:groups).should = list.sort { |a,b| b <=> a } user.state(:groups).is = list.sort assert(user.state(:groups).insync?, "Groups state did not sort groups") user.delete(:groups) end def test_autorequire file = tempfile() comp = nil user = nil group =nil home = nil ogroup = nil assert_nothing_raised { user = Puppet.type(:user).create( :name => "pptestu", :home => file, :gid => "pptestg", :groups => "yayness" ) home = Puppet.type(:file).create( :path => file, :owner => "pptestu", :ensure => "directory" ) group = Puppet.type(:group).create( :name => "pptestg" ) ogroup = Puppet.type(:group).create( :name => "yayness" ) comp = newcomp(user, group, home, ogroup) } rels = nil assert_nothing_raised() { rels = user.autorequire } assert(rels.detect { |r| r.source == group }, "User did not require group") assert(rels.detect { |r| r.source == ogroup }, "User did not require other groups") assert_nothing_raised() { rels = home.autorequire } assert(rels.detect { |r| r.source == user }, "Homedir did not require user") end def test_simpleuser name = "pptest" user = mkuser(name) comp = newcomp("usercomp", user) trans = assert_events([:user_created], comp, "user") assert_equal(user.should(:comment), user.provider.comment, "Comment was not set correctly") assert_rollback_events(trans, [:user_removed], "user") assert(! user.provider.exists?, "User did not get deleted") end def test_allusermodelstates user = nil name = "pptest" user = mkuser(name) assert(! user.provider.exists?, "User %s is present" % name) comp = newcomp("usercomp", user) trans = assert_events([:user_created], comp, "user") user.retrieve assert_equal("Puppet Testing User", user.provider.comment, "Comment was not set") tests = Puppet.type(:user).validstates tests.each { |test| if self.respond_to?("attrtest_%s" % test) self.send("attrtest_%s" % test, user) else Puppet.err "Not testing attr %s of user" % test end } user[:ensure] = :absent assert_apply(user) end end # $Id$