Description:
[grader] +grade submission git-svn-id: http://theory.cpe.ku.ac.th/grader/judge/trunk/scripts@264 6386c4cd-e34a-4fa8-8920-d93eb39b512e
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r61:3dcc15f24294 - - 3 files changed: 34 inserted, 0 deleted

@@ -86,104 +86,127
86 86
87 87 if check_stopfile
88 88 puts "Stop file exists. Terminated."
89 89 clear_stopfile
90 90 exit(0)
91 91 end
92 92
93 93 grader_mode = 'queue'
94 94 if ARGV.length >= 1
95 95 GRADER_ENV = ARGV[0]
96 96 if ARGV.length >=2
97 97 grader_mode = ARGV[1]
98 98 end
99 99 else
100 100 GRADER_ENV = 'exam'
101 101 end
102 102
103 103 puts "environment: #{GRADER_ENV}"
104 104 require File.join(File.dirname(__FILE__),'config/environment')
105 105
106 106 # add grader_mode to config
107 107 # this is needed because method log needs it. TODO: clean this up
108 108 class << config
109 109 attr_accessor :grader_mode
110 110 end
111 111 config.grader_mode = grader_mode
112 112
113 113 # reading rails environment
114 114 log 'Reading rails environment'
115 115
116 116 RAILS_ENV = config.rails_env
117 117 require RAILS_ROOT + '/config/environment'
118 118
119 119 # register grader process
120 120 if config.report_grader
121 121 grader_proc = GraderProcess.register(config.grader_hostname,
122 122 Process.pid,
123 123 grader_mode)
124 124 else
125 125 grader_proc = nil
126 126 end
127 127
128 128 #set loggin environment
129 129 ENV['GRADER_LOGGING'] = log_file_name
130 130
131 131 #
132 132 # MAIN LOOP
133 133 #
134 134
135 135 case grader_mode
136 136 when "queue", "test_request"
137 137 log "Grader: #{grader_mode}"
138 138 if grader_mode=="queue"
139 139 engine = Grader::Engine.new
140 140 else
141 141 engine = Grader::Engine.new(Grader::TestRequestRoomMaker.new,
142 142 Grader::TestRequestReporter.new)
143 143 end
144 144
145 145 runner = Grader::Runner.new(engine, grader_proc)
146 146 while true
147 147
148 148 if check_stopfile # created by calling grader stop
149 149 clear_stopfile
150 150 log "stopped (with stop file)"
151 151 break
152 152 end
153 153
154 154 if grader_mode=="queue"
155 155 task = runner.grade_oldest_task
156 156 else
157 157 task = runner.grade_oldest_test_request
158 158 end
159 159 if task==nil
160 160 sleep(1)
161 161 end
162 162 end
163 163
164 164 when "prob"
165 165 engine = Grader::Engine.new
166 166 runner = Grader::Runner.new(engine, grader_proc)
167 167
168 168 grader_proc.report_active if grader_proc!=nil
169 169
170 170 ARGV.shift
171 171 ARGV.shift
172 172
173 173 ARGV.each do |prob_name|
174 174 prob = Problem.find_by_name(prob_name)
175 175 if prob==nil
176 176 puts "cannot find problem: #{prob_name}"
177 177 else
178 178 runner.grade_problem(prob)
179 179 end
180 180 end
181 181
182 + when "sub"
183 + engine = Grader::Engine.new
184 + runner = Grader::Runner.new(engine, grader_proc)
185 +
186 + grader_proc.report_active if grader_proc!=nil
187 +
188 + ARGV.shift
189 + ARGV.shift
190 +
191 + ARGV.each do |sub_id|
192 + puts "Grading #{sub_id}"
193 + begin
194 + submission = Submission.find(sub_id.to_i)
195 + rescue ActiveRecord::RecordNotFound
196 + puts "Record not found"
197 + submission = nil
198 + end
199 +
200 + if submission!=nil
201 + runner.grade_submission(submission)
202 + end
203 + end
204 +
182 205 else
183 206 display_manual
184 207 exit(0)
185 208 end
186 209
187 210 # report inactive
188 211 grader_proc.report_inactive if grader_proc!=nil
189 212
@@ -1,56 +1,61
1 1 #
2 2 # A runner drives the engine into various tasks.
3 3 #
4 4
5 5 module Grader
6 6
7 7 class Runner
8 8
9 9 def initialize(engine, grader_process=nil)
10 10 @engine = engine
11 11 @grader_process = grader_process
12 12 end
13 13
14 14 def grade_oldest_task
15 15 task = Task.get_inqueue_and_change_status(Task::STATUS_GRADING)
16 16 if task!=nil
17 17 @grader_process.report_active(task) if @grader_process!=nil
18 18
19 19 submission = Submission.find(task.submission_id)
20 20 @engine.grade(submission)
21 21 task.status_complete!
22 22 @grader_process.report_inactive(task) if @grader_process!=nil
23 23 end
24 24 return task
25 25 end
26 26
27 27 def grade_problem(problem)
28 28 users = User.find(:all)
29 29 users.each do |u|
30 30 puts "user: #{u.login}"
31 31 last_sub = Submission.find(:first,
32 32 :conditions => "user_id = #{u.id} and " +
33 33 "problem_id = #{problem.id}",
34 34 :order => 'submitted_at DESC')
35 35 if last_sub!=nil
36 36 @engine.grade(last_sub)
37 37 end
38 38 end
39 39 end
40 40
41 + def grade_submission(submission)
42 + puts "Submission: #{submission.id} by #{submission.user.full_name}"
43 + @engine.grade(submission)
44 + end
45 +
41 46 def grade_oldest_test_request
42 47 test_request = TestRequest.get_inqueue_and_change_status(Task::STATUS_GRADING)
43 48 if test_request!=nil
44 49 @grader_process.report_active(test_request) if @grader_process!=nil
45 50
46 51 @engine.grade(test_request)
47 52 test_request.status_complete!
48 53 @grader_process.report_inactive(test_request) if @grader_process!=nil
49 54 end
50 55 return test_request
51 56 end
52 57
53 58 end
54 59
55 60 end
56 61
@@ -10,123 +10,129
10 10 fp.puts("judge: #{Time.new.strftime("%H:%M")} #{str}")
11 11 fp.close
12 12 end
13 13 end
14 14
15 15 problem_home = ENV['PROBLEM_HOME']
16 16
17 17 def execute(command, error_message="")
18 18 if not system(command)
19 19 msg = "ERROR: #{error_message}"
20 20 log msg
21 21 raise msg
22 22 end
23 23 end
24 24
25 25 # ARGV[0] --- language
26 26 # ARGV[1] --- program source file
27 27 # ARGV[2] --- test result directory
28 28 # ARGV[3] --- sandbox directory
29 29
30 30 if ARGV.length < 2 || ARGV.length > 4
31 31 puts "Usage: judge <language> <program-source> [<test-result-directory>] [<sandbox-directory>]"
32 32 puts " <sandbox-directory> is defaulted to ./sandbox"
33 33 puts " <test-result-directory> is defaulted to ./test-result"
34 34 puts "WARNING: The judge script will forcefully create the (implicitly and explicitly) specified directories and remove anything inside it."
35 35 exit(127)
36 36 end
37 37
38 38 language = ARGV[0]
39 39 if language != "c" && language != "c++" && language != "pas"
40 40 log "You specified a language that is not supported: #{language}."
41 41 exit(127)
42 42 end
43 43
44 44 source_file = ARGV[1]
45 45 if File.exist?(source_file) == false
46 46 log "The source file does not exist."
47 47 exit(127)
48 48 end
49 49
50 50 log "Making test result and sandbox directories..."
51 51
52 52 current_dir = `pwd`
53 53 current_dir.strip!
54 54
55 55 if ARGV.length >= 3
56 56 test_result_dir = ARGV[2]
57 57 else
58 58 test_result_dir = "#{current_dir}/test-result"
59 59 end
60 60 log "Test result directory: #{test_result_dir}"
61 61 system("rm -Rf #{test_result_dir}")
62 62 execute("mkdir #{test_result_dir}", "Cannot make directory #{test_result_dir}.")
63 63
64 64 if ARGV.length >= 4
65 65 sandbox_dir = ARGV[3]
66 66 else
67 67 sandbox_dir = "#{current_dir}/sandbox"
68 68 end
69 69 log "Sandbox directory: #{sandbox_dir}"
70 70 system("rm -Rf #{sandbox_dir}")
71 71 execute("mkdir #{sandbox_dir}", "Cannot make directory #{sandbox_dir}")
72 72
73 73 # Compile
74 74 log
75 75 log "Compiling..."
76 76 execute("cp #{source_file} #{sandbox_dir}", "Cannot copy the source file to #{sandbox_dir}")
77 77 begin
78 78 Dir.chdir sandbox_dir
79 79 rescue
80 80 log "ERROR: Cannot change directory to #{sandbox_dir}."
81 81 exit(127)
82 82 end
83 83 execute("#{problem_home}/script/compile #{language} #{source_file}", "Compilation error!")
84 84 compile_message = `cat compiler_message`
85 85 compile_message.strip!
86 86 execute("mv compiler_message #{test_result_dir}", "Cannot move the compiler message to #{test_result_dir}.")
87 87 if !FileTest.exist?("a.out")
88 88 log "Cannot compile the source code. See message in #{test_result_dir}/compile_message"
89 89 exit(127)
90 90 else
91 91 execute("mv a.out #{test_result_dir}", "Cannot move the compiled program to #{test_result_dir}")
92 92 system("rm -Rf #{sandbox_dir}/*")
93 93 end
94 94
95 95 require "#{problem_home}/script/test_dsl.rb"
96 96 load "#{problem_home}/test_cases/all_tests.cfg"
97 97 problem = Problem.get_instance
98 98
99 99 if problem.well_formed? == false
100 100 log "The problem specification is not well formed."
101 101 exit(127)
102 102 end
103 103
104 104 # Doing the testing.
105 105 (1..(problem.num_tests)).each do |test_num|
106 +
107 + $stdout.print "[#{test_num}]"
108 + $stdout.flush
109 +
106 110 log "Test number: #{test_num}"
107 111 execute("cp #{test_result_dir}/a.out #{sandbox_dir}", "Cannot copy the compiled program into #{sandbox_dir}")
108 112 begin
109 113 execute("#{problem_home}/script/run #{language} #{test_num}", "Error occured during execution of the run script")
110 114 rescue
111 115 # do nothing
112 116 end
113 117 execute("mkdir #{test_result_dir}/#{test_num}", "Cannot create directory #{test_result_dir}/#{test_num}")
114 118 execute("mv #{sandbox_dir}/result #{test_result_dir}/#{test_num}", "Cannot copy the result file into #{test_result_dir}/#{test_num}")
115 119 execute("mv #{sandbox_dir}/comment #{test_result_dir}/#{test_num}", "Cannot copy the comment file into #{test_result_dir}/#{test_num}")
116 120 execute("mv #{sandbox_dir}/output.txt #{test_result_dir}/#{test_num}", "Cannot copy the output file into #{test_result_dir}/#{test_num}")
117 121 execute("rm -Rf #{sandbox_dir}/*", "Cannot clear #{sandbox_dir}")
118 122 end
119 123
124 + $stdout.print "[done]\n"
125 +
120 126 # Grade
121 127 log
122 128 log "Grading..."
123 129 begin
124 130 Dir.chdir test_result_dir
125 131 rescue
126 132 log "ERROR: Cannot change directory to #{test_result_dir}."
127 133 exit(127)
128 134 end
129 135 execute("#{problem_home}/script/grade", "An error occured during grading!")
130 136
131 137 log
132 138 log "All done!"
You need to be logged in to leave comments. Login now