aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick J Cherry <patrick@bytemark.co.uk>2012-05-02 10:44:34 +0100
committerPatrick J Cherry <patrick@bytemark.co.uk>2012-05-02 10:44:34 +0100
commit27d38820a67751a898d5d17073adc556c4bb56a9 (patch)
tree6157be1229f0c5ea7f8f237370ede914cf7e2f95
parente6c1341540eb4c08b1cbfef46cf2360489b27bd0 (diff)
Added configuration options for daytime_hours, dead_zone, and working_hours.
-rw-r--r--lib/mauve/configuration.rb107
-rw-r--r--lib/mauve/mauve_time.rb43
-rw-r--r--lib/mauve/notification.rb28
-rw-r--r--test/tc_mauve_configuration.rb38
-rw-r--r--test/tc_mauve_notification.rb10
-rw-r--r--test/tc_mauve_time.rb23
6 files changed, 224 insertions, 25 deletions
diff --git a/lib/mauve/configuration.rb b/lib/mauve/configuration.rb
index 8a0b982..55bdd9f 100644
--- a/lib/mauve/configuration.rb
+++ b/lib/mauve/configuration.rb
@@ -27,7 +27,7 @@ module Mauve
# People
# @return [Hash]
attr_reader :people
-
+
# Alert groups
# @return [Array]
attr_reader :alert_groups
@@ -43,7 +43,7 @@ module Mauve
# Various further configuration items
#
attr_reader :bytemark_auth_url, :bytemark_calendar_url, :remote_http_timeout, :remote_https_verify_mode, :failed_login_delay
- attr_reader :max_acknowledgement_time
+ attr_reader :max_acknowledgement_time, :working_hours, :dead_zone, :daytime_hours
#
@@ -66,23 +66,30 @@ module Mauve
#
# Set a couple of params for remote HTTP requests.
#
- @remote_http_timeout = 5
- @remote_https_verify_mode = OpenSSL::SSL::VERIFY_PEER
+ self.remote_http_timeout = 5
+ self.remote_https_verify_mode = "peer"
#
# Rate limit login attempts to limit the success of brute-forcing.
#
- @failed_login_delay = 1
+ self.failed_login_delay = 1
#
# Maximum amount of time to acknowledge for
#
- @max_acknowledgement_time = 15.days
+ self.max_acknowledgement_time = 15.days
+
+ #
+ # Working hours
+ #
+ self.dead_zone = 3...6
+ self.daytime_hours = 8...20
+ self.working_hours = 9...17
end
# Set the calendar URL.
#
- # @param [String] arg
+ # @param [String] arg
# @return [URI]
def bytemark_calendar_url=(arg)
raise ArgumentError, "bytemark_calendar_url must be a string" unless arg.is_a?(String)
@@ -104,7 +111,7 @@ module Mauve
# Set the Bytemark Authentication URL
#
- # @param [String] arg
+ # @param [String] arg
# @return [URI]
def bytemark_auth_url=(arg)
raise ArgumentError, "bytemark_auth_url must be a string" unless arg.is_a?(String)
@@ -128,7 +135,7 @@ module Mauve
# @param [Integer] arg
# @return [Integer]
def remote_http_timeout=(arg)
- raise ArgumentError, "remote_http_timeout must be an integer" unless s.is_a?(Integer)
+ raise ArgumentError, "remote_http_timeout must be an integer" unless arg.is_a?(Integer)
@remote_http_timeout = arg
end
@@ -156,7 +163,7 @@ module Mauve
raise ArgumentError, "failed_login_delay must be numeric" unless arg.is_a?(Numeric)
@failed_login_delay = arg
end
-
+
# Set the maximum amount of time alerts can be ack'd for
#
#
@@ -169,5 +176,85 @@ module Mauve
lambda{|at| CalendarInterface.get_attendees(x,at)}
end
+ def working_hours=(arg)
+ @working_hours = do_parse_range(arg)
+ end
+
+ def daytime_hours=(arg)
+ @daytime_hours = do_parse_range(arg)
+ end
+
+ def dead_zone=(arg)
+ @dead_zone = do_parse_range(arg)
+ end
+
+ private
+
+ # This method takes a range, and wraps it within the specs defined by
+ # allowed_range.
+ #
+ # It can take an array of Numerics, Strings, Ranges etc
+ #
+ # @param
+ #
+ def do_parse_range(arg, allowed_range = (0...24))
+ args = [arg].flatten
+
+ #
+ # Tidy up our allowed ranges
+ #
+ min = allowed_range.first
+ max = allowed_range.last
+
+ #
+ # If we've been given a numeric range, make sure they're all floats.
+ #
+ min = min.to_f if min.is_a?(Numeric)
+ max = max.to_f if max.is_a?(Numeric)
+
+ ranges = []
+
+ args.each do |arg|
+ case arg
+ when Range
+ from = arg.first
+ to = arg.last
+ exclude_end = arg.exclude_end?
+ else
+ from = arg
+ to = arg
+ end
+
+ from = min unless allowed_range.include?(from)
+
+ #
+ # In the case of integers, we want to match up until, but not including
+ # the next integer.
+ #
+ if to.is_a?(Integer)
+ to = (exclude_end ? to : to.succ)
+ exclude_end = true
+ end
+
+ to = max unless allowed_range.include?(to)
+
+ from = from.to_f if from.is_a?(Numeric)
+ to = to.to_f if to.is_a?(Numeric)
+
+ if from > to or (from >= to and exclude_end)
+ ranges << Range.new(from, max, allowed_range.exclude_end?)
+ ranges << Range.new(min, to, exclude_end)
+ else
+ ranges << Range.new(from, to, exclude_end)
+ end
+
+ end
+
+ ranges
+ end
+
+
end
+
+
end
diff --git a/lib/mauve/mauve_time.rb b/lib/mauve/mauve_time.rb
index dfbf99b..ab0734a 100644
--- a/lib/mauve/mauve_time.rb
+++ b/lib/mauve/mauve_time.rb
@@ -103,17 +103,38 @@ class Time
#
#
def bank_holidays
- @bank_holidays ||= []
+ @bank_holidays = if defined? Server and Server.instance
+ Server.instance.bank_holidays
+ else
+ @bank_holidays || []
+ end
end
- # This sets the bank holiday dates for the bank_holiday? check.
+ # Returns an array of ranges of working hours
#
- # @param [Array] arg An array of Date of bank holidays
- # @returns [Array]
#
- def bank_holidays=(arg)
- raise ArgumentError unless arg.is_a?(Array) and arg.all?{|a| a.is_a?(Date)}
- @bank_holidays = arg
+ def working_hours
+ if defined? Configuration and Configuration.current
+ Configuration.current.working_hours
+ else
+ [9.0...17.0]
+ end
+ end
+
+ def dead_zone
+ if defined? Configuration and Configuration.current
+ Configuration.current.working_hours
+ else
+ [3.0...7.0]
+ end
+ end
+
+ def daytime_hours
+ if defined? Configuration and Configuration.current
+ Configuration.current.working_hours
+ else
+ [8.0...20.0]
+ end
end
# This relies on bank_holidays being set.
@@ -128,14 +149,16 @@ class Time
#
# @return [Boolean]
def working_hours?
- !bank_holiday? and (1..5).include?(self.wday) and ((9..16).include?(self.hour) or (self.hour == 8 && self.min >= 30))
+ (1..5).include?(self.wday) and
+ self.working_hours.any?{|r| r.include?(self.hour.to_f + self.min.to_f/60.0)} and
+ !self.bank_holiday?
end
# Test to see if it is currently daytime. The daytime day is 14 hours long
#
# @return [Boolean]
def daytime_hours?
- (8..21).include?(self.hour)
+ self.daytime_hours.any?{|r| r.include?(self.hour.to_f + self.min.to_f/60.0)}
end
# We're always in wallclock hours
@@ -149,7 +172,7 @@ class Time
#
# @return [Boolean]
def dead_zone?
- (3..6).include?(self.hour)
+ self.dead_zone.any?{|r| r.include?(self.hour.to_f + self.min.to_f/60.0)}
end
# Format the time as a string, relative to +now+
diff --git a/lib/mauve/notification.rb b/lib/mauve/notification.rb
index 899972b..6ff9541 100644
--- a/lib/mauve/notification.rb
+++ b/lib/mauve/notification.rb
@@ -157,6 +157,18 @@ module Mauve
(@test_time - @alert.raised_at) >= seconds
end
+ # Tests if the alert has raised for a certain time.
+ #
+ # @param [Integer] seconds Number of seconds
+ # @return [Boolean]
+ def raised_for(seconds)
+ @test_time = @time if @test_time.nil?
+ @alert &&
+ @alert.raised? &&
+ (@test_time - @alert.raised_at) >= seconds
+ end
+
+
# Checks to see if x is contained in y
#
# @param [Array] y Array to search for +x+
@@ -177,10 +189,17 @@ module Mauve
# @return [Boolean]
def working_hours?
@test_time = @time if @test_time.nil?
- @test_time.bank_holidays = Server.instance.bank_holidays
@test_time.working_hours?
end
+ #
+ # Return true if today is a bank holiday
+ #
+ def bank_holiday?
+ @test_time = @time if @test_time.nil?
+ @test_time.bank_holiday?
+ end
+
# Test to see if we're in the dead zone. See Time#dead_zone?
#
# @return [Boolean]
@@ -189,6 +208,13 @@ module Mauve
@test_time.dead_zone?
end
+ #
+ # Return true if we're in daytime_hours. See Time#daytime_hours?
+ #
+ def daytime_hours?
+ @test_time = @time if @test_time.nil?
+ @test_time.daytime_hours?
+ end
end
# A Notification is an instruction to notify a person, or a list of people,
diff --git a/test/tc_mauve_configuration.rb b/test/tc_mauve_configuration.rb
new file mode 100644
index 0000000..bbc1901
--- /dev/null
+++ b/test/tc_mauve_configuration.rb
@@ -0,0 +1,38 @@
+$:.unshift "../lib/"
+
+require 'th_mauve'
+require 'mauve/configuration'
+
+class TcMauveConfiguration < Mauve::UnitTest
+ include Mauve
+
+ def setup
+ setup_logger
+ end
+
+ def teardown
+ teardown_logger
+ end
+
+ def test_do_parse_range
+ [
+ [[1.0...2.0], 1],
+ [[1.0...3.0], 1..2],
+ [[1.0...2.0], 1...2],
+ [[1.0...2.0, 4.0...7.0], [1, 4..6]],
+ [[1.0..1.0], 1.0],
+ [[1.0..2.0], 1.0..2.0],
+ [[1.0...2.0], 1.0...2.0],
+ [[1.0..1.0, 4.0..6.0], [1.0, 4.0..6.0]],
+ [[7.0...24.0, 0.0...7.0], 7..6],
+ [[6.0...7.0, 0.0...1.0], 6..0, 0...7],
+ [["x".."z", "a".."c"], "x".."c", "a".."z"]
+ ].each do |output, *input|
+ c = Configuration.new
+ assert_equal(output, c.__send__("do_parse_range",*input))
+ end
+ end
+
+end
+
+
diff --git a/test/tc_mauve_notification.rb b/test/tc_mauve_notification.rb
index 21ff41e..df8fa9b 100644
--- a/test/tc_mauve_notification.rb
+++ b/test/tc_mauve_notification.rb
@@ -224,6 +224,16 @@ EOF
logger_pop
end
+ def test_bank_holiday
+ time = Time.now
+
+ dr = DuringRunner.new(time)
+ assert(!dr.send(:bank_holiday?))
+
+ time.bank_holidays << Date.new(Time.now.year, Time.now.month, Time.now.day)
+ assert(dr.send(:bank_holiday?))
+ end
+
end
class TcMauveNotification < Mauve::UnitTest
diff --git a/test/tc_mauve_time.rb b/test/tc_mauve_time.rb
index 6e5989b..66cb4f7 100644
--- a/test/tc_mauve_time.rb
+++ b/test/tc_mauve_time.rb
@@ -16,8 +16,8 @@ class TestMauveTime < Mauve::UnitTest
#
# Working hours..
#
- hour_0 = Time.local(2011,6,6,8,30,0)
- hour_1 = Time.local(2011,6,6,9,30,0)
+ hour_0 = Time.local(2011,6,6,9,0,0)
+ hour_1 = Time.local(2011,6,6,10,0,0)
assert_equal(hour_1, t.in_x_hours(1,"working"))
assert_equal(hour_0, t.in_x_hours(0,"working"))
@@ -31,7 +31,7 @@ class TestMauveTime < Mauve::UnitTest
# Working hours..
#
hour_0 = Time.local(2011,6,3,16,45,32)
- hour_1 = Time.local(2011,6,6,9,15,32)
+ hour_1 = Time.local(2011,6,6,9,45,32)
assert_equal(hour_1, t.in_x_hours(1,"working"))
assert_equal(hour_0, t.in_x_hours(0,"working"))
@@ -41,10 +41,25 @@ class TestMauveTime < Mauve::UnitTest
x = Time.now
assert(!x.bank_holiday?)
-
x.bank_holidays << Date.new(x.year, x.month, x.day)
assert(x.bank_holiday?)
end
+ def test_dead_zone?
+ x = Time.local(2012,5,2,4,30,0)
+ assert(x.dead_zone?)
+
+ x = Time.local(2012,5,2,9,30,0)
+ assert(!x.dead_zone?)
+ end
+
+ def test_daytime_hours
+ x = Time.local(2012,5,2,4,30,0)
+ assert(!x.daytime_hours?)
+
+ x = Time.local(2012,5,2,9,30,0)
+ assert(x.daytime_hours?)
+ end
+
end