128 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
		
		
			
		
	
	
			128 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
|   | require 'workers/stack_bootstrap_worker' | ||
|  | 
 | ||
|  | RSpec.describe StackBootstrapWorker, type: :worker, stubbed_connector: true do | ||
|  |   let(:out) { double(:out, puts: nil, flush: nil) } | ||
|  |   let(:file) { 'temp.txt' } | ||
|  | 
 | ||
|  |   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)) | ||
|  |     allow(stubbed_connector).to receive(:save_report) | ||
|  |     allow(stubbed_connector).to receive(:stack_insert) | ||
|  | 
 | ||
|  |     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 } | ||
|  |     allow(worker).to receive(:call).and_yield(out, file) | ||
|  |     allow(Devops::Model::StackEc2).to receive(:create) { Devops::Model::StackEc2.new(stack_attrs) } | ||
|  |   end | ||
|  | 
 | ||
|  | 
 | ||
|  |   it 'requires "stack_attributes" in options' do | ||
|  |     expect{ | ||
|  |       worker.perform({}) | ||
|  |     }.to raise_error KeyError | ||
|  |   end | ||
|  | 
 | ||
|  |   it 'saves report about operation' do | ||
|  |     expect(stubbed_connector).to receive(:save_report).with(instance_of(Devops::Model::Report)) | ||
|  |     perform_without_bootstrap | ||
|  |   end | ||
|  | 
 | ||
|  |   it 'saves report about operation, creates stack and persists stack servers' do | ||
|  |     allow(worker).to receive(:create_stack).and_call_original | ||
|  |     expect(stubbed_connector).to receive(:save_report).with(instance_of(Devops::Model::Report)).ordered | ||
|  |     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 |