Description:
[grader] report error when the check script crashed (i.e., when the result file is not found, while the compilation is okay) git-svn-id: http://theory.cpe.ku.ac.th/grader/judge/trunk/scripts@117 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

r30:8c0d78da1958 - - 4 files changed: 23 inserted, 4 deleted

@@ -10,86 +10,102
10 10 problem = submission.problem
11 11 grading_room = "#{@config.user_result_dir}/" +
12 12 "#{user.login}/#{problem.name}/#{submission.id}"
13 13
14 14 FileUtils.mkdir_p(grading_room)
15 15 grading_room
16 16 end
17 17
18 18 def find_problem_home(submission)
19 19 problem = submission.problem
20 20 "#{@config.problems_dir}/#{problem.name}"
21 21 end
22 22
23 23 def save_source(submission,source_name)
24 24 dir = self.produce_grading_room(submission)
25 25 f = File.open("#{dir}/#{source_name}","w")
26 26 f.write(submission.source)
27 27 f.close
28 28 end
29 29
30 30 def clean_up(submission)
31 31 end
32 32 end
33 33
34 34 class SubmissionReporter
35 35 def initialize
36 36 @config = Grader::Configuration.get_instance
37 37 end
38 38
39 39 def report(sub,test_result_dir)
40 40 save_result(sub,read_result(test_result_dir))
41 41 end
42 42
43 43 def report_error(sub,msg)
44 44 save_result(sub,{:points => 0,
45 45 :comment => "Grading error: #{msg}" })
46 46 end
47 47
48 48 protected
49 49 def read_result(test_result_dir)
50 50 cmp_msg_fname = "#{test_result_dir}/compiler_message"
51 51 cmp_file = File.open(cmp_msg_fname)
52 52 cmp_msg = cmp_file.read
53 53 cmp_file.close
54 54
55 55 result_fname = "#{test_result_dir}/result"
56 56 comment_fname = "#{test_result_dir}/comment"
57 57 if FileTest.exist?(result_fname)
58 + comment = ""
59 + begin
58 60 result_file = File.open(result_fname)
59 61 result = result_file.readline.to_i
60 62 result_file.close
63 + rescue
64 + result = 0
65 + comment = "error reading result file."
66 + end
61 67
68 + begin
62 69 comment_file = File.open(comment_fname)
63 - comment = comment_file.readline.chomp
70 + comment += comment_file.readline.chomp
64 71 comment_file.close
72 + rescue
73 + comment += ""
74 + end
65 75
66 76 return {:points => result,
67 77 :comment => comment,
68 78 :cmp_msg => cmp_msg}
69 79 else
80 + if FileTest.exist?("#{test_result_dir}/a.out")
81 + return {:points => 0,
82 + :comment => 'error during grading',
83 + :cmp_msg => cmp_msg}
84 + else
70 85 return {:points => 0,
71 86 :comment => 'compile error',
72 87 :cmp_msg => cmp_msg}
73 88 end
74 89 end
90 + end
75 91
76 92 def save_result(submission,result)
77 93 problem = submission.problem
78 94 submission.graded_at = Time.now
79 95 points = result[:points]
80 96 submission.points = points
81 97 comment = @config.report_comment(result[:comment])
82 98 if problem == nil
83 99 submission.grader_comment = 'PASSED: ' + comment + '(problem is nil)'
84 100 elsif points == problem.full_score
85 101 submission.grader_comment = 'PASSED: ' + comment
86 102 else
87 103 submission.grader_comment = 'FAILED: ' + comment
88 104 end
89 105 submission.compiler_message = result[:cmp_msg] or ''
90 106 submission.save
91 107 end
92 108
93 109 end
94 110
95 111 end
@@ -1,80 +1,81
1 1 #!/usr/bin/ruby
2 2
3 3 def log(str='')
4 4 if ENV['TALKATIVE']!=nil
5 5 puts str
6 6 end
7 7 if ENV['GRADER_LOGGING']!=nil
8 8 log_fname = ENV['GRADER_LOGGING']
9 9 fp = File.open(log_fname,"a")
10 10 fp.puts("grade: #{Time.new.strftime("%H:%M")} #{str}")
11 11 fp.close
12 12 end
13 13 end
14 14
15 15 def char_comment(comment)
16 16 if comment =~ /[iI]ncorrect/
17 17 '-'
18 18 elsif comment =~ /[Cc]orrect/
19 19 'P'
20 20 elsif comment =~ /[Tt]ime/
21 21 'T'
22 22 else
23 23 'x' # these are run time errors
24 24 end
25 25 end
26 26
27 27 problem_home = ENV['PROBLEM_HOME']
28 28 require "#{problem_home}/script/test_dsl.rb"
29 29 load "#{problem_home}/test_cases/all_tests.cfg"
30 30 problem = Problem.get_instance
31 31
32 32 if problem.well_formed? == false
33 33 log "The problem specification is not well formed."
34 34 exit(127)
35 35 end
36 36
37 37 all_score = 0
38 38 all_comment = ''
39 39 (1..(problem.runs.length-1)).each do |k|
40 40 log "grade run #{k}"
41 41 run = problem.runs[k]
42 42 run_score = 0
43 43 run_comment = ''
44 44 run_comment_short = ''
45 45 run.tests.each do |test_num|
46 46 result_file_name = "#{test_num}/result"
47 47 if not File.exists?(result_file_name)
48 + run_comment += "result file for test #{test_num} not found\n"
49 + run_comment_short += 'x'
48 50 log "Cannot find the file #{test_num}/result!"
49 - exit(127)
50 - end
51 -
51 + else
52 52 result_file = File.new(result_file_name, "r")
53 53 result_file_lines = result_file.readlines
54 54 run_score = run_score + result_file_lines[1].to_i
55 55 run_comment += result_file_lines[0]
56 56 run_comment_short += char_comment(result_file_lines[0])
57 57 result_file.close
58 58 end
59 + end
59 60
60 61 run_result_file = File.new("result-#{k}", "w")
61 62 run_result_file.write run_score
62 63 run_result_file.write "\n"
63 64 run_result_file.close
64 65
65 66 run_comment_file = File.new("comment-#{k}", "w")
66 67 run_comment_file.write "#{run_comment}\n"
67 68 run_comment_file.close
68 69
69 70 all_score = all_score + run_score
70 71 all_comment += run_comment_short
71 72 end
72 73
73 74 result_file = File.new("result", "w")
74 75 result_file.write all_score
75 76 result_file.write "\n"
76 77 result_file.close
77 78
78 79 comment_file = File.new("comment", "w")
79 80 comment_file.write "#{all_comment}\n"
80 81 comment_file.close
@@ -1,66 +1,67
1 1 #!/usr/bin/ruby
2 2
3 3 def log(str='')
4 4 if ENV['TALKATIVE']!=nil
5 5 puts str
6 6 end
7 7 if ENV['GRADER_LOGGING']!=nil
8 8 log_fname = ENV['GRADER_LOGGING']
9 9 fp = File.open(log_fname,"a")
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 + log "ERROR: #{error_message}"
19 20 puts "ERROR: #{error_message}"
20 21 exit(127)
21 22 end
22 23 end
23 24
24 25 # ARGV[0] --- language
25 26 # ARGV[1] --- program source file
26 27 # ARGV[2] --- test result directory
27 28 # ARGV[3] --- sandbox directory
28 29
29 30 if ARGV.length < 2 || ARGV.length > 4
30 31 puts "Usage: judge <language> <program-source> [<test-result-directory>] [<sandbox-directory>]"
31 32 puts " <sandbox-directory> is defaulted to ./sandbox"
32 33 puts " <test-result-directory> is defaulted to ./test-result"
33 34 puts "WARNING: The judge script will forcefully create the (implicitly and explicitly) specified directories and remove anything inside it."
34 35 exit(127)
35 36 end
36 37
37 38 language = ARGV[0]
38 39 if language != "c" && language != "c++" && language != "pascal"
39 40 log "You specified a language that is not supported."
40 41 exit(127)
41 42 end
42 43
43 44 source_file = ARGV[1]
44 45 if File.exist?(source_file) == false
45 46 log "The source file does not exist."
46 47 exit(127)
47 48 end
48 49
49 50 log "Making test result and sandbox directories..."
50 51
51 52 current_dir = `pwd`
52 53 current_dir.strip!
53 54
54 55 if ARGV.length >= 3
55 56 test_result_dir = ARGV[2]
56 57 else
57 58 test_result_dir = "#{current_dir}/test-result"
58 59 end
59 60 log "Test result directory: #{test_result_dir}"
60 61 system("rm -Rf #{test_result_dir}")
61 62 execute("mkdir #{test_result_dir}", "Cannot make directory #{test_result_dir}.")
62 63
63 64 if ARGV.length >= 4
64 65 sandbox_dir = ARGV[3]
65 66 else
66 67 sandbox_dir = "#{current_dir}/sandbox"
@@ -87,55 +87,56
87 87 result_file = File.new("result", "w")
88 88 comment_file = File.new("comment", "w")
89 89
90 90 # Check if the program actually produced any output.
91 91 run_result_file = File.new("run_result", "r")
92 92 run_result = run_result_file.readlines
93 93 run_result_file.close
94 94 time_elapsed = run_result[run_result.length-1]
95 95 running_time = extract_time(time_elapsed)
96 96
97 97 report = lambda{ |status, points, comment|
98 98 result_file.write status.strip
99 99 result_file.write "\n"
100 100 result_file.write points.to_s.strip
101 101 result_file.write "\n"
102 102 result_file.write time_elapsed.strip
103 103 result_file.write "\n"
104 104 result_file.close
105 105 `rm run_result`
106 106 # `rm output.txt` --- keep the output
107 107
108 108 comment_file.write comment
109 109 comment_file.write "--run-result--\n"
110 110 run_result.each do |l|
111 111 comment_file.write l
112 112 end
113 113 comment_file.close
114 114
115 115 log "Done!"
116 116 exit(0)
117 117 }
118 118
119 119 if run_result[0][0,2] != "OK"
120 120 log "There was a runtime error."
121 121 report.call(run_result[0], 0, "No comment.\n")
122 122 end
123 123
124 124 if running_time[:user].to_f + running_time[:sys].to_f > time_limit
125 125 log "Time limit exceeded."
126 126 report.call("Time limit exceeded", 0, "No comment.\n")
127 127 end
128 128
129 129 # Run 'check' to evaluate the output.
130 130 #puts "There was no runtime error. Proceed to checking the output."
131 131 check_command = "#{problem_home}/script/check #{language} #{test_num}"
132 132 log "Checking the output..."
133 133 log check_command
134 134 if not system(check_command)
135 + log "Problem with check script"
135 136 exit(127)
136 137 end
137 138
138 139 check_file = File.new("check_result", "r")
139 140 check_file_lines = check_file.readlines
140 141
141 142 report.call(check_file_lines[0], check_file_lines[1], "No comment.\n")
You need to be logged in to leave comments. Login now