spec/lib/flapjack/gateways/oobetet_spec.rb in flapjack-1.6.0 vs spec/lib/flapjack/gateways/oobetet_spec.rb in flapjack-2.0.0b1

- old
+ new

@@ -8,123 +8,195 @@ 'jabberid' => 'flapjack@example.com', 'password' => 'password', 'alias' => 'flapjack', 'watched_check' => 'PING', 'watched_entity' => 'foo.bar.net', + 'pagerduty_contact' => 'pdservicekey', 'rooms' => ['flapjacktest@conference.example.com'] } } - let(:stanza) { double('stanza') } + let(:now) { Time.now } - it "raises an error if a required config setting is not set" do - expect(Socket).to receive(:gethostname).and_return('thismachine') + let(:lock) { double(Monitor) } - fo = Flapjack::Gateways::Oobetet.new(:config => config.delete('watched_check'), :logger => @logger) + context 'notifications' do - expect { - fo.setup - }.to raise_error - end + it "raises an error if a required config setting is not set" do + expect { + Flapjack::Gateways::Oobetet::Notifier.new(:config => config.delete('watched_check')) + }.to raise_error("Flapjack::Oobetet: watched_check must be defined in the config") + end - it "hooks up event handlers to the appropriate methods" do - fo = Flapjack::Gateways::Oobetet.new(:config => config, :logger => @logger) + it "starts and is stopped by an exception" do + expect(Kernel).to receive(:sleep).with(10).and_raise(Flapjack::PikeletStop) - expect(EventMachine::Synchrony).to receive(:next_tick).exactly(3).times.and_yield + expect(lock).to receive(:synchronize).and_yield - expect(fo).to receive(:register_handler).with(:ready).and_yield(stanza) - expect(fo).to receive(:on_ready).with(stanza) + fon = Flapjack::Gateways::Oobetet::Notifier.new(:lock => lock, + :config => config) + expect(fon).to receive(:check_timers) + expect { fon.start }.to raise_error(Flapjack::PikeletStop) + end - expect(fo).to receive(:register_handler).with(:message, :groupchat?).and_yield(stanza) - expect(fo).to receive(:on_groupchat).with(stanza) + it "checks for a breach and emits notifications" do + time_check = double(Flapjack::Gateways::Oobetet::TimeChecker) + expect(time_check).to receive(:respond_to?).with(:announce).and_return(false) + expect(time_check).to receive(:respond_to?).with(:breach?).and_return(true) + expect(time_check).to receive(:breach?). + and_return("haven't seen a test problem notification in the last 300 seconds") - expect(fo).to receive(:register_handler).with(:disconnected).and_yield(stanza) - expect(fo).to receive(:on_disconnect).with(stanza).and_return(true) + bot = double(Flapjack::Gateways::Oobetet::Bot) + expect(bot).to receive(:respond_to?).with(:announce).and_return(true) + expect(bot).to receive(:announce).with(/^Flapjack Self Monitoring is Critical/) - fo.register_handlers - end + # TODO be more specific about the request body + req = stub_request(:post, "https://events.pagerduty.com/generic/2010-04-15/create_event.json"). + to_return(:status => 200, :body => Flapjack.dump_json('status' => 'success')) - it "joins a chat room after connecting" do - fo = Flapjack::Gateways::Oobetet.new(:config => config, :logger => @logger) + fon = Flapjack::Gateways::Oobetet::Notifier.new(:lock => lock, :config => config) + fon.instance_variable_set('@siblings', [time_check, bot]) + fon.send(:check_timers) - expect(fo).to receive(:write).with(an_instance_of(Blather::Stanza::Presence)) - expect(fo).to receive(:write).with(an_instance_of(Blather::Stanza::Message)) + expect(req).to have_been_requested + end - fo.on_ready(stanza) end - it "reconnects when disconnected (if not quitting)" do - fo = Flapjack::Gateways::Oobetet.new(:config => config, :logger => @logger) + context 'time checking' do - expect(EventMachine::Timer).to receive(:new).with(1).and_yield - expect(fo).to receive(:connect) + let(:now) { Time.now } + let(:a_minute_ago) { now.to_i - 60 } + let(:a_day_ago) { now.to_i - (60 * 60 * 24) } - ret = fo.on_disconnect(stanza) - expect(ret).to be true - end + it "starts and is stopped by a signal" do + expect(lock).to receive(:synchronize).and_yield + stop_cond = double(MonitorMixin::ConditionVariable) + expect(stop_cond).to receive(:wait_until) - it "records times of a problem status messages" do - fo = Flapjack::Gateways::Oobetet.new(:config => config, :logger => @logger) - fo.setup + fot = Flapjack::Gateways::Oobetet::TimeChecker.new(:lock => lock, :stop_condition => stop_cond, + :config => config) + fot.start + end - t = Time.now + it "records times of a problem status message" do + expect(lock).to receive(:synchronize).and_yield + fot = Flapjack::Gateways::Oobetet::TimeChecker.new(:lock => lock, :config => config) + fot.send(:receive_status, 'problem', now.to_i) + fot_times = fot.instance_variable_get('@times') + expect(fot_times).not_to be_nil + expect(fot_times).to have_key(:last_problem) + expect(fot_times[:last_problem]).to eq(now.to_i) + end - expect(stanza).to receive(:body).and_return( %q{PROBLEM: "PING" on foo.bar.net} ) - expect(Time).to receive(:now).and_return(t) + it "records times of a recovery status message" do + expect(lock).to receive(:synchronize).and_yield + fot = Flapjack::Gateways::Oobetet::TimeChecker.new(:lock => lock, :config => config) + fot.send(:receive_status, 'recovery', now.to_i) + fot_times = fot.instance_variable_get('@times') + expect(fot_times).not_to be_nil + expect(fot_times).to have_key(:last_recovery) + expect(fot_times[:last_recovery]).to eq(now.to_i) + end - fo.on_groupchat(stanza) - fo_times = fo.instance_variable_get('@times') - expect(fo_times).not_to be_nil - expect(fo_times).to have_key(:last_problem) - expect(fo_times[:last_problem]).to eq(t.to_i) - end + it "records times of an acknowledgement status message" do + expect(lock).to receive(:synchronize).and_yield + fot = Flapjack::Gateways::Oobetet::TimeChecker.new(:lock => lock, :config => config) + fot.send(:receive_status, 'acknowledgement', now.to_i) + fot_times = fot.instance_variable_get('@times') + expect(fot_times).not_to be_nil + expect(fot_times).to have_key(:last_ack) + expect(fot_times[:last_ack]).to eq(now.to_i) + end - it "records times of a recovery status messages" do - fo = Flapjack::Gateways::Oobetet.new(:config => config, :logger => @logger) - fo.setup + it "detects a time period with no test problem alerts" do + expect(lock).to receive(:synchronize).and_yield + fot = Flapjack::Gateways::Oobetet::TimeChecker.new(:lock => lock, :config => config) + fot_times = fot.instance_variable_get('@times') - t = Time.now + fot_times[:last_problem] = a_day_ago + fot_times[:last_recovery] = a_minute_ago + fot_times[:last_ack] = a_minute_ago + fot_times[:last_ack_sent] = a_minute_ago - expect(stanza).to receive(:body).and_return( %q{RECOVERY: "PING" on foo.bar.net} ) - expect(Time).to receive(:now).and_return(t) + breach = fot.breach?(now.to_i) + expect(breach).not_to be_nil + expect(breach).to eq("haven't seen a test problem notification in the last 300 seconds") + end - fo.on_groupchat(stanza) - fo_times = fo.instance_variable_get('@times') - expect(fo_times).not_to be_nil - expect(fo_times).to have_key(:last_recovery) - expect(fo_times[:last_recovery]).to eq(t.to_i) + it "detects a time period with no test recovery alerts" do + expect(lock).to receive(:synchronize).and_yield + fot = Flapjack::Gateways::Oobetet::TimeChecker.new(:lock => lock, :config => config) + fot_times = fot.instance_variable_get('@times') + + fot_times[:last_problem] = a_minute_ago + fot_times[:last_recovery] = a_day_ago + fot_times[:last_ack] = a_minute_ago + fot_times[:last_ack_sent] = a_minute_ago + + breach = fot.breach?(now.to_i) + expect(breach).not_to be_nil + expect(breach).to eq("haven't seen a test recovery notification in the last 300 seconds") + end + end - it "records times of an acknowledgement status messages" do - fo = Flapjack::Gateways::Oobetet.new(:config => config, :logger => @logger) - fo.setup + context 'XMPP' do - t = Time.now + let(:muc_client) { double(::Jabber::MUC::SimpleMUCClient) } - expect(stanza).to receive(:body).and_return( %q{ACKNOWLEDGEMENT: "PING" on foo.bar.net} ) - expect(Time).to receive(:now).and_return(t) + it "raises an error if a required config setting is not set" do + expect { + Flapjack::Gateways::Oobetet::Bot.new(:config => config.delete('watched_check')) + }.to raise_error("Flapjack::Oobetet: watched_check must be defined in the config") + end - fo.on_groupchat(stanza) - fo_times = fo.instance_variable_get('@times') - expect(fo_times).not_to be_nil - expect(fo_times).to have_key(:last_ack) - expect(fo_times[:last_ack]).to eq(t.to_i) - end + it "starts and is stopped by a signal" do + t = now.to_i - it "runs a loop checking for recorded problems" do - timer = double('timer') - expect(timer).to receive(:cancel) - expect(EM::Synchrony).to receive(:add_periodic_timer).with(60).and_return(timer) + time_checker = double(Flapjack::Gateways::Oobetet::TimeChecker) + expect(time_checker).to receive(:respond_to?).with(:receive_status).and_return(true) + expect(time_checker).to receive(:receive_status).with('recovery', t) - fo = Flapjack::Gateways::Oobetet.new(:config => config, :logger => @logger) - expect(fo).to receive(:register_handler).exactly(3).times - expect(fo).to receive(:connect) + client = double(::Jabber::Client) + expect(client).to receive(:connect) + expect(client).to receive(:auth).with('password') + expect(client).to receive(:send).with(an_instance_of(::Jabber::Presence)) - expect(EM::Synchrony).to receive(:sleep).with(10) { - fo.instance_variable_set('@should_quit', true) - nil - } + expect(muc_client).to receive(:on_message).and_yield(t, 'test', 'Recovery "PING" on foo.bar.net') + expect(muc_client).to receive(:join).with('flapjacktest@conference.example.com/flapjack') + expect(muc_client).to receive(:say).with(/^flapjack oobetet gateway started/) - fo.start + expect(muc_client).to receive(:active?).and_return(true) + expect(muc_client).to receive(:exit) + + expect(client).to receive(:close) + + expect(::Jabber::Client).to receive(:new).and_return(client) + expect(::Jabber::MUC::SimpleMUCClient).to receive(:new).and_return(muc_client) + + expect(lock).to receive(:synchronize).and_yield + stop_cond = double(MonitorMixin::ConditionVariable) + expect(stop_cond).to receive(:wait_until) + + fob = Flapjack::Gateways::Oobetet::Bot.new(:lock => lock, :stop_condition => stop_cond, + :config => config) + fob.instance_variable_set('@siblings', [time_checker]) + fob.start + end + + it "announces to jabber rooms" do + muc_client2 = double(::Jabber::MUC::SimpleMUCClient) + + expect(muc_client).to receive(:say).with('hello!') + expect(muc_client2).to receive(:say).with('hello!') + + expect(lock).to receive(:synchronize).and_yield + + fob = Flapjack::Gateways::Oobetet::Bot.new(:lock => lock, :config => config) + fob.instance_variable_set('@muc_clients', {'room1' => muc_client, 'room2' => muc_client2}) + fob.announce('hello!') + end + end end