Description:
Merge pull request #1 from jittat/master update from jittat/master
Commit status:
[Not Reviewed]
References:
merge default
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r210:3ae633914385 - - 7 files changed: 14 inserted, 15 deleted

@@ -1,181 +1,180
1 #!/bin/sh
1 #!/bin/sh
2
2
3 echo "This script will install and configure Cafe grader."
3 echo "This script will install and configure Cafe grader."
4
4
5 - echo "This will install Ruby 1.9.2 under rvm"
5 + RUBY_VERSION=2.1.2
6 + echo "This will install Ruby $RUBY_VERSION under RVM"
6
7
7 echo "Installing required apts"
8 echo "Installing required apts"
8
9
9 sudo apt-get update
10 sudo apt-get update
10 sudo apt-get install mysql-server mysql-client \
11 sudo apt-get install mysql-server mysql-client \
11 g++ gcc apache2 libmysqlclient15-dev build-essential \
12 g++ gcc apache2 libmysqlclient15-dev build-essential \
12 git-core openssl libreadline6 libreadline6-dev \
13 git-core openssl libreadline6 libreadline6-dev \
13 zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev \
14 zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev \
14 sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev \
15 sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev \
15 ncurses-dev automake libtool bison subversion \
16 ncurses-dev automake libtool bison subversion \
16 pkg-config curl nodejs unzip pyflakes ruby default-jdk
17 pkg-config curl nodejs unzip pyflakes ruby default-jdk
17
18
18 echo "Installing RVM"
19 echo "Installing RVM"
19 curl -k -L https://get.rvm.io | bash -s stable
20 curl -k -L https://get.rvm.io | bash -s stable
20 source ~/.rvm/scripts/rvm
21 source ~/.rvm/scripts/rvm
21
22
22 - echo "Installing Ruby 2.1.2 in RVM"
23 + echo "Installing Ruby $RUBY_VERSION in RVM"
23
24
24 - rvm install 2.1.2
25 + rvm install $RUBY_VERSION
25 - rvm use 2.1.2
26 + rvm use $RUBY_VERSION
26
27
27 echo "Fetching Cafe Grader from Git repositories"
28 echo "Fetching Cafe Grader from Git repositories"
28
29
29 echo "Fetching web interface"
30 echo "Fetching web interface"
30
31
31 mkdir cafe_grader
32 mkdir cafe_grader
32 cd cafe_grader
33 cd cafe_grader
33 git clone -q git://github.com/jittat/cafe-grader-web.git web
34 git clone -q git://github.com/jittat/cafe-grader-web.git web
34
35
35 echo "Configuring rails app"
36 echo "Configuring rails app"
36
37
37 cp web/config/application.rb.SAMPLE web/config/application.rb
38 cp web/config/application.rb.SAMPLE web/config/application.rb
38 cp web/config/initializers/cafe_grader_config.rb.SAMPLE web/config/initializers/cafe_grader_config.rb
39 cp web/config/initializers/cafe_grader_config.rb.SAMPLE web/config/initializers/cafe_grader_config.rb
39
40
40 #replace UTC in application.rb with the system timezone
41 #replace UTC in application.rb with the system timezone
41 timezone='UTC'
42 timezone='UTC'
42 if [ -f '/etc/timezone' ]; then
43 if [ -f '/etc/timezone' ]; then
43 timezone=\"`cat /etc/timezone`\"
44 timezone=\"`cat /etc/timezone`\"
44 else
45 else
45 if [ -f '/etc/sysconfig/clock' ]; then
46 if [ -f '/etc/sysconfig/clock' ]; then
46 timezone=`grep -e '^TIMEZONE' /etc/sysconfig/clock | grep -o -e '\".*\"'`
47 timezone=`grep -e '^TIMEZONE' /etc/sysconfig/clock | grep -o -e '\".*\"'`
47 fi
48 fi
48 fi
49 fi
49 replace="s!'UTC'!$timezone!g"
50 replace="s!'UTC'!$timezone!g"
50 sed -i $replace web/config/application.rb
51 sed -i $replace web/config/application.rb
51
52
52 echo "At this point we will need MySQL user and database."
53 echo "At this point we will need MySQL user and database."
53 echo "Have you created MySQL user and database for Cafe grader? (Y/N) "
54 echo "Have you created MySQL user and database for Cafe grader? (Y/N) "
54 read ch
55 read ch
55
56
56 if [ "$ch" = "n" -o "$ch" = "N" ]
57 if [ "$ch" = "n" -o "$ch" = "N" ]
57 then
58 then
58 echo "Please open another terminal and create the user and database for Cafe grader."
59 echo "Please open another terminal and create the user and database for Cafe grader."
59 echo "Don't forget to grant access to that database for the user."
60 echo "Don't forget to grant access to that database for the user."
60 echo "Please have username, password, and database name ready before continue."
61 echo "Please have username, password, and database name ready before continue."
61 echo
62 echo
62 echo "The following are instructions:"
63 echo "The following are instructions:"
63 echo "1. Run mysql:"
64 echo "1. Run mysql:"
64 echo
65 echo
65 echo " mysql -u root -p"
66 echo " mysql -u root -p"
66 echo
67 echo
67 echo " if you have just installed mysql, the root password is the one that you have just entered"
68 echo " if you have just installed mysql, the root password is the one that you have just entered"
68 echo "2. Create a new database, a new user, and grant access to grader database:"
69 echo "2. Create a new database, a new user, and grant access to grader database:"
69 echo
70 echo
70 echo " create user 'USERNAME'@'localhost' identified by 'PASSWORD';"
71 echo " create user 'USERNAME'@'localhost' identified by 'PASSWORD';"
71 echo " create database \`DATABASENEME\`;"
72 echo " create database \`DATABASENEME\`;"
72 echo " grant all on \`DATABASENAME\`.* to 'USERNAME'@'localhost';"
73 echo " grant all on \`DATABASENAME\`.* to 'USERNAME'@'localhost';"
73 echo
74 echo
74 echo " Replace USERNAME, PASSWORD, and DATABASENAME accordingly."
75 echo " Replace USERNAME, PASSWORD, and DATABASENAME accordingly."
75 echo
76 echo
76 echo "Hit enter when ready..."
77 echo "Hit enter when ready..."
77 read dummy
78 read dummy
78 fi
79 fi
79
80
80 CAFE_PATH=`pwd`
81 CAFE_PATH=`pwd`
81
82
82 cd web
83 cd web
83
84
84 echo "Please provide grader database:"
85 echo "Please provide grader database:"
85 read database
86 read database
86
87
87 echo "Please provide grader username:"
88 echo "Please provide grader username:"
88 read username
89 read username
89
90
90 echo "Please provide $username password:"
91 echo "Please provide $username password:"
91 read password
92 read password
92
93
93 echo "development:" > config/database.yml
94 echo "development:" > config/database.yml
94 echo " adapter: mysql2" >> config/database.yml
95 echo " adapter: mysql2" >> config/database.yml
95 echo " encoding: utf8" >> config/database.yml
96 echo " encoding: utf8" >> config/database.yml
96 echo " reconnect: false" >> config/database.yml
97 echo " reconnect: false" >> config/database.yml
97 echo " database: $database" >> config/database.yml
98 echo " database: $database" >> config/database.yml
98 echo " pool: 5" >> config/database.yml
99 echo " pool: 5" >> config/database.yml
99 echo " username: $username" >> config/database.yml
100 echo " username: $username" >> config/database.yml
100 echo " password: $password" >> config/database.yml
101 echo " password: $password" >> config/database.yml
101 echo " host: localhost" >> config/database.yml
102 echo " host: localhost" >> config/database.yml
102 echo " socket: /var/run/mysqld/mysqld.sock" >> config/database.yml
103 echo " socket: /var/run/mysqld/mysqld.sock" >> config/database.yml
103 echo "" >> config/database.yml
104 echo "" >> config/database.yml
104 echo "production:" >> config/database.yml
105 echo "production:" >> config/database.yml
105 echo " adapter: mysql2" >> config/database.yml
106 echo " adapter: mysql2" >> config/database.yml
106 echo " encoding: utf8" >> config/database.yml
107 echo " encoding: utf8" >> config/database.yml
107 echo " reconnect: false" >> config/database.yml
108 echo " reconnect: false" >> config/database.yml
108 echo " database: $database" >> config/database.yml
109 echo " database: $database" >> config/database.yml
109 echo " pool: 5" >> config/database.yml
110 echo " pool: 5" >> config/database.yml
110 echo " username: $username" >> config/database.yml
111 echo " username: $username" >> config/database.yml
111 echo " password: $password" >> config/database.yml
112 echo " password: $password" >> config/database.yml
112 echo " host: localhost" >> config/database.yml
113 echo " host: localhost" >> config/database.yml
113 echo " socket: /var/run/mysqld/mysqld.sock" >> config/database.yml
114 echo " socket: /var/run/mysqld/mysqld.sock" >> config/database.yml
114
115
115 echo "Object.instance_eval{remove_const :GRADER_ROOT_DIR}" >> config/initializers/cafe_grader_config.rb
116 echo "Object.instance_eval{remove_const :GRADER_ROOT_DIR}" >> config/initializers/cafe_grader_config.rb
116 echo "Object.instance_eval{remove_const :GRADING_RESULT_DIR}" >> config/initializers/cafe_grader_config.rb
117 echo "Object.instance_eval{remove_const :GRADING_RESULT_DIR}" >> config/initializers/cafe_grader_config.rb
117 echo "GRADER_ROOT_DIR = '$CAFE_PATH/judge'" >> config/initializers/cafe_grader_config.rb
118 echo "GRADER_ROOT_DIR = '$CAFE_PATH/judge'" >> config/initializers/cafe_grader_config.rb
118 echo "GRADING_RESULT_DIR = '$CAFE_PATH/judge/result'" >> config/initializers/cafe_grader_config.rb
119 echo "GRADING_RESULT_DIR = '$CAFE_PATH/judge/result'" >> config/initializers/cafe_grader_config.rb
119
120
120 echo "Installing required gems"
121 echo "Installing required gems"
121 gem install bundler
122 gem install bundler
122 bundle install
123 bundle install
123
124
124 echo "Running rake tasks to initialize database"
125 echo "Running rake tasks to initialize database"
125
126
126 rake db:migrate
127 rake db:migrate
127 rake db:seed
128 rake db:seed
128
129
129 echo "Running rake tasks to precompile the assets"
130 echo "Running rake tasks to precompile the assets"
130
131
131 rake assets:precompile
132 rake assets:precompile
132
133
133 echo "Intalling web interface complete..."
134 echo "Intalling web interface complete..."
134 echo
135 echo
135 echo "Fetching grader"
136 echo "Fetching grader"
136
137
137 cd ..
138 cd ..
138
139
139 mkdir judge
140 mkdir judge
140 cd judge
141 cd judge
141 git clone -q git://github.com/jittat/cafe-grader-judge-scripts.git scripts
142 git clone -q git://github.com/jittat/cafe-grader-judge-scripts.git scripts
142 mkdir raw
143 mkdir raw
143 mkdir ev-exam
144 mkdir ev-exam
144 mkdir ev
145 mkdir ev
145 mkdir result
146 mkdir result
146 mkdir log
147 mkdir log
147
148
148 echo "Configuring grader"
149 echo "Configuring grader"
149
150
150 cp scripts/config/env_exam.rb.SAMPLE scripts/config/env_exam.rb
151 cp scripts/config/env_exam.rb.SAMPLE scripts/config/env_exam.rb
151 cp scripts/config/env_grading.rb.SAMPLE scripts/config/env_grading.rb
152 cp scripts/config/env_grading.rb.SAMPLE scripts/config/env_grading.rb
152
153
153 # create new environment.rb file
154 # create new environment.rb file
154 echo "RAILS_ROOT = '$CAFE_PATH/web'" > scripts/config/environment.rb
155 echo "RAILS_ROOT = '$CAFE_PATH/web'" > scripts/config/environment.rb
155 echo "GRADER_ROOT = '$CAFE_PATH/judge/scripts'" >> scripts/config/environment.rb
156 echo "GRADER_ROOT = '$CAFE_PATH/judge/scripts'" >> scripts/config/environment.rb
156 echo "require File.join(File.dirname(__FILE__),'../lib/boot')" >> scripts/config/environment.rb
157 echo "require File.join(File.dirname(__FILE__),'../lib/boot')" >> scripts/config/environment.rb
157 echo "require File.dirname(__FILE__) + \"/env_#{GRADER_ENV}.rb\"" >> scripts/config/environment.rb
158 echo "require File.dirname(__FILE__) + \"/env_#{GRADER_ENV}.rb\"" >> scripts/config/environment.rb
158
159
159 # compiling box
160 # compiling box
160 MACHINE_TYPE=`uname -m`
161 MACHINE_TYPE=`uname -m`
161 if [ ${MACHINE_TYPE} == 'x86_64' ]; then
162 if [ ${MACHINE_TYPE} == 'x86_64' ]; then
162 gcc -std=c99 -o scripts/std-script/box scripts/std-script/box64-new.c
163 gcc -std=c99 -o scripts/std-script/box scripts/std-script/box64-new.c
163 - # 64-bit stuff here
164 else
164 else
165 g++ -o scripts/std-script/box scripts/std-script/box.cc
165 g++ -o scripts/std-script/box scripts/std-script/box.cc
166 - # 32-bit stuff here
167 fi
166 fi
168
167
169
168
170 cd ..
169 cd ..
171
170
172 echo "Now you are ready to run cafe grader...."
171 echo "Now you are ready to run cafe grader...."
173 echo
172 echo
174 echo "Try:"
173 echo "Try:"
175 echo
174 echo
176 echo " cd web"
175 echo " cd web"
177 echo " rails s"
176 echo " rails s"
178 echo
177 echo
179 echo "and access web at http://localhost:3000/"
178 echo "and access web at http://localhost:3000/"
180 echo "The root username is 'root', its password is 'ioionrails'."
179 echo "The root username is 'root', its password is 'ioionrails'."
181
180
@@ -1,73 +1,73
1 - #!/usr/bin/ruby
1 + #!/usr/bin/env ruby
2
2
3 # new_problem:
3 # new_problem:
4 # * creates a directory for a problem in the current directory,
4 # * creates a directory for a problem in the current directory,
5 # * create standard testcase config file
5 # * create standard testcase config file
6
6
7 require 'erb'
7 require 'erb'
8
8
9 def process_options(options)
9 def process_options(options)
10 i = 2
10 i = 2
11 while i<ARGV.length
11 while i<ARGV.length
12 if ARGV[i]=='-t'
12 if ARGV[i]=='-t'
13 options[:time_limit] = ARGV[i+1].to_i if ARGV.length>i+1
13 options[:time_limit] = ARGV[i+1].to_i if ARGV.length>i+1
14 i += 1
14 i += 1
15 end
15 end
16 if ARGV[i]=='-m'
16 if ARGV[i]=='-m'
17 options[:mem_limit] = ARGV[i+1].to_i if ARGV.length>i+1
17 options[:mem_limit] = ARGV[i+1].to_i if ARGV.length>i+1
18 i += 1
18 i += 1
19 end
19 end
20 i += 1
20 i += 1
21 end
21 end
22 end
22 end
23
23
24
24
25 puts "This script is out of dated, shall be fixed soon"
25 puts "This script is out of dated, shall be fixed soon"
26 puts "Right now, you can create raw_ev and import"
26 puts "Right now, you can create raw_ev and import"
27 exit(0)
27 exit(0)
28
28
29 GRADER_DIR = File.dirname(__FILE__)
29 GRADER_DIR = File.dirname(__FILE__)
30
30
31 # print usage
31 # print usage
32 if ARGV.length < 2
32 if ARGV.length < 2
33 puts <<USAGE
33 puts <<USAGE
34 using: new_problem problem number_of_testcase [options]
34 using: new_problem problem number_of_testcase [options]
35 * creates a directory for a problem in the current directory,
35 * creates a directory for a problem in the current directory,
36 * create standard testcase config file
36 * create standard testcase config file
37 * options: -t time-limit (in seconds)
37 * options: -t time-limit (in seconds)
38 -m mem-limit (in MB)
38 -m mem-limit (in MB)
39 USAGE
39 USAGE
40 exit(127)
40 exit(127)
41 end
41 end
42
42
43 # processing arguments
43 # processing arguments
44 problem = ARGV[0]
44 problem = ARGV[0]
45 num_testcases = ARGV[1].to_i
45 num_testcases = ARGV[1].to_i
46
46
47 options = {:time_limit => 1, :mem_limit => 16}
47 options = {:time_limit => 1, :mem_limit => 16}
48 process_options(options)
48 process_options(options)
49
49
50 # start working
50 # start working
51 puts "creating directories"
51 puts "creating directories"
52
52
53 system("mkdir #{problem}")
53 system("mkdir #{problem}")
54 system("mkdir #{problem}/script")
54 system("mkdir #{problem}/script")
55 system("mkdir #{problem}/test_cases")
55 system("mkdir #{problem}/test_cases")
56
56
57 puts "creating testcases directories"
57 puts "creating testcases directories"
58
58
59 1.upto(num_testcases) do |i|
59 1.upto(num_testcases) do |i|
60 system("mkdir #{problem}/test_cases/#{i}")
60 system("mkdir #{problem}/test_cases/#{i}")
61 end
61 end
62
62
63 # generating all_tests.cfg
63 # generating all_tests.cfg
64 puts "generating testcase config file"
64 puts "generating testcase config file"
65
65
66 template = File.open(File.dirname(__FILE__) + "/templates/all_tests.cfg.erb").read
66 template = File.open(File.dirname(__FILE__) + "/templates/all_tests.cfg.erb").read
67 all_test_cfg = ERB.new(template)
67 all_test_cfg = ERB.new(template)
68
68
69 cfg_file = File.open("#{problem}/test_cases/all_tests.cfg","w")
69 cfg_file = File.open("#{problem}/test_cases/all_tests.cfg","w")
70 cfg_file.puts all_test_cfg.result
70 cfg_file.puts all_test_cfg.result
71 cfg_file.close
71 cfg_file.close
72
72
73 puts "done"
73 puts "done"
@@ -1,48 +1,48
1 - #!/usr/bin/ruby
1 + #!/usr/bin/env ruby
2
2
3 #
3 #
4 # This is a check script wrapper. It read all required information
4 # This is a check script wrapper. It read all required information
5 # and call a real check script call REAL_CHECK_SCRIPT in directory
5 # and call a real check script call REAL_CHECK_SCRIPT in directory
6 # [problem_home]/script
6 # [problem_home]/script
7 #
7 #
8
8
9 REAL_CHECK_SCRIPT = "<%= script_name %>"
9 REAL_CHECK_SCRIPT = "<%= script_name %>"
10
10
11 # The REAL_CHECK_SCRIPT is called with:
11 # The REAL_CHECK_SCRIPT is called with:
12 #
12 #
13 # (script) <lang> <test-num> <in-file> <out-file> <ans-file> <full-score>
13 # (script) <lang> <test-num> <in-file> <out-file> <ans-file> <full-score>
14 #
14 #
15 # and REAL_CHECK_SCRIPT's output to standard out is redirected to
15 # and REAL_CHECK_SCRIPT's output to standard out is redirected to
16 # 'check_result' as required by normal check script.
16 # 'check_result' as required by normal check script.
17
17
18 problem_home = ENV['PROBLEM_HOME']
18 problem_home = ENV['PROBLEM_HOME']
19 require "#{problem_home}/script/test_dsl.rb"
19 require "#{problem_home}/script/test_dsl.rb"
20
20
21 if ARGV.length < 2
21 if ARGV.length < 2
22 puts "Usage: check <language> <test-number> [<output-file>]"
22 puts "Usage: check <language> <test-number> [<output-file>]"
23 exit(0)
23 exit(0)
24 end
24 end
25
25
26 language = ARGV[0]
26 language = ARGV[0]
27 test_num = ARGV[1].to_i
27 test_num = ARGV[1].to_i
28 if ARGV.length >= 3
28 if ARGV.length >= 3
29 output_file_name = ARGV[2]
29 output_file_name = ARGV[2]
30 else
30 else
31 output_file_name = "output.txt"
31 output_file_name = "output.txt"
32 end
32 end
33
33
34 load "#{problem_home}/test_cases/all_tests.cfg"
34 load "#{problem_home}/test_cases/all_tests.cfg"
35 problem = Problem.get_instance
35 problem = Problem.get_instance
36
36
37 answer_file_name = "#{problem_home}/test_cases/#{test_num}/answer-#{test_num}.txt"
37 answer_file_name = "#{problem_home}/test_cases/#{test_num}/answer-#{test_num}.txt"
38 input_file_name = "#{problem_home}/test_cases/#{test_num}/input-#{test_num}.txt"
38 input_file_name = "#{problem_home}/test_cases/#{test_num}/input-#{test_num}.txt"
39
39
40 score = problem.get_score(test_num)
40 score = problem.get_score(test_num)
41
41
42 cmd = "#{problem_home}/script/#{REAL_CHECK_SCRIPT} " +
42 cmd = "#{problem_home}/script/#{REAL_CHECK_SCRIPT} " +
43 "#{language} #{test_num} #{input_file_name} #{output_file_name} " +
43 "#{language} #{test_num} #{input_file_name} #{output_file_name} " +
44 "#{answer_file_name} #{score} > check_result"
44 "#{answer_file_name} #{score} > check_result"
45
45
46 #puts "wrapper-CMD: #{cmd}"
46 #puts "wrapper-CMD: #{cmd}"
47
47
48 system(cmd)
48 system(cmd)
@@ -1,59 +1,59
1 - #!/usr/bin/ruby
1 + #!/usr/bin/env ruby
2
2
3 problem_home = ENV['PROBLEM_HOME']
3 problem_home = ENV['PROBLEM_HOME']
4 require "#{problem_home}/script/test_dsl.rb"
4 require "#{problem_home}/script/test_dsl.rb"
5
5
6 if ARGV.length < 2
6 if ARGV.length < 2
7 puts "Usage: check <language> <test-number> [<output-file>]"
7 puts "Usage: check <language> <test-number> [<output-file>]"
8 exit(0)
8 exit(0)
9 end
9 end
10
10
11 language = ARGV[0]
11 language = ARGV[0]
12 test_num = ARGV[1].to_i
12 test_num = ARGV[1].to_i
13 if ARGV.length >= 3
13 if ARGV.length >= 3
14 output_file_name = ARGV[2]
14 output_file_name = ARGV[2]
15 else
15 else
16 output_file_name = "output.txt"
16 output_file_name = "output.txt"
17 end
17 end
18
18
19 load "#{problem_home}/test_cases/all_tests.cfg"
19 load "#{problem_home}/test_cases/all_tests.cfg"
20 problem = Problem.get_instance
20 problem = Problem.get_instance
21
21
22 output_file = File.new(output_file_name, "r")
22 output_file = File.new(output_file_name, "r")
23 answer_file = File.new("#{problem_home}/test_cases/#{test_num}/answer-#{test_num}.txt")
23 answer_file = File.new("#{problem_home}/test_cases/#{test_num}/answer-#{test_num}.txt")
24 result_file = File.new("check_result", "w")
24 result_file = File.new("check_result", "w")
25
25
26 output_file_content = output_file.read
26 output_file_content = output_file.read
27 answer_file_content = answer_file.read
27 answer_file_content = answer_file.read
28
28
29 report_correct = lambda {
29 report_correct = lambda {
30 result_file.write "Correct\n"
30 result_file.write "Correct\n"
31 result_file.write problem.get_score(test_num)
31 result_file.write problem.get_score(test_num)
32 result_file.write "\n"
32 result_file.write "\n"
33 result_file.close
33 result_file.close
34 exit(0)
34 exit(0)
35 }
35 }
36
36
37 report_wrong = lambda {
37 report_wrong = lambda {
38 result_file.write "Incorrect\n"
38 result_file.write "Incorrect\n"
39 result_file.write "0\n"
39 result_file.write "0\n"
40 result_file.close
40 result_file.close
41 exit(0)
41 exit(0)
42 }
42 }
43
43
44 ##################
44 ##################
45 # Your code here #
45 # Your code here #
46 ##################
46 ##################
47 num_pattern = /^[0-9]*/
47 num_pattern = /^[0-9]*/
48 if (output_file_content =~ num_pattern) == nil
48 if (output_file_content =~ num_pattern) == nil
49 report_wrong.call
49 report_wrong.call
50 end
50 end
51
51
52 output_i = output_file_content.to_i
52 output_i = output_file_content.to_i
53 answer_i = answer_file_content.to_i
53 answer_i = answer_file_content.to_i
54
54
55 if output_i == answer_i
55 if output_i == answer_i
56 report_correct.call
56 report_correct.call
57 else
57 else
58 report_wrong.call
58 report_wrong.call
59 end
59 end
@@ -1,59 +1,59
1 - #!/usr/bin/ruby
1 + #!/usr/bin/env ruby
2
2
3 problem_home = ENV['PROBLEM_HOME']
3 problem_home = ENV['PROBLEM_HOME']
4 require "#{problem_home}/script/test_dsl.rb"
4 require "#{problem_home}/script/test_dsl.rb"
5
5
6 if ARGV.length < 2
6 if ARGV.length < 2
7 puts "Usage: check <language> <test-number> [<output-file>]"
7 puts "Usage: check <language> <test-number> [<output-file>]"
8 exit(0)
8 exit(0)
9 end
9 end
10
10
11 language = ARGV[0]
11 language = ARGV[0]
12 test_num = ARGV[1].to_i
12 test_num = ARGV[1].to_i
13 if ARGV.length >= 3
13 if ARGV.length >= 3
14 output_file_name = ARGV[2]
14 output_file_name = ARGV[2]
15 else
15 else
16 output_file_name = "output.txt"
16 output_file_name = "output.txt"
17 end
17 end
18
18
19 load "#{problem_home}/test_cases/all_tests.cfg"
19 load "#{problem_home}/test_cases/all_tests.cfg"
20 problem = Problem.get_instance
20 problem = Problem.get_instance
21
21
22 output_file = File.new(output_file_name, "r")
22 output_file = File.new(output_file_name, "r")
23 answer_file = File.new("#{problem_home}/test_cases/#{test_num}/answer-#{test_num}.txt")
23 answer_file = File.new("#{problem_home}/test_cases/#{test_num}/answer-#{test_num}.txt")
24 result_file = File.new("check_result", "w")
24 result_file = File.new("check_result", "w")
25
25
26 output_file_content = output_file.read
26 output_file_content = output_file.read
27 answer_file_content = answer_file.read
27 answer_file_content = answer_file.read
28
28
29 report_correct = lambda {
29 report_correct = lambda {
30 result_file.write "Correct\n"
30 result_file.write "Correct\n"
31 result_file.write problem.get_score(test_num)
31 result_file.write problem.get_score(test_num)
32 result_file.write "\n"
32 result_file.write "\n"
33 result_file.close
33 result_file.close
34 exit(0)
34 exit(0)
35 }
35 }
36
36
37 report_wrong = lambda {
37 report_wrong = lambda {
38 result_file.write "Incorrect\n"
38 result_file.write "Incorrect\n"
39 result_file.write "0\n"
39 result_file.write "0\n"
40 result_file.close
40 result_file.close
41 exit(0)
41 exit(0)
42 }
42 }
43
43
44 ##################
44 ##################
45 # Your code here #
45 # Your code here #
46 ##################
46 ##################
47 num_pattern = /^[0-9]*/
47 num_pattern = /^[0-9]*/
48 if (output_file_content =~ num_pattern) == nil
48 if (output_file_content =~ num_pattern) == nil
49 report_wrong.call
49 report_wrong.call
50 end
50 end
51
51
52 output_i = output_file_content.to_i
52 output_i = output_file_content.to_i
53 answer_i = answer_file_content.to_i
53 answer_i = answer_file_content.to_i
54
54
55 if output_i == answer_i
55 if output_i == answer_i
56 report_correct.call
56 report_correct.call
57 else
57 else
58 report_wrong.call
58 report_wrong.call
59 end
59 end
@@ -1,59 +1,59
1 - #!/usr/bin/ruby
1 + #!/usr/bin/env ruby
2
2
3 problem_home = ENV['PROBLEM_HOME']
3 problem_home = ENV['PROBLEM_HOME']
4 require "#{problem_home}/script/test_dsl.rb"
4 require "#{problem_home}/script/test_dsl.rb"
5
5
6 if ARGV.length < 2
6 if ARGV.length < 2
7 puts "Usage: check <language> <test-number> [<output-file>]"
7 puts "Usage: check <language> <test-number> [<output-file>]"
8 exit(0)
8 exit(0)
9 end
9 end
10
10
11 language = ARGV[0]
11 language = ARGV[0]
12 test_num = ARGV[1].to_i
12 test_num = ARGV[1].to_i
13 if ARGV.length >= 3
13 if ARGV.length >= 3
14 output_file_name = ARGV[2]
14 output_file_name = ARGV[2]
15 else
15 else
16 output_file_name = "output.txt"
16 output_file_name = "output.txt"
17 end
17 end
18
18
19 load "#{problem_home}/test_cases/all_tests.cfg"
19 load "#{problem_home}/test_cases/all_tests.cfg"
20 problem = Problem.get_instance
20 problem = Problem.get_instance
21
21
22 output_file = File.new(output_file_name, "r")
22 output_file = File.new(output_file_name, "r")
23 answer_file = File.new("#{problem_home}/test_cases/#{test_num}/answer-#{test_num}.txt")
23 answer_file = File.new("#{problem_home}/test_cases/#{test_num}/answer-#{test_num}.txt")
24 result_file = File.new("check_result", "w")
24 result_file = File.new("check_result", "w")
25
25
26 output_file_content = output_file.read
26 output_file_content = output_file.read
27 answer_file_content = answer_file.read
27 answer_file_content = answer_file.read
28
28
29 report_correct = lambda {
29 report_correct = lambda {
30 result_file.write "Correct\n"
30 result_file.write "Correct\n"
31 result_file.write problem.get_score(test_num)
31 result_file.write problem.get_score(test_num)
32 result_file.write "\n"
32 result_file.write "\n"
33 result_file.close
33 result_file.close
34 exit(0)
34 exit(0)
35 }
35 }
36
36
37 report_wrong = lambda {
37 report_wrong = lambda {
38 result_file.write "Incorrect\n"
38 result_file.write "Incorrect\n"
39 result_file.write "0\n"
39 result_file.write "0\n"
40 result_file.close
40 result_file.close
41 exit(0)
41 exit(0)
42 }
42 }
43
43
44 ##################
44 ##################
45 # Your code here #
45 # Your code here #
46 ##################
46 ##################
47 num_pattern = /^[0-9]*/
47 num_pattern = /^[0-9]*/
48 if (output_file_content =~ num_pattern) == nil
48 if (output_file_content =~ num_pattern) == nil
49 report_wrong.call
49 report_wrong.call
50 end
50 end
51
51
52 output_i = output_file_content.to_i
52 output_i = output_file_content.to_i
53 answer_i = answer_file_content.to_i
53 answer_i = answer_file_content.to_i
54
54
55 if output_i == answer_i
55 if output_i == answer_i
56 report_correct.call
56 report_correct.call
57 else
57 else
58 report_wrong.call
58 report_wrong.call
59 end
59 end
@@ -109,220 +109,220
109 end
109 end
110
110
111 it "should not allow malicious submission to see PROBLEM_HOME" do
111 it "should not allow malicious submission to see PROBLEM_HOME" do
112 problem_test_yesno = stub(Problem,
112 problem_test_yesno = stub(Problem,
113 :id => 1, :name => 'test_yesno',
113 :id => 1, :name => 'test_yesno',
114 :full_score => 10)
114 :full_score => 10)
115 grader_should(:grade => "yesno_access_problem_home.c",
115 grader_should(:grade => "yesno_access_problem_home.c",
116 :on => problem_test_yesno,
116 :on => problem_test_yesno,
117 :and_report => {
117 :and_report => {
118 :score => 0,
118 :score => 0,
119 :comment => /(-|x)/})
119 :comment => /(-|x)/})
120 end
120 end
121
121
122 it "should not allow malicious submission to open files" do
122 it "should not allow malicious submission to open files" do
123 problem_test_yesno = stub(Problem,
123 problem_test_yesno = stub(Problem,
124 :id => 1, :name => 'test_yesno',
124 :id => 1, :name => 'test_yesno',
125 :full_score => 10)
125 :full_score => 10)
126 grader_should(:grade => "yesno_open_file.c",
126 grader_should(:grade => "yesno_open_file.c",
127 :on => problem_test_yesno,
127 :on => problem_test_yesno,
128 :and_report => {
128 :and_report => {
129 :score => 0,
129 :score => 0,
130 :comment => /(-|x)/})
130 :comment => /(-|x)/})
131 end
131 end
132
132
133 def grader_should(args)
133 def grader_should(args)
134 @user1 = stub(User,
134 @user1 = stub(User,
135 :id => 1, :login => 'user1')
135 :id => 1, :login => 'user1')
136
136
137 submission =
137 submission =
138 create_submission_from_file(1, @user1, args[:on], args[:grade], args[:language])
138 create_submission_from_file(1, @user1, args[:on], args[:grade], args[:language])
139 submission.should_receive(:graded_at=)
139 submission.should_receive(:graded_at=)
140
140
141 expected_score = args[:and_report][:score]
141 expected_score = args[:and_report][:score]
142 expected_comment = args[:and_report][:comment]
142 expected_comment = args[:and_report][:comment]
143 if args[:and_report][:compiler_message]!=nil
143 if args[:and_report][:compiler_message]!=nil
144 expected_compiler_message = args[:and_report][:compiler_message]
144 expected_compiler_message = args[:and_report][:compiler_message]
145 else
145 else
146 expected_compiler_message = ''
146 expected_compiler_message = ''
147 end
147 end
148
148
149 submission.should_receive(:points=).with(expected_score)
149 submission.should_receive(:points=).with(expected_score)
150 submission.should_receive(:grader_comment=).with(expected_comment)
150 submission.should_receive(:grader_comment=).with(expected_comment)
151 submission.should_receive(:compiler_message=).with(expected_compiler_message)
151 submission.should_receive(:compiler_message=).with(expected_compiler_message)
152 submission.should_receive(:save)
152 submission.should_receive(:save)
153
153
154 @engine.grade(submission)
154 @engine.grade(submission)
155 end
155 end
156
156
157 protected
157 protected
158
158
159 def create_normal_submission_mock_from_file(source_fname)
159 def create_normal_submission_mock_from_file(source_fname)
160 create_submission_from_file(1, @user_user1, @problem_test_normal, source_fname)
160 create_submission_from_file(1, @user_user1, @problem_test_normal, source_fname)
161 end
161 end
162
162
163 end
163 end
164
164
165 describe "A grader engine, when grading test requests" do
165 describe "A grader engine, when grading test requests" do
166
166
167 include GraderEngineHelperMethods
167 include GraderEngineHelperMethods
168
168
169 before(:each) do
169 before(:each) do
170 @config = Grader::Configuration.get_instance
170 @config = Grader::Configuration.get_instance
171 @engine = Grader::Engine.new(:room_maker => Grader::TestRequestRoomMaker.new,
171 @engine = Grader::Engine.new(:room_maker => Grader::TestRequestRoomMaker.new,
172 :reporter => Grader::TestRequestReporter.new)
172 :reporter => Grader::TestRequestReporter.new)
173 init_sandbox
173 init_sandbox
174 end
174 end
175
175
176 it "should report error if there is no problem template" do
176 it "should report error if there is no problem template" do
177 problem = stub(Problem,
177 problem = stub(Problem,
178 :id => 1, :name => 'nothing')
178 :id => 1, :name => 'nothing')
179 grader_should(:grade => 'test1_correct.c',
179 grader_should(:grade => 'test1_correct.c',
180 :on => problem,
180 :on => problem,
181 :with => 'in1.txt',
181 :with => 'in1.txt',
182 :and_report => {
182 :and_report => {
183 :graded_at= => nil,
183 :graded_at= => nil,
184 :compiler_message= => '',
184 :compiler_message= => '',
185 :grader_comment= => '',
185 :grader_comment= => '',
186 :running_stat= => /template not found/,
186 :running_stat= => /template not found/,
187 :running_time= => nil,
187 :running_time= => nil,
188 :exit_status= => nil,
188 :exit_status= => nil,
189 :memory_usage= => nil,
189 :memory_usage= => nil,
190 :save => nil})
190 :save => nil})
191 end
191 end
192
192
193 it "should run test request and produce output file" do
193 it "should run test request and produce output file" do
194 problem = stub(Problem,
194 problem = stub(Problem,
195 :id => 1, :name => 'test_normal')
195 :id => 1, :name => 'test_normal')
196 grader_should(:grade => 'test1_correct.c',
196 grader_should(:grade => 'test1_correct.c',
197 :on => problem,
197 :on => problem,
198 :with => 'in1.txt',
198 :with => 'in1.txt',
199 :and_report => {
199 :and_report => {
200 :graded_at= => nil,
200 :graded_at= => nil,
201 :compiler_message= => '',
201 :compiler_message= => '',
202 :grader_comment= => '',
202 :grader_comment= => '',
203 :running_stat= => /0.0\d* sec./,
203 :running_stat= => /0.0\d* sec./,
204 :output_file_name= => lambda { |fname|
204 :output_file_name= => lambda { |fname|
205 - File.exists?(fname).should be_true
205 + File.exists?(fname).should be true
206 },
206 },
207 :running_time= => nil,
207 :running_time= => nil,
208 :exit_status= => nil,
208 :exit_status= => nil,
209 :memory_usage= => nil,
209 :memory_usage= => nil,
210 :save => nil})
210 :save => nil})
211 end
211 end
212
212
213 it "should clean up problem directory after running test request" do
213 it "should clean up problem directory after running test request" do
214 problem = stub(Problem,
214 problem = stub(Problem,
215 :id => 1, :name => 'test_normal')
215 :id => 1, :name => 'test_normal')
216 grader_should(:grade => 'test1_correct.c',
216 grader_should(:grade => 'test1_correct.c',
217 :on => problem,
217 :on => problem,
218 :with => 'in1.txt',
218 :with => 'in1.txt',
219 :and_report => {
219 :and_report => {
220 :graded_at= => nil,
220 :graded_at= => nil,
221 :compiler_message= => '',
221 :compiler_message= => '',
222 :grader_comment= => '',
222 :grader_comment= => '',
223 :running_stat= => nil,
223 :running_stat= => nil,
224 :output_file_name= => nil,
224 :output_file_name= => nil,
225 :running_time= => nil,
225 :running_time= => nil,
226 :exit_status= => nil,
226 :exit_status= => nil,
227 :memory_usage= => nil,
227 :memory_usage= => nil,
228 :save => nil})
228 :save => nil})
229 - File.exists?(@config.user_result_dir + "/test_request/test_normal/test_cases/1/input-1.txt").should be_false
229 + File.exists?(@config.user_result_dir + "/test_request/test_normal/test_cases/1/input-1.txt").should be false
230 end
230 end
231
231
232 it "should compile test request with error and report compilation error" do
232 it "should compile test request with error and report compilation error" do
233 problem = stub(Problem,
233 problem = stub(Problem,
234 :id => 1, :name => 'test_normal')
234 :id => 1, :name => 'test_normal')
235 grader_should(:grade => 'test1_compile_error.c',
235 grader_should(:grade => 'test1_compile_error.c',
236 :on => problem,
236 :on => problem,
237 :with => 'in1.txt',
237 :with => 'in1.txt',
238 :and_report => {
238 :and_report => {
239 :graded_at= => nil,
239 :graded_at= => nil,
240 :compiler_message= => /.+/,
240 :compiler_message= => /.+/,
241 :grader_comment= => /[Cc]ompil.*error/,
241 :grader_comment= => /[Cc]ompil.*error/,
242 :running_stat= => '',
242 :running_stat= => '',
243 :save => nil})
243 :save => nil})
244 end
244 end
245
245
246 it "should report exit status" do
246 it "should report exit status" do
247 problem = stub(Problem,
247 problem = stub(Problem,
248 :id => 1, :name => 'test_normal')
248 :id => 1, :name => 'test_normal')
249 grader_should(:grade => 'add_nonzero_exit_status.c',
249 grader_should(:grade => 'add_nonzero_exit_status.c',
250 :on => problem,
250 :on => problem,
251 :with => 'in1.txt',
251 :with => 'in1.txt',
252 :and_report => {
252 :and_report => {
253 :graded_at= => nil,
253 :graded_at= => nil,
254 :compiler_message= => '',
254 :compiler_message= => '',
255 :grader_comment= => '',
255 :grader_comment= => '',
256 :running_stat= => /[Ee]xit.*status.*10.*0\.0\d* sec/m,
256 :running_stat= => /[Ee]xit.*status.*10.*0\.0\d* sec/m,
257 :output_file_name= => lambda { |fname|
257 :output_file_name= => lambda { |fname|
258 - File.exists?(fname).should be_true
258 + File.exists?(fname).should be true
259 },
259 },
260 :running_time= => nil,
260 :running_time= => nil,
261 :exit_status= => /10/,
261 :exit_status= => /10/,
262 :memory_usage= => nil,
262 :memory_usage= => nil,
263 :save => nil})
263 :save => nil})
264 end
264 end
265
265
266 it "should produce running statistics for normal submission" do
266 it "should produce running statistics for normal submission" do
267 problem = stub(Problem,
267 problem = stub(Problem,
268 :id => 1, :name => 'test_normal')
268 :id => 1, :name => 'test_normal')
269 grader_should(:grade => 'test_run_stat.c',
269 grader_should(:grade => 'test_run_stat.c',
270 :on => problem,
270 :on => problem,
271 :with => 'in1.txt',
271 :with => 'in1.txt',
272 :and_report => {
272 :and_report => {
273 :graded_at= => nil,
273 :graded_at= => nil,
274 :compiler_message= => '',
274 :compiler_message= => '',
275 :grader_comment= => '',
275 :grader_comment= => '',
276 :running_stat= => nil,
276 :running_stat= => nil,
277 :output_file_name= => lambda { |fname|
277 :output_file_name= => lambda { |fname|
278 - File.exists?(fname).should be_true
278 + File.exists?(fname).should be true
279 },
279 },
280 :running_time= => lambda { |t|
280 :running_time= => lambda { |t|
281 (t>=0.14) and (t<=0.16)
281 (t>=0.14) and (t<=0.16)
282 },
282 },
283 :exit_status= => nil,
283 :exit_status= => nil,
284 :memory_usage= => lambda { |s|
284 :memory_usage= => lambda { |s|
285 (s>=500) and (s<=1000)
285 (s>=500) and (s<=1000)
286 },
286 },
287 :save => nil})
287 :save => nil})
288 end
288 end
289
289
290 protected
290 protected
291 def grader_should(args)
291 def grader_should(args)
292 @user1 = stub(User,
292 @user1 = stub(User,
293 :id => 1, :login => 'user1')
293 :id => 1, :login => 'user1')
294
294
295 problem = args[:on]
295 problem = args[:on]
296 input_file = @config.test_request_input_base_dir + "/" + args[:with]
296 input_file = @config.test_request_input_base_dir + "/" + args[:with]
297
297
298 submission =
298 submission =
299 create_submission_from_file(1, @user1, args[:on], args[:grade])
299 create_submission_from_file(1, @user1, args[:on], args[:grade])
300
300
301 test_request = stub(TestRequest,
301 test_request = stub(TestRequest,
302 :id => 1,
302 :id => 1,
303 :user => @user1,
303 :user => @user1,
304 :problem => problem,
304 :problem => problem,
305 :submission => submission,
305 :submission => submission,
306 :input_file_name => input_file,
306 :input_file_name => input_file,
307 :language => submission.language,
307 :language => submission.language,
308 :problem_name => problem.name)
308 :problem_name => problem.name)
309
309
310 expectations = args[:and_report]
310 expectations = args[:and_report]
311
311
312 expectations.each do |key,val|
312 expectations.each do |key,val|
313 if val==nil
313 if val==nil
314 test_request.should_receive(key)
314 test_request.should_receive(key)
315 elsif val.class == Proc
315 elsif val.class == Proc
316 test_request.should_receive(key) { |fname|
316 test_request.should_receive(key) { |fname|
317 val.call(fname)
317 val.call(fname)
318 }
318 }
319 else
319 else
320 test_request.should_receive(key).with(val)
320 test_request.should_receive(key).with(val)
321 end
321 end
322 end
322 end
323
323
324 @engine.grade(test_request)
324 @engine.grade(test_request)
325 end
325 end
326
326
327 end
327 end
328
328
You need to be logged in to leave comments. Login now