Show More
Commit Description:
removed many 'system' invokations
Commit Description:
removed many 'system' invokations
References:
File last commit:
Show/Diff file:
Action:
lib/engine.rb
| 186 lines
| 4.6 KiB
| text/x-ruby
| RubyLexer
|
|
r23 | require 'fileutils' | ||
|
r78 | require File.join(File.dirname(__FILE__),'dir_init') | ||
|
r22 | |||
module Grader | ||||
|
r23 | # | ||
# A grader engine grades a submission, against anything: a test | ||||
# data, or a user submitted test data. It uses two helpers objects: | ||||
# room_maker and reporter. | ||||
# | ||||
|
r22 | class Engine | ||
|
r23 | |||
attr_writer :room_maker | ||||
attr_writer :reporter | ||||
|
r22 | |||
|
r92 | def initialize(options={}) | ||
# default options | ||||
if not options.include? :room_maker | ||||
options[:room_maker] = Grader::SubmissionRoomMaker.new | ||||
end | ||||
if not options.include? :reporter | ||||
options[:reporter] = Grader::SubmissionReporter.new | ||||
end | ||||
|
r22 | @config = Grader::Configuration.get_instance | ||
|
r23 | |||
|
r92 | @room_maker = options[:room_maker] | ||
@reporter = options[:reporter] | ||||
|
r22 | end | ||
|
r23 | |||
# takes a submission, asks room_maker to produce grading directories, | ||||
# calls grader scripts, and asks reporter to save the result | ||||
def grade(submission) | ||||
|
r22 | current_dir = `pwd`.chomp | ||
|
r23 | user = submission.user | ||
problem = submission.problem | ||||
|
r22 | |||
# TODO: will have to create real exception for this | ||||
|
r23 | if user==nil or problem == nil | ||
@reporter.report_error(submission,"Grading error: problem with submission") | ||||
#raise "engine: user or problem is nil" | ||||
end | ||||
|
r50 | |||
# TODO: this is another hack so that output only task can be judged | ||||
if submission.language!=nil | ||||
language = submission.language.name | ||||
lang_ext = submission.language.ext | ||||
else | ||||
language = 'c' | ||||
lang_ext = 'c' | ||||
end | ||||
|
r22 | # FIX THIS | ||
talk 'some hack on language' | ||||
if language == 'cpp' | ||||
language = 'c++' | ||||
end | ||||
|
r23 | # COMMENT: should it be only source.ext? | ||
if problem!=nil | ||||
source_name = "#{problem.name}.#{lang_ext}" | ||||
else | ||||
source_name = "source.#{lang_ext}" | ||||
end | ||||
|
r22 | |||
|
r23 | begin | ||
grading_dir = @room_maker.produce_grading_room(submission) | ||||
@room_maker.save_source(submission,source_name) | ||||
problem_home = @room_maker.find_problem_home(submission) | ||||
# puts "GRADING DIR: #{grading_dir}" | ||||
# puts "PROBLEM DIR: #{problem_home}" | ||||
|
r22 | |||
|
r83 | if !FileTest.exist?(problem_home) | ||
raise "No test data." | ||||
end | ||||
|
r71 | dinit = DirInit::Manager.new(problem_home) | ||
dinit.setup do | ||||
copy_log = copy_script(problem_home) | ||||
save_copy_log(problem_home,copy_log) | ||||
end | ||||
|
r23 | |||
call_judge(problem_home,language,grading_dir,source_name) | ||||
@reporter.report(submission,"#{grading_dir}/test-result") | ||||
|
r22 | |||
|
r71 | dinit.teardown do | ||
copy_log = load_copy_log(problem_home) | ||||
clear_copy_log(problem_home) | ||||
clear_script(copy_log,problem_home) | ||||
end | ||||
|
r23 | |||
rescue RuntimeError => msg | ||||
|
r83 | @reporter.report_error(submission, msg) | ||
|
r23 | |||
ensure | ||||
@room_maker.clean_up(submission) | ||||
Dir.chdir(current_dir) # this is really important | ||||
|
r22 | end | ||
end | ||||
|
r23 | |||
|
r22 | protected | ||
def talk(str) | ||||
if @config.talkative | ||||
puts str | ||||
end | ||||
end | ||||
|
r23 | def call_judge(problem_home,language,grading_dir,fname) | ||
|
r22 | ENV['PROBLEM_HOME'] = problem_home | ||
|
r23 | talk grading_dir | ||
Dir.chdir grading_dir | ||||
|
r22 | cmd = "#{problem_home}/script/judge #{language} #{fname}" | ||
talk "CMD: #{cmd}" | ||||
system(cmd) | ||||
end | ||||
def get_std_script_dir | ||||
GRADER_ROOT + '/std-script' | ||||
end | ||||
def copy_script(problem_home) | ||||
script_dir = "#{problem_home}/script" | ||||
std_script_dir = get_std_script_dir | ||||
raise "std-script directory not found" if !FileTest.exist?(std_script_dir) | ||||
scripts = Dir[std_script_dir + '/*'] | ||||
copied = [] | ||||
scripts.each do |s| | ||||
fname = File.basename(s) | ||||
if !FileTest.exist?("#{script_dir}/#{fname}") | ||||
copied << fname | ||||
|
r101 | FileUtils.cp(s, "#{script_dir}") | ||
|
r22 | end | ||
end | ||||
return copied | ||||
end | ||||
|
r71 | |||
def copy_log_filename(problem_home) | ||||
return File.join(problem_home, '.scripts_copied') | ||||
end | ||||
def save_copy_log(problem_home, log) | ||||
f = File.new(copy_log_filename(problem_home),"w") | ||||
log.each do |fname| | ||||
f.write("#{fname}\n") | ||||
end | ||||
f.close | ||||
end | ||||
|
r22 | |||
|
r71 | def load_copy_log(problem_home) | ||
f = File.new(copy_log_filename(problem_home),"r") | ||||
log = [] | ||||
f.readlines.each do |line| | ||||
log << line.strip | ||||
end | ||||
f.close | ||||
log | ||||
end | ||||
def clear_copy_log(problem_home) | ||||
File.delete(copy_log_filename(problem_home)) | ||||
end | ||||
|
r22 | def clear_script(log,problem_home) | ||
log.each do |s| | ||||
|
r101 | FileUtils.rm("#{problem_home}/script/#{s}") | ||
|
r22 | end | ||
end | ||||
def mkdir_if_does_not_exist(dirname) | ||||
Dir.mkdir(dirname) if !FileTest.exist?(dirname) | ||||
end | ||||
end | ||||
end | ||||