Add tests for execution environment copy to Poseidon

This commit is contained in:
Konrad Hanff
2021-06-01 14:39:30 +02:00
committed by Sebastian Serth
parent 90fac7b94c
commit d22d24df4d
3 changed files with 109 additions and 1 deletions

View File

@ -6,7 +6,10 @@ describe ExecutionEnvironmentsController do
let(:execution_environment) { FactoryBot.create(:ruby) } let(:execution_environment) { FactoryBot.create(:ruby) }
let(:user) { FactoryBot.create(:admin) } let(:user) { FactoryBot.create(:admin) }
before { allow(controller).to receive(:current_user).and_return(user) } before do
allow(controller).to receive(:current_user).and_return(user)
allow(controller).to receive(:copy_execution_environment_to_poseidon).and_return(nil)
end
describe 'POST #create' do describe 'POST #create' do
before { allow(DockerClient).to receive(:image_tags).at_least(:once).and_return([]) } before { allow(DockerClient).to receive(:image_tags).at_least(:once).and_return([]) }
@ -23,6 +26,10 @@ describe ExecutionEnvironmentsController do
expect { perform_request.call }.to change(ExecutionEnvironment, :count).by(1) expect { perform_request.call }.to change(ExecutionEnvironment, :count).by(1)
end end
it 'registers the execution environment with Poseidon' do
expect(controller).to have_received(:copy_execution_environment_to_poseidon)
end
expect_redirect(ExecutionEnvironment.last) expect_redirect(ExecutionEnvironment.last)
end end
@ -32,6 +39,10 @@ describe ExecutionEnvironmentsController do
expect_assigns(execution_environment: ExecutionEnvironment) expect_assigns(execution_environment: ExecutionEnvironment)
expect_status(200) expect_status(200)
expect_template(:new) expect_template(:new)
it 'does not register the execution environment with Poseidon' do
expect(controller).not_to have_received(:copy_execution_environment_to_poseidon)
end
end end
end end
@ -156,12 +167,17 @@ describe ExecutionEnvironmentsController do
context 'with a valid execution environment' do context 'with a valid execution environment' do
before do before do
allow(DockerClient).to receive(:image_tags).at_least(:once).and_return([]) allow(DockerClient).to receive(:image_tags).at_least(:once).and_return([])
allow(controller).to receive(:copy_execution_environment_to_poseidon).and_return(nil)
put :update, params: {execution_environment: FactoryBot.attributes_for(:ruby), id: execution_environment.id} put :update, params: {execution_environment: FactoryBot.attributes_for(:ruby), id: execution_environment.id}
end end
expect_assigns(docker_images: Array) expect_assigns(docker_images: Array)
expect_assigns(execution_environment: ExecutionEnvironment) expect_assigns(execution_environment: ExecutionEnvironment)
expect_redirect(:execution_environment) expect_redirect(:execution_environment)
it 'updates the execution environment at Poseidon' do
expect(controller).to have_received(:copy_execution_environment_to_poseidon)
end
end end
context 'with an invalid execution environment' do context 'with an invalid execution environment' do
@ -170,6 +186,10 @@ describe ExecutionEnvironmentsController do
expect_assigns(execution_environment: ExecutionEnvironment) expect_assigns(execution_environment: ExecutionEnvironment)
expect_status(200) expect_status(200)
expect_template(:edit) expect_template(:edit)
it 'does not update the execution environment at Poseidon' do
expect(controller).not_to have_received(:copy_execution_environment_to_poseidon)
end
end end
end end
end end

View File

