summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPrabhu Ramachandran2013-07-29 23:58:29 -0700
committerPrabhu Ramachandran2013-07-29 23:58:29 -0700
commit70b73660f9c10174e318d570a820ca0cc01f8d5f (patch)
tree26df2b155c4db789dabd53f309057ac0aaca5f04
parentee64cfe58c42540d0736cc32d3acd36ab7a6d31d (diff)
parentb522a1ba1c1edff7648c6c7d69fa2867a08b4100 (diff)
downloadonline_test-70b73660f9c10174e318d570a820ca0cc01f8d5f.tar.gz
online_test-70b73660f9c10174e318d570a820ca0cc01f8d5f.tar.bz2
online_test-70b73660f9c10174e318d570a820ca0cc01f8d5f.zip
Merge pull request #14 from prathamesh920/fresh_java
fresh java
-rwxr-xr-xtestapp/code_server.py158
-rw-r--r--testapp/exam/forms.py1
-rw-r--r--testapp/exam/models.py1
-rw-r--r--testapp/exam/views.py2
-rw-r--r--testapp/exam/xmlrpc_clients.py1
-rw-r--r--testapp/java_files/main_array_sum.java36
-rw-r--r--testapp/java_files/main_fact.java29
-rw-r--r--testapp/java_files/main_great.java39
-rw-r--r--testapp/java_files/main_hello_name.java29
-rw-r--r--testapp/java_files/main_palindrome.java29
-rw-r--r--testapp/java_files/main_square.java32
-rw-r--r--testapp/test_server.py114
12 files changed, 458 insertions, 13 deletions
diff --git a/testapp/code_server.py b/testapp/code_server.py
index c853753..8b3f8f1 100755
--- a/testapp/code_server.py
+++ b/testapp/code_server.py
@@ -353,7 +353,7 @@ class CodeServer(object):
return success, err
def _compile_command(self, cmd, *args, **kw):
- """Compiles C/C++ code and returns errors if any.
+ """Compiles C/C++/java code and returns errors if any.
Run a command in a subprocess while blocking, the process is killed
if it takes more than 2 seconds to run. Return the Popen object, the
stderr.
@@ -370,6 +370,7 @@ class CodeServer(object):
raise
return proc_compile, err
+
def _check_c_cpp_code(self, ref_code_path, submit_code_path):
""" Function validates student code using instructor code as
reference.The first argument ref_code_path, is the path to
@@ -504,6 +505,161 @@ class CodeServer(object):
return success, err
+ def run_java_code(self, answer, test_code, in_dir=None):
+ """Tests given java code (`answer`) with the `test_code` supplied.
+
+ The testcode is a path to the reference code.
+ The reference code will call the function submitted by the student.
+ The reference code will check for the expected output.
+
+ If the path's start with a "/" then we assume they are absolute paths.
+ If not, we assume they are relative paths w.r.t. the location of this
+ code_server script.
+
+ If the optional `in_dir` keyword argument is supplied it changes the
+ directory to that directory (it does not change it back to the original
+ when done).
+
+ Returns
+ -------
+
+ A tuple: (success, error message).
+
+ """
+ if in_dir is not None and isdir(in_dir):
+ os.chdir(in_dir)
+
+ # The file extension must be .java
+ # The class name and file name must be same in java
+ submit_f = open('Test.java', 'w')
+ submit_f.write(answer.lstrip())
+ submit_f.close()
+ submit_path = abspath(submit_f.name)
+
+ ref_path = test_code.strip()
+ if not ref_path.startswith('/'):
+ ref_path = join(MY_DIR, ref_path)
+
+ # Add a new signal handler for the execution of this code.
+ old_handler = signal.signal(signal.SIGALRM, timeout_handler)
+ signal.alarm(SERVER_TIMEOUT)
+
+ # Do whatever testing needed.
+ success = False
+ try:
+ success, err = self._check_java_code(ref_path, submit_path)
+ except TimeoutException:
+ err = self.timeout_msg
+ except:
+ type, value = sys.exc_info()[:2]
+ err = "Error: {0}".format(repr(value))
+ finally:
+ # Set back any original signal handler.
+ signal.signal(signal.SIGALRM, old_handler)
+
+ # Delete the created file.
+ os.remove(submit_path)
+
+ # Cancel the signal if any, see signal.alarm documentation.
+ signal.alarm(0)
+
+ # Put us back into the server pool queue since we are free now.
+ self.queue.put(self.port)
+
+ return success, err
+
+ def _check_java_code(self, ref_code_path, submit_code_path):
+ """ Function validates student code using instructor code as
+ reference.The first argument ref_code_path, is the path to
+ instructor code, it is assumed to have executable permission.
+ The second argument submit_code_path, is the path to the student
+ code, it is assumed to have executable permission.
+
+ Returns
+ --------
+
+ returns (True, "Correct answer") : If the student function returns
+ expected output when called by reference code.
+
+ returns (False, error_msg): If the student function fails to return
+ expected output when called by reference code.
+
+ Returns (False, error_msg): If mandatory arguments are not files or
+ if the required permissions are not given to the file(s).
+
+ """
+ if not isfile(ref_code_path):
+ return False, "No file at %s" % ref_code_path
+ if not isfile(submit_code_path):
+ return False, 'No file at %s' % submit_code_path
+
+ success = False
+ compile_command = "javac %s" % (submit_code_path)
+ ret = self._compile_command(compile_command)
+ proc, stdnt_stderr = ret
+ stdnt_stderr = self._remove_null_substitute_char(stdnt_stderr)
+
+ # Only if compilation is successful, the program is executed
+ # And tested with testcases
+ if stdnt_stderr == '':
+ student_directory = os.getcwd() + '/'
+ student_file_name = "Test"
+ compile_main = "javac %s -classpath %s -d %s" % (ref_code_path,
+ student_directory,
+ student_directory)
+ ret = self._compile_command(compile_main)
+ proc, main_err = ret
+ main_err = self._remove_null_substitute_char(main_err)
+
+ if main_err == '':
+ main_file_name = (ref_code_path.split('/')[-1]).split('.')[0]
+ run_command = "java -cp %s %s" % (student_directory,
+ main_file_name)
+ ret = self._run_command(run_command,
+ stdin=None,
+ shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ proc, stdout, stderr = ret
+ if proc.returncode == 0:
+ success, err = True, "Correct answer"
+ else:
+ err = stdout + "\n" + stderr
+ success = False
+ os.remove("%s%s.class" % (student_directory, main_file_name))
+ else:
+ err = "Error:\n"
+ try:
+ error_lines = main_err.splitlines()
+ for e in error_lines:
+ if ':' in e:
+ err = err + "\n" + e.split(":", 1)[1]
+ else:
+ err = err + "\n" + e
+ except:
+ err = err + "\n" + main_err
+ os.remove("%s%s.class" % (student_directory, student_file_name))
+ else:
+ err = "Compilation Error:\n"
+ try:
+ error_lines = stdnt_stderr.splitlines()
+ for e in error_lines:
+ if ':' in e:
+ err = err + "\n" + e.split(":", 1)[1]
+ else:
+ err = err + "\n" + e
+ except:
+ err = err + "\n" + stdnt_stderr
+ return success, err
+
+ def _remove_null_substitute_char(self, string):
+ """Returns a string without any null and substitute characters"""
+ stripped = ""
+ for c in string:
+ if ord(c) is not 26 and ord(c) is not 0:
+ stripped = stripped + c
+ return ''.join(stripped)
+
def run(self):
"""Run XMLRPC server, serving our methods.
"""
diff --git a/testapp/exam/forms.py b/testapp/exam/forms.py
index 1b60a71..8506de2 100644
--- a/testapp/exam/forms.py
+++ b/testapp/exam/forms.py
@@ -18,6 +18,7 @@ QUESTION_TYPE_CHOICES = (
("mcq", "MCQ"),
("C", "C Language"),
("C++", "C++ Language"),
+ ("java", "Java Language"),
)
UNAME_CHARS = letters + "._" + digits
diff --git a/testapp/exam/models.py b/testapp/exam/models.py
index fac01ec..5d6e2cf 100644
--- a/testapp/exam/models.py
+++ b/testapp/exam/models.py
@@ -20,6 +20,7 @@ QUESTION_TYPE_CHOICES = (
("mcq", "MultipleChoice"),
("C", "C Language"),
("C++", "C++ Language"),
+ ("java", "Java Language"),
)
################################################################################
diff --git a/testapp/exam/views.py b/testapp/exam/views.py
index 4c47004..dd11346 100644
--- a/testapp/exam/views.py
+++ b/testapp/exam/views.py
@@ -963,7 +963,7 @@ def user_data(request, username):
"""Render user data."""
current_user = request.user
- if not current_user.is_authenticated() or not is_moderator(user):
+ if not current_user.is_authenticated() or not is_moderator(current_user):
raise Http404('You are not allowed to view this page!')
data = get_user_data(username)
diff --git a/testapp/exam/xmlrpc_clients.py b/testapp/exam/xmlrpc_clients.py
index b846212..cc21e62 100644
--- a/testapp/exam/xmlrpc_clients.py
+++ b/testapp/exam/xmlrpc_clients.py
@@ -25,6 +25,7 @@ class CodeServerProxy(object):
"bash": 'run_bash_code',
"C": "run_c_code",
"C++": "run_cplus_code",
+ "java": "run_java_code",
}
def run_code(self, answer, test_code, user_dir, language):
diff --git a/testapp/java_files/main_array_sum.java b/testapp/java_files/main_array_sum.java
new file mode 100644
index 0000000..5eae299
--- /dev/null
+++ b/testapp/java_files/main_array_sum.java
@@ -0,0 +1,36 @@
+class main_array_sum
+{
+ public static <E> void check(E expect, E result)
+ {
+ if(result.equals(expect))
+ {
+ System.out.println("Correct:\nOutput expected "+expect+" and got "+result);
+ }
+ else
+ {
+ System.out.println("Incorrect:\nOutput expected "+expect+" but got "+result);
+ System.exit(1);
+ }
+ }
+ public static void main(String arg[])
+ {
+ int result;
+ Test t = new Test();
+ int x[] = {0,0,0,0,0};
+ result = t.array_sum(x);
+ System.out.println("Input submitted to the function: {0,0,0,0,0}");
+ check(0, result);
+ int a[] = {1,2,3,4,5};
+ result = t.array_sum(a);
+ System.out.println("Input submitted to the function: {1,2,3,4,5}");
+ check(15, result);
+ int b[] = {1,2,3,0,0};
+ result = t.array_sum(b);
+ System.out.println("Input submitted to the function: {1,2,3,0,0}");
+ check(6, result);
+ int c[] = {1,1,1,1,1};
+ result = t.array_sum(c);
+ System.out.println("Input submitted to the function: {1,1,1,1,1}");
+ check(5, result);
+ }
+}
diff --git a/testapp/java_files/main_fact.java b/testapp/java_files/main_fact.java
new file mode 100644
index 0000000..325dab6
--- /dev/null
+++ b/testapp/java_files/main_fact.java
@@ -0,0 +1,29 @@
+class main_fact
+{
+ public static <E> void check(E expect, E result)
+ {
+ if(result.equals(expect))
+ {
+ System.out.println("Correct:\nOutput expected "+expect+" and got "+result);
+ }
+ else
+ {
+ System.out.println("Incorrect:\nOutput expected "+expect+" but got "+result);
+ System.exit(1);
+ }
+ }
+ public static void main(String arg[])
+ {
+ Test t = new Test();
+ int result;
+ result = t.factorial(0);
+ System.out.println("Input submitted to the function: 0");
+ check(1, result);
+ result = t.factorial(3);
+ System.out.println("Input submitted to the function: 3");
+ check(6, result);
+ result = t.factorial(4);
+ System.out.println("Input submitted to the function: 4");
+ check(24, result);
+ }
+}
diff --git a/testapp/java_files/main_great.java b/testapp/java_files/main_great.java
new file mode 100644
index 0000000..4bfcb1f
--- /dev/null
+++ b/testapp/java_files/main_great.java
@@ -0,0 +1,39 @@
+class main_great
+{
+ public static <E> void check(E expect, E result)
+ {
+ if(result.equals(expect))
+ {
+ System.out.println("Correct:\nOutput expected "+expect+" and got "+result);
+ }
+ else
+ {
+ System.out.println("Incorrect:\nOutput expected "+expect+" but got "+result);
+ System.exit(1);
+ }
+ }
+ public static void main(String arg[])
+ {
+ Test t = new Test();
+ int result;
+ result = t.greatest(1, 3, 4);
+ System.out.println("Input submitted to the function: 1, 3, 4");
+ check(4, result);
+ result = t.greatest(5, 10, 3);
+ System.out.println("Input submitted to the function: 5, 10, 3");
+ check(10, result);
+ result = t.greatest(6, 1, 4);
+ System.out.println("Input submitted to the function: 6, 1, 4");
+ check(6, result);
+ result = t.greatest(6, 11, 14);
+ System.out.println("Input submitted to the function: 6, 11, 14");
+ check(14, result);
+ result = t.greatest(3, 31, 4);
+ System.out.println("Input submitted to the function: 3, 31, 4");
+ check(31, result);
+ result = t.greatest(26, 13, 3);
+ System.out.println("Input submitted to the function: 26, 13, 3");
+ check(26, result);
+
+ }
+}
diff --git a/testapp/java_files/main_hello_name.java b/testapp/java_files/main_hello_name.java
new file mode 100644
index 0000000..84bb282
--- /dev/null
+++ b/testapp/java_files/main_hello_name.java
@@ -0,0 +1,29 @@
+class main_hello_name
+{
+ public static <E> void check(E expect, E result)
+ {
+ if(result.equals(expect))
+ {
+ System.out.println("Correct:\nOutput expected "+expect+" and got "+result);
+ }
+ else
+ {
+ System.out.println("Incorrect:\nOutput expected "+expect+" but got "+result);
+ System.exit(1);
+ }
+ }
+ public static void main(String arg[])
+ {
+ Test t = new Test();
+ String result;
+ result = t.hello_name("Raj");
+ System.out.println("Input submitted to the function: 'Raj'");
+ check("hello Raj", result);
+ result = t.hello_name("Pratham");
+ System.out.println("Input submitted to the function: 'Pratham'");
+ check("hello Pratham", result);
+ result = t.hello_name("Ram");
+ System.out.println("Input submitted to the function: 'Ram'");
+ check("hello Ram", result);
+ }
+}
diff --git a/testapp/java_files/main_palindrome.java b/testapp/java_files/main_palindrome.java
new file mode 100644
index 0000000..bd463e5
--- /dev/null
+++ b/testapp/java_files/main_palindrome.java
@@ -0,0 +1,29 @@
+class main_palindrome
+{
+ public static <E> void check(E expect, E result)
+ {
+ if(result.equals(expect))
+ {
+ System.out.println("Correct\n:Output expected "+expect+" and got "+result);
+ }
+ else
+ {
+ System.out.println("Incorrect:\nOutput expected "+expect+" but got "+result);
+ System.exit(1);
+ }
+ }
+ public static void main(String arg[])
+ {
+ Test t = new Test();
+ boolean result;
+ result= t.palindrome(123);
+ System.out.println("Input submitted to the function: 123");
+ check(false, result);
+ result = t.palindrome(151);
+ System.out.println("Input submitted to the function: 151");
+ check(true, result);
+ result = t.palindrome(23432);
+ System.out.println("Input submitted to the function: 23432");
+ check(true, result);
+ }
+}
diff --git a/testapp/java_files/main_square.java b/testapp/java_files/main_square.java
new file mode 100644
index 0000000..5cb8c35
--- /dev/null
+++ b/testapp/java_files/main_square.java
@@ -0,0 +1,32 @@
+class main_square
+{
+ public static <E> void check(E expect, E result)
+ {
+ if(result.equals(expect))
+ {
+ System.out.println("Correct:\nOutput expected "+expect+" and got "+result);
+ }
+ else
+ {
+ System.out.println("Incorrect:\nOutput expected "+expect+" but got "+result);
+ System.exit(1);
+ }
+ }
+ public static void main(String arg[])
+ {
+ Test t = new Test();
+ int result, input, output;
+ input = 0; output = 0;
+ result = t.square_num(input);
+ System.out.println("Input submitted to the function: "+input);
+ check(output, result);
+ input = 5; output = 25;
+ result = t.square_num(input);
+ System.out.println("Input submitted to the function: "+input);
+ check(output, result);
+ input = 6; output = 36;
+ result = t.square_num(input);
+ System.out.println("Input submitted to the function: "+input);
+ check(output, result);
+ }
+}
diff --git a/testapp/test_server.py b/testapp/test_server.py
index 5c88d73..2a17739 100644
--- a/testapp/test_server.py
+++ b/testapp/test_server.py
@@ -44,14 +44,16 @@ def test_c():
int ad(int a, int b)
{return a+b;}
"""
- result = code_server.run_code(src, 'c_cpp_files/main.cpp', '/tmp', language="C")
+ result = code_server.run_code(src, 'c_cpp_files/main.cpp',
+ '/tmp', language="C")
check_result(result, 'error')
src = """
int add(int a, int b)
{return a+b}
"""
- result = code_server.run_code(src, 'c_cpp_files/main.cpp', '/tmp', language="C")
+ result = code_server.run_code(src, 'c_cpp_files/main.cpp',
+ '/tmp', language="C")
check_result(result, 'compilation error')
src = """
@@ -59,14 +61,16 @@ def test_c():
{while(1>0){}
return a+b;}
"""
- result = code_server.run_code(src, 'c_cpp_files/main.cpp', '/tmp', language="C")
+ result = code_server.run_code(src, 'c_cpp_files/main.cpp',
+ '/tmp', language="C")
check_result(result, 'more than')
src = """
int add(int a, int b)
{return a+b;}
"""
- result = code_server.run_code(src, 'c_cpp_files/main.cpp', '/tmp', language="C")
+ result = code_server.run_code(src, 'c_cpp_files/main.cpp',
+ '/tmp', language="C")
check_result(result, 'correct answer')
src = """
@@ -74,7 +78,8 @@ def test_c():
int add(int a, int b)
{printf("All Correct");}
"""
- result = code_server.run_code(src, 'c_cpp_files/main.cpp', '/tmp', language="C")
+ result = code_server.run_code(src, 'c_cpp_files/main.cpp',
+ '/tmp', language="C")
check_result(result, 'incorrect')
@@ -86,8 +91,9 @@ def test_cpp():
return a+b
}
"""
- result = code_server.run_code(src, 'c_cpp_files/main.cpp', '/tmp', language="C++")
- check_result(result, 'compilation error')
+ result = code_server.run_code(src, 'c_cpp_files/main.cpp',
+ '/tmp', language="C++")
+ check_result(result, 'error')
src = """
int add(int a, int b)
@@ -95,7 +101,8 @@ def test_cpp():
return a+b;
}
"""
- result = code_server.run_code(src, 'c_cpp_files/main.cpp', '/tmp', language="C++")
+ result = code_server.run_code(src, 'c_cpp_files/main.cpp',
+ '/tmp', language="C++")
check_result(result, 'correct answer')
src = """
@@ -104,7 +111,8 @@ def test_cpp():
return a+b;
}
"""
- result = code_server.run_code(src, 'c_cpp_files/main.cpp', '/tmp', language="C++")
+ result = code_server.run_code(src, 'c_cpp_files/main.cpp',
+ '/tmp', language="C++")
check_result(result, 'error')
src = """
@@ -115,9 +123,92 @@ def test_cpp():
return a+b;
}
"""
- result = code_server.run_code(src, 'c_cpp_files/main.cpp', '/tmp', language="C++")
+ result = code_server.run_code(src, 'c_cpp_files/main.cpp',
+ '/tmp', language="C++")
+ check_result(result, 'more than')
+
+
+def test_java():
+ """Test if server runs java code as expected."""
+ src = """
+ class Test
+ {
+ int square_num(int a)
+ {
+ return a*a;
+ }
+ }
+ """
+ result = code_server.run_code(src, 'java_files/main_square.java',
+ '/tmp', language="java")
+ check_result(result, 'correct answer')
+
+ src = """
+ class Test
+ {
+ int square_num(int a)
+ {
+ return b*b;
+ }
+ }
+ """
+ result = code_server.run_code(src, 'java_files/main_square.java',
+ '/tmp', language="java")
+ check_result(result, 'error')
+
+ src = """
+ class Test
+ {
+ int square_nu(int a)
+ {
+ return a*a;
+ }
+ }
+ """
+ result = code_server.run_code(src, 'java_files/main_square.java',
+ '/tmp', language="java")
+ check_result(result, 'error')
+
+ src = """
+ class Test
+ {
+ int square_num(int a)
+ {
+ while(0==0)
+ {}
+ }
+ }
+ """
+ result = code_server.run_code(src, 'java_files/main_square.java',
+ '/tmp', language="java")
check_result(result, 'more than')
+ src = """
+ class Test
+ {
+ int square_num(int a)
+ {
+ return a+b
+ }
+ }
+ """
+ result = code_server.run_code(src, 'java_files/main_square.java',
+ '/tmp', language="java")
+ check_result(result, 'error')
+
+ src = """
+ class Test
+ {
+ int square_num(int a)
+ {
+ return a+b
+
+ """
+ result = code_server.run_code(src, 'java_files/main_square.java',
+ '/tmp', language="java")
+ check_result(result, 'error')
+
+
def test_bash():
"""Test if server runs Bash code as expected."""
src = """
@@ -133,7 +224,7 @@ def test_bash():
[[ $# -eq 2 ]] && echo $(( $1 - $2 )) && exit $(( $1 - $2 ))
"""
result = code_server.run_code(src,
- 'docs/sample.sh\ndocs/sample.args', '/tmp', language="bash")
+ 'docs/sample.sh\ndocs/sample.args', '/tmp', language="bash")
check_result(result, 'error')
src = """\
@@ -165,3 +256,4 @@ if __name__ == '__main__':
test_bash()
test_c()
test_cpp()
+ test_java()