Apply manual rubocop fixes
This commit is contained in:
@ -3,10 +3,12 @@
|
||||
module ActiveModel
|
||||
module Validations
|
||||
class BooleanPresenceValidator < EachValidator
|
||||
BOOLEAN_VALUES = [false, true].freeze
|
||||
|
||||
def validate(record)
|
||||
[attributes].flatten.each do |attribute|
|
||||
value = record.send(:read_attribute_for_validation, attribute)
|
||||
record.errors.add(attribute, nil, options) unless [false, true].include?(value)
|
||||
record.errors.add(attribute, nil, options) unless BOOLEAN_VALUES.include?(value)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -12,7 +12,7 @@ class Assessor
|
||||
|
||||
def calculate_score(test_outcome)
|
||||
score = 0.0
|
||||
if test_outcome[:passed].to_f != 0.0 && test_outcome[:count].to_f != 0.0
|
||||
if test_outcome[:passed].to_d != 0.0.to_d && test_outcome[:count].to_d != 0.0.to_d
|
||||
score = (test_outcome[:passed].to_f / test_outcome[:count])
|
||||
# prevent negative scores
|
||||
score = [0.0, score].max
|
||||
|
@ -9,7 +9,7 @@ module CodeOcean
|
||||
def read(options = {})
|
||||
path = Rails.root.join('config', "#{@filename}.yml#{options[:erb] ? '.erb' : ''}")
|
||||
if ::File.exist?(path)
|
||||
content = options[:erb] ? YAML.safe_load(ERB.new(::File.new(path, 'r').read).result) : YAML.load_file(path)
|
||||
content = options[:erb] ? YAML.safe_load(ERB.new(::File.new(path, 'r').read).result, aliases: true, permitted_classes: [Range]) : YAML.load_file(path)
|
||||
content[Rails.env].with_indifferent_access
|
||||
else
|
||||
raise Error.new("Configuration file not found: #{path}")
|
||||
|
@ -78,7 +78,7 @@ class DockerClient
|
||||
}
|
||||
end
|
||||
|
||||
def create_socket(container, stderr = false)
|
||||
def create_socket(container, stderr: false)
|
||||
# TODO: factor out query params
|
||||
# todo separate stderr
|
||||
query_params = "logs=0&stream=1&#{stderr ? 'stderr=1' : 'stdout=1&stdin=1'}"
|
||||
@ -111,7 +111,7 @@ class DockerClient
|
||||
end
|
||||
|
||||
def self.create_container(execution_environment)
|
||||
tries ||= 0
|
||||
# tries ||= 0
|
||||
# container.start sometimes creates the passed local_workspace_path on disk (depending on the setup).
|
||||
# this is however not guaranteed and caused issues on the server already. Therefore create the necessary folders manually!
|
||||
local_workspace_path = generate_local_workspace_path
|
||||
@ -133,14 +133,14 @@ class DockerClient
|
||||
Thread.new do
|
||||
timeout = SELF_DESTROY_GRACE_PERIOD.to_i
|
||||
sleep(timeout)
|
||||
container.docker_client.kill_container(container, false)
|
||||
container.docker_client.kill_container(container)
|
||||
Rails.logger.info("Force killing container in status #{container.status} after #{Time.zone.now - container.start_time} seconds.")
|
||||
ensure
|
||||
# guarantee that the thread is releasing the DB connection after it is done
|
||||
ActiveRecord::Base.connection_pool.release_connection
|
||||
end
|
||||
else
|
||||
container.docker_client.kill_container(container, false)
|
||||
container.docker_client.kill_container(container)
|
||||
Rails.logger.info("Killing container in status #{container.status} after #{Time.zone.now - container.start_time} seconds.")
|
||||
end
|
||||
ensure
|
||||
@ -280,7 +280,7 @@ class DockerClient
|
||||
{status: :container_depleted, waiting_for_container_time: waiting_for_container_time,
|
||||
container_execution_time: nil}
|
||||
end
|
||||
rescue Excon::Errors::SocketError => e
|
||||
rescue Excon::Errors::SocketError
|
||||
# socket errors seems to be normal when using exec
|
||||
# so lets ignore them for now
|
||||
# (tries += 1) <= RETRY_COUNT ? retry : raise(error)
|
||||
@ -310,10 +310,8 @@ container_execution_time: nil}
|
||||
end
|
||||
|
||||
def kill_after_timeout(container)
|
||||
"
|
||||
We need to start a second thread to kill the websocket connection,
|
||||
as it is impossible to determine whether further input is requested.
|
||||
"
|
||||
# We need to start a second thread to kill the websocket connection,
|
||||
# as it is impossible to determine whether further input is requested.
|
||||
container.status = :executing
|
||||
@thread = Thread.new do
|
||||
timeout = @execution_environment.permitted_execution_time.to_i # seconds
|
||||
@ -365,16 +363,14 @@ container_execution_time: nil}
|
||||
end
|
||||
end
|
||||
|
||||
def kill_container(container, _create_new = true)
|
||||
def kill_container(container)
|
||||
exit_thread_if_alive
|
||||
Rails.logger.info("killing container #{container}")
|
||||
self.class.destroy_container(container)
|
||||
end
|
||||
|
||||
def execute_run_command(submission, filename, &block)
|
||||
"
|
||||
Run commands by attaching a websocket to Docker.
|
||||
"
|
||||
# Run commands by attaching a websocket to Docker.
|
||||
filepath = submission.collect_files.find {|f| f.name_with_extension == filename }.filepath
|
||||
command = submission.execution_environment.run_command % command_substitutions(filepath)
|
||||
create_workspace_files = proc { create_workspace_files(container, submission) }
|
||||
@ -383,9 +379,7 @@ container_execution_time: nil}
|
||||
end
|
||||
|
||||
def execute_test_command(submission, filename, &block)
|
||||
"
|
||||
Stick to existing Docker API with exec command.
|
||||
"
|
||||
# Stick to existing Docker API with exec command.
|
||||
file = submission.collect_files.find {|f| f.name_with_extension == filename }
|
||||
filepath = file.filepath
|
||||
command = submission.execution_environment.test_command % command_substitutions(filepath)
|
||||
@ -495,26 +489,23 @@ container_execution_time: nil}
|
||||
if output.nil?
|
||||
kill_container(container)
|
||||
else
|
||||
result = {status: (output[2]).zero? ? :ok : :failed, stdout: output[0].join.force_encoding('utf-8'),
|
||||
stderr: output[1].join.force_encoding('utf-8')}
|
||||
result = {status: (output[2])&.zero? ? :ok : :failed, stdout: output[0].join.force_encoding('utf-8'), stderr: output[1].join.force_encoding('utf-8')}
|
||||
end
|
||||
|
||||
# if we use pooling and recylce the containers, put it back. otherwise, destroy it.
|
||||
if DockerContainerPool.config[:active] && RECYCLE_CONTAINERS
|
||||
self.class.return_container(container,
|
||||
@execution_environment)
|
||||
self.class.return_container(container, @execution_environment)
|
||||
else
|
||||
self.class.destroy_container(container)
|
||||
end
|
||||
result
|
||||
rescue Timeout::Error
|
||||
Rails.logger.info("got timeout error for container #{container}")
|
||||
stdout = container.exec(['cat', '/tmp/stdout.log'])[0].join.force_encoding('utf-8')
|
||||
stderr = container.exec(['cat', '/tmp/stderr.log'])[0].join.force_encoding('utf-8')
|
||||
stdout = container.exec(%w[cat /tmp/stdout.log])[0].join.force_encoding('utf-8')
|
||||
stderr = container.exec(%w[cat /tmp/stderr.log])[0].join.force_encoding('utf-8')
|
||||
kill_container(container)
|
||||
{status: :timeout, stdout: stdout, stderr: stderr}
|
||||
end
|
||||
|
||||
private :send_command
|
||||
|
||||
class Error < RuntimeError; end
|
||||
|
@ -52,9 +52,7 @@ class FileTree < Tree::TreeNode
|
||||
private :map_to_js_tree
|
||||
|
||||
def node_icon(node)
|
||||
if node.is_root?
|
||||
folder_icon
|
||||
elsif node.is_leaf?
|
||||
if node.is_leaf? && !node.is_root?
|
||||
file_icon(node.content)
|
||||
else
|
||||
folder_icon
|
||||
|
@ -9,13 +9,9 @@ class Python20CourseWeek
|
||||
2
|
||||
when /Python20 Aufgabe 3/
|
||||
3
|
||||
when /Python20 Aufgabe 4/
|
||||
when /Python20 Aufgabe 4/, /Python20 Snake/
|
||||
4
|
||||
when /Python20 Snake/
|
||||
4
|
||||
else
|
||||
# Not part of the Python20 course
|
||||
nil
|
||||
# else: Not part of the Python20 course
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -81,7 +81,7 @@ namespace :detect_exercise_anomalies do
|
||||
def find_anomalies(collection)
|
||||
working_times = collect_working_times(collection).compact
|
||||
if working_times.values.size.positive?
|
||||
average = working_times.values.reduce(:+) / working_times.values.size
|
||||
average = working_times.values.sum / working_times.values.size
|
||||
return working_times.select do |_, working_time|
|
||||
working_time > average * MAX_TIME_FACTOR or working_time < average * MIN_TIME_FACTOR
|
||||
end
|
||||
@ -120,7 +120,8 @@ namespace :detect_exercise_anomalies do
|
||||
users_to_notify = []
|
||||
|
||||
users = {}
|
||||
%i[performers_by_time performers_by_score].each do |method|
|
||||
methods = %i[performers_by_time performers_by_score]
|
||||
methods.each do |method|
|
||||
# merge users found by multiple methods returning a hash {best: [], worst: []}
|
||||
users = users.merge(send(method, exercise, NUMBER_OF_USERS_PER_CLASS)) {|_key, this, other| this + other }
|
||||
end
|
||||
|
Reference in New Issue
Block a user