Fix specs
This commit is contained in:
@ -248,12 +248,13 @@ class DockerClient
|
|||||||
Rails.logger.error('No further actions are done concerning that.')
|
Rails.logger.error('No further actions are done concerning that.')
|
||||||
end
|
end
|
||||||
|
|
||||||
#currently only used to check if containers have been started correctly, or other internal checks
|
# currently only used to check if containers have been started correctly, or other internal checks
|
||||||
|
# also used for the admin shell to any container
|
||||||
def execute_arbitrary_command(command, &block)
|
def execute_arbitrary_command(command, &block)
|
||||||
execute_command(command, nil, block)
|
execute_command(command, nil, block)
|
||||||
end
|
end
|
||||||
|
|
||||||
#only used by score
|
# only used by score and execute_arbitrary_command
|
||||||
def execute_command(command, before_execution_block, output_consuming_block)
|
def execute_command(command, before_execution_block, output_consuming_block)
|
||||||
#tries ||= 0
|
#tries ||= 0
|
||||||
container_request_time = Time.now
|
container_request_time = Time.now
|
||||||
|
@ -52,9 +52,16 @@ class DockerContainerPool
|
|||||||
def self.quantities
|
def self.quantities
|
||||||
response = JSON.parse(Faraday.get(config[:location] + "/docker_container_pool/quantities").body)
|
response = JSON.parse(Faraday.get(config[:location] + "/docker_container_pool/quantities").body)
|
||||||
response.transform_keys(&:to_i)
|
response.transform_keys(&:to_i)
|
||||||
|
rescue StandardError => e
|
||||||
|
Raven.extra_context({response: response.inspect})
|
||||||
|
Raven.capture_exception(e)
|
||||||
|
[]
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.dump_info
|
def self.dump_info
|
||||||
JSON.parse(Faraday.get(config[:location] + "/docker_container_pool/dump_info").body)
|
JSON.parse(Faraday.get(config[:location] + "/docker_container_pool/dump_info").body)
|
||||||
|
rescue StandardError => e
|
||||||
|
Raven.capture_exception(e)
|
||||||
|
nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -205,7 +205,7 @@ describe DockerClient, docker: true do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'sends the command' do
|
it 'sends the command' do
|
||||||
expect(docker_client).to receive(:send_command).with(command, kind_of(Docker::Container))
|
expect(docker_client).to receive(:send_command).with(command, kind_of(Docker::Container)).and_return({})
|
||||||
execute_arbitrary_command
|
execute_arbitrary_command
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -213,14 +213,14 @@ describe DockerClient, docker: true do
|
|||||||
let(:error) { Excon::Errors::SocketError.new(SocketError.new) }
|
let(:error) { Excon::Errors::SocketError.new(SocketError.new) }
|
||||||
|
|
||||||
context 'when retries are left' do
|
context 'when retries are left' do
|
||||||
let(:result) { 42 }
|
let(:result) { { status: "ok", stdout: 42 } }
|
||||||
|
|
||||||
before(:each) do
|
before(:each) do
|
||||||
expect(docker_client).to receive(:send_command).and_raise(error).and_return(result)
|
expect(docker_client).to receive(:send_command).and_raise(error).and_return(result)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'retries to execute the command' do
|
it 'retries to execute the command' do
|
||||||
expect(execute_arbitrary_command).to eq(result)
|
expect(execute_arbitrary_command[:stdout]).to eq(result[:stdout])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,155 +0,0 @@
|
|||||||
require 'rails_helper'
|
|
||||||
|
|
||||||
describe DockerContainerPool do
|
|
||||||
let(:container) { double(:start_time => Time.now, :status => 'available', :json => {'State' => {'Running' => true}}) }
|
|
||||||
|
|
||||||
def reload_class
|
|
||||||
load('docker_container_pool.rb')
|
|
||||||
end
|
|
||||||
private :reload_class
|
|
||||||
|
|
||||||
before(:each) do
|
|
||||||
@execution_environment = FactoryBot.create(:ruby)
|
|
||||||
reload_class
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'uses thread-safe data structures' do
|
|
||||||
expect(described_class.instance_variable_get(:@containers)).to be_a(Concurrent::Hash)
|
|
||||||
expect(described_class.instance_variable_get(:@containers)[@execution_environment.id]).to be_a(Concurrent::Array)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.clean_up' do
|
|
||||||
before(:each) { described_class.instance_variable_set(:@refill_task, double) }
|
|
||||||
after(:each) { described_class.clean_up }
|
|
||||||
|
|
||||||
it 'stops the refill task' do
|
|
||||||
expect(described_class.instance_variable_get(:@refill_task)).to receive(:shutdown)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'destroys all containers' do
|
|
||||||
described_class.instance_variable_get(:@containers).values.flatten.each do |container|
|
|
||||||
expect(DockerClient).to receive(:destroy_container).with(container)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.get_container' do
|
|
||||||
context 'when active' do
|
|
||||||
before(:each) do
|
|
||||||
expect(described_class).to receive(:config).and_return(active: true)
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with an available container' do
|
|
||||||
before(:each) { described_class.instance_variable_get(:@containers)[@execution_environment.id].push(container) }
|
|
||||||
|
|
||||||
it 'takes a container from the pool' do
|
|
||||||
expect(described_class).not_to receive(:create_container).with(@execution_environment)
|
|
||||||
expect(described_class.get_container(@execution_environment)).to eq(container)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'without an available container' do
|
|
||||||
before(:each) do
|
|
||||||
expect(described_class.instance_variable_get(:@containers)[@execution_environment.id]).to be_empty
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'not creates a new container' do
|
|
||||||
expect(described_class).not_to receive(:create_container).with(@execution_environment)
|
|
||||||
described_class.get_container(@execution_environment)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when inactive' do
|
|
||||||
before(:each) do
|
|
||||||
expect(described_class).to receive(:config).and_return(active: false)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'creates a new container' do
|
|
||||||
expect(described_class).to receive(:create_container).with(@execution_environment)
|
|
||||||
described_class.get_container(@execution_environment)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.quantities' do
|
|
||||||
it 'maps execution environments to quantities of available containers' do
|
|
||||||
expect(described_class.quantities.keys).to eq(ExecutionEnvironment.all.map(&:id))
|
|
||||||
expect(described_class.quantities.values.uniq).to eq([0])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.refill' do
|
|
||||||
before(:each) { @execution_environment.update(pool_size: 10) }
|
|
||||||
after(:each) { described_class.refill }
|
|
||||||
|
|
||||||
context 'when configured to work synchronously' do
|
|
||||||
before(:each) do
|
|
||||||
expect(described_class).to receive(:config).and_return(refill: {async: false})
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'works synchronously' do
|
|
||||||
expect(described_class).to receive(:refill_for_execution_environment)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when configured to work asynchronously' do
|
|
||||||
before(:each) do
|
|
||||||
expect(described_class).to receive(:config).and_return(refill: {async: true})
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'works asynchronously' do
|
|
||||||
expect_any_instance_of(Concurrent::Future).to receive(:execute) do |future|
|
|
||||||
expect(described_class).to receive(:refill_for_execution_environment)
|
|
||||||
future.instance_variable_get(:@task).call
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.refill_for_execution_environment' do
|
|
||||||
let(:batch_size) { 5 }
|
|
||||||
|
|
||||||
before(:each) do
|
|
||||||
expect(described_class).to receive(:config).and_return(refill: {batch_size: batch_size})
|
|
||||||
end
|
|
||||||
|
|
||||||
after(:each) { described_class.refill_for_execution_environment(@execution_environment) }
|
|
||||||
|
|
||||||
context 'with something to refill' do
|
|
||||||
before(:each) { @execution_environment.update(pool_size: 10) }
|
|
||||||
|
|
||||||
it 'complies with the maximum batch size' do
|
|
||||||
expect(described_class).to receive(:create_container).with(@execution_environment).exactly(batch_size).times
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with nothing to refill' do
|
|
||||||
before(:each) { @execution_environment.update(pool_size: 0) }
|
|
||||||
|
|
||||||
it 'does nothing' do
|
|
||||||
expect(described_class).not_to receive(:create_container)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.start_refill_task' do
|
|
||||||
let(:interval) { 30 }
|
|
||||||
let(:timeout) { 60 }
|
|
||||||
|
|
||||||
before(:each) do
|
|
||||||
expect(described_class).to receive(:config).at_least(:once).and_return(refill: {interval: interval, timeout: timeout})
|
|
||||||
end
|
|
||||||
|
|
||||||
after(:each) { described_class.start_refill_task }
|
|
||||||
|
|
||||||
# changed from false to true
|
|
||||||
it 'creates an asynchronous task' do
|
|
||||||
expect(Concurrent::TimerTask).to receive(:new).with(execution_interval: interval, run_now: true, timeout_interval: timeout).and_call_original
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'executes the task' do
|
|
||||||
expect_any_instance_of(Concurrent::TimerTask).to receive(:execute)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
Reference in New Issue
Block a user