# encoding: utf-8 $:.unshift "../lib" require 'th_mauve' require 'th_mauve_resolv' require 'mauve/alert' require 'mauve/proto' require 'mauve/server' require 'mauve/configuration' require 'mauve/configuration_builder' require 'mauve/configuration_builders' class TcMauveAlert < Mauve::UnitTest include Mauve def setup super setup_database @test_config =< "test-host", :alert_id => "test_raise!", :subject => "test") a.raise! assert_equal(Time.now, a.raised_at) assert(a.raised?) assert(!a.cleared?) assert(!a.acknowledged?) end def test_acknowledge! person = Mauve::Person.new("test-user") Server.instance.setup Mauve::Configuration.current.people[person.username] = person alert = Alert.new( :alert_id => "test_acknowledge!", :source => "test", :subject => "test" ) alert.raise! logger_pop assert(alert.raised?) # # This acknowledges an alert for 3 mins. # alert.acknowledge!(person, Time.now + 3.minutes) logger_pop assert_equal(person.username, alert.acknowledged_by) assert_equal(Time.now, alert.acknowledged_at) assert_equal(Time.now + 3.minutes, alert.will_unacknowledge_at) assert(alert.acknowledged?) next_alert = Alert.find_next_with_event assert_equal(next_alert.id, alert.id) assert_equal(Time.now+3.minutes, next_alert.due_at) Timecop.freeze(Time.now + 3.minutes) # # The alert should unacknowledge itself. # alert.poll logger_pop assert(!alert.acknowledged?) end def test_unacknowledge! end def test_clear! end def test_due_at end def test_poll end def test_recieve_update Server.instance.setup update = Proto::AlertUpdate.new update.source = "test-host" message = Proto::Alert.new update.alert << message message.id = "test_recieve_update" message.summary = "test summary" message.detail = "test detail" message.raise_time = Time.now.to_i message.clear_time = Time.now.to_i+5.minutes Alert.receive_update(update, Time.now, "127.0.0.1") a = Alert.first(:alert_id => 'test_recieve_update') assert(a.raised?) assert_equal("test-host", a.subject) assert_equal("test-host", a.source) assert_equal("test detail", a.detail) assert_equal("test summary", a.summary) end def test_recieve_update_with_suppression Server.instance.setup update = Proto::AlertUpdate.new update.source = "test-host" message = Proto::Alert.new update.alert << message message.id = "test_recieve_update" # # If we send the same message every 2 minutes, with the suppress time # moving forward each time, it should get set once, and then stay the same # after that. # suppress_until = nil 5.times do |i| message.raise_time = Time.now.to_i message.suppress_until = Time.now.to_i + 10.minutes suppress_until = Time.now + 10.minutes if suppress_until.nil? Alert.receive_update(update, Time.now, "127.0.0.1") a = Alert.first(:alert_id => 'test_recieve_update') assert(a.raised?, "Alert not raised after a raised message has been sent") assert(a.suppressed?, "Alert has not been suppressed when the suppress_until value has been set") assert_equal(suppress_until, a.suppress_until, "The suppress until time has been set incorrectly when being raised repeatedly") Timecop.freeze(Time.now + 2.minute) end # # Ten minutes have passed == the suppression should have lapsed. # assert_equal(0, (Time.now - suppress_until).to_i, "Ten minutes have not elapsed!") a = Alert.first(:alert_id => 'test_recieve_update') assert(!a.suppressed?, "The alert is still suppressed past its suppress_until time") # # Try again -- the suppression has expired, but the alert is still raised. # This should not re-set the suppress_until value. # 5.times do message.suppress_until = Time.now.to_i + 10.minutes Alert.receive_update(update, Time.now, "127.0.0.1") a = Alert.first(:alert_id => 'test_recieve_update') assert(a.raised?) assert_equal(suppress_until, a.suppress_until) assert(!a.suppressed?) Timecop.freeze(Time.now + 2.minute) end # # Now on clear, we should be able to set the suppression time again. # suppress_until = Time.now + 10.minutes message.raise_time = nil message.clear_time = Time.now.to_i message.suppress_until = suppress_until.to_i Alert.receive_update(update, Time.now, "127.0.0.1") a = Alert.first(:alert_id => 'test_recieve_update') assert(a.cleared?) assert_equal(suppress_until, a.suppress_until) # # Now move on two minutes, and raise the alert. The suppression time should not move forward. # Timecop.freeze(Time.now + 2.minutes) 4.times do message.raise_time = Time.now.to_i message.suppress_until = Time.now.to_i + 10.minutes Alert.receive_update(update, Time.now, "127.0.0.1") a = Alert.first(:alert_id => 'test_recieve_update') assert(a.raised?) assert(a.suppressed?) assert_equal(suppress_until, a.suppress_until) Timecop.freeze(Time.now + 2.minute) end # # 10 minutes have now passed, The alert should no longer be suppressed. # assert_equal(0, (Time.now - suppress_until).to_i, "Ten minutes have not elapsed!") a = Alert.first(:alert_id => 'test_recieve_update') assert(!a.suppressed?, "The alert is still suppressed past its suppress_until time") # # Try again -- the suppression has expired, but the alert is still raised. # In this case the suppress_until time should not be moved on, until the # alert has cleared. # message.suppress_until = Time.now.to_i + 10.minutes Alert.receive_update(update, Time.now, "127.0.0.1") a = Alert.first(:alert_id => 'test_recieve_update') assert(a.raised?) assert_equal(suppress_until, a.suppress_until) assert(!a.suppressed?) # # Now clear, and the suppress time should be set back to nil. # message.raise_time = nil message.clear_time = Time.now.to_i message.suppress_until = nil Alert.receive_update(update, Time.now, "127.0.0.1") a = Alert.first(:alert_id => 'test_recieve_update') assert(a.cleared?) assert_equal(nil, a.suppress_until) assert(!a.suppressed?) end def test_notify_if_needed Configuration.current = ConfigurationBuilder.parse(@test_config) Server.instance.setup # # Notifications should be sent if: # # * the alert has changed state (update_type); or # * the alert new and "raised". alert = Alert.new( :alert_id => "test_notify_if_needed", :source => "test", :subject => "test" ) # # Must not notify -- this is a new alert which is not raised. # alert.clear! assert_equal(0, Server.instance.notification_buffer.size, "Notifications sent erroneously on clear.") # # Now raise. # alert.raise! assert_equal(1, Server.instance.notification_buffer.size, "Wrong number of notifications sent out when new alert raised.") # # Empty the buffer. Server.instance.notification_buffer.pop Timecop.freeze(Time.now+5) alert.raise! # # Should not re-raise. # assert_equal(0, Server.instance.notification_buffer.size, "Notification sent erroneously on second raise.") alert.acknowledge!(Mauve::Configuration.current.people["test"]) assert_equal(1, Server.instance.notification_buffer.size, "Wrong number of notifications sent erroneously on acknowledge.") # # Empty the buffer. Server.instance.notification_buffer.pop alert.subject = "changed subject" assert(alert.save) assert_equal(0, Server.instance.notification_buffer.size, "Notification sent erroneously on change of subject.") alert.clear! assert_equal(1, Server.instance.notification_buffer.size, "Wrong number of notifications sent erroneously on clear.") end # # These are more in-depth tests # def test_no_notification_for_old_alerts Configuration.current = ConfigurationBuilder.parse(@test_config) Server.instance.setup assert_equal(Time.now, Server.instance.started_at) Timecop.freeze(Time.now - 10.minutes) alert = Alert.new( :alert_id => "test_no_notification_for_old_alerts", :source => "test", :subject => "test", :will_raise_at => Time.now + 10.minutes ) alert.clear! Timecop.freeze(Time.now + 10.minutes) assert_equal(Time.now - 10.minutes, alert.updated_at, "Alert should be last updated before the server instance thinks it started.") 5.times do assert(Server.instance.in_initial_sleep?,"Server not in initial sleep when it should be.") alert.poll assert_equal(Server.instance.started_at + Server.instance.initial_sleep, alert.will_raise_at) assert_equal(0, Server.instance.notification_buffer.size, "Notification sent for old alert") Timecop.freeze(Time.now + 1.minute) end # # No longer in sleep period. # assert(!Server.instance.in_initial_sleep?,"Server in initial sleep when it shouldn't be.") alert.poll assert(alert.raised?) assert_equal(1, Server.instance.notification_buffer.size, "Notification sent for old alert") # # TODO need to do for will_clear_at and will_unacknowledge_at # end def test_heartbeats_during_clock_change updates = YAML.load_file(File.join(File.dirname(__FILE__),"bst_to_gmt.yaml")) Timecop.freeze(updates.first[1]-20.minutes) Configuration.current = ConfigurationBuilder.parse(@test_config) Server.instance.setup assert_equal(Time.now, Server.instance.started_at) updates.each do |update, received_at, source_ip| Timecop.freeze(received_at) Alert.receive_update(update, received_at, source_ip) alert = Alert.first assert(alert.cleared?) alert.poll assert(alert.cleared?) assert_equal(0, Server.instance.notification_buffer.length) end end def test_destroy_history_on_destroy Configuration.current = ConfigurationBuilder.parse(@test_config) Server.instance.setup alert = Alert.new( :alert_id => "test_destroy_history_on_destroy", :source => "test", :subject => "test" ) alert.save alert.raise! alert.reload assert_equal(1, History.all.length) Timecop.freeze(Time.now + 5.minutes) alert.clear! assert_equal(2, History.all.length) # # OK now we destroy the alert. Destory the histories too. # alert.destroy assert_equal(0, History.all.length) end def test_alert_suppression # # This is a bit of a duff test # Configuration.current = ConfigurationBuilder.parse(@test_config) Server.instance.setup alert = Alert.new( :alert_id => "test_alert_suppression1", :source => "test", :subject => "test", :suppress_until => Time.now + 5.minutes ) alert.save alert.reload assert_equal(Time.now + 5.minutes, alert.suppress_until) assert(alert.suppressed?) alert = Alert.new( :alert_id => "test_alert_suppression2", :source => "test", :subject => "test", :suppress_until => Time.now - 5.minutes ) alert.save alert.reload assert_equal(Time.now - 5.minutes, alert.suppress_until) assert(!alert.suppressed?,"Alert marked as suppressed when the suppression period has expired") alert = Alert.new( :alert_id => "test_alert_suppressio3", :source => "test", :subject => "test" ) alert.save alert.reload assert_equal(nil, alert.suppress_until) assert(!alert.suppressed?,"Alert marked as suppressed when the suppression period was never set") end def test_long_fields_get_truncated Configuration.current = ConfigurationBuilder.parse(@test_config) Server.instance.setup alert = Alert.new( :alert_id => "x"*257, :source => "test", :subject => "test" ) assert(alert.save, "Alert with overly long field failed to save") # This should trigger a warning. logger_pop alert.reload assert_equal(256, alert.alert_id.length) end def test_remove_html_utf_8 problem_string = "
This is a ûŧđ ™ message.\n\n

" fixed_string = Alert.remove_html(problem_string) assert_equal "This is a ûŧđ ™ message.", fixed_string.strip end def test_remove_html_invalid_character problem_string = "caf\xa9".force_encoding("ascii") fixed_string = Alert.remove_html(problem_string) assert_equal "caf?", fixed_string end end