diff options
| author | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2005-09-16 07:07:34 +0000 |
|---|---|---|
| committer | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2005-09-16 07:07:34 +0000 |
| commit | 11d3d24b758c5df43bec1761ceae70d8cb012953 (patch) | |
| tree | 3ebbacc9162e122c551abe2a59c36e0f013ff2c0 | |
| parent | 036ba7a439f13c5eb110ee0d2663583ef31ee723 (diff) | |
| download | puppet-11d3d24b758c5df43bec1761ceae70d8cb012953.tar.gz puppet-11d3d24b758c5df43bec1761ceae70d8cb012953.tar.xz puppet-11d3d24b758c5df43bec1761ceae70d8cb012953.zip | |
cron is working, but i want to write quite a few more test cases
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@677 980ebf18-57e1-0310-9a29-db15c13687c0
| -rwxr-xr-x | lib/puppet/type/cron.rb | 256 | ||||
| -rwxr-xr-x | test/types/tc_cron.rb | 131 |
2 files changed, 329 insertions, 58 deletions
diff --git a/lib/puppet/type/cron.rb b/lib/puppet/type/cron.rb index 7e0ae9fc4..09d50c813 100755 --- a/lib/puppet/type/cron.rb +++ b/lib/puppet/type/cron.rb @@ -9,22 +9,22 @@ module Puppet module CronType module Default def self.read(user) - %x{crontab -u #{user} -l} + tab = %x{crontab -u #{user} -l 2>/dev/null} + end + + def self.remove(user) + %x{crontab -u #{user} -r 2>/dev/null} end def self.write(user, text) - IO.popen("crontab -u #{user} -") { |p| + IO.popen("crontab -u #{user} -", "w") { |p| p.print text } end end module SunOS - def self.read(user) - %x{crontab -l #{user}} - end - - def self.write(user, text) + def self.asuser(user) # FIXME this should use our user object, since it already does # this for us require 'etc' @@ -43,13 +43,34 @@ module Puppet Process.euid = uid end - IO.popen("crontab -") { |p| - p.print text - } + retval = yield + if olduid Process.euid = olduid end + + return retval + end + + def self.read(user) + self.asuser(user) { + %x{crontab -l 2>/dev/null} + } + end + + def self.remove(user) + self.asuser(user) { + %x{crontab -r 2>/dev/null} + } + end + + def self.write(user, text) + self.asuser(user) { + IO.popen("crontab", "w") { |p| + p.print text + } + } end end end @@ -64,17 +85,33 @@ module Puppet user's environment is desired it should be sourced manually." def retrieve - # nothing... + unless defined? @is and ! @is.nil? + @is = :notfound + end end def sync @parent.store + event = nil if @is == :notfound - return :cron_created + #@is = @should + event = :cron_created + elsif @should == :notfound + # FIXME I need to actually delete the cronjob... + event = :cron_deleted + elsif @should == @is + Puppet.err "Uh, they're both %s" % @should + return nil else - return :cron_changed + #@is = @should + Puppet.err "@is is %s" % @is + event = :cron_changed end + + @parent.store + + return event end end end @@ -125,6 +162,11 @@ module Puppet @instances = {} + @@weekdays = %w{sunday monday tuesday wednesday thursday friday saturday} + + @@months = %w{january february march april may june july + august september october november december} + case Facter["operatingsystem"].value when "SunOS": @crontype = Puppet::CronType::SunOS @@ -135,59 +177,98 @@ module Puppet # FIXME so the fundamental problem is, what if the object # already exists? + def self.clear + @instances = {} + @loaded = {} + @synced = {} + super + end + + def self.crontype + return @crontype + end + def self.fields return [:minute, :hour, :monthday, :month, :weekday, :command] end def self.instance(obj) - @instances << obj + user = obj[:user] + if @instances.include?(user) + unless @instances[obj[:user]].include?(obj) + @instances[obj[:user]] << obj + end + else + @instances[obj[:user]] = [obj] + end end def self.retrieve(user) - Puppet.err "Retrieving" - crons = [] hash = {} + name = nil + unless @instances.include?(user) + @instances[user] = [] + end #%x{crontab -u #{user} -l 2>/dev/null}.split("\n").each { |line| @crontype.read(user).split("\n").each { |line| case line - when /^# Puppet Name: (\w+)$/: hash[:name] = $1 - when /^#/: # add other comments to the list as they are - crons << line + when /^# Puppet Name: (\w+)$/: name = $1 + when /^#/: + # add other comments to the list as they are + @instances[user] << line else ary = line.split(" ") fields().each { |param| - hash[param] = ary.shift + value = ary.shift + unless value == "*" + hash[param] = value + end } if ary.length > 0 hash[:command] += " " + ary.join(" ") end cron = nil - unless hash.include?(:name) + unless name Puppet.info "Autogenerating name for %s" % hash[:command] - hash[:name] = "cron-%s" % hash.object_id + name = "cron-%s" % hash.object_id end + unless hash.include?(:command) + raise Puppet::DevError, "No command for %s" % name + end unless cron = Puppet::Type::Cron[hash[:command]] - cron = Puppet::Type::Cron.create + cron = Puppet::Type::Cron.create( + :name => name + ) end hash.each { |param, value| cron.is = [param, value] } - crons << cron hash.clear + name = nil end } + if $? == 0 + #return tab + else + #return nil + end - @instances[user] = crons @loaded[user] = Time.now end def self.store(user) if @instances.include?(user) @crontype.write(user, - @instances[user].join("\n") + @instances[user].collect { |obj| + if obj.is_a?(Cron) + obj.to_cron + else + obj.to_s + end + }.join("\n") ) @synced[user] = Time.now else @@ -203,30 +284,9 @@ module Puppet end end - def self.sync(user) - Puppet.err ary.length - str = ary.collect { |obj| - Puppet.err obj.name - self.to_cron(obj) - }.join("\n") - - puts str - end - - def self.to_cron(obj) - hash = {:command => obj.should(:command)} - self.fields().reject { |f| f == :command }.each { |param| - hash[param] = obj[param] || "*" - } - - self.fields.collect { |f| - hash[f] - }.join(" ") - end - def initialize(hash) - self.class.instance(self) super + self.class.instance(self) end def is=(ary) @@ -234,13 +294,93 @@ module Puppet if param.is_a?(String) param = param.intern end - unless @states.include?(param) + if self.class.validstate?(param) self.newstate(param) + @states[param].is = value + else + self[param] = value + end + end + + def numfix(num) + if num =~ /^\d+$/ + return num.to_i + elsif num.is_a?(Integer) + return num + else + return false + end + end + + def limitcheck(num, lower, upper, type) + if num >= lower and num <= upper + return num + else + return false + end + end + + def alphacheck(value, type, ary) + tmp = value.downcase + if tmp.length == 3 + ary.each_with_index { |name, index| + if name =~ /#{tmp}/i + return index + end + } + else + if ary.include?(tmp) + return ary.index(tmp) + end + end + + return false + end + + def parameter(value, type, lower, upper, alpha = nil, ary = nil) + retval = nil + if num = numfix(value) + retval = limitcheck(num, lower, upper, type) + elsif alpha + retval = alphacheck(value, type, ary) + end + + if retval + @parameters[type] = retval + else + raise Puppet::Error, "%s is not a valid %s" % + [value, type] end - @states[param].is = value + end + + def paramminute=(value) + parameter(value, :minute, 0, 59) + end + + def paramhour=(value) + parameter(value, :hour, 0, 23) + end + + def paramweekday=(value) + parameter(value, :weekday, 0, 6, true, @@weekdays) + end + + def parammonth=(value) + parameter(value, :month, 1, 12, true, @@months) + end + + def parammonthday=(value) + parameter(value, :monthday, 1, 31) end def paramuser=(user) + require 'etc' + + begin + obj = Etc.getpwnam(user) + rescue ArgumentError + raise Puppet::Error, "User %s not found" + end @parameters[:user] = user end @@ -249,13 +389,25 @@ module Puppet raise Puppet::Error, "You must specify the cron user" end - # look for the existing instance... - # and then set @is = :notfound + self.class.retrieve(@parameters[:user]) + @states[:command].retrieve end def store self.class.store(@parameters[:user]) end + + def to_cron + hash = {:command => @states[:command].should || @states[:command].is } + self.class.fields().reject { |f| f == :command }.each { |param| + hash[param] = @parameters[param] || "*" + } + + return "# Puppet Name: %s\n" % self.name + + self.class.fields.collect { |f| + hash[f] + }.join(" ") + end end end end diff --git a/test/types/tc_cron.rb b/test/types/tc_cron.rb index d35d873f3..a33ee992d 100755 --- a/test/types/tc_cron.rb +++ b/test/types/tc_cron.rb @@ -23,6 +23,23 @@ class TestExec < TestPuppet unless defined? @me raise "Could not retrieve user name; 'id' did not work" end + tab = Puppet::Type::Cron.crontype.read(@me) + + if $? == 0 + @currenttab = tab + else + @currenttab = nil + end + + super + end + + def teardown + if @currenttab + Puppet::Type::Cron.crontype.write(@me, @currenttab) + else + Puppet::Type::Cron.crontype.remove(@me) + end super end @@ -32,18 +49,120 @@ class TestExec < TestPuppet } end - def test_mkcron + def mkcron(name) cron = nil assert_nothing_raised { cron = Puppet::Type::Cron.create( - :command => "date > %s/crontest" % tmpdir(), - :name => "testcron", - :user => @me + :command => "date > %s/crontest%s" % [tmpdir(), name], + :name => name, + :user => @me, + :minute => rand(59), + :month => "1", + :monthday => "1", + :hour => "1" ) } - comp = newcomp("crontest", cron) + return cron + end + + def cyclecron(cron) + name = cron.name + comp = newcomp(name, cron) + + trans = assert_events(comp, [:cron_created], name) + cron.retrieve + assert(cron.insync?) + trans = assert_events(comp, [], name) + cron[:command] = :notfound + trans = assert_events(comp, [:cron_deleted], name) + end + + def test_mkcronwithnotab + Puppet::Type::Cron.crontype.remove(@me) + + cron = mkcron("crontest") + cyclecron(cron) + end + + def test_mkcronwithtab + Puppet::Type::Cron.crontype.remove(@me) + Puppet::Type::Cron.crontype.write(@me, +"1 1 1 1 * date > %s/crontesting\n" % testdir() + ) + + cron = mkcron("crontest") + cyclecron(cron) + end + + def test_makeandretrievecron + Puppet::Type::Cron.crontype.remove(@me) + + name = "storeandretrieve" + cron = mkcron(name) + comp = newcomp(name, cron) + trans = assert_events(comp, [:cron_created], name) + + cron = nil + + Puppet::Type::Cron.clear + Puppet::Type::Cron.retrieve(@me) + + assert(cron = Puppet::Type::Cron[name], "Could not retrieve named cron") + assert_instance_of(Puppet::Type::Cron, cron) + end + + def test_arguments + values = { + :monthday => { + :valid => [ 1, 13, ], + :invalid => [ -1, 0, 32 ] + }, + :weekday => { + :valid => [ 0, 3, 6, "tue", "wed", "Wed", "MOnday", "SaTurday" ], + :invalid => [ -1, 7, "tues", "teusday", "thurs" ] + }, + :hour => { + :valid => [ 0, 21, 23 ], + :invalid => [ -1, 24 ] + }, + :minute => { + :valid => [ 0, 34, 59 ], + :invalid => [ -1, 60 ] + }, + :month => { + :valid => [ 1, 11, 12, "mar", "March", "apr", "October", "DeCeMbEr" ], + :invalid => [ 0, 13, "marc", "sept" ] + } + } + + cron = mkcron("valtesting") + values.each { |param, hash| + hash.each { |type, values| + values.each { |value| + case type + when :valid: + assert_nothing_raised { + cron[param] = value + } + + if value.is_a?(Integer) + assert_equal(value, cron[param], + "Cron value was not set correctly") + end + when :invalid: + assert_raise(Puppet::Error, "%s is incorrectly a valid %s" % + [value, param]) { + cron[param] = value + } + end - trans = assert_events(comp, [:cron_created], "crontest") + if value.is_a?(Integer) + value = value.to_s + redo + end + } + } + } end end |
