fluke/devops-service/spec/executors/server_executor_spec.rb

277 lines
9.5 KiB
Ruby
Raw Normal View History

2015-12-21 18:23:17 +03:00
require 'lib/executors/server_executor'
2018-04-04 22:44:39 +03:00
require 'providers/aws/server_category_provider_aws'
require 'workers/delete_expired_server_worker'
2015-12-21 18:23:17 +03:00
2018-04-04 22:44:39 +03:00
RSpec.describe Devops::Executor::ServerExecutor, type: :executor, stubbed_logger: true do
2015-12-21 18:23:17 +03:00
let(:project) { build(:project) }
2018-04-04 22:44:39 +03:00
let(:environment) { build(:environment, id: 'foo') }
let(:category) { build(:category, id: 'name') }
let(:server) { build(:server, project: project.id, environment: 'foo', category: 'name') }
let(:output) { File.open(File::NULL, "w") }
2015-12-28 13:07:13 +03:00
let(:provider) { double('Provider instance') }
2018-04-04 22:44:39 +03:00
let(:current_user) { 'user' }
let(:executor) { described_class.new(server, output, current_user) }
let(:account_instance) { double('account instance', ssh_key: 'provider_key') }
let(:provider_instance) {
instance_double(Devops::Model::ServerCategoryProviderAws,
name: 'aws',
account: 'acc',
account_instance: account_instance,
image: build(:image),
create_server: true,
waiting_server: true,
flavor: 'flavor',
subnet: [],
security_groups: []
)
}
2015-12-21 18:23:17 +03:00
2015-12-28 13:07:13 +03:00
2015-12-21 18:23:17 +03:00
before do
2018-04-04 22:44:39 +03:00
allow(Devops::Model::Project).to receive(:find_with_environment) { project }
allow(Provider).to receive(:get_connector) { provider_instance }
allow(Provider).to receive(:create_category_provider) { provider_instance }
allow(project).to receive(:environment) { environment }
allow(environment).to receive(:get_category) { category }
executor.job_task = build(:task)
2015-12-21 18:23:17 +03:00
end
describe '#initialize' do
2018-04-04 22:44:39 +03:00
it 'sets server, project, environment, out instance variables' do
expect(executor.server).to eq server
2018-04-04 22:44:39 +03:00
expect(executor.environment).to eq environment
2015-12-21 18:23:17 +03:00
expect(executor).to have_instance_variable_value(:project, project)
expect(executor).to have_instance_variable_value(:out, output)
2015-12-21 18:23:17 +03:00
end
it 'defines :flush method on @out if it is absent' do
out = Class.new.new
expect(out).not_to respond_to(:flush)
2018-04-04 22:44:39 +03:00
described_class.new(server, out, current_user)
2015-12-21 18:23:17 +03:00
expect(out).to respond_to(:flush)
end
it 'sets current_user from options' do
2018-04-04 22:44:39 +03:00
executor = described_class.new(server, '', current_user)
expect(executor.current_user).to eq current_user
2015-12-21 18:23:17 +03:00
end
end
2018-04-04 22:44:39 +03:00
describe '#task=' do
it 'sets task instance variable' do
executor.job_task= 'foo'
expect(executor).to have_instance_variable_value(:job_task, 'foo')
end
end
describe '#project=' do
it 'sets project instance variable' do
executor.project= 'foo'
expect(executor).to have_instance_variable_value(:project, 'foo')
end
end
2015-12-21 18:23:17 +03:00
describe '#create_server_object' do
it 'builds Server object' do
2018-04-04 22:44:39 +03:00
server = executor.create_server_object({})
2015-12-21 18:23:17 +03:00
expect(server).to be_a(Devops::Model::Server)
expect(server.project).to eq 'my_project'
2018-04-04 22:44:39 +03:00
expect(server.environment).to eq 'foo'
expect(server.created_by).to eq current_user
end
it 'sets private_ip from options' do
server = executor.create_server_object('private_ip' => 'ip')
expect(server.private_ip).to eq 'ip'
2015-12-21 18:23:17 +03:00
end
end
2018-04-04 22:44:39 +03:00
describe '#create_server', clean_db_after_example: true do
2016-01-20 10:32:57 +03:00
let(:image) { double('Image instance', remote_user: 'remote_user') }
2018-04-04 22:44:39 +03:00
let(:run_list) { %w(role[asd]) }
2016-03-17 13:49:19 +03:00
let(:create_server_options) { {
2018-04-04 22:44:39 +03:00
'run_list' => run_list,
2016-03-17 13:49:19 +03:00
'name' => 'node_name',
2018-04-04 22:44:39 +03:00
'cm_name' => 'node_name',
'ssh_key' => 'key',
'without_bootstrap' => nil
2016-03-17 13:49:19 +03:00
} }
let(:create_server) { executor.create_server(create_server_options) }
before do
2015-12-28 13:07:13 +03:00
allow(provider).to receive(:create_server) { true }
allow(image).to receive(:bootstrap_template) { 'template' }
2018-04-04 22:44:39 +03:00
allow(Devops::Model::Image).to receive_message_chain('where.first') { build(:image) }
end
it 'builds server model from given options' do
2016-01-20 10:32:57 +03:00
create_server
2018-04-04 22:44:39 +03:00
expect(executor.server.created_by).to eq current_user
expect(executor.server.ssh_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
2018-04-04 22:44:39 +03:00
create_server_options.delete('run_list')
2016-01-20 10:32:57 +03:00
create_server
expect(executor.server.run_list).to eq []
end
it 'sets key to default provider ssh key by default' do
2018-04-04 22:44:39 +03:00
create_server_options.delete('ssh_key')
2016-01-20 10:32:57 +03:00
create_server
2018-04-04 22:44:39 +03:00
expect(executor.server.ssh_key).to eq 'provider_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
2016-01-20 10:32:57 +03:00
create_server
end
it 'creates server in cloud' do
2018-04-04 22:44:39 +03:00
built_server = build(:server)
allow(executor).to receive(:create_server_object) { built_server }
expect(provider_instance).to receive(:create_server).with(built_server, output)
2016-01-20 10:32:57 +03:00
create_server
end
it 'inserts built server into mongo' do
2018-04-04 22:44:39 +03:00
built_server = build(:server)
allow(executor).to receive(:create_server_object) { built_server }
expect(built_server).to receive(:save).at_least(1).times
2016-01-20 10:32:57 +03:00
create_server
end
it 'schedules expiration for server' do
2018-04-04 22:44:39 +03:00
environment.expires = '2m'
allow(DeleteExpiredServerWorker).to receive(:perform_in)
2016-03-09 15:44:57 +03:00
expect(DeleteExpiredServerWorker).to receive(:perform_in).with(120, hash_including(:server_id))
2016-01-20 10:32:57 +03:00
create_server
end
2018-04-04 22:44:39 +03:00
it "doesn't schedule expiration if environment.expires is nil" do
environment.expires = nil
expect(DeleteExpiredServerWorker).not_to receive(:perform_in)
2016-01-20 10:32:57 +03:00
create_server
end
context "when project is sandbox" do
2018-04-04 22:44:39 +03:00
pending 'it sets deployers to owner and passed deployers' do
allow(project).to receive(:is_sandbox?) { true }
create_server_options['project_info'] = {'deployers' => %w(user1 user2)}
expect(executor).to receive(:two_phase_bootstrap).with(hash_including(deployers: %w(me user1 user2)))
2016-01-20 10:32:57 +03:00
create_server
end
end
2015-12-28 13:07:13 +03:00
context "if creating server in cloud wasn't successful" do
2018-04-04 22:44:39 +03:00
it 'raises an error' do
allow(provider_instance).to receive(:create_server) { false }
expect{create_server}.to raise_error(Devops::Exception::CreationError)
2015-12-28 13:07:13 +03:00
end
end
end
2018-04-04 22:44:39 +03:00
describe '#bootstrap_server', clean_db_after_example: true do
2015-12-28 13:07:13 +03:00
let(:image) { double('Key instance', path: 'path') }
2018-04-04 22:44:39 +03:00
let(:bootstrap) { executor.bootstrap_server({}, {}) }
2015-12-28 13:07:13 +03:00
before do
allow(executor).to receive(:sleep)
allow(provider).to receive(:create_default_chef_node_name).and_return('chef_node')
2018-04-04 22:44:39 +03:00
allow(category).to receive(:cm_tool) { double('cm_tool', bootstrap_instance: nil) }
end
end
2018-04-04 22:44:39 +03:00
describe '#unbootstrap' do
it 'delegates to cm_tool' do
unbootstrap_result = double('unbootstrap result')
allow(category).to receive(:cm_tool) {
double('cm_tool', delete_instance: unbootstrap_result)
}
2018-04-04 22:44:39 +03:00
expect(executor.unbootstrap_server).to eq unbootstrap_result
end
end
describe '#rollback' do
before do
allow(server).to receive_message_chain('provider_instance.delete_server')
2018-04-04 22:44:39 +03:00
allow(category).to receive_message_chain('cm_tool.delete_instance')
end
it "does nothing if server.id is nil" do
server.id = nil
2018-04-04 22:44:39 +03:00
expect(category).not_to receive(:cm_tool)
expect(server).not_to receive(:provider_instance)
executor.roll_back
end
it 'deletes node from chef server and instance from cloud' do
2018-04-04 22:44:39 +03:00
expect(category).to receive_message_chain('cm_tool.delete_instance')
expect(server).to receive_message_chain('provider_instance.delete_server')
executor.roll_back
end
it "doesn't raise if deleting server in cloud raises an error" do
allow(server).to receive_message_chain('provider_instance.delete_server') { raise }
expect { executor.roll_back }.not_to raise_error
end
2016-01-19 13:36:29 +03:00
end
describe '#add_run_list_to_deploy_info' do
it "doesn't change deploy info if it already includes run list" do
deploy_info = {'run_list' => %w(foo)}
expect {
executor.add_run_list_to_deploy_info(output, deploy_info)
}.not_to change { deploy_info }
end
it 'computes and adds run_list to deploy_info' do
deploy_info = {}
allow(executor).to receive(:compute_run_list) { %w(foo) }
expect(executor).to receive(:compute_run_list)
executor.add_run_list_to_deploy_info(output, deploy_info)
expect(deploy_info['run_list']).to eq %w(foo)
end
end
describe '#compute_run_list' do
before do
2018-04-04 22:44:39 +03:00
allow(category).to receive_message_chain('provider_instance.run_list') { %w(a) }
project.run_list = %w(b)
2018-04-04 22:44:39 +03:00
environment.run_list = %w(c)
server.run_list = %w(d)
end
2018-04-04 22:44:39 +03:00
pending "returns array with run list merged from provider's, project's, env's and server's run lists" do
expect(executor.compute_run_list).to be_an(Array).and contain_exactly(*%w(a b c d))
end
2018-04-04 22:44:39 +03:00
pending "includes stack's run list if stack is set", stubbed_connector: true do
server.stack = 'stack'
allow(stubbed_connector).to receive(:stack) { instance_double(Devops::Model::StackEc2, run_list: %w(e)) }
expect(executor.compute_run_list).to be_an(Array).and contain_exactly(*%w(a b c d e))
end
2018-04-04 22:44:39 +03:00
pending "doesn't contain nils" do
server.run_list = nil
server.stack = 'stack'
allow(stubbed_connector).to receive(:stack) { instance_double(Devops::Model::StackEc2, run_list: nil) }
expect(executor.compute_run_list).to be_an(Array).and contain_exactly(*%w(a b c))
end
2018-04-04 22:44:39 +03:00
pending 'returns uniq elements' do
project.run_list = %w(a)
2018-04-04 22:44:39 +03:00
environment.run_list = %w(a)
expect(executor.compute_run_list).to be_an(Array).and contain_exactly(*%w(a d))
end
end
2018-04-04 22:44:39 +03:00
end