summaryrefslogtreecommitdiff
path: root/testapp
diff options
context:
space:
mode:
authorankitjavalkar2015-02-05 14:28:48 +0530
committerankitjavalkar2015-04-26 19:31:24 +0530
commitecb202633d3b90c55128030adb7817387bf28c95 (patch)
treebc90138ce3e57ce3c2d6db3c845673077145e4c0 /testapp
parent28e2d32f9839b0e3cb3e99ce0113832627610bd7 (diff)
downloadonline_test-ecb202633d3b90c55128030adb7817387bf28c95.tar.gz
online_test-ecb202633d3b90c55128030adb7817387bf28c95.tar.bz2
online_test-ecb202633d3b90c55128030adb7817387bf28c95.zip
Modify method of passing test case attributes to code server
Conflicts: testapp/exam/admin.py testapp/exam/models.py testapp/exam/views.py
Diffstat (limited to 'testapp')
-rw-r--r--testapp/exam/admin.py3
-rwxr-xr-xtestapp/exam/code_server.py32
-rw-r--r--testapp/exam/models.py75
-rw-r--r--testapp/exam/views.py76
-rw-r--r--testapp/exam/xmlrpc_clients.py4
5 files changed, 154 insertions, 36 deletions
diff --git a/testapp/exam/admin.py b/testapp/exam/admin.py
index 060859a..1bdf436 100644
--- a/testapp/exam/admin.py
+++ b/testapp/exam/admin.py
@@ -1,5 +1,6 @@
-from testapp.exam.models import Question, Quiz
+from exam.models import Question, Quiz, TestCase
from django.contrib import admin
admin.site.register(Question)
+admin.site.register(TestCase)
admin.site.register(Quiz)
diff --git a/testapp/exam/code_server.py b/testapp/exam/code_server.py
index 64d6a47..c070986 100755
--- a/testapp/exam/code_server.py
+++ b/testapp/exam/code_server.py
@@ -68,7 +68,8 @@ class CodeServer(object):
'have an infinite loop in your code.' % SERVER_TIMEOUT
self.timeout_msg = msg
- def run_python_code(self, answer, test_code, test_obj, in_dir=None): ####
+ def run_python_code(self, answer, test_code, test_parameter, in_dir=None): ####
+ # def run_python_code(self, answer, test_code, in_dir=None): ####
"""Tests given Python function (`answer`) with the `test_code`
supplied. If the optional `in_dir` keyword argument is supplied
it changes the directory to that directory (it does not change
@@ -90,11 +91,23 @@ class CodeServer(object):
success = False
tb = None
+
+ test_code_eval = ""
+ for test_case in test_parameter:
+ # for key, val in test_case.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'))
+ test_code_eval += tcode + "\n"
try:
submitted = compile(answer, '<string>', mode='exec')
g = {}
exec submitted in g
- _tests = compile(test_code, '<string>', mode='exec')
+ _tests = compile(test_code_eval, '<string>', mode='exec')
exec _tests in g
except TimeoutException:
err = self.timeout_msg
@@ -123,7 +136,8 @@ class CodeServer(object):
return success, err
- def run_bash_code(self, answer, test_code, test_obj, in_dir=None): ####
+ # def run_bash_code(self, answer, test_code, test_parameter, in_dir=None): ####
+ def run_bash_code(self, answer, test_code, in_dir=None): ####
"""Tests given Bash code (`answer`) with the `test_code` supplied.
The testcode should typically contain two lines, the first is a path to
@@ -290,7 +304,8 @@ class CodeServer(object):
stdnt_stdout+stdnt_stderr)
return False, err
- def run_c_code(self, answer, test_code, test_obj, in_dir=None): ####
+ # def run_c_code(self, answer, test_code, test_parameter, in_dir=None): ####
+ def run_c_code(self, answer, test_code, in_dir=None): ####
"""Tests given C code (`answer`) with the `test_code` supplied.
The testcode is a path to the reference code.
@@ -442,7 +457,8 @@ class CodeServer(object):
err = err + "\n" + stdnt_stderr
return success, err
- def run_cplus_code(self, answer, test_code, test_obj, in_dir=None): ####
+ # def run_cplus_code(self, answer, test_code, test_parameter, in_dir=None): ####
+ def run_cplus_code(self, answer, test_code, in_dir=None): ####
"""Tests given C++ code (`answer`) with the `test_code` supplied.
The testcode is a path to the reference code.
@@ -504,7 +520,8 @@ class CodeServer(object):
return success, err
- def run_java_code(self, answer, test_code, test_obj, in_dir=None): ####
+ # def run_java_code(self, answer, test_code, test_parameter, in_dir=None): ####
+ 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.
@@ -659,7 +676,8 @@ class CodeServer(object):
stripped = stripped + c
return ''.join(stripped)
- def run_scilab_code(self, answer, test_code, test_obj, in_dir=None): ####
+ # def run_scilab_code(self, answer, test_code, test_parameter, in_dir=None): ####
+ def run_scilab_code(self, answer, test_code, in_dir=None): ####
"""Tests given Scilab function (`answer`) with the `test_code`
supplied. If the optional `in_dir` keyword argument is supplied
it changes the directory to that directory (it does not change
diff --git a/testapp/exam/models.py b/testapp/exam/models.py
index df3b485..4eeceac 100644
--- a/testapp/exam/models.py
+++ b/testapp/exam/models.py
@@ -62,15 +62,6 @@ class Question(models.Model):
# Test cases for the question in the form of code that is run.
test = models.TextField(blank=True)
- #Test case Keyword arguments in dict form
- test_keyword_args = models.TextField(blank=True) ####
-
- #Test case Positional arguments in list form
- test_pos_args = models.TextField(blank=True) ####
-
- #Test case Expected answer in list form
- test_expected_answer = models.TextField(blank=True) ####
-
# Any multiple choice options. Place one option per line.
options = models.TextField(blank=True)
@@ -91,6 +82,34 @@ class Question(models.Model):
# Tags for the Question.
tags = TaggableManager()
+ def consolidate_test_cases(self, test):
+ test_case_parameter= []
+
+ for i in test:
+ kw_args_dict = {}
+ pos_args_list = []
+
+ parameter_dict = {}
+ parameter_dict['test_id'] = i.id
+ parameter_dict['func_name'] = i.func_name
+ parameter_dict['expected_answer'] = i.expected_answer
+ parameter_dict['ref_code_path'] = i.ref_code_path
+
+ if i.kw_args:
+ for args in i.kw_args.split(","):
+ key, val = args.split("=")
+ kw_args_dict[key.strip()] = val.strip()
+
+ if i.pos_args:
+ for args in i.pos_args.split(","):
+ pos_args_list.append(args.strip())
+
+ parameter_dict['kw_args'] = kw_args_dict
+ parameter_dict['pos_args'] = pos_args_list
+ test_case_parameter.append(parameter_dict)
+
+ return test_case_parameter
+
def __unicode__(self):
return self.summary
@@ -411,16 +430,48 @@ class AssignmentUpload(models.Model):
class TestCase(models.Model):
question = models.ForeignKey(Question)
+ # Test case function name
+ func_name = models.CharField(max_length=200)
+
# Test case Keyword arguments in dict form
- test_keyword_args = models.TextField(blank=True)
+ kw_args = models.TextField(blank=True)
# Test case Positional arguments in list form
- test_pos_args = models.TextField(blank=True)
+ pos_args = models.TextField(blank=True)
# Test case Expected answer in list form
- test_expected_answer = models.TextField(blank=True)
+ expected_answer = models.TextField(blank=True)
+
+ # Test case path to system test code applicable for CPP, C, Java and Scilab
+ ref_code_path = models.TextField(blank=True)
# Is this Test Case public or not. If it is not
# public it will not be visible to the user
# public = models.BooleanField(default=False)
+ # def consolidate_test_cases(self):
+ # test_case_parameter= {}
+ # kw_args_dict = {}
+ # pos_args_list = []
+
+ # for i in self:
+ # test_case_parameter.setdefault(i.id, {})
+ # test_case_parameter[i.id]['func_name'] = i.func_name
+ # test_case_parameter[i.id]['expected_answer'] = i.expected_answer
+
+ # for args in i.kw_args.split(","):
+ # key, val = args.split("=")
+ # kw_args_dict[key.strip()] = val.strip()
+
+
+ # for args in i.pos_args.split(","):
+ # pos_args_list.append(args.strip())
+
+ # test_case_parameter[i.id]['kw_args'] = kw_args_dict
+ # test_case_parameter[i.id]['pos_args'] = pos_args_list
+
+ # # test_case_parameter[i.id]['kw_args'] = i.kw_args
+ # # test_case_parameter[i.id]['pos_args'] = i.pos_args
+
+ # return test_case_parameter
+
diff --git a/testapp/exam/views.py b/testapp/exam/views.py
index 9b6ce69..ac2668c 100644
--- a/testapp/exam/views.py
+++ b/testapp/exam/views.py
@@ -16,7 +16,7 @@ from taggit.models import Tag
from itertools import chain
# Local imports.
from testapp.exam.models import Quiz, Question, QuestionPaper, QuestionSet
-from testapp.exam.models import Profile, Answer, AnswerPaper, User
+from testapp.exam.models import Profile, Answer, AnswerPaper, User, TestCase
from testapp.exam.forms import UserRegisterForm, UserLoginForm, QuizForm,\
QuestionForm, RandomQuestionForm
from testapp.exam.xmlrpc_clients import code_server
@@ -848,6 +848,49 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None):
if not user.is_authenticated() or paper.end_time < datetime.datetime.now():
return my_redirect('/exam/login/')
question = get_object_or_404(Question, pk=q_id)
+ q_paper = QuestionPaper.objects.get(id=questionpaper_id)
+ paper = AnswerPaper.objects.get(user=request.user, question_paper=q_paper)
+ test = TestCase.objects.filter(question=question)
+ test_parameter = question.consolidate_test_cases(test)
+
+ # ####
+ # for i in TestCase.objects.all():
+ # print "=====$$$$$=====KEY", i.kw_args
+ # print "=====$$$$$=====POS", i.pos_args
+ # print "=====$$$$$=====FUNC", i.func_name
+
+ # test_case_parameters = {}
+ # kw_args_dict = {}
+ # pos_args_list = []
+
+ # for i in TestCase.objects.all():
+ # test_case_parameters.setdefault(i.id, {})
+ # test_case_parameters[i.id]['func_name'] = i.func_name
+ # test_case_parameters[i.id]['expected_answer'] = i.expected_answer
+
+ # for args in i.kw_args.split(","):
+ # key, val = args.split("=")
+ # kw_args_dict[key.strip()] = val.strip()
+
+
+ # for args in i.pos_args.split(","):
+ # pos_args_list.append(args.strip())
+
+ # test_case_parameters[i.id]['kw_args'] = kw_args_dict
+ # test_case_parameters[i.id]['pos_args'] = pos_args_list
+
+ # print "######-----####-----", test_case_parameters
+
+ # test_obj = TestCase.objects.filter(question=question)
+ # test_parameter = []
+ # for i in test_obj:
+ # d = {}
+ # d['test_func_name'] = i.test_func_name
+ # d['test_keyword_args'] = i.test_keyword_args
+ # d['test_pos_args'] = i.test_pos_args
+ # d['test_expected_answer'] = i.test_expected_answer
+ # test_parameter.append(d)
+ # ####
snippet_code = request.POST.get('snippet')
user_code = request.POST.get('answer')
skip = request.POST.get('skip', None)
@@ -860,6 +903,19 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None):
next_q = paper.skip()
return show_question(request, next_q, attempt_num, questionpaper_id)
+ # ### of the form addnum(1, 2, one=2, two=2)
+ # test_code_eval = ""
+ # for param in test_parameter:
+ # # print "TESTCASE----OUTLOOP", literal_eval(test_case['test_keyword_args'])
+
+ # tcode = "assert {0}({1}, {2})\n""" \
+ # .format(param.get('test_func_name'), param.get('test_pos_args'), param.get('test_keyword_args'))
+ # # .format(", ".join(str(i) for i in test_case['test_pos_args']),
+ # # ", ".join(str(key+"="+arg) for key, arg in eval(test_case['test_keyword_args']).iteritems()))
+ # test_code_eval = "\n".join(tcode)
+
+ # print test_code_eval
+
# Add the answer submitted, regardless of it being correct or not.
if question.type == 'mcq':
user_answer = request.POST.get('answer')
@@ -876,7 +932,8 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None):
assign.save()
user_answer = 'ASSIGNMENT UPLOADED'
else:
- user_answer = snippet_code + "\n" + user_code
+ user_code = request.POST.get('answer')
+ user_answer = user_code #snippet_code + "\n" + user_code
new_answer = Answer(question=question, answer=user_answer,
correct=False)
@@ -887,7 +944,7 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None):
# questions, we obtain the results via XML-RPC with the code executed
# safely in a separate process (the code_server.py) running as nobody.
if not question.type == 'upload':
- correct, success, err_msg = validate_answer(user, user_answer, question)
+ correct, success, err_msg = validate_answer(user, user_answer, question, test_parameter)
if correct:
new_answer.correct = correct
new_answer.marks = question.points
@@ -933,7 +990,7 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None):
questionpaper_id, success_msg)
-def validate_answer(user, user_answer, question):
+def validate_answer(user, user_answer, question, test_parameter):####
"""
Checks whether the answer submitted by the user is right or wrong.
If right then returns correct = True, success and
@@ -958,18 +1015,9 @@ def validate_answer(user, user_answer, question):
message = 'Correct answer'
elif question.type == 'code':
user_dir = get_user_dir(user)
- success, message = code_server.run_code(user_answer, question.test,
- question.test_keyword_args, question.test_pos_args,
- question.test_expected_answer, user_dir, question.language) ####
+ success, message = code_server.run_code(user_answer, question.test, test_parameter, user_dir, question.language) ####
if success:
correct = True
-
- ####
- print "MESS>>>", question.test
- print "POS>>>", question.test_pos_args
- print "KEY>>>", question.test_keyword_args
- print "EXP>>>", question.test_expected_answer
- ####
return correct, success, message
diff --git a/testapp/exam/xmlrpc_clients.py b/testapp/exam/xmlrpc_clients.py
index 1aab8de..320d627 100644
--- a/testapp/exam/xmlrpc_clients.py
+++ b/testapp/exam/xmlrpc_clients.py
@@ -29,7 +29,7 @@ class CodeServerProxy(object):
"scilab": "run_scilab_code",
}
- def run_code(self, answer, test_code, test_obj, keyword_args, pos_args, expected_answer, user_dir, language): ####
+ def run_code(self, answer, test_code, test_parameter, user_dir, language): ####
"""Tests given code (`answer`) with the `test_code` supplied. 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
@@ -55,7 +55,7 @@ class CodeServerProxy(object):
try:
server = self._get_server()
method = getattr(server, method_name)
- result = method(answer, test_code, test_obj, user_dir) ####
+ result = method(answer, test_code, test_parameter, user_dir) ####
except ConnectionError:
result = [False, 'Unable to connect to any code servers!']
return result