diff options
-rwxr-xr-x | testapp/exam/code_server.py | 20 | ||||
-rw-r--r-- | testapp/exam/evaluate_bash_code.py | 20 | ||||
-rw-r--r-- | testapp/exam/evaluate_c_code.py | 13 | ||||
-rw-r--r-- | testapp/exam/evaluate_code.py | 21 | ||||
-rw-r--r-- | testapp/exam/evaluate_cpp_code.py | 4 | ||||
-rw-r--r-- | testapp/exam/evaluate_java_code.py | 13 | ||||
-rw-r--r-- | testapp/exam/evaluate_python_code.py | 24 | ||||
-rw-r--r-- | testapp/exam/evaluate_scilab_code.py | 24 | ||||
-rw-r--r-- | testapp/exam/language_registry.py | 7 |
9 files changed, 80 insertions, 66 deletions
diff --git a/testapp/exam/code_server.py b/testapp/exam/code_server.py index 111562a..697b131 100755 --- a/testapp/exam/code_server.py +++ b/testapp/exam/code_server.py @@ -40,9 +40,11 @@ from evaluate_java_code import EvaluateJavaCode from evaluate_scilab_code import EvaluateScilabCode from evaluate_bash_code import EvaluateBashCode + MY_DIR = abspath(dirname(__file__)) -## Private Protocol ########## + +# Private Protocol ########## def run_as_nobody(): """Runs the current process as nobody.""" # Set the effective uid and to that of nobody. @@ -50,6 +52,7 @@ def run_as_nobody(): os.setegid(nobody.pw_gid) os.seteuid(nobody.pw_uid) + ############################################################################### # `CodeServer` class. ############################################################################### @@ -61,10 +64,13 @@ class CodeServer(object): self.port = port self.queue = queue - ## Public Protocol ########## + # Public Protocol ########## def check_code(self, language, json_data, in_dir=None): - """Calls relevant EvaluateCode class based on language to check the answer code""" - evaluate_code_instance = self.create_class_instance(language, json_data, in_dir) + """Calls relevant EvaluateCode class based on language to check the + answer code + """ + evaluate_code_instance = self.create_class_instance(language, + json_data, in_dir) result = evaluate_code_instance.run_code() @@ -73,14 +79,14 @@ class CodeServer(object): return json.dumps(result) - ## Public Protocol ########## + # Public Protocol ########## def create_class_instance(self, language, json_data, in_dir): """Create instance of relevant EvaluateCode class based on language""" cls = registry.get_class(language) instance = cls.from_json(language, json_data, in_dir) return instance - ## Public Protocol ########## + # Public Protocol ########## def run(self): """Run XMLRPC server, serving our methods.""" server = SimpleXMLRPCServer(("localhost", self.port)) @@ -120,7 +126,7 @@ class ServerPool(object): p.start() self.servers = servers - ## Public Protocol ########## + # Public Protocol ########## def get_server_port(self): """Get available server port from ones in the pool. This will block diff --git a/testapp/exam/evaluate_bash_code.py b/testapp/exam/evaluate_bash_code.py index 49f20fa..2905d65 100644 --- a/testapp/exam/evaluate_bash_code.py +++ b/testapp/exam/evaluate_bash_code.py @@ -13,14 +13,15 @@ from language_registry import registry class EvaluateBashCode(EvaluateCode): """Tests the Bash code obtained from Code Server""" - ## Public Protocol ########## + # Public Protocol ########## def evaluate_code(self): submit_path = self.create_submit_code_file('submit.sh') self.set_file_as_executable(submit_path) get_ref_path, get_test_case_path = self.ref_code_path.strip().split(',') get_ref_path = get_ref_path.strip() get_test_case_path = get_test_case_path.strip() - ref_path, test_case_path = self.set_test_code_file_path(get_ref_path, get_test_case_path) + ref_path, test_case_path = self.set_test_code_file_path(get_ref_path, + get_test_case_path) success, err = self._check_bash_script(ref_path, submit_path, test_case_path) @@ -30,7 +31,7 @@ class EvaluateBashCode(EvaluateCode): return success, err - ## Private Protocol ########## + # Private Protocol ########## def _check_bash_script(self, ref_path, submit_path, test_case_path=None): """ Function validates student script using instructor script as @@ -86,12 +87,11 @@ class EvaluateBashCode(EvaluateCode): return False, "No test case at %s" % test_case_path if not os.access(ref_path, os.R_OK): return False, "Test script %s, not readable" % test_case_path - valid_answer = True # We initially make it one, so that we can - # stop once a test case fails - loop_count = 0 # Loop count has to be greater than or - # equal to one. - # Useful for caching things like empty - # test files,etc. + # valid_answer is True, so that we can stop once a test case fails + valid_answer = True + # loop_count has to be greater than or equal to one. + # Useful for caching things like empty test files,etc. + loop_count = 0 test_cases = open(test_case_path).readlines() num_lines = len(test_cases) for test_case in test_cases: @@ -116,4 +116,4 @@ class EvaluateBashCode(EvaluateCode): return False, err -registry.register('bash', EvaluateBashCode)
\ No newline at end of file +registry.register('bash', EvaluateBashCode) diff --git a/testapp/exam/evaluate_c_code.py b/testapp/exam/evaluate_c_code.py index d52beae..0b9e352 100644 --- a/testapp/exam/evaluate_c_code.py +++ b/testapp/exam/evaluate_c_code.py @@ -13,7 +13,7 @@ from language_registry import registry class EvaluateCCode(EvaluateCode): """Tests the C code obtained from Code Server""" - ## Public Protocol ########## + # Public Protocol ########## def evaluate_code(self): submit_path = self.create_submit_code_file('submit.c') get_ref_path = self.ref_code_path @@ -25,8 +25,8 @@ class EvaluateCCode(EvaluateCode): c_ref_output_path = os.getcwd() + '/executable' # Set command variables - compile_command = 'g++ {0} -c -o {1}'.format(submit_path, - c_user_output_path) + compile_command = 'g++ {0} -c -o {1}'.format(submit_path, + c_user_output_path) compile_main = 'g++ {0} {1} -o {2}'.format(ref_path, c_user_output_path, c_ref_output_path) @@ -43,7 +43,7 @@ class EvaluateCCode(EvaluateCode): return success, err - ## Public Protocol ########## + # Public Protocol ########## def check_code(self, ref_code_path, submit_code_path, compile_command, compile_main, run_command_args, remove_user_output, remove_ref_output): @@ -122,8 +122,7 @@ class EvaluateCCode(EvaluateCode): return success, err - - ## Public Protocol ########## + # Public Protocol ########## def remove_null_substitute_char(self, string): """Returns a string without any null and substitute characters""" stripped = "" @@ -133,4 +132,4 @@ class EvaluateCCode(EvaluateCode): return ''.join(stripped) -registry.register('c', EvaluateCCode)
\ No newline at end of file +registry.register('c', EvaluateCCode) diff --git a/testapp/exam/evaluate_code.py b/testapp/exam/evaluate_code.py index 161c1a2..b9892ed 100644 --- a/testapp/exam/evaluate_code.py +++ b/testapp/exam/evaluate_code.py @@ -16,23 +16,26 @@ from settings import SERVER_PORTS, SERVER_TIMEOUT, SERVER_POOL_PORT MY_DIR = abspath(dirname(__file__)) + # Raised when the code times-out. # c.f. http://pguides.net/python/timeout-a-function class TimeoutException(Exception): pass -## Private Protocol ########## +# Private Protocol ########## def timeout_handler(signum, frame): """A handler for the ALARM signal.""" raise TimeoutException('Code took too long to run.') + def create_signal_handler(): """Add a new signal handler for the execution of this code.""" prev_handler = signal.signal(signal.SIGALRM, timeout_handler) signal.alarm(SERVER_TIMEOUT) return prev_handler + def set_original_signal_handler(old_handler=None): """Set back any original signal handler.""" if old_handler is not None: @@ -41,18 +44,19 @@ def set_original_signal_handler(old_handler=None): else: raise Exception("Signal Handler: object cannot be NoneType") + def delete_signal_handler(): signal.alarm(0) return - ############################################################################### # `TestCode` class. ############################################################################### class EvaluateCode(object): """Tests the code obtained from Code Server""" - def __init__(self, test_case_data, language, user_answer, ref_code_path=None, in_dir=None): + def __init__(self, test_case_data, language, user_answer, + ref_code_path=None, in_dir=None): msg = 'Code took more than %s seconds to run. You probably '\ 'have an infinite loop in your code.' % SERVER_TIMEOUT self.timeout_msg = msg @@ -62,7 +66,7 @@ class EvaluateCode(object): self.ref_code_path = ref_code_path self.in_dir = in_dir - ## Public Protocol ########## + # Public Protocol ########## @classmethod def from_json(cls, language, json_data, in_dir): @@ -71,7 +75,8 @@ class EvaluateCode(object): user_answer = json_data.get("user_answer") ref_code_path = json_data.get("ref_code_path") - instance = cls(Test_case_data, language, user_answer, ref_code_path, in_dir) + instance = cls(Test_case_data, language, user_answer, ref_code_path, + in_dir) return instance def run_code(self): @@ -128,7 +133,7 @@ class EvaluateCode(object): submit_f = open(file_name, 'w') submit_f.write(self.user_answer.lstrip()) submit_f.close() - submit_path = abspath(submit_f.name) + submit_path = abspath(submit_f.name) return submit_path @@ -179,8 +184,8 @@ class EvaluateCode(object): raise return proc_compile, err - ## Private Protocol ########## + # Private Protocol ########## def _change_dir(self, in_dir): if in_dir is not None and isdir(in_dir): - os.chdir(in_dir)
\ No newline at end of file + os.chdir(in_dir) diff --git a/testapp/exam/evaluate_cpp_code.py b/testapp/exam/evaluate_cpp_code.py index ed744d1..987d041 100644 --- a/testapp/exam/evaluate_cpp_code.py +++ b/testapp/exam/evaluate_cpp_code.py @@ -14,7 +14,7 @@ from language_registry import registry class EvaluateCppCode(EvaluateCCode, EvaluateCode): """Tests the C code obtained from Code Server""" - ## Public Protocol ########## + # Public Protocol ########## def evaluate_code(self): submit_path = self.create_submit_code_file('submitstd.cpp') get_ref_path = self.ref_code_path @@ -45,4 +45,4 @@ class EvaluateCppCode(EvaluateCCode, EvaluateCode): return success, err -registry.register('cpp', EvaluateCppCode)
\ No newline at end of file +registry.register('cpp', EvaluateCppCode) diff --git a/testapp/exam/evaluate_java_code.py b/testapp/exam/evaluate_java_code.py index 9ddbbed..d04be4e 100644 --- a/testapp/exam/evaluate_java_code.py +++ b/testapp/exam/evaluate_java_code.py @@ -14,7 +14,7 @@ from language_registry import registry class EvaluateJavaCode(EvaluateCCode, EvaluateCode): """Tests the C code obtained from Code Server""" - ## Public Protocol ########## + # Public Protocol ########## def evaluate_code(self): submit_path = self.create_submit_code_file('Test.java') ref_path, test_case_path = self.set_test_code_file_path(self.ref_code_path) @@ -22,13 +22,14 @@ class EvaluateJavaCode(EvaluateCCode, EvaluateCode): # Set file paths java_student_directory = os.getcwd() + '/' - java_ref_file_name = (ref_path.split('/')[-1]) #.split('.')[0] + java_ref_file_name = (ref_path.split('/')[-1]).split('.')[0] # Set command variables compile_command = 'javac {0}'.format(submit_path), - compile_main = 'javac {0} -classpath {1} -d {2}'.format(ref_path, - java_student_directory, - java_student_directory) + compile_main = ('javac {0} -classpath ' + '{1} -d {2}').format(ref_path, + java_student_directory, + java_student_directory) run_command_args = "java -cp {0} {1}".format(java_student_directory, java_ref_file_name) remove_user_output = "{0}{1}.class".format(java_student_directory, @@ -46,4 +47,4 @@ class EvaluateJavaCode(EvaluateCCode, EvaluateCode): return success, err -registry.register('java', EvaluateJavaCode)
\ No newline at end of file +registry.register('java', EvaluateJavaCode) diff --git a/testapp/exam/evaluate_python_code.py b/testapp/exam/evaluate_python_code.py index 2682897..8892ae6 100644 --- a/testapp/exam/evaluate_python_code.py +++ b/testapp/exam/evaluate_python_code.py @@ -12,7 +12,7 @@ from language_registry import registry class EvaluatePythonCode(EvaluateCode): """Tests the Python code obtained from Code Server""" - ## Public Protocol ########## + # Public Protocol ########## def evaluate_code(self): success = False @@ -37,22 +37,24 @@ class EvaluatePythonCode(EvaluateCode): del tb return success, err - ## Private Protocol ########## + # Private Protocol ########## def _create_test_case(self): - """ - Create assert based test cases in python + """ + Create assert based test cases in python """ test_code = "" for test_case in self.test_case_data: - pos_args = ", ".join(str(i) for i in test_case.get('pos_args')) if test_case.get('pos_args') \ - else "" - kw_args = ", ".join(str(k+"="+a) for k, a in test_case.get('kw_args').iteritems()) \ + pos_args = ", ".join(str(i) for i in test_case.get('pos_args')) \ + if test_case.get('pos_args') else "" + kw_args = ", ".join(str(k+"="+a) for k, a + in test_case.get('kw_args').iteritems()) \ if test_case.get('kw_args') else "" - args = pos_args + ", " + kw_args if pos_args and kw_args else pos_args or kw_args - tcode = "assert {0}({1}) == {2}" \ - .format(test_case.get('func_name'), args, test_case.get('expected_answer')) + args = pos_args + ", " + kw_args if pos_args and kw_args \ + else pos_args or kw_args + tcode = "assert {0}({1}) == {2}".format(test_case.get('func_name'), + args, test_case.get('expected_answer')) test_code += tcode + "\n" return test_code -registry.register('python', EvaluatePythonCode)
\ No newline at end of file +registry.register('python', EvaluatePythonCode) diff --git a/testapp/exam/evaluate_scilab_code.py b/testapp/exam/evaluate_scilab_code.py index cc46605..899abc9 100644 --- a/testapp/exam/evaluate_scilab_code.py +++ b/testapp/exam/evaluate_scilab_code.py @@ -13,7 +13,7 @@ from language_registry import registry class EvaluateScilabCode(EvaluateCode): """Tests the Scilab code obtained from Code Server""" - ## Public Protocol ########## + # Public Protocol ########## def evaluate_code(self): submit_path = self.create_submit_code_file('function.sci') ref_path, test_case_path = self.set_test_code_file_path() @@ -44,34 +44,34 @@ class EvaluateScilabCode(EvaluateCode): return success, err - ## Private Protocol ########## + # Private Protocol ########## def _remove_scilab_exit(self, string): """ Removes exit, quit and abort from the scilab code """ new_string = "" - i=0 + i = 0 for line in string.splitlines(): - new_line = re.sub(r"exit.*$","",line) - new_line = re.sub(r"quit.*$","",new_line) - new_line = re.sub(r"abort.*$","",new_line) + new_line = re.sub(r"exit.*$", "", line) + new_line = re.sub(r"quit.*$", "", new_line) + new_line = re.sub(r"abort.*$", "", new_line) if line != new_line: - i=i+1 - new_string = new_string +'\n'+ new_line + i = i + 1 + new_string = new_string + '\n' + new_line return new_string, i - ## Private Protocol ########## + # Private Protocol ########## def _get_error(self, string): """ Fetches only the error from the string. Returns None if no error. """ - obj = re.search("!.+\n.+",string); + obj = re.search("!.+\n.+", string) if obj: return obj.group() return None - ## Private Protocol ########## + # Private Protocol ########## def _strip_output(self, out): """ Cleans whitespace from the output @@ -83,4 +83,4 @@ class EvaluateScilabCode(EvaluateCode): return strip_out -registry.register('scilab', EvaluateScilabCode)
\ No newline at end of file +registry.register('scilab', EvaluateScilabCode) diff --git a/testapp/exam/language_registry.py b/testapp/exam/language_registry.py index 207cd21..4d56de2 100644 --- a/testapp/exam/language_registry.py +++ b/testapp/exam/language_registry.py @@ -1,16 +1,17 @@ #!/usr/bin/env python + class LanguageRegistry(object): def __init__(self): self._registry = {} - ## Public Protocol ########## + # Public Protocol ########## def get_class(self, language): return self._registry[language] - ## Public Protocol ########## + # Public Protocol ########## def register(self, language, cls): self._registry[language] = cls -registry = LanguageRegistry()
\ No newline at end of file +registry = LanguageRegistry() |