Refactoring main invocation path to return error codes
This commit is contained in:
@@ -9,9 +9,8 @@ module Pipeline::Rpc::Worker
|
||||
@return_address = return_address
|
||||
end
|
||||
|
||||
def setup(track_slug, version, exercise_slug, solution_slug)
|
||||
track_dir = environment.track_dir(track_slug, version)
|
||||
Pipeline::Runtime::AnalysisRun.new(track_dir, exercise_slug, solution_slug)
|
||||
def setup_container_run(track_dir, exercise_slug, job_slug)
|
||||
Pipeline::Runtime::AnalysisRun.new(track_dir, exercise_slug, job_slug)
|
||||
end
|
||||
|
||||
def prepare_folder(iteration_folder)
|
||||
|
||||
@@ -2,50 +2,93 @@ module Pipeline::Rpc::Worker
|
||||
|
||||
class ContainerAction < WorkerAction
|
||||
|
||||
attr_reader :reader, :return_address, :s3
|
||||
attr_reader :reader, :return_address, :s3, :track_slug, :container_version
|
||||
|
||||
def initialize(request, return_address)
|
||||
@request = request
|
||||
@return_address = return_address
|
||||
end
|
||||
|
||||
def setup(track_slug, version, exercise_slug, job_slug)
|
||||
track_dir = environment.track_dir(track_slug, version)
|
||||
Pipeline::Runtime::AnalysisRun.new(track_dir, exercise_slug, job_slug)
|
||||
end
|
||||
|
||||
def invoke
|
||||
@s3 = Aws::S3::Client.new(
|
||||
credentials: parse_credentials(request["context"]),
|
||||
region: "eu-west-1")
|
||||
|
||||
language_slug = request["track_slug"]
|
||||
exercise_slug = request["exercise_slug"]
|
||||
job_slug = request["id"]
|
||||
container_version = request["container_version"]
|
||||
@track_slug = request["track_slug"]
|
||||
@exercise_slug = request["exercise_slug"]
|
||||
@job_slug = request["id"]
|
||||
@container_version = request["container_version"]
|
||||
|
||||
unless environment.released?(language_slug, container_version)
|
||||
return {
|
||||
error: "Container #{language_slug}:#{container_version} isn't available"
|
||||
check_container
|
||||
setup_run unless @error
|
||||
prepare_input unless @error
|
||||
run_container unless @error
|
||||
|
||||
response = {return_address: return_address}
|
||||
|
||||
if @error
|
||||
response[:msg_type] = :error_response
|
||||
response.merge(@error)
|
||||
else
|
||||
response[:msg_type] = :response
|
||||
response[:return_address] = return_address
|
||||
response.merge(@result)
|
||||
end
|
||||
end
|
||||
|
||||
def check_container
|
||||
unless environment.released?(track_slug, container_version)
|
||||
@error = {
|
||||
status_code: 404,
|
||||
error: "Container #{track_slug}:#{container_version} isn't available"
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def setup_run
|
||||
track_dir = environment.track_dir(track_slug, container_version)
|
||||
|
||||
analysis_run = setup(language_slug, container_version, exercise_slug, job_slug)
|
||||
analysis_run.prepare_iteration do |iteration_folder|
|
||||
prepare_folder(iteration_folder)
|
||||
end
|
||||
begin
|
||||
result = analysis_run.analyze!
|
||||
result["return_address"] = return_address
|
||||
result['msg_type'] = 'response'
|
||||
result
|
||||
@analysis_run = setup_container_run(track_dir, @exercise_slug, @job_slug)
|
||||
rescue => e
|
||||
puts e
|
||||
ensure
|
||||
puts "DONE"
|
||||
@error = {
|
||||
status_code: 500,
|
||||
error: "Failure setting up job",
|
||||
detail: e
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def prepare_input
|
||||
begin
|
||||
@analysis_run.prepare_iteration do |iteration_folder|
|
||||
prepare_folder(iteration_folder)
|
||||
end
|
||||
rescue => e
|
||||
@error = {
|
||||
status_code: 500,
|
||||
error: "Failure preparing input",
|
||||
detail: e
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def run_container
|
||||
begin
|
||||
@result = @analysis_run.analyze!
|
||||
rescue => e
|
||||
@error = {
|
||||
status_code: 500,
|
||||
error: "Error from container",
|
||||
detail: e
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def setup_container_run(track_dir, exercise_slug, job_slug)
|
||||
raise "Please create run command"
|
||||
end
|
||||
|
||||
def prepare_folder(iteration_folder)
|
||||
raise "Please prepare input"
|
||||
end
|
||||
|
||||
@@ -6,9 +6,8 @@ module Pipeline::Rpc::Worker
|
||||
super(request, return_address)
|
||||
end
|
||||
|
||||
def setup(track_slug, version, exercise_slug, solution_slug)
|
||||
track_dir = environment.track_dir(track_slug, version)
|
||||
Pipeline::Runtime::RepresentRun.new(track_dir, exercise_slug, solution_slug)
|
||||
def setup_container_run(track_dir, exercise_slug, job_slug)
|
||||
Pipeline::Runtime::RepresentRun.new(track_dir, exercise_slug, job_slug)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -6,9 +6,8 @@ module Pipeline::Rpc::Worker
|
||||
super(request, return_address)
|
||||
end
|
||||
|
||||
def setup(track_slug, version, exercise_slug, solution_slug)
|
||||
track_dir = environment.track_dir(track_slug, version)
|
||||
Pipeline::Runtime::TestRun.new(track_dir, exercise_slug, solution_slug)
|
||||
def setup_container_run(track_dir, exercise_slug, job_slug)
|
||||
Pipeline::Runtime::TestRun.new(track_dir, exercise_slug, job_slug)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
108
test/pipeline/rpc/worker/container_action_test.rb
Normal file
108
test/pipeline/rpc/worker/container_action_test.rb
Normal file
@@ -0,0 +1,108 @@
|
||||
require 'test_helper'
|
||||
|
||||
class Pipeline::Rpc::Worker::WorkerActionTest < Minitest::Test
|
||||
|
||||
def setup
|
||||
@credentials = {
|
||||
"access_key_id" => "ACCESS_KEY_ID",
|
||||
"secret_access_key" => "SECRET_KEY",
|
||||
"session_token" => "SESSION",
|
||||
}
|
||||
@request = {
|
||||
"context" => { "credentials" => @credentials },
|
||||
"track_slug" => "demo",
|
||||
"exercise_slug" => "my-exercise",
|
||||
"id" => "my-input-id",
|
||||
"container_version" => "abcdef"
|
||||
}
|
||||
@return_address = "_return_address"
|
||||
@environment = mock()
|
||||
@action = Pipeline::Rpc::Worker::ContainerAction.new(@request, @return_address)
|
||||
@action.environment = @environment
|
||||
end
|
||||
|
||||
def test_prepare_folder_raises
|
||||
error = assert_raises do
|
||||
@action.prepare_folder("/tmp/my_folder")
|
||||
end
|
||||
assert_equal "Please prepare input", error.message
|
||||
end
|
||||
|
||||
def test_setup_container_run
|
||||
error = assert_raises do
|
||||
@action.setup_container_run("/tmp/my_folder", "foo", "bar")
|
||||
end
|
||||
assert_equal "Please create run command", error.message
|
||||
end
|
||||
|
||||
def test_invoke_when_correct_container_is_not_released
|
||||
@environment.expects(:released?).with("demo", "abcdef").returns(false)
|
||||
result = @action.invoke
|
||||
assert_equal 404, result[:status_code]
|
||||
assert_equal "Container demo:abcdef isn't available", result[:error]
|
||||
assert_equal :error_response, result[:msg_type]
|
||||
end
|
||||
|
||||
def test_invoke_when_set_fails
|
||||
@environment.expects(:released?).with("demo", "abcdef").returns(true)
|
||||
@environment.expects(:track_dir).with("demo", "abcdef").returns("/tmp/foobar")
|
||||
|
||||
@action.expects(:setup_container_run).raises("Ouch! Couldn't setup job")
|
||||
|
||||
result = @action.invoke
|
||||
assert_equal 500, result[:status_code]
|
||||
assert_equal "Failure setting up job", result[:error]
|
||||
assert_equal :error_response, result[:msg_type]
|
||||
end
|
||||
|
||||
def test_invoke_when_prepare_iteration_fails
|
||||
@environment.expects(:released?).with("demo", "abcdef").returns(true)
|
||||
@environment.expects(:track_dir).with("demo", "abcdef").returns("/tmp/foobar")
|
||||
|
||||
@stub_job_invoker = mock()
|
||||
@stub_job_invoker.expects(:prepare_iteration).raises("Ouch! Couldn't prepare input")
|
||||
@stub_job_invoker.expects(:analyze!).never
|
||||
|
||||
@action.expects(:setup_container_run).with("/tmp/foobar", "my-exercise", "my-input-id").returns @stub_job_invoker
|
||||
|
||||
result = @action.invoke
|
||||
assert_equal 500, result[:status_code]
|
||||
assert_equal "Failure preparing input", result[:error]
|
||||
assert_equal :error_response, result[:msg_type]
|
||||
end
|
||||
|
||||
def test_invoke_when_container_errors
|
||||
@environment.expects(:released?).with("demo", "abcdef").returns(true)
|
||||
@environment.expects(:track_dir).with("demo", "abcdef").returns("/tmp/foobar")
|
||||
|
||||
@stub_job_invoker = mock()
|
||||
@stub_job_invoker.expects(:prepare_iteration)
|
||||
@stub_job_invoker.expects(:analyze!).raises("Container error")
|
||||
|
||||
@action.expects(:setup_container_run).with("/tmp/foobar", "my-exercise", "my-input-id").returns @stub_job_invoker
|
||||
|
||||
result = @action.invoke
|
||||
assert_equal 500, result[:status_code]
|
||||
assert_equal "Error from container", result[:error]
|
||||
assert_equal :error_response, result[:msg_type]
|
||||
end
|
||||
|
||||
def test_invoke
|
||||
@invocation_result = { a: 1, b: 2 }
|
||||
|
||||
@environment.expects(:released?).with("demo", "abcdef").returns(true)
|
||||
@environment.expects(:track_dir).with("demo", "abcdef").returns("/tmp/foobar")
|
||||
|
||||
@stub_job_invoker = mock()
|
||||
@stub_job_invoker.expects(:prepare_iteration)
|
||||
@stub_job_invoker.expects(:analyze!).returns(@invocation_result)
|
||||
|
||||
@action.expects(:setup_container_run).with("/tmp/foobar", "my-exercise", "my-input-id").returns @stub_job_invoker
|
||||
|
||||
result = @action.invoke
|
||||
assert_equal 1, result[:a]
|
||||
assert_equal 2, result[:b]
|
||||
assert_equal :response, result[:msg_type]
|
||||
end
|
||||
|
||||
end
|
||||
31
test/pipeline/rpc/worker/worker_action_test.rb
Normal file
31
test/pipeline/rpc/worker/worker_action_test.rb
Normal file
@@ -0,0 +1,31 @@
|
||||
require 'test_helper'
|
||||
require 'json'
|
||||
|
||||
class Pipeline::Rpc::Worker::WorkerActionTest < Minitest::Test
|
||||
|
||||
def setup
|
||||
@action = Pipeline::Rpc::Worker::WorkerAction.new
|
||||
end
|
||||
|
||||
def test_invoke_does_nothing
|
||||
@action.invoke
|
||||
end
|
||||
|
||||
def test_parse_credentials
|
||||
@credentials = {
|
||||
"access_key_id" => "ACCESS_KEY_ID",
|
||||
"secret_access_key" => "SECRET_KEY",
|
||||
"session_token" => "SESSION",
|
||||
}
|
||||
@request = {
|
||||
"credentials" => @credentials
|
||||
}
|
||||
credentials = @action.parse_credentials(@request)
|
||||
|
||||
assert_equal Aws::Credentials, credentials.class
|
||||
assert_equal "ACCESS_KEY_ID", credentials.access_key_id
|
||||
assert_equal "SECRET_KEY", credentials.secret_access_key
|
||||
assert_equal "SESSION", credentials.session_token
|
||||
end
|
||||
|
||||
end
|
||||
Reference in New Issue
Block a user