Show More
Commit Description:
handle the case when problem id or submission id is null. Grader will simply skip such request. Add more report on console (for command line grading)...
Commit Description:
handle the case when problem id or submission id is null. Grader will simply skip such request. Add more report on console (for command line grading)
(mercurial grafted from d233105d3965c5368c9b33125f390e39b25f910e)
References:
File last commit:
Show/Diff file:
Action:
std-script/judge
| 175 lines
| 4.5 KiB
| text/plain
| TextLexer
|
|
r137 | #!/usr/bin/env ruby | ||
|
r0 | |||
|
r101 | require 'fileutils' | ||
|
r22 | def log(str='') | ||
if ENV['TALKATIVE']!=nil | ||||
puts str | ||||
end | ||||
if ENV['GRADER_LOGGING']!=nil | ||||
log_fname = ENV['GRADER_LOGGING'] | ||||
fp = File.open(log_fname,"a") | ||||
fp.puts("judge: #{Time.new.strftime("%H:%M")} #{str}") | ||||
fp.close | ||||
end | ||||
end | ||||
|
r0 | problem_home = ENV['PROBLEM_HOME'] | ||
def execute(command, error_message="") | ||||
if not system(command) | ||||
|
r31 | msg = "ERROR: #{error_message}" | ||
log msg | ||||
|
r137 | raise(msg) | ||
|
r0 | end | ||
end | ||||
|
r101 | def call_and_log(error_message) | ||
begin | ||||
yield | ||||
rescue | ||||
msg = "ERROR: #{error_message}" | ||||
log msg | ||||
raise msg | ||||
end | ||||
end | ||||
def clear_and_create_empty_dir(dir) | ||||
FileUtils.rm_rf(dir, :secure => true) | ||||
call_and_log("Cannot make directory #{dir}.") { FileUtils.mkdir(dir) } | ||||
end | ||||
|
r0 | # ARGV[0] --- language | ||
# ARGV[1] --- program source file | ||||
# ARGV[2] --- test result directory | ||||
# ARGV[3] --- sandbox directory | ||||
if ARGV.length < 2 || ARGV.length > 4 | ||||
puts "Usage: judge <language> <program-source> [<test-result-directory>] [<sandbox-directory>]" | ||||
puts " <sandbox-directory> is defaulted to ./sandbox" | ||||
puts " <test-result-directory> is defaulted to ./test-result" | ||||
puts "WARNING: The judge script will forcefully create the (implicitly and explicitly) specified directories and remove anything inside it." | ||||
exit(127) | ||||
end | ||||
language = ARGV[0] | ||||
|
r53 | if language != "c" && language != "c++" && language != "pas" | ||
log "You specified a language that is not supported: #{language}." | ||||
|
r0 | exit(127) | ||
end | ||||
source_file = ARGV[1] | ||||
if File.exist?(source_file) == false | ||||
|
r22 | log "The source file does not exist." | ||
|
r0 | exit(127) | ||
end | ||||
|
r22 | log "Making test result and sandbox directories..." | ||
|
r0 | |||
|
r102 | current_dir = FileUtils.pwd | ||
|
r0 | current_dir.strip! | ||
if ARGV.length >= 3 | ||||
test_result_dir = ARGV[2] | ||||
else | ||||
test_result_dir = "#{current_dir}/test-result" | ||||
end | ||||
|
r101 | |||
|
r22 | log "Test result directory: #{test_result_dir}" | ||
|
r101 | clear_and_create_empty_dir(test_result_dir) | ||
|
r0 | |||
if ARGV.length >= 4 | ||||
sandbox_dir = ARGV[3] | ||||
else | ||||
sandbox_dir = "#{current_dir}/sandbox" | ||||
end | ||||
|
r22 | log "Sandbox directory: #{sandbox_dir}" | ||
|
r101 | clear_and_create_empty_dir(sandbox_dir) | ||
|
r0 | |||
# Compile | ||||
|
r22 | log | ||
log "Compiling..." | ||||
|
r101 | call_and_log("Cannot copy the source file to #{sandbox_dir}") { | ||
FileUtils.cp(source_file, sandbox_dir) | ||||
} | ||||
|
r0 | begin | ||
Dir.chdir sandbox_dir | ||||
rescue | ||||
|
r22 | log "ERROR: Cannot change directory to #{sandbox_dir}." | ||
|
r0 | exit(127) | ||
end | ||||
execute("#{problem_home}/script/compile #{language} #{source_file}", "Compilation error!") | ||||
|
r102 | compile_message = open("compiler_message").read | ||
|
r0 | compile_message.strip! | ||
|
r101 | call_and_log("Cannot move the compiler message to #{test_result_dir}.") { | ||
FileUtils.mv("compiler_message", test_result_dir) | ||||
} | ||||
|
r3 | if !FileTest.exist?("a.out") | ||
|
r22 | log "Cannot compile the source code. See message in #{test_result_dir}/compile_message" | ||
|
r0 | exit(127) | ||
else | ||||
|
r101 | call_and_log("Cannot move the compiled program to #{test_result_dir}") { | ||
FileUtils.mv("a.out",test_result_dir) | ||||
} | ||||
FileUtils.rm_rf("#{sandbox_dir}/.") | ||||
|
r0 | end | ||
require "#{problem_home}/script/test_dsl.rb" | ||||
load "#{problem_home}/test_cases/all_tests.cfg" | ||||
problem = Problem.get_instance | ||||
if problem.well_formed? == false | ||||
|
r22 | log "The problem specification is not well formed." | ||
|
r0 | exit(127) | ||
end | ||||
# Doing the testing. | ||||
(1..(problem.num_tests)).each do |test_num| | ||||
|
r61 | |||
$stdout.print "[#{test_num}]" | ||||
$stdout.flush | ||||
|
r22 | log "Test number: #{test_num}" | ||
|
r137 | |||
|
r101 | call_and_log("Cannot copy the compiled program into #{sandbox_dir}") { | ||
|
r137 | FileUtils.cp("#{test_result_dir}/a.out", sandbox_dir, :preserve => true) | ||
|
r101 | } | ||
|
r137 | |||
|
r31 | begin | ||
execute("#{problem_home}/script/run #{language} #{test_num}", "Error occured during execution of the run script") | ||||
rescue | ||||
# do nothing | ||||
end | ||||
|
r137 | |||
|
r101 | call_and_log("Cannot create directory #{test_result_dir}/#{test_num}") { | ||
FileUtils.mkdir "#{test_result_dir}/#{test_num}" | ||||
} | ||||
call_and_log("Cannot copy the result file into #{test_result_dir}/#{test_num}") { | ||||
FileUtils.mv "#{sandbox_dir}/result", "#{test_result_dir}/#{test_num}" | ||||
} | ||||
call_and_log("Cannot copy the comment file into #{test_result_dir}/#{test_num}") { | ||||
FileUtils.mv "#{sandbox_dir}/comment", "#{test_result_dir}/#{test_num}" | ||||
} | ||||
call_and_log("Cannot copy the output file into #{test_result_dir}/#{test_num}") { | ||||
FileUtils.mv "#{sandbox_dir}/output.txt", "#{test_result_dir}/#{test_num}" | ||||
} | ||||
call_and_log("Cannot clear #{sandbox_dir}") { | ||||
FileUtils.rm_rf(Dir.glob("#{sandbox_dir}/*"), :secure => true) | ||||
} | ||||
|
r0 | end | ||
|
r61 | $stdout.print "[done]\n" | ||
|
r0 | # Grade | ||
|
r22 | log | ||
log "Grading..." | ||||
|
r0 | begin | ||
Dir.chdir test_result_dir | ||||
rescue | ||||
|
r22 | log "ERROR: Cannot change directory to #{test_result_dir}." | ||
|
r0 | exit(127) | ||
end | ||||
execute("#{problem_home}/script/grade", "An error occured during grading!") | ||||
|
r22 | log | ||
log "All done!" | ||||