| 
									
										
										
										
											2015-12-21 18:23:17 +03:00
										 |  |  | require 'lib/executors/server_executor' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-29 16:10:05 +03:00
										 |  |  | RSpec.describe Devops::Executor::ServerExecutor, type: :executor, stubbed_connector: true, stubbed_logger: true do | 
					
						
							| 
									
										
										
										
											2015-12-21 18:23:17 +03:00
										 |  |  |   let(:project) { build(:project) } | 
					
						
							|  |  |  |   let(:deploy_env) { project.deploy_env('foo') } | 
					
						
							|  |  |  |   let(:server) { build(:server, project: project.id, deploy_env: 'foo') } | 
					
						
							| 
									
										
										
										
											2015-12-24 18:51:52 +03:00
										 |  |  |   let(:output) { File.open(File::NULL, "w") } | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  |   let(:provider) { double('Provider instance') } | 
					
						
							| 
									
										
										
										
											2015-12-24 18:51:52 +03:00
										 |  |  |   let(:executor) { described_class.new(server, output) } | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  |     allow(stubbed_connector).to receive(:project) { project } | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  |     allow(executor.deploy_env).to receive(:provider_instance) { provider } | 
					
						
							|  |  |  |     allow(server).to receive(:provider_instance) { provider } | 
					
						
							| 
									
										
										
										
											2015-12-21 18:23:17 +03:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe '#initialize' do | 
					
						
							|  |  |  |     it 'sets server, project, deploy_env, out instance variables' do | 
					
						
							| 
									
										
										
										
											2015-12-24 18:51:52 +03:00
										 |  |  |       expect(executor.server).to eq server | 
					
						
							|  |  |  |       expect(executor.deploy_env).to eq deploy_env | 
					
						
							| 
									
										
										
										
											2015-12-21 18:23:17 +03:00
										 |  |  |       expect(executor).to have_instance_variable_value(:project, project) | 
					
						
							| 
									
										
										
										
											2015-12-24 18:51:52 +03:00
										 |  |  |       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) | 
					
						
							|  |  |  |       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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-19 16:17:06 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-19 17:44:10 +03:00
										 |  |  |   describe '#report=' do | 
					
						
							|  |  |  |     it 'sets report instance variable' do | 
					
						
							|  |  |  |       executor.report= 'foo' | 
					
						
							|  |  |  |       expect(executor).to have_instance_variable_value(:report, '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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-19 16:17:06 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-31 17:52:11 +03:00
										 |  |  |   describe '.reason_from_error_code' do | 
					
						
							| 
									
										
										
										
											2016-01-19 14:29:34 +03:00
										 |  |  |     it 'returns symbol given an integer' do | 
					
						
							| 
									
										
										
										
											2016-01-31 17:52:11 +03:00
										 |  |  |       expect(described_class.reason_from_error_code(2)).to eq :server_bootstrap_fail | 
					
						
							| 
									
										
										
										
											2016-01-19 14:29:34 +03:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "returns :unknown_error if can't recognize error code" do | 
					
						
							| 
									
										
										
										
											2016-01-31 17:52:11 +03:00
										 |  |  |       expect(described_class.reason_from_error_code(123)).to eq :unknown_error | 
					
						
							| 
									
										
										
										
											2016-01-19 14:29:34 +03:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-19 16:17:06 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-21 18:23:17 +03:00
										 |  |  |   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 | 
					
						
							| 
									
										
										
										
											2015-12-24 18:51:52 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-19 16:17:06 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-29 16:10:05 +03:00
										 |  |  |   describe '#create_server' do | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |     let(:image) { double('Image instance', remote_user: 'remote_user') } | 
					
						
							|  |  |  |     let(:create_server) { | 
					
						
							| 
									
										
										
										
											2015-12-24 18:51:52 +03:00
										 |  |  |       executor.create_server( | 
					
						
							|  |  |  |         'created_by' => 'user', | 
					
						
							|  |  |  |         'run_list' => @run_list, | 
					
						
							|  |  |  |         'name' => 'node_name', | 
					
						
							|  |  |  |         'key' => @key, | 
					
						
							|  |  |  |         'without_bootstrap' => @without_bootstrap | 
					
						
							|  |  |  |       ) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     before do | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  |       allow(provider).to receive(:create_server) { true } | 
					
						
							|  |  |  |       allow(stubbed_connector).to receive(:image) { image } | 
					
						
							| 
									
										
										
										
											2015-12-24 18:51:52 +03:00
										 |  |  |       allow(stubbed_connector).to receive(:server_insert) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |       @without_bootstrap = true | 
					
						
							|  |  |  |       @run_list = %w(role[asd]) | 
					
						
							|  |  |  |       @key = 'key' | 
					
						
							| 
									
										
										
										
											2015-12-24 18:51:52 +03:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it 'builds server model from given options' do | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |       create_server | 
					
						
							| 
									
										
										
										
											2015-12-24 18:51:52 +03:00
										 |  |  |       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 | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |       create_server | 
					
						
							| 
									
										
										
										
											2015-12-24 18:51:52 +03:00
										 |  |  |       expect(executor.server.run_list).to eq [] | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it 'sets key to default provider ssh key by default' do | 
					
						
							|  |  |  |       @key = nil | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  |       allow(provider).to receive(:ssh_key) { 'default_key' } | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |       create_server | 
					
						
							| 
									
										
										
										
											2015-12-24 18:51:52 +03:00
										 |  |  |       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 | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |       create_server | 
					
						
							| 
									
										
										
										
											2015-12-24 18:51:52 +03:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it 'creates server in cloud' do | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  |       expect(provider).to receive(:create_server).with( | 
					
						
							| 
									
										
										
										
											2015-12-24 18:51:52 +03:00
										 |  |  |         an_instance_of(Devops::Model::Server), deploy_env.image, deploy_env.flavor, deploy_env.subnets, deploy_env.groups, output | 
					
						
							|  |  |  |       ) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |       create_server | 
					
						
							| 
									
										
										
										
											2015-12-24 18:51:52 +03:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it 'inserts built server into mongo' do | 
					
						
							|  |  |  |       expect(stubbed_connector).to receive(:server_insert) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |       create_server | 
					
						
							| 
									
										
										
										
											2015-12-24 18:51:52 +03:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it 'schedules expiration for server' do | 
					
						
							| 
									
										
										
										
											2016-01-19 17:44:10 +03:00
										 |  |  |       deploy_env.expires = '2m' | 
					
						
							| 
									
										
										
										
											2016-02-02 10:34:17 +03:00
										 |  |  |       allow(DeleteExpiredServerWorker).to receive(:perform_in) | 
					
						
							|  |  |  |       expect(DeleteExpiredServerWorker).to receive(:perform_in).with(120, {server_chef_node_name: 'node_name'}) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |       create_server | 
					
						
							| 
									
										
										
										
											2016-01-19 17:44:10 +03:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "doesn't schedule expiration if deploy_env.expires is nil" do | 
					
						
							|  |  |  |       deploy_env.expires = nil | 
					
						
							| 
									
										
										
										
											2016-02-02 10:34:17 +03:00
										 |  |  |       expect(DeleteExpiredServerWorker).not_to receive(:perform_in) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |       create_server | 
					
						
							| 
									
										
										
										
											2015-12-24 18:51:52 +03:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context 'without_bootstrap option is false' do | 
					
						
							|  |  |  |       it 'launches bootstrap' do | 
					
						
							|  |  |  |         @without_bootstrap = false | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  |         allow(image).to receive(:bootstrap_template) { 'template' } | 
					
						
							| 
									
										
										
										
											2015-12-24 18:51:52 +03:00
										 |  |  |         allow(executor).to receive(:two_phase_bootstrap) | 
					
						
							|  |  |  |         expect(executor).to receive(:two_phase_bootstrap) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |         create_server | 
					
						
							| 
									
										
										
										
											2015-12-24 18:51:52 +03:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context 'without_bootstrap option is nil' do | 
					
						
							|  |  |  |       it 'launches bootstrap' do | 
					
						
							|  |  |  |         @without_bootstrap = nil | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  |         allow(image).to receive(:bootstrap_template) { 'template' } | 
					
						
							| 
									
										
										
										
											2015-12-24 18:51:52 +03:00
										 |  |  |         allow(executor).to receive(:two_phase_bootstrap) | 
					
						
							|  |  |  |         expect(executor).to receive(:two_phase_bootstrap) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |         create_server | 
					
						
							| 
									
										
										
										
											2015-12-24 18:51:52 +03:00
										 |  |  |       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) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |         create_server | 
					
						
							| 
									
										
										
										
											2015-12-24 18:51:52 +03:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context 'if error has been raised during execution' do | 
					
						
							|  |  |  |       before do | 
					
						
							|  |  |  |         allow(stubbed_connector).to receive(:server_delete) | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  |         allow(provider).to receive(:create_server) { raise } | 
					
						
							| 
									
										
										
										
											2015-12-24 18:51:52 +03:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it 'rollbacks server creating' do | 
					
						
							|  |  |  |         expect(executor).to receive(:roll_back) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |         create_server | 
					
						
							| 
									
										
										
										
											2015-12-24 18:51:52 +03:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it 'deletes server from mongo' do | 
					
						
							|  |  |  |         expect(stubbed_connector).to receive(:server_delete) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |         create_server | 
					
						
							| 
									
										
										
										
											2015-12-24 18:51:52 +03:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context "if creating server in cloud wasn't successful" do | 
					
						
							| 
									
										
										
										
											2015-12-29 16:10:05 +03:00
										 |  |  |       it 'returns creating_server_in_cloud_failed error code' do | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  |         allow(provider).to receive(:create_server) { false } | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |         expect(create_server).to eq 10
 | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-29 16:10:05 +03:00
										 |  |  |   describe '#bootstrap', stubbed_knife: true do | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  |     let(:image) { double('Key instance', path: 'path') } | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |     let(:bootstrap) { executor.bootstrap({}) } | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     before do | 
					
						
							|  |  |  |       allow(executor).to receive(:sleep) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:23:34 +03:00
										 |  |  |       allow(executor).to receive(:last_command_successful?).and_return(true) | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  |       allow(executor).to receive(:execute_system_command) | 
					
						
							|  |  |  |       allow(provider).to receive(:create_default_chef_node_name).and_return('chef_node') | 
					
						
							|  |  |  |       allow(stubbed_connector).to receive(:key).and_return(image) | 
					
						
							|  |  |  |       allow(stubbed_connector).to receive(:server_set_chef_node_name) | 
					
						
							|  |  |  |       allow(stubbed_knife).to receive(:knife_bootstrap).and_return(0) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it 'run before hook' do | 
					
						
							|  |  |  |       expect(executor).to receive(:run_hook).with(:before_bootstrap, output).ordered | 
					
						
							|  |  |  |       expect(executor).to receive(:run_hook).with(:after_bootstrap, output).ordered | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |       bootstrap | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context "when server's private ip is unset" do | 
					
						
							| 
									
										
										
										
											2015-12-29 16:10:05 +03:00
										 |  |  |       it 'returns server_bootstrap_private_ip_unset error code' do | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  |         server.private_ip = nil | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |         expect(bootstrap).to eq 4
 | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2015-12-24 18:51:52 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  |     it 'tries to ssh to server' do | 
					
						
							|  |  |  |       expect(executor).to receive(:execute_system_command).with(/ssh/) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |       bootstrap | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context "couldn't ssh to server" do | 
					
						
							| 
									
										
										
										
											2016-01-20 10:23:34 +03:00
										 |  |  |       before { allow(executor).to receive(:last_command_successful?) { false } } | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it 'tries to ssh to server maximum MAX_SSH_RETRIES_AMOUNT times' do | 
					
						
							|  |  |  |         max_retries = Devops::Executor::ServerExecutor::MAX_SSH_RETRIES_AMOUNT | 
					
						
							|  |  |  |         expect(executor).to receive(:execute_system_command).exactly(max_retries).times | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |         bootstrap | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-29 16:10:05 +03:00
										 |  |  |       it 'returns server_bootstrap_fail error code' do | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |         expect(bootstrap).to eq 2
 | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context 'after successful ssh check' do | 
					
						
							| 
									
										
										
										
											2016-01-20 10:23:34 +03:00
										 |  |  |       before { allow(executor).to receive(:last_command_successful?).and_return(false, true) } | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it "sets default chef node name if it's nil" do | 
					
						
							|  |  |  |         executor.server.chef_node_name = nil | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |         expect {bootstrap}.to change {executor.server.chef_node_name}.to 'chef_node' | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it 'executes knife bootstrap' do | 
					
						
							|  |  |  |         expect(stubbed_knife).to receive(:knife_bootstrap).with(output, server.private_ip, instance_of(Array)) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |         bootstrap | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it "bootstraps to public ip if it's set" do | 
					
						
							|  |  |  |         server.public_ip = '8.8.8.8' | 
					
						
							|  |  |  |         expect(stubbed_knife).to receive(:knife_bootstrap).with(output, '8.8.8.8', instance_of(Array)) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |         bootstrap | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       context 'after successful bootstrap' do | 
					
						
							|  |  |  |         it "updates server's chef node name in db" do | 
					
						
							|  |  |  |           expect(stubbed_connector).to receive(:server_set_chef_node_name).with(instance_of(Devops::Model::Server)) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |           bootstrap | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       context "if bootstraping wasn't successful" do | 
					
						
							|  |  |  |         before { allow(stubbed_knife).to receive(:knife_bootstrap).and_return(123) } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-29 16:10:05 +03:00
										 |  |  |         it 'returns :server_bootstrap_fail code' do | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |           expect(bootstrap).to eq 2
 | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it "doesn't run after hook" do | 
					
						
							|  |  |  |           expect(executor).to receive(:run_hook).with(:before_bootstrap, output) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |           bootstrap | 
					
						
							| 
									
										
										
										
											2015-12-28 13:07:13 +03:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2015-12-24 18:51:52 +03:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2015-12-29 16:10:05 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-19 16:17:06 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-29 16:10:05 +03:00
										 |  |  |   describe '#two_phase_bootstrap', stubbed_knife: true do | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |     let(:two_phase_bootstrap) { executor.two_phase_bootstrap({}) } | 
					
						
							| 
									
										
										
										
											2015-12-29 16:10:05 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     before do | 
					
						
							|  |  |  |       allow(provider).to receive(:run_list) {[]} | 
					
						
							|  |  |  |       allow(stubbed_connector).to receive(:server_delete) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context 'when bootstrap was successful' do | 
					
						
							|  |  |  |       before do | 
					
						
							|  |  |  |         allow(executor).to receive(:bootstrap) { 0 } | 
					
						
							|  |  |  |         allow(executor).to receive(:check_server_on_chef_server) { false } | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       context 'if node presents on chef server' do | 
					
						
							|  |  |  |         before do | 
					
						
							|  |  |  |           allow(executor).to receive(:check_server_on_chef_server) { true } | 
					
						
							|  |  |  |           allow(executor).to receive(:deploy_server) | 
					
						
							|  |  |  |           allow(stubbed_knife).to receive(:set_run_list) | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it 'builds run list' do | 
					
						
							|  |  |  |           expect(executor).to receive(:compute_run_list) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |           two_phase_bootstrap | 
					
						
							| 
									
										
										
										
											2015-12-29 16:10:05 +03:00
										 |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it 'sets run list to chef node' do | 
					
						
							|  |  |  |           expect(stubbed_knife).to receive(:set_run_list) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |           two_phase_bootstrap | 
					
						
							| 
									
										
										
										
											2015-12-29 16:10:05 +03:00
										 |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it 'deploys server' do | 
					
						
							|  |  |  |           expect(executor).to receive(:deploy_server) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |           two_phase_bootstrap | 
					
						
							| 
									
										
										
										
											2015-12-29 16:10:05 +03:00
										 |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         context 'if deploy was successful' do | 
					
						
							|  |  |  |           it 'returns 0' do | 
					
						
							|  |  |  |             allow(executor).to receive(:deploy_server) { 0 } | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |             expect(two_phase_bootstrap).to eq 0
 | 
					
						
							| 
									
										
										
										
											2015-12-29 16:10:05 +03:00
										 |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         context "if deploy wasn't successful" do | 
					
						
							|  |  |  |           it 'returns :deploy_failed code' do | 
					
						
							|  |  |  |             allow(executor).to receive(:deploy_server) { 1 } | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |             expect(two_phase_bootstrap).to eq 8
 | 
					
						
							| 
									
										
										
										
											2015-12-29 16:10:05 +03:00
										 |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         context 'when an error occured during deploy' do | 
					
						
							|  |  |  |           it 'returns :deploy_unknown_error code' do | 
					
						
							|  |  |  |             allow(executor).to receive(:deploy_server) { raise } | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |             expect(two_phase_bootstrap).to eq 6
 | 
					
						
							| 
									
										
										
										
											2015-12-29 16:10:05 +03:00
										 |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       context "if node doesn't present on chef server" do | 
					
						
							|  |  |  |         it 'roll backs and then deletes server from mongo' do | 
					
						
							|  |  |  |           allow(executor).to receive(:check_server_on_chef_server) { false } | 
					
						
							|  |  |  |           allow(executor).to receive(:roll_back) | 
					
						
							|  |  |  |           allow(stubbed_connector).to receive(:server_delete) | 
					
						
							|  |  |  |           expect(executor).to receive(:roll_back).ordered | 
					
						
							|  |  |  |           expect(stubbed_connector).to receive(:server_delete).ordered | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |           two_phase_bootstrap | 
					
						
							| 
									
										
										
										
											2015-12-29 16:10:05 +03:00
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context "when bootstrap wasn't successful" do | 
					
						
							|  |  |  |       it 'returns :server_bootstrap_fail error code' do | 
					
						
							|  |  |  |         allow(executor).to receive(:bootstrap) { 1 } | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |         expect(two_phase_bootstrap).to eq 2
 | 
					
						
							| 
									
										
										
										
											2015-12-29 16:10:05 +03:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context 'when an error occured during bootstrap' do | 
					
						
							|  |  |  |       it 'returns :server_bootstrap_unknown_error error code' do | 
					
						
							|  |  |  |         allow(executor).to receive(:bootstrap) { raise } | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |         expect(two_phase_bootstrap).to eq 7
 | 
					
						
							| 
									
										
										
										
											2015-12-29 16:10:05 +03:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe '#check_server_on_chef_server', stubbed_knife: true do | 
					
						
							|  |  |  |     before do | 
					
						
							|  |  |  |       server.chef_node_name = 'a' | 
					
						
							|  |  |  |       allow(stubbed_knife).to receive(:chef_node_list) { @node_list } | 
					
						
							|  |  |  |       allow(stubbed_knife).to receive(:chef_client_list) { @client_list } | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it 'returns true when node_name in node list and in client list' do | 
					
						
							|  |  |  |       @node_list = %w(a); @client_list = %w(a) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |       expect(executor.check_server_on_chef_server).to be true | 
					
						
							| 
									
										
										
										
											2015-12-29 16:10:05 +03:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "returns false if node name isn't in node list" do | 
					
						
							|  |  |  |       @node_list = []; @client_list = %w(a) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |       expect(executor.check_server_on_chef_server).to be false | 
					
						
							| 
									
										
										
										
											2015-12-29 16:10:05 +03:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "returns false if node name isn't in node list" do | 
					
						
							|  |  |  |       @node_list = %w(a); @client_list = [] | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |       expect(executor.check_server_on_chef_server).to be false | 
					
						
							| 
									
										
										
										
											2015-12-29 16:10:05 +03:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-19 16:17:06 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-20 10:23:34 +03:00
										 |  |  |   describe '#unbootstrap', stubbed_knife: true do | 
					
						
							|  |  |  |     before do | 
					
						
							|  |  |  |       allow(stubbed_connector).to receive_message_chain('key.path') { 'path_to_key' } | 
					
						
							|  |  |  |       allow(stubbed_knife).to receive(:chef_node_delete) | 
					
						
							|  |  |  |       allow(stubbed_knife).to receive(:chef_client_delete) | 
					
						
							|  |  |  |       allow(executor).to receive(:execute_system_command) { '' } | 
					
						
							|  |  |  |       allow(executor).to receive(:last_command_successful?) { true } | 
					
						
							|  |  |  |       allow(executor).to receive(:sleep) | 
					
						
							| 
									
										
										
										
											2016-01-21 20:46:15 +03:00
										 |  |  |       allow(Net::SSH).to receive(:start) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:23:34 +03:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-21 20:46:15 +03:00
										 |  |  |     it 'connects by ssh' do | 
					
						
							|  |  |  |       expect(Net::SSH).to receive(:start) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:23:34 +03:00
										 |  |  |       executor.unbootstrap | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-21 20:46:15 +03:00
										 |  |  |     it 'returns hash with error after 5 unsuccessful retries' do | 
					
						
							|  |  |  |       allow(Net::SSH).to receive(:start) { raise } | 
					
						
							|  |  |  |       expect(Net::SSH).to receive(:start).exactly(5).times | 
					
						
							|  |  |  |       expect(executor.unbootstrap).to be_a(Hash).and include(:error) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:23:34 +03:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-19 16:17:06 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-14 13:43:42 +03:00
										 |  |  |   describe '#deploy_server_with_tags', stubbed_knife: true do | 
					
						
							|  |  |  |     let(:current_tags) { @current_tags } | 
					
						
							|  |  |  |     let(:initial_tags) { %w(a b) } | 
					
						
							|  |  |  |     let(:joined_initial_tags) { initial_tags.join(' ') } | 
					
						
							|  |  |  |     let(:given_tags) { %w(c d) } | 
					
						
							|  |  |  |     let(:joined_given_tags) { given_tags.join(' ') } | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |     let(:deploy_server_with_tags) { executor.deploy_server_with_tags(given_tags, {}) } | 
					
						
							| 
									
										
										
										
											2016-01-14 13:43:42 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     before do | 
					
						
							|  |  |  |       @current_tags = initial_tags.dup | 
					
						
							|  |  |  |       allow(stubbed_knife).to receive(:tags_list) { @current_tags } | 
					
						
							|  |  |  |       allow(stubbed_knife).to receive(:swap_tags) do |_, tags_to_delete, tags_to_add| | 
					
						
							|  |  |  |         @current_tags -= tags_to_delete.split | 
					
						
							|  |  |  |         @current_tags += tags_to_add.split | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |       allow(executor).to receive(:deploy_server) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context 'when tags are empty' do | 
					
						
							|  |  |  |       it 'just deploys server' do | 
					
						
							|  |  |  |         expect(executor).to receive(:deploy_server) | 
					
						
							|  |  |  |         expect(stubbed_knife).not_to receive(:swap_tags) | 
					
						
							|  |  |  |         executor.deploy_server_with_tags([], {}) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context 'when tags are not empty' do | 
					
						
							|  |  |  |       it 'temporarily swaps current_tags with given ones, deploys server and then restores tags' do | 
					
						
							|  |  |  |         expect(stubbed_knife).to receive(:tags_list).ordered | 
					
						
							|  |  |  |         expect(stubbed_knife).to receive(:swap_tags).with(instance_of(String), joined_initial_tags, joined_given_tags).ordered | 
					
						
							|  |  |  |         expect(executor).to receive(:deploy_server).ordered | 
					
						
							|  |  |  |         expect(stubbed_knife).to receive(:swap_tags).with(instance_of(String), joined_given_tags, joined_initial_tags).ordered | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |         deploy_server_with_tags | 
					
						
							| 
									
										
										
										
											2016-01-14 13:43:42 +03:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context 'if error occures during deploy' do | 
					
						
							|  |  |  |       it 'restores tags anyway' do | 
					
						
							|  |  |  |         allow(executor).to receive(:deploy_server) { raise } | 
					
						
							|  |  |  |         expect { | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |           deploy_server_with_tags | 
					
						
							| 
									
										
										
										
											2016-01-14 13:43:42 +03:00
										 |  |  |         }.to raise_error StandardError | 
					
						
							|  |  |  |         expect(current_tags).to eq initial_tags | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context 'if cannot add tags to server' do | 
					
						
							|  |  |  |       it 'returns :server_cannot_update_tags code' do | 
					
						
							|  |  |  |         allow(stubbed_knife).to receive(:swap_tags) { false } | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |         expect(deploy_server_with_tags).to eq 3
 | 
					
						
							| 
									
										
										
										
											2016-01-14 13:43:42 +03:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-19 16:17:06 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-20 01:43:34 +03:00
										 |  |  |   describe '#deploy_server', stubbed_knife: true do | 
					
						
							| 
									
										
										
										
											2016-01-19 13:36:29 +03:00
										 |  |  |     let(:deploy_info) { @deploy_info } | 
					
						
							|  |  |  |     let(:json_file_name) { 'json.json' } | 
					
						
							|  |  |  |     let(:json_file_path) { File.join(SpecSupport.tmp_dir, json_file_name) } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |     let(:deploy_server) { executor.deploy_server(deploy_info) } | 
					
						
							| 
									
										
										
										
											2016-01-19 13:36:29 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     before do | 
					
						
							|  |  |  |       allow(executor).to receive(:run_hook).with(:before_deploy, any_args) | 
					
						
							|  |  |  |       allow(executor).to receive(:run_hook).with(:after_deploy, any_args) | 
					
						
							|  |  |  |       allow(stubbed_knife).to receive(:ssh_stream) { 'Chef Client finished'} | 
					
						
							|  |  |  |       allow(stubbed_connector).to receive(:key) { double('Key', path: 'path_to_key') } | 
					
						
							|  |  |  |       allow(stubbed_connector).to receive(:server_update) | 
					
						
							|  |  |  |       @deploy_info = {} | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it 'runs before_deploy and after_deploy hooks' do | 
					
						
							|  |  |  |       expect(executor).to receive(:run_hook).with(:before_deploy, any_args).ordered | 
					
						
							|  |  |  |       expect(executor).to receive(:run_hook).with(:after_deploy, any_args).ordered | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |       deploy_server | 
					
						
							| 
									
										
										
										
											2016-01-19 13:36:29 +03:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context 'when uses json file' do | 
					
						
							|  |  |  |       before(:all) do | 
					
						
							|  |  |  |         @tmp_files_at_start = Dir.entries(SpecSupport.tmp_dir) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |       before do | 
					
						
							|  |  |  |         allow(DevopsConfig).to receive(:config).and_return({ | 
					
						
							|  |  |  |           project_info_dir: SpecSupport.tmp_dir, | 
					
						
							|  |  |  |           address: 'host.com', | 
					
						
							|  |  |  |           port: '8080', | 
					
						
							|  |  |  |           url_prefix: 'api' | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |         deploy_info['use_json_file'] = true | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       after(:all) do | 
					
						
							|  |  |  |         diff = Dir.entries(SpecSupport.tmp_dir) - @tmp_files_at_start | 
					
						
							|  |  |  |         diff.each do |file| | 
					
						
							|  |  |  |           FileUtils.rm(File.join(SpecSupport.tmp_dir, file)) | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it 'writes deploy_info to json file if it not exists' do | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |         expect { deploy_server }.to change { Dir.entries(SpecSupport.tmp_dir)} | 
					
						
							| 
									
										
										
										
											2016-01-19 13:36:29 +03:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it "writes deploy_info to given json file name if it doesn't exist" do | 
					
						
							|  |  |  |         FileUtils.rm(json_file_path) if File.exists?(json_file_path) | 
					
						
							|  |  |  |         deploy_info['json_file'] = json_file_name | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |         expect { deploy_server }.to change { | 
					
						
							| 
									
										
										
										
											2016-01-19 13:36:29 +03:00
										 |  |  |           Dir.entries(SpecSupport.tmp_dir) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         FileUtils.rm(json_file_path) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it 'reads json from file if it exists' do | 
					
						
							|  |  |  |         deploy_info['json_file'] = json_file_name | 
					
						
							|  |  |  |         File.open(json_file_path, 'w') { |file| file.puts '{"foo": "bar"'} | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |         expect { deploy_server }.not_to change { | 
					
						
							| 
									
										
										
										
											2016-01-19 13:36:29 +03:00
										 |  |  |           Dir.entries(SpecSupport.tmp_dir) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         FileUtils.rm(json_file_path) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it 'adds link to json to deploy command' do | 
					
						
							|  |  |  |         deploy_info['json_file'] = json_file_name | 
					
						
							|  |  |  |         regexp = %r(-j http://host.com:8080/api/v2.0/deploy/data/#{json_file_name}) | 
					
						
							|  |  |  |         expect(stubbed_knife).to receive(:ssh_stream).with(anything, regexp, any_args) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |         deploy_server | 
					
						
							| 
									
										
										
										
											2016-01-19 13:36:29 +03:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context "doesn't use json file" do | 
					
						
							|  |  |  |       before do | 
					
						
							|  |  |  |         deploy_info['use_json_file'] = false | 
					
						
							|  |  |  |         deploy_info['run_list'] = %w(foo bar) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it "adds run list to command if server's stack is set" do | 
					
						
							|  |  |  |         server.stack = 'stack' | 
					
						
							|  |  |  |         expect(stubbed_knife).to receive(:ssh_stream).with(anything, %r(-r foo,bar), any_args) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |         deploy_server | 
					
						
							| 
									
										
										
										
											2016-01-19 13:36:29 +03:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it "doesn't add run list to command if server's stack is unset" do | 
					
						
							|  |  |  |         expect(stubbed_knife).to receive(:ssh_stream).with(anything, 'chef-client --no-color', any_args) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |         deploy_server | 
					
						
							| 
									
										
										
										
											2016-01-19 13:36:29 +03:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-02-12 21:13:09 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it "uses deploy_env's chef_client_options if they are set" do | 
					
						
							|  |  |  |         deploy_env.chef_client_options = '-r role' | 
					
						
							|  |  |  |         expect(stubbed_knife).to receive(:ssh_stream).with(anything, 'chef-client --no-color -r role', any_args) | 
					
						
							|  |  |  |         deploy_server | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-02-20 14:44:21 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it "doesn't use deploy_env's chef_client_options if it's blank string" do | 
					
						
							|  |  |  |         deploy_env.chef_client_options = '' | 
					
						
							|  |  |  |         expect(stubbed_knife).to receive(:ssh_stream).with(anything, 'chef-client --no-color', any_args) | 
					
						
							|  |  |  |         deploy_server | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-01-19 13:36:29 +03:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "uses server's key" do | 
					
						
							|  |  |  |       expect(stubbed_connector).to receive(:key).with('key_id') | 
					
						
							|  |  |  |       expect(stubbed_knife).to receive(:ssh_stream).with(any_args, 'path_to_key') | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |       deploy_server | 
					
						
							| 
									
										
										
										
											2016-01-19 13:36:29 +03:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "uses public ip if it's set" do | 
					
						
							|  |  |  |       server.public_ip = '127.0.0.1' | 
					
						
							|  |  |  |       expect(stubbed_knife).to receive(:ssh_stream).with(anything, anything, '127.0.0.1', any_args) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |       deploy_server | 
					
						
							| 
									
										
										
										
											2016-01-19 13:36:29 +03:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "uses private_ip if public_ip isn't set" do | 
					
						
							|  |  |  |       expect(stubbed_knife).to receive(:ssh_stream).with(anything, anything, server.private_ip, any_args) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |       deploy_server | 
					
						
							| 
									
										
										
										
											2016-01-19 13:36:29 +03:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context 'if deploy was successful' do | 
					
						
							|  |  |  |       it "updates server's last operation" do | 
					
						
							|  |  |  |         expect(server).to receive(:set_last_operation).with('deploy', anything) | 
					
						
							|  |  |  |         expect(stubbed_connector).to receive(:server_update).with(server) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |         deploy_server | 
					
						
							| 
									
										
										
										
											2016-01-19 13:36:29 +03:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it 'returns 0' do | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |         expect(deploy_server).to eq 0
 | 
					
						
							| 
									
										
										
										
											2016-01-19 13:36:29 +03:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context "when deploy wasn't successful" do | 
					
						
							|  |  |  |       before { allow(stubbed_knife).to receive(:ssh_stream) { 'fail'} } | 
					
						
							|  |  |  |       it "doesn't run after_deploy hook" do | 
					
						
							|  |  |  |         expect(executor).to receive(:run_hook).with(:before_deploy, any_args) | 
					
						
							|  |  |  |         expect(executor).not_to receive(:run_hook).with(:after_deploy, any_args) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |         deploy_server | 
					
						
							| 
									
										
										
										
											2016-01-19 13:36:29 +03:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it 'returns 1' do | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |         expect(deploy_server).to eq 1
 | 
					
						
							| 
									
										
										
										
											2016-01-19 13:36:29 +03:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-01-19 16:17:06 +03:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe '#delete_from_chef_server', stubbed_knife: true do | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |     let(:delete_from_chef_server) { executor.delete_from_chef_server('foo') } | 
					
						
							| 
									
										
										
										
											2016-01-19 16:17:06 +03:00
										 |  |  |     before do | 
					
						
							|  |  |  |       allow(stubbed_knife).to receive(:chef_client_delete) | 
					
						
							|  |  |  |       allow(stubbed_knife).to receive(:chef_node_delete) | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |       delete_from_chef_server | 
					
						
							| 
									
										
										
										
											2016-01-19 16:17:06 +03:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it 'returns hash with :chef_node and :chef_client keys' do | 
					
						
							| 
									
										
										
										
											2016-01-20 10:32:57 +03:00
										 |  |  |       expect(delete_from_chef_server).to be_a(Hash).and include(:chef_node, :chef_client) | 
					
						
							| 
									
										
										
										
											2016-01-19 16:17:06 +03:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it 'calls to :chef_node_delete and :chef_client_delete' do | 
					
						
							|  |  |  |       expect(stubbed_knife).to have_received(:chef_client_delete) | 
					
						
							|  |  |  |       expect(stubbed_knife).to have_received(:chef_node_delete) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe '#delete_server' do | 
					
						
							|  |  |  |     let(:delete_server) { executor.delete_server } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context 'when server is static' do | 
					
						
							|  |  |  |       before do | 
					
						
							|  |  |  |         server.provider = 'static' | 
					
						
							|  |  |  |         allow(stubbed_connector).to receive(:server_delete).with(server.id) | 
					
						
							|  |  |  |         allow(executor).to receive(:unbootstrap) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it 'performs unbootstrap' do | 
					
						
							|  |  |  |         expect(executor).to receive(:unbootstrap) | 
					
						
							|  |  |  |         delete_server | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it 'deletes server from mongo' do | 
					
						
							|  |  |  |         expect(stubbed_connector).to receive(:server_delete).with(server.id) | 
					
						
							|  |  |  |         delete_server | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-02 11:43:13 +03:00
										 |  |  |       it 'returns 0' do | 
					
						
							|  |  |  |         expect(delete_server).to eq 0
 | 
					
						
							| 
									
										
										
										
											2016-01-19 16:17:06 +03:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it "doesn't try to remove it from cloud" do | 
					
						
							|  |  |  |         expect{delete_server}.not_to raise_error | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context "when server isn't static", stubbed_knife: true do | 
					
						
							|  |  |  |       before do | 
					
						
							|  |  |  |         allow(server).to receive_message_chain('provider_instance.delete_server') | 
					
						
							|  |  |  |         allow(stubbed_connector).to receive(:server_delete).with(server.id) | 
					
						
							|  |  |  |         allow(stubbed_knife).to receive(:chef_node_delete) | 
					
						
							|  |  |  |         allow(stubbed_knife).to receive(:chef_client_delete) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it 'deletes from info about note chef server' do | 
					
						
							|  |  |  |         allow(executor).to receive(:delete_from_chef_server).and_call_original | 
					
						
							|  |  |  |         expect(executor).to receive(:delete_from_chef_server) | 
					
						
							|  |  |  |         delete_server | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it "doesn't unbootstrap server" do | 
					
						
							|  |  |  |         expect(executor).not_to receive(:unbootstrap) | 
					
						
							|  |  |  |         delete_server | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it 'deletes server from cloud' do | 
					
						
							|  |  |  |         expect(server).to receive_message_chain('provider_instance.delete_server').with(server) | 
					
						
							|  |  |  |         delete_server | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it "doesn't raise error if server wasn't found in cloud" do | 
					
						
							|  |  |  |         allow(server).to receive_message_chain('provider_instance.name') | 
					
						
							|  |  |  |         allow(server).to receive_message_chain('provider_instance.delete_server') { | 
					
						
							|  |  |  |           raise Fog::Compute::OpenStack::NotFound | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         expect { delete_server }.not_to raise_error | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-01-19 13:36:29 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-19 16:17:06 +03:00
										 |  |  |       it 'deletes server from mongo' do | 
					
						
							|  |  |  |         expect(stubbed_connector).to receive(:server_delete).with(server.id) | 
					
						
							|  |  |  |         delete_server | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-02 11:43:13 +03:00
										 |  |  |       it 'returns 0' do | 
					
						
							|  |  |  |         expect(delete_server).to eq 0
 | 
					
						
							| 
									
										
										
										
											2016-01-19 16:17:06 +03:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe '#rollback' do | 
					
						
							|  |  |  |     before do | 
					
						
							|  |  |  |       allow(executor).to receive(:delete_from_chef_server) { {} } | 
					
						
							|  |  |  |       allow(server).to receive_message_chain('provider_instance.delete_server') | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "does nothing if server.id is nil" do | 
					
						
							|  |  |  |       server.id = nil | 
					
						
							|  |  |  |       expect(executor).not_to receive(:delete_from_chef_server) | 
					
						
							|  |  |  |       expect(server).not_to receive(:provider_instance) | 
					
						
							|  |  |  |       executor.roll_back | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it 'deletes node from chef server and instance from cloud' do | 
					
						
							|  |  |  |       expect(executor).to receive(:delete_from_chef_server) | 
					
						
							|  |  |  |       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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-19 17:00:21 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |   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 | 
					
						
							|  |  |  |       allow(deploy_env).to receive_message_chain('provider_instance.run_list') { %w(a) } | 
					
						
							|  |  |  |       project.run_list = %w(b) | 
					
						
							|  |  |  |       deploy_env.run_list = %w(c) | 
					
						
							|  |  |  |       server.run_list = %w(d) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "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 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "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 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it "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 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it 'returns uniq elements' do | 
					
						
							|  |  |  |       project.run_list = %w(a) | 
					
						
							|  |  |  |       deploy_env.run_list = %w(a) | 
					
						
							|  |  |  |       expect(executor.compute_run_list).to be_an(Array).and contain_exactly(*%w(a d)) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							| 
									
										
										
										
											2015-12-21 18:23:17 +03:00
										 |  |  | end |