Show More
Commit Description:
add option -A <opt> to box. This options allow more argument to be explicitly passed to the program...
Commit Description:
add option -A <opt> to box. This options allow more argument to be explicitly passed to the program We have to use this because if the argument we wish to pass to the program is option (in -? format), box will intepret it as its option and failed accordingly. be noted that, by the definition of getopt, these options will be put after original argument (check the code for more info)
References:
File last commit:
Show/Diff file:
Action:
std-script/run | 189 lines | 6.1 KiB | text/plain | AmplLexer |
#!/usr/bin/env ruby
require 'fileutils'
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
def extract_time(t)
# puts "TIME: #{t}"
if (result=/^(.*)r(.*)u(.*)s/.match(t))
{:real => result[1], :user => result[2], :sys => result[3]}
else
#{:real => 0, :user => 0, :sys => 0}
#puts "ERROR READING RUNNING TIME: #{t}"
raise "Error reading running time: #{t}"
end
end
def compile_box(source,bin)
system("g++ #{source} -o #{bin}")
end
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']
source_name = ENV['SOURCE_NAME']
require "#{problem_home}/script/test_dsl.rb"
load "#{problem_home}/test_cases/all_tests.cfg"
problem = Problem.get_instance
sandbox_dir = Dir.getwd
if problem.well_formed? == false
log "The problem specification is not well formed."
exit(127)
end
# Check if the test number is okay.
if test_num <= 0 || test_num > problem.num_tests
log "You have specified a wrong test number."
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} .`
# 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"
compile_box("#{problem_home}/script/box.cc",
"#{problem_home}/script/box")
end
# Hide PROBLEM_HOME
ENV['PROBLEM_HOME'] = nil
ENV['SOURCE_NAME'] = nil
# Run the program.
#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}"
#
JAVA_OPTION = "-s set_robust_list -s futex -s clone -s getppid -s clone -s wait4 -p /usr/bin/ -p ./"
RUBY_OPTION = "-p /usr/lib64/ -p /usr/local/lib64/ -p /usr/local/lib/ -p /lib64/ -p /dev/urandom -p #{sandbox_dir}/#{program_name} -p #{sandbox_dir}/ -s set_robust_list -s sched_getaffinity -s clock_gettime -s sigaltstack -s pipe2 -s clone -s futex -s openat -s pipe"
PYTHON_OPTION = "-p /usr/lib64/ -p /usr/local/lib64/ -p /usr/local/lib/ -p /usr/bin/ -p /lib64/ -p #{sandbox_dir}/#{program_name} -p ./#{program_name} -p #{sandbox_dir}/#{source_name} -s set_robust_list -s openat -s recvmsg -s connect -s socket -s sendto -s futex -E PYTHONNOUSERSITE=yes"
PHP_OPTION = "-p /usr/lib64/ -p/lib64/ -p /usr/bin/ -p #{sandbox_dir}/#{program_name} -p ./#{program_name} -p /usr/share/ -s setfsuid -s setfsgid -s openat -s set_robust_list -s futex -s clone -s socket -s connect"
case language
when "java"
# for java, extract the classname
# wne have to add additional systemcall and we don't check the mem limit (dunno how to fix...)
classname = 'DUMMY'
File.open(program_name,"r").each do |line|
classname = line
end
#for java, we cannot really check the memory limit...
run_command = "#{problem_home}/script/box -a 3 -f -T -t #{time_limit} #{JAVA_OPTION} -i #{input_file_name} -o output.txt /usr/bin/java #{classname} "
when "ruby"
run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit*=2} -m #{mem_limit} #{RUBY_OPTION} -i #{input_file_name} -o output.txt /usr/bin/ruby #{program_name} "
when "python"
run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit*=2} -m #{mem_limit} #{PYTHON_OPTION} -i #{input_file_name} -o output.txt /usr/bin/python #{program_name} "
when "php"
run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit*=2} #{PHP_OPTION} -i #{input_file_name} -o output.txt /usr/bin/php #{program_name} "
else # for c++, pascal, we do the normal checking
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} "
end
log "Running test #{test_num}..."
log run_command
log
system(run_command,err: 'run_result')
# Restore PROBLEM_HOME
ENV['PROBLEM_HOME'] = problem_home
# 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
run_stat = run_result[run_result.length-1]
running_time = extract_time(run_stat)
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"
result_file.write run_stat.strip
result_file.write "\n"
result_file.close
FileUtils.rm "run_result"
# `rm output.txt` --- keep the output
comment_file.write comment
# added for debuggin --- jittat
comment_file.write "--run-result--\n"
run_result.each do |l|
comment_file.write l
end
comment_file.close
log "Done!"
exit(0)
}
if run_result[0][0,2] != "OK"
log "There was a runtime error."
report.call(run_result[0], 0, "No comment.\n")
end
if running_time[:user].to_f > time_limit
log "Time limit exceeded."
report.call("Time limit exceeded", 0, "No comment.\n")
end
# 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}"
log "Checking the output..."
log check_command
if not system(check_command)
log "Problem with check script"
report.call("Incorrect",0,"Check script error.\n")
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")