require 'workers/stack_bootstrap/stack_synchronizer' RSpec.describe StackSynchronizer, stubbed_connector: true, init_messages: true do let(:out) { double(:out, puts: nil, flush: nil) } let(:stack) { build(:stack) } let(:syncer) { described_class.new(stack, out) } before do allow(stack).to receive(:sync!) allow(stack).to receive(:events).and_return( [{'event_id' => 1}] ) allow(syncer).to receive(:sleep) allow(stubbed_connector).to receive(:stack_update) end def setup_statuses(statuses_array) statuses = statuses_array.to_enum allow(stack).to receive(:sync!) { stack.stack_status = statuses.next } end describe '#sync', stubbed_logger: true do it 'waits for stack creating to be finished' do setup_statuses(['CREATE_IN_PROGRESS'] * 10 + ['CREATE_COMPLETE']) expect(syncer).to receive(:sleep).at_least(10).times expect(stack).to receive(:sync!).at_least(10).times syncer.sync end it 'prints each message only once' do event1 = {'event_id' => 1, 'timestamp' => 't1'} event2 = {'event_id' => 2, 'timestamp' => 't2'} event3 = {'event_id' => 3, 'timestamp' => 't3'} allow(stack).to receive(:events).and_return([event1], [event1, event2], [event1, event2, event3]) setup_statuses(['CREATE_IN_PROGRESS', 'CREATE_IN_PROGRESS', 'CREATE_IN_PROGRESS', 'CREATE_COMPLETE']) expect(syncer).to receive(:sleep).exactly(4).times expect(out).to receive(:puts).with(/t1/).once.ordered expect(out).to receive(:puts).with(/t2/).once.ordered expect(out).to receive(:puts).with(/t3/).once.ordered syncer.sync end it 'updates stack when status is changed' do setup_statuses(['CREATE_IN_PROGRESS', 'CREATE_IN_PROGRESS', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_COMPLETE']) expect(stubbed_connector).to receive(:stack_update).exactly(3).times syncer.sync end context 'when stack creating was successful' do it 'updates stack in DB when stack creating is finished and returns 0' do setup_statuses(['CREATE_COMPLETE']) expect(stubbed_connector).to receive(:stack_update).with(stack) expect(out).to receive(:puts).with(/CREATE_COMPLETE/) expect(syncer.sync).to be_ok end end context 'when stack was rollbacked' do it 'returns 1 (:stack_rolled_back)' do setup_statuses(['CREATE_IN_PROGRESS', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_COMPLETE']) expect(out).to receive(:puts).with(/ROLLBACK_COMPLETE/) expect(syncer.sync).to be_stack_rolled_back end end context 'when unkown stack status was found' do it 'returns 2 (:unkown_status)' do setup_statuses(['CREATE_IN_PROGRESS', 'unknown']) expect(out).to receive(:puts).with(/unknown/) expect(syncer.sync).to be_unkown_status end end context "when stack hasn't been synced in an hour" do it 'returns 3 (:timeout)' do allow(stack).to receive(:stack_status) {'CREATE_IN_PROGRESS'} expect(out).to receive(:puts).with(/hasn't been synced/) expect(syncer.sync).to be_timeout end end context 'when an error occured during syncing', stubbed_logger: true do it 'returns 5 (:error)' do setup_statuses(['CREATE_IN_PROGRESS', 'CREATE_COMPLETE']) allow(stubbed_connector).to receive(:stack_update) { raise } expect(syncer.sync.code).to eq 5 end end end end