spec/lib/flapjack/coordinator_spec.rb in flapjack-0.6.38 vs spec/lib/flapjack/coordinator_spec.rb in flapjack-0.6.39

- old
+ new

@@ -1,16 +1,173 @@ require 'spec_helper' require 'flapjack/coordinator' describe Flapjack::Coordinator do - it "is initialized" + let(:fiber) { mock('Fiber') } - it "starts a suite of services based on config settings" + let(:config) { + {'redis' => {}, + 'executive' => {'enabled' => 'yes'}, + 'email_notifier' => {'enabled' => 'yes'}, + 'web' => {'enabled' => 'yes'} + } + } - it "runs daemonized" + before(:each) { + # temporary workaround for failing test due to preserved state; + # won't be needed soon as this code has been fixed in a branch + Flapjack::API.class_variable_set('@@redis', nil) + Flapjack::Web.class_variable_set('@@redis', nil) + } - it "runs undaemonized" + # leaving actual testing of daemonisation to that class's tests + it "daemonizes properly" do + fc = Flapjack::Coordinator.new(config) + fc.should_receive(:daemonize) + fc.should_not_receive(:build_pikelet) + fc.should_not_receive(:build_resque_pikelet) + fc.should_not_receive(:build_thin_pikelet) + fc.start(:daemonize => true, :signals => false) + end - it "stops its services when closing" + it "runs undaemonized" do + EM.should_receive(:synchrony).and_yield + + fc = Flapjack::Coordinator.new(config) + fc.should_receive(:build_pikelet) + fc.should_receive(:build_resque_pikelet) + fc.should_receive(:build_thin_pikelet) + fc.start(:daemonize => false, :signals => false) + end + + it "starts after daemonizing" do + EM.should_receive(:synchrony).and_yield + + fc = Flapjack::Coordinator.new(config) + fc.should_receive(:build_pikelet) + fc.should_receive(:build_resque_pikelet) + fc.should_receive(:build_thin_pikelet) + fc.after_daemonize + end + + it "traps system signals and shuts down" + + # TODO whem merged with other changes, this will check pik[:class] instead, + # having to create instances of the pikelet classes is messy + it "stops its services when closing" do + fiber_exec = mock('fiber_exec') + fiber_rsq = mock('fiber_rsq') + + exec = Flapjack::Executive.new + exec.should_receive(:add_shutdown_event) + email = EM::Resque::Worker.new('example') + email.should_receive(:shutdown) + web = Thin::Server.new('0.0.0.0', 3000, Flapjack::Web, :signals => false) + web.should_receive(:stop!) + + redis = mock('redis') + redis.should_receive(:quit) + Redis.should_receive(:new).and_return(redis) + + fiber.should_receive(:resume) + fiber_stop = mock('fiber_stop') + fiber_stop.should_receive(:resume) + Fiber.should_receive(:new).twice.and_yield.and_return(fiber, fiber_stop) + + fiber_exec.should_receive(:alive?).and_return(true, false) + fiber_rsq.should_receive(:alive?).and_return(true, false) + + EM.should_receive(:stop) + + pikelets = [{:fiber => fiber_exec, :instance => exec}, + {:fiber => fiber_rsq, :instance => email}, + {:instance => web}] + + fc = Flapjack::Coordinator.new + fc.instance_variable_set('@redis_options', {}) + fc.instance_variable_set('@pikelets', pikelets) + fc.stop + end + + it "creates an executive pikelet" do + exec = mock('executive') + exec.should_receive(:bootstrap) + Flapjack::Executive.should_receive(:new).and_return(exec) + exec.should_receive(:main) + + fiber.should_receive(:resume) + Fiber.should_receive(:new).and_yield.and_return(fiber) + + fc = Flapjack::Coordinator.new + fc.send(:build_pikelet, 'executive', {}) + pikelets = fc.instance_variable_get('@pikelets') + pikelets.should_not be_nil + pikelets.should be_an(Array) + pikelets.should have(1).pikelet + pikelets.first.should == {:fiber => fiber, :type => 'executive', :instance => exec} + end + + it "handles an exception raised by a jabber pikelet" do + jabber = mock('jabber') + jabber.should_receive(:bootstrap) + Flapjack::Jabber.should_receive(:new).and_return(jabber) + jabber.should_receive(:main).and_raise(RuntimeError) + + fiber.should_receive(:resume) + Fiber.should_receive(:new).and_yield.and_return(fiber) + + fc = Flapjack::Coordinator.new + fc.should_receive(:stop) + fc.send(:build_pikelet, 'jabber_gateway', {}) + pikelets = fc.instance_variable_get('@pikelets') + pikelets.should_not be_nil + pikelets.should be_an(Array) + pikelets.should have(1).pikelet + pikelets.first.should == {:fiber => fiber, :type => 'jabber_gateway', :instance => jabber} + end + + it "creates a resque worker pikelet" do + redis = mock('redis') + Flapjack::RedisPool.should_receive(:new).and_return(redis) + Resque.should_receive(:redis=).with(redis) + + worker = mock('worker') + EM::Resque::Worker.should_receive(:new).and_return(worker) + worker.should_receive(:work) + + fiber.should_receive(:resume) + Fiber.should_receive(:new).and_yield.and_return(fiber) + + fc = Flapjack::Coordinator.new + fc.send(:build_resque_pikelet, 'email_notifier', {}) + pikelets = fc.instance_variable_get('@pikelets') + pikelets.should_not be_nil + pikelets.should be_an(Array) + pikelets.should have(1).pikelet + pikelets.first.should == {:fiber => fiber, :type => 'email_notifier', :instance => worker} + end + + it "handles an exception raised by a resque worker pikelet" + + it "creates a thin server pikelet" do + redis = mock('redis') + Flapjack::RedisPool.should_receive(:new).and_return(redis) + + server = mock('server') + server.should_receive(:start) + Thin::Server.should_receive(:new). + with(/^(?:\d{1,3}\.){3}\d{1,3}$/, an_instance_of(Fixnum), Flapjack::Web, :signals => false). + and_return(server) + + fc = Flapjack::Coordinator.new + fc.send(:build_thin_pikelet, 'web', {}) + pikelets = fc.instance_variable_get('@pikelets') + pikelets.should_not be_nil + pikelets.should be_an(Array) + pikelets.should have(1).pikelet + pikelets.first.should == {:type => 'web', :instance => server} + end + + # NB: exceptions are handled directly by the Thin pikelets end \ No newline at end of file