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