| 
									
										
										
										
											2016-03-30 12:05:59 +03:00
										 |  |  | require 'lib/executors/stack_executor' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-30 12:57:24 +03:00
										 |  |  | class Devops::Executor::StackExecutor | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |   RSpec.describe self, type: :executor, stubbed_logger: true do | 
					
						
							| 
									
										
										
										
											2016-03-30 12:57:24 +03:00
										 |  |  |     let(:out) { double('out', puts: nil, flush: nil) } | 
					
						
							|  |  |  |     let(:stack) { build(:stack) } | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |     let(:executor_without_stack) { described_class.new(out: out, current_user: 'user') } | 
					
						
							|  |  |  |     let(:executor_with_stack) { described_class.new(out: out, stack: stack, current_user: 'user') } | 
					
						
							| 
									
										
										
										
											2016-04-04 13:17:07 +03:00
										 |  |  |     let(:new_servers_by_priorities) { | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |         0 => [{id: 1}], | 
					
						
							|  |  |  |         2 => [{id: 2}] | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     let(:just_persisted_by_priority) { | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         0 => [double('info 1', id: 1)], | 
					
						
							|  |  |  |         2 => [double('info 2', id: 2)] | 
					
						
							| 
									
										
										
										
											2016-04-04 13:17:07 +03:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     let(:fetcher) { | 
					
						
							|  |  |  |       instance_double(StackServersFetcher, | 
					
						
							|  |  |  |         new_servers_by_priorities: new_servers_by_priorities, | 
					
						
							|  |  |  |         stale_servers: build_list(:server, 2), | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |         fetch: nil | 
					
						
							| 
									
										
										
										
											2016-04-04 13:17:07 +03:00
										 |  |  |       ) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     before do | 
					
						
							|  |  |  |       allow(executor_with_stack).to receive(:fetcher) { fetcher } | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-30 12:05:59 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-30 12:57:24 +03:00
										 |  |  |     describe '#wait_till_stack_is_created' do | 
					
						
							| 
									
										
										
										
											2016-04-04 13:17:07 +03:00
										 |  |  |       let(:waiter) { instance_double(StackCreationWaiter, wait: double("creation_result", ok?: true)) } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       before do | 
					
						
							|  |  |  |         allow(executor_with_stack).to receive(:waiter) { waiter } | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |         allow(stack).to receive(:unlock_persisting!) | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it 'waites till stack is created, then fetches stack servers and unlocks stack persisting' do | 
					
						
							|  |  |  |         expect(waiter).to receive(:wait).ordered | 
					
						
							|  |  |  |         expect(stack).to receive(:unlock_persisting!).ordered | 
					
						
							|  |  |  |         executor_with_stack.wait_till_stack_is_created | 
					
						
							| 
									
										
										
										
											2016-04-04 13:17:07 +03:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-30 12:57:24 +03:00
										 |  |  |       it "return true if syncer returns ok" do | 
					
						
							|  |  |  |         expect(executor_with_stack.wait_till_stack_is_created).to be true | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-03-30 12:05:59 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-30 12:57:24 +03:00
										 |  |  |       it "return false if syncer returns not ok" do | 
					
						
							| 
									
										
										
										
											2016-04-04 13:17:07 +03:00
										 |  |  |         allow(waiter).to receive(:wait) { double("creation_result", ok?: false, reason: '') } | 
					
						
							| 
									
										
										
										
											2016-03-30 12:57:24 +03:00
										 |  |  |         expect(executor_with_stack.wait_till_stack_is_created).to be false | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-03-30 12:05:59 +03:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-04 13:17:07 +03:00
										 |  |  |     describe '#create_stack' do | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |       let(:created_stack) { instance_double(Devops::Model::StackAws, save: nil) } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       before do | 
					
						
							|  |  |  |         allow(Devops::Model::StackFactory).to receive(:create).and_return(created_stack) | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-04-04 13:17:07 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-30 12:57:24 +03:00
										 |  |  |       it 'initiate creation in cloud and persists stack' do | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |         expect(Devops::Model::StackFactory).to receive(:create).with('aws', instance_of(Hash), out) | 
					
						
							|  |  |  |         expect(created_stack).to receive(:save) | 
					
						
							|  |  |  |         executor_with_stack.create_stack({'provider' => 'aws'}) | 
					
						
							| 
									
										
										
										
											2016-04-04 13:17:07 +03:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it 'locks persisting on create' do | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |         executor_with_stack.create_stack({'provider' => 'aws'}) | 
					
						
							|  |  |  |         expect(Devops::Model::StackFactory).to have_received(:create) do |_, params| | 
					
						
							| 
									
										
										
										
											2016-04-04 13:17:07 +03:00
										 |  |  |           expect(params).to include('persisting_is_locked' => true) | 
					
						
							|  |  |  |         end | 
					
						
							| 
									
										
										
										
											2016-03-30 12:57:24 +03:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-03-30 12:05:59 +03:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-04 13:17:07 +03:00
										 |  |  |     describe '#persist_new_servers' do | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |       let(:persister) { instance_double(StackServersPersister, persist: build(:server)) } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-04 13:17:07 +03:00
										 |  |  |       before do | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |         allow(executor_with_stack).to receive(:persister) { persister } | 
					
						
							|  |  |  |         allow(stack).to receive(:lock_persisting!) | 
					
						
							|  |  |  |         allow(stack).to receive(:unlock_persisting!) | 
					
						
							|  |  |  |         allow(executor_with_stack).to receive(:reload_stack) { stack } | 
					
						
							| 
									
										
										
										
											2016-03-30 12:57:24 +03:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-03-30 12:05:59 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-04 13:17:07 +03:00
										 |  |  |       it 'calls StackServersPersister#persist for each server' do | 
					
						
							|  |  |  |         expect(persister).to receive(:persist).exactly(2).times | 
					
						
							|  |  |  |         executor_with_stack.persist_new_servers | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-03-30 12:05:59 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |       it 'locks persisting of a stack before start and unlocks after finish' do | 
					
						
							|  |  |  |         expect(stack).to receive(:lock_persisting!).ordered | 
					
						
							|  |  |  |         expect(persister).to receive(:persist).ordered | 
					
						
							|  |  |  |         expect(stack).to receive(:unlock_persisting!).ordered | 
					
						
							| 
									
										
										
										
											2016-04-15 15:51:52 +03:00
										 |  |  |         executor_with_stack.persist_new_servers | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-04-22 14:25:08 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |       it 'unlocks persisting even in case of failures' do | 
					
						
							|  |  |  |         allow(persister).to receive(:persist) { raise } | 
					
						
							|  |  |  |         expect(stack).to receive(:unlock_persisting!) | 
					
						
							|  |  |  |         expect { executor_with_stack.persist_new_servers }.to raise_error StandardError | 
					
						
							| 
									
										
										
										
											2016-04-22 14:25:08 +03:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-04-22 14:25:08 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |     describe '#bootstrap_just_persisted' do | 
					
						
							| 
									
										
										
										
											2016-04-22 14:25:08 +03:00
										 |  |  |       it 'calls PrioritizedGroupsBootstrapper#bootstrap_servers_by_priority' do | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |         result = double('bootstrap_result') | 
					
						
							|  |  |  |         allow(executor_with_stack).to receive(:just_persisted_by_priority) { just_persisted_by_priority } | 
					
						
							|  |  |  |         allow_any_instance_of(PrioritizedGroupsBootstrapper).to receive(:bootstrap_servers_by_priority) { result } | 
					
						
							| 
									
										
										
										
											2016-04-22 14:25:08 +03:00
										 |  |  |         expect_any_instance_of(PrioritizedGroupsBootstrapper).to receive(:bootstrap_servers_by_priority) | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |         expect(executor_with_stack.bootstrap_just_persisted(1000)).to eq result | 
					
						
							| 
									
										
										
										
											2016-04-04 13:17:07 +03:00
										 |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     describe '#delete_stale_servers' do | 
					
						
							|  |  |  |       it 'builds server executor per stale server and properly delete them' do | 
					
						
							|  |  |  |         executor1 = instance_double(Devops::Executor::ServerExecutor, delete_server: nil) | 
					
						
							|  |  |  |         executor2 = instance_double(Devops::Executor::ServerExecutor, delete_server: nil) | 
					
						
							|  |  |  |         allow(Devops::Executor::ServerExecutor).to receive(:new).and_return(executor1, executor2) | 
					
						
							|  |  |  |         expect(executor1).to receive(:delete_server).ordered | 
					
						
							|  |  |  |         expect(executor2).to receive(:delete_server).ordered | 
					
						
							|  |  |  |         executor_with_stack.delete_stale_servers | 
					
						
							| 
									
										
										
										
											2016-03-30 12:57:24 +03:00
										 |  |  |       end | 
					
						
							| 
									
										
										
										
											2016-03-30 12:05:59 +03:00
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |     describe '#delete_stack' do | 
					
						
							| 
									
										
										
										
											2016-03-30 12:57:24 +03:00
										 |  |  |       it 'deletes stack from cloud, then deletes stack servers, and then deletes stack itself' do | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |         allow(stack).to receive(:delete) | 
					
						
							| 
									
										
										
										
											2016-03-30 12:57:24 +03:00
										 |  |  |         expect(stack).to receive(:delete_stack_in_cloud!).ordered | 
					
						
							| 
									
										
										
										
											2018-04-04 22:44:39 +03:00
										 |  |  |         expect(Devops::Model::Server).to receive(:delete_stack_servers).ordered | 
					
						
							|  |  |  |         expect(stack).to receive(:delete).ordered | 
					
						
							| 
									
										
										
										
											2016-03-30 12:57:24 +03:00
										 |  |  |         executor_with_stack.delete_stack | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2016-03-30 12:05:59 +03:00
										 |  |  |   end | 
					
						
							|  |  |  | end |