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