@ -4,6 +4,7 @@ FactoryBot.define do
factory :coffee_script, class: 'ExecutionEnvironment' do factory :coffee_script, class: 'ExecutionEnvironment' do
created_by_teacher created_by_teacher
default_memory_limit default_memory_limit
default_cpu_limit
docker_image { 'hklement/ubuntu-coffee:latest' } docker_image { 'hklement/ubuntu-coffee:latest' }
file_type { association :dot_coffee, user: user } file_type { association :dot_coffee, user: user }
help help
@ -18,6 +19,7 @@ FactoryBot.define do
factory :html, class: 'ExecutionEnvironment' do factory :html, class: 'ExecutionEnvironment' do
created_by_teacher created_by_teacher
default_memory_limit default_memory_limit
default_cpu_limit
docker_image { 'hklement/ubuntu-html:latest' } docker_image { 'hklement/ubuntu-html:latest' }
file_type { association :dot_html, user: user } file_type { association :dot_html, user: user }
help help
@ -34,6 +36,7 @@ FactoryBot.define do
factory :java, class: 'ExecutionEnvironment' do factory :java, class: 'ExecutionEnvironment' do
created_by_teacher created_by_teacher
default_memory_limit default_memory_limit
default_cpu_limit
docker_image { 'openhpi/co_execenv_java:8' } docker_image { 'openhpi/co_execenv_java:8' }
file_type { association :dot_java, user: user } file_type { association :dot_java, user: user }
help help
@ -50,6 +53,7 @@ FactoryBot.define do
factory :jruby, class: 'ExecutionEnvironment' do factory :jruby, class: 'ExecutionEnvironment' do
created_by_teacher created_by_teacher
default_memory_limit default_memory_limit
default_cpu_limit
docker_image { 'hklement/ubuntu-jruby:latest' } docker_image { 'hklement/ubuntu-jruby:latest' }
file_type { association :dot_rb, user: user } file_type { association :dot_rb, user: user }
help help
@ -66,6 +70,7 @@ FactoryBot.define do
factory :node_js, class: 'ExecutionEnvironment' do factory :node_js, class: 'ExecutionEnvironment' do
created_by_teacher created_by_teacher
default_memory_limit default_memory_limit
default_cpu_limit
docker_image { 'hklement/ubuntu-node:latest' } docker_image { 'hklement/ubuntu-node:latest' }
file_type { association :dot_js, user: user } file_type { association :dot_js, user: user }
help help
@ -80,6 +85,7 @@ FactoryBot.define do
factory :python, class: 'ExecutionEnvironment' do factory :python, class: 'ExecutionEnvironment' do
created_by_teacher created_by_teacher
default_memory_limit default_memory_limit
default_cpu_limit
docker_image { 'openhpi/co_execenv_python:3.4' } docker_image { 'openhpi/co_execenv_python:3.4' }
file_type { association :dot_py, user: user } file_type { association :dot_py, user: user }
help help
@ -96,6 +102,7 @@ FactoryBot.define do
factory :ruby, class: 'ExecutionEnvironment' do factory :ruby, class: 'ExecutionEnvironment' do
created_by_teacher created_by_teacher
default_memory_limit default_memory_limit
default_cpu_limit
docker_image { 'hklement/ubuntu-ruby:latest' } docker_image { 'hklement/ubuntu-ruby:latest' }
file_type { association :dot_rb, user: user } file_type { association :dot_rb, user: user }
help help
@ -112,6 +119,7 @@ FactoryBot.define do
factory :sinatra, class: 'ExecutionEnvironment' do factory :sinatra, class: 'ExecutionEnvironment' do
created_by_teacher created_by_teacher
default_memory_limit default_memory_limit
default_cpu_limit
docker_image { 'hklement/ubuntu-sinatra:latest' } docker_image { 'hklement/ubuntu-sinatra:latest' }
file_type { association :dot_rb, user: user } file_type { association :dot_rb, user: user }
exposed_ports { '4567' } exposed_ports { '4567' }
@ -129,6 +137,7 @@ FactoryBot.define do
factory :sqlite, class: 'ExecutionEnvironment' do factory :sqlite, class: 'ExecutionEnvironment' do
created_by_teacher created_by_teacher
default_memory_limit default_memory_limit
default_cpu_limit
docker_image { 'hklement/ubuntu-sqlite:latest' } docker_image { 'hklement/ubuntu-sqlite:latest' }
file_type { association :dot_sql, user: user } file_type { association :dot_sql, user: user }
help help
@ -146,6 +155,10 @@ FactoryBot.define do
memory_limit { DockerClient::DEFAULT_MEMORY_LIMIT } memory_limit { DockerClient::DEFAULT_MEMORY_LIMIT }
end end
trait :default_cpu_limit do
cpu_limit { 20 }
end
trait :help do trait :help do
help { Forgery(:lorem_ipsum).words(Forgery(:basic).number(at_least: 50, at_most: 100)) } help { Forgery(:lorem_ipsum).words(Forgery(:basic).number(at_least: 50, at_most: 100)) }
end end

