diff --git a/grader b/grader --- a/grader +++ b/grader @@ -15,7 +15,7 @@ def clear_stopfile if FileTest.exist?(File.dirname(__FILE__) + "/stop.#{Process.pid}") - system("rm " + File.dirname(__FILE__) + "/stop.#{Process.pid}") + File.delete(File.dirname(__FILE__) + "/stop.#{Process.pid}") end end diff --git a/grader_id b/grader_id --- a/grader_id +++ b/grader_id @@ -1,18 +1,13 @@ #!/usr/bin/ruby +require 'fileutils' + def talk(str) if TALKATIVE puts str end end -def execute(command, error_message="") - if not system(command) - puts "ERROR: #{error_message}" - exit(127) - end -end - def save_source(submission,dir,fname) f = File.open("#{dir}/#{fname}","w") f.write(submission.source) @@ -81,18 +76,6 @@ save_result(sub,read_result("#{problem_out_dir}/test-result")) end -def stop_grader - File.open(File.dirname(__FILE__) + '/stop','w') -end - -def check_stopfile - FileTest.exist?(File.dirname(__FILE__) + '/stop') -end - -def clear_stopfile - system("rm " + File.dirname(__FILE__) + '/stop') -end - # reading environment and options GRADER_ENV = 'exam' puts "environment: #{GRADER_ENV}" @@ -104,7 +87,5 @@ RAILS_ENV = 'development' require RAILS_APP_DIR + '/config/environment' -current_dir = `pwd` +current_dir = FileUtils.pwd grade(ARGV[0].to_i) - - diff --git a/import_problem b/import_problem --- a/import_problem +++ b/import_problem @@ -32,8 +32,8 @@ end def copy_testcase(importing_test_dir,fname,dir,i) - system("cp #{importing_test_dir}/#{fname}.in #{input_filename(dir,i)}") - system("cp #{importing_test_dir}/#{fname}.sol #{answer_filename(dir,i)}") + FileUtils.cp("#{importing_test_dir}/#{fname}.in", "#{input_filename(dir,i)}") + FileUtils.cp("#{importing_test_dir}/#{fname}.sol", "#{answer_filename(dir,i)}") end def process_options(options) @@ -100,6 +100,12 @@ end while true end +def create_dir_if_not_exists(dir) + if ! FileTest.exists? dir + FileUtils.mkdir(dir) + end +end + def import_problem(ev_dir, problem, testcase_dir, num_testruns, raw_prefix, check_script, options) testrun_info = build_testrun_info_from_dir(num_testruns, testcase_dir, raw_prefix) @@ -113,9 +119,9 @@ # start working puts "creating directories" - system("mkdir #{problem_dir}") - system("mkdir #{problem_dir}/script") - system("mkdir #{problem_dir}/test_cases") + create_dir_if_not_exists("#{problem_dir}") + create_dir_if_not_exists("#{problem_dir}/script") + create_dir_if_not_exists("#{problem_dir}/test_cases") puts "copying testcases" @@ -132,7 +138,7 @@ puts "copy #{testcase_fname} to #{testcase_num}" - system("mkdir #{problem_dir}/test_cases/#{testcase_num}") + create_dir_if_not_exists("#{problem_dir}/test_cases/#{testcase_num}") copy_testcase("#{testcase_dir}",testcase_fname,"#{problem_dir}/test_cases/#{testcase_num}",testcase_num) num_testcases += 1 @@ -163,14 +169,14 @@ File.chmod(0755,"#{problem_dir}/script/check") - system("cp #{check_script_fname} #{problem_dir}/script/#{script_name}") + FileUtils.cp("#{check_script_fname}", "#{problem_dir}/script/#{script_name}") else if File.exists?(SCRIPT_DIR + "/templates/check.#{check_script}") check_script_fname = SCRIPT_DIR + "/templates/check.#{check_script}" else check_script_fname = check_script end - system("cp #{check_script_fname} #{problem_dir}/script/check") + FileUtils.cp("#{check_script_fname}", "#{problem_dir}/script/check") end # generating test_request directory @@ -185,8 +191,10 @@ cfg_file.puts test_request_all_test_cfg.result cfg_file.close - system("cp #{SCRIPT_DIR}/templates/check_empty #{ev_dir}/test_request/#{problem}/script/check") - system("cp #{SCRIPT_DIR}/templates/answer-1.txt #{ev_dir}/test_request/#{problem}/test_cases/1") + FileUtils.cp("#{SCRIPT_DIR}/templates/check_empty", + "#{ev_dir}/test_request/#{problem}/script/check") + FileUtils.cp("#{SCRIPT_DIR}/templates/answer-1.txt", + "#{ev_dir}/test_request/#{problem}/test_cases/1") puts "done" end diff --git a/lib/dir_init.rb b/lib/dir_init.rb --- a/lib/dir_init.rb +++ b/lib/dir_init.rb @@ -25,7 +25,7 @@ # Check if someone has initialized the dir. If not, call block. def setup # :yields: block - dir = File.new(@dir_name) + dir = File.new(@dir_name + '/lockfile',"w+") dir.flock(File::LOCK_EX) begin counter_filename = get_counter_filename diff --git a/lib/engine.rb b/lib/engine.rb --- a/lib/engine.rb +++ b/lib/engine.rb @@ -1,5 +1,4 @@ require 'fileutils' -require 'ftools' require File.join(File.dirname(__FILE__),'dir_init') module Grader @@ -32,7 +31,7 @@ # takes a submission, asks room_maker to produce grading directories, # calls grader scripts, and asks reporter to save the result def grade(submission) - current_dir = `pwd`.chomp + current_dir = FileUtils.pwd user = submission.user problem = submission.problem @@ -137,9 +136,10 @@ scripts.each do |s| fname = File.basename(s) + next if FileTest.directory?(s) if !FileTest.exist?("#{script_dir}/#{fname}") copied << fname - system("cp #{s} #{script_dir}") + FileUtils.cp(s, "#{script_dir}") end end @@ -174,7 +174,7 @@ def clear_script(log,problem_home) log.each do |s| - system("rm #{problem_home}/script/#{s}") + FileUtils.rm("#{problem_home}/script/#{s}") end end diff --git a/lib/test_request_helper.rb b/lib/test_request_helper.rb --- a/lib/test_request_helper.rb +++ b/lib/test_request_helper.rb @@ -5,6 +5,23 @@ module Grader + def self.link_or_copy(src, des) + begin + FileUtils.ln_s(src, des) + rescue NotImplementedError + FileUtils.cp(src,des) + end + end + + def self.call_and_log(error_message) + begin + yield + rescue + msg = "ERROR: #{error_message}" + raise msg + end + end + # # A TestRequestRoomMaker is a helper object for Engine # - finds grading room: in user_result_dir/(user)/test_request/ ... @@ -28,8 +45,8 @@ # to the sandbox directory later. The run script should do it. # if FileTest.exists?("#{test_request.input_file_name}.files") - cmd = "cp #{test_request.input_file_name}.files/* #{grading_room}" - system(cmd) + FileUtils.cp_r("#{test_request.input_file_name}.files/.", + "#{grading_room}") end grading_room @@ -82,11 +99,12 @@ end def copy_problem_template(template_dir,problem_home) - cmd = "cp -R #{template_dir}/* #{problem_home}" - system_and_raise_when_fail(cmd,"Test Request: cannot copy problem template") + Grader::call_and_log("Test Request: cannot copy problem template") { + FileUtils.cp_r("#{template_dir}/.","#{problem_home}") + } end - - def link_input_file(test_request,problem_home) + + def link_input_file(test_request, problem_home) input_fname = "#{test_request.input_file_name}" if !File.exists?(input_fname) raise "Test Request: input file not found." @@ -97,20 +115,14 @@ FileUtils.rm([input_fname_problem_home], :force => true) end - cmd = "ln -s #{input_fname} #{input_fname_problem_home}" - system_and_raise_when_fail(cmd,"Test Request: cannot link input file") + Grader::link_or_copy("#{input_fname}", "#{input_fname_problem_home}") end def remove_data_files(problem_home) if File.exists?("#{problem_home}/test_cases/1/input-1.txt") - cmd = "rm #{problem_home}/test_cases/1/*" - system_and_raise_when_fail(cmd,"Test Request: cannot remove data files") - end - end - - def system_and_raise_when_fail(cmd,msg) - if !system(cmd) - raise msg + Grader::call_and_log("Test Request: cannot remove data files") { + FileUtils.rm Dir.glob("#{problem_home}/test_cases/1/*") + } end end @@ -221,10 +233,7 @@ target_file_name = random_output_file_name(test_request.user, test_request.problem) FileUtils.mkdir_p(File.dirname(target_file_name)) - cmd = "ln -s #{fname} #{target_file_name}" - if !system(cmd) - raise "TestRequestReporter: cannot move output file" - end + Grader::link_or_copy("#{fname}", "#{target_file_name}") return target_file_name end diff --git a/std-script/.gitignore b/std-script/.gitignore --- a/std-script/.gitignore +++ b/std-script/.gitignore @@ -1,2 +1,2 @@ box - +box.exe diff --git a/std-script/judge b/std-script/judge --- a/std-script/judge +++ b/std-script/judge @@ -1,5 +1,7 @@ #!/usr/bin/ruby +require 'fileutils' + def log(str='') if ENV['TALKATIVE']!=nil puts str @@ -22,6 +24,21 @@ end end +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 + # ARGV[0] --- language # ARGV[1] --- program source file # ARGV[2] --- test result directory @@ -49,7 +66,7 @@ log "Making test result and sandbox directories..." -current_dir = `pwd` +current_dir = FileUtils.pwd current_dir.strip! if ARGV.length >= 3 @@ -57,9 +74,9 @@ else test_result_dir = "#{current_dir}/test-result" end + log "Test result directory: #{test_result_dir}" -system("rm -Rf #{test_result_dir}") -execute("mkdir #{test_result_dir}", "Cannot make directory #{test_result_dir}.") +clear_and_create_empty_dir(test_result_dir) if ARGV.length >= 4 sandbox_dir = ARGV[3] @@ -67,13 +84,14 @@ sandbox_dir = "#{current_dir}/sandbox" end log "Sandbox directory: #{sandbox_dir}" -system("rm -Rf #{sandbox_dir}") -execute("mkdir #{sandbox_dir}", "Cannot make directory #{sandbox_dir}") +clear_and_create_empty_dir(sandbox_dir) # Compile log log "Compiling..." -execute("cp #{source_file} #{sandbox_dir}", "Cannot copy the source file to #{sandbox_dir}") +call_and_log("Cannot copy the source file to #{sandbox_dir}") { + FileUtils.cp(source_file, sandbox_dir) +} begin Dir.chdir sandbox_dir rescue @@ -81,15 +99,19 @@ exit(127) end execute("#{problem_home}/script/compile #{language} #{source_file}", "Compilation error!") -compile_message = `cat compiler_message` +compile_message = open("compiler_message").read compile_message.strip! -execute("mv compiler_message #{test_result_dir}", "Cannot move the compiler message to #{test_result_dir}.") +call_and_log("Cannot move the compiler message to #{test_result_dir}.") { + FileUtils.mv("compiler_message", test_result_dir) +} if !FileTest.exist?("a.out") log "Cannot compile the source code. See message in #{test_result_dir}/compile_message" exit(127) else - execute("mv a.out #{test_result_dir}", "Cannot move the compiled program to #{test_result_dir}") - system("rm -Rf #{sandbox_dir}/*") + call_and_log("Cannot move the compiled program to #{test_result_dir}") { + FileUtils.mv("a.out",test_result_dir) + } + FileUtils.rm_rf("#{sandbox_dir}/.") end require "#{problem_home}/script/test_dsl.rb" @@ -108,17 +130,29 @@ $stdout.flush log "Test number: #{test_num}" - execute("cp #{test_result_dir}/a.out #{sandbox_dir}", "Cannot copy the compiled program into #{sandbox_dir}") + call_and_log("Cannot copy the compiled program into #{sandbox_dir}") { + FileUtils.cp("#{test_result_dir}/a.out", sandbox_dir) + } begin execute("#{problem_home}/script/run #{language} #{test_num}", "Error occured during execution of the run script") rescue # do nothing end - execute("mkdir #{test_result_dir}/#{test_num}", "Cannot create directory #{test_result_dir}/#{test_num}") - execute("mv #{sandbox_dir}/result #{test_result_dir}/#{test_num}", "Cannot copy the result file into #{test_result_dir}/#{test_num}") - execute("mv #{sandbox_dir}/comment #{test_result_dir}/#{test_num}", "Cannot copy the comment file into #{test_result_dir}/#{test_num}") - execute("mv #{sandbox_dir}/output.txt #{test_result_dir}/#{test_num}", "Cannot copy the output file into #{test_result_dir}/#{test_num}") - execute("rm -Rf #{sandbox_dir}/*", "Cannot clear #{sandbox_dir}") + 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) + } end $stdout.print "[done]\n" diff --git a/std-script/run b/std-script/run --- a/std-script/run +++ b/std-script/run @@ -111,7 +111,7 @@ result_file.write run_stat.strip result_file.write "\n" result_file.close - `rm run_result` + FileUtils.rm "run_result" # `rm output.txt` --- keep the output comment_file.write comment diff --git a/test/engine_spec_helper.rb b/test/engine_spec_helper.rb --- a/test/engine_spec_helper.rb +++ b/test/engine_spec_helper.rb @@ -1,17 +1,18 @@ +require 'fileutils' + module GraderEngineHelperMethods def clear_sandbox config = Grader::Configuration.get_instance - clear_cmd = "rm -rf #{config.test_sandbox_dir}/*" - system(clear_cmd) + FileUtils.rm_rf(Dir.glob("#{config.test_sandbox_dir}/*"), + :secure => true) end def init_sandbox config = Grader::Configuration.get_instance clear_sandbox FileUtils.mkdir_p config.user_result_dir - cp_cmd = "cp -R #{config.test_data_dir}/ev #{config.test_sandbox_dir}" - system(cp_cmd) + FileUtils.cp_r("#{config.test_data_dir}/ev", "#{config.test_sandbox_dir}") end def create_submission_from_file(id, user, problem,