Description:
handle the case when problem id or submission id is null. Grader will simply skip such request. Add more report on console (for command line grading)
(mercurial grafted from d233105d3965c5368c9b33125f390e39b25f910e)
Commit status:
[Not Reviewed]
References:
Diff options:
Comments:
0 Commit comments
0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
r181:5c6f0b732e70 - - 2 files changed: 30 inserted, 30 deleted
@@ -313,97 +313,97 | |||
|
313 | 313 | contest = Contest.find_by_name(contest_name) |
|
314 | 314 | if contest==nil |
|
315 | 315 | puts "cannot find contest: #{contest_name}" |
|
316 | 316 | exit(0) |
|
317 | 317 | end |
|
318 | 318 | |
|
319 | 319 | if options[:report] |
|
320 | 320 | result_collector = ResultCollector.new |
|
321 | 321 | else |
|
322 | 322 | result_collector = nil |
|
323 | 323 | end |
|
324 | 324 | |
|
325 | 325 | if options[:dry_run] |
|
326 | 326 | puts "Running in dry mode" |
|
327 | 327 | end |
|
328 | 328 | |
|
329 | 329 | prob_reporter = Grader::SubmissionReporter.new(:dry_run => dry_run, |
|
330 | 330 | :result_collector => result_collector) |
|
331 | 331 | engine = Grader::Engine.new(:reporter => prob_reporter) |
|
332 | 332 | runner = Grader::Runner.new(engine, grader_proc) |
|
333 | 333 | |
|
334 | 334 | grader_proc.report_active if grader_proc!=nil |
|
335 | 335 | |
|
336 | 336 | contest.problems.each do |problem| |
|
337 | 337 | puts "Grading: #{problem.name}" |
|
338 | 338 | runner.grade_problem(problem, |
|
339 | 339 | :user_conditions => lambda do |u| |
|
340 | 340 | u.contest_finished? and |
|
341 | 341 | u.contest_ids.include?(contest.id) |
|
342 | 342 | end) |
|
343 | 343 | end |
|
344 | 344 | |
|
345 | 345 | if options[:report] |
|
346 | 346 | result_collector.print_report_by_user |
|
347 | 347 | end |
|
348 | 348 | end |
|
349 | 349 | |
|
350 | 350 | def grader_grade_submissions(grader_proc, options) |
|
351 | 351 | engine = Grader::Engine.new |
|
352 | 352 | runner = Grader::Runner.new(engine, grader_proc) |
|
353 | 353 | |
|
354 | 354 | grader_proc.report_active if grader_proc!=nil |
|
355 | 355 | |
|
356 | 356 | ARGV.each do |sub_id| |
|
357 | 357 | puts "Grading #{sub_id}" |
|
358 | 358 | begin |
|
359 | 359 | submission = Submission.find(sub_id.to_i) |
|
360 | 360 | rescue ActiveRecord::RecordNotFound |
|
361 |
- puts " |
|
|
361 | + puts "Submission #{sub_id} not found" | |
|
362 | 362 | submission = nil |
|
363 | 363 | end |
|
364 | 364 | |
|
365 | 365 | if submission!=nil |
|
366 | 366 | runner.grade_submission(submission) |
|
367 | 367 | end |
|
368 | 368 | end |
|
369 | 369 | end |
|
370 | 370 | |
|
371 | 371 | ######################################### |
|
372 | 372 | # main program |
|
373 | 373 | ######################################### |
|
374 | 374 | |
|
375 | 375 | options = process_options_and_stop_file |
|
376 | 376 | GRADER_ENV = options[:environment] |
|
377 | 377 | grader_mode = options[:mode] |
|
378 | 378 | dry_run = options[:dry_run] |
|
379 | 379 | |
|
380 | 380 | puts "environment: #{GRADER_ENV}" |
|
381 | 381 | require File.join(File.dirname(__FILE__),'config/environment') |
|
382 | 382 | |
|
383 | 383 | # add grader_mode to config |
|
384 | 384 | # this is needed because method log needs it. TODO: clean this up |
|
385 | 385 | class << config |
|
386 | 386 | attr_accessor :grader_mode |
|
387 | 387 | end |
|
388 | 388 | config.grader_mode = grader_mode |
|
389 | 389 | |
|
390 | 390 | # reading rails environment |
|
391 | 391 | log 'Reading rails environment' |
|
392 | 392 | |
|
393 | 393 | RAILS_ENV = config.rails_env |
|
394 | 394 | require RAILS_ROOT + '/config/environment' |
|
395 | 395 | |
|
396 | 396 | # register grader process |
|
397 | 397 | if config.report_grader |
|
398 | 398 | grader_proc = GraderProcess.register(config.grader_hostname, |
|
399 | 399 | Process.pid, |
|
400 | 400 | grader_mode) |
|
401 | 401 | else |
|
402 | 402 | grader_proc = nil |
|
403 | 403 | end |
|
404 | 404 | |
|
405 | 405 | #set loggin environment |
|
406 | 406 | ENV['GRADER_LOGGING'] = log_file_name |
|
407 | 407 | |
|
408 | 408 | # register exit handler to report inactive, and terminated |
|
409 | 409 | at_exit do |
@@ -1,182 +1,182 | |||
|
1 | 1 | require 'fileutils' |
|
2 | 2 | require File.join(File.dirname(__FILE__),'dir_init') |
|
3 | 3 | |
|
4 | 4 | module Grader |
|
5 | 5 | |
|
6 | 6 | # |
|
7 | 7 | # A grader engine grades a submission, against anything: a test |
|
8 | 8 | # data, or a user submitted test data. It uses two helpers objects: |
|
9 | 9 | # room_maker and reporter. |
|
10 | 10 | # |
|
11 | 11 | class Engine |
|
12 | 12 | |
|
13 | 13 | attr_writer :room_maker |
|
14 | 14 | attr_writer :reporter |
|
15 | 15 | |
|
16 | 16 | def initialize(options={}) |
|
17 | 17 | # default options |
|
18 | 18 | if not options.include? :room_maker |
|
19 | 19 | options[:room_maker] = Grader::SubmissionRoomMaker.new |
|
20 | 20 | end |
|
21 | 21 | if not options.include? :reporter |
|
22 | 22 | options[:reporter] = Grader::SubmissionReporter.new |
|
23 | 23 | end |
|
24 | 24 | |
|
25 | 25 | @config = Grader::Configuration.get_instance |
|
26 | 26 | |
|
27 | 27 | @room_maker = options[:room_maker] |
|
28 | 28 | @reporter = options[:reporter] |
|
29 | 29 | end |
|
30 | 30 | |
|
31 | 31 | # takes a submission, asks room_maker to produce grading directories, |
|
32 | 32 | # calls grader scripts, and asks reporter to save the result |
|
33 | 33 | def grade(submission) |
|
34 | 34 | current_dir = FileUtils.pwd |
|
35 | 35 | |
|
36 | 36 | user = submission.user |
|
37 | 37 | problem = submission.problem |
|
38 | 38 | |
|
39 | - # TODO: will have to create real exception for this | |
|
40 | - if user==nil or problem == nil | |
|
41 | - @reporter.report_error(submission,"Grading error: problem with submission") | |
|
42 | - #raise "engine: user or problem is nil" | |
|
43 | - end | |
|
44 | - | |
|
45 | - # TODO: this is another hack so that output only task can be judged | |
|
46 | - if submission.language!=nil | |
|
47 | - language = submission.language.name | |
|
48 | - lang_ext = submission.language.ext | |
|
49 | - else | |
|
50 | - language = 'c' | |
|
51 | - lang_ext = 'c' | |
|
52 | - end | |
|
39 | + begin | |
|
40 | + # TODO: will have to create real exception for this | |
|
41 | + if user==nil or problem == nil | |
|
42 | + @reporter.report_error(submission,"Grading error: problem with submission") | |
|
43 | + raise "engine: user or problem is nil" | |
|
44 | + end | |
|
53 | 45 | |
|
54 | - # This is needed because older version of std-scripts/compile | |
|
55 | - # only look for c++. | |
|
56 | - if language == 'cpp' | |
|
57 | - language = 'c++' | |
|
58 |
- |
|
|
46 | + # TODO: this is another hack so that output only task can be judged | |
|
47 | + if submission.language!=nil | |
|
48 | + language = submission.language.name | |
|
49 | + lang_ext = submission.language.ext | |
|
50 | + else | |
|
51 | + language = 'c' | |
|
52 | + lang_ext = 'c' | |
|
53 | + end | |
|
59 | 54 | |
|
60 | - # COMMENT: should it be only source.ext? | |
|
61 | - if problem!=nil | |
|
62 | - source_name = "#{problem.name}.#{lang_ext}" | |
|
63 | - else | |
|
64 | - source_name = "source.#{lang_ext}" | |
|
65 | - end | |
|
55 | + # This is needed because older version of std-scripts/compile | |
|
56 | + # only look for c++. | |
|
57 | + if language == 'cpp' | |
|
58 | + language = 'c++' | |
|
59 | + end | |
|
66 | 60 | |
|
67 | - begin | |
|
61 | + # COMMENT: should it be only source.ext? | |
|
62 | + if problem!=nil | |
|
63 | + source_name = "#{problem.name}.#{lang_ext}" | |
|
64 | + else | |
|
65 | + source_name = "source.#{lang_ext}" | |
|
66 | + end | |
|
67 | + | |
|
68 | 68 | grading_dir = @room_maker.produce_grading_room(submission) |
|
69 | 69 | @room_maker.save_source(submission,source_name) |
|
70 | 70 | problem_home = @room_maker.find_problem_home(submission) |
|
71 | 71 | |
|
72 | 72 | # puts "GRADING DIR: #{grading_dir}" |
|
73 | 73 | # puts "PROBLEM DIR: #{problem_home}" |
|
74 | 74 | |
|
75 | 75 | if !FileTest.exist?(problem_home) |
|
76 | 76 | puts "PROBLEM DIR: #{problem_home}" |
|
77 |
- |
|
|
78 | - raise "No test data." | |
|
77 | + raise "engine: No test data." | |
|
79 | 78 | end |
|
80 | 79 | |
|
81 | 80 | dinit = DirInit::Manager.new(problem_home) |
|
82 | 81 | |
|
83 | 82 | dinit.setup do |
|
84 | 83 | copy_log = copy_script(problem_home) |
|
85 | 84 | save_copy_log(problem_home,copy_log) |
|
86 | 85 | end |
|
87 | 86 | |
|
88 | 87 | call_judge(problem_home,language,grading_dir,source_name) |
|
89 | 88 | |
|
90 | 89 | @reporter.report(submission,"#{grading_dir}/test-result") |
|
91 | 90 | |
|
92 | 91 | dinit.teardown do |
|
93 | 92 | copy_log = load_copy_log(problem_home) |
|
94 | 93 | clear_copy_log(problem_home) |
|
95 | 94 | clear_script(copy_log,problem_home) |
|
96 | 95 | end |
|
97 | 96 | |
|
98 | 97 | rescue RuntimeError => msg |
|
99 | 98 | @reporter.report_error(submission, msg) |
|
99 | + puts "ERROR: #{msg}" | |
|
100 | 100 | |
|
101 | 101 | ensure |
|
102 | 102 | @room_maker.clean_up(submission) |
|
103 | 103 | Dir.chdir(current_dir) # this is really important |
|
104 | 104 | end |
|
105 | 105 | end |
|
106 | 106 | |
|
107 | 107 | protected |
|
108 | 108 | |
|
109 | 109 | def talk(str) |
|
110 | 110 | if @config.talkative |
|
111 | 111 | puts str |
|
112 | 112 | end |
|
113 | 113 | end |
|
114 | 114 | |
|
115 | 115 | def call_judge(problem_home,language,grading_dir,fname) |
|
116 | 116 | ENV['PROBLEM_HOME'] = problem_home |
|
117 | 117 | ENV['RUBYOPT'] = '' |
|
118 | 118 | |
|
119 | 119 | talk grading_dir |
|
120 | 120 | Dir.chdir grading_dir |
|
121 | 121 | cmd = "#{problem_home}/script/judge #{language} #{fname}" |
|
122 | 122 | talk "CMD: #{cmd}" |
|
123 | 123 | system(cmd) |
|
124 | 124 | end |
|
125 | 125 | |
|
126 | 126 | def get_std_script_dir |
|
127 | 127 | GRADER_ROOT + '/std-script' |
|
128 | 128 | end |
|
129 | 129 | |
|
130 | 130 | def copy_script(problem_home) |
|
131 | 131 | script_dir = "#{problem_home}/script" |
|
132 | 132 | std_script_dir = get_std_script_dir |
|
133 | 133 | |
|
134 | - raise "std-script directory not found" if !FileTest.exist?(std_script_dir) | |
|
134 | + raise "engine: std-script directory not found" if !FileTest.exist?(std_script_dir) | |
|
135 | 135 | |
|
136 | 136 | scripts = Dir[std_script_dir + '/*'] |
|
137 | 137 | |
|
138 | 138 | copied = [] |
|
139 | 139 | |
|
140 | 140 | scripts.each do |s| |
|
141 | 141 | fname = File.basename(s) |
|
142 | 142 | next if FileTest.directory?(s) |
|
143 | 143 | if !FileTest.exist?("#{script_dir}/#{fname}") |
|
144 | 144 | copied << fname |
|
145 | 145 | FileUtils.cp(s, "#{script_dir}", :preserve => true) |
|
146 | 146 | end |
|
147 | 147 | end |
|
148 | 148 | |
|
149 | 149 | return copied |
|
150 | 150 | end |
|
151 | 151 | |
|
152 | 152 | def copy_log_filename(problem_home) |
|
153 | 153 | return File.join(problem_home, '.scripts_copied') |
|
154 | 154 | end |
|
155 | 155 | |
|
156 | 156 | def save_copy_log(problem_home, log) |
|
157 | 157 | f = File.new(copy_log_filename(problem_home),"w") |
|
158 | 158 | log.each do |fname| |
|
159 | 159 | f.write("#{fname}\n") |
|
160 | 160 | end |
|
161 | 161 | f.close |
|
162 | 162 | end |
|
163 | 163 | |
|
164 | 164 | def load_copy_log(problem_home) |
|
165 | 165 | f = File.new(copy_log_filename(problem_home),"r") |
|
166 | 166 | log = [] |
|
167 | 167 | f.readlines.each do |line| |
|
168 | 168 | log << line.strip |
|
169 | 169 | end |
|
170 | 170 | f.close |
|
171 | 171 | log |
|
172 | 172 | end |
|
173 | 173 | |
|
174 | 174 | def clear_copy_log(problem_home) |
|
175 | 175 | File.delete(copy_log_filename(problem_home)) |
|
176 | 176 | end |
|
177 | 177 | |
|
178 | 178 | def clear_script(log,problem_home) |
|
179 | 179 | log.each do |s| |
|
180 | 180 | FileUtils.rm("#{problem_home}/script/#{s}") |
|
181 | 181 | end |
|
182 | 182 | end |
You need to be logged in to leave comments.
Login now