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
|
|
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) | ||
r156 | # puts "TIME: #{t}" | |||
if (result=/^(.*)r(.*)u(.*)s/.match(t)) | ||||
|
r23 | {: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'] | ||||
r161 | source_name = ENV['SOURCE_NAME'] | |||
|
r0 | require "#{problem_home}/script/test_dsl.rb" | ||
load "#{problem_home}/test_cases/all_tests.cfg" | ||||
problem = Problem.get_instance | ||||
r161 | sandbox_dir = Dir.getwd | |||
|
r0 | 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 | ||||
r161 | ENV['SOURCE_NAME'] = nil | |||
|
r35 | |||
|
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}" | ||
r147 | # | |||
|
r137 | |||
r161 | JAVA_OPTION = "-s set_robust_list -s futex -s clone -s getppid -s clone -s wait4 -p /usr/bin/ -p ./" | |||
r169 | 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" | ||||
r171 | 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" | |||
r147 | ||||
case language | ||||
when "java" | ||||
r158 | # 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 | ||||
r161 | #for java, we cannot really check the memory limit... | |||
r178 | 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} " | |||
r147 | when "ruby" | |||
r178 | 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} " | |||
r154 | when "python" | |||
r178 | 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} " | |||
r165 | when "php" | |||
r178 | 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} " | |||
r154 | else # for c++, pascal, we do the normal checking | |||
r178 | 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} " | |||
r147 | end | |||
|
r137 | |||
|
r22 | log "Running test #{test_num}..." | ||
log run_command | ||||
r161 | log | |||
r178 | system(run_command,err: 'run_result') | |||
|
r0 | |||
|
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) | ||
} | ||||
r161 | ||||
|
r0 | 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 | ||||
r147 | if running_time[:user].to_f > time_limit | |||
|
r23 | 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") | ||||