require 'workers/stack_bootstrap_worker' require 'lib/executors/stack_executor' RSpec.describe StackBootstrapWorker, type: :worker, stubbed_connector: true, init_messages: true do let(:stack_attrs) { attributes_for(:stack_ec2).stringify_keys } let(:worker) { described_class.new } let(:perform_with_bootstrap) { worker.perform('stack_attributes' => stack_attrs) } let(:perform_without_bootstrap) { set_without_bootstrap_to(true) worker.perform('stack_attributes' => stack_attrs) } let(:executor) { instance_double(Devops::Executor::StackExecutor, wait_till_stack_is_created: true, persist_new_servers: nil, delete_stack: nil, bootstrap_just_persisted: bootstrap_result(:ok) ) } def bootstrap_result(reason) Devops::Executor::StackExecutor::PrioritizedGroupsBootstrapper::Result.from_reason(reason) end def set_without_bootstrap_to(value) stack_attrs.merge!('launch_options' => {'without_bootstrap' => value}) end def set_skip_rollback_to(value) stack_attrs.merge!('launch_options' => {'skip_rollback' => value}) end before do allow(worker).to receive(:update_report) allow(worker).to receive(:executor) { executor } allow(stubbed_connector).to receive(:unlock_persisting_stack) # #create_stack should be lazy evaluated because stack_attrs may change allow(executor).to receive(:create_stack) { Devops::Model::StackEc2.new(stack_attrs) } end it 'requires "stack_attributes" in options' do expect{ worker.perform({}) }.to raise_error KeyError end it 'updates report about operation' do expect(worker).to receive(:update_report) perform_without_bootstrap end it 'updates report about operation, creates stack and persists stack servers' do expect(worker).to receive(:update_report).ordered expect(executor).to receive(:create_stack).ordered expect(executor).to receive(:persist_new_servers).ordered perform_without_bootstrap end it "waits for stack creation to be completed" do expect(executor).to receive(:wait_till_stack_is_created) perform_with_bootstrap end it "returns 1 if waiting wasn't successful" do allow(executor).to receive(:wait_till_stack_is_created) { false } expect(perform_with_bootstrap).to eq 1 end it 'return 1 as a result of a block, not returning from #perform immediately' do allow(executor).to receive(:wait_till_stack_is_created) { false } allow(worker).to receive(:call) do |&block| block.call 'block_return_value' end expect(perform_with_bootstrap).to eq 'block_return_value' end context 'if without_bootstrap is true' do it "doesn't bootstrap servers" do expect(worker).not_to receive(:bootstrap_or_rollback_if_failed) perform_without_bootstrap end it 'returns 0' do expect(perform_without_bootstrap).to eq 0 end end context 'if without_bootstrap is false' do it 'returns 0 when bootstraping servers was successful' do expect(perform_with_bootstrap).to eq 0 end context "when a known error occured during servers bootstrap" do before do allow(executor).to receive(:bootstrap_just_persisted) { bootstrap_result(:bootstrap_error) } end it 'rollbacks stack and returns 1 if skip_rollback is false' do set_skip_rollback_to(false) expect(executor).to receive(:delete_stack) perform_with_bootstrap expect(perform_with_bootstrap).to eq 1 end it "doesn't rollback stack, but returns 1 if skip_rollback is true" do set_skip_rollback_to(true) expect(executor).not_to receive(:delete_stack) perform_with_bootstrap expect(perform_with_bootstrap).to eq 1 end end it "doesn't rollback stack and returns 2 when a known error occured during servers deploy" do allow(executor).to receive(:bootstrap_just_persisted) { bootstrap_result(:deploy_error) } expect(worker).not_to receive(:rollback_stack!) expect(perform_with_bootstrap).to eq 2 end context "when an unknown error occured during servers bootsrap and deploy" do let(:error) { StandardError.new } before do allow(executor).to receive(:bootstrap_just_persisted) { raise error } end it 'rollbacks stack and reraises that error if skip_rollback is false' do set_skip_rollback_to(false) expect(worker).to receive(:rollback_stack!) expect{perform_with_bootstrap}.to raise_error(error) end it "doesn't rollback stack, but reraises that error if skip_rollback is true" do set_skip_rollback_to(true) expect(worker).not_to receive(:rollback_stack!) expect{perform_with_bootstrap}.to raise_error(error) end end end end