diff --git a/spec/unit/parser/resource.rb b/spec/unit/parser/resource.rb index 1948a3c07..776e9c742 100755 --- a/spec/unit/parser/resource.rb +++ b/spec/unit/parser/resource.rb @@ -1,321 +1,319 @@ #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../spec_helper' # LAK: FIXME This is just new tests for resources; I have # not moved all tests over yet. describe Puppet::Parser::Resource do before do @parser = Puppet::Parser::Parser.new :Code => "" @source = @parser.newclass "" @node = Puppet::Node.new("yaynode") @compiler = Puppet::Parser::Compiler.new(@node, @parser) @scope = @compiler.topscope end def mkresource(args = {}) args[:source] ||= "source" args[:scope] ||= stub('scope', :source => mock('source')) {:type => "resource", :title => "testing", :source => "source", :scope => "scope"}.each do |param, value| args[param] ||= value end params = args[:params] || {:one => "yay", :three => "rah"} if args[:params] == :none args.delete(:params) else args[:params] = paramify(args[:source], params) end Puppet::Parser::Resource.new(args) end def param(name, value, source) Puppet::Parser::Resource::Param.new(:name => name, :value => value, :source => source) end def paramify(source, hash) hash.collect do |name, value| Puppet::Parser::Resource::Param.new( :name => name, :value => value, :source => source ) end end it "should be isomorphic if it is builtin and models an isomorphic type" do Puppet::Type.type(:file).expects(:isomorphic?).returns(true) @resource = Puppet::Parser::Resource.new(:type => "file", :title => "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true end it "should not be isomorphic if it is builtin and models a non-isomorphic type" do Puppet::Type.type(:file).expects(:isomorphic?).returns(false) @resource = Puppet::Parser::Resource.new(:type => "file", :title => "whatever", :scope => @scope, :source => @source).isomorphic?.should be_false end it "should be isomorphic if it is not builtin" do @parser.newdefine "whatever" @resource = Puppet::Parser::Resource.new(:type => "whatever", :title => "whatever", :scope => @scope, :source => @source).isomorphic?.should be_true end it "should have a array-indexing method for retrieving parameter values" do @resource = mkresource @resource[:one].should == "yay" end describe "when initializing" do before do @arguments = {:type => "resource", :title => "testing", :scope => stub('scope', :source => mock('source'))} end [:type, :title, :scope].each do |name| it "should fail unless #{name.to_s} is specified" do try = @arguments.dup try.delete(name) lambda { Puppet::Parser::Resource.new(try) }.should raise_error(ArgumentError) end end it "should set the reference correctly" do res = Puppet::Parser::Resource.new(@arguments) res.ref.should == "Resource[testing]" end end describe "when evaluating" do before do @type = Puppet::Parser::Resource @definition = @parser.newdefine "mydefine" @class = @parser.newclass "myclass" @nodedef = @parser.newnode("mynode")[0] end it "should evaluate the associated AST definition" do res = @type.new(:type => "mydefine", :title => "whatever", :scope => @scope, :source => @source) @definition.expects(:evaluate_code).with(res) res.evaluate end it "should evaluate the associated AST class" do res = @type.new(:type => "class", :title => "myclass", :scope => @scope, :source => @source) @class.expects(:evaluate_code).with(res) res.evaluate end it "should evaluate the associated AST node" do res = @type.new(:type => "node", :title => "mynode", :scope => @scope, :source => @source) @nodedef.expects(:evaluate_code).with(res) res.evaluate end end describe "when finishing" do before do @class = @parser.newclass "myclass" @nodedef = @parser.newnode("mynode")[0] @resource = Puppet::Parser::Resource.new(:type => "file", :title => "whatever", :scope => @scope, :source => @source) end it "should do nothing if it has already been finished" do @resource.finish @resource.expects(:add_metaparams).never @resource.finish end it "should add all defaults available from the scope" do @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => param(:owner, "default", @resource.source)) @resource.finish @resource[:owner].should == "default" end it "should not replace existing parameters with defaults" do @resource.set_parameter :owner, "oldvalue" @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => :replaced) @resource.finish @resource[:owner].should == "oldvalue" end it "should add a copy of each default, rather than the actual default parameter instance" do newparam = param(:owner, "default", @resource.source) other = newparam.dup other.value = "other" newparam.expects(:dup).returns(other) @resource.scope.expects(:lookupdefaults).with(@resource.type).returns(:owner => newparam) @resource.finish @resource[:owner].should == "other" end it "should copy metaparams from its scope" do @scope.setvar("noop", "true") @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams } @resource["noop"].should == "true" end it "should not copy metaparams that it already has" do @resource.set_parameter("noop", "false") @scope.setvar("noop", "true") @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams } @resource["noop"].should == "false" end it "should stack relationship metaparams from its container if it already has them" do @resource.set_parameter("require", "resource") @scope.setvar("require", "container") @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams } @resource["require"].sort.should == %w{container resource} end it "should flatten the array resulting from stacking relationship metaparams" do @resource.set_parameter("require", ["resource1", "resource2"]) @scope.setvar("require", %w{container1 container2}) @resource.class.publicize_methods(:add_metaparams) { @resource.add_metaparams } @resource["require"].sort.should == %w{container1 container2 resource1 resource2} end it "should add any tags from the scope resource" do scope_resource = stub 'scope_resource', :tags => %w{one two} @scope.stubs(:resource).returns(scope_resource) @resource.class.publicize_methods(:add_scope_tags) { @resource.add_scope_tags } @resource.tags.should be_include("one") @resource.tags.should be_include("two") end end describe "when being tagged" do before do @scope_resource = stub 'scope_resource', :tags => %w{srone srtwo} @scope = stub 'scope', :resource => @scope_resource @resource = Puppet::Parser::Resource.new(:type => "file", :title => "yay", :scope => @scope, :source => mock('source')) end it "should get tagged with the resource type" do @resource.tags.should be_include("file") end it "should get tagged with the title" do @resource.tags.should be_include("yay") end it "should get tagged with each name in the title if the title is a qualified class name" do resource = Puppet::Parser::Resource.new(:type => "file", :title => "one::two", :scope => @scope, :source => mock('source')) resource.tags.should be_include("one") resource.tags.should be_include("two") end it "should get tagged with each name in the type if the type is a qualified class name" do resource = Puppet::Parser::Resource.new(:type => "one::two", :title => "whatever", :scope => @scope, :source => mock('source')) resource.tags.should be_include("one") resource.tags.should be_include("two") end it "should not get tagged with non-alphanumeric titles" do resource = Puppet::Parser::Resource.new(:type => "file", :title => "this is a test", :scope => @scope, :source => mock('source')) resource.tags.should_not be_include("this is a test") end it "should fail on tags containing '*' characters" do lambda { @resource.tag("bad*tag") }.should raise_error(Puppet::ParseError) end it "should fail on tags starting with '-' characters" do lambda { @resource.tag("-badtag") }.should raise_error(Puppet::ParseError) end it "should fail on tags containing ' ' characters" do lambda { @resource.tag("bad tag") }.should raise_error(Puppet::ParseError) end it "should allow alpha tags" do lambda { @resource.tag("good_tag") }.should_not raise_error(Puppet::ParseError) end end describe "when merging overrides" do before do @source = "source1" @resource = mkresource :source => @source @override = mkresource :source => @source end it "should fail when the override was not created by a parent class" do @override.source = "source2" @override.source.expects(:child_of?).with("source1").returns(false) - assert_raise(Puppet::ParseError, "Allowed unrelated resources to override") do - @resource.merge(@override) - end + lambda { @resource.merge(@override) }.should raise_error(Puppet::ParseError) end it "should succeed when the override was created in the current scope" do @resource.source = "source3" @override.source = @resource.source @override.source.expects(:child_of?).with("source3").never params = {:a => :b, :c => :d} @override.expects(:params).returns(params) @resource.expects(:override_parameter).with(:b) @resource.expects(:override_parameter).with(:d) @resource.merge(@override) end it "should succeed when a parent class created the override" do @resource.source = "source3" @override.source = "source4" @override.source.expects(:child_of?).with("source3").returns(true) params = {:a => :b, :c => :d} @override.expects(:params).returns(params) @resource.expects(:override_parameter).with(:b) @resource.expects(:override_parameter).with(:d) @resource.merge(@override) end it "should add new parameters when the parameter is not set" do @source.stubs(:child_of?).returns true @override.set_parameter(:testing, "value") @resource.merge(@override) @resource[:testing].should == "value" end it "should replace existing parameter values" do @source.stubs(:child_of?).returns true @resource.set_parameter(:testing, "old") @override.set_parameter(:testing, "value") @resource.merge(@override) @resource[:testing].should == "value" end it "should add values to the parameter when the override was created with the '+>' syntax" do @source.stubs(:child_of?).returns true param = Puppet::Parser::Resource::Param.new(:name => :testing, :value => "testing", :source => @resource.source) param.add = true @override.set_parameter(param) @resource.set_parameter(:testing, "other") @resource.merge(@override) @resource[:testing].should == %w{other testing} end end end diff --git a/spec/unit/ral/type/file.rb b/spec/unit/ral/type/file.rb index 1ef924569..e1a597434 100755 --- a/spec/unit/ral/type/file.rb +++ b/spec/unit/ral/type/file.rb @@ -1,97 +1,100 @@ #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../../spec_helper' describe Puppet::Type.type(:file) do before do @path = Tempfile.new("puppetspec") @path.close!() @path = @path.path @file = Puppet::Type::File.create(:name => @path) end describe "when used with content and replace=>false" do before do @file[:content] = "foo" @file[:replace] = false end it "should be insync if the file exists and the content is different" do File.open(@path, "w") do |f| f.puts "bar" end @file.property(:content).insync?("bar").should be_true end it "should be insync if the file exists and the content is right" do File.open(@path, "w") do |f| f.puts "foo" end @file.property(:content).insync?("foo").should be_true end it "should not be insync if the file does not exist" do @file.property(:content).insync?(:nil).should be_false end end describe "when retrieving remote files" do before do @filesource = Puppet::Type::File::FileSource.new @filesource.server = mock 'fileserver' @file.stubs(:uri2obj).returns(@filesource) @file[:source] = "puppet:///test" end it "should fail without writing if it cannot retrieve remote contents" do # create the file, because we only get the problem when it starts # out absent. File.open(@file[:path], "w") { |f| f.puts "a" } @file.expects(:write).never @filesource.server.stubs(:describe).returns("493\tfile\t100\t0\t{md5}3f5fef3bddbc4398c46a7bd7ba7b3af7") @filesource.server.stubs(:retrieve).raises(RuntimeError) @file.property(:source).retrieve lambda { @file.property(:source).sync }.should raise_error(Puppet::Error) end end describe "when managing links" do require 'puppettest/support/assertions' include PuppetTest + require 'tempfile' before do - @basedir = tempfile() + @basedir = tempfile Dir.mkdir(@basedir) @file = File.join(@basedir, "file") @link = File.join(@basedir, "link") File.open(@file, "w", 0644) { |f| f.puts "yayness"; f.flush } File.symlink(@file, @link) @resource = Puppet.type(:file).create( :path => @link, :mode => "755" ) + @catalog = Puppet::Node::Catalog.new + @catalog.add_resource @resource end after do - teardown + remove_tmp_files end it "should default to managing the link" do - assert_events([], @resource) + @catalog.apply # I convert them to strings so they display correctly if there's an error. ("%o" % (File.stat(@file).mode & 007777)).should == "%o" % 0644 end it "should be able to follow links" do @resource[:links] = :follow - assert_events([:file_changed], @resource) + @catalog.apply ("%o" % (File.stat(@file).mode & 007777)).should == "%o" % 0755 end end after do Puppet::Type::File.clear end end diff --git a/test/lib/puppettest.rb b/test/lib/puppettest.rb index e276bdf0f..63f8121b5 100755 --- a/test/lib/puppettest.rb +++ b/test/lib/puppettest.rb @@ -1,339 +1,344 @@ # Add .../test/lib testlib = File.expand_path(File.dirname(__FILE__)) $LOAD_PATH.unshift(testlib) unless $LOAD_PATH.include?(testlib) # Add .../lib mainlib = File.expand_path(File.join(File.dirname(__FILE__), '../../lib')) $LOAD_PATH.unshift(mainlib) unless $LOAD_PATH.include?(mainlib) require 'puppet' # include any gems in vendor/gems Dir["#{mainlib}/../vendor/gems/**"].each do |path| libpath = File.join(path, "lib") if File.directory?(libpath) $LOAD_PATH.unshift(libpath) else $LOAD_PATH.unshift(path) end end require 'mocha' # Only load the test/unit class if we're not in the spec directory. # Else we get the bogus 'no tests, no failures' message. unless Dir.getwd =~ /spec/ require 'test/unit' end # Yay; hackish but it works if ARGV.include?("-d") ARGV.delete("-d") $console = true end # Some monkey-patching to allow us to test private methods. class Class def publicize_methods(*methods) saved_private_instance_methods = methods.empty? ? self.private_instance_methods : methods self.class_eval { public(*saved_private_instance_methods) } yield self.class_eval { private(*saved_private_instance_methods) } end end module PuppetTest + # These need to be here for when rspec tests use these + # support methods. + @@tmpfiles = [] + # Munge cli arguments, so we can enable debugging if we want # and so we can run just specific methods. def self.munge_argv require 'getoptlong' result = GetoptLong.new( [ "--debug", "-d", GetoptLong::NO_ARGUMENT ], [ "--resolve", "-r", GetoptLong::REQUIRED_ARGUMENT ], [ "-n", GetoptLong::REQUIRED_ARGUMENT ], [ "--help", "-h", GetoptLong::NO_ARGUMENT ] ) usage = "USAGE: TESTOPTS='[-n -n ...] [-d]' rake [target] [target] ..." opts = [] dir = method = nil result.each { |opt,arg| case opt when "--resolve" dir, method = arg.split(",") when "--debug" $puppet_debug = true Puppet::Util::Log.level = :debug Puppet::Util::Log.newdestination(:console) when "--help" puts usage exit else opts << opt << arg end } suites = nil args = ARGV.dup # Reset the options, so the test suite can deal with them (this is # what makes things like '-n' work). opts.each { |o| ARGV << o } return args end # Find the root of the Puppet tree; this is not the test directory, but # the parent of that dir. def basedir(*list) unless defined? @@basedir Dir.chdir(File.dirname(__FILE__)) do @@basedir = File.dirname(File.dirname(Dir.getwd)) end end if list.empty? @@basedir else File.join(@@basedir, *list) end end def datadir(*list) File.join(basedir, "test", "data", *list) end def exampledir(*args) unless defined? @@exampledir @@exampledir = File.join(basedir, "examples") end if args.empty? return @@exampledir else return File.join(@@exampledir, *args) end end module_function :basedir, :datadir, :exampledir def cleanup(&block) @@cleaners << block end # Rails clobbers RUBYLIB, thanks def libsetup curlibs = ENV["RUBYLIB"].split(":") $:.reject do |dir| dir =~ /^\/usr/ end.each do |dir| unless curlibs.include?(dir) curlibs << dir end end ENV["RUBYLIB"] = curlibs.join(":") end def logcollector collector = [] Puppet::Util::Log.newdestination(collector) cleanup do Puppet::Util::Log.close(collector) end collector end def rake? $0 =~ /test_loader/ end # Redirect stdout and stderr def redirect @stderr = tempfile @stdout = tempfile $stderr = File.open(@stderr, "w") $stdout = File.open(@stdout, "w") cleanup do $stderr = STDERR $stdout = STDOUT end end def setup @memoryatstart = Puppet::Util.memory if defined? @@testcount @@testcount += 1 else @@testcount = 0 end @configpath = File.join(tmpdir, "configdir" + @@testcount.to_s + "/" ) unless defined? $user and $group $user = nonrootuser().uid.to_s $group = nonrootgroup().gid.to_s end Puppet.settings.clear Puppet[:user] = $user Puppet[:group] = $group Puppet[:confdir] = @configpath Puppet[:vardir] = @configpath unless File.exists?(@configpath) Dir.mkdir(@configpath) end - @@tmpfiles = [@configpath, tmpdir()] + @@tmpfiles << @configpath << tmpdir() @@tmppids = [] @@cleaners = [] @logs = [] # If we're running under rake, then disable debugging and such. #if rake? or ! Puppet[:debug] #if defined?($puppet_debug) or ! rake? if textmate? Puppet[:color] = false end Puppet::Util::Log.newdestination(@logs) if defined? $console Puppet.info @method_name Puppet::Util::Log.newdestination(:console) Puppet[:trace] = true end Puppet::Util::Log.level = :debug #$VERBOSE = 1 #else # Puppet::Util::Log.close # Puppet::Util::Log.newdestination(@logs) # Puppet[:httplog] = tempfile() #end Puppet[:ignoreschedules] = true #@start = Time.now end def tempfile if defined? @@tmpfilenum @@tmpfilenum += 1 else @@tmpfilenum = 1 end f = File.join(self.tmpdir(), "tempfile_" + @@tmpfilenum.to_s) @@tmpfiles << f return f end def textmate? if ENV["TM_FILENAME"] return true else return false end end def tstdir dir = tempfile() Dir.mkdir(dir) return dir end def tmpdir unless defined? @tmpdir and @tmpdir @tmpdir = case Facter["operatingsystem"].value when "Darwin": "/private/tmp" when "SunOS": "/var/tmp" else "/tmp" end @tmpdir = File.join(@tmpdir, "puppettesting" + Process.pid.to_s) unless File.exists?(@tmpdir) FileUtils.mkdir_p(@tmpdir) File.chmod(01777, @tmpdir) end end @tmpdir end def remove_tmp_files @@tmpfiles.each { |file| unless file =~ /tmp/ puts "Not deleting tmpfile %s" % file next end if FileTest.exists?(file) system("chmod -R 755 %s" % file) system("rm -rf %s" % file) end } @@tmpfiles.clear end def teardown #@stop = Time.now #File.open("/tmp/test_times.log", ::File::WRONLY|::File::CREAT|::File::APPEND) { |f| f.puts "%0.4f %s %s" % [@stop - @start, @method_name, self.class] } @@cleaners.each { |cleaner| cleaner.call() } remove_tmp_files @@tmppids.each { |pid| %x{kill -INT #{pid} 2>/dev/null} } @@tmppids.clear + Puppet::Type.allclear Puppet::Util::Storage.clear Puppet.clear Puppet.settings.clear Puppet::Indirector::Indirection.clear_cache @memoryatend = Puppet::Util.memory diff = @memoryatend - @memoryatstart if diff > 1000 Puppet.info "%s#%s memory growth (%s to %s): %s" % [self.class, @method_name, @memoryatstart, @memoryatend, diff] end # reset all of the logs Puppet::Util::Log.close @logs.clear # Just in case there are processes waiting to die... require 'timeout' begin Timeout::timeout(5) do Process.waitall end rescue Timeout::Error # just move on end end def logstore @logs = [] Puppet::Util::Log.newdestination(@logs) end end require 'puppettest/support' require 'puppettest/filetesting' require 'puppettest/fakes' require 'puppettest/exetest' require 'puppettest/parsertesting' require 'puppettest/servertest' require 'puppettest/testcase' diff --git a/test/ral/providers/cron/crontab.rb b/test/ral/providers/cron/crontab.rb index 1ff1e34ef..53bd76c50 100755 --- a/test/ral/providers/cron/crontab.rb +++ b/test/ral/providers/cron/crontab.rb @@ -1,604 +1,603 @@ #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../../lib/puppettest' require 'puppettest' require 'mocha' require 'puppettest/fileparsing' -require 'puppet/type/cron' class TestCronParsedProvider < Test::Unit::TestCase include PuppetTest include PuppetTest::FileParsing FIELDS = { :crontab => %w{command minute hour month monthday weekday}.collect { |o| o.intern }, :freebsd_special => %w{special command}.collect { |o| o.intern }, :environment => [:line], :blank => [:line], :comment => [:line], } # These are potentially multi-line records; there's no one-to-one map, but they model # a full cron job. These tests assume individual record types will always be correctly # parsed, so all they def sample_crons unless defined? @sample_crons @sample_crons = YAML.load(File.read(File.join(@crondir, "crontab_collections.yaml"))) end @sample_crons end # These are simple lines that can appear in the files; there is a one to one # mapping between records and lines. We have plenty of redundancy here because # we use these records to build up our complex, multi-line cron jobs below. def sample_records unless defined? @sample_records @sample_records = YAML.load(File.read(File.join(@crondir, "crontab_sample_records.yaml"))) end @sample_records end def setup super @type = Puppet::Type.type(:cron) @provider = @type.provider(:crontab) @provider.initvars @crondir = datadir(File.join(%w{providers cron})) @oldfiletype = @provider.filetype end def teardown Puppet::Util::FileType.filetype(:ram).clear @provider.clear super end # Make sure a cron job matches up. Any non-passed fields are considered absent. def assert_cron_equal(msg, cron, options) assert_instance_of(@provider, cron, "not an instance of provider in %s" % msg) options.each do |param, value| assert_equal(value, cron.send(param), "%s was not equal in %s" % [param, msg]) end %w{command environment minute hour month monthday weekday}.each do |var| unless options.include?(var.intern) assert_equal(:absent, cron.send(var), "%s was not parsed absent in %s" % [var, msg]) end end end # Make sure a cron record matches. This only works for crontab records. def assert_record_equal(msg, record, options) unless options.include?(:record_type) raise ArgumentError, "You must pass the required record type" end assert_instance_of(Hash, record, "not an instance of a hash in %s" % msg) options.each do |param, value| assert_equal(value, record[param], "%s was not equal in %s" % [param, msg]) end FIELDS[record[:record_type]].each do |var| unless options.include?(var) assert_equal(:absent, record[var], "%s was not parsed absent in %s" % [var, msg]) end end end def assert_header(file) header = [] file.gsub! /^(# HEADER: .+$)\n/ do header << $1 '' end assert_equal(4, header.length, "Did not get four header lines") end # This handles parsing every possible iteration of cron records. Note that this is only # single-line stuff and doesn't include multi-line values (e.g., with names and/or envs). # Those have separate tests. def test_parse_line # First just do each sample record one by one sample_records.each do |name, options| result = nil assert_nothing_raised("Could not parse %s: '%s'" % [name, options[:text]]) do result = @provider.parse_line(options[:text]) end assert_record_equal("record for %s" % name, result, options[:record]) end # Then do them all at once. records = [] text = "" sample_records.each do |name, options| records << options[:record] text += options[:text] + "\n" end result = nil assert_nothing_raised("Could not match all records in one file") do result = @provider.parse(text) end records.zip(result).each do |should, record| assert_record_equal("record for %s in full match" % should.inspect, record, should) end end # Here we test that each record generates to the correct text. def test_generate_line # First just do each sample record one by one sample_records.each do |name, options| result = nil assert_nothing_raised("Could not generate %s: '%s'" % [name, options[:record]]) do result = @provider.to_line(options[:record]) end assert_equal(options[:text], result, "Did not generate correct text for %s" % name) end # Then do them all at once. records = [] text = "" sample_records.each do |name, options| records << options[:record] text += options[:text] + "\n" end result = nil assert_nothing_raised("Could not match all records in one file") do result = @provider.to_file(records) end assert_header(result) assert_equal(text, result, "Did not generate correct full crontab") end # Test cronjobs that are made up from multiple records. def test_multi_line_cronjobs fulltext = "" all_records = [] sample_crons.each do |name, record_names| records = record_names.collect do |record_name| unless record = sample_records[record_name] raise "Could not find sample record %s" % record_name end record end text = records.collect { |r| r[:text] }.join("\n") + "\n" record_list = records.collect { |r| r[:record] } # Add it to our full collection all_records += record_list fulltext += text # First make sure we generate each one correctly result = nil assert_nothing_raised("Could not generate multi-line cronjob %s" % [name]) do result = @provider.to_file(record_list) end assert_header(result) assert_equal(text, result, "Did not generate correct text for multi-line cronjob %s" % name) # Now make sure we parse each one correctly assert_nothing_raised("Could not parse multi-line cronjob %s" % [name]) do result = @provider.parse(text) end record_list.zip(result).each do |should, record| assert_record_equal("multiline cronjob %s" % name, record, should) end end # Make sure we can generate it all correctly result = nil assert_nothing_raised("Could not generate all multi-line cronjobs") do result = @provider.to_file(all_records) end assert_header(result) assert_equal(fulltext, result, "Did not generate correct text for all multi-line cronjobs") # Now make sure we parse them all correctly assert_nothing_raised("Could not parse multi-line cronjobs") do result = @provider.parse(fulltext) end all_records.zip(result).each do |should, record| assert_record_equal("multiline cronjob %s", record, should) end end # Take our sample files, and make sure we can entirely parse them, # then that we can generate them again and we get the same data. def test_parse_and_generate_sample_files @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram)) crondir = datadir(File.join(%w{providers cron})) files = Dir.glob("%s/crontab.*" % crondir) setme @provider.default_target = @me target = @provider.target_object(@me) files.each do |file| str = args = nil assert_nothing_raised("could not load %s" % file) do str, args = YAML.load(File.read(file)) end # Stupid old yaml args.each do |hash| hash.each do |param, value| if param.is_a?(String) and param =~ /^:/ hash.delete(param) param = param.sub(/^:/,'').intern hash[param] = value end if value.is_a?(String) and value =~ /^:/ value = value.sub(/^:/,'').intern hash[param] = value end end end target.write(str) assert_nothing_raised("could not parse %s" % file) do @provider.prefetch end records = @provider.send(:instance_variable_get, "@records") args.zip(records) do |should, sis| # Make the values a bit more equal. should[:target] = @me should[:ensure] = :present #should[:environment] ||= [] should[:on_disk] = true is = sis.dup sis.dup.each do |p,v| is.delete(p) if v == :absent end assert_equal(should, is, "Did not parse %s correctly" % file) end assert_nothing_raised("could not generate %s" % file) do @provider.flush_target(@me) end assert_equal(str, target.read, "%s changed" % file) @provider.clear end end # A simple test to see if we can load the cron from disk. def test_load setme() records = nil assert_nothing_raised { records = @provider.retrieve(@me) } assert_instance_of(Array, records, "did not get correct response") end # Test that a cron job turns out as expected, by creating one and generating # it directly def test_simple_to_cron # make the cron setme() name = "yaytest" args = {:name => name, :command => "date > /dev/null", :minute => "30", :user => @me, :record_type => :crontab } # generate the text str = nil assert_nothing_raised { str = @provider.to_line(args) } assert_equal("# Puppet Name: #{name}\n30 * * * * date > /dev/null", str, "Cron did not generate correctly") end # Test that comments are correctly retained def test_retain_comments str = "# this is a comment\n#and another comment\n" user = "fakeuser" records = nil @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram)) target = @provider.target_object(user) target.write(str) assert_nothing_raised { @provider.prefetch } assert_nothing_raised { newstr = @provider.flush_target(user) assert(target.read.include?(str), "Comments were lost") } end def test_simpleparsing @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram)) text = "5 1,2 * 1 0 /bin/echo funtest" records = nil assert_nothing_raised { records = @provider.parse(text) } should = { :minute => %w{5}, :hour => %w{1 2}, :monthday => :absent, :month => %w{1}, :weekday => %w{0}, :command => "/bin/echo funtest" } is = records.shift assert(is, "Did not get record") should.each do |p, v| assert_equal(v, is[p], "did not parse %s correctly" % p) end end # Make sure we can create a cron in an empty tab. # LAK:FIXME This actually modifies the user's crontab, # which is pretty heinous. def test_mkcron_if_empty setme @provider.filetype = @oldfiletype records = @provider.retrieve(@me) target = @provider.target_object(@me) cleanup do if records.length == 0 target.remove else target.write(@provider.to_file(records)) end end # Now get rid of it assert_nothing_raised("Could not remove cron tab") do target.remove end @provider.flush :target => @me, :command => "/do/something", :record_type => :crontab created = @provider.retrieve(@me) assert(created.detect { |r| r[:command] == "/do/something" }, "Did not create cron tab") end # Make sure we correctly bidirectionally parse things. def test_records_and_strings @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram)) setme target = @provider.target_object(@me) [ "* * * * * /some/command", "0,30 * * * * /some/command", "0-30 * * * * /some/command", "# Puppet Name: name\n0-30 * * * * /some/command", "# Puppet Name: name\nVAR=VALUE\n0-30 * * * * /some/command", "# Puppet Name: name\nVAR=VALUE\nC=D\n0-30 * * * * /some/command", "0 * * * * /some/command" ].each do |str| @provider.initvars str += "\n" target.write(str) assert_equal(str, target.read, "Did not write correctly") assert_nothing_raised("Could not prefetch with %s" % str.inspect) do @provider.prefetch end assert_nothing_raised("Could not flush with %s" % str.inspect) do @provider.flush_target(@me) end assert_equal(str, target.read, "Changed in read/write") @provider.clear end end # Test that a specified cron job will be matched against an existing job # with no name, as long as all fields match def test_matchcron mecron = "0,30 * * * * date * * * * * funtest # a comment 0,30 * * 1 * date " youcron = "0,30 * * * * date * * * * * yaytest # a comment 0,30 * * 1 * fooness " setme @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram)) you = "you" # Write the same tab to multiple targets @provider.target_object(@me).write(mecron.gsub(/^\s+/, '')) @provider.target_object(you).write(youcron.gsub(/^\s+/, '')) # Now make some crons that should match matchers = [ @type.create( :name => "yaycron", :minute => [0, 30], :command => "date", :user => @me ), @type.create( :name => "youtest", :command => "yaytest", :user => you ) ] nonmatchers = [ @type.create( :name => "footest", :minute => [0, 30], :hour => 1, :command => "fooness", :user => @me # wrong target ), @type.create( :name => "funtest2", :command => "funtest", :user => you # wrong target for this cron ) ] # Create another cron so we prefetch two of them @type.create(:name => "testing", :minute => 30, :command => "whatever", :user => "you") assert_nothing_raised("Could not prefetch cron") do @provider.prefetch([matchers, nonmatchers].flatten.inject({}) { |crons, cron| crons[cron.name] = cron; crons }) end matchers.each do |cron| assert_equal(:present, cron.provider.ensure, "Cron %s was not matched" % cron.name) if value = cron.value(:minute) and value == "*" value = :absent end assert_equal(value, cron.provider.minute, "Minutes were not retrieved, so cron was not matched") assert_equal(cron.value(:target), cron.provider.target, "Cron %s was matched from the wrong target" % cron.name) end nonmatchers.each do |cron| assert_equal(:absent, cron.provider.ensure, "Cron %s was incorrectly matched" % cron.name) end end def test_data setme @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram)) target = @provider.target_object(@me) fakedata("data/providers/cron/examples").each do |file| text = File.read(file) target.write(text) assert_nothing_raised("Could not parse %s" % file) do @provider.prefetch end # mark the provider modified @provider.modified(@me) # and zero the text target.write("") result = nil assert_nothing_raised("Could not generate %s" % file) do @provider.flush_target(@me) end # Ignore whitespace differences, since those don't affect function. modtext = text.gsub(/[ \t]+/, " ") modtarget = target.read.gsub(/[ \t]+/, " ") assert_equal(modtext, modtarget, "File was not rewritten the same") @provider.clear end end # Match freebsd's annoying @daily stuff. def test_match_freebsd_special @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram)) setme target = @provider.target_object(@me) [ "@daily /some/command", "@daily /some/command more" ].each do |str| @provider.initvars str += "\n" target.write(str) assert_equal(str, target.read, "Did not write correctly") assert_nothing_raised("Could not prefetch with %s" % str.inspect) do @provider.prefetch end records = @provider.send(:instance_variable_get, "@records") records.each do |r| assert_equal(:freebsd_special, r[:record_type], "Did not create lines as freebsd lines") end assert_nothing_raised("Could not flush with %s" % str.inspect) do @provider.flush_target(@me) end assert_equal(str, target.read, "Changed in read/write") @provider.clear end end def test_prefetch cron = @type.create :command => "/bin/echo yay", :name => "test", :hour => 4 assert_nothing_raised("Could not prefetch cron") do cron.provider.class.prefetch("test" => cron) end end # Testing #669. def test_environment_settings @provider.stubs(:filetype).returns(Puppet::Util::FileType.filetype(:ram)) setme target = @provider.target_object(@me) # First with no env settings resource = @type.create :command => "/bin/echo yay", :name => "test", :hour => 4 cron = resource.provider cron.ensure = :present cron.command = "/bin/echo yay" cron.hour = %w{4} cron.flush result = target.read assert_equal("# Puppet Name: test\n* 4 * * * /bin/echo yay\n", result, "Did not write cron out correctly") # Now set the env cron.environment = "TEST=foo" cron.flush result = target.read assert_equal("# Puppet Name: test\nTEST=foo\n* 4 * * * /bin/echo yay\n", result, "Did not write out environment setting") # Modify it cron.environment = ["TEST=foo", "BLAH=yay"] cron.flush result = target.read assert_equal("# Puppet Name: test\nTEST=foo\nBLAH=yay\n* 4 * * * /bin/echo yay\n", result, "Did not write out environment setting") # And remove it cron.environment = :absent cron.flush result = target.read assert_equal("# Puppet Name: test\n* 4 * * * /bin/echo yay\n", result, "Did not write out environment setting") end end diff --git a/test/ral/providers/sshkey/parsed.rb b/test/ral/providers/sshkey/parsed.rb index b94b7a69a..4f18e6494 100755 --- a/test/ral/providers/sshkey/parsed.rb +++ b/test/ral/providers/sshkey/parsed.rb @@ -1,110 +1,109 @@ #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../../lib/puppettest' require 'puppettest' require 'puppettest/fileparsing' -require 'puppet/type/sshkey' class TestParsedSSHKey < Test::Unit::TestCase include PuppetTest include PuppetTest::FileParsing def setup super @provider = Puppet.type(:sshkey).provider(:parsed) @oldfiletype = @provider.filetype end def teardown Puppet::Util::FileType.filetype(:ram).clear @provider.filetype = @oldfiletype @provider.clear super end def mkkey(name = "host.domain.com") if defined? @pcount @pcount += 1 else @pcount = 1 end args = { :name => name || "/fspuppet%s" % @pcount, :key => "thisismykey%s" % @pcount, :alias => ["host1.domain.com","192.168.0.1"], :type => "dss", :ensure => :present } fakeresource = fakeresource(:sshkey, args[:name]) key = @provider.new(fakeresource) args.each do |p,v| key.send(p.to_s + "=", v) end return key end def test_keysparse fakedata("data/types/sshkey").each { |file| fakedataparse(file) } end def test_simplekey @provider.filetype = :ram file = @provider.default_target key = nil assert_nothing_raised do key = mkkey end assert(key, "did not create key") assert_nothing_raised do key.flush end assert(key.alias, "No alias set for key") hash = key.property_hash.dup text = @provider.target_object(file).read names = [key.name, key.alias].flatten.join(",") assert_equal("#{names} #{key.type} #{key.key}\n", text) assert_nothing_raised do @provider.prefetch end hash.each do |p, v| next unless key.respond_to?(p) assert_equal(v, key.send(p), "%s did not match" % p) end assert(key.name !~ /,/, "Aliases were not split out during parsing") end def test_hooks result = nil assert_nothing_raised("Could not call post hook") do result = @provider.parse_line("one,two type key") end assert_equal("one", result[:name], "Did not call post hook") assert_equal(%w{two}, result[:alias], "Did not call post hook") assert_equal("one,two type key", @provider.to_line(:record_type => :parsed, :name => "one", :alias => %w{two}, :type => "type", :key => "key"), "Did not use pre-hook when generating line" ) end end