Description:
Merge branch 'master' of gitorious.org:cafe-grader/cafe-grader-judge-scripts into windows
Commit status:
[Not Reviewed]
References:
merge default
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r124:20e4101950cb - - 8 files changed: 264 inserted, 123 deleted

@@ -0,0 +1,3
1 + sandbox
2 + coverage
3 +
@@ -0,0 +1,13
1 + /*
2 + LANG: C++
3 + */
4 + #include <cstdio>
5 +
6 + int main()
7 + {
8 + int a,b,r;
9 + r = scanf("%d %d",&a,&b);
10 + printf("%d\n",a+b);
11 + return 0;
12 + }
13 +
@@ -0,0 +1,14
1 + require 'rake'
2 + require 'spec/rake/spectask'
3 +
4 + desc "Run all examples"
5 + Spec::Rake::SpecTask.new('spec') do |t|
6 + t.spec_files = FileList['*spec.rb']
7 + end
8 +
9 + desc "Run all examples with RCov"
10 + Spec::Rake::SpecTask.new('spec_with_rcov') do |t|
11 + t.spec_files = FileList['*spec.rb']
12 + t.rcov = true
13 + t.rcov_opts = ['--exclude', '.*_spec\.rb']
14 + end
@@ -47,13 +47,13
47 47 Grader.
48 48 using: (1) grader
49 49 (2) grader environment [mode]
50 50 (3) grader stop [all|pids-list]
51 51 (4) grader --help
52 52 (1) call grader with environment = 'exam', mode = 'queue'
53 - (2) possible modes are: 'queue', 'prob', 'test_request'
53 + (2) possible modes are: 'queue', 'test_request', 'prob', 'sub', 'contest', and 'autonew'
54 54 (3) create stop-file to stop running grader in queue mode
55 55 (4) You are here.
56 56 USAGE
57 57 end
58 58
59 59 def process_options_and_stop_file
@@ -105,19 +105,19
105 105 if ARGV.length >=1
106 106 options[:mode] = ARGV.shift
107 107 end
108 108 end
109 109
110 110 options[:dry_run] = (ARGV.delete('--dry') != nil)
111 - if options[:dry_run] and (not ['prob','contest'].include? options[:mode])
111 + if options[:dry_run] and (not ['prob','contest','autonew'].include? options[:mode])
112 112 puts "Dry run currently works only for 'prob' or 'contest' modes."
113 113 exit(0)
114 114 end
115 115
116 116 options[:report] = (ARGV.delete('--report') != nil)
117 - if options[:report] and (not ['prob','contest'].include? options[:mode])
117 + if options[:report] and (not ['prob','contest','autonew'].include? options[:mode])
118 118 puts "Report currently works only for 'prob' or 'contest' modes."
119 119 exit(0)
120 120 end
121 121
122 122 return options
123 123 end
@@ -126,20 +126,27
126 126 def initialize
127 127 @results = {}
128 128 @problems = {}
129 129 @users = {}
130 130 end
131 131
132 - def save(user, problem, grading_result)
132 + def after_save_hook(submission, grading_result)
133 + end
134 +
135 + def save(submission, grading_result)
136 + user = submission.user
137 + problem = submission.problem
133 138 if not @problems.has_key? problem.id
134 139 @problems[problem.id] = problem
135 140 end
136 141 if not @users.has_key? user.id
137 142 @users[user.id] = user
138 143 end
139 144 @results[[user.id, problem.id]] = grading_result
145 +
146 + after_save_hook(submission, grading_result)
140 147 end
141 148
142 149 def print_report_by_user
143 150 puts "---------------------"
144 151 puts " REPORT"
145 152 puts "---------------------"
@@ -161,12 +168,206
161 168 end
162 169 print "\n"
163 170 end
164 171 end
165 172 end
166 173
174 + def grader_general_loop(engine, grader_proc, options)
175 + runner = Grader::Runner.new(engine, grader_proc)
176 + while true
177 +
178 + if check_stopfile # created by calling grader stop
179 + clear_stopfile
180 + log "stopped (with stop file)"
181 + break
182 + end
183 +
184 + task = yield(runner)
185 +
186 + if task==nil
187 + sleep(1)
188 + end
189 + end
190 + end
191 +
192 + def grader_queue_loop(grader_proc, options)
193 + log "Grader: queue"
194 + engine = Grader::Engine.new
195 + grader_general_loop(engine, grader_proc, options) do |runner|
196 + runner.grade_oldest_task
197 + end
198 + end
199 +
200 + def grader_test_request_loop(grader_proc, options)
201 + log "Grader: test_request"
202 + engine = Grader::Engine.new(:room_maker => Grader::TestRequestRoomMaker.new,
203 + :reporter => Grader::TestRequestReporter.new)
204 + grader_general_loop(engine, grader_proc, options) do |runner|
205 + runner.grade_oldest_test_request
206 + end
207 + end
208 +
209 + def grader_autonew_loop(grader_proc, options)
210 + log "Grader: autonew"
211 +
212 + if options[:report]
213 + result_collector = ResultCollector.new
214 + else
215 + result_collector = nil
216 + end
217 +
218 + if options[:dry_run]
219 + puts "Running in dry mode"
220 + end
221 +
222 + prob_reporter = Grader::SubmissionReporter.new(:dry_run => options[:dry_run],
223 + :result_collector => result_collector)
224 +
225 + engine = Grader::Engine.new(:reporter => prob_reporter)
226 + runner = Grader::Runner.new(engine, grader_proc)
227 +
228 + grader_proc.report_active if grader_proc!=nil
229 +
230 + latest_submitted_at = nil
231 + graded_submission_ids = {}
232 +
233 + while true
234 +
235 + if check_stopfile # created by calling grader stop
236 + clear_stopfile
237 + log "stopped (with stop file)"
238 + break
239 + end
240 +
241 + if latest_submitted_at==nil
242 + submissions = Submission.all
243 + else
244 + submissions = Submission.all(:conditions => ["submitted_at >= :latest",
245 + {:latest => latest_submitted_at}])
246 + end
247 +
248 + graded_any = false
249 +
250 + if submissions.length != 0
251 + submissions.each do |submission|
252 + if ! graded_submission_ids[submission.id]
253 + runner.grade_submission(submission)
254 + graded_submission_ids[submission.id] = true
255 + if (!latest_submitted_at or
256 + latest_submitted_at < submission.submitted_at)
257 + latest_submitted_at = submission.submitted_at
258 + end
259 + puts "graded: #{submission.id}"
260 + puts "latest: #{latest_submitted_at}"
261 + graded_any = true
262 + end
263 + end
264 + end
265 +
266 + if ! graded_any
267 + sleep(1)
268 + end
269 + end
270 + end
271 +
272 + def grader_grade_problems(grader_proc, options)
273 + if options[:report]
274 + result_collector = ResultCollector.new
275 + else
276 + result_collector = nil
277 + end
278 +
279 + if options[:dry_run]
280 + puts "Running in dry mode"
281 + end
282 +
283 + prob_reporter = Grader::SubmissionReporter.new(:dry_run => options[:dry_run],
284 + :result_collector => result_collector)
285 + engine = Grader::Engine.new(:reporter => prob_reporter)
286 + runner = Grader::Runner.new(engine, grader_proc)
287 +
288 + grader_proc.report_active if grader_proc!=nil
289 +
290 + ARGV.each do |prob_name|
291 + prob = Problem.find_by_name(prob_name)
292 + if prob==nil
293 + puts "cannot find problem: #{prob_name}"
294 + else
295 + runner.grade_problem(prob)
296 + end
297 + end
298 +
299 + if options[:report]
300 + result_collector.print_report_by_user
301 + end
302 + end
303 +
304 + def grader_grade_contests(grader_proc, options)
305 + # always use dry run when grading during contest
306 + dry_run = options[:dry_run] = true
307 +
308 + contest_name = ARGV.shift
309 +
310 + contest = Contest.find_by_name(contest_name)
311 + if contest==nil
312 + puts "cannot find contest: #{contest_name}"
313 + exit(0)
314 + end
315 +
316 + if options[:report]
317 + result_collector = ResultCollector.new
318 + else
319 + result_collector = nil
320 + end
321 +
322 + if options[:dry_run]
323 + puts "Running in dry mode"
324 + end
325 +
326 + prob_reporter = Grader::SubmissionReporter.new(:dry_run => dry_run,
327 + :result_collector => result_collector)
328 + engine = Grader::Engine.new(:reporter => prob_reporter)
329 + runner = Grader::Runner.new(engine, grader_proc)
330 +
331 + grader_proc.report_active if grader_proc!=nil
332 +
333 + contest.problems.each do |problem|
334 + puts "Grading: #{problem.name}"
335 + runner.grade_problem(problem,
336 + :user_conditions => lambda do |u|
337 + u.contest_finished? and
338 + u.contest_ids.include?(contest.id)
339 + end)
340 + end
341 +
342 + if options[:report]
343 + result_collector.print_report_by_user
344 + end
345 + end
346 +
347 + def grader_grade_submissions(grader_proc, options)
348 + engine = Grader::Engine.new
349 + runner = Grader::Runner.new(engine, grader_proc)
350 +
351 + grader_proc.report_active if grader_proc!=nil
352 +
353 + ARGV.each do |sub_id|
354 + puts "Grading #{sub_id}"
355 + begin
356 + submission = Submission.find(sub_id.to_i)
357 + rescue ActiveRecord::RecordNotFound
358 + puts "Record not found"
359 + submission = nil
360 + end
361 +
362 + if submission!=nil
363 + runner.grade_submission(submission)
364 + end
365 + end
366 + end
367 +
167 368 #########################################
168 369 # main program
169 370 #########################################
170 371
171 372 options = process_options_and_stop_file
172 373 GRADER_ENV = options[:environment]
@@ -211,134 +412,29
211 412
212 413 #
213 414 # MAIN LOOP
214 415 #
215 416
216 417 case grader_mode
217 - when "queue", "test_request"
218 - log "Grader: #{grader_mode}"
219 - if grader_mode=="queue"
220 - engine = Grader::Engine.new
221 - else
222 - engine = Grader::Engine.new(:room_maker => Grader::TestRequestRoomMaker.new,
223 - :reporter => Grader::TestRequestReporter.new)
224 - end
225 -
226 - runner = Grader::Runner.new(engine, grader_proc)
227 - while true
418 + when "queue"
419 + grader_queue_loop(grader_proc, options)
228 420
229 - if check_stopfile # created by calling grader stop
230 - clear_stopfile
231 - log "stopped (with stop file)"
232 - break
233 - end
234 -
235 - if grader_mode=="queue"
236 - task = runner.grade_oldest_task
237 - else
238 - task = runner.grade_oldest_test_request
239 - end
240 - if task==nil
241 - sleep(1)
242 - end
243 - end
421 + when "test_request"
422 + grader_test_request_loop(grader_proc, options)
244 423
245 424 when "prob"
246 - if options[:report]
247 - result_collector = ResultCollector.new
248 - else
249 - result_collector = nil
250 - end
251 -
252 - if options[:dry_run]
253 - puts "Running in dry mode"
254 - end
255 -
256 - prob_reporter = Grader::SubmissionReporter.new(:dry_run => dry_run,
257 - :result_collector => result_collector)
258 - engine = Grader::Engine.new(:reporter => prob_reporter)
259 - runner = Grader::Runner.new(engine, grader_proc)
260 -
261 - grader_proc.report_active if grader_proc!=nil
262 -
263 - ARGV.each do |prob_name|
264 - prob = Problem.find_by_name(prob_name)
265 - if prob==nil
266 - puts "cannot find problem: #{prob_name}"
267 - else
268 - runner.grade_problem(prob)
269 - end
270 - end
271 -
272 - if options[:report]
273 - result_collector.print_report_by_user
274 - end
425 + grader_grade_problems(grader_proc, options)
275 426
276 427 when "contest"
277 - # always use dry run when grading during contest
278 - contest_name = ARGV.shift
279 -
280 - dry_run = options[:dry_run] = true
281 -
282 - contest = Contest.find_by_name(contest_name)
283 - if contest==nil
284 - puts "cannot find contest: #{contest_name}"
285 - exit(0)
286 - end
287 -
288 - if options[:report]
289 - result_collector = ResultCollector.new
290 - else
291 - result_collector = nil
292 - end
293 -
294 - if options[:dry_run]
295 - puts "Running in dry mode"
296 - end
297 -
298 - prob_reporter = Grader::SubmissionReporter.new(:dry_run => dry_run,
299 - :result_collector => result_collector)
300 - engine = Grader::Engine.new(:reporter => prob_reporter)
301 - runner = Grader::Runner.new(engine, grader_proc)
302 -
303 - grader_proc.report_active if grader_proc!=nil
304 -
305 - contest.problems.each do |problem|
306 - puts "Grading: #{problem.name}"
307 - runner.grade_problem(problem,
308 - :user_conditions => lambda do |u|
309 - u.contest_finished? and
310 - u.contest_ids.include?(contest.id)
311 - end)
312 - end
313 -
314 - if options[:report]
315 - result_collector.print_report_by_user
316 - end
428 + grader_grade_contests(grader_proc, options)
317 429
318 430 when "sub"
319 - engine = Grader::Engine.new
320 - runner = Grader::Runner.new(engine, grader_proc)
321 -
322 - grader_proc.report_active if grader_proc!=nil
431 + grader_grade_submissions(grader_proc, options)
323 432
324 - ARGV.each do |sub_id|
325 - puts "Grading #{sub_id}"
326 - begin
327 - submission = Submission.find(sub_id.to_i)
328 - rescue ActiveRecord::RecordNotFound
329 - puts "Record not found"
330 - submission = nil
331 - end
332 -
333 - if submission!=nil
334 - runner.grade_submission(submission)
335 - end
336 - end
337 -
338 -
433 + when "autonew"
434 + grader_autonew_loop(grader_proc, options)
339 435
340 436 else
341 437 display_manual
342 438 exit(0)
343 439 end
344 440
@@ -48,14 +48,14
48 48 lang_ext = submission.language.ext
49 49 else
50 50 language = 'c'
51 51 lang_ext = 'c'
52 52 end
53 53
54 - # FIX THIS
55 - talk 'some hack on language'
54 + # This is needed because older version of std-scripts/compile
55 + # only look for c++.
56 56 if language == 'cpp'
57 57 language = 'c++'
58 58 end
59 59
60 60 # COMMENT: should it be only source.ext?
61 61 if problem!=nil
@@ -39,14 +39,13
39 39 @result_collector = options[:result_collector]
40 40 end
41 41
42 42 def report(sub,test_result_dir)
43 43 result = read_result(test_result_dir)
44 44 if @result_collector
45 - @result_collector.save(sub.user,
46 - sub.problem,
45 + @result_collector.save(sub,
47 46 result)
48 47 end
49 48 save_result(sub,result)
50 49 end
51 50
52 51 def report_error(sub,msg)
@@ -74,12 +74,16
74 74 open(params[:message_file],"w") do |f|
75 75 f.puts "ERROR: The source file did not exist."
76 76 end
77 77 exit(127)
78 78 end
79 79
80 + if params[:prog_lang]=='cpp':
81 + params[:prog_lang] = 'c++'
82 + end
83 +
80 84 # Compile.
81 85 case params[:prog_lang]
82 86
83 87 when "c"
84 88 command = "#{C_COMPILER} #{params[:source_file]} -o #{params[:output_file]} #{C_OPTIONS} 2> #{params[:message_file]}"
85 89 system(command)
@@ -25,12 +25,23
25 25 :and_report => {
26 26 :score => 135,
27 27 :comment => /^(\[|P|\])+/})
28 28 end
29 29
30 30
31 + it "should grade normal submission in C++" do
32 + cpp_lang = stub(Language, :name => 'cpp', :ext => 'cpp')
33 +
34 + grader_should(:grade => "test1_correct_cc.cc",
35 + :language => cpp_lang,
36 + :on => @problem_test_normal,
37 + :and_report => {
38 + :score => 135,
39 + :comment => /^(\[|P|\])+/})
40 + end
41 +
31 42 it "should produce error message when submission cannot compile" do
32 43 grader_should(:grade => "test1_compile_error.c",
33 44 :on => @problem_test_normal,
34 45 :and_report => {
35 46 :score => 0,
36 47 :comment => 'compilation error',
@@ -119,14 +130,15
119 130 :comment => /(-|x)/})
120 131 end
121 132
122 133 def grader_should(args)
123 134 @user1 = stub(User,
124 135 :id => 1, :login => 'user1')
136 +
125 137 submission =
126 - create_submission_from_file(1, @user1, args[:on], args[:grade])
138 + create_submission_from_file(1, @user1, args[:on], args[:grade], args[:language])
127 139 submission.should_receive(:graded_at=)
128 140
129 141 expected_score = args[:and_report][:score]
130 142 expected_comment = args[:and_report][:comment]
131 143 if args[:and_report][:compiler_message]!=nil
132 144 expected_compiler_message = args[:and_report][:compiler_message]
You need to be logged in to leave comments. Login now