Description:
translates test_request input/output file paths for remote grading test_request
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r117:cc3e1102f8c6 - - 5 files changed: 35 inserted, 2 deleted

@@ -1,20 +1,23
1 1 #
2 2 # See documentation in lib/configuration.rb
3 3 #
4 4 Grader::Initializer.run do |config|
5 5
6 6 config.problems_dir = GRADER_ROOT + "/../ev-exam"
7 7 config.user_result_dir = GRADER_ROOT + "/../result"
8 8
9 9 config.talkative = true
10 10 config.logging = true
11 11 config.log_dir = GRADER_ROOT + "/../log"
12 12
13 13 config.report_grader = true
14 14
15 15 config.test_request_input_base_dir = RAILS_ROOT + "/data/test_request/input"
16 16 config.test_request_output_base_dir = RAILS_ROOT + "/data/test_request/output"
17 17 config.test_request_problem_templates_dir = config.problems_dir + "/test_request"
18 18
19 + # change this if you want the path on the output to be translated
20 + config.test_request_org_output_base_dir = config.test_request_output_base_dir
21 +
19 22 config.comment_report_style = :short
20 23 end
@@ -1,19 +1,22
1 1 #
2 2 # See documentation in lib/configuration.rb
3 3 #
4 4 Grader::Initializer.run do |config|
5 5 config.problems_dir = GRADER_ROOT + "/../ev"
6 6 config.user_result_dir = GRADER_ROOT + "/../result"
7 7
8 8 config.talkative = true
9 9 config.logging = true
10 10 config.log_dir = GRADER_ROOT + "/../log"
11 11
12 12 config.report_grader = true
13 13
14 14 config.test_request_input_base_dir = RAILS_ROOT + "/data/test_request/input"
15 15 config.test_request_output_base_dir = RAILS_ROOT + "/data/test_request/output"
16 16 config.test_request_problem_templates_dir = config.problems_dir + "/test_request"
17 17
18 + # change this if you want the path on the output to be translated
19 + config.test_request_org_output_base_dir = config.test_request_output_base_dir
20 +
18 21 config.comment_report_style = :full
19 22 end
@@ -1,29 +1,32
1 1 #
2 2 # See documentation in lib/configuration.rb
3 3 #
4 4 Grader::Initializer.run do |config|
5 5 config.problems_dir = GRADER_ROOT + "/test/sandbox/ev"
6 6 config.user_result_dir = GRADER_ROOT + "/test/sandbox/result"
7 7
8 8 config.talkative = false
9 9
10 10 config.report_grader = false
11 11
12 12 config.rails_env = 'test'
13 13
14 14 config.comment_report_style = :full
15 15
16 16 config.test_request_input_base_dir = GRADER_ROOT + "/test/data/test_request/input"
17 17 config.test_request_output_base_dir = GRADER_ROOT + "/test/sandbox/test_request/output"
18 18 config.test_request_problem_templates_dir = GRADER_ROOT + "/test/data/test_request/problems"
19 19
20 + # change this if you want the path on the output to be translated
21 + config.test_request_org_output_base_dir = config.test_request_output_base_dir
22 +
20 23 #
21 24 # These options are for testing
22 25 #
23 26 class << config
24 27 attr_accessor :test_data_dir, :test_sandbox_dir
25 28 end
26 29
27 30 config.test_data_dir = GRADER_ROOT + "/test/data"
28 31 config.test_sandbox_dir = GRADER_ROOT + "/test/sandbox"
29 32 end
@@ -12,48 +12,52
12 12 # execution results for submission [x] of user [u] in directory
13 13 # user_result_dir/[u]/[x]
14 14 attr_accessor :problems_dir
15 15 attr_accessor :user_result_dir
16 16
17 17 # If report_grader=true, the grader would add a row in model
18 18 # GraderProcess. It would report itself with grader_hostname and
19 19 # process id.
20 20 attr_accessor :report_grader
21 21 attr_accessor :grader_hostname
22 22
23 23 # If talkative=true, grader would report status to console. If
24 24 # logging=true, grader would report status to a log file located
25 25 # in log_dir, in a file name mode.options.pid. TODO: defined
26 26 # log file naming.
27 27 attr_accessor :talkative
28 28 attr_accessor :logging
29 29 attr_accessor :log_dir
30 30
31 31 # These are directories related to the test interface.
32 32 attr_accessor :test_request_input_base_dir
33 33 attr_accessor :test_request_output_base_dir
34 34 attr_accessor :test_request_problem_templates_dir
35 35
36 + # this is for linking output from test request
37 + # TODO: find a cleaner way to do this.
38 + attr_accessor :test_request_org_output_base_dir
39 +
36 40 # Comment received from the grading script will be filtered
37 41 # through Configuration#report_comment. How this method behave
38 42 # depends on this option; right now only two formats, :short and
39 43 # :long
40 44 attr_accessor :comment_report_style
41 45
42 46 def report_comment(comment)
43 47 case comment_report_style
44 48 when :short
45 49 if comment.chomp =~ /^[\[\]P]+$/ # all P's
46 50 'passed'
47 51 elsif comment.chomp =~ /[Cc]ompil.*[Ee]rror/
48 52 'compilation error'
49 53 else
50 54 'failed'
51 55 end
52 56
53 57 when :full
54 58 comment.chomp
55 59 end
56 60 end
57 61
58 62 # Codes for singleton
59 63 private_class_method :new
@@ -1,31 +1,37
1 1 #
2 2 # This part contains various test_request helpers for interfacing
3 3 # with Grader::Engine. There are TestRequestRoomMaker and
4 4 # TestRequestReporter.
5 5
6 6 module Grader
7 7
8 + def self.translate_filepath(filename, marker, new_base_path)
9 + p = filename.index(marker)
10 + end_path = filename[(p+marker.length)..-1]
11 + return new_base_path + end_path
12 + end
13 +
8 14 def self.link_or_copy(src, des)
9 15 begin
10 16 FileUtils.ln_s(src, des)
11 17 rescue NotImplementedError
12 18 FileUtils.cp(src,des)
13 19 end
14 20 end
15 21
16 22 def self.call_and_log(error_message)
17 23 begin
18 24 yield
19 25 rescue
20 26 msg = "ERROR: #{error_message}"
21 27 raise msg
22 28 end
23 29 end
24 30
25 31 #
26 32 # A TestRequestRoomMaker is a helper object for Engine
27 33 # - finds grading room: in user_result_dir/(user)/test_request/ ...
28 34 # - prepare problem configuration for grading --- basically it copy
29 35 # all config files, and copy user's input into the testcase
30 36 # directory. First, it finds the template from problem template
31 37 # directory; if it can't find a template, it'll use the template
@@ -83,50 +89,57
83 89
84 90 protected
85 91 def grading_room_dir(test_request)
86 92 problem_name = test_request.problem_name
87 93 user = test_request.user
88 94 grading_room = "#{@config.user_result_dir}" +
89 95 "/#{user.login}/test_request" +
90 96 "/#{problem_name}/#{test_request.id}"
91 97 grading_room
92 98 end
93 99
94 100 def problem_home_dir(test_request)
95 101 problem_name = test_request.problem_name
96 102 user = test_request.user
97 103 "#{@config.user_result_dir}" +
98 104 "/#{user.login}/test_request/#{problem_name}"
99 105 end
100 106
101 107 def copy_problem_template(template_dir,problem_home)
102 108 Grader::call_and_log("Test Request: cannot copy problem template") {
103 109 FileUtils.cp_r("#{template_dir}/.","#{problem_home}")
104 110 }
105 111 end
106 112
113 + def translate_input_filename(filename)
114 + return Grader::translate_filepath(filename,
115 + 'input',
116 + @config.test_request_input_base_dir)
117 + end
118 +
107 119 def link_input_file(test_request, problem_home)
108 - input_fname = "#{test_request.input_file_name}"
120 + input_fname = translate_input_filename(test_request.input_file_name)
121 +
109 122 if !File.exists?(input_fname)
110 123 raise "Test Request: input file not found."
111 124 end
112 125
113 126 input_fname_problem_home = "#{problem_home}/test_cases/1/input-1.txt"
114 127 if File.exists?(input_fname_problem_home)
115 128 FileUtils.rm([input_fname_problem_home], :force => true)
116 129 end
117 130
118 131 Grader::link_or_copy("#{input_fname}", "#{input_fname_problem_home}")
119 132 end
120 133
121 134 def remove_data_files(problem_home)
122 135 if File.exists?("#{problem_home}/test_cases/1/input-1.txt")
123 136 Grader::call_and_log("Test Request: cannot remove data files") {
124 137 FileUtils.rm Dir.glob("#{problem_home}/test_cases/1/*")
125 138 }
126 139 end
127 140 end
128 141
129 142 end
130 143
131 144 class TestRequestReporter
132 145 def initialize
@@ -193,62 +206,69
193 206 seconds = (res[1].to_f + res[2].to_f)
194 207 time_stat = "Time used: #{seconds} sec."
195 208 else
196 209 seconds = nil
197 210 time_stat = "Time used: n/a sec."
198 211 end
199 212
200 213 # extract memory usage
201 214 if res = /s(.*)m/.match(running_stat_line)
202 215 memory_used = res[1].to_i
203 216 else
204 217 memory_used = -1
205 218 end
206 219
207 220 return {
208 221 :msg => "#{run_stat}\n#{time_stat}",
209 222 :running_time => seconds,
210 223 :exit_status => run_stat,
211 224 :memory_usage => memory_used
212 225 }
213 226 end
214 227
215 228 def save_result(test_request,result)
216 229 if result[:output_file_name]!=nil
217 - test_request.output_file_name = link_output_file(test_request,
230 + org_filename = link_output_file(test_request,
218 231 result[:output_file_name])
232 + test_request.output_file_name = translate_output_filename(org_filename)
219 233 end
220 234 test_request.graded_at = Time.now
221 235 test_request.compiler_message = (result[:cmp_msg] or '')
222 236 test_request.grader_comment = (result[:comment] or '')
223 237 if result[:running_stat]!=nil
224 238 test_request.running_stat = (result[:running_stat][:msg] or '')
225 239 test_request.running_time = (result[:running_stat][:running_time] or nil)
226 240 test_request.exit_status = result[:running_stat][:exit_status]
227 241 test_request.memory_usage = result[:running_stat][:memory_usage]
228 242 else
229 243 test_request.running_stat = ''
230 244 end
231 245 test_request.save
232 246 end
233 247
234 248 protected
249 + def translate_output_filename(filename)
250 + return Grader::translate_filepath(filename,
251 + 'output',
252 + @config.test_request_org_output_base_dir)
253 + end
254 +
235 255 def link_output_file(test_request, fname)
236 256 target_file_name = random_output_file_name(test_request.user,
237 257 test_request.problem)
238 258 FileUtils.mkdir_p(File.dirname(target_file_name))
239 259 Grader::link_or_copy("#{fname}", "#{target_file_name}")
240 260 return target_file_name
241 261 end
242 262
243 263 def random_output_file_name(user,problem)
244 264 problem_name = TestRequest.name_of(problem)
245 265 begin
246 266 tmpname = "#{@config.test_request_output_base_dir}" +
247 267 "/#{user.login}/#{problem_name}/#{rand(10000)}"
248 268 end while File.exists?(tmpname)
249 269 tmpname
250 270 end
251 271
252 272 end
253 273
254 274 end
You need to be logged in to leave comments. Login now