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/run
| 159 lines
| 4.1 KiB
| text/plain
| AmplLexer
|
|
r137 | #!/usr/bin/env ruby | ||
|
r0 | |||
|
r105 | 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("run: #{Time.new.strftime("%H:%M")} #{str}") | ||||
fp.close | ||||
end | ||||
end | ||||
|
r23 | def extract_time(t) | ||
|
r42 | # puts "TIME: #{t}" | ||
|
r23 | if (result=/^(.*)r(.*)u(.*)s/.match(t)) | ||
{:real => result[1], :user => result[2], :sys => result[3]} | ||||
else | ||||
|
r42 | #{:real => 0, :user => 0, :sys => 0} | ||
#puts "ERROR READING RUNNING TIME: #{t}" | ||||
raise "Error reading running time: #{t}" | ||||
|
r23 | end | ||
end | ||||
def compile_box(source,bin) | ||||
|
r42 | system("g++ #{source} -o #{bin}") | ||
|
r23 | end | ||
|
r0 | if ARGV.length < 2 || ARGV.length > 3 | ||
puts "Usage: run <language> <test-num> [<program-name>]" | ||||
exit(127) | ||||
end | ||||
language = ARGV[0] | ||||
test_num = ARGV[1].to_i | ||||
if ARGV.length > 2 | ||||
program_name = ARGV[2] | ||||
else | ||||
program_name = "a.out" | ||||
end | ||||
problem_home = ENV['PROBLEM_HOME'] | ||||
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 | ||||
# Check if the test number is okay. | ||||
if test_num <= 0 || test_num > problem.num_tests | ||||
|
r22 | log "You have specified a wrong test number." | ||
|
r0 | exit(127) | ||
end | ||||
##################################### | ||||
# Set the relavant file names here. # | ||||
##################################### | ||||
input_file_name = "#{problem_home}/test_cases/#{test_num}/input-#{test_num}.txt" | ||||
##################################### | ||||
time_limit = problem.get_time_limit test_num | ||||
mem_limit = problem.get_mem_limit(test_num) * 1024 | ||||
# Copy the input file. | ||||
#`cp #{problem_home}/test_cases/#{test_num}/#{input_file_name} .` | ||||
|
r23 | # check if box is there, if not, compile it! | ||
if !File.exists?("#{problem_home}/script/box") | ||||
log "WARNING: Compiling box: to increase efficiency, it should be compile manually" | ||||
|
r42 | compile_box("#{problem_home}/script/box.cc", | ||
|
r23 | "#{problem_home}/script/box") | ||
end | ||||
|
r35 | # Hide PROBLEM_HOME | ||
ENV['PROBLEM_HOME'] = nil | ||||
|
r0 | # Run the program. | ||
|
r42 | #run_command = "/usr/bin/time -f \"#{time_output_format}\" 2>run_result #{problem_home}/script/box_new -a 2 -f -t #{time_limit} -m #{mem_limit} -i #{input_file_name} -o output.txt #{program_name}" | ||
|
r137 | |||
|
r62 | run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit} -m #{mem_limit} -i #{input_file_name} -o output.txt #{program_name} 2>run_result" | ||
|
r137 | |||
|
r22 | log "Running test #{test_num}..." | ||
log run_command | ||||
log | ||||
|
r0 | system(run_command) | ||
|
r35 | # Restore PROBLEM_HOME | ||
ENV['PROBLEM_HOME'] = problem_home | ||||
|
r0 | # Create the result file. | ||
result_file = File.new("result", "w") | ||||
comment_file = File.new("comment", "w") | ||||
# Check if the program actually produced any output. | ||||
run_result_file = File.new("run_result", "r") | ||||
run_result = run_result_file.readlines | ||||
run_result_file.close | ||||
|
r42 | |||
run_stat = run_result[run_result.length-1] | ||||
running_time = extract_time(run_stat) | ||||
|
r0 | |||
report = lambda{ |status, points, comment| | ||||
result_file.write status.strip | ||||
result_file.write "\n" | ||||
result_file.write points.to_s.strip | ||||
result_file.write "\n" | ||||
|
r42 | result_file.write run_stat.strip | ||
|
r0 | result_file.write "\n" | ||
result_file.close | ||||
|
r102 | FileUtils.rm "run_result" | ||
|
r8 | # `rm output.txt` --- keep the output | ||
|
r0 | |||
comment_file.write comment | ||||
|
r42 | |||
# added for debuggin --- jittat | ||||
|
r7 | comment_file.write "--run-result--\n" | ||
run_result.each do |l| | ||||
comment_file.write l | ||||
end | ||||
|
r42 | |||
|
r0 | comment_file.close | ||
|
r22 | log "Done!" | ||
|
r0 | exit(0) | ||
} | ||||
if run_result[0][0,2] != "OK" | ||||
|
r22 | log "There was a runtime error." | ||
|
r0 | report.call(run_result[0], 0, "No comment.\n") | ||
end | ||||
|
r23 | if running_time[:user].to_f + running_time[:sys].to_f > time_limit | ||
log "Time limit exceeded." | ||||
report.call("Time limit exceeded", 0, "No comment.\n") | ||||
end | ||||
|
r0 | # Run 'check' to evaluate the output. | ||
#puts "There was no runtime error. Proceed to checking the output." | ||||
check_command = "#{problem_home}/script/check #{language} #{test_num}" | ||||
|
r22 | log "Checking the output..." | ||
log check_command | ||||
|
r0 | if not system(check_command) | ||
|
r30 | log "Problem with check script" | ||
|
r31 | report.call("Incorrect",0,"Check script error.\n") | ||
|
r0 | exit(127) | ||
end | ||||
check_file = File.new("check_result", "r") | ||||
check_file_lines = check_file.readlines | ||||
report.call(check_file_lines[0], check_file_lines[1], "No comment.\n") | ||||