Description:
Merge branch 'master' into win-local
Commit status:
[Not Reviewed]
References:
merge default
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r104:ad31dc743745 - - 10 files changed: 111 inserted, 78 deleted

@@ -6,25 +6,25
6 else
6 else
7 File.open(File.dirname(__FILE__) + "/stop.#{id}",'w').close
7 File.open(File.dirname(__FILE__) + "/stop.#{id}",'w').close
8 end
8 end
9 end
9 end
10
10
11 def check_stopfile
11 def check_stopfile
12 FileTest.exist?(File.dirname(__FILE__) + "/stop.all") or
12 FileTest.exist?(File.dirname(__FILE__) + "/stop.all") or
13 FileTest.exist?(File.dirname(__FILE__) + "/stop.#{Process.pid}")
13 FileTest.exist?(File.dirname(__FILE__) + "/stop.#{Process.pid}")
14 end
14 end
15
15
16 def clear_stopfile
16 def clear_stopfile
17 if FileTest.exist?(File.dirname(__FILE__) + "/stop.#{Process.pid}")
17 if FileTest.exist?(File.dirname(__FILE__) + "/stop.#{Process.pid}")
18 - system("rm " + File.dirname(__FILE__) + "/stop.#{Process.pid}")
18 + File.delete(File.dirname(__FILE__) + "/stop.#{Process.pid}")
19 end
19 end
20 end
20 end
21
21
22 def config
22 def config
23 Grader::Configuration.get_instance
23 Grader::Configuration.get_instance
24 end
24 end
25
25
26 def log_file_name
26 def log_file_name
27 if !File.exists?(config.log_dir)
27 if !File.exists?(config.log_dir)
28 raise "Log directory does not exist: #{config.log_dir}"
28 raise "Log directory does not exist: #{config.log_dir}"
29 end
29 end
30 config.log_dir +
30 config.log_dir +
@@ -1,27 +1,22
1 #!/usr/bin/ruby
1 #!/usr/bin/ruby
2
2
3 + require 'fileutils'
4 +
3 def talk(str)
5 def talk(str)
4 if TALKATIVE
6 if TALKATIVE
5 puts str
7 puts str
6 end
8 end
7 end
9 end
8
10
9 - def execute(command, error_message="")
10 - if not system(command)
11 - puts "ERROR: #{error_message}"
12 - exit(127)
13 - end
14 - end
15 -
16 def save_source(submission,dir,fname)
11 def save_source(submission,dir,fname)
17 f = File.open("#{dir}/#{fname}","w")
12 f = File.open("#{dir}/#{fname}","w")
18 f.write(submission.source)
13 f.write(submission.source)
19 f.close
14 f.close
20 end
15 end
21
16
22 def call_judge(problem_home,language,problem_out_dir,fname)
17 def call_judge(problem_home,language,problem_out_dir,fname)
23 ENV['PROBLEM_HOME'] = problem_home
18 ENV['PROBLEM_HOME'] = problem_home
24 Dir.chdir problem_out_dir
19 Dir.chdir problem_out_dir
25 cmd = "#{problem_home}/script/judge #{language} #{fname}"
20 cmd = "#{problem_home}/script/judge #{language} #{fname}"
26 # puts "CMD: #{cmd}"
21 # puts "CMD: #{cmd}"
27 system(cmd)
22 system(cmd)
@@ -72,39 +67,25
72
67
73 problem_out_dir = "#{user_dir}/#{problem.name}"
68 problem_out_dir = "#{user_dir}/#{problem.name}"
74 Dir.mkdir(problem_out_dir) if !FileTest.exist?(problem_out_dir)
69 Dir.mkdir(problem_out_dir) if !FileTest.exist?(problem_out_dir)
75
70
76 problem_home = "#{PROBLEMS_DIR}/#{problem.name}"
71 problem_home = "#{PROBLEMS_DIR}/#{problem.name}"
77 source_name = "#{problem.name}.#{lang_ext}"
72 source_name = "#{problem.name}.#{lang_ext}"
78
73
79 save_source(sub,problem_out_dir,source_name)
74 save_source(sub,problem_out_dir,source_name)
80 call_judge(problem_home,language,problem_out_dir,source_name)
75 call_judge(problem_home,language,problem_out_dir,source_name)
81 save_result(sub,read_result("#{problem_out_dir}/test-result"))
76 save_result(sub,read_result("#{problem_out_dir}/test-result"))
82 end
77 end
83
78
84 - def stop_grader
85 - File.open(File.dirname(__FILE__) + '/stop','w')
86 - end
87 -
88 - def check_stopfile
89 - FileTest.exist?(File.dirname(__FILE__) + '/stop')
90 - end
91 -
92 - def clear_stopfile
93 - system("rm " + File.dirname(__FILE__) + '/stop')
94 - end
95 -
96 # reading environment and options
79 # reading environment and options
97 GRADER_ENV = 'exam'
80 GRADER_ENV = 'exam'
98 puts "environment: #{GRADER_ENV}"
81 puts "environment: #{GRADER_ENV}"
99 require File.dirname(__FILE__) + "/environment.rb"
82 require File.dirname(__FILE__) + "/environment.rb"
100
83
101 #main program
84 #main program
102 talk 'Reading rails environment'
85 talk 'Reading rails environment'
103
86
104 RAILS_ENV = 'development'
87 RAILS_ENV = 'development'
105 require RAILS_APP_DIR + '/config/environment'
88 require RAILS_APP_DIR + '/config/environment'
106
89
107 - current_dir = `pwd`
90 + current_dir = FileUtils.pwd
108 grade(ARGV[0].to_i)
91 grade(ARGV[0].to_i)
109 -
110 -
@@ -23,26 +23,26
23 def answer_filename(dir,i)
23 def answer_filename(dir,i)
24 "#{dir}/answer-#{i}.txt"
24 "#{dir}/answer-#{i}.txt"
25 end
25 end
26
26
27 def build_testrun_info_from_dir(num_testruns, importing_test_dir, raw_prefix='')
27 def build_testrun_info_from_dir(num_testruns, importing_test_dir, raw_prefix='')
28 filenames = Dir["#{importing_test_dir}/#{raw_prefix}*.in"].collect do |filename|
28 filenames = Dir["#{importing_test_dir}/#{raw_prefix}*.in"].collect do |filename|
29 File.basename((/(.*)\.in/.match(filename))[1])
29 File.basename((/(.*)\.in/.match(filename))[1])
30 end
30 end
31 build_testrun_info(num_testruns,filenames,raw_prefix)
31 build_testrun_info(num_testruns,filenames,raw_prefix)
32 end
32 end
33
33
34 def copy_testcase(importing_test_dir,fname,dir,i)
34 def copy_testcase(importing_test_dir,fname,dir,i)
35 - system("cp #{importing_test_dir}/#{fname}.in #{input_filename(dir,i)}")
35 + FileUtils.cp("#{importing_test_dir}/#{fname}.in", "#{input_filename(dir,i)}")
36 - system("cp #{importing_test_dir}/#{fname}.sol #{answer_filename(dir,i)}")
36 + FileUtils.cp("#{importing_test_dir}/#{fname}.sol", "#{answer_filename(dir,i)}")
37 end
37 end
38
38
39 def process_options(options)
39 def process_options(options)
40 i = 3
40 i = 3
41 while i<ARGV.length
41 while i<ARGV.length
42 if ARGV[i]=='-t'
42 if ARGV[i]=='-t'
43 options[:time_limit] = ARGV[i+1].to_f if ARGV.length>i+1
43 options[:time_limit] = ARGV[i+1].to_f if ARGV.length>i+1
44 i += 1
44 i += 1
45 end
45 end
46 if ARGV[i]=='-m'
46 if ARGV[i]=='-m'
47 options[:mem_limit] = ARGV[i+1].to_i if ARGV.length>i+1
47 options[:mem_limit] = ARGV[i+1].to_i if ARGV.length>i+1
48 i += 1
48 i += 1
@@ -91,57 +91,63
91 def count_testruns(testcase_dir, raw_prefix)
91 def count_testruns(testcase_dir, raw_prefix)
92 n = 0
92 n = 0
93 begin
93 begin
94 # check for test case n+1
94 # check for test case n+1
95 if ((Dir["#{testcase_dir}/#{raw_prefix}#{n+1}.in"].length==0) and
95 if ((Dir["#{testcase_dir}/#{raw_prefix}#{n+1}.in"].length==0) and
96 (Dir["#{testcase_dir}/#{raw_prefix}#{n+1}[a-z].in"].length==0))
96 (Dir["#{testcase_dir}/#{raw_prefix}#{n+1}[a-z].in"].length==0))
97 return n
97 return n
98 end
98 end
99 n += 1
99 n += 1
100 end while true
100 end while true
101 end
101 end
102
102
103 + def create_dir_if_not_exists(dir)
104 + if ! FileTest.exists? dir
105 + FileUtils.mkdir(dir)
106 + end
107 + end
108 +
103 def import_problem(ev_dir, problem, testcase_dir, num_testruns, raw_prefix, check_script, options)
109 def import_problem(ev_dir, problem, testcase_dir, num_testruns, raw_prefix, check_script, options)
104 testrun_info = build_testrun_info_from_dir(num_testruns, testcase_dir, raw_prefix)
110 testrun_info = build_testrun_info_from_dir(num_testruns, testcase_dir, raw_prefix)
105
111
106 if !(FileTest.exists? ev_dir)
112 if !(FileTest.exists? ev_dir)
107 puts "Testdata dir (#{ev_dir}) not found."
113 puts "Testdata dir (#{ev_dir}) not found."
108 return
114 return
109 end
115 end
110
116
111 problem_dir = "#{ev_dir}/#{problem}"
117 problem_dir = "#{ev_dir}/#{problem}"
112
118
113 # start working
119 # start working
114 puts "creating directories"
120 puts "creating directories"
115
121
116 - system("mkdir #{problem_dir}")
122 + create_dir_if_not_exists("#{problem_dir}")
117 - system("mkdir #{problem_dir}/script")
123 + create_dir_if_not_exists("#{problem_dir}/script")
118 - system("mkdir #{problem_dir}/test_cases")
124 + create_dir_if_not_exists("#{problem_dir}/test_cases")
119
125
120 puts "copying testcases"
126 puts "copying testcases"
121
127
122 tr_num = 0
128 tr_num = 0
123
129
124 num_testcases = 0
130 num_testcases = 0
125
131
126 testrun_info.each do |testrun|
132 testrun_info.each do |testrun|
127 tr_num += 1
133 tr_num += 1
128 puts "testrun: #{tr_num}"
134 puts "testrun: #{tr_num}"
129
135
130 testrun.each do |testcase_info|
136 testrun.each do |testcase_info|
131 testcase_num, testcase_fname = testcase_info
137 testcase_num, testcase_fname = testcase_info
132
138
133 puts "copy #{testcase_fname} to #{testcase_num}"
139 puts "copy #{testcase_fname} to #{testcase_num}"
134
140
135 - system("mkdir #{problem_dir}/test_cases/#{testcase_num}")
141 + create_dir_if_not_exists("#{problem_dir}/test_cases/#{testcase_num}")
136 copy_testcase("#{testcase_dir}",testcase_fname,"#{problem_dir}/test_cases/#{testcase_num}",testcase_num)
142 copy_testcase("#{testcase_dir}",testcase_fname,"#{problem_dir}/test_cases/#{testcase_num}",testcase_num)
137
143
138 num_testcases += 1
144 num_testcases += 1
139 end
145 end
140 end
146 end
141
147
142 # generating all_tests.cfg
148 # generating all_tests.cfg
143 puts "generating testcase config file"
149 puts "generating testcase config file"
144
150
145 template = File.open(SCRIPT_DIR + "/templates/all_tests.cfg.erb").read
151 template = File.open(SCRIPT_DIR + "/templates/all_tests.cfg.erb").read
146 all_test_cfg = ERB.new(template)
152 all_test_cfg = ERB.new(template)
147
153
@@ -154,48 +160,50
154 # wrapper script
160 # wrapper script
155 check_script_fname = res[1]
161 check_script_fname = res[1]
156 script_name = File.basename(check_script_fname)
162 script_name = File.basename(check_script_fname)
157 check_wrapper_template = File.open(SCRIPT_DIR + "/templates/check_wrapper").read
163 check_wrapper_template = File.open(SCRIPT_DIR + "/templates/check_wrapper").read
158 check_wrapper = ERB.new(check_wrapper_template)
164 check_wrapper = ERB.new(check_wrapper_template)
159
165
160 check_file = File.open("#{problem_dir}/script/check","w")
166 check_file = File.open("#{problem_dir}/script/check","w")
161 check_file.puts check_wrapper.result binding
167 check_file.puts check_wrapper.result binding
162 check_file.close
168 check_file.close
163
169
164 File.chmod(0755,"#{problem_dir}/script/check")
170 File.chmod(0755,"#{problem_dir}/script/check")
165
171
166 - system("cp #{check_script_fname} #{problem_dir}/script/#{script_name}")
172 + FileUtils.cp("#{check_script_fname}", "#{problem_dir}/script/#{script_name}")
167 else
173 else
168 if File.exists?(SCRIPT_DIR + "/templates/check.#{check_script}")
174 if File.exists?(SCRIPT_DIR + "/templates/check.#{check_script}")
169 check_script_fname = SCRIPT_DIR + "/templates/check.#{check_script}"
175 check_script_fname = SCRIPT_DIR + "/templates/check.#{check_script}"
170 else
176 else
171 check_script_fname = check_script
177 check_script_fname = check_script
172 end
178 end
173 - system("cp #{check_script_fname} #{problem_dir}/script/check")
179 + FileUtils.cp("#{check_script_fname}", "#{problem_dir}/script/check")
174 end
180 end
175
181
176 # generating test_request directory
182 # generating test_request directory
177 puts "generating test_request template"
183 puts "generating test_request template"
178 FileUtils.mkdir_p("#{ev_dir}/test_request/#{problem}/script")
184 FileUtils.mkdir_p("#{ev_dir}/test_request/#{problem}/script")
179 FileUtils.mkdir_p("#{ev_dir}/test_request/#{problem}/test_cases/1")
185 FileUtils.mkdir_p("#{ev_dir}/test_request/#{problem}/test_cases/1")
180
186
181 template = File.open(SCRIPT_DIR + "/templates/test_request_all_tests.cfg.erb").read
187 template = File.open(SCRIPT_DIR + "/templates/test_request_all_tests.cfg.erb").read
182 test_request_all_test_cfg = ERB.new(template)
188 test_request_all_test_cfg = ERB.new(template)
183
189
184 cfg_file = File.open("#{ev_dir}/test_request/#{problem}/test_cases/all_tests.cfg","w")
190 cfg_file = File.open("#{ev_dir}/test_request/#{problem}/test_cases/all_tests.cfg","w")
185 cfg_file.puts test_request_all_test_cfg.result
191 cfg_file.puts test_request_all_test_cfg.result
186 cfg_file.close
192 cfg_file.close
187
193
188 - system("cp #{SCRIPT_DIR}/templates/check_empty #{ev_dir}/test_request/#{problem}/script/check")
194 + FileUtils.cp("#{SCRIPT_DIR}/templates/check_empty",
189 - system("cp #{SCRIPT_DIR}/templates/answer-1.txt #{ev_dir}/test_request/#{problem}/test_cases/1")
195 + "#{ev_dir}/test_request/#{problem}/script/check")
196 + FileUtils.cp("#{SCRIPT_DIR}/templates/answer-1.txt",
197 + "#{ev_dir}/test_request/#{problem}/test_cases/1")
190
198
191 puts "done"
199 puts "done"
192 end
200 end
193
201
194
202
195 SCRIPT_DIR = File.dirname(__FILE__)
203 SCRIPT_DIR = File.dirname(__FILE__)
196
204
197 # print usage
205 # print usage
198 if (ARGV.length < 3) or (ARGV[2][0,1]=="-")
206 if (ARGV.length < 3) or (ARGV[2][0,1]=="-")
199 print_usage
207 print_usage
200 exit(127)
208 exit(127)
201 end
209 end
@@ -16,25 +16,25
16 module DirInit
16 module DirInit
17
17
18 class Manager
18 class Manager
19
19
20 def initialize(dir_name, usage_filename='.usage_counter')
20 def initialize(dir_name, usage_filename='.usage_counter')
21 @dir_name = dir_name
21 @dir_name = dir_name
22 @usage_filename = usage_filename
22 @usage_filename = usage_filename
23 end
23 end
24
24
25 # Check if someone has initialized the dir. If not, call block.
25 # Check if someone has initialized the dir. If not, call block.
26
26
27 def setup # :yields: block
27 def setup # :yields: block
28 - dir = File.new(@dir_name)
28 + dir = File.new(@dir_name + '/lockfile',"w+")
29 dir.flock(File::LOCK_EX)
29 dir.flock(File::LOCK_EX)
30 begin
30 begin
31 counter_filename = get_counter_filename
31 counter_filename = get_counter_filename
32 if File.exist? counter_filename
32 if File.exist? counter_filename
33 # someone is here
33 # someone is here
34 f = File.new(counter_filename,"r+")
34 f = File.new(counter_filename,"r+")
35 counter = f.read.to_i
35 counter = f.read.to_i
36 f.seek(0)
36 f.seek(0)
37 f.write("#{counter+1}\n")
37 f.write("#{counter+1}\n")
38 f.close
38 f.close
39 else
39 else
40 # i'm the first, create the counter file
40 # i'm the first, create the counter file
@@ -1,14 +1,13
1 require 'fileutils'
1 require 'fileutils'
2 - require 'ftools'
3 require File.join(File.dirname(__FILE__),'dir_init')
2 require File.join(File.dirname(__FILE__),'dir_init')
4
3
5 module Grader
4 module Grader
6
5
7 #
6 #
8 # A grader engine grades a submission, against anything: a test
7 # A grader engine grades a submission, against anything: a test
9 # data, or a user submitted test data. It uses two helpers objects:
8 # data, or a user submitted test data. It uses two helpers objects:
10 # room_maker and reporter.
9 # room_maker and reporter.
11 #
10 #
12 class Engine
11 class Engine
13
12
14 attr_writer :room_maker
13 attr_writer :room_maker
@@ -23,25 +22,25
23 options[:reporter] = Grader::SubmissionReporter.new
22 options[:reporter] = Grader::SubmissionReporter.new
24 end
23 end
25
24
26 @config = Grader::Configuration.get_instance
25 @config = Grader::Configuration.get_instance
27
26
28 @room_maker = options[:room_maker]
27 @room_maker = options[:room_maker]
29 @reporter = options[:reporter]
28 @reporter = options[:reporter]
30 end
29 end
31
30
32 # takes a submission, asks room_maker to produce grading directories,
31 # takes a submission, asks room_maker to produce grading directories,
33 # calls grader scripts, and asks reporter to save the result
32 # calls grader scripts, and asks reporter to save the result
34 def grade(submission)
33 def grade(submission)
35 - current_dir = `pwd`.chomp
34 + current_dir = FileUtils.pwd
36
35
37 user = submission.user
36 user = submission.user
38 problem = submission.problem
37 problem = submission.problem
39
38
40 # TODO: will have to create real exception for this
39 # TODO: will have to create real exception for this
41 if user==nil or problem == nil
40 if user==nil or problem == nil
42 @reporter.report_error(submission,"Grading error: problem with submission")
41 @reporter.report_error(submission,"Grading error: problem with submission")
43 #raise "engine: user or problem is nil"
42 #raise "engine: user or problem is nil"
44 end
43 end
45
44
46 # TODO: this is another hack so that output only task can be judged
45 # TODO: this is another hack so that output only task can be judged
47 if submission.language!=nil
46 if submission.language!=nil
@@ -128,27 +127,28
128 def copy_script(problem_home)
127 def copy_script(problem_home)
129 script_dir = "#{problem_home}/script"
128 script_dir = "#{problem_home}/script"
130 std_script_dir = get_std_script_dir
129 std_script_dir = get_std_script_dir
131
130
132 raise "std-script directory not found" if !FileTest.exist?(std_script_dir)
131 raise "std-script directory not found" if !FileTest.exist?(std_script_dir)
133
132
134 scripts = Dir[std_script_dir + '/*']
133 scripts = Dir[std_script_dir + '/*']
135
134
136 copied = []
135 copied = []
137
136
138 scripts.each do |s|
137 scripts.each do |s|
139 fname = File.basename(s)
138 fname = File.basename(s)
139 + next if FileTest.directory?(s)
140 if !FileTest.exist?("#{script_dir}/#{fname}")
140 if !FileTest.exist?("#{script_dir}/#{fname}")
141 copied << fname
141 copied << fname
142 - system("cp #{s} #{script_dir}")
142 + FileUtils.cp(s, "#{script_dir}")
143 end
143 end
144 end
144 end
145
145
146 return copied
146 return copied
147 end
147 end
148
148
149 def copy_log_filename(problem_home)
149 def copy_log_filename(problem_home)
150 return File.join(problem_home, '.scripts_copied')
150 return File.join(problem_home, '.scripts_copied')
151 end
151 end
152
152
153 def save_copy_log(problem_home, log)
153 def save_copy_log(problem_home, log)
154 f = File.new(copy_log_filename(problem_home),"w")
154 f = File.new(copy_log_filename(problem_home),"w")
@@ -165,23 +165,23
165 log << line.strip
165 log << line.strip
166 end
166 end
167 f.close
167 f.close
168 log
168 log
169 end
169 end
170
170
171 def clear_copy_log(problem_home)
171 def clear_copy_log(problem_home)
172 File.delete(copy_log_filename(problem_home))
172 File.delete(copy_log_filename(problem_home))
173 end
173 end
174
174
175 def clear_script(log,problem_home)
175 def clear_script(log,problem_home)
176 log.each do |s|
176 log.each do |s|
177 - system("rm #{problem_home}/script/#{s}")
177 + FileUtils.rm("#{problem_home}/script/#{s}")
178 end
178 end
179 end
179 end
180
180
181 def mkdir_if_does_not_exist(dirname)
181 def mkdir_if_does_not_exist(dirname)
182 Dir.mkdir(dirname) if !FileTest.exist?(dirname)
182 Dir.mkdir(dirname) if !FileTest.exist?(dirname)
183 end
183 end
184
184
185 end
185 end
186
186
187 end
187 end
@@ -1,44 +1,61
1 #
1 #
2 # This part contains various test_request helpers for interfacing
2 # This part contains various test_request helpers for interfacing
3 # with Grader::Engine. There are TestRequestRoomMaker and
3 # with Grader::Engine. There are TestRequestRoomMaker and
4 # TestRequestReporter.
4 # TestRequestReporter.
5
5
6 module Grader
6 module Grader
7
7
8 + def self.link_or_copy(src, des)
9 + begin
10 + FileUtils.ln_s(src, des)
11 + rescue NotImplementedError
12 + FileUtils.cp(src,des)
13 + end
14 + end
15 +
16 + def self.call_and_log(error_message)
17 + begin
18 + yield
19 + rescue
20 + msg = "ERROR: #{error_message}"
21 + raise msg
22 + end
23 + end
24 +
8 #
25 #
9 # A TestRequestRoomMaker is a helper object for Engine
26 # A TestRequestRoomMaker is a helper object for Engine
10 # - finds grading room: in user_result_dir/(user)/test_request/ ...
27 # - finds grading room: in user_result_dir/(user)/test_request/ ...
11 # - prepare problem configuration for grading --- basically it copy
28 # - prepare problem configuration for grading --- basically it copy
12 # all config files, and copy user's input into the testcase
29 # all config files, and copy user's input into the testcase
13 # directory. First, it finds the template from problem template
30 # directory. First, it finds the template from problem template
14 # directory; if it can't find a template, it'll use the template
31 # directory; if it can't find a template, it'll use the template
15 # from default template.
32 # from default template.
16 class TestRequestRoomMaker
33 class TestRequestRoomMaker
17 def initialize
34 def initialize
18 @config = Grader::Configuration.get_instance
35 @config = Grader::Configuration.get_instance
19 end
36 end
20
37
21 def produce_grading_room(test_request)
38 def produce_grading_room(test_request)
22 grading_room = grading_room_dir(test_request)
39 grading_room = grading_room_dir(test_request)
23 FileUtils.mkdir_p(grading_room)
40 FileUtils.mkdir_p(grading_room)
24
41
25 #
42 #
26 # Also copy additional submitted file to this directory as well.
43 # Also copy additional submitted file to this directory as well.
27 # The program would see this file only if it is copied
44 # The program would see this file only if it is copied
28 # to the sandbox directory later. The run script should do it.
45 # to the sandbox directory later. The run script should do it.
29 #
46 #
30 if FileTest.exists?("#{test_request.input_file_name}.files")
47 if FileTest.exists?("#{test_request.input_file_name}.files")
31 - cmd = "cp #{test_request.input_file_name}.files/* #{grading_room}"
48 + FileUtils.cp_r("#{test_request.input_file_name}.files/.",
32 - system(cmd)
49 + "#{grading_room}")
33 end
50 end
34
51
35 grading_room
52 grading_room
36 end
53 end
37
54
38 def find_problem_home(test_request)
55 def find_problem_home(test_request)
39 problem_name = test_request.problem_name
56 problem_name = test_request.problem_name
40
57
41 template_dir = "#{@config.test_request_problem_templates_dir}/" + problem_name
58 template_dir = "#{@config.test_request_problem_templates_dir}/" + problem_name
42
59
43 raise "Test Request: error template not found" if !File.exists?(template_dir)
60 raise "Test Request: error template not found" if !File.exists?(template_dir)
44
61
@@ -73,53 +90,48
73 "/#{problem_name}/#{test_request.id}"
90 "/#{problem_name}/#{test_request.id}"
74 grading_room
91 grading_room
75 end
92 end
76
93
77 def problem_home_dir(test_request)
94 def problem_home_dir(test_request)
78 problem_name = test_request.problem_name
95 problem_name = test_request.problem_name
79 user = test_request.user
96 user = test_request.user
80 "#{@config.user_result_dir}" +
97 "#{@config.user_result_dir}" +
81 "/#{user.login}/test_request/#{problem_name}"
98 "/#{user.login}/test_request/#{problem_name}"
82 end
99 end
83
100
84 def copy_problem_template(template_dir,problem_home)
101 def copy_problem_template(template_dir,problem_home)
85 - cmd = "cp -R #{template_dir}/* #{problem_home}"
102 + Grader::call_and_log("Test Request: cannot copy problem template") {
86 - system_and_raise_when_fail(cmd,"Test Request: cannot copy problem template")
103 + FileUtils.cp_r("#{template_dir}/.","#{problem_home}")
104 + }
87 end
105 end
88
106
89 def link_input_file(test_request,problem_home)
107 def link_input_file(test_request, problem_home)
90 input_fname = "#{test_request.input_file_name}"
108 input_fname = "#{test_request.input_file_name}"
91 if !File.exists?(input_fname)
109 if !File.exists?(input_fname)
92 raise "Test Request: input file not found."
110 raise "Test Request: input file not found."
93 end
111 end
94
112
95 input_fname_problem_home = "#{problem_home}/test_cases/1/input-1.txt"
113 input_fname_problem_home = "#{problem_home}/test_cases/1/input-1.txt"
96 if File.exists?(input_fname_problem_home)
114 if File.exists?(input_fname_problem_home)
97 FileUtils.rm([input_fname_problem_home], :force => true)
115 FileUtils.rm([input_fname_problem_home], :force => true)
98 end
116 end
99
117
100 - cmd = "ln -s #{input_fname} #{input_fname_problem_home}"
118 + Grader::link_or_copy("#{input_fname}", "#{input_fname_problem_home}")
101 - system_and_raise_when_fail(cmd,"Test Request: cannot link input file")
102 end
119 end
103
120
104 def remove_data_files(problem_home)
121 def remove_data_files(problem_home)
105 if File.exists?("#{problem_home}/test_cases/1/input-1.txt")
122 if File.exists?("#{problem_home}/test_cases/1/input-1.txt")
106 - cmd = "rm #{problem_home}/test_cases/1/*"
123 + Grader::call_and_log("Test Request: cannot remove data files") {
107 - system_and_raise_when_fail(cmd,"Test Request: cannot remove data files")
124 + FileUtils.rm Dir.glob("#{problem_home}/test_cases/1/*")
108 - end
125 + }
109 - end
110 -
111 - def system_and_raise_when_fail(cmd,msg)
112 - if !system(cmd)
113 - raise msg
114 end
126 end
115 end
127 end
116
128
117 end
129 end
118
130
119 class TestRequestReporter
131 class TestRequestReporter
120 def initialize
132 def initialize
121 @config = Grader::Configuration.get_instance
133 @config = Grader::Configuration.get_instance
122 end
134 end
123
135
124 def report(test_request,test_result_dir)
136 def report(test_request,test_result_dir)
125 save_result(test_request,read_result(test_result_dir))
137 save_result(test_request,read_result(test_result_dir))
@@ -212,28 +224,25
212 test_request.memory_usage = result[:running_stat][:memory_usage]
224 test_request.memory_usage = result[:running_stat][:memory_usage]
213 else
225 else
214 test_request.running_stat = ''
226 test_request.running_stat = ''
215 end
227 end
216 test_request.save
228 test_request.save
217 end
229 end
218
230
219 protected
231 protected
220 def link_output_file(test_request, fname)
232 def link_output_file(test_request, fname)
221 target_file_name = random_output_file_name(test_request.user,
233 target_file_name = random_output_file_name(test_request.user,
222 test_request.problem)
234 test_request.problem)
223 FileUtils.mkdir_p(File.dirname(target_file_name))
235 FileUtils.mkdir_p(File.dirname(target_file_name))
224 - cmd = "ln -s #{fname} #{target_file_name}"
236 + Grader::link_or_copy("#{fname}", "#{target_file_name}")
225 - if !system(cmd)
226 - raise "TestRequestReporter: cannot move output file"
227 - end
228 return target_file_name
237 return target_file_name
229 end
238 end
230
239
231 def random_output_file_name(user,problem)
240 def random_output_file_name(user,problem)
232 problem_name = TestRequest.name_of(problem)
241 problem_name = TestRequest.name_of(problem)
233 begin
242 begin
234 tmpname = "#{@config.test_request_output_base_dir}" +
243 tmpname = "#{@config.test_request_output_base_dir}" +
235 "/#{user.login}/#{problem_name}/#{rand(10000)}"
244 "/#{user.login}/#{problem_name}/#{rand(10000)}"
236 end while File.exists?(tmpname)
245 end while File.exists?(tmpname)
237 tmpname
246 tmpname
238 end
247 end
239
248
@@ -1,36 +1,53
1 #!/usr/bin/ruby
1 #!/usr/bin/ruby
2
2
3 + require 'fileutils'
4 +
3 def log(str='')
5 def log(str='')
4 if ENV['TALKATIVE']!=nil
6 if ENV['TALKATIVE']!=nil
5 puts str
7 puts str
6 end
8 end
7 if ENV['GRADER_LOGGING']!=nil
9 if ENV['GRADER_LOGGING']!=nil
8 log_fname = ENV['GRADER_LOGGING']
10 log_fname = ENV['GRADER_LOGGING']
9 fp = File.open(log_fname,"a")
11 fp = File.open(log_fname,"a")
10 fp.puts("judge: #{Time.new.strftime("%H:%M")} #{str}")
12 fp.puts("judge: #{Time.new.strftime("%H:%M")} #{str}")
11 fp.close
13 fp.close
12 end
14 end
13 end
15 end
14
16
15 problem_home = ENV['PROBLEM_HOME']
17 problem_home = ENV['PROBLEM_HOME']
16
18
17 def execute(command, error_message="")
19 def execute(command, error_message="")
18 if not system(command)
20 if not system(command)
19 msg = "ERROR: #{error_message}"
21 msg = "ERROR: #{error_message}"
20 log msg
22 log msg
21 raise msg
23 raise msg
22 end
24 end
23 end
25 end
24
26
27 + def call_and_log(error_message)
28 + begin
29 + yield
30 + rescue
31 + msg = "ERROR: #{error_message}"
32 + log msg
33 + raise msg
34 + end
35 + end
36 +
37 + def clear_and_create_empty_dir(dir)
38 + FileUtils.rm_rf(dir, :secure => true)
39 + call_and_log("Cannot make directory #{dir}.") { FileUtils.mkdir(dir) }
40 + end
41 +
25 # ARGV[0] --- language
42 # ARGV[0] --- language
26 # ARGV[1] --- program source file
43 # ARGV[1] --- program source file
27 # ARGV[2] --- test result directory
44 # ARGV[2] --- test result directory
28 # ARGV[3] --- sandbox directory
45 # ARGV[3] --- sandbox directory
29
46
30 if ARGV.length < 2 || ARGV.length > 4
47 if ARGV.length < 2 || ARGV.length > 4
31 puts "Usage: judge <language> <program-source> [<test-result-directory>] [<sandbox-directory>]"
48 puts "Usage: judge <language> <program-source> [<test-result-directory>] [<sandbox-directory>]"
32 puts " <sandbox-directory> is defaulted to ./sandbox"
49 puts " <sandbox-directory> is defaulted to ./sandbox"
33 puts " <test-result-directory> is defaulted to ./test-result"
50 puts " <test-result-directory> is defaulted to ./test-result"
34 puts "WARNING: The judge script will forcefully create the (implicitly and explicitly) specified directories and remove anything inside it."
51 puts "WARNING: The judge script will forcefully create the (implicitly and explicitly) specified directories and remove anything inside it."
35 exit(127)
52 exit(127)
36 end
53 end
@@ -40,94 +57,111
40 log "You specified a language that is not supported: #{language}."
57 log "You specified a language that is not supported: #{language}."
41 exit(127)
58 exit(127)
42 end
59 end
43
60
44 source_file = ARGV[1]
61 source_file = ARGV[1]
45 if File.exist?(source_file) == false
62 if File.exist?(source_file) == false
46 log "The source file does not exist."
63 log "The source file does not exist."
47 exit(127)
64 exit(127)
48 end
65 end
49
66
50 log "Making test result and sandbox directories..."
67 log "Making test result and sandbox directories..."
51
68
52 - current_dir = `pwd`
69 + current_dir = FileUtils.pwd
53 current_dir.strip!
70 current_dir.strip!
54
71
55 if ARGV.length >= 3
72 if ARGV.length >= 3
56 test_result_dir = ARGV[2]
73 test_result_dir = ARGV[2]
57 else
74 else
58 test_result_dir = "#{current_dir}/test-result"
75 test_result_dir = "#{current_dir}/test-result"
59 end
76 end
77 +
60 log "Test result directory: #{test_result_dir}"
78 log "Test result directory: #{test_result_dir}"
61 - system("rm -Rf #{test_result_dir}")
79 + clear_and_create_empty_dir(test_result_dir)
62 - execute("mkdir #{test_result_dir}", "Cannot make directory #{test_result_dir}.")
63
80
64 if ARGV.length >= 4
81 if ARGV.length >= 4
65 sandbox_dir = ARGV[3]
82 sandbox_dir = ARGV[3]
66 else
83 else
67 sandbox_dir = "#{current_dir}/sandbox"
84 sandbox_dir = "#{current_dir}/sandbox"
68 end
85 end
69 log "Sandbox directory: #{sandbox_dir}"
86 log "Sandbox directory: #{sandbox_dir}"
70 - system("rm -Rf #{sandbox_dir}")
87 + clear_and_create_empty_dir(sandbox_dir)
71 - execute("mkdir #{sandbox_dir}", "Cannot make directory #{sandbox_dir}")
72
88
73 # Compile
89 # Compile
74 log
90 log
75 log "Compiling..."
91 log "Compiling..."
76 - execute("cp #{source_file} #{sandbox_dir}", "Cannot copy the source file to #{sandbox_dir}")
92 + call_and_log("Cannot copy the source file to #{sandbox_dir}") {
93 + FileUtils.cp(source_file, sandbox_dir)
94 + }
77 begin
95 begin
78 Dir.chdir sandbox_dir
96 Dir.chdir sandbox_dir
79 rescue
97 rescue
80 log "ERROR: Cannot change directory to #{sandbox_dir}."
98 log "ERROR: Cannot change directory to #{sandbox_dir}."
81 exit(127)
99 exit(127)
82 end
100 end
83 execute("#{problem_home}/script/compile #{language} #{source_file}", "Compilation error!")
101 execute("#{problem_home}/script/compile #{language} #{source_file}", "Compilation error!")
84 - compile_message = `cat compiler_message`
102 + compile_message = open("compiler_message").read
85 compile_message.strip!
103 compile_message.strip!
86 - execute("mv compiler_message #{test_result_dir}", "Cannot move the compiler message to #{test_result_dir}.")
104 + call_and_log("Cannot move the compiler message to #{test_result_dir}.") {
105 + FileUtils.mv("compiler_message", test_result_dir)
106 + }
87 if !FileTest.exist?("a.out")
107 if !FileTest.exist?("a.out")
88 log "Cannot compile the source code. See message in #{test_result_dir}/compile_message"
108 log "Cannot compile the source code. See message in #{test_result_dir}/compile_message"
89 exit(127)
109 exit(127)
90 else
110 else
91 - execute("mv a.out #{test_result_dir}", "Cannot move the compiled program to #{test_result_dir}")
111 + call_and_log("Cannot move the compiled program to #{test_result_dir}") {
92 - system("rm -Rf #{sandbox_dir}/*")
112 + FileUtils.mv("a.out",test_result_dir)
113 + }
114 + FileUtils.rm_rf("#{sandbox_dir}/.")
93 end
115 end
94
116
95 require "#{problem_home}/script/test_dsl.rb"
117 require "#{problem_home}/script/test_dsl.rb"
96 load "#{problem_home}/test_cases/all_tests.cfg"
118 load "#{problem_home}/test_cases/all_tests.cfg"
97 problem = Problem.get_instance
119 problem = Problem.get_instance
98
120
99 if problem.well_formed? == false
121 if problem.well_formed? == false
100 log "The problem specification is not well formed."
122 log "The problem specification is not well formed."
101 exit(127)
123 exit(127)
102 end
124 end
103
125
104 # Doing the testing.
126 # Doing the testing.
105 (1..(problem.num_tests)).each do |test_num|
127 (1..(problem.num_tests)).each do |test_num|
106
128
107 $stdout.print "[#{test_num}]"
129 $stdout.print "[#{test_num}]"
108 $stdout.flush
130 $stdout.flush
109
131
110 log "Test number: #{test_num}"
132 log "Test number: #{test_num}"
111 - execute("cp #{test_result_dir}/a.out #{sandbox_dir}", "Cannot copy the compiled program into #{sandbox_dir}")
133 + call_and_log("Cannot copy the compiled program into #{sandbox_dir}") {
134 + FileUtils.cp("#{test_result_dir}/a.out", sandbox_dir)
135 + }
112 begin
136 begin
113 execute("#{problem_home}/script/run #{language} #{test_num}", "Error occured during execution of the run script")
137 execute("#{problem_home}/script/run #{language} #{test_num}", "Error occured during execution of the run script")
114 rescue
138 rescue
115 # do nothing
139 # do nothing
116 end
140 end
117 - execute("mkdir #{test_result_dir}/#{test_num}", "Cannot create directory #{test_result_dir}/#{test_num}")
141 + call_and_log("Cannot create directory #{test_result_dir}/#{test_num}") {
118 - execute("mv #{sandbox_dir}/result #{test_result_dir}/#{test_num}", "Cannot copy the result file into #{test_result_dir}/#{test_num}")
142 + FileUtils.mkdir "#{test_result_dir}/#{test_num}"
119 - execute("mv #{sandbox_dir}/comment #{test_result_dir}/#{test_num}", "Cannot copy the comment file into #{test_result_dir}/#{test_num}")
143 + }
120 - execute("mv #{sandbox_dir}/output.txt #{test_result_dir}/#{test_num}", "Cannot copy the output file into #{test_result_dir}/#{test_num}")
144 + call_and_log("Cannot copy the result file into #{test_result_dir}/#{test_num}") {
121 - execute("rm -Rf #{sandbox_dir}/*", "Cannot clear #{sandbox_dir}")
145 + FileUtils.mv "#{sandbox_dir}/result", "#{test_result_dir}/#{test_num}"
146 + }
147 + call_and_log("Cannot copy the comment file into #{test_result_dir}/#{test_num}") {
148 + FileUtils.mv "#{sandbox_dir}/comment", "#{test_result_dir}/#{test_num}"
149 + }
150 + call_and_log("Cannot copy the output file into #{test_result_dir}/#{test_num}") {
151 + FileUtils.mv "#{sandbox_dir}/output.txt", "#{test_result_dir}/#{test_num}"
152 + }
153 + call_and_log("Cannot clear #{sandbox_dir}") {
154 + FileUtils.rm_rf(Dir.glob("#{sandbox_dir}/*"), :secure => true)
155 + }
122 end
156 end
123
157
124 $stdout.print "[done]\n"
158 $stdout.print "[done]\n"
125
159
126 # Grade
160 # Grade
127 log
161 log
128 log "Grading..."
162 log "Grading..."
129 begin
163 begin
130 Dir.chdir test_result_dir
164 Dir.chdir test_result_dir
131 rescue
165 rescue
132 log "ERROR: Cannot change directory to #{test_result_dir}."
166 log "ERROR: Cannot change directory to #{test_result_dir}."
133 exit(127)
167 exit(127)
@@ -102,25 +102,25
102
102
103 run_stat = run_result[run_result.length-1]
103 run_stat = run_result[run_result.length-1]
104 running_time = extract_time(run_stat)
104 running_time = extract_time(run_stat)
105
105
106 report = lambda{ |status, points, comment|
106 report = lambda{ |status, points, comment|
107 result_file.write status.strip
107 result_file.write status.strip
108 result_file.write "\n"
108 result_file.write "\n"
109 result_file.write points.to_s.strip
109 result_file.write points.to_s.strip
110 result_file.write "\n"
110 result_file.write "\n"
111 result_file.write run_stat.strip
111 result_file.write run_stat.strip
112 result_file.write "\n"
112 result_file.write "\n"
113 result_file.close
113 result_file.close
114 - `rm run_result`
114 + FileUtils.rm "run_result"
115 # `rm output.txt` --- keep the output
115 # `rm output.txt` --- keep the output
116
116
117 comment_file.write comment
117 comment_file.write comment
118
118
119 # added for debuggin --- jittat
119 # added for debuggin --- jittat
120 comment_file.write "--run-result--\n"
120 comment_file.write "--run-result--\n"
121 run_result.each do |l|
121 run_result.each do |l|
122 comment_file.write l
122 comment_file.write l
123 end
123 end
124
124
125 comment_file.close
125 comment_file.close
126
126
@@ -1,26 +1,27
1 + require 'fileutils'
2 +
1 module GraderEngineHelperMethods
3 module GraderEngineHelperMethods
2
4
3 def clear_sandbox
5 def clear_sandbox
4 config = Grader::Configuration.get_instance
6 config = Grader::Configuration.get_instance
5 - clear_cmd = "rm -rf #{config.test_sandbox_dir}/*"
7 + FileUtils.rm_rf(Dir.glob("#{config.test_sandbox_dir}/*"),
6 - system(clear_cmd)
8 + :secure => true)
7 end
9 end
8
10
9 def init_sandbox
11 def init_sandbox
10 config = Grader::Configuration.get_instance
12 config = Grader::Configuration.get_instance
11 clear_sandbox
13 clear_sandbox
12 FileUtils.mkdir_p config.user_result_dir
14 FileUtils.mkdir_p config.user_result_dir
13 - cp_cmd = "cp -R #{config.test_data_dir}/ev #{config.test_sandbox_dir}"
15 + FileUtils.cp_r("#{config.test_data_dir}/ev", "#{config.test_sandbox_dir}")
14 - system(cp_cmd)
15 end
16 end
16
17
17 def create_submission_from_file(id, user, problem,
18 def create_submission_from_file(id, user, problem,
18 source_fname, language=nil)
19 source_fname, language=nil)
19
20
20 language = stub(Language, :name => 'c', :ext => 'c') if language==nil
21 language = stub(Language, :name => 'c', :ext => 'c') if language==nil
21
22
22 config = Grader::Configuration.get_instance
23 config = Grader::Configuration.get_instance
23 source = File.open(config.test_data_dir + "/" + source_fname).read
24 source = File.open(config.test_data_dir + "/" + source_fname).read
24 stub(Submission,
25 stub(Submission,
25 :id => id, :user => user, :problem => problem,
26 :id => id, :user => user, :problem => problem,
26 :source => source, :language => language)
27 :source => source, :language => language)
You need to be logged in to leave comments. Login now