require 'lib/executors/server_executor' RSpec.describe Devops::Executor::ServerExecutor, type: :executor, stubbed_connector: true do let(:project) { build(:project) } let(:deploy_env) { project.deploy_env('foo') } let(:server) { build(:server, project: project.id, deploy_env: 'foo') } let(:output) { File.open(File::NULL, "w") } let(:executor) { described_class.new(server, output) } before do allow(stubbed_connector).to receive(:project) { project } end describe '#initialize' do it 'sets server, project, deploy_env, out instance variables' do expect(executor.server).to eq server expect(executor.deploy_env).to eq deploy_env expect(executor).to have_instance_variable_value(:project, project) expect(executor).to have_instance_variable_value(:out, output) end it 'set knife_instance instance variable' do allow(KnifeFactory).to receive(:instance) expect(executor).to be_instance_variable_defined(:@knife_instance) end it 'defines :flush method on @out if it is absent' do out = Class.new.new expect(out).not_to respond_to(:flush) described_class.new(server, out) expect(out).to respond_to(:flush) end it 'sets current_user from options' do user = double executor = described_class.new(server, '', {current_user: user}) expect(executor).to have_instance_variable_value(:current_user, user) end end describe '#create_server_object' do it 'builds Server object' do server = executor.create_server_object('created_by' => 'me') expect(server).to be_a(Devops::Model::Server) expect(server.project).to eq 'my_project' expect(server.deploy_env).to eq 'foo' expect(server.created_by).to eq 'me' end end describe '#create_server', stubbed_connector: true, stubbed_logger: true do let!(:without_bootstrap) { @without_bootstrap = true } let!(:run_list) { @run_list = %w(role[asd]) } let!(:key) { @key = 'key' } subject { executor.create_server( 'created_by' => 'user', 'run_list' => @run_list, 'name' => 'node_name', 'key' => @key, 'without_bootstrap' => @without_bootstrap ) } before do @provider = double('Provider instance') allow(executor.deploy_env).to receive(:provider_instance) { @provider } allow(@provider).to receive(:create_server) { true } @image = double('Image instance') allow(@image).to receive(:remote_user) { 'remote_user' } allow(stubbed_connector).to receive(:image) { @image} allow(stubbed_connector).to receive(:server_insert) end it 'builds server model from given options' do subject expect(executor.server.created_by).to eq 'user' expect(executor.server.chef_node_name).to eq 'node_name' expect(executor.server.key).to eq @key expect(executor.server.run_list).to eq @run_list end it 'sets run list to an empty array by default' do @run_list = nil subject expect(executor.server.run_list).to eq [] end it 'sets key to default provider ssh key by default' do @key = nil allow(@provider).to receive(:ssh_key) { 'default_key' } subject expect(executor.server.key).to eq 'default_key' end it 'runs hooks' do expect(executor).to receive(:run_hook).with(:before_create).ordered expect(executor).to receive(:run_hook).with(:after_create).ordered subject end it 'creates server in cloud' do expect(@provider).to receive(:create_server).with( an_instance_of(Devops::Model::Server), deploy_env.image, deploy_env.flavor, deploy_env.subnets, deploy_env.groups, output ) subject end it 'inserts built server into mongo' do expect(stubbed_connector).to receive(:server_insert) subject end it 'schedules expiration for server' do expect(executor).to receive(:schedule_expiration).with(an_instance_of(Devops::Model::Server)) subject end context 'without_bootstrap option is false' do it 'launches bootstrap' do @without_bootstrap = false allow(@image).to receive(:bootstrap_template) { 'template' } allow(executor).to receive(:two_phase_bootstrap) expect(executor).to receive(:two_phase_bootstrap) subject end end context 'without_bootstrap option is nil' do it 'launches bootstrap' do @without_bootstrap = nil allow(@image).to receive(:bootstrap_template) { 'template' } allow(executor).to receive(:two_phase_bootstrap) expect(executor).to receive(:two_phase_bootstrap) subject end end context 'without_bootstrap option is true' do it "doesn't launch bootstrap" do @without_bootstrap = true expect(executor).not_to receive(:two_phase_bootstrap) subject end end context 'if error has been raised during execution' do before do allow(stubbed_connector).to receive(:server_delete) allow(@provider).to receive(:create_server) { raise } end it 'rollbacks server creating' do expect(executor).to receive(:roll_back) subject end it 'deletes server from mongo' do expect(stubbed_connector).to receive(:server_delete) subject end end end end