diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/data/providers/cron/crontab_collections.yaml | 44 | ||||
-rw-r--r-- | test/data/providers/cron/crontab_multiple_with_env.yaml | 54 | ||||
-rw-r--r-- | test/data/providers/cron/crontab_sample_records.yaml | 272 | ||||
-rwxr-xr-x | test/ral/providers/cron/crontab.rb | 236 | ||||
-rwxr-xr-x | test/ral/providers/parsedfile.rb | 46 | ||||
-rwxr-xr-x | test/ral/types/cron.rb | 42 | ||||
-rwxr-xr-x | test/ral/types/interface.rb | 2 |
7 files changed, 606 insertions, 90 deletions
diff --git a/test/data/providers/cron/crontab_collections.yaml b/test/data/providers/cron/crontab_collections.yaml new file mode 100644 index 000000000..45c8eaf65 --- /dev/null +++ b/test/data/providers/cron/crontab_collections.yaml @@ -0,0 +1,44 @@ +--- +:with_name: +- :name +- :spaces_in_command_with_times +:with_env: +- :environment +- :spaces_in_command_with_times +:simple: +- :spaces_in_command_with_times +:with_multiple_envs: +- :environment +- :lowercase_environment +- :spaces_in_command_with_times +:with_name_and_env: +- :name_with_spaces +- :another_env +- :spaces_in_command_with_times +:with_name_and_multiple_envs: +- :long_name +- :another_env +- :fourth_env +- :spaces_in_command_with_times +--- +:with_name: +- :name +- :spaces_in_command_with_times +:with_env: +- :environment +- :spaces_in_command_with_times +:simple: +- :spaces_in_command_with_times +:with_multiple_envs: +- :environment +- :lowercase_environment +- :spaces_in_command_with_times +:with_name_and_env: +- :name_with_spaces +- :another_env +- :spaces_in_command_with_times +:with_name_and_multiple_envs: +- :long_name +- :another_env +- :fourth_env +- :spaces_in_command_with_times diff --git a/test/data/providers/cron/crontab_multiple_with_env.yaml b/test/data/providers/cron/crontab_multiple_with_env.yaml new file mode 100644 index 000000000..8573bd467 --- /dev/null +++ b/test/data/providers/cron/crontab_multiple_with_env.yaml @@ -0,0 +1,54 @@ +--- +- | + # comment 1 + # Puppet Name: name2 + env3=val + * * * * * command4 + # Puppet Name: name with spaces + env3=val + env4=other + * * * * * command5 + # comment 5 + +- - :record_type: :comment + :line: "# comment 1" + - :command: command4 + :environment: + - env3=val + :name: name2 + :record_type: :crontab + - :command: command5 + :environment: + - env3=val + - env4=other + :name: name with spaces + :record_type: :crontab + - :record_type: :comment + :line: "# comment 5" +--- +- | + # comment 1 + # Puppet Name: name2 + env3=val + * * * * * command4 + # Puppet Name: name with spaces + env3=val + env4=other + * * * * * command5 + # comment 5 + +- - :record_type: :comment + :line: "# comment 1" + - :command: command4 + :environment: + - env3=val + :name: name2 + :record_type: :crontab + - :command: command5 + :environment: + - env3=val + - env4=other + :name: name with spaces + :record_type: :crontab + - :record_type: :comment + :line: "# comment 5" diff --git a/test/data/providers/cron/crontab_sample_records.yaml b/test/data/providers/cron/crontab_sample_records.yaml new file mode 100644 index 000000000..cafe9de25 --- /dev/null +++ b/test/data/providers/cron/crontab_sample_records.yaml @@ -0,0 +1,272 @@ +--- +:longcommment: + :text: "# This is a comment" + :record: + :line: "# This is a comment" + :record_type: :comment +:special: + :text: "@hourly /bin/date" + :record: + :special: hourly + :command: /bin/date + :record_type: :freebsd_special +:long_name: + :text: "# Puppet Name: long_name" + :record: + :line: "# Puppet Name: long_name" + :name: long_name + :record_type: :comment +:multiple_minutes: + :text: 5,15 * * * * /bin/date + :record: + :minute: + - "5" + - "15" + :command: /bin/date + :record_type: :crontab +:environment: + :text: ONE=TWO + :record: + :line: ONE=TWO + :record_type: :environment +:empty: + :text: "" + :record: + :line: "" + :record_type: :blank +:simple: + :text: "* * * * * /bin/date" + :record: + :command: /bin/date + :record_type: :crontab +:whitespace: + :text: " " + :record: + :line: " " + :record_type: :blank +:minute_and_hour: + :text: 5 15 * * * /bin/date + :record: + :minute: + - "5" + :hour: + - "15" + :command: /bin/date + :record_type: :crontab +:lowercase_environment: + :text: a=b + :record: + :line: a=b + :record_type: :environment +:special_with_spaces: + :text: "@daily /bin/echo testing" + :record: + :special: daily + :command: /bin/echo testing + :record_type: :freebsd_special +:tabs: + :text: !binary | + CQ== + + :record: + :line: !binary | + CQ== + + :record_type: :blank +:multiple_minute_and_hour: + :text: 5,10 15,20 * * * /bin/date + :record: + :minute: + - "5" + - "10" + :hour: + - "15" + - "20" + :command: /bin/date + :record_type: :crontab +:name: + :text: "# Puppet Name: testing" + :record: + :line: "# Puppet Name: testing" + :name: testing + :record_type: :comment +:another_env: + :text: Testing=True + :record: + :line: Testing=True + :record_type: :environment +:shortcomment: + :text: "#" + :record: + :line: "#" + :record_type: :comment +:spaces_in_command: + :text: "* * * * * /bin/echo testing" + :record: + :command: /bin/echo testing + :record_type: :crontab +:fourth_env: + :text: True=False + :record: + :line: True=False + :record_type: :environment +:simple_with_minute: + :text: 5 * * * * /bin/date + :record: + :minute: + - "5" + :command: /bin/date + :record_type: :crontab +:spaces_in_command_with_times: + :text: 5,10 15,20 * * * /bin/echo testing + :record: + :minute: + - "5" + - "10" + :hour: + - "15" + - "20" + :command: /bin/echo testing + :record_type: :crontab +:name_with_spaces: + :text: "# Puppet Name: another name" + :record: + :line: "# Puppet Name: another name" + :name: another name + :record_type: :comment +--- +:longcommment: + :text: "# This is a comment" + :record: + :line: "# This is a comment" + :record_type: :comment +:special: + :text: "@hourly /bin/date" + :record: + :special: hourly + :command: /bin/date + :record_type: :freebsd_special +:long_name: + :text: "# Puppet Name: long_name" + :record: + :line: "# Puppet Name: long_name" + :name: long_name + :record_type: :comment +:multiple_minutes: + :text: 5,15 * * * * /bin/date + :record: + :minute: + - "5" + - "15" + :command: /bin/date + :record_type: :crontab +:environment: + :text: ONE=TWO + :record: + :line: ONE=TWO + :record_type: :environment +:empty: + :text: "" + :record: + :line: "" + :record_type: :blank +:simple: + :text: "* * * * * /bin/date" + :record: + :command: /bin/date + :record_type: :crontab +:whitespace: + :text: " " + :record: + :line: " " + :record_type: :blank +:minute_and_hour: + :text: 5 15 * * * /bin/date + :record: + :minute: + - "5" + :hour: + - "15" + :command: /bin/date + :record_type: :crontab +:lowercase_environment: + :text: a=b + :record: + :line: a=b + :record_type: :environment +:special_with_spaces: + :text: "@daily /bin/echo testing" + :record: + :special: daily + :command: /bin/echo testing + :record_type: :freebsd_special +:tabs: + :text: !binary | + CQ== + + :record: + :line: !binary | + CQ== + + :record_type: :blank +:multiple_minute_and_hour: + :text: 5,10 15,20 * * * /bin/date + :record: + :minute: + - "5" + - "10" + :hour: + - "15" + - "20" + :command: /bin/date + :record_type: :crontab +:name: + :text: "# Puppet Name: testing" + :record: + :line: "# Puppet Name: testing" + :name: testing + :record_type: :comment +:another_env: + :text: Testing=True + :record: + :line: Testing=True + :record_type: :environment +:shortcomment: + :text: "#" + :record: + :line: "#" + :record_type: :comment +:spaces_in_command: + :text: "* * * * * /bin/echo testing" + :record: + :command: /bin/echo testing + :record_type: :crontab +:fourth_env: + :text: True=False + :record: + :line: True=False + :record_type: :environment +:simple_with_minute: + :text: 5 * * * * /bin/date + :record: + :minute: + - "5" + :command: /bin/date + :record_type: :crontab +:spaces_in_command_with_times: + :text: 5,10 15,20 * * * /bin/echo testing + :record: + :minute: + - "5" + - "10" + :hour: + - "15" + - "20" + :command: /bin/echo testing + :record_type: :crontab +:name_with_spaces: + :text: "# Puppet Name: another name" + :record: + :line: "# Puppet Name: another name" + :name: another name + :record_type: :comment diff --git a/test/ral/providers/cron/crontab.rb b/test/ral/providers/cron/crontab.rb index e48883019..7df7bab3d 100755 --- a/test/ral/providers/cron/crontab.rb +++ b/test/ral/providers/cron/crontab.rb @@ -11,11 +11,41 @@ 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 @@ -27,31 +57,160 @@ class TestCronParsedProvider < Test::Unit::TestCase super end - def test_parse_record - fields = [:month, :weekday, :monthday, :hour, :command, :minute] - { - "* * * * * /bin/echo" => {:command => "/bin/echo"}, - "10 * * * * /bin/echo test" => {:minute => ["10"], - :command => "/bin/echo test"} - }.each do |line, should| + # 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 parse %s" % line.inspect) do - result = @provider.parse_line(line) + assert_nothing_raised("Could not generate %s: '%s'" % [name, options[:record]]) do + result = @provider.to_line(options[:record]) end - should[:record_type] = :crontab - fields.each do |field| - if should[field] - assert_equal(should[field], result[field], - "Did not parse %s in %s correctly" % [field, line.inspect]) - else - assert_equal(:absent, result[field], - "Did not set %s absent in %s" % [field, line.inspect]) + 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 - def test_parse_and_generate + # 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.filetype = :ram crondir = datadir(File.join(%w{providers cron})) files = Dir.glob("%s/crontab.*" % crondir) @@ -408,38 +567,37 @@ class TestCronParsedProvider < Test::Unit::TestCase target = @provider.target_object(@me) # First with no env settings - cron = @type.create :command => "/bin/echo yay", :name => "test", :hour => 4 + resource = @type.create :command => "/bin/echo yay", :name => "test", :hour => 4 + cron = resource.provider - assert_apply(cron) + cron.ensure = :present + cron.command = "/bin/echo yay" + cron.hour = %w{4} + cron.flush - props = cron.retrieve.inject({}) { |hash, ary| hash[ary[0]] = ary[1]; hash } + 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" - assert_apply(cron) + cron.environment = "TEST=foo" + cron.flush - props = cron.retrieve.inject({}) { |hash, ary| hash[ary[0]] = ary[1]; hash } - assert(target.read.include?("TEST=foo"), "Did not get environment setting") - #assert_equal(["TEST=foo"], props[:environment], "Did not get environment setting") + 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"] - assert_apply(cron) + cron.environment = ["TEST=foo", "BLAH=yay"] + cron.flush - props = cron.retrieve.inject({}) { |hash, ary| hash[ary[0]] = ary[1]; hash } - assert(target.read.include?("TEST=foo"), "Did not keep environment setting") - assert(target.read.include?("BLAH=yay"), "Did not get second environment setting") - #assert_equal(["TEST=foo", "BLAH=yay"], props[:environment], "Did not modify environment setting") + 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 - assert_apply(cron) - - props = cron.retrieve.inject({}) { |hash, ary| hash[ary[0]] = ary[1]; hash } - assert(! target.read.include?("TEST=foo"), "Did not remove environment setting") - assert(! target.read.include?("BLAH=yay"), "Did not remove second environment setting") - #assert_nil(props[:environment], "Did not modify environment setting") + 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/parsedfile.rb b/test/ral/providers/parsedfile.rb index e31bba75d..053a1993d 100755 --- a/test/ral/providers/parsedfile.rb +++ b/test/ral/providers/parsedfile.rb @@ -35,7 +35,7 @@ class TestParsedFile < Test::Unit::TestCase # A simple block to skip the complexity of a full transaction. def apply(resource) - [:one, :two, :ensure].each do |st| + [:one, :two, :ensure, :target].each do |st| Puppet.info "Setting %s: %s => %s" % [resource[:name], st, resource.should(st)] resource.provider.send(st.to_s + "=", resource.should(st)) @@ -202,44 +202,36 @@ class TestParsedFile < Test::Unit::TestCase prov.target_object(:default).write "will b d\n" # Create some resources for some of those demo files - resource = mkresource "bill", :target => :file1, :one => "b", :two => "c" - default = mkresource "will", :target => :default, :one => "b", :two => "d" + bill = mkresource "bill", :target => :file1, :one => "b", :two => "c" + will = mkresource "will", :target => :default, :one => "b", :two => "d" - resources = {"bill" => resource, "will" => default} + resources = {"bill" => bill, "will" => will} + prov_ids = {"bill" => bill.provider.object_id, "will" => will.provider.object_id} assert_nothing_raised do prov.prefetch(resources) end - # Make sure we prefetched our resources. - assert_equal("b", resource.provider.one, "did not prefetch resource from file1") - assert_equal("c", resource.provider.two, "did not prefetch resource from file1") - assert_equal("b", default.provider.one, "did not prefetch resource from default") - assert_equal("d", default.provider.two, "did not prefetch resource from default") - - # Now list all of them and make sure we get everything back - providers = nil - assert_nothing_raised do - providers = prov.instances - end - - providers.each do |provider| - assert_instance_of(prov, provider, "'instances' class method did not return providers") - end + assert(bill.provider.object_id != prov_ids["bill"], "provider was not replaced in resource") + assert(will.provider.object_id != prov_ids["will"], "provider was not replaced in resource") - %w{bill jill will}.each do |name| - assert(providers.find { |provider| provider.name == name}, - "Did not return %s in list" % name) - end + # Make sure we prefetched our resources. + assert_equal("b", bill.provider.one, "did not prefetch resource from file1") + assert_equal("c", bill.provider.two, "did not prefetch resource from file1") + assert_equal("b", will.provider.one, "did not prefetch resource from default") + assert_equal("d", will.provider.two, "did not prefetch resource from default") # Now modify our resources and write them out, making sure that prefetching # hasn't somehow destroyed this ability - resource[:one] = "a" - default[:one] = "a" + bill[:one] = "a" + will[:one] = "a" + assert_apply(bill) + assert_apply(will) - assert_apply(resource) - assert_apply(default) + prov.prefetch(resources) + assert_equal("a", bill.provider.one, "did not prefetch resource from file1") + assert_equal("a", will.provider.one, "did not prefetch resource from default") assert_equal("bill a c\njill b d\n", prov.target_object(:file1).read, "Did not write changed resource correctly") diff --git a/test/ral/types/cron.rb b/test/ral/types/cron.rb index 75a10c6fc..9a3466821 100755 --- a/test/ral/types/cron.rb +++ b/test/ral/types/cron.rb @@ -25,10 +25,12 @@ class TestCron < Test::Unit::TestCase end def teardown + super @crontype.defaultprovider = nil if defined? @oldfiletype @provider.filetype = @oldfiletype end + Puppet::Util::FileType.filetype(:ram).clear end def eachprovider @@ -138,11 +140,17 @@ class TestCron < Test::Unit::TestCase property = cron.send(:property, :command) cron.provider.command = command cron.provider.ensure = :present + cron.provider.user = @me cron.provider.month = ["4"] cron.provider.class.prefetch currentvalue = cron.retrieve - assert(cron.insync?(currentvalue), "command parsing removes trailing whitespace") + currentvalue.each do |prop, value| + # We're only interested in comparing the command. + next unless prop.name.to_s == "command" + assert(prop.insync?(value), "Property %s is not considered in sync with value %s" % [prop.name, value.inspect]) + end + @crontype.clear end end @@ -232,14 +240,18 @@ class TestCron < Test::Unit::TestCase ) } - #minute = cron.send(:property, :minute) + cron.provider.ensure = :present cron.provider.command = '/bin/date > /dev/null' cron.provider.minute = %w{0 30} cron.provider.class.prefetch currentvalue = cron.retrieve - assert(cron.insync?(currentvalue), "minute is out of sync with %s" % provider.name) + currentvalue.each do |prop, value| + # We're only interested in comparing minutes. + next unless prop.name.to_s == "minute" + assert(prop.insync?(value), "Property %s is not considered in sync with value %s" % [prop.name, value.inspect]) + end @crontype.clear end end @@ -309,23 +321,6 @@ class TestCron < Test::Unit::TestCase end end - # Disabled, since we no longer have naming requirements. - def disabled_test_names - cron = mkcron("nametest") - - ["bad name", "bad.name"].each do |name| - assert_raise(ArgumentError) do - cron[:name] = name - end - end - - ["good-name", "good-name", "AGoodName"].each do |name| - assert_nothing_raised do - cron[:name] = name - end - end - end - def test_divisionnumbers cron = mkcron("divtest") cron[:minute] = "*/5" @@ -468,7 +463,7 @@ class TestCron < Test::Unit::TestCase end # Make sure the user stuff defaults correctly. - def test_default_user + def test_default_user crontab = @crontype.provider(:crontab) if crontab.suitable? inst = @crontype.create( @@ -491,11 +486,12 @@ class TestCron < Test::Unit::TestCase # #705 - make sure extra spaces don't screw things up def test_spaces_in_command string = "echo multiple spaces" - cron = @crontype.create(:name => "testing", :command => string) + cron = @crontype.create(:name => "space testing", :command => string) assert_apply(cron) cron.class.clear - cron = @crontype.create(:name => "testing", :command => string) + cron = @crontype.create(:name => "space testing", :command => string) + # Now make sure that it's correctly in sync cron.provider.class.prefetch("testing" => cron) properties = cron.retrieve diff --git a/test/ral/types/interface.rb b/test/ral/types/interface.rb index 66425deb2..0e2768d9e 100755 --- a/test/ral/types/interface.rb +++ b/test/ral/types/interface.rb @@ -6,7 +6,7 @@ require 'puppettest' require 'mocha' class TestInterfaceType < PuppetTest::TestCase - include PuppetTest + confine "Could not find suitable interface provider" => Puppet::Type.type(:interface).suitableprovider.length > 0 def setup super |