Merge pull request #1237 from openHPI/aws_experiment

Prepare AWS Experiment
This commit is contained in:
Sebastian Serth
2022-04-18 21:18:29 +02:00
committed by GitHub
9 changed files with 81 additions and 3 deletions

View File

@ -294,7 +294,7 @@ class SubmissionsController < ApplicationController
# save the output of this "run" as a "testrun" (scoring runs are saved in submission.rb)
def save_run_output
Testrun.create(
testrun = Testrun.create(
file: @file,
cause: 'run',
submission: @submission,
@ -302,6 +302,7 @@ class SubmissionsController < ApplicationController
container_execution_time: @container_execution_time,
waiting_for_container_time: @waiting_for_container_time
)
TestrunExecutionEnvironment.create(testrun: testrun, execution_environment: @submission.used_execution_environment)
end
def send_hints(tubesock, errors)

View File

@ -16,6 +16,7 @@ class ExecutionEnvironment < ApplicationRecord
has_many :exercises
belongs_to :file_type
has_many :error_templates
belongs_to :testrun_execution_environment, optional: true, dependent: :destroy
scope :with_exercises, -> { where('id IN (SELECT execution_environment_id FROM exercises)') }

View File

@ -46,6 +46,8 @@ class Submission < ApplicationRecord
validates :cause, inclusion: {in: CAUSES}
attr_reader :used_execution_environment
# after_save :trigger_working_times_action_cable
def build_files_hash(files, attribute)
@ -195,7 +197,8 @@ class Submission < ApplicationRecord
def prepared_runner
request_time = Time.zone.now
begin
runner = Runner.for(user, exercise.execution_environment)
@used_execution_environment = AwsStudy.get_execution_environment(user, exercise)
runner = Runner.for(user, @used_execution_environment)
files = collect_files
files.reject!(&:teacher_defined_assessment?) if cause == 'run'
Rails.logger.debug { "#{Time.zone.now.getutc.inspect}: Copying files to Runner #{runner.id} for #{user_type} #{user_id} and Submission #{id}." }
@ -253,6 +256,7 @@ class Submission < ApplicationRecord
container_execution_time: output[:container_execution_time],
waiting_for_container_time: output[:waiting_for_container_time]
)
TestrunExecutionEnvironment.create(testrun: testrun, execution_environment: @used_execution_environment)
filename = file.filepath

View File

@ -3,4 +3,5 @@
class Testrun < ApplicationRecord
belongs_to :file, class_name: 'CodeOcean::File', optional: true
belongs_to :submission
belongs_to :testrun_execution_environment, optional: true, dependent: :destroy
end

View File

@ -0,0 +1,6 @@
# frozen_string_literal: true
class TestrunExecutionEnvironment < ApplicationRecord
belongs_to :testrun
belongs_to :execution_environment
end

View File

@ -0,0 +1,12 @@
# frozen_string_literal: true
class AddTestrunExecutionEnvironment < ActiveRecord::Migration[6.1]
def change
create_table :testrun_execution_environments do |t|
t.belongs_to :testrun, foreign_key: true, null: false, index: true
t.belongs_to :execution_environment, foreign_key: true, null: false, index: {name: 'index_testrun_execution_environments'}
t.timestamps
end
end
end

View File

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2021_11_18_185051) do
ActiveRecord::Schema.define(version: 2022_04_15_125948) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_trgm"
@ -461,6 +461,15 @@ ActiveRecord::Schema.define(version: 2021_11_18_185051) do
t.datetime "updated_at"
end
create_table "testrun_execution_environments", force: :cascade do |t|
t.bigint "testrun_id", null: false
t.bigint "execution_environment_id", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["execution_environment_id"], name: "index_testrun_execution_environments"
t.index ["testrun_id"], name: "index_testrun_execution_environments_on_testrun_id"
end
create_table "testruns", id: :serial, force: :cascade do |t|
t.boolean "passed"
t.text "output"
@ -536,6 +545,8 @@ ActiveRecord::Schema.define(version: 2021_11_18_185051) do
add_foreign_key "exercise_tips", "tips"
add_foreign_key "remote_evaluation_mappings", "study_groups"
add_foreign_key "submissions", "study_groups"
add_foreign_key "testrun_execution_environments", "execution_environments"
add_foreign_key "testrun_execution_environments", "testruns"
add_foreign_key "tips", "file_types"
add_foreign_key "user_exercise_feedbacks", "submissions"
end

30
lib/aws_study.rb Normal file
View File

@ -0,0 +1,30 @@
# frozen_string_literal: true
class AwsStudy
def self.get_for(exercise)
java20_collection = ExerciseCollection.find_by(name: 'java2020', id: 11)
java20_bonus_collection = ExerciseCollection.find_by(name: 'java2020-bonusexercise', id: 12)
exercise.exercise_collections.any? {|ec| [java20_collection, java20_bonus_collection].include?(ec) }
end
def self.get_execution_environment(user, exercise)
# Poseidon is disabled and thus no AWS support available
return exercise.execution_environment unless Runner::Strategy::Poseidon == Runner.strategy_class
java20_exercise = get_for(exercise)
# Exercise is not part of the experiment
return exercise.execution_environment unless java20_exercise
user_group = UserGroupSeparator.get_aws_group(user.id)
case user_group
when :use_aws
# AWS functions are currently identified with their name
aws_function = ExecutionEnvironment.find_by(docker_image: 'java11Exec')
# Fallback to the default execution environment if no AWS function is found
aws_function || exercise.execution_environment
else # :no_aws
exercise.execution_environment
end
end
end

View File

@ -32,4 +32,16 @@ class UserGroupSeparator
:no_community_solution
end
end
# Different user groups for using AWS lambda functions instead of Nomad based on the user_id
# This test is independent from any other A/B Test
def self.get_aws_group(user_id)
user_group = user_id % 2 # => 0, 1
case user_group
when 0
:no_aws
else # 1
:use_aws
end
end
end