| 
									
										
										
										
											2016-01-31 17:52:11 +03:00
										 |  |  | require 'workers/stack_bootstrap_worker' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RSpec.describe StackBootstrapWorker, type: :worker, stubbed_connector: true do | 
					
						
							|  |  |  |   let(:stack_attrs) { attributes_for(:stack_ec2).stringify_keys } | 
					
						
							|  |  |  |   let(:perform_with_bootstrap) { worker.perform('stack_attributes' => stack_attrs) } | 
					
						
							|  |  |  |   let(:perform_without_bootstrap) { worker.perform('stack_attributes' => stack_attrs.merge('without_bootstrap' => true)) } | 
					
						
							|  |  |  |   let(:stack_synchronizer) { instance_double(StackSynchronizer, sync: 0) } | 
					
						
							|  |  |  |   let(:stack_servers_bootstrapper) { instance_double(StackServersBootstrapper, bootstrap: true) } | 
					
						
							|  |  |  |   let(:stack_servers_persister) { instance_double(StackServersPersister, persist: {1 => build_list(:server, 2)}) } | 
					
						
							|  |  |  |   let(:worker) { described_class.new } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   before do | 
					
						
							|  |  |  |     allow(Provider::ProviderFactory).to receive(:providers).and_return(%w(ec2)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-17 13:49:19 +03:00
										 |  |  |     allow(worker).to receive(:update_report) | 
					
						
							| 
									
										
										
										
											2016-01-31 17:52:11 +03:00
										 |  |  |     allow(worker).to receive(:stack_synchronizer) { stack_synchronizer } | 
					
						
							|  |  |  |     allow(worker).to receive(:stack_servers_bootstrapper) { stack_servers_bootstrapper } | 
					
						
							|  |  |  |     allow(worker).to receive(:stack_servers_persister) { stack_servers_persister } | 
					
						
							| 
									
										
										
										
											2016-03-17 13:49:19 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     allow(stubbed_connector).to receive(:stack_insert) | 
					
						
							| 
									
										
										
										
											2016-01-31 17:52:11 +03:00
										 |  |  |     allow(Devops::Model::StackEc2).to receive(:create) { Devops::Model::StackEc2.new(stack_attrs) } | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it 'requires "stack_attributes" in options' do | 
					
						
							| 
									
										
										
										
											2016-03-17 13:49:19 +03:00
										 |  |  |     expect{ worker.perform({}) }.to raise_error KeyError | 
					
						
							| 
									
										
										
										
											2016-01-31 17:52:11 +03:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-10 20:39:49 +03:00
										 |  |  |   it 'updates report about operation' do | 
					
						
							| 
									
										
										
										
											2016-03-17 13:49:19 +03:00
										 |  |  |     expect(worker).to receive(:update_report) | 
					
						
							| 
									
										
										
										
											2016-01-31 17:52:11 +03:00
										 |  |  |     perform_without_bootstrap | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-10 20:39:49 +03:00
										 |  |  |   it 'updates report about operation, creates stack and persists stack servers' do | 
					
						
							| 
									
										
										
										
											2016-01-31 17:52:11 +03:00
										 |  |  |     allow(worker).to receive(:create_stack).and_call_original | 
					
						
							| 
									
										
										
										
											2016-03-17 13:49:19 +03:00
										 |  |  |     expect(worker).to receive(:update_report).ordered | 
					
						
							| 
									
										
										
										
											2016-01-31 17:52:11 +03:00
										 |  |  |     expect(worker).to receive(:create_stack).ordered | 
					
						
							|  |  |  |     expect(stack_servers_persister).to receive(:persist).ordered | 
					
						
							|  |  |  |     perform_without_bootstrap | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   context 'if without_bootstrap is true' do | 
					
						
							|  |  |  |     it "doesn't bootstrap servers" do | 
					
						
							|  |  |  |       expect(stack_servers_bootstrapper).not_to receive(:bootstrap) | 
					
						
							|  |  |  |       perform_without_bootstrap | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it 'returns 0' do | 
					
						
							|  |  |  |       expect(perform_without_bootstrap).to eq 0
 | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   context 'if without_bootstrap is false or not set' do | 
					
						
							|  |  |  |     it 'bootstraps servers in order by priorities, separately' do | 
					
						
							|  |  |  |       first_servers = build_list(:server, 2) | 
					
						
							|  |  |  |       last_servers = build_list(:server, 3) | 
					
						
							|  |  |  |       allow(stack_servers_persister).to receive(:persist) { | 
					
						
							|  |  |  |         {3 => first_servers, 1 => last_servers} | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       expect(stack_servers_bootstrapper).to receive(:bootstrap).with(first_servers).ordered | 
					
						
							|  |  |  |       expect(stack_servers_bootstrapper).to receive(:bootstrap).with(last_servers).ordered | 
					
						
							|  |  |  |       perform_with_bootstrap | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context 'when bootstraping servers was successful' do | 
					
						
							|  |  |  |       it 'returns 0' do | 
					
						
							|  |  |  |         expect(perform_with_bootstrap).to eq 0
 | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context 'when a known error occured during servers bootstrap' do | 
					
						
							|  |  |  |       before do | 
					
						
							|  |  |  |         allow(stack_servers_bootstrapper).to receive(:bootstrap) { raise StackServerBootstrapError } | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it 'rollbacks stack and returns 2' do | 
					
						
							|  |  |  |         expect_any_instance_of(Devops::Model::StackEc2).to receive(:delete_stack_in_cloud!) | 
					
						
							|  |  |  |         expect(stubbed_connector).to receive(:stack_servers_delete) | 
					
						
							|  |  |  |         expect(stubbed_connector).to receive(:stack_delete) | 
					
						
							|  |  |  |         perform_with_bootstrap | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it 'returns 2' do | 
					
						
							|  |  |  |         allow(worker).to receive(:rollback_stack!) | 
					
						
							|  |  |  |         expect(perform_with_bootstrap).to eq 2
 | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context 'when a known error occured during servers deploy' do | 
					
						
							|  |  |  |       it "doesn't rollback stack and returns 3" do | 
					
						
							|  |  |  |         allow(stack_servers_bootstrapper).to receive(:bootstrap) { raise StackServerDeployError } | 
					
						
							|  |  |  |         expect(worker).not_to receive(:rollback_stack!) | 
					
						
							|  |  |  |         expect(perform_with_bootstrap).to eq 3
 | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context "when a servers bootstrap & deploy haven't been finished due to timeout" do | 
					
						
							|  |  |  |       it "doesn't rollback stack and returns 3" do | 
					
						
							|  |  |  |         allow(stack_servers_bootstrapper).to receive(:bootstrap) { raise StackServerBootstrapDeployTimeout } | 
					
						
							|  |  |  |         expect(worker).not_to receive(:rollback_stack!) | 
					
						
							|  |  |  |         expect(perform_with_bootstrap).to eq 4
 | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     context 'when an unknown error occured during servers bootsrap and deploy' do | 
					
						
							|  |  |  |       it 'rollbacks stack and reraises that error' do | 
					
						
							|  |  |  |         error = StandardError.new | 
					
						
							|  |  |  |         allow(stack_servers_bootstrapper).to receive(:bootstrap) { raise error } | 
					
						
							|  |  |  |         allow(worker).to receive(:rollback_stack!) | 
					
						
							|  |  |  |         expect(worker).to receive(:rollback_stack!) | 
					
						
							|  |  |  |         expect{perform_with_bootstrap}.to raise_error(error) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   context "when stack creation wasn't successful" do | 
					
						
							|  |  |  |     it 'returns 1' do | 
					
						
							|  |  |  |       allow(stack_synchronizer).to receive(:sync) { 5 } | 
					
						
							|  |  |  |       allow(stack_synchronizer).to receive(:reason_from_error_code) { :error } | 
					
						
							|  |  |  |       expect(perform_without_bootstrap).to eq 1
 | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |