From 28d40605c8ae0007e4c8a77cffedd6f15e36f338 Mon Sep 17 00:00:00 2001 From: Sebastian Serth Date: Tue, 14 Apr 2020 15:20:15 +0200 Subject: [PATCH] Fix specs --- lib/docker_client.rb | 5 +- lib/docker_container_pool.rb | 7 ++ spec/lib/docker_client_spec.rb | 6 +- spec/lib/docker_container_pool_spec.rb | 155 ------------------------- 4 files changed, 13 insertions(+), 160 deletions(-) delete mode 100644 spec/lib/docker_container_pool_spec.rb diff --git a/lib/docker_client.rb b/lib/docker_client.rb index d3bd87a6..e8aeef78 100644 --- a/lib/docker_client.rb +++ b/lib/docker_client.rb @@ -248,12 +248,13 @@ class DockerClient Rails.logger.error('No further actions are done concerning that.') 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) execute_command(command, nil, block) end - #only used by score + # only used by score and execute_arbitrary_command def execute_command(command, before_execution_block, output_consuming_block) #tries ||= 0 container_request_time = Time.now diff --git a/lib/docker_container_pool.rb b/lib/docker_container_pool.rb index cf538e2d..b2cfba85 100644 --- a/lib/docker_container_pool.rb +++ b/lib/docker_container_pool.rb @@ -52,9 +52,16 @@ class DockerContainerPool def self.quantities response = JSON.parse(Faraday.get(config[:location] + "/docker_container_pool/quantities").body) response.transform_keys(&:to_i) + rescue StandardError => e + Raven.extra_context({response: response.inspect}) + Raven.capture_exception(e) + [] end def self.dump_info JSON.parse(Faraday.get(config[:location] + "/docker_container_pool/dump_info").body) + rescue StandardError => e + Raven.capture_exception(e) + nil end end diff --git a/spec/lib/docker_client_spec.rb b/spec/lib/docker_client_spec.rb index 5d1118bd..a7a46d24 100644 --- a/spec/lib/docker_client_spec.rb +++ b/spec/lib/docker_client_spec.rb @@ -205,7 +205,7 @@ describe DockerClient, docker: true do end 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 end @@ -213,14 +213,14 @@ describe DockerClient, docker: true do let(:error) { Excon::Errors::SocketError.new(SocketError.new) } context 'when retries are left' do - let(:result) { 42 } + let(:result) { { status: "ok", stdout: 42 } } before(:each) do expect(docker_client).to receive(:send_command).and_raise(error).and_return(result) end 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 diff --git a/spec/lib/docker_container_pool_spec.rb b/spec/lib/docker_container_pool_spec.rb deleted file mode 100644 index b6f6f42f..00000000 --- a/spec/lib/docker_container_pool_spec.rb +++ /dev/null @@ -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