summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml5
-rw-r--r--requirements/requirements-common.txt (renamed from requirements.txt)2
-rw-r--r--requirements/requirements-py2.txt2
-rw-r--r--requirements/requirements-py3.txt2
-rw-r--r--setup.py25
-rw-r--r--yaksh/bash_code_evaluator.py5
-rw-r--r--yaksh/bash_stdio_evaluator.py7
-rw-r--r--yaksh/code_evaluator.py17
-rwxr-xr-xyaksh/code_server.py14
-rw-r--r--yaksh/cpp_code_evaluator.py29
-rw-r--r--yaksh/cpp_stdio_evaluator.py12
-rw-r--r--[-rwxr-xr-x]yaksh/evaluator_tests/test_bash_evaluation.py27
-rw-r--r--[-rwxr-xr-x]yaksh/evaluator_tests/test_c_cpp_evaluation.py49
-rw-r--r--yaksh/evaluator_tests/test_code_evaluation.py3
-rw-r--r--[-rwxr-xr-x]yaksh/evaluator_tests/test_java_evaluation.py92
-rw-r--r--[-rwxr-xr-x]yaksh/evaluator_tests/test_python_evaluation.py137
-rw-r--r--yaksh/evaluator_tests/test_scilab_evaluation.py19
-rw-r--r--yaksh/forms.py6
-rw-r--r--yaksh/java_code_evaluator.py12
-rw-r--r--yaksh/java_stdio_evaluator.py9
-rw-r--r--yaksh/language_registry.py8
-rw-r--r--yaksh/models.py29
-rw-r--r--yaksh/python_assertion_evaluator.py13
-rw-r--r--yaksh/python_stdio_evaluator.py21
-rw-r--r--yaksh/scilab_code_evaluator.py9
-rw-r--r--yaksh/settings.py22
-rw-r--r--yaksh/stdio_evaluator.py12
-rw-r--r--yaksh/templatetags/custom_filters.py1
-rw-r--r--yaksh/test.txt1
-rw-r--r--yaksh/test_models.py18
-rw-r--r--yaksh/tests/test_code_server.py8
-rw-r--r--yaksh/views.py7
-rw-r--r--yaksh/xmlrpc_clients.py15
33 files changed, 390 insertions, 248 deletions
diff --git a/.travis.yml b/.travis.yml
index 3484d2d..c47785e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,6 +2,7 @@ language: python
python:
- "2.7"
+ - "3.5"
env:
- DJANGO=1.8.13
@@ -9,12 +10,8 @@ env:
# command to install dependencies
install:
- - pip install tornado
- pip install git+https://github.com/FOSSEE/online_test.git#egg=yaksh-0.1
- pip install -q Django==$DJANGO
- - pip install -q pytz==2016.4
- - pip install -q python-social-auth==0.2.19
- - pip install selenium
before_install:
- sudo apt-get update -qq
diff --git a/requirements.txt b/requirements/requirements-common.txt
index bea0017..8138a4f 100644
--- a/requirements.txt
+++ b/requirements/requirements-common.txt
@@ -1,6 +1,6 @@
django==1.9.5
-mysql-python==1.2.5
django-taggit==0.18.1
pytz==2016.4
python-social-auth==0.2.19
tornado
+selenium
diff --git a/requirements/requirements-py2.txt b/requirements/requirements-py2.txt
new file mode 100644
index 0000000..38777a1
--- /dev/null
+++ b/requirements/requirements-py2.txt
@@ -0,0 +1,2 @@
+-r requirements-common.txt
+mysql-python==1.2.5
diff --git a/requirements/requirements-py3.txt b/requirements/requirements-py3.txt
new file mode 100644
index 0000000..3d13335
--- /dev/null
+++ b/requirements/requirements-py3.txt
@@ -0,0 +1,2 @@
+-r requirements-common.txt
+mysqlclient==1.3.9
diff --git a/setup.py b/setup.py
index 0c0b7f9..3ab362a 100644
--- a/setup.py
+++ b/setup.py
@@ -1,11 +1,28 @@
import os
from setuptools import setup, find_packages
+import sys
README = open(os.path.join(os.path.dirname(__file__), 'README.md')).read()
# allow setup.py to be run from any path
os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir)))
+install_requires=[
+ 'django==1.9.5',
+ 'django-taggit==0.18.1',
+ 'pytz==2016.4',
+ 'python-social-auth==0.2.19',
+ 'tornado',
+]
+if sys.version_info[:2] == (2, 7):
+ install_requires+=[
+ 'mysql-python==1.2.5'
+]
+if sys.version_info[0] >= 3:
+ install_requires+=[
+ 'mysqlclient==1.3.9'
+]
+
setup(
name='yaksh',
author='Python Team at FOSSEE, IIT Bombay',
@@ -22,13 +39,7 @@ setup(
},
description='A django app to conduct online tests.',
long_description=README,
- install_requires=[
- 'django==1.9.5',
- 'mysql-python==1.2.5',
- 'django-taggit==0.18.1',
- 'pytz==2016.4',
- 'python-social-auth==0.2.19'
- ],
+ install_requires=install_requires,
classifiers=[
'Development Status :: 4 - Beta',
'Environment :: Web Environment',
diff --git a/yaksh/bash_code_evaluator.py b/yaksh/bash_code_evaluator.py
index bce7f07..e148fa8 100644
--- a/yaksh/bash_code_evaluator.py
+++ b/yaksh/bash_code_evaluator.py
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+from __future__ import unicode_literals
import traceback
import pwd
import os
@@ -8,8 +9,8 @@ import subprocess
import importlib
# local imports
-from code_evaluator import CodeEvaluator
-from file_utils import copy_files, delete_files
+from .code_evaluator import CodeEvaluator
+from .file_utils import copy_files, delete_files
class BashCodeEvaluator(CodeEvaluator):
diff --git a/yaksh/bash_stdio_evaluator.py b/yaksh/bash_stdio_evaluator.py
index 8ff0743..e5e0da6 100644
--- a/yaksh/bash_stdio_evaluator.py
+++ b/yaksh/bash_stdio_evaluator.py
@@ -1,11 +1,12 @@
#!/usr/bin/env python
+from __future__ import unicode_literals
import subprocess
import os
from os.path import isfile
-# local imports
-from stdio_evaluator import StdIOEvaluator
-from file_utils import copy_files, delete_files
+#local imports
+from .stdio_evaluator import StdIOEvaluator
+from .file_utils import copy_files, delete_files
class BashStdioEvaluator(StdIOEvaluator):
diff --git a/yaksh/code_evaluator.py b/yaksh/code_evaluator.py
index 8a9b7a6..870a67f 100644
--- a/yaksh/code_evaluator.py
+++ b/yaksh/code_evaluator.py
@@ -1,5 +1,6 @@
+#!/usr/bin/env python
+from __future__ import unicode_literals
import sys
-from SimpleXMLRPCServer import SimpleXMLRPCServer
import pwd
import os
import stat
@@ -9,8 +10,15 @@ import traceback
from multiprocessing import Process, Queue
import subprocess
import re
-# Local imports.
-from settings import SERVER_TIMEOUT
+
+try:
+ from SimpleXMLRPCServer import SimpleXMLRPCServer
+except ImportError:
+ # The above import will not work on Python-3.x.
+ from xmlrpc.server import SimpleXMLRPCServer
+
+# Local imports
+from .settings import SERVER_TIMEOUT
MY_DIR = abspath(dirname(__file__))
@@ -127,6 +135,7 @@ class CodeEvaluator(object):
def teardown(self):
# Cancel the signal
delete_signal_handler()
+ self._change_dir(dirname(MY_DIR))
def check_code(self):
raise NotImplementedError("check_code method not implemented")
@@ -176,7 +185,7 @@ class CodeEvaluator(object):
proc.kill()
# Re-raise exception.
raise
- return proc, stdout, stderr
+ return proc, stdout.decode('utf-8'), stderr.decode('utf-8')
def _change_dir(self, in_dir):
if in_dir is not None and isdir(in_dir):
diff --git a/yaksh/code_server.py b/yaksh/code_server.py
index e19e9c8..b3c9c30 100755
--- a/yaksh/code_server.py
+++ b/yaksh/code_server.py
@@ -23,7 +23,7 @@ that returns an available server.
"""
# Standard library imports
-from SimpleXMLRPCServer import SimpleXMLRPCServer
+from __future__ import unicode_literals
import json
from multiprocessing import Process, Queue
import os
@@ -36,6 +36,12 @@ import subprocess
import sys
try:
+ from SimpleXMLRPCServer import SimpleXMLRPCServer
+except ImportError:
+ # The above import will not work on Python-3.x.
+ from xmlrpc.server import SimpleXMLRPCServer
+
+try:
from urllib import unquote
except ImportError:
# The above import will not work on Python-3.x.
@@ -45,9 +51,9 @@ except ImportError:
from tornado.ioloop import IOLoop
from tornado.web import Application, RequestHandler
-# Local imports.
-from settings import SERVER_PORTS, SERVER_POOL_PORT
-from language_registry import create_evaluator_instance, unpack_json
+# Local imports
+from .settings import SERVER_PORTS, SERVER_POOL_PORT
+from .language_registry import create_evaluator_instance, unpack_json
MY_DIR = abspath(dirname(__file__))
diff --git a/yaksh/cpp_code_evaluator.py b/yaksh/cpp_code_evaluator.py
index c65242d..5380dea 100644
--- a/yaksh/cpp_code_evaluator.py
+++ b/yaksh/cpp_code_evaluator.py
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+from __future__ import unicode_literals
import traceback
import pwd
import os
@@ -6,9 +7,9 @@ from os.path import join, isfile
import subprocess
import importlib
-# local imports
-from code_evaluator import CodeEvaluator
-from file_utils import copy_files, delete_files
+# Local imports
+from .code_evaluator import CodeEvaluator
+from .file_utils import copy_files, delete_files
class CppCodeEvaluator(CodeEvaluator):
@@ -18,9 +19,10 @@ class CppCodeEvaluator(CodeEvaluator):
self.submit_code_path = self.create_submit_code_file('submit.c')
self.compiled_user_answer = None
self.compiled_test_code = None
+ self.user_output_path = ""
+ self.ref_output_path = ""
def teardown(self):
- super(CppCodeEvaluator, self).teardown()
# Delete the created file.
os.remove(self.submit_code_path)
if os.path.exists(self.ref_output_path):
@@ -29,9 +31,11 @@ class CppCodeEvaluator(CodeEvaluator):
os.remove(self.user_output_path)
if self.files:
delete_files(self.files)
+ super(CppCodeEvaluator, self).teardown()
+
def set_file_paths(self):
- user_output_path = os.getcwd() + '/output'
+ user_output_path = os.getcwd() + '/output_file'
ref_output_path = os.getcwd() + '/executable'
return user_output_path, ref_output_path
@@ -104,7 +108,6 @@ class CppCodeEvaluator(CodeEvaluator):
Returns (False, error_msg): If mandatory arguments are not files or
if the required permissions are not given to the file(s).
"""
-
success = False
proc, stdnt_out, stdnt_stderr = self.compiled_user_answer
stdnt_stderr = self._remove_null_substitute_char(stdnt_stderr)
@@ -125,28 +128,28 @@ class CppCodeEvaluator(CodeEvaluator):
if proc.returncode == 0:
success, err = True, "Correct answer"
else:
- err = stdout + "\n" + stderr
+ err = "{0} \n {1}".format(stdout, stderr)
else:
err = "Error:"
try:
error_lines = main_err.splitlines()
for e in error_lines:
if ':' in e:
- err = err + "\n" + e.split(":", 1)[1]
+ err = "{0} \n {1}".format(err, e.split(":", 1)[1])
else:
- err = err + "\n" + e
+ err = "{0} \n {1}".format(err, e)
except:
- err = err + "\n" + main_err
+ err = "{0} \n {1}".format(err, main_err)
else:
err = "Compilation Error:"
try:
error_lines = stdnt_stderr.splitlines()
for e in error_lines:
if ':' in e:
- err = err + "\n" + e.split(":", 1)[1]
+ err = "{0} \n {1}".format(err, e.split(":", 1)[1])
else:
- err = err + "\n" + e
+ err = "{0} \n {1}".format(err, e)
except:
- err = err + "\n" + stdnt_stderr
+ err = "{0} \n {1}".format(err, stdnt_stderr)
return success, err
diff --git a/yaksh/cpp_stdio_evaluator.py b/yaksh/cpp_stdio_evaluator.py
index 720ed0f..9d2b969 100644
--- a/yaksh/cpp_stdio_evaluator.py
+++ b/yaksh/cpp_stdio_evaluator.py
@@ -1,12 +1,12 @@
#!/usr/bin/env python
+from __future__ import unicode_literals
import subprocess
import os
from os.path import isfile
-#local imports
-
-from stdio_evaluator import StdIOEvaluator
-from file_utils import copy_files, delete_files
+#Local imports
+from .stdio_evaluator import StdIOEvaluator
+from .file_utils import copy_files, delete_files
class CppStdioEvaluator(StdIOEvaluator):
@@ -17,13 +17,13 @@ class CppStdioEvaluator(StdIOEvaluator):
self.submit_code_path = self.create_submit_code_file('main.c')
def teardown(self):
- super(CppStdioEvaluator, self).teardown()
os.remove(self.submit_code_path)
if self.files:
delete_files(self.files)
+ super(CppStdioEvaluator, self).teardown()
def set_file_paths(self):
- user_output_path = os.getcwd() + '/output'
+ user_output_path = os.getcwd() + '/output_file'
ref_output_path = os.getcwd() + '/executable'
return user_output_path, ref_output_path
diff --git a/yaksh/evaluator_tests/test_bash_evaluation.py b/yaksh/evaluator_tests/test_bash_evaluation.py
index 084e5e4..66ade19 100755..100644
--- a/yaksh/evaluator_tests/test_bash_evaluation.py
+++ b/yaksh/evaluator_tests/test_bash_evaluation.py
@@ -1,5 +1,8 @@
+from __future__ import unicode_literals
import unittest
import os
+import shutil
+import tempfile
from yaksh.bash_code_evaluator import BashCodeEvaluator
from yaksh.bash_stdio_evaluator import BashStdioEvaluator
from yaksh.settings import SERVER_TIMEOUT
@@ -8,15 +11,23 @@ from textwrap import dedent
class BashAssertionEvaluationTestCases(unittest.TestCase):
def setUp(self):
+ with open('/tmp/test.txt', 'wb') as f:
+ f.write('2'.encode('ascii'))
+ tmp_in_dir_path = tempfile.mkdtemp()
self.test_case_data = [
{"test_case": "bash_files/sample.sh,bash_files/sample.args"}
]
- self.in_dir = os.getcwd()
+ tmp_in_dir_path = tempfile.mkdtemp()
+ self.in_dir = tmp_in_dir_path
self.timeout_msg = ("Code took more than {0} seconds to run. "
"You probably have an infinite loop in your"
" code.").format(SERVER_TIMEOUT)
self.file_paths = None
+ def tearDown(self):
+ os.remove('/tmp/test.txt')
+ shutil.rmtree(self.in_dir)
+
def test_correct_answer(self):
user_answer = ("#!/bin/bash\n[[ $# -eq 2 ]]"
" && echo $(( $1 + $2 )) && exit $(( $1 + $2 ))"
@@ -28,7 +39,7 @@ class BashAssertionEvaluationTestCases(unittest.TestCase):
}
result = get_class.evaluate(**kwargs)
self.assertTrue(result.get('success'))
- self.assertEquals(result.get('error'), "Correct answer")
+ self.assertEqual(result.get('error'), "Correct answer")
def test_error(self):
user_answer = ("#!/bin/bash\n[[ $# -eq 2 ]] "
@@ -52,10 +63,10 @@ class BashAssertionEvaluationTestCases(unittest.TestCase):
}
result = get_class.evaluate(**kwargs)
self.assertFalse(result.get("success"))
- self.assertEquals(result.get("error"), self.timeout_msg)
+ self.assertEqual(result.get("error"), self.timeout_msg)
def test_file_based_assert(self):
- self.file_paths = [(os.getcwd()+"/yaksh/test.txt", False)]
+ self.file_paths = [('/tmp/test.txt', False)]
self.test_case_data = [
{"test_case": "bash_files/sample1.sh,bash_files/sample1.args"}
]
@@ -67,7 +78,7 @@ class BashAssertionEvaluationTestCases(unittest.TestCase):
}
result = get_class.evaluate(**kwargs)
self.assertTrue(result.get("success"))
- self.assertEquals(result.get("error"), "Correct answer")
+ self.assertEqual(result.get("error"), "Correct answer")
class BashStdioEvaluationTestCases(unittest.TestCase):
def setUp(self):
@@ -88,7 +99,7 @@ class BashStdioEvaluationTestCases(unittest.TestCase):
"test_case_data": test_case_data
}
result = get_class.evaluate(**kwargs)
- self.assertEquals(result.get('error'), "Correct answer")
+ self.assertEqual(result.get('error'), "Correct answer")
self.assertTrue(result.get('success'))
def test_array_input(self):
@@ -108,7 +119,7 @@ class BashStdioEvaluationTestCases(unittest.TestCase):
"test_case_data": test_case_data
}
result = get_class.evaluate(**kwargs)
- self.assertEquals(result.get('error'), "Correct answer")
+ self.assertEqual(result.get('error'), "Correct answer")
self.assertTrue(result.get('success'))
def test_incorrect_answer(self):
@@ -142,7 +153,7 @@ class BashStdioEvaluationTestCases(unittest.TestCase):
"test_case_data": test_case_data
}
result = get_class.evaluate(**kwargs)
- self.assertEquals(result.get('error'), "Correct answer")
+ self.assertEqual(result.get('error'), "Correct answer")
self.assertTrue(result.get('success'))
if __name__ == '__main__':
diff --git a/yaksh/evaluator_tests/test_c_cpp_evaluation.py b/yaksh/evaluator_tests/test_c_cpp_evaluation.py
index c6994f6..c990436 100755..100644
--- a/yaksh/evaluator_tests/test_c_cpp_evaluation.py
+++ b/yaksh/evaluator_tests/test_c_cpp_evaluation.py
@@ -1,5 +1,8 @@
+from __future__ import absolute_import
import unittest
import os
+import shutil
+import tempfile
from yaksh.cpp_code_evaluator import CppCodeEvaluator
from yaksh.cpp_stdio_evaluator import CppStdioEvaluator
from yaksh.settings import SERVER_TIMEOUT
@@ -8,13 +11,20 @@ from textwrap import dedent
class CAssertionEvaluationTestCases(unittest.TestCase):
def setUp(self):
+ with open('/tmp/test.txt', 'wb') as f:
+ f.write('2'.encode('ascii'))
+ tmp_in_dir_path = tempfile.mkdtemp()
self.test_case_data = [{"test_case": "c_cpp_files/main.cpp"}]
- self.in_dir = os.getcwd()
+ self.in_dir = tmp_in_dir_path
self.timeout_msg = ("Code took more than {0} seconds to run. "
"You probably have an infinite loop in your"
" code.").format(SERVER_TIMEOUT)
self.file_paths = None
+ def tearDown(self):
+ os.remove('/tmp/test.txt')
+ shutil.rmtree(self.in_dir)
+
def test_correct_answer(self):
user_answer = "int add(int a, int b)\n{return a+b;}"
get_class = CppCodeEvaluator(self.in_dir)
@@ -24,7 +34,7 @@ class CAssertionEvaluationTestCases(unittest.TestCase):
}
result = get_class.evaluate(**kwargs)
self.assertTrue(result.get('success'))
- self.assertEquals(result.get('error'), "Correct answer")
+ self.assertEqual(result.get('error'), "Correct answer")
def test_incorrect_answer(self):
user_answer = "int add(int a, int b)\n{return a-b;}"
@@ -34,9 +44,10 @@ class CAssertionEvaluationTestCases(unittest.TestCase):
'file_paths': self.file_paths
}
result = get_class.evaluate(**kwargs)
+ lines_of_error = len(result.get('error').splitlines())
self.assertFalse(result.get('success'))
self.assertIn("Incorrect:", result.get('error'))
- self.assertTrue(result.get('error').splitlines > 1)
+ self.assertTrue(lines_of_error > 1)
def test_compilation_error(self):
user_answer = "int add(int a, int b)\n{return a+b}"
@@ -58,10 +69,10 @@ class CAssertionEvaluationTestCases(unittest.TestCase):
}
result = get_class.evaluate(**kwargs)
self.assertFalse(result.get("success"))
- self.assertEquals(result.get("error"), self.timeout_msg)
+ self.assertEqual(result.get("error"), self.timeout_msg)
def test_file_based_assert(self):
- self.file_paths = [(os.getcwd()+"/yaksh/test.txt", False)]
+ self.file_paths = [('/tmp/test.txt', False)]
self.test_case_data = [{"test_case": "c_cpp_files/file_data.c"}]
user_answer = dedent("""
#include<stdio.h>
@@ -82,7 +93,7 @@ class CAssertionEvaluationTestCases(unittest.TestCase):
}
result = get_class.evaluate(**kwargs)
self.assertTrue(result.get('success'))
- self.assertEquals(result.get('error'), "Correct answer")
+ self.assertEqual(result.get('error'), "Correct answer")
class CppStdioEvaluationTestCases(unittest.TestCase):
@@ -106,7 +117,7 @@ class CppStdioEvaluationTestCases(unittest.TestCase):
'test_case_data': self.test_case_data
}
result = get_class.evaluate(**kwargs)
- self.assertEquals(result.get('error'), "Correct answer")
+ self.assertEqual(result.get('error'), "Correct answer")
self.assertTrue(result.get('success'))
def test_array_input(self):
@@ -126,7 +137,7 @@ class CppStdioEvaluationTestCases(unittest.TestCase):
'test_case_data': self.test_case_data
}
result = get_class.evaluate(**kwargs)
- self.assertEquals(result.get('error'), "Correct answer")
+ self.assertEqual(result.get('error'), "Correct answer")
self.assertTrue(result.get('success'))
def test_string_input(self):
@@ -144,7 +155,7 @@ class CppStdioEvaluationTestCases(unittest.TestCase):
'test_case_data': self.test_case_data
}
result = get_class.evaluate(**kwargs)
- self.assertEquals(result.get('error'), "Correct answer")
+ self.assertEqual(result.get('error'), "Correct answer")
self.assertTrue(result.get('success'))
def test_incorrect_answer(self):
@@ -159,9 +170,10 @@ class CppStdioEvaluationTestCases(unittest.TestCase):
'test_case_data': self.test_case_data
}
result = get_class.evaluate(**kwargs)
+ lines_of_error = len(result.get('error').splitlines())
self.assertFalse(result.get('success'))
self.assertIn("Incorrect", result.get('error'))
- self.assertTrue(result.get('error').splitlines > 1)
+ self.assertTrue(lines_of_error > 1)
def test_error(self):
user_answer = dedent("""
@@ -191,7 +203,7 @@ class CppStdioEvaluationTestCases(unittest.TestCase):
}
result = get_class.evaluate(**kwargs)
self.assertFalse(result.get("success"))
- self.assertEquals(result.get("error"), self.timeout_msg)
+ self.assertEqual(result.get("error"), self.timeout_msg)
def test_only_stdout(self):
self.test_case_data = [{'expected_output': '11',
@@ -207,7 +219,7 @@ class CppStdioEvaluationTestCases(unittest.TestCase):
'test_case_data': self.test_case_data
}
result = get_class.evaluate(**kwargs)
- self.assertEquals(result.get('error'), "Correct answer")
+ self.assertEqual(result.get('error'), "Correct answer")
self.assertTrue(result.get('success'))
def test_cpp_correct_answer(self):
@@ -224,7 +236,7 @@ class CppStdioEvaluationTestCases(unittest.TestCase):
'test_case_data': self.test_case_data
}
result = get_class.evaluate(**kwargs)
- self.assertEquals(result.get('error'), "Correct answer")
+ self.assertEqual(result.get('error'), "Correct answer")
self.assertTrue(result.get('success'))
def test_cpp_array_input(self):
@@ -245,7 +257,7 @@ class CppStdioEvaluationTestCases(unittest.TestCase):
'test_case_data': self.test_case_data
}
result = get_class.evaluate(**kwargs)
- self.assertEquals(result.get('error'), "Correct answer")
+ self.assertEqual(result.get('error'), "Correct answer")
self.assertTrue(result.get('success'))
def test_cpp_string_input(self):
@@ -264,7 +276,7 @@ class CppStdioEvaluationTestCases(unittest.TestCase):
'test_case_data': self.test_case_data
}
result = get_class.evaluate(**kwargs)
- self.assertEquals(result.get('error'), "Correct answer")
+ self.assertEqual(result.get('error'), "Correct answer")
self.assertTrue(result.get('success'))
def test_cpp_incorrect_answer(self):
@@ -280,9 +292,10 @@ class CppStdioEvaluationTestCases(unittest.TestCase):
'test_case_data': self.test_case_data
}
result = get_class.evaluate(**kwargs)
+ lines_of_error = len(result.get('error').splitlines())
self.assertFalse(result.get('success'))
self.assertIn("Incorrect", result.get('error'))
- self.assertTrue(result.get('error').splitlines > 1)
+ self.assertTrue(lines_of_error > 1)
def test_cpp_error(self):
user_answer = dedent("""
@@ -314,7 +327,7 @@ class CppStdioEvaluationTestCases(unittest.TestCase):
}
result = get_class.evaluate(**kwargs)
self.assertFalse(result.get("success"))
- self.assertEquals(result.get("error"), self.timeout_msg)
+ self.assertEqual(result.get("error"), self.timeout_msg)
def test_cpp_only_stdout(self):
self.test_case_data = [{'expected_output': '11',
@@ -331,7 +344,7 @@ class CppStdioEvaluationTestCases(unittest.TestCase):
'test_case_data': self.test_case_data
}
result = get_class.evaluate(**kwargs)
- self.assertEquals(result.get('error'), "Correct answer")
+ self.assertEqual(result.get('error'), "Correct answer")
self.assertTrue(result.get('success'))
if __name__ == '__main__':
diff --git a/yaksh/evaluator_tests/test_code_evaluation.py b/yaksh/evaluator_tests/test_code_evaluation.py
index cbca32d..88e0253 100644
--- a/yaksh/evaluator_tests/test_code_evaluation.py
+++ b/yaksh/evaluator_tests/test_code_evaluation.py
@@ -1,3 +1,4 @@
+from __future__ import unicode_literals
import unittest
import os
from yaksh import python_assertion_evaluator
@@ -38,7 +39,7 @@ class RegistryTestCase(unittest.TestCase):
"stdiobasedtestcase": stdout_evaluator_path
}
)
- self.assertEquals(evaluator_class, class_name)
+ self.assertEqual(evaluator_class, class_name)
def tearDown(self):
self.registry_object = None
diff --git a/yaksh/evaluator_tests/test_java_evaluation.py b/yaksh/evaluator_tests/test_java_evaluation.py
index 60afb3b..e375bdb 100755..100644
--- a/yaksh/evaluator_tests/test_java_evaluation.py
+++ b/yaksh/evaluator_tests/test_java_evaluation.py
@@ -1,5 +1,8 @@
+from __future__ import unicode_literals
import unittest
import os
+import shutil
+import tempfile
from yaksh import code_evaluator as evaluator
from yaksh.java_code_evaluator import JavaCodeEvaluator
from yaksh.java_stdio_evaluator import JavaStdioEvaluator
@@ -9,10 +12,13 @@ from textwrap import dedent
class JavaAssertionEvaluationTestCases(unittest.TestCase):
def setUp(self):
+ with open('/tmp/test.txt', 'wb') as f:
+ f.write('2'.encode('ascii'))
+ tmp_in_dir_path = tempfile.mkdtemp()
self.test_case_data = [
{"test_case": "java_files/main_square.java"}
]
- self.in_dir = os.getcwd()
+ self.in_dir = tmp_in_dir_path
evaluator.SERVER_TIMEOUT = 9
self.timeout_msg = ("Code took more than {0} seconds to run. "
"You probably have an infinite loop in"
@@ -20,7 +26,8 @@ class JavaAssertionEvaluationTestCases(unittest.TestCase):
self.file_paths = None
def tearDown(self):
- evaluator.SERVER_TIMEOUT = 2
+ os.remove('/tmp/test.txt')
+ shutil.rmtree(self.in_dir)
def test_correct_answer(self):
user_answer = "class Test {\n\tint square_num(int a) {\n\treturn a*a;\n\t}\n}"
@@ -30,7 +37,7 @@ class JavaAssertionEvaluationTestCases(unittest.TestCase):
'file_paths': self.file_paths
}
result = get_class.evaluate(**kwargs)
- self.assertEquals(result.get('error'), "Correct answer")
+ self.assertEqual(result.get('error'), "Correct answer")
self.assertTrue(result.get('success'))
def test_incorrect_answer(self):
@@ -42,8 +49,10 @@ class JavaAssertionEvaluationTestCases(unittest.TestCase):
}
result = get_class.evaluate(**kwargs)
self.assertFalse(result.get('success'))
- self.assertIn("Incorrect:", result.get('error'))
- self.assertTrue(result.get('error').splitlines > 1)
+ lines_of_error = len(result.get('error').splitlines())
+ self.assertFalse(result.get('success'))
+ self.assertIn("Incorrect", result.get('error'))
+ self.assertTrue(lines_of_error > 1)
def test_error(self):
user_answer = "class Test {\n\tint square_num(int a) {\n\treturn a*a"
@@ -65,10 +74,10 @@ class JavaAssertionEvaluationTestCases(unittest.TestCase):
}
result = get_class.evaluate(**kwargs)
self.assertFalse(result.get("success"))
- self.assertEquals(result.get("error"), self.timeout_msg)
+ self.assertEqual(result.get("error"), self.timeout_msg)
def test_file_based_assert(self):
- self.file_paths = [(os.getcwd()+"/yaksh/test.txt", False)]
+ self.file_paths = [("/tmp/test.txt", False)]
self.test_case_data = [
{"test_case": "java_files/read_file.java"}
]
@@ -97,11 +106,15 @@ class JavaAssertionEvaluationTestCases(unittest.TestCase):
}
result = get_class.evaluate(**kwargs)
self.assertTrue(result.get("success"))
- self.assertEquals(result.get("error"), "Correct answer")
+ self.assertEqual(result.get("error"), "Correct answer")
class JavaStdioEvaluationTestCases(unittest.TestCase):
def setUp(self):
+ with open('/tmp/test.txt', 'wb') as f:
+ f.write('2'.encode('ascii'))
+ tmp_in_dir_path = tempfile.mkdtemp()
+ self.in_dir = tmp_in_dir_path
self.test_case_data = [{'expected_output': '11',
'expected_input': '5\n6'}]
evaluator.SERVER_TIMEOUT = 4
@@ -109,8 +122,10 @@ class JavaStdioEvaluationTestCases(unittest.TestCase):
"You probably have an infinite loop in"
" your code.").format(evaluator.SERVER_TIMEOUT)
- def teardown(self):
+ def tearDown(self):
evaluator.SERVER_TIMEOUT = 4
+ os.remove('/tmp/test.txt')
+ shutil.rmtree(self.in_dir)
def test_correct_answer(self):
user_answer = dedent("""
@@ -122,12 +137,12 @@ class JavaStdioEvaluationTestCases(unittest.TestCase):
int b = s.nextInt();
System.out.print(a+b);
}}""")
- get_class = JavaStdioEvaluator()
+ get_class = JavaStdioEvaluator(self.in_dir)
kwargs = {'user_answer': user_answer,
'test_case_data': self.test_case_data
}
result = get_class.evaluate(**kwargs)
- self.assertEquals(result.get('error'), "Correct answer")
+ self.assertEqual(result.get('error'), "Correct answer")
self.assertTrue(result.get('success'))
def test_array_input(self):
@@ -144,12 +159,12 @@ class JavaStdioEvaluationTestCases(unittest.TestCase):
a[i] = s.nextInt();
System.out.print(a[i]);}
}}""")
- get_class = JavaStdioEvaluator()
+ get_class = JavaStdioEvaluator(self.in_dir)
kwargs = {'user_answer': user_answer,
'test_case_data': self.test_case_data
}
result = get_class.evaluate(**kwargs)
- self.assertEquals(result.get('error'), "Correct answer")
+ self.assertEqual(result.get('error'), "Correct answer")
self.assertTrue(result.get('success'))
def test_incorrect_answer(self):
@@ -163,14 +178,15 @@ class JavaStdioEvaluationTestCases(unittest.TestCase):
int b = s.nextInt();
System.out.print(a);
}}""")
- get_class = JavaStdioEvaluator()
+ get_class = JavaStdioEvaluator(self.in_dir)
kwargs = {'user_answer': user_answer,
'test_case_data': self.test_case_data
}
result = get_class.evaluate(**kwargs)
+ lines_of_error = len(result.get('error').splitlines())
self.assertFalse(result.get('success'))
self.assertIn("Incorrect", result.get('error'))
- self.assertTrue(result.get('error').splitlines > 1)
+ self.assertTrue(lines_of_error > 1)
def test_error(self):
@@ -179,7 +195,7 @@ class JavaStdioEvaluationTestCases(unittest.TestCase):
{
System.out.print("a");
}""")
- get_class = JavaStdioEvaluator()
+ get_class = JavaStdioEvaluator(self.in_dir)
kwargs = {'user_answer': user_answer,
'test_case_data': self.test_case_data
}
@@ -196,13 +212,13 @@ class JavaStdioEvaluationTestCases(unittest.TestCase):
{
System.out.print("a");}
}}""")
- get_class = JavaStdioEvaluator()
+ get_class = JavaStdioEvaluator(self.in_dir)
kwargs = {'user_answer': user_answer,
'test_case_data': self.test_case_data
}
result = get_class.evaluate(**kwargs)
self.assertFalse(result.get("success"))
- self.assertEquals(result.get("error"), self.timeout_msg)
+ self.assertEqual(result.get("error"), self.timeout_msg)
def test_only_stdout(self):
self.test_case_data = [{'expected_output': '11',
@@ -214,12 +230,12 @@ class JavaStdioEvaluationTestCases(unittest.TestCase):
int b = 6;
System.out.print(a+b);
}}""")
- get_class = JavaStdioEvaluator()
+ get_class = JavaStdioEvaluator(self.in_dir)
kwargs = {'user_answer': user_answer,
'test_case_data': self.test_case_data
}
result = get_class.evaluate(**kwargs)
- self.assertEquals(result.get('error'), "Correct answer")
+ self.assertEqual(result.get('error'), "Correct answer")
self.assertTrue(result.get('success'))
def test_string_input(self):
@@ -234,13 +250,45 @@ class JavaStdioEvaluationTestCases(unittest.TestCase):
String b = s.nextLine();
System.out.print(a+b);
}}""")
- get_class = JavaStdioEvaluator()
+ get_class = JavaStdioEvaluator(self.in_dir)
kwargs = {'user_answer': user_answer,
'test_case_data': self.test_case_data
}
result = get_class.evaluate(**kwargs)
- self.assertEquals(result.get('error'), "Correct answer")
+ self.assertEqual(result.get('error'), "Correct answer")
self.assertTrue(result.get('success'))
+ def test_file_based_stdout(self):
+ self.file_paths = [("/tmp/test.txt", False)]
+ self.test_case_data = [{'expected_output': '2',
+ 'expected_input': ''}]
+ user_answer = dedent("""
+ import java.io.BufferedReader;
+ import java.io.FileReader;
+ import java.io.IOException;
+ class Test{
+ public static void main(String[] args) throws IOException {
+ BufferedReader br = new BufferedReader(new FileReader("test.txt"));
+ try {
+ StringBuilder sb = new StringBuilder();
+ String line = br.readLine();
+ while (line != null) {
+ sb.append(line);
+ line = br.readLine();}
+ System.out.print(sb.toString());
+ } finally {
+ br.close();
+ }}}
+ """)
+ get_class = JavaStdioEvaluator(self.in_dir)
+ kwargs = {'user_answer': user_answer,
+ 'test_case_data': self.test_case_data,
+ 'file_paths': self.file_paths
+ }
+ result = get_class.evaluate(**kwargs)
+ self.assertTrue(result.get("success"))
+ self.assertEqual(result.get("error"), "Correct answer")
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/yaksh/evaluator_tests/test_python_evaluation.py b/yaksh/evaluator_tests/test_python_evaluation.py
index b72d26b..45cc40d 100755..100644
--- a/yaksh/evaluator_tests/test_python_evaluation.py
+++ b/yaksh/evaluator_tests/test_python_evaluation.py
@@ -1,13 +1,22 @@
+from __future__ import unicode_literals
import unittest
import os
+import tempfile
+import shutil
+from textwrap import dedent
+
+# Local import
from yaksh.python_assertion_evaluator import PythonAssertionEvaluator
from yaksh.python_stdio_evaluator import PythonStdioEvaluator
from yaksh.settings import SERVER_TIMEOUT
-from textwrap import dedent
class PythonAssertionEvaluationTestCases(unittest.TestCase):
def setUp(self):
+ with open('/tmp/test.txt', 'wb') as f:
+ f.write('2'.encode('ascii'))
+ tmp_in_dir_path = tempfile.mkdtemp()
+ self.in_dir = tmp_in_dir_path
self.test_case_data = [{"test_case": 'assert(add(1,2)==3)'},
{"test_case": 'assert(add(-1,2)==1)'},
{"test_case": 'assert(add(-1,-2)==-3)'},
@@ -17,6 +26,10 @@ class PythonAssertionEvaluationTestCases(unittest.TestCase):
" your code.").format(SERVER_TIMEOUT)
self.file_paths = None
+ def tearDown(self):
+ os.remove('/tmp/test.txt')
+ shutil.rmtree(self.in_dir)
+
def test_correct_answer(self):
# Given
user_answer = "def add(a,b):\n\treturn a + b"
@@ -159,7 +172,6 @@ class PythonAssertionEvaluationTestCases(unittest.TestCase):
""")
recursion_error_msg = ["Traceback",
"call",
- "RuntimeError",
"maximum recursion depth exceeded"
]
kwargs = {'user_answer': user_answer,
@@ -174,7 +186,6 @@ class PythonAssertionEvaluationTestCases(unittest.TestCase):
# Then
self.assertFalse(result.get("success"))
- self.assertEqual(969, len(err))
for msg in recursion_error_msg:
self.assertIn(msg, result.get("error"))
@@ -187,7 +198,6 @@ class PythonAssertionEvaluationTestCases(unittest.TestCase):
type_error_msg = ["Traceback",
"call",
"TypeError",
- "exactly",
"argument"
]
kwargs = {'user_answer': user_answer,
@@ -238,7 +248,7 @@ class PythonAssertionEvaluationTestCases(unittest.TestCase):
def test_file_based_assert(self):
# Given
self.test_case_data = [{"test_case": "assert(ans()=='2')"}]
- self.file_paths = [(os.getcwd()+"/yaksh/test.txt", False)]
+ self.file_paths = [('/tmp/test.txt', False)]
user_answer = dedent("""
def ans():
with open("test.txt") as f:
@@ -322,65 +332,10 @@ class PythonAssertionEvaluationTestCases(unittest.TestCase):
self.assertIn(msg, result.get("error"))
-class PythonStdoutEvaluationTestCases(unittest.TestCase):
- def setUp(self):
- self.test_case_data = [{"expected_input": None,
- "expected_output": "0 1 1 2 3"
- }]
-
- self.timeout_msg = ("Code took more than {0} seconds to run. "
- "You probably have an infinite loop"
- " in your code.").format(SERVER_TIMEOUT)
-
- def test_correct_answer(self):
- # Given
- user_answer = "a,b=0,1\nfor i in range(5):\n\tprint a,\n\ta,b=b,a+b"
- kwargs = {'user_answer': user_answer,
- 'test_case_data': self.test_case_data,
- }
-
- # When
- evaluator = PythonStdioEvaluator()
- result = evaluator.evaluate(**kwargs)
-
- # Then
- self.assertEqual(result.get('error'), "Correct answer")
- self.assertTrue(result.get('success'))
-
- def test_incorrect_answer(self):
- # Given
- user_answer = "a,b=0,1\nfor i in range(5):\n\tprint b,\n\ta,b=b,a+b"
- kwargs = {'user_answer': user_answer,
- 'test_case_data': self.test_case_data,
- }
-
- # When
- evaluator = PythonStdioEvaluator()
- result = evaluator.evaluate(**kwargs)
-
- # Then
- self.assertFalse(result.get('success'))
- self.assertIn("Incorrect answer", result.get('error'))
-
- def test_infinite_loop(self):
- # Given
- user_answer = "def add(a, b):\n\twhile True:\n\t\tpass\nadd(1,2)"
- kwargs = {'user_answer': user_answer,
- 'test_case_data': self.test_case_data
- }
-
- # When
- evaluator = PythonStdioEvaluator()
- result = evaluator.evaluate(**kwargs)
-
- # Then
- self.assertEqual(result.get('error'), self.timeout_msg)
- self.assertFalse(result.get('success'))
-
-
class PythonStdIOEvaluationTestCases(unittest.TestCase):
-
def setUp(self):
+ with open('/tmp/test.txt', 'wb') as f:
+ f.write('2'.encode('ascii'))
self.file_paths = None
def test_correct_answer_integer(self):
@@ -389,9 +344,9 @@ class PythonStdIOEvaluationTestCases(unittest.TestCase):
"expected_output": "3"
}]
user_answer = dedent("""
- a = input()
- b = input()
- print a+b
+ a = int(input())
+ b = int(input())
+ print(a+b)
"""
)
kwargs = {'user_answer': user_answer,
@@ -408,13 +363,16 @@ class PythonStdIOEvaluationTestCases(unittest.TestCase):
def test_correct_answer_list(self):
# Given
- self.test_case_data = [{"expected_input": "[1,2,3]\n[5,6,7]",
+ self.test_case_data = [{"expected_input": "1,2,3\n5,6,7",
"expected_output": "[1, 2, 3, 5, 6, 7]"
}]
user_answer = dedent("""
- a = input()
- b = input()
- print a+b
+ from six.moves import input
+ input_a = input()
+ input_b = input()
+ a = [int(i) for i in input_a.split(',')]
+ b = [int(i) for i in input_b.split(',')]
+ print(a+b)
"""
)
kwargs = {'user_answer': user_answer,
@@ -431,14 +389,14 @@ class PythonStdIOEvaluationTestCases(unittest.TestCase):
def test_correct_answer_string(self):
# Given
- self.test_case_data = [{"expected_input": """the quick brown fox jumps\
- over the lazy dog\nthe""",
+ self.test_case_data = [{"expected_input": ("the quick brown fox jumps over the lazy dog\nthe"),
"expected_output": "2"
}]
user_answer = dedent("""
- a = raw_input()
- b = raw_input()
- print (a.count(b))
+ from six.moves import input
+ a = str(input())
+ b = str(input())
+ print(a.count(b))
"""
)
kwargs = {'user_answer': user_answer,
@@ -459,9 +417,9 @@ class PythonStdIOEvaluationTestCases(unittest.TestCase):
"expected_output": "3"
}]
user_answer = dedent("""
- a = input()
- b = input()
- print a-b
+ a = int(input())
+ b = int(input())
+ print(a-b)
"""
)
kwargs = {'user_answer': user_answer,
@@ -479,12 +437,12 @@ class PythonStdIOEvaluationTestCases(unittest.TestCase):
def test_file_based_answer(self):
# Given
self.test_case_data = [{"expected_input": "", "expected_output": "2"}]
- self.file_paths = [(os.getcwd()+"/yaksh/test.txt", False)]
+ self.file_paths = [('/tmp/test.txt', False)]
user_answer = dedent("""
with open("test.txt") as f:
a = f.read()
- print a[0]
+ print(a[0])
"""
)
kwargs = {'user_answer': user_answer,
@@ -500,5 +458,26 @@ class PythonStdIOEvaluationTestCases(unittest.TestCase):
self.assertEqual(result.get('error'), "Correct answer")
self.assertTrue(result.get('success'))
+ def test_infinite_loop(self):
+ # Given
+ test_case_data = [{"expected_input": "1\n2",
+ "expected_output": "3"
+ }]
+ timeout_msg = ("Code took more than {0} seconds to run. "
+ "You probably have an infinite loop in"
+ " your code.").format(SERVER_TIMEOUT)
+ user_answer = "while True:\n\tpass"
+ kwargs = {'user_answer': user_answer,
+ 'test_case_data': test_case_data
+ }
+
+ # When
+ evaluator = PythonStdioEvaluator()
+ result = evaluator.evaluate(**kwargs)
+
+ # Then
+ self.assertEqual(result.get('error'), timeout_msg)
+ self.assertFalse(result.get('success'))
+
if __name__ == '__main__':
unittest.main()
diff --git a/yaksh/evaluator_tests/test_scilab_evaluation.py b/yaksh/evaluator_tests/test_scilab_evaluation.py
index f5e3767..b366480 100644
--- a/yaksh/evaluator_tests/test_scilab_evaluation.py
+++ b/yaksh/evaluator_tests/test_scilab_evaluation.py
@@ -1,18 +1,26 @@
+from __future__ import unicode_literals
import unittest
import os
+import shutil
+import tempfile
+
from yaksh import code_evaluator as evaluator
from yaksh.scilab_code_evaluator import ScilabCodeEvaluator
from yaksh.settings import SERVER_TIMEOUT
class ScilabEvaluationTestCases(unittest.TestCase):
def setUp(self):
+ tmp_in_dir_path = tempfile.mkdtemp()
self.test_case_data = [{"test_case": "scilab_files/test_add.sce"}]
- self.in_dir = os.getcwd()
+ self.in_dir = tmp_in_dir_path
self.timeout_msg = ("Code took more than {0} seconds to run. "
"You probably have an infinite loop"
" in your code.").format(SERVER_TIMEOUT)
self.file_paths = None
+ def tearDown(self):
+ shutil.rmtree(self.in_dir)
+
def test_correct_answer(self):
user_answer = ("funcprot(0)\nfunction[c]=add(a,b)"
"\n\tc=a+b;\nendfunction")
@@ -22,7 +30,7 @@ class ScilabEvaluationTestCases(unittest.TestCase):
'file_paths': self.file_paths
}
result = get_class.evaluate(**kwargs)
- self.assertEquals(result.get('error'), "Correct answer")
+ self.assertEqual(result.get('error'), "Correct answer")
self.assertTrue(result.get('success'))
def test_error(self):
@@ -35,7 +43,7 @@ class ScilabEvaluationTestCases(unittest.TestCase):
}
result = get_class.evaluate(**kwargs)
self.assertFalse(result.get("success"))
- self.assertTrue("error" in result.get("error"))
+ self.assertTrue('error' in result.get("error"))
def test_incorrect_answer(self):
@@ -47,9 +55,10 @@ class ScilabEvaluationTestCases(unittest.TestCase):
'file_paths': self.file_paths
}
result = get_class.evaluate(**kwargs)
+ lines_of_error = len(result.get('error').splitlines())
self.assertFalse(result.get('success'))
self.assertIn("Message", result.get('error'))
- self.assertTrue(result.get('error').splitlines > 1)
+ self.assertTrue(lines_of_error > 1)
def test_infinite_loop(self):
user_answer = ("funcprot(0)\nfunction[c]=add(a,b)"
@@ -61,7 +70,7 @@ class ScilabEvaluationTestCases(unittest.TestCase):
}
result = get_class.evaluate(**kwargs)
self.assertFalse(result.get("success"))
- self.assertEquals(result.get("error"), self.timeout_msg)
+ self.assertEqual(result.get("error"), self.timeout_msg)
if __name__ == '__main__':
unittest.main()
diff --git a/yaksh/forms.py b/yaksh/forms.py
index 23131b7..a12ce9a 100644
--- a/yaksh/forms.py
+++ b/yaksh/forms.py
@@ -9,7 +9,11 @@ from taggit.managers import TaggableManager
from taggit.forms import TagField
from django.forms.models import inlineformset_factory
from django.db.models import Q
-from string import letters, punctuation, digits
+try:
+ from string import letters
+except ImportError:
+ from string import ascii_letters as letters
+from string import punctuation, digits
import datetime
import pytz
diff --git a/yaksh/java_code_evaluator.py b/yaksh/java_code_evaluator.py
index ff76317..1ce1c0e 100644
--- a/yaksh/java_code_evaluator.py
+++ b/yaksh/java_code_evaluator.py
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+from __future__ import unicode_literals
import traceback
import pwd
import os
@@ -6,9 +7,9 @@ from os.path import join, isfile
import subprocess
import importlib
-# local imports
-from code_evaluator import CodeEvaluator
-from file_utils import copy_files, delete_files
+# Local imports
+from .code_evaluator import CodeEvaluator
+from .file_utils import copy_files, delete_files
class JavaCodeEvaluator(CodeEvaluator):
@@ -18,9 +19,10 @@ class JavaCodeEvaluator(CodeEvaluator):
self.submit_code_path = self.create_submit_code_file('Test.java')
self.compiled_user_answer = None
self.compiled_test_code = None
+ self.user_output_path = ""
+ self.ref_output_path = ""
def teardown(self):
- super(JavaCodeEvaluator, self).teardown()
# Delete the created file.
os.remove(self.submit_code_path)
if os.path.exists(self.user_output_path):
@@ -29,6 +31,8 @@ class JavaCodeEvaluator(CodeEvaluator):
os.remove(self.ref_output_path)
if self.files:
delete_files(self.files)
+ super(JavaCodeEvaluator, self).teardown()
+
def get_commands(self, clean_ref_code_path, user_code_directory):
compile_command = 'javac {0}'.format(self.submit_code_path),
diff --git a/yaksh/java_stdio_evaluator.py b/yaksh/java_stdio_evaluator.py
index f4b8773..bc9cf80 100644
--- a/yaksh/java_stdio_evaluator.py
+++ b/yaksh/java_stdio_evaluator.py
@@ -1,11 +1,12 @@
#!/usr/bin/env python
+from __future__ import unicode_literals
import subprocess
import os
from os.path import isfile
-#local imports
-from stdio_evaluator import StdIOEvaluator
-from file_utils import copy_files, delete_files
+#Local imports
+from .stdio_evaluator import StdIOEvaluator
+from .file_utils import copy_files, delete_files
class JavaStdioEvaluator(StdIOEvaluator):
@@ -16,10 +17,10 @@ class JavaStdioEvaluator(StdIOEvaluator):
self.submit_code_path = self.create_submit_code_file('Test.java')
def teardown(self):
- super(JavaStdioEvaluator, self).teardown()
os.remove(self.submit_code_path)
if self.files:
delete_files(self.files)
+ super(JavaStdioEvaluator, self).teardown()
def set_file_paths(self, directory, file_name):
output_path = "{0}{1}.class".format(directory, file_name)
diff --git a/yaksh/language_registry.py b/yaksh/language_registry.py
index 398e1aa..0e0140b 100644
--- a/yaksh/language_registry.py
+++ b/yaksh/language_registry.py
@@ -1,6 +1,10 @@
-from settings import code_evaluators
+from __future__ import unicode_literals
import importlib
import json
+import six
+
+# Local imports
+from .settings import code_evaluators
registry = None
@@ -24,7 +28,7 @@ def create_evaluator_instance(language, test_case_type, json_data, in_dir):
class _LanguageRegistry(object):
def __init__(self):
self._register = {}
- for language, module in code_evaluators.iteritems():
+ for language, module in six.iteritems(code_evaluators):
self._register[language] = None
# Public Protocol ##########
diff --git a/yaksh/models.py b/yaksh/models.py
index 69dff6d..444df4a 100644
--- a/yaksh/models.py
+++ b/yaksh/models.py
@@ -11,7 +11,10 @@ from django.contrib.contenttypes.models import ContentType
from taggit.managers import TaggableManager
from django.utils import timezone
from django.core.files import File
-from StringIO import StringIO
+try:
+ from StringIO import StringIO as string_io
+except ImportError:
+ from io import BytesIO as string_io
import pytz
import os
import stat
@@ -19,7 +22,7 @@ from os.path import join, abspath, dirname, exists
import shutil
import zipfile
import tempfile
-from file_utils import extract_files
+from .file_utils import extract_files
from yaksh.xmlrpc_clients import code_server
from django.conf import settings
@@ -177,7 +180,7 @@ class Course(models.Model):
success = False
return success
- def __unicode__(self):
+ def __str__(self):
return self.name
###############################################################################
@@ -270,7 +273,7 @@ class Question(models.Model):
def dump_questions(self, question_ids, user):
questions = Question.objects.filter(id__in=question_ids, user_id=user.id)
questions_dict = []
- zip_file_name = StringIO()
+ zip_file_name = string_io()
zip_file = zipfile.ZipFile(zip_file_name, "a")
for question in questions:
test_case = question.get_test_cases()
@@ -364,7 +367,7 @@ class Question(models.Model):
self.read_json("questions_dump.json", user)
- def __unicode__(self):
+ def __str__(self):
return self.summary
@@ -418,7 +421,7 @@ class Answer(models.Model):
else:
self.marks = marks
- def __unicode__(self):
+ def __str__(self):
return self.answer
@@ -540,7 +543,7 @@ class Quiz(models.Model):
course=course)
return demo_quiz
- def __unicode__(self):
+ def __str__(self):
desc = self.description or 'Quiz'
return '%s: on %s for %d minutes' % (desc, self.start_date_time,
self.duration)
@@ -682,7 +685,7 @@ class QuestionPaper(models.Model):
for question in questions:
question_paper.fixed_questions.add(question)
- def __unicode__(self):
+ def __str__(self):
return "Question Paper for " + self.quiz.description
###############################################################################
@@ -702,7 +705,7 @@ class QuestionSet(models.Model):
def get_random_questions(self):
""" Returns random questions from set of questions"""
- return sample(self.questions.all(), self.num_questions)
+ return sample(list(self.questions.all()), self.num_questions)
###############################################################################
@@ -1075,7 +1078,7 @@ class AnswerPaper(models.Model):
self.update_marks('complete')
return True, msg
- def __unicode__(self):
+ def __str__(self):
u = self.user
q = self.question_paper.quiz
return u'AnswerPaper paper of {0} {1} for quiz {2}'\
@@ -1099,7 +1102,7 @@ class StandardTestCase(TestCase):
def get_field_value(self):
return {"test_case": self.test_case}
- def __unicode__(self):
+ def __str__(self):
return u'Question: {0} | Test Case: {1}'.format(self.question,
self.test_case
)
@@ -1113,7 +1116,7 @@ class StdioBasedTestCase(TestCase):
return {"expected_output": self.expected_output,
"expected_input": self.expected_input}
- def __unicode__(self):
+ def __str__(self):
return u'Question: {0} | Exp. Output: {1} | Exp. Input: {2}'.format(self.question,
self.expected_output, self.expected_input
)
@@ -1126,7 +1129,7 @@ class McqTestCase(TestCase):
def get_field_value(self):
return {"options": self.options, "correct": self.correct}
- def __unicode__(self):
+ def __str__(self):
return u'Question: {0} | Correct: {1}'.format(self.question,
self.correct
)
diff --git a/yaksh/python_assertion_evaluator.py b/yaksh/python_assertion_evaluator.py
index 1b66fd2..dd1c041 100644
--- a/yaksh/python_assertion_evaluator.py
+++ b/yaksh/python_assertion_evaluator.py
@@ -1,13 +1,14 @@
#!/usr/bin/env python
+from __future__ import unicode_literals
import sys
import traceback
import os
from os.path import join
import importlib
-# local imports
-from code_evaluator import CodeEvaluator, TimeoutException
-from file_utils import copy_files, delete_files
+# Local imports
+from .code_evaluator import CodeEvaluator, TimeoutException
+from .file_utils import copy_files, delete_files
class PythonAssertionEvaluator(CodeEvaluator):
@@ -18,10 +19,10 @@ class PythonAssertionEvaluator(CodeEvaluator):
self.exec_scope = None
def teardown(self):
- super(PythonAssertionEvaluator, self).teardown()
# Delete the created file.
if self.files:
delete_files(self.files)
+ super(PythonAssertionEvaluator, self).teardown()
def compile_code(self, user_answer, file_paths, test_case):
self.files = []
@@ -32,7 +33,7 @@ class PythonAssertionEvaluator(CodeEvaluator):
else:
submitted = compile(user_answer, '<string>', mode='exec')
self.exec_scope = {}
- exec submitted in self.exec_scope
+ exec(submitted, self.exec_scope)
return self.exec_scope
def check_code(self, user_answer, file_paths, test_case):
@@ -40,7 +41,7 @@ class PythonAssertionEvaluator(CodeEvaluator):
try:
tb = None
_tests = compile(test_case, '<string>', mode='exec')
- exec _tests in self.exec_scope
+ exec(_tests, self.exec_scope)
except AssertionError:
type, value, tb = sys.exc_info()
info = traceback.extract_tb(tb)
diff --git a/yaksh/python_stdio_evaluator.py b/yaksh/python_stdio_evaluator.py
index 2cfd9c8..cbbbfd6 100644
--- a/yaksh/python_stdio_evaluator.py
+++ b/yaksh/python_stdio_evaluator.py
@@ -1,16 +1,23 @@
#!/usr/bin/env python
+from __future__ import unicode_literals
import sys
import traceback
import os
from os.path import join
import importlib
from contextlib import contextmanager
-from ast import literal_eval
-# local imports
-from code_evaluator import CodeEvaluator
-from StringIO import StringIO
-from file_utils import copy_files, delete_files
from textwrap import dedent
+
+try:
+ from StringIO import StringIO
+except ImportError:
+ from io import StringIO
+
+# Local imports
+from .code_evaluator import CodeEvaluator
+from .file_utils import copy_files, delete_files
+
+
@contextmanager
def redirect_stdout():
new_target = StringIO()
@@ -25,10 +32,10 @@ class PythonStdioEvaluator(CodeEvaluator):
"""Tests the Python code obtained from Code Server"""
def teardown(self):
- super(PythonStdioEvaluator, self).teardown()
# Delete the created file.
if self.files:
delete_files(self.files)
+ super(PythonStdioEvaluator, self).teardown()
def compile_code(self, user_answer, file_paths, expected_input, expected_output):
@@ -43,7 +50,7 @@ class PythonStdioEvaluator(CodeEvaluator):
sys.stdin = input_buffer
with redirect_stdout() as output_buffer:
exec_scope = {}
- exec submitted in exec_scope
+ exec(submitted, exec_scope)
self.output_value = output_buffer.getvalue().rstrip("\n")
return self.output_value
diff --git a/yaksh/scilab_code_evaluator.py b/yaksh/scilab_code_evaluator.py
index 53fa343..915491c 100644
--- a/yaksh/scilab_code_evaluator.py
+++ b/yaksh/scilab_code_evaluator.py
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+from __future__ import unicode_literals
import traceback
import os
from os.path import join, isfile
@@ -6,9 +7,9 @@ import subprocess
import re
import importlib
-# local imports
-from code_evaluator import CodeEvaluator
-from file_utils import copy_files, delete_files
+# Local imports
+from .code_evaluator import CodeEvaluator
+from .file_utils import copy_files, delete_files
class ScilabCodeEvaluator(CodeEvaluator):
@@ -19,11 +20,11 @@ class ScilabCodeEvaluator(CodeEvaluator):
self.create_submit_code_file('function.sci')
def teardown(self):
- super(ScilabCodeEvaluator, self).teardown()
# Delete the created file.
os.remove(self.submit_code_path)
if self.files:
delete_files(self.files)
+ super(ScilabCodeEvaluator, self).teardown()
def check_code(self, user_answer, file_paths, test_case):
self.files = []
diff --git a/yaksh/settings.py b/yaksh/settings.py
index b1336f4..6383999 100644
--- a/yaksh/settings.py
+++ b/yaksh/settings.py
@@ -20,21 +20,21 @@ SERVER_TIMEOUT = 4
URL_ROOT = ''
code_evaluators = {
- "python": {"standardtestcase": "python_assertion_evaluator.PythonAssertionEvaluator",
- "stdiobasedtestcase": "python_stdio_evaluator.PythonStdioEvaluator"
+ "python": {"standardtestcase": "yaksh.python_assertion_evaluator.PythonAssertionEvaluator",
+ "stdiobasedtestcase": "yaksh.python_stdio_evaluator.PythonStdioEvaluator"
},
- "c": {"standardtestcase": "cpp_code_evaluator.CppCodeEvaluator",
- "stdiobasedtestcase": "cpp_stdio_evaluator.CppStdioEvaluator"
+ "c": {"standardtestcase": "yaksh.cpp_code_evaluator.CppCodeEvaluator",
+ "stdiobasedtestcase": "yaksh.cpp_stdio_evaluator.CppStdioEvaluator"
},
- "cpp": {"standardtestcase": "cpp_code_evaluator.CppCodeEvaluator",
- "stdiobasedtestcase": "cpp_stdio_evaluator.CppStdioEvaluator"
+ "cpp": {"standardtestcase": "yaksh.cpp_code_evaluator.CppCodeEvaluator",
+ "stdiobasedtestcase": "yaksh.cpp_stdio_evaluator.CppStdioEvaluator"
},
- "java": {"standardtestcase": "java_code_evaluator.JavaCodeEvaluator",
- "stdiobasedtestcase": "java_stdio_evaluator.JavaStdioEvaluator"},
+ "java": {"standardtestcase": "yaksh.java_code_evaluator.JavaCodeEvaluator",
+ "stdiobasedtestcase": "yaksh.java_stdio_evaluator.JavaStdioEvaluator"},
- "bash": {"standardtestcase": "bash_code_evaluator.BashCodeEvaluator",
- "stdiobasedtestcase": "bash_stdio_evaluator.BashStdioEvaluator"
+ "bash": {"standardtestcase": "yaksh.bash_code_evaluator.BashCodeEvaluator",
+ "stdiobasedtestcase": "yaksh.bash_stdio_evaluator.BashStdioEvaluator"
},
- "scilab": {"standardtestcase": "scilab_code_evaluator.ScilabCodeEvaluator"},
+ "scilab": {"standardtestcase": "yaksh.scilab_code_evaluator.ScilabCodeEvaluator"},
}
diff --git a/yaksh/stdio_evaluator.py b/yaksh/stdio_evaluator.py
index efb2ae5..7530b96 100644
--- a/yaksh/stdio_evaluator.py
+++ b/yaksh/stdio_evaluator.py
@@ -1,9 +1,10 @@
+from __future__ import unicode_literals
+
# Local imports
-from code_evaluator import CodeEvaluator
+from .code_evaluator import CodeEvaluator
class StdIOEvaluator(CodeEvaluator):
-
def setup(self):
super(StdIOEvaluator, self).setup()
pass
@@ -15,7 +16,10 @@ class StdIOEvaluator(CodeEvaluator):
def evaluate_stdio(self, user_answer, proc, expected_input, expected_output):
success = False
ip = expected_input.replace(",", " ")
- user_output, output_err = proc.communicate(input='{0}\n'.format(ip))
+ encoded_input = '{0}\n'.format(ip).encode('utf-8')
+ user_output_bytes, output_err_bytes = proc.communicate(encoded_input)
+ user_output = user_output_bytes.decode('utf-8')
+ output_err = output_err_bytes.decode('utf-8')
expected_output = expected_output.replace("\r", "")
if not expected_input:
error_msg = "Expected Output is {0} ".\
@@ -30,5 +34,5 @@ class StdIOEvaluator(CodeEvaluator):
err = " Incorrect answer\n" + error_msg +\
"\n Your output is {0}".format(repr(user_output))
else:
- err = "Error:"+"\n"+output_err
+ err = "Error:\n {0}".format(output_err)
return success, err
diff --git a/yaksh/templatetags/custom_filters.py b/yaksh/templatetags/custom_filters.py
index 5baa977..9d7b939 100644
--- a/yaksh/templatetags/custom_filters.py
+++ b/yaksh/templatetags/custom_filters.py
@@ -6,6 +6,7 @@ register = template.Library()
@stringfilter
@register.filter(name='escape_quotes')
def escape_quotes(value):
+ value = value.decode("utf-8")
escape_single_quotes = value.replace("'", "\\'")
escape_single_and_double_quotes = escape_single_quotes.replace('"', '\\"')
diff --git a/yaksh/test.txt b/yaksh/test.txt
deleted file mode 100644
index 0cfbf08..0000000
--- a/yaksh/test.txt
+++ /dev/null
@@ -1 +0,0 @@
-2
diff --git a/yaksh/test_models.py b/yaksh/test_models.py
index 50ead1d..019a339 100644
--- a/yaksh/test_models.py
+++ b/yaksh/test_models.py
@@ -58,6 +58,9 @@ def setUpModule():
language='Python', prerequisite=quiz,
course=course)
+ with open('/tmp/test.txt', 'wb') as f:
+ f.write('2'.encode('ascii'))
+
def tearDownModule():
User.objects.all().delete()
Question.objects.all().delete()
@@ -66,7 +69,8 @@ def tearDownModule():
que_id_list = ["25", "22", "24", "27"]
for que_id in que_id_list:
dir_path = os.path.join(os.getcwd(), "yaksh", "data","question_{0}".format(que_id))
- shutil.rmtree(dir_path)
+ if os.path.exists(dir_path):
+ shutil.rmtree(dir_path)
###############################################################################
class ProfileTestCases(unittest.TestCase):
@@ -115,7 +119,7 @@ class QuestionTestCases(unittest.TestCase):
self.question2.save()
# create a temp directory and add files for loading questions test
- file_path = os.path.join(os.getcwd(), "yaksh", "test.txt")
+ file_path = "/tmp/test.txt"
self.load_tmp_path = tempfile.mkdtemp()
shutil.copy(file_path, self.load_tmp_path)
file1 = os.path.join(self.load_tmp_path, "test.txt")
@@ -164,7 +168,8 @@ class QuestionTestCases(unittest.TestCase):
tag_list = []
for tag in self.question1.tags.all():
tag_list.append(tag.name)
- self.assertEqual(tag_list, ['python', 'function'])
+ for tag in tag_list:
+ self.assertIn(tag, ['python', 'function'])
def test_dump_questions(self):
""" Test dump questions into json """
@@ -714,7 +719,7 @@ class AnswerPaperTestCases(unittest.TestCase):
def test_get_question_answer(self):
""" Test get_question_answer() method of Answer Paper"""
answered = self.answerpaper.get_question_answers()
- first_answer = answered.values()[0][0]
+ first_answer = list(answered.values())[0][0]
self.assertEqual(first_answer.answer, 'Demo answer')
self.assertTrue(first_answer.correct)
self.assertEqual(len(answered), 2)
@@ -895,4 +900,7 @@ class TestCaseTestCases(unittest.TestCase):
result = self.question1.consolidate_answer_data(
user_answer="demo_answer"
)
- self.assertEqual(result, self.answer_data_json)
+ actual_data = json.loads(result)
+ exp_data = json.loads(self.answer_data_json)
+ self.assertEqual(actual_data['user_answer'], exp_data['user_answer'])
+ self.assertEqual(actual_data['test_case_data'], exp_data['test_case_data'])
diff --git a/yaksh/tests/test_code_server.py b/yaksh/tests/test_code_server.py
index a73f073..8835110 100644
--- a/yaksh/tests/test_code_server.py
+++ b/yaksh/tests/test_code_server.py
@@ -1,3 +1,4 @@
+from __future__ import unicode_literals
import json
try:
from Queue import Queue
@@ -5,7 +6,7 @@ except ImportError:
from queue import Queue
from threading import Thread
import unittest
-import urllib
+from six.moves import urllib
from yaksh.code_server import ServerPool, SERVER_POOL_PORT
from yaksh import settings
@@ -18,7 +19,7 @@ class TestCodeServer(unittest.TestCase):
def setUpClass(cls):
settings.code_evaluators['python']['standardtestcase'] = \
"yaksh.python_assertion_evaluator.PythonAssertionEvaluator"
- ports = range(8001, 8006)
+ ports = range(8001, 8006)
server_pool = ServerPool(ports=ports, pool_port=SERVER_POOL_PORT)
cls.server_pool = server_pool
cls.server_thread = t = Thread(target=server_pool.run)
@@ -117,7 +118,8 @@ class TestCodeServer(unittest.TestCase):
url = "http://localhost:%s/status"%SERVER_POOL_PORT
# When
- data = urllib.urlopen(url).read()
+ response = urllib.request.urlopen(url)
+ data = response.read().decode('utf-8')
# Then
expect = 'out of 5 are free'
diff --git a/yaksh/views.py b/yaksh/views.py
index 4c5b9b8..0ed5f5a 100644
--- a/yaksh/views.py
+++ b/yaksh/views.py
@@ -21,6 +21,7 @@ from taggit.models import Tag
from itertools import chain
import json
import zipfile
+import six
# Local imports.
from yaksh.models import get_model_class, Quiz, Question, QuestionPaper, QuestionSet, Course
from yaksh.models import Profile, Answer, AnswerPaper, User, TestCase, FileUpload,\
@@ -29,9 +30,9 @@ from yaksh.forms import UserRegisterForm, UserLoginForm, QuizForm,\
QuestionForm, RandomQuestionForm,\
QuestionFilterForm, CourseForm, ProfileForm, UploadFileForm,\
get_object_form, FileForm
-from settings import URL_ROOT
+from .settings import URL_ROOT
from yaksh.models import AssignmentUpload
-from file_utils import extract_files
+from .file_utils import extract_files
@@ -982,7 +983,7 @@ def grade_user(request, quiz_id=None, user_id=None, attempt_number=None):
if request.method == "POST":
papers = data['papers']
for paper in papers:
- for question, answers in paper.get_question_answers().iteritems():
+ for question, answers in six.iteritems(paper.get_question_answers()):
marks = float(request.POST.get('q%d_marks' % question.id, 0))
answers = answers[-1]
answers.set_marks(marks)
diff --git a/yaksh/xmlrpc_clients.py b/yaksh/xmlrpc_clients.py
index 6bfe0d6..4da70dd 100644
--- a/yaksh/xmlrpc_clients.py
+++ b/yaksh/xmlrpc_clients.py
@@ -1,11 +1,19 @@
-from xmlrpclib import ServerProxy
+from __future__ import unicode_literals
import time
import random
import socket
import json
import urllib
+from six.moves import urllib
-from settings import SERVER_PORTS, SERVER_POOL_PORT
+try:
+ from xmlrpclib import ServerProxy
+except ImportError:
+ # The above import will not work on Python-3.x.
+ from xmlrpc.client import ServerProxy
+
+# Local imports
+from .settings import SERVER_PORTS, SERVER_POOL_PORT
class ConnectionError(Exception):
@@ -58,7 +66,8 @@ class CodeServerProxy(object):
return result
def _get_server(self):
- port = json.loads(urllib.urlopen(self.pool_url).read())
+ response = urllib.request.urlopen(self.pool_url)
+ port = json.loads(response.read().decode('utf-8'))
proxy = ServerProxy('http://localhost:%d' % port)
return proxy