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

- old
+ new

@@ -1,309 +1,255 @@ require 'spec_helper' - require 'flapjack/coordinator' describe Flapjack::Coordinator do - let(:fiber) { double(Fiber) } - let(:config) { double(Flapjack::Configuration) } + let(:config) { double(Flapjack::Configuration) } + let(:redis_config) { double('redis_config')} - let(:logger) { double(Flapjack::Logger) } - - let(:redis) { double(::Redis) } - let!(:time) { Time.now } it "starts and stops a pikelet" do - expect(Flapjack::Logger).to receive(:new).and_return(logger) - cfg = {'processor' => {'enabled' => true}} - expect(EM).to receive(:synchrony).and_yield - expect(config).to receive(:for_redis).and_return({}) + expect(config).to receive(:all).twice.and_return(cfg) - expect(redis).to receive(:keys).with('entity_tag:*').and_return([]) - expect(redis).to receive(:keys).with('check_tag:*').and_return([]) - expect(Flapjack::RedisPool).to receive(:new).and_return(redis) + expect(config).to receive(:for_redis).and_return(redis_config) + expect(Flapjack::RedisProxy).to receive(:config=).with(redis_config) processor = double('processor') expect(processor).to receive(:start) expect(processor).to receive(:stop) - expect(processor).to receive(:update_status) - expect(processor).to receive(:status).exactly(3).times.and_return('stopped') - expect(Time).to receive(:now).and_return(time) + running_cond = double(MonitorMixin::ConditionVariable) + expect(running_cond).to receive(:signal) - fc = Flapjack::Coordinator.new(config) - expect(Flapjack::Pikelet).to receive(:create).with('processor', - :config => cfg['processor'], :redis_config => {}, :boot_time => time). - and_return(processor) + monitor = double(Monitor) + expect(monitor).to receive(:synchronize).and_yield + expect(monitor).to receive(:new_cond).and_return(running_cond) + expect(Monitor).to receive(:new).and_return(monitor) - expect(EM).to receive(:stop) - expect(EM::Synchrony).to receive(:sleep) { - fc.instance_variable_set('@received_signals', ['INT']) - } - - expect(Syslog).to receive(:opened?).and_return(true) - expect(Syslog).to receive(:close) - - fc.start(:signals => false) - end - - it "handles an exception raised by a pikelet and shuts down" do - expect(Flapjack::Logger).to receive(:new).and_return(logger) - expect(logger).to receive(:fatal) - - cfg = {'processor' => {'enabled' => true}} - expect(EM).to receive(:synchrony).and_yield - expect(config).to receive(:for_redis).and_return({}) - expect(config).to receive(:all).twice.and_return(cfg) - - expect(redis).to receive(:keys).with('entity_tag:*').and_return([]) - expect(redis).to receive(:keys).with('check_tag:*').and_return([]) - expect(Flapjack::RedisPool).to receive(:new).and_return(redis) - - processor = double('processor') - expect(processor).to receive(:start).and_raise(RuntimeError) - expect(processor).to receive(:stop) - expect(processor).to receive(:update_status) - expect(processor).to receive(:status).exactly(3).times.and_return('stopped') - expect(Time).to receive(:now).and_return(time) fc = Flapjack::Coordinator.new(config) + expect(running_cond).to receive(:wait_until) { + fc.instance_variable_set('@state', :stopping) + } + expect(Flapjack::Pikelet).to receive(:create).with('processor', - :config => cfg['processor'], :redis_config => {}, :boot_time => time) - .and_return(processor) + an_instance_of(Proc), :config => cfg['processor'], + :boot_time => time). + and_return([processor]) - expect(EM).to receive(:stop) - - expect(Syslog).to receive(:opened?).and_return(true) - expect(Syslog).to receive(:close) - fc.start(:signals => false) end it "loads an old executive pikelet config block with no new data" do cfg = {'executive' => {'enabled' => true}} - expect(EM).to receive(:synchrony).and_yield - expect(config).to receive(:for_redis).and_return({}) + expect(config).to receive(:all).twice.and_return(cfg) - expect(redis).to receive(:keys).with('entity_tag:*').and_return([]) - expect(redis).to receive(:keys).with('check_tag:*').and_return([]) - expect(Flapjack::RedisPool).to receive(:new).and_return(redis) + expect(config).to receive(:for_redis).and_return(redis_config) + expect(Flapjack::RedisProxy).to receive(:config=).with(redis_config) processor = double('processor') expect(processor).to receive(:start) expect(processor).to receive(:stop) - expect(processor).to receive(:update_status) - expect(processor).to receive(:status).exactly(3).times.and_return('stopped') - notifier = double('processor') + notifier = double('notifier') expect(notifier).to receive(:start) expect(notifier).to receive(:stop) - expect(notifier).to receive(:update_status) - expect(notifier).to receive(:status).exactly(3).times.and_return('stopped') + running_cond = double(MonitorMixin::ConditionVariable) + expect(running_cond).to receive(:signal) + + monitor = double(Monitor) + expect(monitor).to receive(:synchronize).and_yield + expect(monitor).to receive(:new_cond).and_return(running_cond) + expect(Monitor).to receive(:new).and_return(monitor) + expect(Time).to receive(:now).and_return(time) + fc = Flapjack::Coordinator.new(config) + expect(running_cond).to receive(:wait_until) { + fc.instance_variable_set('@state', :stopping) + } + expect(Flapjack::Pikelet).to receive(:create).with('processor', - :config => cfg['executive'], :redis_config => {}, :boot_time => time). - and_return(processor) + an_instance_of(Proc), :config => cfg['executive'], + :boot_time => time). + and_return([processor]) expect(Flapjack::Pikelet).to receive(:create).with('notifier', - :config => cfg['executive'], :redis_config => {}, :boot_time => time). - and_return(notifier) + an_instance_of(Proc), :config => cfg['executive'], + :boot_time => time). + and_return([notifier]) - expect(EM).to receive(:stop) - expect(EM::Synchrony).to receive(:sleep) { - fc.instance_variable_set('@received_signals', ['INT']) - } - - expect(Syslog).to receive(:opened?).and_return(true) - expect(Syslog).to receive(:close) - fc.start(:signals => false) end it "loads an old executive pikelet config block with some new data" do cfg = {'executive' => {'enabled' => true}, 'processor' => {'foo' => 'bar'}, 'notifier' => {'enabled' => false} } - expect(EM).to receive(:synchrony).and_yield - expect(config).to receive(:for_redis).and_return({}) + expect(config).to receive(:all).twice.and_return(cfg) - expect(redis).to receive(:keys).with('entity_tag:*').and_return([]) - expect(redis).to receive(:keys).with('check_tag:*').and_return([]) - expect(Flapjack::RedisPool).to receive(:new).and_return(redis) + expect(config).to receive(:for_redis).and_return(redis_config) + expect(Flapjack::RedisProxy).to receive(:config=).with(redis_config) processor = double('processor') expect(processor).to receive(:start) expect(processor).to receive(:stop) - expect(processor).to receive(:update_status) - expect(processor).to receive(:status).exactly(3).times.and_return('stopped') + running_cond = double(MonitorMixin::ConditionVariable) + expect(running_cond).to receive(:signal) + + monitor = double(Monitor) + expect(monitor).to receive(:synchronize).and_yield + expect(monitor).to receive(:new_cond).and_return(running_cond) + expect(Monitor).to receive(:new).and_return(monitor) + expect(Time).to receive(:now).and_return(time) fc = Flapjack::Coordinator.new(config) - expect(Flapjack::Pikelet).to receive(:create).with('processor', - :config => cfg['executive'].merge(cfg['processor']), - :redis_config => {}, :boot_time => time). - and_return(processor) - - expect(EM).to receive(:stop) - expect(EM::Synchrony).to receive(:sleep) { - fc.instance_variable_set('@received_signals', ['INT']) + expect(running_cond).to receive(:wait_until) { + fc.instance_variable_set('@state', :stopping) } - expect(Syslog).to receive(:opened?).and_return(true) - expect(Syslog).to receive(:close) + expect(Flapjack::Pikelet).to receive(:create).with('processor', + an_instance_of(Proc), :config => cfg['processor'].merge('enabled' => true), + :boot_time => time). + and_return([processor]) fc.start(:signals => false) end it "traps system signals and shuts down" do - expect(Flapjack::Logger).to receive(:new).and_return(logger) - expect(RbConfig::CONFIG).to receive(:[]).with('host_os').and_return('darwin12.0.0') + expect(config).to receive(:all).and_return({}) + + thread = double(Thread) + expect(thread).to receive(:join).exactly(3).times + expect(Thread).to receive(:new).exactly(3).times.and_yield.and_return(thread) + expect(Kernel).to receive(:trap).with('INT').and_yield expect(Kernel).to receive(:trap).with('TERM').and_yield expect(Kernel).to receive(:trap).with('HUP').and_yield - expect(config).to receive(:all).and_return({}) - expect(config).to receive(:for_redis).and_return({}) + shutdown = double('shutdown') + expect(shutdown).to receive(:call).with(2).once + expect(shutdown).to receive(:call).with(15).once + reload = double('reload') + expect(reload).to receive(:call).once + fc = Flapjack::Coordinator.new(config) + fc.instance_variable_set('@shutdown', shutdown) + fc.instance_variable_set('@reload', reload) fc.send(:setup_signals) - expect(fc.instance_variable_get('@received_signals')).to eq(['INT', 'TERM', 'HUP']) end it "only traps two system signals on Windows" do - expect(Flapjack::Logger).to receive(:new).and_return(logger) - expect(RbConfig::CONFIG).to receive(:[]).with('host_os').and_return('mswin') + expect(config).to receive(:all).and_return({}) + + thread = double(Thread) + expect(thread).to receive(:join).twice + expect(Thread).to receive(:new).twice.and_yield.and_return(thread) + expect(Kernel).to receive(:trap).with('INT').and_yield expect(Kernel).to receive(:trap).with('TERM').and_yield expect(Kernel).not_to receive(:trap).with('HUP') - expect(config).to receive(:all).and_return({}) - expect(config).to receive(:for_redis).and_return({}) + shutdown = double('shutdown') + expect(shutdown).to receive(:call).with(2).once + expect(shutdown).to receive(:call).with(15).once + reload = double('reload') + fc = Flapjack::Coordinator.new(config) + fc.instance_variable_set('@shutdown', shutdown) + fc.instance_variable_set('@reload', reload) fc.send(:setup_signals) - expect(fc.instance_variable_get('@received_signals')).to eq(['INT', 'TERM']) end it "stops one pikelet and starts another on reload" do - expect(Flapjack::Logger).to receive(:new).and_return(logger) - old_cfg = {'processor' => {'enabled' => true}} new_cfg = {'gateways' => {'jabber' => {'enabled' => true}}} - new_config = double('new_config') - filename = double('filename') + expect(config).to receive(:all).exactly(3).times.and_return(old_cfg, old_cfg, new_cfg) + expect(config).to receive(:reload) - expect(config).to receive(:all).twice.and_return(old_cfg) - expect(config).to receive(:filename).and_return(filename) - - expect(Flapjack::Configuration).to receive(:new).and_return(new_config) - expect(new_config).to receive(:load).with(filename) - expect(new_config).to receive(:all).and_return(new_cfg) - processor = double('processor') - expect(processor).to receive(:type).twice.and_return('processor') + expect(processor).to receive(:type).and_return('processor') expect(processor).to receive(:stop) - expect(processor).to receive(:update_status) - expect(processor).to receive(:status).exactly(3).times.and_return('stopped') - expect(config).to receive(:for_redis).and_return({}) - fc = Flapjack::Coordinator.new(config) - jabber = double('jabber') expect(Flapjack::Pikelet).to receive(:create). - with('jabber', :config => {"enabled" => true}, :redis_config => {}, + with('jabber', an_instance_of(Proc), + :config => {"enabled" => true}, :boot_time => time). - and_return(jabber) + and_return([jabber]) expect(jabber).to receive(:start) + fc = Flapjack::Coordinator.new(config) + fc.instance_variable_set('@boot_time', time) fc.instance_variable_set('@pikelets', [processor]) fc.send(:reload) expect(fc.instance_variable_get('@pikelets')).to eq([jabber]) end it "reloads a pikelet config without restarting it" do - expect(Flapjack::Logger).to receive(:new).and_return(logger) - old_cfg = {'processor' => {'enabled' => true, 'foo' => 'bar'}} new_cfg = {'processor' => {'enabled' => true, 'foo' => 'baz'}} - new_config = double('new_config') - filename = double('filename') + expect(config).to receive(:all).exactly(3).times.and_return(old_cfg, old_cfg, new_cfg) + expect(config).to receive(:reload) - expect(config).to receive(:all).twice.and_return(old_cfg) - expect(config).to receive(:filename).and_return(filename) - - expect(Flapjack::Configuration).to receive(:new).and_return(new_config) - expect(new_config).to receive(:load).with(filename) - expect(new_config).to receive(:all).and_return(new_cfg) - processor = double('processor') expect(processor).not_to receive(:start) expect(processor).to receive(:type).exactly(3).times.and_return('processor') expect(processor).to receive(:reload).with(new_cfg['processor']).and_return(true) expect(processor).not_to receive(:stop) - expect(config).to receive(:for_redis).and_return({}) fc = Flapjack::Coordinator.new(config) fc.instance_variable_set('@boot_time', time) fc.instance_variable_set('@pikelets', [processor]) fc.send(:reload) expect(fc.instance_variable_get('@pikelets')).to eq([processor]) end it "reloads a pikelet config while restarting it" do - expect(Flapjack::Logger).to receive(:new).and_return(logger) - old_cfg = {'processor' => {'enabled' => true, 'foo' => 'bar'}} new_cfg = {'processor' => {'enabled' => true, 'baz' => 'qux'}} - new_config = double('new_config') - filename = double('filename') + expect(config).to receive(:all).exactly(3).times.and_return(old_cfg, old_cfg, new_cfg) + expect(config).to receive(:reload) - expect(config).to receive(:all).twice.and_return(old_cfg) - expect(config).to receive(:filename).and_return(filename) - - expect(Flapjack::Configuration).to receive(:new).and_return(new_config) - expect(new_config).to receive(:load).with(filename) - expect(new_config).to receive(:all).and_return(new_cfg) - processor = double('processor') expect(processor).to receive(:type).exactly(5).times.and_return('processor') expect(processor).to receive(:reload).with(new_cfg['processor']).and_return(false) expect(processor).to receive(:stop) - expect(processor).to receive(:update_status) - expect(processor).to receive(:status).exactly(3).times.and_return('stopped') - new_exec = double('new_executive') - expect(new_exec).to receive(:start) + new_processor = double('new_processor') + expect(new_processor).to receive(:start) - expect(config).to receive(:for_redis).and_return({}) fc = Flapjack::Coordinator.new(config) expect(Flapjack::Pikelet).to receive(:create). - with('processor', :config => new_cfg['processor'], :redis_config => {}, + with('processor', an_instance_of(Proc), + :config => new_cfg['processor'], :boot_time => time). - and_return(new_exec) + and_return([new_processor]) fc.instance_variable_set('@boot_time', time) fc.instance_variable_set('@pikelets', [processor]) fc.send(:reload) - expect(fc.instance_variable_get('@pikelets')).to eq([new_exec]) + expect(fc.instance_variable_get('@pikelets')).to eq([new_processor]) end end