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(:perform_with_bootstrap) { worker.perform('stack_attributes' => stack_attrs) } let(:perform_without_bootstrap) { worker.perform('stack_attributes' => stack_attrs.merge('without_bootstrap' => true)) } let(:worker) { described_class.new } let(:executor) { instance_double(Devops::Executor::StackExecutor, wait_till_stack_is_created: true, create_stack: Devops::Model::StackEc2.new(stack_attrs), persist_stack_servers: nil, delete_stack: nil ) } def bootstrap_result(reason) Devops::Executor::StackExecutor::ServersBootstrapper::Result.from_reason(reason) end before do allow(worker).to receive(:update_report) allow(worker).to receive(:executor) { executor } allow(worker).to receive(:persist_stack_servers) { {1 => build_list(:server, 2)} } allow(worker).to receive(:bootstrap_servers_by_priority) { bootstrap_result(:ok) } 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(worker).to receive(:persist_stack_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 context 'if without_bootstrap is true' do it "doesn't bootstrap servers" do expect(worker).not_to receive(:bootstrap_servers_by_priority) perform_without_bootstrap end it 'returns 0' do expect(perform_without_bootstrap).to eq 0 end end context 'if without_bootstrap is false or not set' do it 'returns 0 when bootstraping servers was successful' do expect(perform_with_bootstrap).to eq 0 end it 'rollbacks stack and returns 2 when a known error occured during servers bootstrap' do allow(worker).to receive(:bootstrap_servers_by_priority) { bootstrap_result(:bootstrap_error) } expect(executor).to receive(:delete_stack) perform_with_bootstrap expect(perform_with_bootstrap).to eq 2 end it "doesn't rollback stack and returns 3 when a known error occured during servers deploy" do allow(worker).to receive(:bootstrap_servers_by_priority) { bootstrap_result(:deploy_error) } expect(worker).not_to receive(:rollback_stack!) expect(perform_with_bootstrap).to eq 3 end it "doesn't rollback stack and returns 3 when a servers bootstrap & deploy haven't been finished due to timeout" do allow(worker).to receive(:bootstrap_servers_by_priority) { bootstrap_result(:timeout_reached) } expect(worker).not_to receive(:rollback_stack!) expect(perform_with_bootstrap).to eq 4 end it 'rollbacks stack and reraises that error when an unknown error occured during servers bootsrap and deploy' do error = StandardError.new allow(worker).to receive(:bootstrap_servers_by_priority) { raise error } expect(worker).to receive(:rollback_stack!) expect{perform_with_bootstrap}.to raise_error(error) end end end