require 'workers/stack_bootstrap_worker' 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 } before do allow(Provider::ProviderFactory).to receive(:providers).and_return(%w(ec2)) allow(worker).to receive(:update_report) allow(worker).to receive(:sync_stack) { true } allow(worker).to receive(:persist_stack_servers) { {1 => build_list(:server, 2)} } allow(worker).to receive(:bootstrap_servers_by_priority) { ServersBootstrapper::Result.new(0) } allow(stubbed_connector).to receive(:stack_insert) { Devops::Model::StackEc2.new(stack_attrs) } allow(Devops::Model::StackEc2).to receive(:create) 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 allow(worker).to receive(:create_stack).and_call_original expect(worker).to receive(:update_report).ordered expect(worker).to receive(:create_stack).ordered expect(worker).to receive(:persist_stack_servers).ordered perform_without_bootstrap 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) { ServersBootstrapper::Result.from_reason(:bootstrap_error) } expect_any_instance_of(Devops::Model::StackEc2).to receive(:delete_stack_in_cloud!) expect(stubbed_connector).to receive(:stack_servers_delete) expect(stubbed_connector).to receive(:stack_delete) 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) { ServersBootstrapper::Result.from_reason(: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) { ServersBootstrapper::Result.from_reason(: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 } allow(worker).to receive(:rollback_stack!) expect(worker).to receive(:rollback_stack!) expect{perform_with_bootstrap}.to raise_error(error) end end context "without stubbing methods", stubbed_connector: true do before do allow(worker).to receive(:sync_stack).and_call_original allow(worker).to receive(:persist_stack_servers).and_call_original allow(worker).to receive(:bootstrap_servers_by_priority).and_call_original allow(StackServersPersister).to receive(:new) { instance_double(StackServersPersister, persist: {1 => build_list(:server, 2)}) } allow(PrioritizedGroupsBootstrapper).to receive(:new) { instance_double(PrioritizedGroupsBootstrapper, bootstrap_servers_by_priority: ServersBootstrapper::Result.new(0)) } end it "return 0 if syncer returns ok" do allow(StackSynchronizer).to receive(:new) { instance_double(StackSynchronizer, sync: StackSynchronizer::SyncResult.new(0)) } expect(StackServersPersister).to receive(:new).with(instance_of(Devops::Model::StackEc2), anything) expect(perform_with_bootstrap).to eq 0 end it 'returns 1 if syncer returns error' do allow(StackSynchronizer).to receive(:new) { instance_double(StackSynchronizer, sync: StackSynchronizer::SyncResult.new(5)) } expect(perform_with_bootstrap).to eq 1 end end end