Description:
update java-bm
Commit status:
[Not Reviewed]
References:
merge java
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r214:336e928de90e - - 9 files changed: 60 inserted, 21 deleted

@@ -1,154 +1,180
1 1 #!/bin/sh
2 2
3 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 8 echo "Installing required apts"
8 9
9 10 sudo apt-get update
10 11 sudo apt-get install mysql-server mysql-client \
11 12 g++ gcc apache2 libmysqlclient15-dev build-essential \
12 13 git-core openssl libreadline6 libreadline6-dev \
13 14 zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev \
14 15 sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev \
15 16 ncurses-dev automake libtool bison subversion \
16 - pkg-config curl nodejs unzip
17 + pkg-config curl nodejs unzip pyflakes ruby default-jdk
17 18
18 19 echo "Installing RVM"
19 20 curl -k -L https://get.rvm.io | bash -s stable
20 - ~/.rvm/scripts/rvm
21 + source ~/.rvm/scripts/rvm
21 22
22 - echo "Installing Ruby 1.9.2 in RVM"
23 + echo "Installing Ruby $RUBY_VERSION in RVM"
23 24
24 - rvm install 1.9.2
25 - rvm use 1.9.2
25 + rvm install $RUBY_VERSION
26 + rvm use $RUBY_VERSION
26 27
27 28 echo "Fetching Cafe Grader from Git repositories"
28 29
29 30 echo "Fetching web interface"
30 31
31 32 mkdir cafe_grader
32 33 cd cafe_grader
33 34 git clone -q git://github.com/jittat/cafe-grader-web.git web
34 35
35 36 echo "Configuring rails app"
36 37
37 38 cp web/config/application.rb.SAMPLE web/config/application.rb
38 39 cp web/config/initializers/cafe_grader_config.rb.SAMPLE web/config/initializers/cafe_grader_config.rb
39 40
41 + #replace UTC in application.rb with the system timezone
42 + timezone='UTC'
43 + if [ -f '/etc/timezone' ]; then
44 + timezone=\"`cat /etc/timezone`\"
45 + else
46 + if [ -f '/etc/sysconfig/clock' ]; then
47 + timezone=`grep -e '^TIMEZONE' /etc/sysconfig/clock | grep -o -e '\".*\"'`
48 + fi
49 + fi
50 + replace="s!'UTC'!$timezone!g"
51 + sed -i $replace web/config/application.rb
52 +
40 53 echo "At this point we will need MySQL user and database."
41 54 echo "Have you created MySQL user and database for Cafe grader? (Y/N) "
42 55 read ch
43 56
44 57 if [ "$ch" = "n" -o "$ch" = "N" ]
45 58 then
46 59 echo "Please open another terminal and create the user and database for Cafe grader."
47 60 echo "Don't forget to grant access to that database for the user."
48 61 echo "Please have username, password, and database name ready before continue."
49 62 echo
50 63 echo "The following are instructions:"
51 64 echo "1. Run mysql:"
52 65 echo
53 66 echo " mysql -u root -p"
54 67 echo
55 68 echo " if you have just installed mysql, the root password is the one that you have just entered"
56 69 echo "2. Create a new database, a new user, and grant access to grader database:"
57 70 echo
58 71 echo " create user 'USERNAME'@'localhost' identified by 'PASSWORD';"
59 72 echo " create database \`DATABASENEME\`;"
60 73 echo " grant all on \`DATABASENAME\`.* to 'USERNAME'@'localhost';"
61 74 echo
62 75 echo " Replace USERNAME, PASSWORD, and DATABASENAME accordingly."
63 76 echo
64 77 echo "Hit enter when ready..."
65 78 read dummy
66 79 fi
67 80
68 81 CAFE_PATH=`pwd`
69 82
70 83 cd web
71 84
72 85 echo "Please provide grader database:"
73 86 read database
74 87
75 88 echo "Please provide grader username:"
76 89 read username
77 90
78 91 echo "Please provide $username password:"
79 92 read password
80 93
81 94 echo "development:" > config/database.yml
82 95 echo " adapter: mysql2" >> config/database.yml
83 96 echo " encoding: utf8" >> config/database.yml
84 97 echo " reconnect: false" >> config/database.yml
85 98 echo " database: $database" >> config/database.yml
86 99 echo " pool: 5" >> config/database.yml
87 100 echo " username: $username" >> config/database.yml
88 101 echo " password: $password" >> config/database.yml
89 102 echo " host: localhost" >> config/database.yml
90 103 echo " socket: /var/run/mysqld/mysqld.sock" >> config/database.yml
91 104 echo "" >> config/database.yml
92 105 echo "production:" >> config/database.yml
93 106 echo " adapter: mysql2" >> config/database.yml
94 107 echo " encoding: utf8" >> config/database.yml
95 108 echo " reconnect: false" >> config/database.yml
96 109 echo " database: $database" >> config/database.yml
97 110 echo " pool: 5" >> config/database.yml
98 111 echo " username: $username" >> config/database.yml
99 112 echo " password: $password" >> config/database.yml
100 113 echo " host: localhost" >> config/database.yml
101 114 echo " socket: /var/run/mysqld/mysqld.sock" >> config/database.yml
102 115
103 116 echo "Object.instance_eval{remove_const :GRADER_ROOT_DIR}" >> config/initializers/cafe_grader_config.rb
104 117 echo "Object.instance_eval{remove_const :GRADING_RESULT_DIR}" >> config/initializers/cafe_grader_config.rb
105 118 echo "GRADER_ROOT_DIR = '$CAFE_PATH/judge'" >> config/initializers/cafe_grader_config.rb
106 119 echo "GRADING_RESULT_DIR = '$CAFE_PATH/judge/result'" >> config/initializers/cafe_grader_config.rb
107 120
108 121 echo "Installing required gems"
109 122 gem install bundler
110 123 bundle install
111 124
112 125 echo "Running rake tasks to initialize database"
113 126
114 127 rake db:migrate
115 128 rake db:seed
116 129
130 + echo "Running rake tasks to precompile the assets"
131 +
132 + rake assets:precompile
133 +
117 134 echo "Intalling web interface complete..."
118 135 echo
119 136 echo "Fetching grader"
120 137
121 138 cd ..
122 139
123 140 mkdir judge
124 141 cd judge
125 142 git clone -q git://github.com/jittat/cafe-grader-judge-scripts.git scripts
126 143 mkdir raw
127 144 mkdir ev-exam
128 145 mkdir ev
129 146 mkdir result
130 147 mkdir log
131 148
132 149 echo "Configuring grader"
133 150
134 151 cp scripts/config/env_exam.rb.SAMPLE scripts/config/env_exam.rb
135 152 cp scripts/config/env_grading.rb.SAMPLE scripts/config/env_grading.rb
136 153
137 154 # create new environment.rb file
138 155 echo "RAILS_ROOT = '$CAFE_PATH/web'" > scripts/config/environment.rb
139 156 echo "GRADER_ROOT = '$CAFE_PATH/judge/scripts'" >> scripts/config/environment.rb
140 157 echo "require File.join(File.dirname(__FILE__),'../lib/boot')" >> scripts/config/environment.rb
141 158 echo "require File.dirname(__FILE__) + \"/env_#{GRADER_ENV}.rb\"" >> scripts/config/environment.rb
142 159
160 + # compiling box
161 + MACHINE_TYPE=`uname -m`
162 + if [ ${MACHINE_TYPE} == 'x86_64' ]; then
163 + gcc -std=c99 -o scripts/std-script/box scripts/std-script/box64-new.c
164 + else
165 + g++ -o scripts/std-script/box scripts/std-script/box.cc
166 + fi
167 +
168 +
143 169 cd ..
144 170
145 171 echo "Now you are ready to run cafe grader...."
146 172 echo
147 173 echo "Try:"
148 174 echo
149 175 echo " cd web"
150 176 echo " rails s"
151 177 echo
152 178 echo "and access web at http://localhost:3000/"
153 179 echo "The root username is 'root', its password is 'ioionrails'."
154 180
@@ -1,49 +1,49
1 - #!/usr/bin/ruby
1 + #!/usr/bin/env ruby
2 2
3 3 # new_problem:
4 4 # * creates a directory for a problem in the current directory,
5 5 # * create standard testcase config file
6 6
7 7 require 'erb'
8 8
9 9 def process_options(options)
10 10 i = 2
11 11 while i<ARGV.length
12 12 if ARGV[i]=='-t'
13 13 options[:time_limit] = ARGV[i+1].to_i if ARGV.length>i+1
14 14 i += 1
15 15 end
16 16 if ARGV[i]=='-m'
17 17 options[:mem_limit] = ARGV[i+1].to_i if ARGV.length>i+1
18 18 i += 1
19 19 end
20 20 i += 1
21 21 end
22 22 end
23 23
24 24
25 25 puts "This script is out of dated, shall be fixed soon"
26 26 puts "Right now, you can create raw_ev and import"
27 27 exit(0)
28 28
29 29 GRADER_DIR = File.dirname(__FILE__)
30 30
31 31 # print usage
32 32 if ARGV.length < 2
33 33 puts <<USAGE
34 34 using: new_problem problem number_of_testcase [options]
35 35 * creates a directory for a problem in the current directory,
36 36 * create standard testcase config file
37 37 * options: -t time-limit (in seconds)
38 38 -m mem-limit (in MB)
39 39 USAGE
40 40 exit(127)
41 41 end
42 42
43 43 # processing arguments
44 44 problem = ARGV[0]
45 45 num_testcases = ARGV[1].to_i
46 46
47 47 options = {:time_limit => 1, :mem_limit => 16}
48 48 process_options(options)
49 49
@@ -1611,137 +1611,150
1611 1611 die("setrlimit(RLIMIT_STACK): %m");
1612 1612
1613 1613 rl.rlim_cur = rl.rlim_max = 64;
1614 1614 if (setrlimit(RLIMIT_NOFILE, &rl) < 0)
1615 1615 die("setrlimit(RLIMIT_NOFILE): %m");
1616 1616
1617 1617 char **env = setup_environment();
1618 1618 if (filter_syscalls)
1619 1619 {
1620 1620 if (ptrace(PTRACE_TRACEME) < 0)
1621 1621 die("ptrace(PTRACE_TRACEME): %m");
1622 1622 /* Trick: Make sure that we are stopped until the boxkeeper wakes up. */
1623 1623 raise(SIGSTOP);
1624 1624 }
1625 1625 execve(args[0], args, env);
1626 1626 die("execve(\"%s\"): %m", args[0]);
1627 1627 }
1628 1628
1629 1629 static void
1630 1630 usage(void)
1631 1631 {
1632 1632 fprintf(stderr, "Invalid arguments!\n");
1633 1633 printf("\
1634 1634 Usage: box [<options>] -- <command> <arguments>\n\
1635 1635 \n\
1636 1636 Options:\n\
1637 1637 -a <level>\tSet file access level (0=none, 1=cwd, 2=/etc,/lib,..., 3=whole fs, 9=no checks; needs -f)\n\
1638 1638 -c <dir>\tChange directory to <dir> first\n\
1639 1639 -e\t\tInherit full environment of the parent process\n\
1640 1640 -E <var>\tInherit the environment variable <var> from the parent process\n\
1641 1641 -E <var>=<val>\tSet the environment variable <var> to <val>; unset it if <var> is empty\n\
1642 1642 -f\t\tFilter system calls (-ff=very restricted)\n\
1643 1643 -i <file>\tRedirect stdin from <file>\n\
1644 1644 -k <size>\tLimit stack size to <size> KB (default: 0=unlimited)\n\
1645 1645 -m <size>\tLimit address space to <size> KB\n\
1646 1646 -M <file>\tOutput process information to <file> (name:value)\n\
1647 1647 -o <file>\tRedirect stdout to <file>\n\
1648 1648 -p <path>\tPermit access to the specified path (or subtree if it ends with a `/')\n\
1649 1649 -p <path>=<act>\tDefine action for the specified path (<act>=yes/no)\n\
1650 1650 -r <file>\tRedirect stderr to <file>\n\
1651 1651 -s <sys>\tPermit the specified syscall (be careful)\n\
1652 1652 -s <sys>=<act>\tDefine action for the specified syscall (<act>=yes/no/file)\n\
1653 1653 -t <time>\tSet run time limit (seconds, fractions allowed)\n\
1654 1654 -T\t\tAllow syscalls for measuring run time\n\
1655 1655 -v\t\tBe verbose (use multiple times for even more verbosity)\n\
1656 1656 -w <time>\tSet wall clock time limit (seconds, fractions allowed)\n\
1657 1657 -x <time>\tSet extra timeout, before which a timing-out program is not yet killed,\n\
1658 1658 \t\tso that its real execution time is reported (seconds, fractions allowed)\n\
1659 + -A <opt>\tPass <opt> as additional argument to the <command>\n\
1660 + \t\tBe noted that this option will be appended after <arguments> respectively\n\
1659 1661 ");
1660 1662 exit(2);
1661 1663 }
1662 1664
1663 1665 int
1664 1666 main(int argc, char **argv)
1665 1667 {
1666 1668 int c;
1667 1669 uid_t uid;
1670 + char **prog_argv = xmalloc(sizeof(char*) * argc);
1671 + int prog_argc = 0;
1668 1672
1669 - while ((c = getopt(argc, argv, "a:c:eE:fi:k:m:M:o:p:r:s:t:Tvw:x:")) >= 0)
1673 + while ((c = getopt(argc, argv, "a:c:eE:fi:k:m:M:o:p:r:s:t:Tvw:x:A:")) >= 0)
1670 1674 switch (c)
1671 1675 {
1672 1676 case 'a':
1673 1677 file_access = atol(optarg);
1674 1678 break;
1675 1679 case 'c':
1676 1680 set_cwd = optarg;
1677 1681 break;
1678 1682 case 'e':
1679 1683 pass_environ = 1;
1680 1684 break;
1681 1685 case 'E':
1682 1686 if (!set_env_action(optarg))
1683 1687 usage();
1684 1688 break;
1685 1689 case 'f':
1686 1690 filter_syscalls++;
1687 1691 break;
1688 1692 case 'k':
1689 1693 stack_limit = atol(optarg);
1690 1694 break;
1691 1695 case 'i':
1692 1696 redir_stdin = optarg;
1693 1697 break;
1694 1698 case 'm':
1695 1699 memory_limit = atol(optarg);
1696 1700 break;
1697 1701 case 'M':
1698 1702 meta_open(optarg);
1699 1703 break;
1700 1704 case 'o':
1701 1705 redir_stdout = optarg;
1702 1706 break;
1703 1707 case 'p':
1704 1708 if (!set_path_action(optarg))
1705 1709 usage();
1706 1710 break;
1707 1711 case 'r':
1708 1712 redir_stderr = optarg;
1709 1713 break;
1710 1714 case 's':
1711 1715 if (!set_syscall_action(optarg))
1712 1716 usage();
1713 1717 break;
1714 1718 case 't':
1715 1719 timeout = 1000*atof(optarg);
1716 1720 break;
1717 1721 case 'T':
1718 1722 syscall_action[__NR_times] = A_YES;
1719 1723 break;
1720 1724 case 'v':
1721 1725 verbose++;
1722 1726 break;
1723 1727 case 'w':
1724 1728 wall_timeout = 1000*atof(optarg);
1725 1729 break;
1726 1730 case 'x':
1727 1731 extra_timeout = 1000*atof(optarg);
1732 + case 'A':
1733 + prog_argv[prog_argc++] = strdup(optarg);
1734 + break;
1728 1735 break;
1729 1736 default:
1730 1737 usage();
1731 1738 }
1732 1739 if (optind >= argc)
1733 1740 usage();
1734 1741
1735 1742 sanity_check();
1736 1743 uid = geteuid();
1737 1744 if (setreuid(uid, uid) < 0)
1738 1745 die("setreuid: %m");
1739 1746 box_pid = fork();
1740 1747 if (box_pid < 0)
1741 1748 die("fork: %m");
1742 - if (!box_pid)
1743 - box_inside(argc-optind, argv+optind);
1744 - else
1749 + if (!box_pid) {
1750 + int real_argc = prog_argc + argc - optind;
1751 + char **real_argv = xmalloc(sizeof(char*) * (real_argc));
1752 + for (int i = 0;i < argc-optind;i++)
1753 + real_argv[i] = strdup(argv[i+optind]);
1754 + for (int i = 0;i < prog_argc;i++)
1755 + real_argv[argc - optind + i] = strdup(prog_argv[i]);
1756 + box_inside(real_argc, real_argv);
1757 + } else
1745 1758 boxkeeper();
1746 1759 die("Internal error: fell over edge of the world");
1747 1760 }
@@ -59,103 +59,103
59 59 if test_num <= 0 || test_num > problem.num_tests
60 60 log "You have specified a wrong test number."
61 61 exit(127)
62 62 end
63 63
64 64 #####################################
65 65 # Set the relavant file names here. #
66 66 #####################################
67 67
68 68 input_file_name = "#{problem_home}/test_cases/#{test_num}/input-#{test_num}.txt"
69 69
70 70 #####################################
71 71
72 72 time_limit = problem.get_time_limit test_num
73 73 mem_limit = problem.get_mem_limit(test_num) * 1024
74 74
75 75 # Copy the input file.
76 76 #`cp #{problem_home}/test_cases/#{test_num}/#{input_file_name} .`
77 77
78 78 # check if box is there, if not, compile it!
79 79 if !File.exists?("#{problem_home}/script/box")
80 80 log "WARNING: Compiling box: to increase efficiency, it should be compile manually"
81 81 compile_box("#{problem_home}/script/box.cc",
82 82 "#{problem_home}/script/box")
83 83 end
84 84
85 85 # Hide PROBLEM_HOME
86 86 ENV['PROBLEM_HOME'] = nil
87 87 ENV['SOURCE_NAME'] = nil
88 88
89 89 # Run the program.
90 90 #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}"
91 91 #
92 92
93 93 JAVA_OPTION = "-s set_robust_list -s futex -s clone -s getppid -s clone -s wait4 -p /usr/bin/ -p ./"
94 94 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"
95 95 PYTHON_OPTION = "-p /usr/lib64/ -p /usr/local/lib64/ -p /usr/local/lib/ -p /usr/bin/ -p /lib64/ -p #{sandbox_dir}/#{program_name} -p ./#{program_name} -p #{sandbox_dir}/#{source_name} -s set_robust_list -s openat -s recvmsg -s connect -s socket -s sendto -s futex -E PYTHONNOUSERSITE=yes"
96 96 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"
97 97
98 98 case language
99 99 when "java"
100 100 # for java, extract the classname
101 101 # wne have to add additional systemcall and we don't check the mem limit (dunno how to fix...)
102 102 classname = 'DUMMY'
103 103 File.open(program_name,"r").each do |line|
104 104 classname = line
105 105 end
106 106 #for java, we cannot really check the memory limit...
107 - 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 #{classname} "
107 + 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} "
108 108 when "ruby"
109 109 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} "
110 110 when "python"
111 111 run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit*=2} -m #{mem_limit} #{PYTHON_OPTION} -i #{input_file_name} -o output.txt /usr/bin/python #{program_name} "
112 112 when "php"
113 - run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit*=2} #{PHP_OPTION} -i #{input_file_name} -o output.txt /usr/bin/php #{program_name} "
113 + run_command = "#{problem_home}/script/box -a 2 -f -T -t #{time_limit*=2} -m #{[128*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} "
114 114 else # for c++, pascal, we do the normal checking
115 115 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} "
116 116 end
117 117
118 118
119 119 log "Running test #{test_num}..."
120 120 log run_command
121 121 log
122 122 system(run_command,err: 'run_result')
123 123
124 124 # Restore PROBLEM_HOME
125 125 ENV['PROBLEM_HOME'] = problem_home
126 126
127 127 # Create the result file.
128 128 result_file = File.new("result", "w")
129 129 comment_file = File.new("comment", "w")
130 130
131 131 # Check if the program actually produced any output.
132 132 run_result_file = File.new("run_result", "r")
133 133 run_result = run_result_file.readlines
134 134 run_result_file.close
135 135
136 136 run_stat = run_result[run_result.length-1]
137 137 running_time = extract_time(run_stat)
138 138
139 139 report = lambda{ |status, points, comment|
140 140 result_file.write status.strip
141 141 result_file.write "\n"
142 142 result_file.write points.to_s.strip
143 143 result_file.write "\n"
144 144 result_file.write run_stat.strip
145 145 result_file.write "\n"
146 146 result_file.close
147 147 FileUtils.rm "run_result"
148 148 # `rm output.txt` --- keep the output
149 149
150 150 comment_file.write comment
151 151
152 152 # added for debuggin --- jittat
153 153 comment_file.write "--run-result--\n"
154 154 run_result.each do |l|
155 155 comment_file.write l
156 156 end
157 157
158 158 comment_file.close
159 159
160 160 log "Done!"
161 161 exit(0)
@@ -1,48 +1,48
1 - #!/usr/bin/ruby
1 + #!/usr/bin/env ruby
2 2
3 3 #
4 4 # This is a check script wrapper. It read all required information
5 5 # and call a real check script call REAL_CHECK_SCRIPT in directory
6 6 # [problem_home]/script
7 7 #
8 8
9 9 REAL_CHECK_SCRIPT = "<%= script_name %>"
10 10
11 11 # The REAL_CHECK_SCRIPT is called with:
12 12 #
13 13 # (script) <lang> <test-num> <in-file> <out-file> <ans-file> <full-score>
14 14 #
15 15 # and REAL_CHECK_SCRIPT's output to standard out is redirected to
16 16 # 'check_result' as required by normal check script.
17 17
18 18 problem_home = ENV['PROBLEM_HOME']
19 19 require "#{problem_home}/script/test_dsl.rb"
20 20
21 21 if ARGV.length < 2
22 22 puts "Usage: check <language> <test-number> [<output-file>]"
23 23 exit(0)
24 24 end
25 25
26 26 language = ARGV[0]
27 27 test_num = ARGV[1].to_i
28 28 if ARGV.length >= 3
29 29 output_file_name = ARGV[2]
30 30 else
31 31 output_file_name = "output.txt"
32 32 end
33 33
34 34 load "#{problem_home}/test_cases/all_tests.cfg"
35 35 problem = Problem.get_instance
36 36
37 37 answer_file_name = "#{problem_home}/test_cases/#{test_num}/answer-#{test_num}.txt"
38 38 input_file_name = "#{problem_home}/test_cases/#{test_num}/input-#{test_num}.txt"
39 39
40 40 score = problem.get_score(test_num)
41 41
42 42 cmd = "#{problem_home}/script/#{REAL_CHECK_SCRIPT} " +
43 43 "#{language} #{test_num} #{input_file_name} #{output_file_name} " +
44 44 "#{answer_file_name} #{score} > check_result"
45 45
46 46 #puts "wrapper-CMD: #{cmd}"
47 47
48 48 system(cmd)
@@ -1,49 +1,49
1 - #!/usr/bin/ruby
1 + #!/usr/bin/env ruby
2 2
3 3 problem_home = ENV['PROBLEM_HOME']
4 4 require "#{problem_home}/script/test_dsl.rb"
5 5
6 6 if ARGV.length < 2
7 7 puts "Usage: check <language> <test-number> [<output-file>]"
8 8 exit(0)
9 9 end
10 10
11 11 language = ARGV[0]
12 12 test_num = ARGV[1].to_i
13 13 if ARGV.length >= 3
14 14 output_file_name = ARGV[2]
15 15 else
16 16 output_file_name = "output.txt"
17 17 end
18 18
19 19 load "#{problem_home}/test_cases/all_tests.cfg"
20 20 problem = Problem.get_instance
21 21
22 22 output_file = File.new(output_file_name, "r")
23 23 answer_file = File.new("#{problem_home}/test_cases/#{test_num}/answer-#{test_num}.txt")
24 24 result_file = File.new("check_result", "w")
25 25
26 26 output_file_content = output_file.read
27 27 answer_file_content = answer_file.read
28 28
29 29 report_correct = lambda {
30 30 result_file.write "Correct\n"
31 31 result_file.write problem.get_score(test_num)
32 32 result_file.write "\n"
33 33 result_file.close
34 34 exit(0)
35 35 }
36 36
37 37 report_wrong = lambda {
38 38 result_file.write "Incorrect\n"
39 39 result_file.write "0\n"
40 40 result_file.close
41 41 exit(0)
42 42 }
43 43
44 44 ##################
45 45 # Your code here #
46 46 ##################
47 47 num_pattern = /^[0-9]*/
48 48 if (output_file_content =~ num_pattern) == nil
49 49 report_wrong.call
@@ -1,49 +1,49
1 - #!/usr/bin/ruby
1 + #!/usr/bin/env ruby
2 2
3 3 problem_home = ENV['PROBLEM_HOME']
4 4 require "#{problem_home}/script/test_dsl.rb"
5 5
6 6 if ARGV.length < 2
7 7 puts "Usage: check <language> <test-number> [<output-file>]"
8 8 exit(0)
9 9 end
10 10
11 11 language = ARGV[0]
12 12 test_num = ARGV[1].to_i
13 13 if ARGV.length >= 3
14 14 output_file_name = ARGV[2]
15 15 else
16 16 output_file_name = "output.txt"
17 17 end
18 18
19 19 load "#{problem_home}/test_cases/all_tests.cfg"
20 20 problem = Problem.get_instance
21 21
22 22 output_file = File.new(output_file_name, "r")
23 23 answer_file = File.new("#{problem_home}/test_cases/#{test_num}/answer-#{test_num}.txt")
24 24 result_file = File.new("check_result", "w")
25 25
26 26 output_file_content = output_file.read
27 27 answer_file_content = answer_file.read
28 28
29 29 report_correct = lambda {
30 30 result_file.write "Correct\n"
31 31 result_file.write problem.get_score(test_num)
32 32 result_file.write "\n"
33 33 result_file.close
34 34 exit(0)
35 35 }
36 36
37 37 report_wrong = lambda {
38 38 result_file.write "Incorrect\n"
39 39 result_file.write "0\n"
40 40 result_file.close
41 41 exit(0)
42 42 }
43 43
44 44 ##################
45 45 # Your code here #
46 46 ##################
47 47 num_pattern = /^[0-9]*/
48 48 if (output_file_content =~ num_pattern) == nil
49 49 report_wrong.call
@@ -1,49 +1,49
1 - #!/usr/bin/ruby
1 + #!/usr/bin/env ruby
2 2
3 3 problem_home = ENV['PROBLEM_HOME']
4 4 require "#{problem_home}/script/test_dsl.rb"
5 5
6 6 if ARGV.length < 2
7 7 puts "Usage: check <language> <test-number> [<output-file>]"
8 8 exit(0)
9 9 end
10 10
11 11 language = ARGV[0]
12 12 test_num = ARGV[1].to_i
13 13 if ARGV.length >= 3
14 14 output_file_name = ARGV[2]
15 15 else
16 16 output_file_name = "output.txt"
17 17 end
18 18
19 19 load "#{problem_home}/test_cases/all_tests.cfg"
20 20 problem = Problem.get_instance
21 21
22 22 output_file = File.new(output_file_name, "r")
23 23 answer_file = File.new("#{problem_home}/test_cases/#{test_num}/answer-#{test_num}.txt")
24 24 result_file = File.new("check_result", "w")
25 25
26 26 output_file_content = output_file.read
27 27 answer_file_content = answer_file.read
28 28
29 29 report_correct = lambda {
30 30 result_file.write "Correct\n"
31 31 result_file.write problem.get_score(test_num)
32 32 result_file.write "\n"
33 33 result_file.close
34 34 exit(0)
35 35 }
36 36
37 37 report_wrong = lambda {
38 38 result_file.write "Incorrect\n"
39 39 result_file.write "0\n"
40 40 result_file.close
41 41 exit(0)
42 42 }
43 43
44 44 ##################
45 45 # Your code here #
46 46 ##################
47 47 num_pattern = /^[0-9]*/
48 48 if (output_file_content =~ num_pattern) == nil
49 49 report_wrong.call
@@ -157,170 +157,170
157 157 protected
158 158
159 159 def create_normal_submission_mock_from_file(source_fname)
160 160 create_submission_from_file(1, @user_user1, @problem_test_normal, source_fname)
161 161 end
162 162
163 163 end
164 164
165 165 describe "A grader engine, when grading test requests" do
166 166
167 167 include GraderEngineHelperMethods
168 168
169 169 before(:each) do
170 170 @config = Grader::Configuration.get_instance
171 171 @engine = Grader::Engine.new(:room_maker => Grader::TestRequestRoomMaker.new,
172 172 :reporter => Grader::TestRequestReporter.new)
173 173 init_sandbox
174 174 end
175 175
176 176 it "should report error if there is no problem template" do
177 177 problem = stub(Problem,
178 178 :id => 1, :name => 'nothing')
179 179 grader_should(:grade => 'test1_correct.c',
180 180 :on => problem,
181 181 :with => 'in1.txt',
182 182 :and_report => {
183 183 :graded_at= => nil,
184 184 :compiler_message= => '',
185 185 :grader_comment= => '',
186 186 :running_stat= => /template not found/,
187 187 :running_time= => nil,
188 188 :exit_status= => nil,
189 189 :memory_usage= => nil,
190 190 :save => nil})
191 191 end
192 192
193 193 it "should run test request and produce output file" do
194 194 problem = stub(Problem,
195 195 :id => 1, :name => 'test_normal')
196 196 grader_should(:grade => 'test1_correct.c',
197 197 :on => problem,
198 198 :with => 'in1.txt',
199 199 :and_report => {
200 200 :graded_at= => nil,
201 201 :compiler_message= => '',
202 202 :grader_comment= => '',
203 203 :running_stat= => /0.0\d* sec./,
204 204 :output_file_name= => lambda { |fname|
205 - File.exists?(fname).should be_true
205 + File.exists?(fname).should be true
206 206 },
207 207 :running_time= => nil,
208 208 :exit_status= => nil,
209 209 :memory_usage= => nil,
210 210 :save => nil})
211 211 end
212 212
213 213 it "should clean up problem directory after running test request" do
214 214 problem = stub(Problem,
215 215 :id => 1, :name => 'test_normal')
216 216 grader_should(:grade => 'test1_correct.c',
217 217 :on => problem,
218 218 :with => 'in1.txt',
219 219 :and_report => {
220 220 :graded_at= => nil,
221 221 :compiler_message= => '',
222 222 :grader_comment= => '',
223 223 :running_stat= => nil,
224 224 :output_file_name= => nil,
225 225 :running_time= => nil,
226 226 :exit_status= => nil,
227 227 :memory_usage= => nil,
228 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 230 end
231 231
232 232 it "should compile test request with error and report compilation error" do
233 233 problem = stub(Problem,
234 234 :id => 1, :name => 'test_normal')
235 235 grader_should(:grade => 'test1_compile_error.c',
236 236 :on => problem,
237 237 :with => 'in1.txt',
238 238 :and_report => {
239 239 :graded_at= => nil,
240 240 :compiler_message= => /.+/,
241 241 :grader_comment= => /[Cc]ompil.*error/,
242 242 :running_stat= => '',
243 243 :save => nil})
244 244 end
245 245
246 246 it "should report exit status" do
247 247 problem = stub(Problem,
248 248 :id => 1, :name => 'test_normal')
249 249 grader_should(:grade => 'add_nonzero_exit_status.c',
250 250 :on => problem,
251 251 :with => 'in1.txt',
252 252 :and_report => {
253 253 :graded_at= => nil,
254 254 :compiler_message= => '',
255 255 :grader_comment= => '',
256 256 :running_stat= => /[Ee]xit.*status.*10.*0\.0\d* sec/m,
257 257 :output_file_name= => lambda { |fname|
258 - File.exists?(fname).should be_true
258 + File.exists?(fname).should be true
259 259 },
260 260 :running_time= => nil,
261 261 :exit_status= => /10/,
262 262 :memory_usage= => nil,
263 263 :save => nil})
264 264 end
265 265
266 266 it "should produce running statistics for normal submission" do
267 267 problem = stub(Problem,
268 268 :id => 1, :name => 'test_normal')
269 269 grader_should(:grade => 'test_run_stat.c',
270 270 :on => problem,
271 271 :with => 'in1.txt',
272 272 :and_report => {
273 273 :graded_at= => nil,
274 274 :compiler_message= => '',
275 275 :grader_comment= => '',
276 276 :running_stat= => nil,
277 277 :output_file_name= => lambda { |fname|
278 - File.exists?(fname).should be_true
278 + File.exists?(fname).should be true
279 279 },
280 280 :running_time= => lambda { |t|
281 281 (t>=0.14) and (t<=0.16)
282 282 },
283 283 :exit_status= => nil,
284 284 :memory_usage= => lambda { |s|
285 285 (s>=500) and (s<=1000)
286 286 },
287 287 :save => nil})
288 288 end
289 289
290 290 protected
291 291 def grader_should(args)
292 292 @user1 = stub(User,
293 293 :id => 1, :login => 'user1')
294 294
295 295 problem = args[:on]
296 296 input_file = @config.test_request_input_base_dir + "/" + args[:with]
297 297
298 298 submission =
299 299 create_submission_from_file(1, @user1, args[:on], args[:grade])
300 300
301 301 test_request = stub(TestRequest,
302 302 :id => 1,
303 303 :user => @user1,
304 304 :problem => problem,
305 305 :submission => submission,
306 306 :input_file_name => input_file,
307 307 :language => submission.language,
308 308 :problem_name => problem.name)
309 309
310 310 expectations = args[:and_report]
311 311
312 312 expectations.each do |key,val|
313 313 if val==nil
314 314 test_request.should_receive(key)
315 315 elsif val.class == Proc
316 316 test_request.should_receive(key) { |fname|
317 317 val.call(fname)
318 318 }
319 319 else
320 320 test_request.should_receive(key).with(val)
321 321 end
322 322 end
323 323
324 324 @engine.grade(test_request)
325 325 end
326 326
You need to be logged in to leave comments. Login now