Description:
add dump submission & octave
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r261:4eedd9c42b48 - - 4 files changed: 62 inserted, 1 deleted

@@ -0,0 +1,45
1 + #!/usr/bin/env ruby
2 +
3 + require 'fileutils'
4 +
5 + ENVIRONMENT_DIRS = ['ev', 'ev-exam']
6 +
7 + def config
8 + Grader::Configuration.get_instance
9 + end
10 +
11 + def usage
12 + puts <<USAGE
13 + Usage:
14 + dump_submission prob_id1 prob_id2 prob_id3 ...
15 +
16 + This will dumps all submission of the given problem ids into <current_dir>/<problem_name>/<user login>/<submission_id>
17 + USAGE
18 + end
19 +
20 + if (ARGV.length == 0)
21 + usage
22 + exit(0)
23 + end
24 +
25 + # load grader environment
26 + GRADER_ENV = 'grading'
27 + require File.join(File.dirname(__FILE__),'config/environment')
28 +
29 + # boot rails, to be able to rename the problem
30 + RAILS_ENV = config.rails_env
31 + require RAILS_ROOT + '/config/environment'
32 +
33 + prob_ids = ARGV.map{ |x| x.to_i}
34 +
35 +
36 + prob_ids.each do |id|
37 + p = Problem.find(id)
38 + p.submissions.each do |s|
39 + dir = "#{p.name}/#{s.user.login}/#{s.id}.#{s.language.ext}"
40 + filename = "#{s.id}.#{s.language.ext}"
41 + FileUtils.mkdir_p dir
42 + File.write("#{dir}/#{filename}",s.source)
43 + puts filename
44 + end
45 + end
@@ -1,82 +1,83
1 1 #!/usr/bin/env ruby
2 2
3 3 require 'fileutils'
4 4
5 5 ##############################
6 6 #
7 7 # Standard Compile Script
8 8 #
9 9 # Supported compilers:
10 10 # gcc, g++, and fpc.
11 11 #
12 12 ##############################
13 13
14 14 def talk(str='')
15 15 if ENV['TALKATIVE']!=nil
16 16 puts str
17 17 end
18 18 if ENV['GRADER_LOGGING']!=nil
19 19 log_fname = ENV['GRADER_LOGGING']
20 20 fp = File.open(log_fname,"a")
21 21 fp.puts("run: #{Time.new.strftime("%H:%M")} #{str}")
22 22 fp.close
23 23 end
24 24 end
25 25
26 26 C_COMPILER = "/usr/bin/gcc"
27 27 CPLUSPLUS_COMPILER = "/usr/bin/g++"
28 28 PASCAL_COMPILER = "/usr/bin/fpc"
29 29 JAVA_COMPILER = "/usr/bin/javac"
30 30 RUBY_INTERPRETER = "/usr/bin/ruby"
31 31 PYTHON_INTERPRETER = "/usr/bin/python3"
32 32 PYTHON_CHECKER = "/usr/bin/pyflakes"
33 33 PHP_INTERPRETER = "/usr/bin/php"
34 34 HASKELL_COMPILER = "/usr/bin/ghc"
35 + OCTAVE_INTERPRETER = "/usr/bin/octave"
35 36
36 37 C_OPTIONS = "-O2 -s -static -std=c99 -DCONTEST -lm -Wall"
37 38 CPLUSPLUS_OPTIONS = "-O2 -s -std=c++11 -static -DCONTEST -lm -Wall"
38 39 PASCAL_OPTIONS = "-O1 -XS -dCONTEST"
39 40 JAVA_OPTIONS = ""
40 41 PYTHON_OPTIONS = ""
41 42 PHP_OPTIONS = "-l"
42 43 HASKELL_OPTIONS = ""
43 44
44 45 # Check for the correct number of arguments. Otherwise, print usage.
45 46 if ARGV.length == 0 or ARGV.length > 4
46 47 puts "Usage: compile <language> [<source-file>] [<output-file>] [<message-file>]"
47 48 puts
48 49 puts "<source-file> is defaulted to \"source\"."
49 50 puts "<output-file> is defaulted to \"a.out\"."
50 51 puts "<message-file> is defaulted to \"compiler_message\"."
51 52 puts
52 53 exit(127)
53 54 end
54 55
55 56 PARAMS = {
56 57 :source_file => [1,'source'],
57 58 :output_file => [2,'a.out'],
58 59 :message_file => [3,'compiler_message']
59 60 }
60 61
61 62 params = {}
62 63 params[:prog_lang] = ARGV[0]
63 64 PARAMS.each_key do |param_name|
64 65 index, default = PARAMS[param_name]
65 66 if ARGV.length > index
66 67 params[param_name] = ARGV[index]
67 68 else
68 69 params[param_name] = default
69 70 end
70 71 talk "COMPILE: param: #{param_name}: #{params[param_name]}"
71 72 end
72 73 talk "COMPILE: working dir = " + Dir.pwd
73 74
74 75 # Remove any remaining output files or message files.
75 76 if FileTest.exists? params[:output_file]
76 77 FileUtils.rm(params[:output_file])
77 78 end
78 79 if FileTest.exists? params[:message_file]
79 80 FileUtils.rm(params[:message_file])
80 81 end
81 82
82 83 # Check if the source file exists before attempt compiling.
@@ -141,62 +142,74
141 142 end
142 143
143 144 when "ruby"
144 145 command = "#{RUBY_INTERPRETER} -c #{params[:source_file]}"
145 146 talk "COMPILE: compiling command [#{command}]"
146 147 if system(command, err: params[:message_file])
147 148 File.open(params[:output_file],"w") do |out_file|
148 149 out_file.puts "#!#{RUBY_INTERPRETER}"
149 150 File.open(params[:source_file],"r").each do |line|
150 151 out_file.print line
151 152 end
152 153 end
153 154 File.chmod(0755, params[:output_file])
154 155 end
155 156
156 157 when "python"
157 158 #command = "#{PYTHON_CHECKER} #{params[:source_file]}"
158 159 #if system(command, out: params[:message_file])
159 160 #compile to python bytecode
160 161 command = "#{PYTHON_INTERPRETER} -c \"import py_compile; py_compile.compile('#{params[:source_file]}','#{params[:source_file]}c');\""
161 162 talk "COMPILE: compiling command [#{command}]"
162 163 system(command, err: params[:message_file])
163 164 if FileTest.exists?("#{params[:source_file]}c")
164 165 File.open(params[:output_file],"w") do |out_file|
165 166 out_file.puts "#!#{PYTHON_INTERPRETER} #{params[:source_file]}c"
166 167 end
167 168 File.chmod(0755, params[:output_file])
168 169 FileUtils.cp("#{params[:source_file]}c",params[:output_file])
169 170 end
170 171 #end
171 172
172 173 when "php"
173 174 command = "#{PHP_INTERPRETER} #{PHP_OPTIONS} #{params[:source_file]}"
174 175 if system(command, err: params[:message_file])
175 176 File.open(params[:output_file],"w") do |out_file|
176 177 out_file.puts "#!#{PHP_INTERPRETER}"
177 178 File.open(params[:source_file],"r").each do |line|
178 179 out_file.print line
179 180 end
180 181 end
181 182 File.chmod(0755, params[:output_file])
182 183 end
183 184
184 185 when "haskell"
185 186 command = "#{HASKELL_COMPILER} #{params[:source_file]} -o #{params[:output_file]} #{HASKELL_OPTIONS}"
186 187 talk "COMPILE: compiling command [#{command}]"
187 188 system(command, err: params[:message_file])
188 189
190 + when "octave"
191 + command = "touch"
192 + talk "COMPILE: compiling command [#{command}], log err to #{params[:message_file]}"
193 + system(command, err: params[:message_file])
194 + File.open(params[:output_file],"w") do |out_file|
195 + out_file.puts "#!#{OCTAVE_INTERPRETER}"
196 + File.open(params[:source_file],"r").each do |line|
197 + out_file.print line
198 + end
199 + end
200 + File.chmod(0755, params[:output_file])
201 +
189 202 else
190 203 talk("COMPILE: ERROR: Invalid language specified!")
191 204 open(params[:message_file],"w") do |f|
192 205 f.puts "ERROR: Invalid language specified!"
193 206 end
194 207 exit(127)
195 208 end
196 209
197 210 # Report success or failure.
198 211 if FileTest.exists? params[:output_file]
199 212 talk "COMPILE: Compilation was successful!"
200 213 else
201 214 talk "COMPILE: ERROR: Something was wrong during the compilation!"
202 215 end
@@ -8,97 +8,97
8 8 end
9 9 if ENV['GRADER_LOGGING']!=nil
10 10 log_fname = ENV['GRADER_LOGGING']
11 11 fp = File.open(log_fname,"a")
12 12 fp.puts("judge: #{Time.new.strftime("%H:%M")} #{str}")
13 13 fp.close
14 14 end
15 15 end
16 16
17 17 problem_home = ENV['PROBLEM_HOME']
18 18
19 19 def execute(command, error_message="")
20 20 if not system(command)
21 21 msg = "ERROR: #{error_message}"
22 22 log msg
23 23 raise(msg)
24 24 end
25 25 end
26 26
27 27 def call_and_log(error_message)
28 28 begin
29 29 yield
30 30 rescue
31 31 msg = "JUDGE: ERROR: #{error_message}"
32 32 log msg
33 33 raise msg
34 34 end
35 35 end
36 36
37 37 def clear_and_create_empty_dir(dir)
38 38 FileUtils.rm_rf(dir, :secure => true)
39 39 call_and_log("Cannot make directory #{dir}.") { FileUtils.mkdir(dir) }
40 40 end
41 41
42 42 # ARGV[0] --- language
43 43 # ARGV[1] --- program source file
44 44 # ARGV[2] --- test result directory
45 45 # ARGV[3] --- sandbox directory
46 46
47 47 if ARGV.length < 2 || ARGV.length > 4
48 48 puts "Usage: judge <language> <program-source> [<test-result-directory>] [<sandbox-directory>]"
49 49 puts " <sandbox-directory> is defaulted to ./sandbox"
50 50 puts " <test-result-directory> is defaulted to ./test-result"
51 51 puts "WARNING: The judge script will forcefully create the (implicitly and explicitly) specified directories and remove anything inside it."
52 52 exit(127)
53 53 end
54 54
55 55 language = ARGV[0]
56 - if language != "c" && language != "c++" && language != "pas" && language != "java" && language != "ruby" && language != "python" && language != "php" && language != "haskell"
56 + if language != "c" && language != "c++" && language != "pas" && language != "java" && language != "ruby" && language != "python" && language != "php" && language != "haskell" && language != "octave"
57 57 log "JUDGE: You specified a language that is not supported: #{language}."
58 58 exit(127)
59 59 end
60 60
61 61 source_file = ARGV[1]
62 62 ENV['SOURCE_NAME'] = source_file
63 63 if File.exist?(source_file) == false
64 64 log "JUDGE: The source file does not exist."
65 65 exit(127)
66 66 end
67 67
68 68 log "JUDGE: Making test result and sandbox directories..."
69 69
70 70 current_dir = FileUtils.pwd
71 71 current_dir.strip!
72 72
73 73 if ARGV.length >= 3
74 74 test_result_dir = ARGV[2]
75 75 else
76 76 test_result_dir = "#{current_dir}/test-result"
77 77 end
78 78
79 79 log "JUDGE: Test result directory: #{test_result_dir}"
80 80 clear_and_create_empty_dir(test_result_dir)
81 81
82 82 if ARGV.length >= 4
83 83 sandbox_dir = ARGV[3]
84 84 else
85 85 sandbox_dir = "#{current_dir}/sandbox"
86 86 end
87 87 log "JUDGE: Sandbox directory: #{sandbox_dir}"
88 88 clear_and_create_empty_dir(sandbox_dir)
89 89
90 90 # ------------------------------
91 91 # Compile
92 92 # ------------------------------
93 93 log "JUDGE: Compiling..."
94 94 log
95 95 call_and_log("Cannot copy the source file to #{sandbox_dir}") {
96 96 FileUtils.cp(source_file, sandbox_dir)
97 97 }
98 98 begin
99 99 Dir.chdir sandbox_dir
100 100 rescue
101 101 log "JUDGE: ERROR: Cannot change directory to #{sandbox_dir}."
102 102 exit(127)
103 103 end
104 104 execute("#{problem_home}/script/compile #{language} #{source_file}", "Compilation error!")
@@ -67,117 +67,120
67 67 load "#{problem_home}/test_cases/all_tests.cfg"
68 68 problem = Problem.get_instance
69 69
70 70 sandbox_dir = Dir.getwd
71 71
72 72 if problem.well_formed? == false
73 73 log "RUN: ERROR: The problem specification is not well formed."
74 74 exit(127)
75 75 end
76 76
77 77 # Check if the test number is okay.
78 78 if test_num <= 0 || test_num > problem.num_tests
79 79 log "RUN: ERROR: You have specified a wrong test number."
80 80 exit(127)
81 81 end
82 82
83 83 #####################################
84 84 # Set the relavant file names here. #
85 85 #####################################
86 86
87 87 input_file_name = "#{problem_home}/test_cases/#{test_num}/input-#{test_num}.txt"
88 88
89 89 #####################################
90 90
91 91 time_limit = problem.get_time_limit test_num
92 92 mem_limit = problem.get_mem_limit(test_num) * 1024
93 93
94 94 # Copy the input file.
95 95 #`cp #{problem_home}/test_cases/#{test_num}/#{input_file_name} .`
96 96
97 97 # check if box is there, if not, compile it!
98 98 if !File.exists?("#{problem_home}/script/box")
99 99 log "WARNING: Compiling box: to increase efficiency, it should be compile manually"
100 100 compile_box("#{problem_home}/script/box.cc",
101 101 "#{problem_home}/script/box")
102 102 end
103 103
104 104 # Hide PROBLEM_HOME
105 105 ENV['PROBLEM_HOME'] = nil
106 106 ENV['SOURCE_NAME'] = nil
107 107
108 108 # Run the program.
109 109 #run_command = "/usr/bin/time -f \"#{time_output_format}\" 2>run_result #{problem_home}/script/box_new -a 2 -f -t #{time_limit} -m #{mem_limit} -i #{input_file_name} -o output.txt #{program_name}"
110 110 #
111 111
112 112 JAVA_OPTION = "-s set_robust_list -s futex -s clone -s getppid -s clone -s wait4 -p /usr/bin/ -p ./"
113 113 RUBY_OPTION = "-p /usr/lib64/ -p /usr/local/lib64/ -p /usr/local/lib/ -p /lib64/ -p /dev/urandom -p #{sandbox_dir}/#{program_name} -p #{sandbox_dir}/ -s set_robust_list -s sched_getaffinity -s clock_gettime -s sigaltstack -s pipe2 -s clone -s futex -s openat -s pipe -s getrandom"
114 114 PYTHON_OPTION = "-p /usr/lib64/ -p /usr/local/lib64/ -p /usr/local/lib/ -p /usr/bin/ -p /lib64/ -p /dev/urandom -p /usr/ -p #{sandbox_dir}/#{program_name} -p ./#{program_name} -p #{sandbox_dir}/#{source_name} -p /proc/sys/crypto/fips_enabled -p /proc/self/status -p /proc/mounts -p /var/lib/dpkg/status -s statfs -s set_robust_list -s openat -s sysinfo -s recvmsg -s connect -s socket -s sendto -s futex -s sigaltstack -s getrandom -E PYTHONNOUSERSITE=yes"
115 + OCTAVE_OPTION = "-p /usr/lib64/ -p /usr/local/lib64/ -p /usr/local/lib/ -p /usr/bin/ -p /lib64/ -p /dev/urandom -p /usr/ -p #{sandbox_dir}/#{program_name} -p ./#{program_name} -p #{sandbox_dir}/#{source_name} -p /proc/sys/crypto/fips_enabled -p /proc/self/status -p /proc/mounts -p /var/lib/dpkg/status -s statfs -s set_robust_list -s openat -s sysinfo -s recvmsg -s connect -s socket -s sendto -s futex -s sigaltstack -s getrandom -s prlimit64 -s execve -E PYTHONNOUSERSITE=yes"
115 116 PHP_OPTION = "-p /usr/lib64/ -p/lib64/ -p /usr/bin/ -p #{sandbox_dir}/#{program_name} -p ./#{program_name} -p /usr/share/ -s setfsuid -s setfsgid -s openat -s set_robust_list -s futex -s clone -s socket -s connect"
116 117 HASKELL_OPTION = "-s set_robust_list -s clock_gettime -s sysinfo -s timer_create -s timer_settime -s futex -s timer_delete"
117 118
118 119 case language
119 120 when "java"
120 121 # for java, extract the classname
121 122 # wne have to add additional systemcall and we don't check the mem limit (dunno how to fix...)
122 123 classname = 'DUMMY'
123 124 File.open(program_name,"r").each do |line|
124 125 classname = line
125 126 end
126 127 #for java, we cannot really check the memory limit...
127 128 run_command = "#{problem_home}/script/box -a 3 -f -T -t #{time_limit} #{JAVA_OPTION} -i #{input_file_name} -o output.txt /usr/bin/java -A -Xmx#{mem_limit}k -A #{classname} "
128 129 when "ruby"
129 130 run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit*=2} -m #{mem_limit} #{RUBY_OPTION} -i #{input_file_name} -o output.txt /usr/bin/ruby #{program_name} "
130 131 when "python"
131 132 run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit*=2} -m #{[512 * 1024,mem_limit].max} #{PYTHON_OPTION} -i #{input_file_name} -o output.txt /usr/bin/python3 #{program_name} "
132 133 when "haskell"
133 134 run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit} -m #{[512 * 1024,mem_limit].max} #{HASKELL_OPTION} -i #{input_file_name} -o output.txt #{program_name} "
134 135 when "php"
135 136 run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit*=2} -m #{[512 * 1024,mem_limit].max} #{PHP_OPTION} -i #{input_file_name} -o output.txt /usr/bin/php -A -d -A memory_limit=#{mem_limit}k -A #{program_name} "
137 + when "octave"
138 + run_command = "#{problem_home}/script/box -T -t #{time_limit*=2} -m #{[512 * 1024,mem_limit].max} #{OCTAVE_OPTION} -i #{input_file_name} -o output.txt /usr/bin/octave -A -W -A --no-gui #{program_name}"
136 139 else # for c++, pascal, we do the normal checking
137 140 run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit} -m #{mem_limit} -i #{input_file_name} -o output.txt #{program_name} "
138 141 end
139 142
140 143
141 144 log "RUN: Running test #{test_num}..."
142 145 log "RUN: Run command = [#{run_command}]"
143 146 log
144 147 system(run_command,err: 'run_result')
145 148
146 149 # Restore PROBLEM_HOME
147 150 ENV['PROBLEM_HOME'] = problem_home
148 151
149 152 # Create the result file.
150 153 result_file = File.new("result", "w")
151 154 comment_file = File.new("comment", "w")
152 155
153 156 # Check if the program actually produced any output.
154 157 run_result_file = File.new("run_result", "r")
155 158 run_result = run_result_file.readlines
156 159 run_result_file.close
157 160
158 161 run_stat = run_result[run_result.length-1]
159 162 running_time = extract_time(run_stat)
160 163
161 164 report = lambda{ |status, points, comment|
162 165 result_file.write status.strip
163 166 result_file.write "\n"
164 167 result_file.write points.to_s.strip
165 168 result_file.write "\n"
166 169 result_file.write run_stat.strip
167 170 result_file.write "\n"
168 171 result_file.close
169 172 FileUtils.rm "run_result"
170 173 # `rm output.txt` --- keep the output
171 174
172 175 comment_file.write comment
173 176
174 177 # added for debuggin --- jittat
175 178 comment_file.write "--run-result--\n"
176 179 run_result.each do |l|
177 180 comment_file.write l
178 181 end
179 182
180 183 comment_file.close
181 184
182 185 log "Done!"
183 186 exit(0)
You need to be logged in to leave comments. Login now