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: 265 inserted, 124 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
@@ -50,7 +50,7
50 (3) grader stop [all|pids-list]
50 (3) grader stop [all|pids-list]
51 (4) grader --help
51 (4) grader --help
52 (1) call grader with environment = 'exam', mode = 'queue'
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 (3) create stop-file to stop running grader in queue mode
54 (3) create stop-file to stop running grader in queue mode
55 (4) You are here.
55 (4) You are here.
56 USAGE
56 USAGE
@@ -108,13 +108,13
108 end
108 end
109
109
110 options[:dry_run] = (ARGV.delete('--dry') != nil)
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 puts "Dry run currently works only for 'prob' or 'contest' modes."
112 puts "Dry run currently works only for 'prob' or 'contest' modes."
113 exit(0)
113 exit(0)
114 end
114 end
115
115
116 options[:report] = (ARGV.delete('--report') != nil)
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 puts "Report currently works only for 'prob' or 'contest' modes."
118 puts "Report currently works only for 'prob' or 'contest' modes."
119 exit(0)
119 exit(0)
120 end
120 end
@@ -129,7 +129,12
129 @users = {}
129 @users = {}
130 end
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 if not @problems.has_key? problem.id
138 if not @problems.has_key? problem.id
134 @problems[problem.id] = problem
139 @problems[problem.id] = problem
135 end
140 end
@@ -137,6 +142,8
137 @users[user.id] = user
142 @users[user.id] = user
138 end
143 end
139 @results[[user.id, problem.id]] = grading_result
144 @results[[user.id, problem.id]] = grading_result
145 +
146 + after_save_hook(submission, grading_result)
140 end
147 end
141
148
142 def print_report_by_user
149 def print_report_by_user
@@ -164,6 +171,200
164 end
171 end
165 end
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 # main program
369 # main program
169 #########################################
370 #########################################
@@ -214,128 +415,23
214 #
415 #
215
416
216 case grader_mode
417 case grader_mode
217 - when "queue", "test_request"
418 + when "queue"
218 - log "Grader: #{grader_mode}"
419 + grader_queue_loop(grader_proc, options)
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
420
226 - runner = Grader::Runner.new(engine, grader_proc)
421 + when "test_request"
227 - while true
422 + grader_test_request_loop(grader_proc, options)
228 -
423 +
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
244 -
245 when "prob"
424 when "prob"
246 - if options[:report]
425 + grader_grade_problems(grader_proc, options)
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
275
426
276 when "contest"
427 when "contest"
277 - # always use dry run when grading during contest
428 + grader_grade_contests(grader_proc, options)
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
317
429
318 when "sub"
430 when "sub"
319 - engine = Grader::Engine.new
431 + grader_grade_submissions(grader_proc, options)
320 - runner = Grader::Runner.new(engine, grader_proc)
321 -
322 - grader_proc.report_active if grader_proc!=nil
323
432
324 - ARGV.each do |sub_id|
433 + when "autonew"
325 - puts "Grading #{sub_id}"
434 + grader_autonew_loop(grader_proc, options)
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 -
339
435
340 else
436 else
341 display_manual
437 display_manual
@@ -51,8 +51,8
51 lang_ext = 'c'
51 lang_ext = 'c'
52 end
52 end
53
53
54 - # FIX THIS
54 + # This is needed because older version of std-scripts/compile
55 - talk 'some hack on language'
55 + # only look for c++.
56 if language == 'cpp'
56 if language == 'cpp'
57 language = 'c++'
57 language = 'c++'
58 end
58 end
@@ -42,8 +42,7
42 def report(sub,test_result_dir)
42 def report(sub,test_result_dir)
43 result = read_result(test_result_dir)
43 result = read_result(test_result_dir)
44 if @result_collector
44 if @result_collector
45 - @result_collector.save(sub.user,
45 + @result_collector.save(sub,
46 - sub.problem,
47 result)
46 result)
48 end
47 end
49 save_result(sub,result)
48 save_result(sub,result)
@@ -77,6 +77,10
77 exit(127)
77 exit(127)
78 end
78 end
79
79
80 + if params[:prog_lang]=='cpp':
81 + params[:prog_lang] = 'c++'
82 + end
83 +
80 # Compile.
84 # Compile.
81 case params[:prog_lang]
85 case params[:prog_lang]
82
86
@@ -28,6 +28,17
28 end
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 it "should produce error message when submission cannot compile" do
42 it "should produce error message when submission cannot compile" do
32 grader_should(:grade => "test1_compile_error.c",
43 grader_should(:grade => "test1_compile_error.c",
33 :on => @problem_test_normal,
44 :on => @problem_test_normal,
@@ -122,8 +133,9
122 def grader_should(args)
133 def grader_should(args)
123 @user1 = stub(User,
134 @user1 = stub(User,
124 :id => 1, :login => 'user1')
135 :id => 1, :login => 'user1')
136 +
125 submission =
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 submission.should_receive(:graded_at=)
139 submission.should_receive(:graded_at=)
128
140
129 expected_score = args[:and_report][:score]
141 expected_score = args[:and_report][:score]
You need to be logged in to leave comments. Login now