summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xlib/puppet/type/schedule.rb32
-rwxr-xr-xspec/unit/ral/types/schedule.rb374
-rwxr-xr-xtest/ral/types/schedule.rb356
3 files changed, 392 insertions, 370 deletions
diff --git a/lib/puppet/type/schedule.rb b/lib/puppet/type/schedule.rb
index 46cff10f5..3fdc008b6 100755
--- a/lib/puppet/type/schedule.rb
+++ b/lib/puppet/type/schedule.rb
@@ -241,7 +241,7 @@ module Puppet
:daily => :day,
:monthly => :month,
:weekly => proc do |prev, now|
- prev.strftime("%U") == now.strftime("%U")
+ prev.strftime("%U") != now.strftime("%U")
end
}
@@ -256,8 +256,7 @@ module Puppet
return method.call(previous, now)
else
# We negate it, because if they're equal we don't run
- val = now.send(method) != previous.send(method)
- return val
+ return now.send(method) != previous.send(method)
end
when :distance
scale = @@scale[value]
@@ -266,6 +265,9 @@ module Puppet
# than the unit of time, we match. We divide the scale
# by the repeat, so that we'll repeat that often within
# the scale.
+ diff = (now.to_i - previous.to_i)
+ comparison = (scale / @resource[:repeat])
+
return (now.to_i - previous.to_i) >= (scale / @resource[:repeat])
end
end
@@ -312,25 +314,27 @@ module Puppet
end
def self.mkdefaultschedules
- # Create our default schedule
- unless self["puppet"]
- Puppet.debug "Creating default schedules"
- self.create(
- :name => "puppet",
- :period => :hourly,
- :repeat => "2"
- )
- end
+ return [] if self["puppet"]
+
+ result = []
+ Puppet.debug "Creating default schedules"
+ result << self.create(
+ :name => "puppet",
+ :period => :hourly,
+ :repeat => "2"
+ )
# And then one for every period
@parameters.find { |p| p.name == :period }.values.each { |value|
unless self[value.to_s]
- self.create(
+ result << self.create(
:name => value.to_s,
:period => value
)
end
}
+
+ result
end
def match?(previous = nil, now = nil)
@@ -346,7 +350,7 @@ module Puppet
self.class.allattrs.each { |param|
if @parameters.include?(param) and
@parameters[param].respond_to?(:match?)
- #self.notice "Trying to match %s" % param
+ self.notice "Trying to match %s" % param
return false unless @parameters[param].match?(previous, now)
end
}
diff --git a/spec/unit/ral/types/schedule.rb b/spec/unit/ral/types/schedule.rb
new file mode 100755
index 000000000..73b3a0bd1
--- /dev/null
+++ b/spec/unit/ral/types/schedule.rb
@@ -0,0 +1,374 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/type/schedule'
+
+module ScheduleTesting
+ def setup
+ Puppet.settings.stubs(:value).with(:ignoreschedules).returns(false)
+
+ @schedule = Puppet::Type::Schedule.create(:name => "testing")
+ end
+
+ def format(time)
+ time.strftime("%H:%M:%S")
+ end
+
+ def diff(unit, incr, method, count)
+ diff = Time.now.to_i.send(method, incr * count)
+ Time.at(diff)
+ end
+
+ def month(method, count)
+ diff(:hour, 3600 * 24 * 30, method, count)
+ end
+
+ def week(method, count)
+ diff(:hour, 3600 * 24 * 7, method, count)
+ end
+
+ def day(method, count)
+ diff(:hour, 3600 * 24, method, count)
+ end
+
+ def hour(method, count)
+ diff(:hour, 3600, method, count)
+ end
+
+ def min(method, count)
+ diff(:min, 60, method, count)
+ end
+
+ def sec(method, count)
+ diff(:sec, 1, method, count)
+ end
+
+ def teardown
+ Puppet::Type::Schedule.clear
+ end
+end
+
+describe Puppet::Type::Schedule do
+ include ScheduleTesting
+
+ it "should default to :distance for period-matching" do
+ @schedule[:periodmatch].should == :distance
+ end
+
+ it "should default to a :repeat of 1" do
+ @schedule[:repeat].should == 1
+ end
+
+ it "should never match when the period is :never" do
+ @schedule[:period] = :never
+ @schedule.match?.should be_false
+ end
+end
+
+describe Puppet::Type::Schedule, "when producing default schedules" do
+ include ScheduleTesting
+
+ %w{hourly daily weekly monthly never}.each do |period|
+ period = period.to_sym
+ it "should produce a #{period} schedule with the period set appropriately" do
+ schedules = Puppet::Type::Schedule.mkdefaultschedules
+ schedules.find { |s| s[:name] == period.to_s and s[:period] == period }.should be_instance_of(Puppet::Type::Schedule)
+ end
+ end
+
+ it "should produce a schedule named puppet with a period of hourly and a repeat of 2" do
+ schedules = Puppet::Type::Schedule.mkdefaultschedules
+ schedules.find { |s|
+ s[:name] == "puppet" and s[:period] == :hourly and s[:repeat] == 2
+ }.should be_instance_of(Puppet::Type::Schedule)
+ end
+end
+
+describe Puppet::Type::Schedule, "when matching ranges" do
+ include ScheduleTesting
+
+ it "should match when the start time is before the current time and the end time is after the current time" do
+ @schedule[:range] = "%s - %s" % [format(Time.now - 10), format(Time.now + 10)]
+ @schedule.match?.should be_true
+ end
+
+ it "should not match when the start time is after the current time" do
+ @schedule[:range] = "%s - %s" % [format(Time.now + 5), format(Time.now + 10)]
+ @schedule.match?.should be_false
+ end
+
+ it "should not match when the end time is previous to the current time" do
+ @schedule[:range] = "%s - %s" % [format(Time.now - 10), format(Time.now - 5)]
+ @schedule.match?.should be_false
+ end
+end
+
+describe Puppet::Type::Schedule, "when matching hourly by distance" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :hourly
+ @schedule[:periodmatch] = :distance
+ end
+
+ it "should match an hour ago" do
+ @schedule.match?(hour("-", 1)).should be_true
+ end
+
+ it "should not match now" do
+ @schedule.match?(Time.now).should be_false
+ end
+
+ it "should not match 59 minutes ago" do
+ @schedule.match?(min("-", 59)).should be_false
+ end
+end
+
+describe Puppet::Type::Schedule, "when matching daily by distance" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :daily
+ @schedule[:periodmatch] = :distance
+ end
+
+ it "should match when the previous time was one day ago" do
+ @schedule.match?(day("-", 1)).should be_true
+ end
+
+ it "should not match when the previous time is now" do
+ @schedule.match?(Time.now).should be_false
+ end
+
+ it "should not match when the previous time was 23 hours ago" do
+ @schedule.match?(hour("-", 23)).should be_false
+ end
+end
+
+describe Puppet::Type::Schedule, "when matching weekly by distance" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :weekly
+ @schedule[:periodmatch] = :distance
+ end
+
+ it "should match seven days ago" do
+ @schedule.match?(day("-", 7)).should be_true
+ end
+
+ it "should not match now" do
+ @schedule.match?(Time.now).should be_false
+ end
+
+ it "should not match six days ago" do
+ @schedule.match?(day("-", 6)).should be_false
+ end
+end
+
+describe Puppet::Type::Schedule, "when matching monthly by distance" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :monthly
+ @schedule[:periodmatch] = :distance
+ end
+
+ it "should match 32 days ago" do
+ @schedule.match?(day("-", 32)).should be_true
+ end
+
+ it "should not match now" do
+ @schedule.match?(Time.now).should be_false
+ end
+
+ it "should not match 27 days ago" do
+ @schedule.match?(day("-", 27)).should be_false
+ end
+end
+
+describe Puppet::Type::Schedule, "when matching hourly by number" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :hourly
+ @schedule[:periodmatch] = :number
+ end
+
+ it "should match if the times are one minute apart and the current minute is 0" do
+ current = Time.now
+
+ # Subtract an hour, reset the minute to zero, then add 59 minutes, so we're the previous hour plus 59 minutes.
+ previous = (current - 3600 - (current.min * 60) + (59 * 60))
+
+ # Now set the "current" time to the zero minute of the current hour.
+ now = (current - (current.min * 60))
+ Time.stubs(:now).returns(now)
+ @schedule.match?(previous).should be_true
+ end
+
+ it "should not match if the times are 58 minutes apart and the current minute is 59" do
+ current = Time.now
+
+ # reset the minute to zero
+ previous = current - (current.min * 60)
+
+ # Now set the "current" time to the 59th minute of the current hour.
+ now = (current - (current.min * 60) + (59 * 60))
+ Time.stubs(:now).returns(now)
+ @schedule.match?(previous).should be_false
+ end
+end
+
+describe Puppet::Type::Schedule, "when matching daily by number" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :daily
+ @schedule[:periodmatch] = :number
+ end
+
+ it "should match if the times are one minute apart and the current minute and hour are 0" do
+ zero = Time.now
+
+ # Reset the current time to X:00:00
+ current = zero - (zero.hour * 3600) - (zero.min * 60) - zero.sec
+
+ # Now set the previous time to one minute before that
+ previous = current - 60
+
+ Time.stubs(:now).returns(current)
+ @schedule.match?(previous).should be_true
+ end
+
+ it "should not match if the times are 23 hours and 58 minutes apart and the current hour is 23 and the current minute is 59" do
+ zero = Time.now
+
+ # Reset the previous time to 00:00:00
+ previous = zero - (zero.hour * 3600) - (zero.min * 60) - zero.sec
+
+ # Set the current time to 23:59
+ now = previous + (23 * 3600) + (59 * 60)
+
+ Time.stubs(:now).returns(now)
+ @schedule.match?(previous).should be_false
+ end
+end
+
+describe Puppet::Type::Schedule, "when matching weekly by number" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :weekly
+ @schedule[:periodmatch] = :number
+ end
+
+ it "should match if the previous time is prior to the most recent Sunday" do
+ now = Time.now
+
+ # Subtract the number days we've progressed into the week, plus one because we're zero-indexed.
+ previous = now - (3600 * 24 * (now.wday + 1))
+
+ @schedule.match?(previous).should be_true
+ end
+
+ it "should not match if the previous time is after the most recent Saturday" do
+ now = Time.now
+
+ # Subtract the number days we've progressed into the week
+ previous = now - (3600 * 24 * now.wday)
+
+ @schedule.match?(previous).should be_false
+ end
+end
+
+describe Puppet::Type::Schedule, "when matching monthly by number" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :monthly
+ @schedule[:periodmatch] = :number
+ end
+
+ it "should match when the previous time is prior to the first day of this month" do
+ now = Time.now
+
+ # Subtract the number days we've progressed into the month
+ previous = now - (3600 * 24 * now.day)
+
+ @schedule.match?(previous).should be_true
+ end
+
+ it "should not match when the previous time is after the last day of last month" do
+ now = Time.now
+
+ # Subtract the number days we've progressed into the month, minus one
+ previous = now - (3600 * 24 * (now.day - 1))
+
+ @schedule.match?(previous).should be_false
+ end
+end
+
+describe Puppet::Type::Schedule, "when matching with a repeat greater than one" do
+ include ScheduleTesting
+
+ before do
+ @schedule[:period] = :daily
+ @schedule[:repeat] = 2
+ end
+
+ it "should fail if the periodmatch is 'number'" do
+ @schedule[:periodmatch] = :number
+ proc { @schedule[:repeat] = 2 }.should raise_error(Puppet::Error)
+ end
+
+ it "should match if the previous run was further away than the distance divided by the repeat" do
+ previous = Time.now - (3600 * 13)
+ @schedule.match?(previous).should be_true
+ end
+
+ it "should not match if the previous run was closer than the distance divided by the repeat" do
+ previous = Time.now - (3600 * 11)
+ @schedule.match?(previous).should be_false
+ end
+end
+
+module OldTesting
+ def mksched
+ @stype.create(:name => "testsched")
+ end
+
+ def test_period_with_repeat
+ previous = @now
+
+ s = mksched
+ s[:period] = :hourly
+
+ assert_nothing_raised("Was not able to set periodmatch") {
+ s[:periodmatch] = :number
+ }
+ assert_raise(Puppet::Error) {
+ s[:repeat] = 2
+ }
+ assert_nothing_raised("Was not able to reset periodmatch") {
+ s[:periodmatch] = :distance
+ }
+
+ assert(! s.match?(min("-", 40)), "matched minus 40 minutes")
+
+ assert_nothing_raised("Was not able to set period") {
+ s[:repeat] = 2
+ }
+
+ assert(! s.match?(min("-", 20)), "matched minus 20 minutes with half-hourly")
+ assert(s.match?(min("-", 40)), "Did not match minus 40 with half-hourly")
+
+ assert_nothing_raised("Was not able to set period") {
+ s[:repeat] = 3
+ }
+
+ assert(! s.match?(min("-", 15)), "matched minus 15 minutes with half-hourly")
+ assert(s.match?(min("-", 25)), "Did not match minus 25 with half-hourly")
+ end
+end
diff --git a/test/ral/types/schedule.rb b/test/ral/types/schedule.rb
deleted file mode 100755
index 2870b8db6..000000000
--- a/test/ral/types/schedule.rb
+++ /dev/null
@@ -1,356 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../../lib/puppettest'
-
-require 'puppettest'
-require 'puppet/type/schedule'
-
-class TestSchedule < Test::Unit::TestCase
- include PuppetTest
-
- def setup
- super
- @stype = Puppet::Type::Schedule
-
- # This will probably get overridden by different tests
- @now = Time.now
- Puppet[:ignoreschedules] = false
- end
-
- def mksched
- s = nil
- assert_nothing_raised {
- s = @stype.create(
- :name => "testsched"
- )
- }
-
- s
- end
-
- def diff(unit, incr, method, count)
- diff = @now.to_i.send(method, incr * count)
- t = Time.at(diff)
-
- #Puppet.notice "%s: %s %s %s = %s" %
- # [unit, @now.send(unit), method, count, t]
- #t.strftime("%H:%M:%S")
- t
- end
-
- def month(method, count)
- diff(:hour, 3600 * 24 * 30, method, count)
- end
-
- def week(method, count)
- diff(:hour, 3600 * 24 * 7, method, count)
- end
-
- def day(method, count)
- diff(:hour, 3600 * 24, method, count)
- end
-
- def hour(method, count)
- diff(:hour, 3600, method, count)
- end
-
- def min(method, count)
- diff(:min, 60, method, count)
- end
-
- def sec(method, count)
- diff(:sec, 1, method, count)
- end
-
- def settimes
- unless defined? @@times
- @@times = [Time.now]
-
- # Make one with an edge year on each side
- ary = Time.now.to_a
- [1999, 2000, 2001].each { |y|
- ary[5] = y; @@times << Time.local(*ary)
- }
-
- # And with edge hours
- ary = Time.now.to_a
- #[23, 0].each { |h| ary[2] = h; @@times << Time.local(*ary) }
- # 23 hour
- ary[2] = 23
- @@times << Time.local(*ary)
- # 0 hour, next day
- ary[2] = 0
- @@times << addday(Time.local(*ary))
-
- # And with edge minutes
- #[59, 0].each { |m| ary[1] = m; @@times << Time.local(*ary) }
- ary = Time.now.to_a
- ary[1] = 59; @@times << Time.local(*ary)
- ary[1] = 0
- #if ary[2] == 23
- @@times << Time.local(*ary)
- #else
- # @@times << addday(Time.local(*ary))
- #end
- end
-
- Puppet.err @@times.inspect
-
- @@times.each { |time|
- @now = time
- yield time
- }
-
- @now = Time.now
- end
-
- def test_range
- s = mksched
-
- ary = @now.to_a
- ary[2] = 12
- @now = Time.local(*ary)
- data = {
- true => [
- # An hour previous, an hour after
- [hour("-", 1), hour("+", 1)],
-
- # an hour previous but a couple minutes later, and an hour plus
- [min("-", 57), hour("+", 1)]
- ],
- false => [
- # five minutes from now, an hour from now
- [min("+", 5), hour("+", 1)],
-
- # an hour ago, 20 minutes ago
- [hour("-", 1), min("-", 20)]
- ]
- }
-
- data.each { |result, values|
- values = values.collect { |value|
- "%s - %s" % [value[0].strftime("%H:%M:%S"),
- value[1].strftime("%H:%M:%S")]
- }
- values.each { |value|
- assert_nothing_raised("Could not parse %s" % value) {
- s[:range] = value
- }
-
- assert_equal(result, s.match?(nil, @now),
- "%s matched %s incorrectly" % [value.inspect, @now])
- }
-
- assert_nothing_raised("Could not parse %s" % [values]) {
- s[:range] = values
- }
-
- assert_equal(result, s.match?(nil, @now),
- "%s matched %s incorrectly" % [values.inspect, @now])
- }
- end
-
- def test_period_by_distance
- previous = @now
-
- s = mksched
-
- assert_nothing_raised {
- s[:period] = :daily
- }
-
- assert(s.match?(day("-", 1)), "did not match minus a day")
- assert(s.match?(day("-", 2)), "did not match two days")
- assert(! s.match?(@now), "matched today")
- assert(! s.match?(hour("-", 11)), "matched minus 11 hours")
-
- # Now test hourly
- assert_nothing_raised {
- s[:period] = :hourly
- }
-
- assert(s.match?(hour("-", 1)), "did not match minus an hour")
- assert(s.match?(hour("-", 2)), "did not match two hours")
- assert(! s.match?(@now), "matched now")
- assert(! s.match?(min("-", 59)), "matched minus 11 hours")
-
- # and weekly
- assert_nothing_raised {
- s[:period] = :weekly
- }
-
- assert(s.match?(week("-", 1)), "did not match minus a week")
- assert(s.match?(day("-", 7)), "did not match minus 7 days")
- assert(s.match?(day("-", 8)), "did not match minus 8 days")
- assert(s.match?(week("-", 2)), "did not match two weeks")
- assert(! s.match?(@now), "matched now")
- assert(! s.match?(day("-", 6)), "matched minus 6 days")
-
- # and monthly
- assert_nothing_raised {
- s[:period] = :monthly
- }
-
- assert(s.match?(month("-", 1)), "did not match minus a month")
- assert(s.match?(week("-", 5)), "did not match minus 5 weeks")
- assert(s.match?(week("-", 7)), "did not match minus 7 weeks")
- assert(s.match?(day("-", 50)), "did not match minus 50 days")
- assert(s.match?(month("-", 2)), "did not match two months")
- assert(! s.match?(@now), "matched now")
- assert(! s.match?(week("-", 3)), "matched minus 3 weeks")
- assert(! s.match?(day("-", 20)), "matched minus 20 days")
- end
-
- # A shortened test...
- def test_period_by_number
- s = mksched
- assert_nothing_raised {
- s[:periodmatch] = :number
- }
-
- assert_nothing_raised {
- s[:period] = :daily
- }
-
- assert(s.match?(day("+", 1)), "didn't match plus a day")
- assert(s.match?(week("+", 1)), "didn't match plus a week")
- assert(! s.match?(@now), "matched today")
- assert(! s.match?(hour("-", 1)), "matched minus an hour")
- assert(! s.match?(hour("-", 2)), "matched plus two hours")
-
- # Now test hourly
- assert_nothing_raised {
- s[:period] = :hourly
- }
-
- assert(s.match?(hour("+", 1)), "did not match plus an hour")
- assert(s.match?(hour("+", 2)), "did not match plus two hours")
- assert(! s.match?(@now), "matched now")
- assert(! s.match?(sec("+", 20)), "matched plus 20 seconds")
- end
-
- def test_periodmatch_default
- s = mksched
-
- match = s[:periodmatch]
- assert(match, "Could not find periodmatch")
-
- assert_equal(:distance, match, "Periodmatch was %s" % match)
- end
-
- def test_scheduled_objects
- s = mksched
- s[:period] = :hourly
-
- f = nil
- path = tempfile()
- assert_nothing_raised {
- f = Puppet.type(:file).create(
- :name => path,
- :schedule => s.name,
- :ensure => "file"
- )
- }
-
- assert(f.scheduled?, "File is not scheduled to run")
-
- assert_apply(f)
-
- assert(! f.scheduled?, "File is scheduled to run already")
- File.unlink(path)
-
- assert_apply(f)
-
- assert(! FileTest.exists?(path), "File was created when not scheduled")
- end
-
- def test_latebinding_schedules
- f = nil
- path = tempfile()
- assert_nothing_raised {
- f = Puppet.type(:file).create(
- :name => path,
- :schedule => "testsched",
- :ensure => "file"
- )
- }
-
- s = mksched
- s[:period] = :hourly
-
- assert_nothing_raised {
- f.schedule
- }
-
- assert(f.scheduled?, "File is not scheduled to run")
- end
-
- # Verify that each of our default schedules exist
- def test_defaultschedules
- assert_nothing_raised do
- Puppet.type(:schedule).mkdefaultschedules
- end
- s = {}
- %w{puppet hourly daily weekly monthly}.each { |period|
- obj = Puppet.type(:schedule)[period]
- assert(obj, "Could not find %s schedule" %
- period)
- s[period] = obj
- }
- assert_nothing_raised("Could not rerun mkdefaultschedules") do
- Puppet.type(:schedule).mkdefaultschedules
- end
- s.each do |period, obj|
- newobj = Puppet.type(:schedule)[period]
- assert(newobj, "somehow lost schedule for %s" % period)
- assert_equal(obj.object_id, newobj.object_id,
- "created a new schedule instead of reusing existing one")
- end
- end
-
- def test_period_with_repeat
- previous = @now
-
- s = mksched
- s[:period] = :hourly
-
- assert_nothing_raised("Was not able to set periodmatch") {
- s[:periodmatch] = :number
- }
- assert_raise(Puppet::Error) {
- s[:repeat] = 2
- }
- assert_nothing_raised("Was not able to reset periodmatch") {
- s[:periodmatch] = :distance
- }
-
- assert(! s.match?(min("-", 40)), "matched minus 40 minutes")
-
- assert_nothing_raised("Was not able to set period") {
- s[:repeat] = 2
- }
-
- assert(! s.match?(min("-", 20)), "matched minus 20 minutes with half-hourly")
- assert(s.match?(min("-", 40)), "Did not match minus 40 with half-hourly")
-
- assert_nothing_raised("Was not able to set period") {
- s[:repeat] = 3
- }
-
- assert(! s.match?(min("-", 15)), "matched minus 15 minutes with half-hourly")
- assert(s.match?(min("-", 25)), "Did not match minus 25 with half-hourly")
- end
-
- # #526
- def test_never_period
- schedule = nil
- assert_nothing_raised do
- schedule = Puppet::Type.type(:schedule).create(
- :name => "test", :period => :never
- )
- end
-
- assert(! schedule.match?, "schedule matched with period == never")
- end
-end
-