View File

@ -30,6 +30,21 @@ describe ExecutionEnvironment do
expect(execution_environment.errors[:memory_limit]).to be_present expect(execution_environment.errors[:memory_limit]).to be_present
end end
it 'validates the minimum value of the cpu limit' do
execution_environment.update(cpu_limit: 0)
expect(execution_environment.errors[:cpu_limit]).to be_present
end
it 'validates that cpu limit is an integer' do
execution_environment.update(cpu_limit: Math::PI)
expect(execution_environment.errors[:cpu_limit]).to be_present
end
it 'validates the presence of a cpu limit' do
execution_environment.update(cpu_limit: nil)
expect(execution_environment.errors[:cpu_limit]).to be_present
end
it 'validates the presence of a name' do it 'validates the presence of a name' do
expect(execution_environment.errors[:name]).to be_present expect(execution_environment.errors[:name]).to be_present
end end
@ -69,6 +84,14 @@ describe ExecutionEnvironment do
expect(execution_environment.errors[:user_type]).to be_present expect(execution_environment.errors[:user_type]).to be_present
end end
it 'validates the format of the exposed ports' do
execution_environment.update(exposed_ports: '1,')
expect(execution_environment.errors[:exposed_ports]).to be_present
execution_environment.update(exposed_ports: '1,a')
expect(execution_environment.errors[:exposed_ports]).to be_present
end
describe '#valid_test_setup?' do describe '#valid_test_setup?' do
context 'with a test command and a testing framework' do context 'with a test command and a testing framework' do
before { execution_environment.update(test_command: FactoryBot.attributes_for(:ruby)[:test_command], testing_framework: FactoryBot.attributes_for(:ruby)[:testing_framework]) } before { execution_environment.update(test_command: FactoryBot.attributes_for(:ruby)[:test_command], testing_framework: FactoryBot.attributes_for(:ruby)[:testing_framework]) }
@ -153,4 +176,56 @@ describe ExecutionEnvironment do
end end
end end
end end
describe '#exposed_ports_list' do
it 'returns an empty array if no ports are exposed' do
execution_environment.exposed_ports = nil
expect(execution_environment.exposed_ports_list).to eq([])
end
it 'returns an array of integers representing the exposed ports' do
execution_environment.exposed_ports = '1,2,3'
expect(execution_environment.exposed_ports_list).to eq([1, 2, 3])
execution_environment.exposed_ports_list.each do |port|
expect(execution_environment.exposed_ports).to include(port.to_s)
end
end
end
describe '#copy_to_poseidon' do
let(:execution_environment) { FactoryBot.create(:ruby) }
it 'makes the correct request to Poseidon' do
allow(Faraday).to receive(:put).and_return(Faraday::Response.new(status: 201))
execution_environment.copy_to_poseidon
expect(Faraday).to have_received(:put) do |url, body, headers|
expect(url).to match(%r{execution-environments/#{execution_environment.id}\z})
expect(body).to eq(execution_environment.to_json)
expect(headers).to include({'Content-Type' => 'application/json'})
end
end
shared_examples 'returns true when the api request was successful' do |status|
it "returns true on status #{status}" do
allow(Faraday).to receive(:put).and_return(Faraday::Response.new(status: status))
expect(execution_environment.copy_to_poseidon).to be_truthy
end
end
shared_examples 'returns false when the api request failed' do |status|
it "returns false on status #{status}" do
allow(Faraday).to receive(:put).and_return(Faraday::Response.new(status: status))
expect(execution_environment.copy_to_poseidon).to be_falsey
end
end
[201, 204].each do |status|
include_examples 'returns true when the api request was successful', status
end
[400, 500].each do |status|
include_examples 'returns false when the api request failed', status
end
end
end end