Extract structured errors on run and submit
This commit is contained in:
@ -9,6 +9,14 @@ module SubmissionScoring
|
|||||||
assessment = assessor.assess(output)
|
assessment = assessor.assess(output)
|
||||||
passed = ((assessment[:passed] == assessment[:count]) and (assessment[:score] > 0))
|
passed = ((assessment[:passed] == assessment[:count]) and (assessment[:score] > 0))
|
||||||
testrun_output = passed ? nil : output[:stderr]
|
testrun_output = passed ? nil : output[:stderr]
|
||||||
|
if !testrun_output.blank?
|
||||||
|
submission.exercise.execution_environment.error_templates.each do |template|
|
||||||
|
pattern = Regexp.new(template.signature).freeze
|
||||||
|
if pattern.match(testrun_output)
|
||||||
|
StructuredError.create_from_template(template, testrun_output)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Testrun.new(submission: submission, file: file, passed: passed, output: testrun_output).save
|
Testrun.new(submission: submission, file: file, passed: passed, output: testrun_output).save
|
||||||
output.merge!(assessment)
|
output.merge!(assessment)
|
||||||
output.merge!(filename: file.name_with_extension, message: feedback_message(file, output[:score]), weight: file.weight)
|
output.merge!(filename: file.name_with_extension, message: feedback_message(file, output[:score]), weight: file.weight)
|
||||||
|
@ -6,7 +6,7 @@ class SubmissionsController < ApplicationController
|
|||||||
include SubmissionScoring
|
include SubmissionScoring
|
||||||
include Tubesock::Hijack
|
include Tubesock::Hijack
|
||||||
|
|
||||||
before_action :set_submission, only: [:download, :download_file, :render_file, :run, :score, :show, :statistics, :stop, :test]
|
before_action :set_submission, only: [:download, :download_file, :render_file, :run, :score, :extract_errors, :show, :statistics, :stop, :test]
|
||||||
before_action :set_docker_client, only: [:run, :test]
|
before_action :set_docker_client, only: [:run, :test]
|
||||||
before_action :set_files, only: [:download, :download_file, :render_file, :show]
|
before_action :set_files, only: [:download, :download_file, :render_file, :show]
|
||||||
before_action :set_file, only: [:download_file, :render_file]
|
before_action :set_file, only: [:download_file, :render_file]
|
||||||
@ -187,6 +187,9 @@ class SubmissionsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def kill_socket(tubesock)
|
def kill_socket(tubesock)
|
||||||
|
# search for errors and save them as StructuredError (for scoring runs see submission_scoring.rb)
|
||||||
|
extract_errors
|
||||||
|
|
||||||
# save the output of this "run" as a "testrun" (scoring runs are saved in submission_scoring.rb)
|
# save the output of this "run" as a "testrun" (scoring runs are saved in submission_scoring.rb)
|
||||||
save_run_output
|
save_run_output
|
||||||
|
|
||||||
@ -195,6 +198,17 @@ class SubmissionsController < ApplicationController
|
|||||||
tubesock.close
|
tubesock.close
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def extract_errors
|
||||||
|
if !@message_buffer.blank?
|
||||||
|
@submission.exercise.execution_environment.error_templates.each do |template|
|
||||||
|
pattern = Regexp.new(template.signature).freeze
|
||||||
|
if pattern.match?(@message_buffer)
|
||||||
|
StructuredError.create_from_template(template, @message_buffer)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def handle_message(message, tubesock, container)
|
def handle_message(message, tubesock, container)
|
||||||
@message_buffer ||= ""
|
@message_buffer ||= ""
|
||||||
# Handle special commands first
|
# Handle special commands first
|
||||||
|
@ -1,4 +1,12 @@
|
|||||||
class StructuredError < ActiveRecord::Base
|
class StructuredError < ActiveRecord::Base
|
||||||
belongs_to :error_template
|
belongs_to :error_template
|
||||||
belongs_to :file, class_name: 'CodeOcean::File'
|
belongs_to :file, class_name: 'CodeOcean::File'
|
||||||
|
|
||||||
|
def self.create_from_template(template, message_buffer)
|
||||||
|
instance = self.create(error_template: template)
|
||||||
|
template.error_template_attributes.each do |attribute|
|
||||||
|
StructuredErrorAttribute.create_from_template(attribute, instance, message_buffer)
|
||||||
|
end
|
||||||
|
instance
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
class StructuredErrorAttribute < ActiveRecord::Base
|
class StructuredErrorAttribute < ActiveRecord::Base
|
||||||
belongs_to :structured_error
|
belongs_to :structured_error
|
||||||
belongs_to :error_template_attribute
|
belongs_to :error_template_attribute
|
||||||
|
|
||||||
|
def self.create_from_template(attribute, structured_error, message_buffer)
|
||||||
|
value = message_buffer.match(attribute.regex).captures[0]
|
||||||
|
self.create(structured_error: structured_error, error_template_attribute: attribute, value: value)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Reference in New Issue
Block a user