Show More
Commit Description:
more commenting on script
Commit Description:
more commenting on script
References:
File last commit:
Show/Diff file:
Action:
std-script/judge
| 194 lines
| 5.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 | ||||
r256 | msg = "JUDGE: ERROR: #{error_message}" | |||
|
r101 | 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] | ||||
r220 | if language != "c" && language != "c++" && language != "pas" && language != "java" && language != "ruby" && language != "python" && language != "php" && language != "haskell" | |||
r256 | log "JUDGE: You specified a language that is not supported: #{language}." | |||
|
r0 | exit(127) | ||
end | ||||
source_file = ARGV[1] | ||||
r161 | ENV['SOURCE_NAME'] = source_file | |||
|
r0 | if File.exist?(source_file) == false | ||
r256 | log "JUDGE: The source file does not exist." | |||
|
r0 | exit(127) | ||
end | ||||
r256 | log "JUDGE: 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 | |||
r256 | log "JUDGE: 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 | ||||
r256 | log "JUDGE: Sandbox directory: #{sandbox_dir}" | |||
|
r101 | clear_and_create_empty_dir(sandbox_dir) | ||
|
r0 | |||
r256 | # ------------------------------ | |||
|
r0 | # Compile | ||
r256 | # ------------------------------ | |||
log "JUDGE: Compiling..." | ||||
|
r22 | log | ||
|
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 | ||||
r256 | log "JUDGE: 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") | ||
r256 | log "JUDGE: EROOR: 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) | ||||
r147 | if language == "java" then Dir["*.class"].each { |file| FileUtils.mv(file,test_result_dir)} end | |||
r154 | if language == "python" then Dir["*.pyc"].each { |file| FileUtils.mv(file,test_result_dir)} end | |||
|
r101 | } | ||
FileUtils.rm_rf("#{sandbox_dir}/.") | ||||
|
r0 | end | ||
r256 | ||||
#----------------------------------------------- | ||||
# run | ||||
#----------------------------------------------- | ||||
|
r0 | 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. | ||||
r256 | log | |||
log "JUDGE: Running each test case..." | ||||
|
r0 | (1..(problem.num_tests)).each do |test_num| | ||
|
r61 | |||
$stdout.print "[#{test_num}]" | ||||
$stdout.flush | ||||
|
r101 | call_and_log("Cannot copy the compiled program into #{sandbox_dir}") { | ||
|
r137 | FileUtils.cp("#{test_result_dir}/a.out", sandbox_dir, :preserve => true) | ||
r147 | if language == "java" then Dir["#{test_result_dir}/*.class"].each { |file| FileUtils.cp(file,sandbox_dir)} end | |||
r154 | if language == "python" then Dir["#{test_result_dir}/*.pyc"].each { |file| FileUtils.cp(file,sandbox_dir)} end | |||
|
r101 | } | ||
|
r137 | |||
r235 | #additionally copy any extra .txt file | |||
data_files = Dir[problem_home + '/*.txt'] | ||||
data_files.each do |file| | ||||
FileUtils.cp(file,sandbox_dir) | ||||
end | ||||
|
r31 | begin | ||
r161 | execute("#{problem_home}/script/run #{language} #{test_num} ", "Error occured during execution of the run script") | |||
|
r31 | rescue | ||
# do nothing | ||||
end | ||||
|
r137 | |||
r257 | ||||
#copy the output of run script to each test-result folder | ||||
|
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 | ||
r256 | log "JUDGE: 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!" | ||||