Description:
[grader] test_request: fixed error when input file is not found, or input file remains in problem home git-svn-id: http://theory.cpe.ku.ac.th/grader/judge/trunk/scripts@171 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

r45:dafc790ec9b7 - - 1 file changed: 17 inserted, 2 deleted

@@ -1,215 +1,230
1 1 #
2 2 # This part contains various test_request helpers for interfacing
3 3 # with Grader::Engine. There are TestRequestRoomMaker and
4 4 # TestRequestReporter.
5 5
6 6 module Grader
7 7
8 8 #
9 9 # A TestRequestRoomMaker is a helper object for Engine
10 10 # - finds grading room: in user_result_dir/(user)/test_request/ ...
11 11 # - prepare problem configuration for grading --- basically it copy
12 12 # all config files, and copy user's input into the testcase
13 13 # directory. First, it finds the template from problem template
14 14 # directory; if it can't find a template, it'll use the template
15 15 # from default template.
16 16 class TestRequestRoomMaker
17 17 def initialize
18 18 @config = Grader::Configuration.get_instance
19 19 end
20 20
21 21 def produce_grading_room(test_request)
22 22 grading_room = grading_room_dir(test_request)
23 23 FileUtils.mkdir_p(grading_room)
24 24 grading_room
25 25 end
26 26
27 27 def find_problem_home(test_request)
28 28 problem_name = test_request.problem_name
29 29
30 30 template_dir = "#{@config.test_request_problem_templates_dir}/" + problem_name
31 31
32 32 raise "Test Request: error template not found" if !File.exists?(template_dir)
33 33
34 34 problem_home = problem_home_dir(test_request)
35 35 FileUtils.mkdir_p(problem_home)
36 36
37 37 copy_problem_template(template_dir,problem_home)
38 38 link_input_file(test_request,problem_home)
39 39
40 40 problem_home
41 41 end
42 42
43 43 def save_source(test_request,source_name)
44 44 dir = self.produce_grading_room(test_request)
45 45 submission = test_request.submission
46 46 f = File.open("#{dir}/#{source_name}","w")
47 47 f.write(submission.source)
48 48 f.close
49 49 end
50 50
51 51 def clean_up(test_request)
52 52 problem_home = problem_home_dir(test_request)
53 53 remove_data_files(problem_home)
54 54 end
55 55
56 56 protected
57 57 def grading_room_dir(test_request)
58 58 problem_name = test_request.problem_name
59 59 user = test_request.user
60 60 "#{@config.user_result_dir}" +
61 61 "/#{user.login}/test_request" +
62 62 "/#{problem_name}/#{test_request.id}"
63 63 end
64 64
65 65 def problem_home_dir(test_request)
66 66 problem_name = test_request.problem_name
67 67 user = test_request.user
68 68 "#{@config.user_result_dir}" +
69 69 "/#{user.login}/test_request/#{problem_name}"
70 70 end
71 71
72 72 def copy_problem_template(template_dir,problem_home)
73 73 cmd = "cp -R #{template_dir}/* #{problem_home}"
74 74 system_and_raise_when_fail(cmd,"Test Request: cannot copy problem template")
75 75 end
76 76
77 77 def link_input_file(test_request,problem_home)
78 - cmd = "ln -s #{test_request.input_file_name} #{problem_home}/test_cases/1/input-1.txt"
78 + input_fname = "#{test_request.input_file_name}"
79 + if !File.exists?(input_fname)
80 + raise "Test Request: input file not found."
81 + end
82 +
83 + input_fname_problem_home = "#{problem_home}/test_cases/1/input-1.txt"
84 + if File.exists?(input_fname_problem_home)
85 + FileUtils.rm([input_fname_problem_home], :force => true)
86 + end
87 +
88 + cmd = "ln -s #{input_fname} #{input_fname_problem_home}"
79 89 system_and_raise_when_fail(cmd,"Test Request: cannot link input file")
80 90 end
81 91
82 92 def remove_data_files(problem_home)
83 93 if File.exists?("#{problem_home}/test_cases/1/input-1.txt")
84 94 cmd = "rm #{problem_home}/test_cases/1/*"
85 95 system_and_raise_when_fail(cmd,"Test Request: cannot remove data files")
86 96 end
87 97 end
88 98
89 99 def system_and_raise_when_fail(cmd,msg)
90 100 if !system(cmd)
91 101 raise msg
92 102 end
93 103 end
94 104
95 105 end
96 106
97 107 class TestRequestReporter
98 108 def initialize
99 109 @config = Grader::Configuration.get_instance
100 110 end
101 111
102 112 def report(test_request,test_result_dir)
103 113 save_result(test_request,read_result(test_result_dir))
104 114 end
105 115
106 116 def report_error(test_request, msg)
107 - save_result(test_request, {:running_stat => {:msg => "#{msg}"}})
117 + save_result(test_request, {:running_stat => {
118 + :msg => "#{msg}",
119 + :running_time => nil,
120 + :exit_status => "Some error occured. Program did not run",
121 + :memory_usage => nil
122 + }})
108 123 end
109 124
110 125 protected
111 126 def read_result(test_result_dir)
112 127 # TODO:
113 128 cmp_msg_fname = "#{test_result_dir}/compiler_message"
114 129 cmp_file = File.open(cmp_msg_fname)
115 130 cmp_msg = cmp_file.read
116 131 cmp_file.close
117 132
118 133 result_file_name = "#{test_result_dir}/1/result"
119 134
120 135 if File.exists?(result_file_name)
121 136 output_file_name = "#{test_result_dir}/1/output.txt"
122 137 results = File.open("#{test_result_dir}/1/result").readlines
123 138 stat = extract_running_stat(results)
124 139
125 140 return {
126 141 :output_file_name => output_file_name,
127 142 :running_stat => stat,
128 143 :comment => "",
129 144 :cmp_msg => cmp_msg}
130 145 else
131 146 return {
132 147 :running_stat => nil,
133 148 :comment => "Compilation error",
134 149 :cmp_msg => cmp_msg}
135 150 end
136 151 end
137 152
138 153 def extract_running_stat(results)
139 154 running_stat_line = results[-1]
140 155
141 156 # extract exit status line
142 157 run_stat = ""
143 158 if !(/[Cc]orrect/.match(results[0]))
144 159 run_stat = results[0].chomp
145 160 else
146 161 run_stat = 'Program exited normally'
147 162 end
148 163
149 164 # extract running time
150 165 if res = /r(.*)u(.*)s/.match(running_stat_line)
151 166 seconds = (res[1].to_f + res[2].to_f)
152 167 time_stat = "Time used: #{seconds} sec."
153 168 else
154 169 seconds = nil
155 170 time_stat = "Time used: n/a sec."
156 171 end
157 172
158 173 # extract memory usage
159 174 if res = /s(.*)m/.match(running_stat_line)
160 175 memory_used = res[1].to_i
161 176 else
162 177 memory_used = -1
163 178 end
164 179
165 180 return {
166 181 :msg => "#{run_stat}\n#{time_stat}",
167 182 :running_time => seconds,
168 183 :exit_status => run_stat,
169 184 :memory_usage => memory_used
170 185 }
171 186 end
172 187
173 188 def save_result(test_request,result)
174 189 if result[:output_file_name]!=nil
175 190 test_request.output_file_name = link_output_file(test_request,
176 191 result[:output_file_name])
177 192 end
178 193 test_request.graded_at = Time.now
179 194 test_request.compiler_message = (result[:cmp_msg] or '')
180 195 test_request.grader_comment = (result[:comment] or '')
181 196 if result[:running_stat]!=nil
182 197 test_request.running_stat = (result[:running_stat][:msg] or '')
183 198 test_request.running_time = (result[:running_stat][:running_time] or nil)
184 199 test_request.exit_status = result[:running_stat][:exit_status]
185 200 test_request.memory_usage = result[:running_stat][:memory_usage]
186 201 else
187 202 test_request.running_stat = ''
188 203 end
189 204 test_request.save
190 205 end
191 206
192 207 protected
193 208 def link_output_file(test_request, fname)
194 209 target_file_name = random_output_file_name(test_request.user,
195 210 test_request.problem)
196 211 FileUtils.mkdir_p(File.dirname(target_file_name))
197 212 cmd = "ln -s #{fname} #{target_file_name}"
198 213 if !system(cmd)
199 214 raise "TestRequestReporter: cannot move output file"
200 215 end
201 216 return target_file_name
202 217 end
203 218
204 219 def random_output_file_name(user,problem)
205 220 problem_name = TestRequest.name_of(problem)
206 221 begin
207 222 tmpname = "#{@config.test_request_output_base_dir}" +
208 223 "/#{user.login}/#{problem_name}/#{rand(10000)}"
209 224 end while File.exists?(tmpname)
210 225 tmpname
211 226 end
212 227
213 228 end
214 229
215 230 end
You need to be logged in to leave comments. Login now