aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/mauve/configuration.rb16
-rw-r--r--lib/mauve/mauve_time.rb15
-rw-r--r--lib/mauve/notification.rb74
-rw-r--r--test/tc_mauve_notification.rb111
-rw-r--r--test/tc_mauve_time.rb (renamed from test/time_test.rb)0
-rw-r--r--test/test_mauve.rb2
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