require 'lib/executors/stack_executor/servers_bootstrapper'
class Devops::Executor::StackExecutor
  RSpec.describe ServersBootstrapper, init_messages: true do
    let(:out) { double(:out, puts: nil, flush: nil) }
    let(:jid) { 1000 }
    let(:servers) { [build(:server, id: 'a'), build(:server, id: 'b')] }
    let(:bootstrapper) { described_class.new(out, jid, servers ) }
    let(:bootstrap_job_ids) { %w(100 200) }
    let(:task) { build(:task) }

    describe '#bootstrap_group' do
      before do
        allow(Worker).to receive(:start_async).and_return(*bootstrap_job_ids)
        allow_any_instance_of(Devops::Helpers::JobWaiter).to receive(:wait) { 0 }
        allow(Devops::Model::JobTask).to receive(:find) { task }
        allow(task).to receive(:add_subtasks)
       end

      it 'start bootstrap workers and add subtasks' do
        expect(Worker).to receive(:start_async).with(BootstrapWorker, hash_including(:server_id, :bootstrap_template, :owner))
        allow(task).to receive(:add_subtasks).and_call_original
        expect(task).to receive(:add_subtasks).with(jid, bootstrap_job_ids)
        bootstrapper.bootstrap_group
      end

      it 'returns :ok result if everything ok' do
        expect( bootstrapper.bootstrap_group.first.reason ).to eq :ok
      end

      it 'returns proper error results' do
        waiter = instance_double(Devops::Helpers::JobWaiter)
        allow(waiter).to receive(:wait).and_return(2, 8)
        allow(Devops::Helpers::JobWaiter).to receive(:new) { waiter }
        expect( bootstrapper.bootstrap_group.map(&:reason) ).to eq [:bootstrap_error, :deploy_error]
      end

      it "returns :timeout_reached result if bootstrap and deploy hasn't been finished in 5000 seconds" do
        allow_any_instance_of(Devops::Helpers::JobWaiter).to receive(:wait) {
          raise Devops::Helpers::JobWaiter::TimeoutReached
        }
        expect( bootstrapper.bootstrap_group.first.reason ).to eq :timeout_reached
      end
    end
  end
end
