diff options
-rw-r--r-- | lib/mauve/configuration.rb | 16 | ||||
-rw-r--r-- | lib/mauve/mauve_time.rb | 15 | ||||
-rw-r--r-- | lib/mauve/notification.rb | 74 | ||||
-rw-r--r-- | test/tc_mauve_notification.rb | 111 | ||||
-rw-r--r-- | test/tc_mauve_time.rb (renamed from test/time_test.rb) | 0 | ||||
-rw-r--r-- | test/test_mauve.rb | 2 |
6 files changed, 184 insertions, 34 deletions
diff --git a/lib/mauve/configuration.rb b/lib/mauve/configuration.rb index 67b76ab..56f5e7e 100644 --- a/lib/mauve/configuration.rb +++ b/lib/mauve/configuration.rb @@ -1,20 +1,6 @@ require 'mauve/source_list' require 'mauve/people_list' - -# Seconds, minutes, hours, days, and weeks... More than that, we -# really should not need it. -class Integer - def seconds; self; end - def minutes; self*60; end - def hours; self*3600; end - def days; self*86400; end - def weeks; self*604800; end - alias_method :day, :days - alias_method :hour, :hours - alias_method :minute, :minutes - alias_method :week, :weeks -end - +require 'mauve/mauve_time' module Mauve diff --git a/lib/mauve/mauve_time.rb b/lib/mauve/mauve_time.rb index 812b0e2..e51cf6d 100644 --- a/lib/mauve/mauve_time.rb +++ b/lib/mauve/mauve_time.rb @@ -1,6 +1,21 @@ require 'date' require 'time' + +# Seconds, minutes, hours, days, and weeks... More than that, we +# really should not need it. +class Integer + def seconds; self; end + def minutes; self*60; end + def hours; self*3600; end + def days; self*86400; end + def weeks; self*604800; end + alias_method :day, :days + alias_method :hour, :hours + alias_method :minute, :minutes + alias_method :week, :weeks +end + class Date def to_mauvetime Mauve::MauveTime.parse(self.to_s) diff --git a/lib/mauve/notification.rb b/lib/mauve/notification.rb index ed96f7e..adb61c3 100644 --- a/lib/mauve/notification.rb +++ b/lib/mauve/notification.rb @@ -26,6 +26,8 @@ module Mauve # class DuringRunner + attr_reader :time, :alert, :during + def initialize(time, alert=nil, &during) raise ArgumentError.new("Must supply time (not #{time.inspect})") unless time.is_a?(Time) @time = time @@ -34,30 +36,62 @@ module Mauve @logger = Log4r::Logger.new "Mauve::DuringRunner" end - def now? - instance_eval(&@during) + # + # + # + def now?(t=@time) + @test_time = t + res = instance_eval(&@during) end - def find_next(interval) - interval = 300 if true == interval.nil? - offset = (@time.nil?)? MauveTime.now : @time - plus_one_week = MauveTime.now + 604800 # ish - while offset < plus_one_week - offset += interval - return offset if DuringRunner.new(offset, @alert, &@during).now? - end - @logger.info("Could not find a reminder time less than a week "+ - "for #{@alert}.") + def find_next(after = 5.minutes) + t = @time+after + # + # If the condition is true after x seconds, return the time in x seconds. + # + return t if self.now?(t) + + # + # Otherwise calculate when the condition is next true. + # + step = 3600 + while t <= @time + 8.days + # + # If we're currently OK, and we won't be OK after the next step (or + # vice-versa) decrease step size, and try again + # + if false == self.now?(t) and true == self.now?(t+step) + # + # Unless we're on the smallest step, try a smaller one. + # + if step == 1 + t += step + break + end + + step /= 60 + next + end + + # + # Decrease the time by the step size if we're currently OK. + # + t += step + end + + return t if self.now?(t) + nil # never again end protected + def hours_in_day(*hours) - x_in_list_of_y(@time.hour, hours.flatten) + x_in_list_of_y(@test_time.hour, hours.flatten) end def days_in_week(*days) - x_in_list_of_y(@time.wday, days.flatten) + x_in_list_of_y(@test_time.wday, days.flatten) end ## Return true if the alert has not been acknowledged within a certain time. @@ -66,7 +100,7 @@ module Mauve @alert && @alert.raised? && !@alert.acknowledged? && - (@time - @alert.raised_at.to_time) > seconds + (@test_time - @alert.raised_at.to_time) > seconds end def x_in_list_of_y(x,y) @@ -80,7 +114,7 @@ module Mauve end def working_hours? - @time.working_hours? + @test_time.working_hours? end # Return true in the dead zone between 3 and 7 in the morning. @@ -89,7 +123,7 @@ module Mauve # # @return [Boolean] Whether now is a in the dead zone or not. def dead_zone? - @time.dead_zone? + @test_time.dead_zone? end end @@ -129,7 +163,7 @@ module Mauve # Not ideal. A quick fix is to make sure that the clause in the # configuration has a fall back that will send an alert in all cases. # - def alert_changed(alert) + def notify(alert) if people.nil? or people.empty? logger.warn "No people found in for notification #{list}" @@ -150,8 +184,10 @@ module Mauve [] end end.flatten.uniq.each do |person| - person.alert_changed(level, alert, is_relevant, remind_at_next(alert)) + person.send_alert(level, alert, is_relevant, remind_at_next(alert)) end + + return nil end def remind_at_next(alert) diff --git a/test/tc_mauve_notification.rb b/test/tc_mauve_notification.rb new file mode 100644 index 0000000..3414292 --- /dev/null +++ b/test/tc_mauve_notification.rb @@ -0,0 +1,111 @@ +$:.unshift "../lib" + +require 'test/unit' +require 'mauve/alert' +require 'mauve/notification' +require 'mauve/configuration' +require 'mauve/configuration_builder' +require 'mauve/mauve_time' +require 'th_mauve_resolv' +require 'pp' + + + +class TcMauveDuringRunner < Test::Unit::TestCase + + def test_initialize + + alert = Mauve::Alert.new + time = Time.now + during = Proc.new { false } + + dr = Mauve::DuringRunner.new(time, alert, &during) + + assert_equal(dr.alert, alert) + assert_equal(dr.time, time) + assert_equal(dr.during, during) + + end + + def test_now? + alert = Mauve::Alert.new + time = Time.now + during = Proc.new { @test_time } + + dr = Mauve::DuringRunner.new(time, alert, &during) + assert_equal(time, dr.now?) + assert_equal(time+3600, dr.now?(time+3600)) + assert_equal(time, dr.time) + end + + def test_find_next + # + # An alert is supposed to remind someone every six hours during working + # hours, and it is raised outside working hours. Assuming it is still + # raised when working hours start, when should the first reminder get sent? + # + # (a) As soon as working hours commence. + # (b) At some point in the first six hours of working hours. + # (c) After six working hours. + # + # (12:38:19) Nick: a) + + # + # This should give us midnight last sunday night. + # + now = Mauve::MauveTime.now + midnight_sunday = now - (now.hour.hours + now.min.minutes + now.sec.seconds + now.wday.days) + + # + # first working hour on Monday + monday_morning = midnight_sunday.in_x_hours(0,"working") + + # + # This should alert at exactly first thing on Monday morning. + # + dr = Mauve::DuringRunner.new(midnight_sunday, nil){ working_hours? } + assert_equal(dr.find_next(6.hours), monday_morning) + + # + # This should alert six hours later than the last one. + # + dr = Mauve::DuringRunner.new(monday_morning, nil){ working_hours? } + assert_equal(dr.find_next(6.hours), monday_morning + 6.hours) + + # + # Now assuming the working day is not 12 hours long, if we progress to 6 + # hours in the future then the next alert should be first thing on Tuesday. + # + dr = Mauve::DuringRunner.new(monday_morning + 6.hours, nil){ working_hours? } + tuesday_morning = monday_morning+24.hours + assert_equal(dr.find_next(6.hours), tuesday_morning) + + # + # If an alert is too far in the future (a week) return nil. + # + dr = Mauve::DuringRunner.new(monday_morning, nil){ @test_time > (@time + 12.days) } + assert_nil(dr.find_next) + end + + def test_hours_in_day + end + + def test_days_in_week + end + + def test_unacknowledged + end + +end + +class TcMauveNotification < Test::Unit::TestCase + + def test_notify + end + + def remind_at_next + end + +end + + diff --git a/test/time_test.rb b/test/tc_mauve_time.rb index 0749fef..0749fef 100644 --- a/test/time_test.rb +++ b/test/tc_mauve_time.rb diff --git a/test/test_mauve.rb b/test/test_mauve.rb index e3df469..a8dba9b 100644 --- a/test/test_mauve.rb +++ b/test/test_mauve.rb @@ -17,6 +17,8 @@ tc_mauve_source_list.rb tc_mauve_people_list.rb tc_mauve_alert.rb tc_mauve_alert_group.rb +tc_mauve_notification.rb +tc_mauve_time.rb ).each do |s| require s end |