From 2a0909ef9d1107ec09a870947946cb336f0373c3 Mon Sep 17 00:00:00 2001
From: adityacp
Date: Thu, 25 Aug 2016 16:23:43 +0530
Subject: added upload and download questions with files
---
yaksh/models.py | 46 +++++++++++++++++++++++++++++++++++++++-------
yaksh/views.py | 44 +++++++++++++++++++++++++++++++++-----------
2 files changed, 72 insertions(+), 18 deletions(-)
(limited to 'yaksh')
diff --git a/yaksh/models.py b/yaksh/models.py
index 73d4b27..d626b26 100644
--- a/yaksh/models.py
+++ b/yaksh/models.py
@@ -10,9 +10,13 @@ from django.forms.models import model_to_dict
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
import pytz
import os
import shutil
+import zipfile
+
languages = (
("python", "Python"),
@@ -231,27 +235,32 @@ class Question(models.Model):
def dump_into_json(self, question_ids, user):
questions = Question.objects.filter(id__in=question_ids, user_id=user.id)
questions_dict = []
+ zip_file_name = StringIO()
+ zip_file = zipfile.ZipFile(zip_file_name, "a")
for question in questions:
test_case = question.get_test_cases()
+ files = question._add_and_get_files(zip_file)
q_dict = {'summary': question.summary,
'description': question.description,
- 'points': question.points,
- 'language': question.language,
- 'type': question.type,
- 'active': question.active,
+ 'points': question.points, 'language': question.language,
+ 'type': question.type, 'active': question.active,
'test_case_type': question.test_case_type,
'snippet': question.snippet,
- 'testcase': [case.get_field_value() for case in test_case]}
+ 'testcase': [case.get_field_value() for case in test_case],
+ 'files': files}
questions_dict.append(q_dict)
-
- return json.dumps(questions_dict, indent=2)
+ question._add_json_to_zip(zip_file, questions_dict)
+ return zip_file_name
def load_from_json(self, questions_list, user):
questions = json.loads(questions_list)
+ ques = Question()
for question in questions:
question['user'] = user
+ files = question.pop('files')
test_cases = question.pop('testcase')
que, result = Question.objects.get_or_create(**question)
+ que._add_files_to_db(files)
model_class = get_model_class(que.test_case_type)
for test_case in test_cases:
model_class.objects.get_or_create(question=que, **test_case)
@@ -278,6 +287,29 @@ class Question(models.Model):
return test_case
+ def _add_and_get_files(self, zip_file):
+ files = FileUpload.objects.filter(question=self)
+ for file in files:
+ zip_file.write(file.file.path, (os.path.basename(file.file.path)))
+ files_list = [os.path.basename(file.file.name) for file in files]
+ return files_list
+
+ def _add_files_to_db(self, files):
+ if files:
+ for file_name in files:
+ file = open(file_name, 'r')
+ django_file = File(file)
+ f = FileUpload.objects.get_or_create(file=django_file, question=self)
+ os.remove(file_name)
+
+ def _add_json_to_zip(self, zip_file, q_dict):
+ json_data = json.dumps(q_dict, indent=2)
+ with open("questions_dump.json", "w") as json_file:
+ json_file.write(json_data)
+ zip_file.write(json_file.name)
+ zip_file.close()
+ os.remove(json_file.name)
+
def __unicode__(self):
return self.summary
diff --git a/yaksh/views.py b/yaksh/views.py
index e1ec44e..87e6005 100644
--- a/yaksh/views.py
+++ b/yaksh/views.py
@@ -22,6 +22,7 @@ import pytz
from taggit.models import Tag
from itertools import chain
import json
+import zipfile
# Local imports.
from yaksh.models import get_model_class, Quiz, Question, QuestionPaper, QuestionSet, Course
@@ -73,6 +74,7 @@ def is_moderator(user):
if user.groups.filter(name='moderator').exists():
return True
+
def add_to_group(users):
""" add users to moderator group """
group = Group.objects.get(name="moderator")
@@ -80,6 +82,22 @@ def add_to_group(users):
if not is_moderator(user):
user.groups.add(group)
+
+def extract_files(questions_file):
+ if zipfile.is_zipfile(questions_file):
+ zip_file = zipfile.ZipFile(questions_file, 'r')
+ zip_file.extractall()
+
+
+def read_json(json_file, user):
+ question = Question()
+ if os.path.exists(json_file):
+ with open(json_file, 'r') as q_file:
+ questions_list = q_file.read()
+ question.load_from_json(questions_list, user)
+ os.remove(json_file)
+
+
def index(request):
"""The start page.
"""
@@ -663,9 +681,11 @@ def courses(request):
ci = RequestContext(request)
if not is_moderator(user):
raise Http404('You are not allowed to view this page')
- courses = Course.objects.filter(creator=user, is_trial=False)
+ demo_user = User.objects.get(username="demo_user")
+ courses = Course.objects.filter(Q(creator=user) | Q(creator=demo_user),
+ is_trial=False)
return my_render_to_response('yaksh/courses.html', {'courses': courses},
- context_instance=ci)
+ context_instance=ci)
@login_required
@@ -869,22 +889,24 @@ def show_all_questions(request):
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
questions_file = request.FILES['file']
- if questions_file.name.split('.')[-1] == "json":
- questions_list = questions_file.read()
- question = Question()
- question.load_from_json(questions_list, user)
+ file_name = questions_file.name.split('.')
+ if file_name[-1] == "zip":
+ extract_files(questions_file)
+ read_json("questions_dump.json", user)
else:
- message = "Please Upload a JSON file"
+ message = "Please Upload a ZIP file"
context['message'] = message
if request.POST.get('download') == 'download':
question_ids = request.POST.getlist('question')
if question_ids:
question = Question()
- questions = question.dump_into_json(question_ids, user)
- response = HttpResponse(questions, content_type='text/json')
- response['Content-Disposition'] = 'attachment; filename=\
- "{0}_questions.json"'.format(user)
+ zip_file = question.dump_into_json(question_ids, user)
+ response = HttpResponse(content_type='application/zip')
+ response['Content-Disposition'] = '''attachment;\
+ filename={0}_questions.zip'''.format(user)
+ zip_file.seek(0)
+ response.write(zip_file.read())
return response
else:
context['msg'] = "Please select atleast one question to download"
--
cgit
From 074ca3fe68b790279c6ed8e0dda580b5ade8586e Mon Sep 17 00:00:00 2001
From: adityacp
Date: Thu, 25 Aug 2016 16:24:56 +0530
Subject: changed templates to view demo quiz
---
yaksh/templates/yaksh/courses.html | 5 ++++-
yaksh/templates/yaksh/showquestions.html | 2 +-
2 files changed, 5 insertions(+), 2 deletions(-)
(limited to 'yaksh')
diff --git a/yaksh/templates/yaksh/courses.html b/yaksh/templates/yaksh/courses.html
index 06c848c..910a68d 100644
--- a/yaksh/templates/yaksh/courses.html
+++ b/yaksh/templates/yaksh/courses.html
@@ -15,9 +15,12 @@
{% else %}
Course(s) Added
{% for course in courses %}
- {% if user != course.creator %}
+ {% if user != course.creator and course.name != "Demo_course"%}
{{course.creator.get_full_name}} added you to this course
{% endif %}
+ {% if course.name == "Demo_course" %}
+ This is Demo Course
+ {% endif %}
diff --git a/yaksh/templates/yaksh/showquestions.html b/yaksh/templates/yaksh/showquestions.html
index 2f4d218..185cbfb 100644
--- a/yaksh/templates/yaksh/showquestions.html
+++ b/yaksh/templates/yaksh/showquestions.html
@@ -11,7 +11,7 @@
{% block manage %}
-
Upload json file for adding questions
+
Upload ZIP file for adding questions
@@ -156,7 +157,7 @@
{% if demo_course %}
{% with demo_course as course %}
-
This is a Demo Course
+ Demo Course
Help
@@ -199,7 +200,7 @@
{% endwith %}
-{% endif %}
+{% endif %}
{% endblock %}
--
cgit
From 4bc766cb85fd999a8e2ac6d7e87e62730edb1244 Mon Sep 17 00:00:00 2001
From: adityacp
Date: Mon, 19 Sep 2016 14:47:09 +0530
Subject: removed string comparison for demo course
---
yaksh/test_views.py | 9 ++++++---
yaksh/views.py | 12 +++++++++---
2 files changed, 15 insertions(+), 6 deletions(-)
(limited to 'yaksh')
diff --git a/yaksh/test_views.py b/yaksh/test_views.py
index 4f9b18d..e88956c 100644
--- a/yaksh/test_views.py
+++ b/yaksh/test_views.py
@@ -650,9 +650,12 @@ class TestCourses(TestCase):
self.client = Client()
self.mod_group = Group.objects.create(name='moderator')
- User.objects.get_or_create(username='demo_user',
- password='demo',
- email='demo@test.com')
+ user = User.objects.get_or_create(username='yaksh_demo_user',
+ password='demo',
+ email='demo@test.com')
+ course = Course.objects.get_or_create(name="Yaksh Demo course",
+ enrollment="open",
+ creator=user[0])
# Create Moderator with profile
self.user1_plaintext_pass = 'demo1'
self.user1 = User.objects.create_user(
diff --git a/yaksh/views.py b/yaksh/views.py
index 6d5ac30..3e42b64 100644
--- a/yaksh/views.py
+++ b/yaksh/views.py
@@ -256,9 +256,15 @@ def add_quiz(request, course_id, quiz_id=None):
user = request.user
course = get_object_or_404(Course, pk=course_id)
ci = RequestContext(request)
- if course.name != "Yaksh_Demo_course":
- if not is_moderator(user) or (user != course.creator and user not in course.teachers.all()):
- raise Http404('You are not allowed to view this page!')
+ if not is_moderator(user):
+ raise Http404('You are not allowed to view this page!')
+ try:
+ demo_user = User.objects.get(username="yaksh_demo_user")
+ except User.DoesNotExist:
+ demo_user = None
+ if course.creator != demo_user:
+ if (user != course.creator and user not in course.teachers.all()):
+ raise Http404('You are not allowed to view this course !')
context = {}
if request.method == "POST":
if quiz_id is None:
--
cgit
From 485f3a74a59402fa2adca7bbea025b856f12d854 Mon Sep 17 00:00:00 2001
From: adityacp
Date: Tue, 20 Sep 2016 14:52:05 +0530
Subject: deleted course fixture file
---
yaksh/management/commands/create_demo_course.py | 99 -------------------------
1 file changed, 99 deletions(-)
delete mode 100644 yaksh/management/commands/create_demo_course.py
(limited to 'yaksh')
diff --git a/yaksh/management/commands/create_demo_course.py b/yaksh/management/commands/create_demo_course.py
deleted file mode 100644
index 6e2712f..0000000
--- a/yaksh/management/commands/create_demo_course.py
+++ /dev/null
@@ -1,99 +0,0 @@
-import os
-import sys
-from django.core.management.base import BaseCommand
-from yaksh.models import Course, Question, Quiz, QuestionPaper, Profile, FileUpload
-from yaksh.file_utils import extract_files
-from yaksh.views import add_to_group
-from django.contrib.auth.models import User
-from django.utils import timezone
-from django.contrib.auth.models import Group
-from datetime import datetime, timedelta
-
-
-def create_demo_course():
- """ creates a demo course, quiz """
-
- success = False
- group = Group.objects.filter(name="moderator")
- if group:
- print("Creating Demo User...")
- # create a demo user
- user, u_status = User.objects.get_or_create(username='yaksh_demo_user',
- email='demo@test.com')
- user.set_password("demo")
- user.save()
- Profile.objects.get_or_create(user=user, roll_number=0,
- institute='demo_institute',
- department='demo_department',
- position='Faculty')
- # add demo user to moderator group
- demo_user = User.objects.filter(username='yaksh_demo_user')
- add_to_group(demo_user)
- else:
- print ("Please Create 'moderator' Group")
- print ("Unable to create Demo Course")
- sys.exit()
-
- print("Creating Demo Course...")
- # create a demo course
- course, c_status = Course.objects.get_or_create(name="Yaksh Demo course",
- enrollment="open",
- creator=user)
-
- print("Creating Demo Quiz...")
- demo_quiz = Quiz.objects.filter(course=course)
- if not demo_quiz:
- # create a demo quiz
- demo_quiz = Quiz.objects.get_or_create(start_date_time=timezone.now(),
- end_date_time=timezone.now() + timedelta(176590),
- duration=30, active=True,
- attempts_allowed=-1,
- time_between_attempts=0,
- description='Yaksh Demo quiz', pass_criteria=0,
- language='Python', prerequisite=None,
- course=course)
- else:
- print("Demo Quiz Already Created")
-
- print("Creating Demo Questions...")
- questions = Question.objects.filter(active=True, summary="Yaksh Demo Question")
- files = FileUpload.objects.filter(question__in=questions)
- if not files:
- #create demo question
- f_path = os.path.join(os.getcwd(), 'yaksh', 'fixtures', 'demo_questions.json')
- zip_file_path = os.path.join(os.getcwd(), 'yaksh', 'fixtures', 'demo_questions.zip')
- extract_files(zip_file_path)
- ques = Question()
- ques.read_json("questions_dump.json", user)
-
- if questions:
- print("Creating Demo Question Paper...")
- # create a demo questionpaper
- que_ppr = QuestionPaper.objects.filter(quiz=demo_quiz[0])
- if not que_ppr:
- question_paper, q_ppr_status = QuestionPaper.objects.get_or_create(quiz=demo_quiz[0],
- total_marks=5.0,
- shuffle_questions=True
- )
- # add fixed set of questions to the question paper
- for question in questions:
- question_paper.fixed_questions.add(question)
- else:
- print("Question Paper Already Created")
- else:
- print("Questions Not Found Please Check Question Summary")
-
- success = True
- return success
-
-
-class Command(BaseCommand):
- help = "Create a Demo Course, Demo Quiz"
-
- def handle(self, *args, **options):
- """ Handle command to create demo course """
- status = create_demo_course()
- if status:
- self.stdout.write("Successfully Created")
- else:
- self.stdout.write("Unable to create Demo Course")
--
cgit
From 6d3ece46b9a6569c711e20db2c3220e32a82751c Mon Sep 17 00:00:00 2001
From: adityacp
Date: Tue, 20 Sep 2016 14:53:01 +0530
Subject: changed manage and courses template
---
yaksh/templates/manage.html | 20 ++++++++++++++++
yaksh/templates/yaksh/courses.html | 47 --------------------------------------
2 files changed, 20 insertions(+), 47 deletions(-)
(limited to 'yaksh')
diff --git a/yaksh/templates/manage.html b/yaksh/templates/manage.html
index b628a44..ea587df 100644
--- a/yaksh/templates/manage.html
+++ b/yaksh/templates/manage.html
@@ -77,6 +77,26 @@
Moderator's Dashboard!
Click on the button given below to add a new course.
+ Click on the button to Create a Demo course.
+ Help
+
+
+
+
+ - A Demo Course and Demo Quiz will be created (Click Courses link on nav bar to view courses).
+ - Some Demo Questions are also created for you (Click Questions link on nav bar to view questions).
+ - In Courses you can view Demo Quiz.
+ - Click on the Demo Quiz and Click on User Mode or God Mode to take the quiz.
+
+ - You can also edit Demo quiz.
+
+
+
+ Close
+
+ {% if msg %}
+ {{ msg }}
+ {% endif %}
{% if trial_paper %}
You have trial papers.
diff --git a/yaksh/templates/yaksh/courses.html b/yaksh/templates/yaksh/courses.html
index bfc3cd8..43f323b 100644
--- a/yaksh/templates/yaksh/courses.html
+++ b/yaksh/templates/yaksh/courses.html
@@ -155,52 +155,5 @@
{% endif %}
-{% if demo_course %}
-{% with demo_course as course %}
- Demo Course
- Help
-
-
-
- - This is a Demo Course
-
- - You will not be able to edit Demo course and Demo Quiz.
- - You can only take Demo Quiz by User Mode or God Mode.
- - This is for you to get familiar with the interface.
-
-
- Close
-
-
-
-
-
-
- Course
- {% if course.active %}
- Active
- {% else %}
- Closed
- {% endif %}
-
-
{{ course.name }}
-
-
-
-
Quiz(zes)
- {% if course.get_quizzes %}
- {% for quiz in course.get_quizzes %}
-
{{ quiz.description }}
- {% endfor %}
- {% else %}
-
No quiz
- {% endif %}
-
-
-
-
-{% endwith %}
-
-{% endif %}
{% endblock %}
--
cgit
From f420bf2cf6b755dee76338134994f9746bbc0d2b Mon Sep 17 00:00:00 2001
From: adityacp
Date: Tue, 20 Sep 2016 14:55:41 +0530
Subject: removed user creation for demo course
---
yaksh/test_views.py | 6 ------
1 file changed, 6 deletions(-)
(limited to 'yaksh')
diff --git a/yaksh/test_views.py b/yaksh/test_views.py
index e88956c..8a38942 100644
--- a/yaksh/test_views.py
+++ b/yaksh/test_views.py
@@ -650,12 +650,6 @@ class TestCourses(TestCase):
self.client = Client()
self.mod_group = Group.objects.create(name='moderator')
- user = User.objects.get_or_create(username='yaksh_demo_user',
- password='demo',
- email='demo@test.com')
- course = Course.objects.get_or_create(name="Yaksh Demo course",
- enrollment="open",
- creator=user[0])
# Create Moderator with profile
self.user1_plaintext_pass = 'demo1'
self.user1 = User.objects.create_user(
--
cgit
From 2ac8383ceb3f8850043ab317a7a7ebd2bfcf3921 Mon Sep 17 00:00:00 2001
From: adityacp
Date: Tue, 20 Sep 2016 14:56:10 +0530
Subject: added url for demo course
---
yaksh/urls.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
(limited to 'yaksh')
diff --git a/yaksh/urls.py b/yaksh/urls.py
index daa6008..fb23c7b 100644
--- a/yaksh/urls.py
+++ b/yaksh/urls.py
@@ -101,5 +101,6 @@ urlpatterns += [
url(r'^manage/remove_teachers/(?P\d+)/$', views.remove_teachers, name='remove_teacher'),
url(r'^manage/download_questions/$', views.show_all_questions),
url(r'^manage/upload_questions/$', views.show_all_questions),
- url(r'^manage/(?P[\w\-]+)/(?P\d+)/$', views.test_quiz)
+ url(r'^manage/(?P[\w\-]+)/(?P\d+)/$', views.test_quiz),
+ url(r'^manage/create_demo_course/$', views.create_demo_course),
]
--
cgit
From 4d8a0b41935ecc182c90acf34e7696a207a664f6 Mon Sep 17 00:00:00 2001
From: adityacp
Date: Tue, 20 Sep 2016 14:56:55 +0530
Subject: Demo course creation without initial fixtures
---
yaksh/models.py | 47 +++++++++++++++++++++++++++++++++++++++++++++++
yaksh/views.py | 38 ++++++++++++++++++++------------------
2 files changed, 67 insertions(+), 18 deletions(-)
(limited to 'yaksh')
diff --git a/yaksh/models.py b/yaksh/models.py
index e7a60df..870d8b9 100644
--- a/yaksh/models.py
+++ b/yaksh/models.py
@@ -17,6 +17,7 @@ import os
import shutil
import zipfile
import tempfile
+from file_utils import extract_files
languages = (
@@ -155,6 +156,23 @@ class Course(models.Model):
def remove_teachers(self, *teachers):
self.teachers.remove(*teachers)
+ def create_demo(self, user):
+ course = Course.objects.filter(creator=user, name="Yaksh Demo course")
+ if not course:
+ course, c_status= Course.objects.get_or_create(name="Yaksh Demo course",
+ enrollment="open",
+ creator=user)
+ quiz = Quiz()
+ demo_quiz = quiz.create_demo_quiz(course)
+ demo_ques = Question()
+ demo_ques.create_demo_questions(user)
+ demo_que_ppr = QuestionPaper()
+ demo_que_ppr.create_demo_que_ppr(demo_quiz)
+ success = True
+ else:
+ success = False
+ return success
+
def __unicode__(self):
return self.name
@@ -323,6 +341,13 @@ class Question(models.Model):
self.load_questions(questions_list, user)
os.remove(json_file)
+ def create_demo_questions(self, user):
+ zip_file_path = os.path.join(os.getcwd(), 'yaksh',
+ 'fixtures', 'demo_questions.zip')
+ extract_files(zip_file_path)
+ self.read_json("questions_dump.json", user)
+
+
def __unicode__(self):
return self.summary
@@ -487,6 +512,17 @@ class Quiz(models.Model):
def has_prerequisite(self):
return True if self.prerequisite else False
+
+ def create_demo_quiz(self, course):
+ demo_quiz = Quiz.objects.get_or_create(start_date_time=timezone.now(),
+ end_date_time=timezone.now() + timedelta(176590),
+ duration=30, active=True,
+ attempts_allowed=-1,
+ time_between_attempts=0,
+ description='Yaksh Demo quiz', pass_criteria=0,
+ language='Python', prerequisite=None,
+ course=course)
+ return demo_quiz
def __unicode__(self):
desc = self.description or 'Quiz'
@@ -618,6 +654,17 @@ class QuestionPaper(models.Model):
if self.quiz.has_prerequisite():
prerequisite = self._get_prequisite_paper()
return prerequisite._is_questionpaper_passed(user)
+
+ def create_demo_que_ppr(self, demo_quiz):
+ question_paper = QuestionPaper.objects.get_or_create(quiz=demo_quiz[0],
+ total_marks=5.0,
+ shuffle_questions=True
+ )
+ questions = Question.objects.filter(active=True,
+ summary="Yaksh Demo Question")
+ # add fixed set of questions to the question paper
+ for question in questions:
+ question_paper[0].fixed_questions.add(question)
def __unicode__(self):
return "Question Paper for " + self.quiz.description
diff --git a/yaksh/views.py b/yaksh/views.py
index 3e42b64..959d323 100644
--- a/yaksh/views.py
+++ b/yaksh/views.py
@@ -256,15 +256,8 @@ def add_quiz(request, course_id, quiz_id=None):
user = request.user
course = get_object_or_404(Course, pk=course_id)
ci = RequestContext(request)
- if not is_moderator(user):
- raise Http404('You are not allowed to view this page!')
- try:
- demo_user = User.objects.get(username="yaksh_demo_user")
- except User.DoesNotExist:
- demo_user = None
- if course.creator != demo_user:
- if (user != course.creator and user not in course.teachers.all()):
- raise Http404('You are not allowed to view this course !')
+ if not is_moderator(user) or (user != course.creator and user not in course.teachers.all()):
+ raise Http404('You are not allowed to view this course !')
context = {}
if request.method == "POST":
if quiz_id is None:
@@ -688,18 +681,10 @@ def courses(request):
ci = RequestContext(request)
if not is_moderator(user):
raise Http404('You are not allowed to view this page')
- try:
- demo_user = User.objects.get(username="yaksh_demo_user")
- demo_course = Course.objects.get(creator=demo_user)
- except User.DoesNotExist, Course.DoesNotExist:
- demo_user = None
- demo_course = None
-
courses = Course.objects.filter(creator=user, is_trial=False)
allotted_courses = Course.objects.filter(teachers=user, is_trial=False)
- context = {'courses': courses, "allotted_courses": allotted_courses,
- 'demo_course': demo_course}
+ context = {'courses': courses, "allotted_courses": allotted_courses}
return my_render_to_response('yaksh/courses.html', context,
context_instance=ci)
@@ -1309,3 +1294,20 @@ def view_answerpaper(request, questionpaper_id):
return my_render_to_response('yaksh/view_answerpaper.html', context)
else:
return my_redirect('/exam/quizzes/')
+
+
+@login_required
+def create_demo_course(request):
+ """ creates a demo course for user """
+ user = request.user
+ ci = RequestContext(request)
+ if not is_moderator(user):
+ raise("You are not allowed to view this page")
+ demo_course = Course()
+ success = demo_course.create_demo(user)
+ if success:
+ msg = "Created Demo course successfully"
+ else:
+ msg = "Demo course already created"
+ context = {'msg': msg}
+ return my_render_to_response('manage.html', context, context_instance=ci)
--
cgit
From a689afd85ef3f0e4ddb8255e06c50f400bebd165 Mon Sep 17 00:00:00 2001
From: adityacp
Date: Tue, 20 Sep 2016 16:09:54 +0530
Subject: used create method instead of get_or_create to create course
---
yaksh/models.py | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
(limited to 'yaksh')
diff --git a/yaksh/models.py b/yaksh/models.py
index 870d8b9..d176c57 100644
--- a/yaksh/models.py
+++ b/yaksh/models.py
@@ -159,9 +159,9 @@ class Course(models.Model):
def create_demo(self, user):
course = Course.objects.filter(creator=user, name="Yaksh Demo course")
if not course:
- course, c_status= Course.objects.get_or_create(name="Yaksh Demo course",
- enrollment="open",
- creator=user)
+ course = Course.objects.create(name="Yaksh Demo course",
+ enrollment="open",
+ creator=user)
quiz = Quiz()
demo_quiz = quiz.create_demo_quiz(course)
demo_ques = Question()
@@ -514,7 +514,7 @@ class Quiz(models.Model):
return True if self.prerequisite else False
def create_demo_quiz(self, course):
- demo_quiz = Quiz.objects.get_or_create(start_date_time=timezone.now(),
+ demo_quiz = Quiz.objects.create(start_date_time=timezone.now(),
end_date_time=timezone.now() + timedelta(176590),
duration=30, active=True,
attempts_allowed=-1,
@@ -656,15 +656,15 @@ class QuestionPaper(models.Model):
return prerequisite._is_questionpaper_passed(user)
def create_demo_que_ppr(self, demo_quiz):
- question_paper = QuestionPaper.objects.get_or_create(quiz=demo_quiz[0],
- total_marks=5.0,
- shuffle_questions=True
- )
+ question_paper = QuestionPaper.objects.create(quiz=demo_quiz,
+ total_marks=5.0,
+ shuffle_questions=True
+ )
questions = Question.objects.filter(active=True,
summary="Yaksh Demo Question")
# add fixed set of questions to the question paper
for question in questions:
- question_paper[0].fixed_questions.add(question)
+ question_paper.fixed_questions.add(question)
def __unicode__(self):
return "Question Paper for " + self.quiz.description
--
cgit
From e1811e3560742a4070f3e92e059a7cd1c50f1f36 Mon Sep 17 00:00:00 2001
From: adityacp
Date: Wed, 21 Sep 2016 14:38:00 +0530
Subject: changed func name from create_demo_que_ppr to create_demo_quiz_paper
---
yaksh/models.py | 4 ++--
yaksh/templates/manage.html | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
(limited to 'yaksh')
diff --git a/yaksh/models.py b/yaksh/models.py
index d176c57..71cd258 100644
--- a/yaksh/models.py
+++ b/yaksh/models.py
@@ -167,7 +167,7 @@ class Course(models.Model):
demo_ques = Question()
demo_ques.create_demo_questions(user)
demo_que_ppr = QuestionPaper()
- demo_que_ppr.create_demo_que_ppr(demo_quiz)
+ demo_que_ppr.create_demo_quiz_ppr(demo_quiz)
success = True
else:
success = False
@@ -655,7 +655,7 @@ class QuestionPaper(models.Model):
prerequisite = self._get_prequisite_paper()
return prerequisite._is_questionpaper_passed(user)
- def create_demo_que_ppr(self, demo_quiz):
+ def create_demo_quiz_ppr(self, demo_quiz):
question_paper = QuestionPaper.objects.create(quiz=demo_quiz,
total_marks=5.0,
shuffle_questions=True
diff --git a/yaksh/templates/manage.html b/yaksh/templates/manage.html
index ea587df..a736b0a 100644
--- a/yaksh/templates/manage.html
+++ b/yaksh/templates/manage.html
@@ -88,7 +88,7 @@
In Courses you can view Demo Quiz.
Click on the Demo Quiz and Click on User Mode or God Mode to take the quiz.
- You can also edit Demo quiz.
+ You can also edit the Demo quiz.
--
cgit
From 95b7927ff4d192c58c1160531b6f8c8c9259f1e4 Mon Sep 17 00:00:00 2001
From: ankitjavalkar
Date: Fri, 19 Aug 2016 20:21:36 +0530
Subject: Add selenium based test
---
yaksh/selenium_test/selenium_test.py | 141 ++++++++++++++++++++++++++++++++
yaksh/selenium_test/test_load.py | 101 +++++++++++++++++++++++
yaksh/selenium_test/test_questions.json | 50 +++++++++++
3 files changed, 292 insertions(+)
create mode 100644 yaksh/selenium_test/selenium_test.py
create mode 100644 yaksh/selenium_test/test_load.py
create mode 100644 yaksh/selenium_test/test_questions.json
(limited to 'yaksh')
diff --git a/yaksh/selenium_test/selenium_test.py b/yaksh/selenium_test/selenium_test.py
new file mode 100644
index 0000000..6a32b61
--- /dev/null
+++ b/yaksh/selenium_test/selenium_test.py
@@ -0,0 +1,141 @@
+from selenium import webdriver
+from selenium.webdriver.common.keys import Keys
+
+import multiprocessing
+import argparse
+
+class SeleniumTest():
+ def __init__(self, url, quiz_name):
+ self.driver = webdriver.Firefox()
+ self.quiz_name = quiz_name
+ self.url = url
+
+ def run_load_test(self, url, username, password):
+ try:
+ self.driver.delete_all_cookies()
+ self.driver.get(self.url)
+ self.login(username, password)
+ self.open_quiz()
+ self.close_quiz()
+ self.logout()
+ self.driver.close()
+ except Exception as e:
+ with open("/tmp/yaksh_load_test_log.txt", "ab") as f:
+ f.write('Username: {0}\nError: {1}\n'.format(username, e))
+ self.driver.close()
+
+ def login(self, username, password):
+ # get the username, password and submit form elements
+ username_elem = self.driver.find_element_by_id("id_username")
+ password_elem = self.driver.find_element_by_id("id_password")
+ submit_login_elem = self.driver.find_element_by_css_selector('button.btn')
+
+ # Type in the username, password and submit form
+ username_elem.send_keys(username)
+ password_elem.send_keys(password)
+ submit_login_elem.click()
+
+ def submit_answer(self, question_label, answer, loop_count=1):
+ self.driver.implicitly_wait(2)
+ for count in range(loop_count):
+ self.driver.find_element_by_link_text(question_label).click()
+ submit_answer_elem = self.driver.find_element_by_id("check")
+ self.driver.execute_script('editor.setValue({})'.format(answer))
+ submit_answer_elem.click()
+
+ def test_c_question(self, question_label):
+ # Incorrect Answer
+ loop_count = 10
+ answer = '\"int add(int a, int b, int c)\\n{return;}\"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ # Infinite Loop
+ loop_count = 3
+ answer = '\"int add(int a, int b, int c)\\n{while(1){}}\"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ # Correct Answer
+ loop_count = 1
+ answer = '\"int add(int a, int b, int c)\\n{return a + b + c;}\"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ def test_python_question(self, question_label):
+ # Incorrect Answer
+ loop_count = 10
+ answer = '\"def is_palindrome(s):\\n return s\"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ # Infinite Loop
+ loop_count = 3
+ answer = '\"while True:\\n pass"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ # Correct Answer
+ loop_count = 1
+ answer = '\"def is_palindrome(s):\\n return s[::-1] == s\"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ def test_bash_question(self, question_label):
+ # Incorrect Answer
+ loop_count = 10
+ answer = '\"#!/bin/bash\\nls\"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ # Infinite Loop
+ loop_count = 3
+ answer = '\"#!/bin/bash\\nwhile [ 1 ]; do : ; done\"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ # Correct Answer
+ loop_count = 1
+ answer = '\"#!/bin/bash\\ncat $1| cut -d: -f2 | paste -d: $3 - $2\"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ def open_quiz(self):
+ # open quiz link
+ quiz_link_elem = self.driver.find_element_by_link_text(self.quiz_name).click()
+ self.driver.implicitly_wait(2)
+
+ # Get page elements
+ start_exam_elem = self.driver.find_element_by_name("start")
+ start_exam_elem.click()
+
+ quit_exam_elem = self.driver.find_element_by_name("quit")
+
+ self.test_c_question(question_label=3)
+ self.test_python_question(question_label=1)
+ self.test_bash_question(question_label=2)
+
+ def close_quiz(self):
+ self.driver.implicitly_wait(5)
+ quit_link_elem = self.driver.find_element_by_id("login_again")
+ quit_link_elem.click()
+
+ def logout(self):
+ self.driver.implicitly_wait(5)
+ logout_link_elem = self.driver.find_element_by_id("logout")
+ logout_link_elem.click()
+
+def user_gen(url, ids):
+ return [(url, 'User%d'%x, 'User%d'%x) for x in ids]
+
+def wrap_run_load_test(args):
+ url = "http://yaksh.fossee.aero.iitb.ac.in/exam/"
+ quiz_name = "sel quiz 1"
+ selenium_test = SeleniumTest(url=url, quiz_name=quiz_name)
+ return selenium_test.run_load_test(*args)
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser()
+ parser.add_argument('start', type=int, help="Starting user id")
+ parser.add_argument("-n", "--number", type=int, default=10, help="number of users")
+ opts = parser.parse_args()
+
+ url = "http://yaksh.fossee.aero.iitb.ac.in/exam/"
+ quiz_name = "yaksh demo quiz"
+ selenium_test = SeleniumTest(url=url, quiz_name=quiz_name)
+ pool = multiprocessing.Pool(opts.number)
+ pool.map(wrap_run_load_test, user_gen(url, range(opts.start, opts.start + opts.number)))
+ pool.close()
+ pool.join()
+
diff --git a/yaksh/selenium_test/test_load.py b/yaksh/selenium_test/test_load.py
new file mode 100644
index 0000000..c552137
--- /dev/null
+++ b/yaksh/selenium_test/test_load.py
@@ -0,0 +1,101 @@
+import os
+import signal
+import subprocess
+from datetime import datetime
+import pytz
+from threading import Thread
+from selenium.webdriver.firefox.webdriver import WebDriver
+
+from django.contrib.staticfiles.testing import StaticLiveServerTestCase
+
+from yaksh.models import User, Profile, Question, Quiz, Course, QuestionPaper, TestCase
+from selenium_test import SeleniumTest
+
+from yaksh.code_server import ServerPool, SERVER_POOL_PORT, SERVER_PORTS
+from yaksh import settings
+from yaksh.xmlrpc_clients import CodeServerProxy
+
+CUR_DIR = os.path.dirname(os.path.abspath(__file__))
+
+class MySeleniumTests(StaticLiveServerTestCase):
+ @classmethod
+ def setUpClass(cls):
+ super(MySeleniumTests, cls).setUpClass()
+ # setup a demo code server
+ settings.code_evaluators['python']['standardtestcase'] = \
+ "yaksh.python_assertion_evaluator.PythonAssertionEvaluator"
+ settings.code_evaluators['c']['standardtestcase'] = \
+ "yaksh.cpp_code_evaluator.CppCodeEvaluator"
+ settings.code_evaluators['bash']['standardtestcase'] = \
+ "yaksh.bash_code_evaluator.BashCodeEvaluator"
+ code_server_pool = ServerPool(ports=SERVER_PORTS, pool_port=SERVER_POOL_PORT)
+ cls.code_server_pool = code_server_pool
+ cls.code_server_thread = t = Thread(target=code_server_pool.run)
+ t.start()
+
+ # Create set of demo users and profiles
+ mod_user = User.objects.create_user(username='yaksh_demo_mod',
+ password='yaksh_demo_mod',
+ email='yaksh_demo_mod@test.com'
+ )
+
+ user = User.objects.create_user(username='demo_yaksh_user',
+ password='demo_yaksh_user',
+ email='demo_yaksh_user@test.com'
+ )
+ Profile.objects.create(user=user,
+ roll_number='demo_rn',
+ institute='IIT',
+ department='Chemical',
+ position='Student'
+ )
+
+ # create a course
+ course = Course.objects.create(name="Demo Load Course",
+ enrollment="Open Course",
+ creator=mod_user
+ )
+ course.students.add(user)
+
+ # create a Quiz
+ quiz = Quiz.objects.create(
+ start_date_time=datetime(2015, 10, 9, 10, 8, 15, 0, tzinfo=pytz.utc),
+ end_date_time=datetime(2199, 10, 9, 10, 8, 15, 0, tzinfo=pytz.utc),
+ duration=30, active=True,
+ attempts_allowed=1, time_between_attempts=0,
+ description='yaksh demo quiz', pass_criteria=0,
+ language='Python', prerequisite=None,
+ course=course
+ )
+
+ # create a question set
+ question = Question()
+ with open(os.path.join(CUR_DIR, 'test_questions.json'), 'r') as f:
+ question_list = f.read()
+ question.load_from_json(question_list, mod_user)
+
+ # create question paper
+ question_paper = QuestionPaper.objects.create(quiz=quiz,
+ total_marks=5,
+ shuffle_questions=False
+ )
+ # add fixed set of questions to the question paper
+ question_paper.fixed_questions.add(*Question.objects.all())
+
+ @classmethod
+ def tearDownClass(cls):
+ User.objects.all().delete()
+ Question.objects.all().delete()
+ Quiz.objects.all().delete()
+ Course.objects.all().delete()
+
+ cls.code_server_pool.stop()
+ cls.code_server_thread.join()
+
+ super(MySeleniumTests, cls).tearDownClass()
+
+ def test_load(self):
+ url = '%s%s' % (self.live_server_url, '/exam/login/')
+ quiz_name = "yaksh demo quiz"
+ selenium_test = SeleniumTest(url=url, quiz_name=quiz_name)
+ selenium_test.run_load_test(url=url, username='demo_yaksh_user', password='demo_yaksh_user')
diff --git a/yaksh/selenium_test/test_questions.json b/yaksh/selenium_test/test_questions.json
new file mode 100644
index 0000000..f1cf02f
--- /dev/null
+++ b/yaksh/selenium_test/test_questions.json
@@ -0,0 +1,50 @@
+[
+ {
+ "snippet": "",
+ "testcase": [
+ {
+ "test_case": "assert is_palindrome(\"hello\") == False"
+ },
+ {
+ "test_case": "assert is_palindrome(\"nitin\") == True"
+ }
+ ],
+ "points": 3.0,
+ "test_case_type": "standardtestcase",
+ "description": "Write a function is_palindrome(arg)
which will take one string argument. Return true if the argument is palindrome & false otherwise.\r\n
\r\nFor Example:\r\n
\r\nis_palindrome(\"Hello\")
should return False
\r\n
\r\n
",
+ "language": "python",
+ "active": true,
+ "type": "code",
+ "summary": "Python, check palindrome (Code)"
+ },
+ {
+ "snippet": "#!/bin/bash",
+ "testcase": [
+ {
+ "test_case": "/src/yaksh/bash_files/sample.sh,/src/yaksh/bash_files/sample.args"
+ }
+ ],
+ "points": 1.0,
+ "test_case_type": "standardtestcase",
+ "description": "Write a bash script that takes exactly two arguments and returns the sum of the numbers",
+ "language": "bash",
+ "active": true,
+ "type": "code",
+ "summary": "Bash Question Concatenate Files(Code)"
+ },
+ {
+ "snippet": "",
+ "testcase": [
+ {
+ "test_case": "c_cpp_files/main2.c"
+ }
+ ],
+ "points": 1.0,
+ "test_case_type": "standardtestcase",
+ "description": "Write a program to add 3 nos",
+ "language": "c",
+ "active": true,
+ "type": "code",
+ "summary": "selenium test"
+ }
+]
--
cgit
From 87930b211e3011ad0e2da982519ef5e6ef5ab865 Mon Sep 17 00:00:00 2001
From: ankitjavalkar
Date: Mon, 29 Aug 2016 17:42:00 +0530
Subject: - Change path of selenium tests - Add to travis
---
yaksh/selenium_test/selenium_test.py | 141 ------------------------------
yaksh/selenium_test/test_load.py | 101 ----------------------
yaksh/selenium_test/test_questions.json | 50 -----------
yaksh/tests/selenium_test.py | 148 ++++++++++++++++++++++++++++++++
yaksh/tests/test_load.py | 101 ++++++++++++++++++++++
yaksh/tests/test_questions.json | 50 +++++++++++
6 files changed, 299 insertions(+), 292 deletions(-)
delete mode 100644 yaksh/selenium_test/selenium_test.py
delete mode 100644 yaksh/selenium_test/test_load.py
delete mode 100644 yaksh/selenium_test/test_questions.json
create mode 100644 yaksh/tests/selenium_test.py
create mode 100644 yaksh/tests/test_load.py
create mode 100644 yaksh/tests/test_questions.json
(limited to 'yaksh')
diff --git a/yaksh/selenium_test/selenium_test.py b/yaksh/selenium_test/selenium_test.py
deleted file mode 100644
index 6a32b61..0000000
--- a/yaksh/selenium_test/selenium_test.py
+++ /dev/null
@@ -1,141 +0,0 @@
-from selenium import webdriver
-from selenium.webdriver.common.keys import Keys
-
-import multiprocessing
-import argparse
-
-class SeleniumTest():
- def __init__(self, url, quiz_name):
- self.driver = webdriver.Firefox()
- self.quiz_name = quiz_name
- self.url = url
-
- def run_load_test(self, url, username, password):
- try:
- self.driver.delete_all_cookies()
- self.driver.get(self.url)
- self.login(username, password)
- self.open_quiz()
- self.close_quiz()
- self.logout()
- self.driver.close()
- except Exception as e:
- with open("/tmp/yaksh_load_test_log.txt", "ab") as f:
- f.write('Username: {0}\nError: {1}\n'.format(username, e))
- self.driver.close()
-
- def login(self, username, password):
- # get the username, password and submit form elements
- username_elem = self.driver.find_element_by_id("id_username")
- password_elem = self.driver.find_element_by_id("id_password")
- submit_login_elem = self.driver.find_element_by_css_selector('button.btn')
-
- # Type in the username, password and submit form
- username_elem.send_keys(username)
- password_elem.send_keys(password)
- submit_login_elem.click()
-
- def submit_answer(self, question_label, answer, loop_count=1):
- self.driver.implicitly_wait(2)
- for count in range(loop_count):
- self.driver.find_element_by_link_text(question_label).click()
- submit_answer_elem = self.driver.find_element_by_id("check")
- self.driver.execute_script('editor.setValue({})'.format(answer))
- submit_answer_elem.click()
-
- def test_c_question(self, question_label):
- # Incorrect Answer
- loop_count = 10
- answer = '\"int add(int a, int b, int c)\\n{return;}\"'
- self.submit_answer(question_label, answer, loop_count)
-
- # Infinite Loop
- loop_count = 3
- answer = '\"int add(int a, int b, int c)\\n{while(1){}}\"'
- self.submit_answer(question_label, answer, loop_count)
-
- # Correct Answer
- loop_count = 1
- answer = '\"int add(int a, int b, int c)\\n{return a + b + c;}\"'
- self.submit_answer(question_label, answer, loop_count)
-
- def test_python_question(self, question_label):
- # Incorrect Answer
- loop_count = 10
- answer = '\"def is_palindrome(s):\\n return s\"'
- self.submit_answer(question_label, answer, loop_count)
-
- # Infinite Loop
- loop_count = 3
- answer = '\"while True:\\n pass"'
- self.submit_answer(question_label, answer, loop_count)
-
- # Correct Answer
- loop_count = 1
- answer = '\"def is_palindrome(s):\\n return s[::-1] == s\"'
- self.submit_answer(question_label, answer, loop_count)
-
- def test_bash_question(self, question_label):
- # Incorrect Answer
- loop_count = 10
- answer = '\"#!/bin/bash\\nls\"'
- self.submit_answer(question_label, answer, loop_count)
-
- # Infinite Loop
- loop_count = 3
- answer = '\"#!/bin/bash\\nwhile [ 1 ]; do : ; done\"'
- self.submit_answer(question_label, answer, loop_count)
-
- # Correct Answer
- loop_count = 1
- answer = '\"#!/bin/bash\\ncat $1| cut -d: -f2 | paste -d: $3 - $2\"'
- self.submit_answer(question_label, answer, loop_count)
-
- def open_quiz(self):
- # open quiz link
- quiz_link_elem = self.driver.find_element_by_link_text(self.quiz_name).click()
- self.driver.implicitly_wait(2)
-
- # Get page elements
- start_exam_elem = self.driver.find_element_by_name("start")
- start_exam_elem.click()
-
- quit_exam_elem = self.driver.find_element_by_name("quit")
-
- self.test_c_question(question_label=3)
- self.test_python_question(question_label=1)
- self.test_bash_question(question_label=2)
-
- def close_quiz(self):
- self.driver.implicitly_wait(5)
- quit_link_elem = self.driver.find_element_by_id("login_again")
- quit_link_elem.click()
-
- def logout(self):
- self.driver.implicitly_wait(5)
- logout_link_elem = self.driver.find_element_by_id("logout")
- logout_link_elem.click()
-
-def user_gen(url, ids):
- return [(url, 'User%d'%x, 'User%d'%x) for x in ids]
-
-def wrap_run_load_test(args):
- url = "http://yaksh.fossee.aero.iitb.ac.in/exam/"
- quiz_name = "sel quiz 1"
- selenium_test = SeleniumTest(url=url, quiz_name=quiz_name)
- return selenium_test.run_load_test(*args)
-
-if __name__ == '__main__':
- parser = argparse.ArgumentParser()
- parser.add_argument('start', type=int, help="Starting user id")
- parser.add_argument("-n", "--number", type=int, default=10, help="number of users")
- opts = parser.parse_args()
-
- url = "http://yaksh.fossee.aero.iitb.ac.in/exam/"
- quiz_name = "yaksh demo quiz"
- selenium_test = SeleniumTest(url=url, quiz_name=quiz_name)
- pool = multiprocessing.Pool(opts.number)
- pool.map(wrap_run_load_test, user_gen(url, range(opts.start, opts.start + opts.number)))
- pool.close()
- pool.join()
-
diff --git a/yaksh/selenium_test/test_load.py b/yaksh/selenium_test/test_load.py
deleted file mode 100644
index c552137..0000000
--- a/yaksh/selenium_test/test_load.py
+++ /dev/null
@@ -1,101 +0,0 @@
-import os
-import signal
-import subprocess
-from datetime import datetime
-import pytz
-from threading import Thread
-from selenium.webdriver.firefox.webdriver import WebDriver
-
-from django.contrib.staticfiles.testing import StaticLiveServerTestCase
-
-from yaksh.models import User, Profile, Question, Quiz, Course, QuestionPaper, TestCase
-from selenium_test import SeleniumTest
-
-from yaksh.code_server import ServerPool, SERVER_POOL_PORT, SERVER_PORTS
-from yaksh import settings
-from yaksh.xmlrpc_clients import CodeServerProxy
-
-CUR_DIR = os.path.dirname(os.path.abspath(__file__))
-
-class MySeleniumTests(StaticLiveServerTestCase):
- @classmethod
- def setUpClass(cls):
- super(MySeleniumTests, cls).setUpClass()
- # setup a demo code server
- settings.code_evaluators['python']['standardtestcase'] = \
- "yaksh.python_assertion_evaluator.PythonAssertionEvaluator"
- settings.code_evaluators['c']['standardtestcase'] = \
- "yaksh.cpp_code_evaluator.CppCodeEvaluator"
- settings.code_evaluators['bash']['standardtestcase'] = \
- "yaksh.bash_code_evaluator.BashCodeEvaluator"
- code_server_pool = ServerPool(ports=SERVER_PORTS, pool_port=SERVER_POOL_PORT)
- cls.code_server_pool = code_server_pool
- cls.code_server_thread = t = Thread(target=code_server_pool.run)
- t.start()
-
- # Create set of demo users and profiles
- mod_user = User.objects.create_user(username='yaksh_demo_mod',
- password='yaksh_demo_mod',
- email='yaksh_demo_mod@test.com'
- )
-
- user = User.objects.create_user(username='demo_yaksh_user',
- password='demo_yaksh_user',
- email='demo_yaksh_user@test.com'
- )
- Profile.objects.create(user=user,
- roll_number='demo_rn',
- institute='IIT',
- department='Chemical',
- position='Student'
- )
-
- # create a course
- course = Course.objects.create(name="Demo Load Course",
- enrollment="Open Course",
- creator=mod_user
- )
- course.students.add(user)
-
- # create a Quiz
- quiz = Quiz.objects.create(
- start_date_time=datetime(2015, 10, 9, 10, 8, 15, 0, tzinfo=pytz.utc),
- end_date_time=datetime(2199, 10, 9, 10, 8, 15, 0, tzinfo=pytz.utc),
- duration=30, active=True,
- attempts_allowed=1, time_between_attempts=0,
- description='yaksh demo quiz', pass_criteria=0,
- language='Python', prerequisite=None,
- course=course
- )
-
- # create a question set
- question = Question()
- with open(os.path.join(CUR_DIR, 'test_questions.json'), 'r') as f:
- question_list = f.read()
- question.load_from_json(question_list, mod_user)
-
- # create question paper
- question_paper = QuestionPaper.objects.create(quiz=quiz,
- total_marks=5,
- shuffle_questions=False
- )
- # add fixed set of questions to the question paper
- question_paper.fixed_questions.add(*Question.objects.all())
-
- @classmethod
- def tearDownClass(cls):
- User.objects.all().delete()
- Question.objects.all().delete()
- Quiz.objects.all().delete()
- Course.objects.all().delete()
-
- cls.code_server_pool.stop()
- cls.code_server_thread.join()
-
- super(MySeleniumTests, cls).tearDownClass()
-
- def test_load(self):
- url = '%s%s' % (self.live_server_url, '/exam/login/')
- quiz_name = "yaksh demo quiz"
- selenium_test = SeleniumTest(url=url, quiz_name=quiz_name)
- selenium_test.run_load_test(url=url, username='demo_yaksh_user', password='demo_yaksh_user')
diff --git a/yaksh/selenium_test/test_questions.json b/yaksh/selenium_test/test_questions.json
deleted file mode 100644
index f1cf02f..0000000
--- a/yaksh/selenium_test/test_questions.json
+++ /dev/null
@@ -1,50 +0,0 @@
-[
- {
- "snippet": "",
- "testcase": [
- {
- "test_case": "assert is_palindrome(\"hello\") == False"
- },
- {
- "test_case": "assert is_palindrome(\"nitin\") == True"
- }
- ],
- "points": 3.0,
- "test_case_type": "standardtestcase",
- "description": "Write a function is_palindrome(arg)
which will take one string argument. Return true if the argument is palindrome & false otherwise.\r\n
\r\nFor Example:\r\n
\r\nis_palindrome(\"Hello\")
should return False
\r\n
\r\n
",
- "language": "python",
- "active": true,
- "type": "code",
- "summary": "Python, check palindrome (Code)"
- },
- {
- "snippet": "#!/bin/bash",
- "testcase": [
- {
- "test_case": "/src/yaksh/bash_files/sample.sh,/src/yaksh/bash_files/sample.args"
- }
- ],
- "points": 1.0,
- "test_case_type": "standardtestcase",
- "description": "Write a bash script that takes exactly two arguments and returns the sum of the numbers",
- "language": "bash",
- "active": true,
- "type": "code",
- "summary": "Bash Question Concatenate Files(Code)"
- },
- {
- "snippet": "",
- "testcase": [
- {
- "test_case": "c_cpp_files/main2.c"
- }
- ],
- "points": 1.0,
- "test_case_type": "standardtestcase",
- "description": "Write a program to add 3 nos",
- "language": "c",
- "active": true,
- "type": "code",
- "summary": "selenium test"
- }
-]
diff --git a/yaksh/tests/selenium_test.py b/yaksh/tests/selenium_test.py
new file mode 100644
index 0000000..a0ce8f2
--- /dev/null
+++ b/yaksh/tests/selenium_test.py
@@ -0,0 +1,148 @@
+from selenium import webdriver
+from selenium.webdriver.common.keys import Keys
+from selenium.webdriver.common.by import By
+from selenium.webdriver.support.ui import WebDriverWait
+from selenium.webdriver.support import expected_conditions as EC
+
+import multiprocessing
+import argparse
+
+class SeleniumTest():
+ def __init__(self, url, quiz_name):
+ try:
+ self.driver = webdriver.PhantomJS()
+ except WebDriverException:
+ self.driver = webdriver.Firefox()
+ self.quiz_name = quiz_name
+ self.url = url
+
+ def run_load_test(self, url, username, password):
+ try:
+ self.driver.delete_all_cookies()
+ self.driver.get(self.url)
+ self.login(username, password)
+ self.open_quiz()
+ self.close_quiz()
+ self.logout()
+ self.driver.close()
+ except Exception as e:
+ with open("/tmp/yaksh_load_test_log.txt", "ab") as f:
+ f.write('Username: {0}\nError: {1}\n'.format(username, e))
+ self.driver.close()
+
+ def login(self, username, password):
+ # get the username, password and submit form elements
+ username_elem = self.driver.find_element_by_id("id_username")
+ password_elem = self.driver.find_element_by_id("id_password")
+ submit_login_elem = self.driver.find_element_by_css_selector('button.btn')
+
+ # Type in the username, password and submit form
+ username_elem.send_keys(username)
+ password_elem.send_keys(password)
+ submit_login_elem.click()
+
+ def submit_answer(self, question_label, answer, loop_count=1):
+ self.driver.implicitly_wait(2)
+ for count in range(loop_count):
+ self.driver.find_element_by_link_text(question_label).click()
+ submit_answer_elem = self.driver.find_element_by_id("check")
+ self.driver.execute_script('editor.setValue({})'.format(answer))
+ submit_answer_elem.click()
+
+ def test_c_question(self, question_label):
+ # Incorrect Answer
+ loop_count = 10
+ answer = '\"int add(int a, int b, int c)\\n{return;}\"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ # Infinite Loop
+ loop_count = 3
+ answer = '\"int add(int a, int b, int c)\\n{while(1){}}\"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ # Correct Answer
+ loop_count = 1
+ answer = '\"int add(int a, int b, int c)\\n{return a + b + c;}\"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ def test_python_question(self, question_label):
+ # Incorrect Answer
+ loop_count = 10
+ answer = '\"def is_palindrome(s):\\n return s\"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ # Infinite Loop
+ loop_count = 3
+ answer = '\"while True:\\n pass"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ # Correct Answer
+ loop_count = 1
+ answer = '\"def is_palindrome(s):\\n return s[::-1] == s\"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ def test_bash_question(self, question_label):
+ # Incorrect Answer
+ loop_count = 10
+ answer = '\"#!/bin/bash\\nls\"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ # Infinite Loop
+ loop_count = 3
+ answer = '\"#!/bin/bash\\nwhile [ 1 ]; do : ; done\"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ # Correct Answer
+ loop_count = 1
+ answer = '\"#!/bin/bash\\n[[ $# -eq 2 ]] && echo $(( $1 + $2 )) && exit $(( $1 + $2 ))\"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ def open_quiz(self):
+ # open quiz link
+ quiz_link_elem = self.driver.find_element_by_link_text(self.quiz_name).click()
+
+ # Get page elements
+ start_exam_elem = WebDriverWait(self.driver, 5).until(
+ EC.presence_of_element_located((By.NAME, "start"))
+ )
+ start_exam_elem.click()
+
+ self.test_c_question(question_label=3)
+ self.test_python_question(question_label=1)
+ self.test_bash_question(question_label=2)
+
+ def close_quiz(self):
+ quit_link_elem = WebDriverWait(self.driver, 5).until(
+ EC.presence_of_element_located((By.ID, "login_again"))
+ )
+ quit_link_elem.click()
+
+ def logout(self):
+ logout_link_elem = WebDriverWait(self.driver, 5).until(
+ EC.presence_of_element_located((By.ID, "logout"))
+ )
+ logout_link_elem.click()
+
+def user_gen(url, ids):
+ return [(url, 'User%d'%x, 'User%d'%x) for x in ids]
+
+def wrap_run_load_test(args):
+ url = "http://yaksh.fossee.aero.iitb.ac.in/exam/"
+ quiz_name = "yaksh_demo_quiz"
+ selenium_test = SeleniumTest(url=url, quiz_name=quiz_name)
+ return selenium_test.run_load_test(*args)
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser()
+ parser.add_argument('url', type=str, help="url of the website being tested")
+ parser.add_argument('start', type=int, help="Starting user id")
+ parser.add_argument("-n", "--number", type=int, default=10, help="number of users")
+ opts = parser.parse_args()
+
+ quiz_name = "yaksh demo quiz"
+ selenium_test = SeleniumTest(url=opts.url, quiz_name=quiz_name)
+ pool = multiprocessing.Pool(opts.number)
+ pool.map(wrap_run_load_test, user_gen(opts.url, range(opts.start, opts.start + opts.number)))
+ pool.close()
+ pool.join()
+
diff --git a/yaksh/tests/test_load.py b/yaksh/tests/test_load.py
new file mode 100644
index 0000000..c552137
--- /dev/null
+++ b/yaksh/tests/test_load.py
@@ -0,0 +1,101 @@
+import os
+import signal
+import subprocess
+from datetime import datetime
+import pytz
+from threading import Thread
+from selenium.webdriver.firefox.webdriver import WebDriver
+
+from django.contrib.staticfiles.testing import StaticLiveServerTestCase
+
+from yaksh.models import User, Profile, Question, Quiz, Course, QuestionPaper, TestCase
+from selenium_test import SeleniumTest
+
+from yaksh.code_server import ServerPool, SERVER_POOL_PORT, SERVER_PORTS
+from yaksh import settings
+from yaksh.xmlrpc_clients import CodeServerProxy
+
+CUR_DIR = os.path.dirname(os.path.abspath(__file__))
+
+class MySeleniumTests(StaticLiveServerTestCase):
+ @classmethod
+ def setUpClass(cls):
+ super(MySeleniumTests, cls).setUpClass()
+ # setup a demo code server
+ settings.code_evaluators['python']['standardtestcase'] = \
+ "yaksh.python_assertion_evaluator.PythonAssertionEvaluator"
+ settings.code_evaluators['c']['standardtestcase'] = \
+ "yaksh.cpp_code_evaluator.CppCodeEvaluator"
+ settings.code_evaluators['bash']['standardtestcase'] = \
+ "yaksh.bash_code_evaluator.BashCodeEvaluator"
+ code_server_pool = ServerPool(ports=SERVER_PORTS, pool_port=SERVER_POOL_PORT)
+ cls.code_server_pool = code_server_pool
+ cls.code_server_thread = t = Thread(target=code_server_pool.run)
+ t.start()
+
+ # Create set of demo users and profiles
+ mod_user = User.objects.create_user(username='yaksh_demo_mod',
+ password='yaksh_demo_mod',
+ email='yaksh_demo_mod@test.com'
+ )
+
+ user = User.objects.create_user(username='demo_yaksh_user',
+ password='demo_yaksh_user',
+ email='demo_yaksh_user@test.com'
+ )
+ Profile.objects.create(user=user,
+ roll_number='demo_rn',
+ institute='IIT',
+ department='Chemical',
+ position='Student'
+ )
+
+ # create a course
+ course = Course.objects.create(name="Demo Load Course",
+ enrollment="Open Course",
+ creator=mod_user
+ )
+ course.students.add(user)
+
+ # create a Quiz
+ quiz = Quiz.objects.create(
+ start_date_time=datetime(2015, 10, 9, 10, 8, 15, 0, tzinfo=pytz.utc),
+ end_date_time=datetime(2199, 10, 9, 10, 8, 15, 0, tzinfo=pytz.utc),
+ duration=30, active=True,
+ attempts_allowed=1, time_between_attempts=0,
+ description='yaksh demo quiz', pass_criteria=0,
+ language='Python', prerequisite=None,
+ course=course
+ )
+
+ # create a question set
+ question = Question()
+ with open(os.path.join(CUR_DIR, 'test_questions.json'), 'r') as f:
+ question_list = f.read()
+ question.load_from_json(question_list, mod_user)
+
+ # create question paper
+ question_paper = QuestionPaper.objects.create(quiz=quiz,
+ total_marks=5,
+ shuffle_questions=False
+ )
+ # add fixed set of questions to the question paper
+ question_paper.fixed_questions.add(*Question.objects.all())
+
+ @classmethod
+ def tearDownClass(cls):
+ User.objects.all().delete()
+ Question.objects.all().delete()
+ Quiz.objects.all().delete()
+ Course.objects.all().delete()
+
+ cls.code_server_pool.stop()
+ cls.code_server_thread.join()
+
+ super(MySeleniumTests, cls).tearDownClass()
+
+ def test_load(self):
+ url = '%s%s' % (self.live_server_url, '/exam/login/')
+ quiz_name = "yaksh demo quiz"
+ selenium_test = SeleniumTest(url=url, quiz_name=quiz_name)
+ selenium_test.run_load_test(url=url, username='demo_yaksh_user', password='demo_yaksh_user')
diff --git a/yaksh/tests/test_questions.json b/yaksh/tests/test_questions.json
new file mode 100644
index 0000000..d617f22
--- /dev/null
+++ b/yaksh/tests/test_questions.json
@@ -0,0 +1,50 @@
+[
+ {
+ "snippet": "",
+ "testcase": [
+ {
+ "test_case": "assert is_palindrome(\"hello\") == False"
+ },
+ {
+ "test_case": "assert is_palindrome(\"nitin\") == True"
+ }
+ ],
+ "points": 3.0,
+ "test_case_type": "standardtestcase",
+ "description": "Write a function is_palindrome(arg)
which will take one string argument. Return true if the argument is palindrome & false otherwise.\r\n
\r\nFor Example:\r\n
\r\nis_palindrome(\"Hello\")
should return False
\r\n
\r\n
",
+ "language": "python",
+ "active": true,
+ "type": "code",
+ "summary": "Python, check palindrome (Code)"
+ },
+ {
+ "snippet": "#!/bin/bash",
+ "testcase": [
+ {
+ "test_case": "bash_files/sample.sh, bash_files/sample.args"
+ }
+ ],
+ "points": 1.0,
+ "test_case_type": "standardtestcase",
+ "description": "Write a bash script that takes exactly two arguments and returns the sum of the numbers",
+ "language": "bash",
+ "active": true,
+ "type": "code",
+ "summary": "Bash Question Concatenate Files(Code)"
+ },
+ {
+ "snippet": "",
+ "testcase": [
+ {
+ "test_case": "c_cpp_files/main2.c"
+ }
+ ],
+ "points": 1.0,
+ "test_case_type": "standardtestcase",
+ "description": "Write a program to add 3 nos",
+ "language": "c",
+ "active": true,
+ "type": "code",
+ "summary": "selenium test"
+ }
+]
--
cgit
From 722e82275c28418dc7535ca7393b81eecadbeba9 Mon Sep 17 00:00:00 2001
From: ankitjavalkar
Date: Tue, 6 Sep 2016 18:56:30 +0530
Subject: Modify selenium based test to accomodate create_demo_course command
---
yaksh/tests/selenium_test.py | 14 +++++------
yaksh/tests/test_load.py | 56 +++++---------------------------------------
2 files changed, 12 insertions(+), 58 deletions(-)
(limited to 'yaksh')
diff --git a/yaksh/tests/selenium_test.py b/yaksh/tests/selenium_test.py
index a0ce8f2..15d730e 100644
--- a/yaksh/tests/selenium_test.py
+++ b/yaksh/tests/selenium_test.py
@@ -3,16 +3,14 @@ from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
+from selenium.common.exceptions import WebDriverException
import multiprocessing
import argparse
class SeleniumTest():
def __init__(self, url, quiz_name):
- try:
- self.driver = webdriver.PhantomJS()
- except WebDriverException:
- self.driver = webdriver.Firefox()
+ self.driver = webdriver.Firefox()
self.quiz_name = quiz_name
self.url = url
@@ -94,7 +92,7 @@ class SeleniumTest():
# Correct Answer
loop_count = 1
- answer = '\"#!/bin/bash\\n[[ $# -eq 2 ]] && echo $(( $1 + $2 )) && exit $(( $1 + $2 ))\"'
+ answer = '\"#!/bin/bash\\ncat $1 | cut -d: -f2 | paste -d: $3 - $2\"'
self.submit_answer(question_label, answer, loop_count)
def open_quiz(self):
@@ -107,8 +105,8 @@ class SeleniumTest():
)
start_exam_elem.click()
- self.test_c_question(question_label=3)
- self.test_python_question(question_label=1)
+ self.test_c_question(question_label=1)
+ self.test_python_question(question_label=3)
self.test_bash_question(question_label=2)
def close_quiz(self):
@@ -139,7 +137,7 @@ if __name__ == '__main__':
parser.add_argument("-n", "--number", type=int, default=10, help="number of users")
opts = parser.parse_args()
- quiz_name = "yaksh demo quiz"
+ quiz_name = "Demo quiz"
selenium_test = SeleniumTest(url=opts.url, quiz_name=quiz_name)
pool = multiprocessing.Pool(opts.number)
pool.map(wrap_run_load_test, user_gen(opts.url, range(opts.start, opts.start + opts.number)))
diff --git a/yaksh/tests/test_load.py b/yaksh/tests/test_load.py
index c552137..27ae750 100644
--- a/yaksh/tests/test_load.py
+++ b/yaksh/tests/test_load.py
@@ -14,9 +14,12 @@ from selenium_test import SeleniumTest
from yaksh.code_server import ServerPool, SERVER_POOL_PORT, SERVER_PORTS
from yaksh import settings
from yaksh.xmlrpc_clients import CodeServerProxy
+from django.core.management import call_command
+
CUR_DIR = os.path.dirname(os.path.abspath(__file__))
+
class MySeleniumTests(StaticLiveServerTestCase):
@classmethod
def setUpClass(cls):
@@ -33,54 +36,7 @@ class MySeleniumTests(StaticLiveServerTestCase):
cls.code_server_thread = t = Thread(target=code_server_pool.run)
t.start()
- # Create set of demo users and profiles
- mod_user = User.objects.create_user(username='yaksh_demo_mod',
- password='yaksh_demo_mod',
- email='yaksh_demo_mod@test.com'
- )
-
- user = User.objects.create_user(username='demo_yaksh_user',
- password='demo_yaksh_user',
- email='demo_yaksh_user@test.com'
- )
- Profile.objects.create(user=user,
- roll_number='demo_rn',
- institute='IIT',
- department='Chemical',
- position='Student'
- )
-
- # create a course
- course = Course.objects.create(name="Demo Load Course",
- enrollment="Open Course",
- creator=mod_user
- )
- course.students.add(user)
-
- # create a Quiz
- quiz = Quiz.objects.create(
- start_date_time=datetime(2015, 10, 9, 10, 8, 15, 0, tzinfo=pytz.utc),
- end_date_time=datetime(2199, 10, 9, 10, 8, 15, 0, tzinfo=pytz.utc),
- duration=30, active=True,
- attempts_allowed=1, time_between_attempts=0,
- description='yaksh demo quiz', pass_criteria=0,
- language='Python', prerequisite=None,
- course=course
- )
-
- # create a question set
- question = Question()
- with open(os.path.join(CUR_DIR, 'test_questions.json'), 'r') as f:
- question_list = f.read()
- question.load_from_json(question_list, mod_user)
-
- # create question paper
- question_paper = QuestionPaper.objects.create(quiz=quiz,
- total_marks=5,
- shuffle_questions=False
- )
- # add fixed set of questions to the question paper
- question_paper.fixed_questions.add(*Question.objects.all())
+ call_command('create_demo_course')
@classmethod
def tearDownClass(cls):
@@ -96,6 +52,6 @@ class MySeleniumTests(StaticLiveServerTestCase):
def test_load(self):
url = '%s%s' % (self.live_server_url, '/exam/login/')
- quiz_name = "yaksh demo quiz"
+ quiz_name = "Demo_quiz"
selenium_test = SeleniumTest(url=url, quiz_name=quiz_name)
- selenium_test.run_load_test(url=url, username='demo_yaksh_user', password='demo_yaksh_user')
+ selenium_test.run_load_test(url=url, username='demo_student', password='demo_student')
--
cgit
From 953f856edc18ed22c72c56b58171e2ce5bc450e5 Mon Sep 17 00:00:00 2001
From: ankitjavalkar
Date: Mon, 12 Sep 2016 16:22:55 +0530
Subject: Run the selenium and unit tests separately
---
yaksh/tests/load_test.py | 60 ++++++++++++++++++++++++++++++++++++++++++++
yaksh/tests/selenium_test.py | 1 -
yaksh/tests/test_load.py | 57 -----------------------------------------
3 files changed, 60 insertions(+), 58 deletions(-)
create mode 100644 yaksh/tests/load_test.py
delete mode 100644 yaksh/tests/test_load.py
(limited to 'yaksh')
diff --git a/yaksh/tests/load_test.py b/yaksh/tests/load_test.py
new file mode 100644
index 0000000..fd90b11
--- /dev/null
+++ b/yaksh/tests/load_test.py
@@ -0,0 +1,60 @@
+import os
+import signal
+import subprocess
+from datetime import datetime
+import pytz
+from threading import Thread
+from selenium.webdriver.firefox.webdriver import WebDriver
+
+from django.contrib.staticfiles.testing import StaticLiveServerTestCase
+
+from yaksh.models import User, Profile, Question, Quiz, Course, QuestionPaper, TestCase
+from selenium_test import SeleniumTest
+
+from yaksh.code_server import ServerPool #SERVER_POOL_PORT, SERVER_PORTS
+from yaksh import settings
+# from django.core.management import call_command
+from yaksh.management.commands.create_demo_course import create_demo_course
+
+
+CUR_DIR = os.path.dirname(os.path.abspath(__file__))
+
+
+class MySeleniumTests(StaticLiveServerTestCase):
+ @classmethod
+ def setUpClass(cls):
+ super(MySeleniumTests, cls).setUpClass()
+ # setup a demo code server
+ settings.code_evaluators['python']['standardtestcase'] = \
+ "yaksh.python_assertion_evaluator.PythonAssertionEvaluator"
+ settings.code_evaluators['c']['standardtestcase'] = \
+ "yaksh.cpp_code_evaluator.CppCodeEvaluator"
+ settings.code_evaluators['bash']['standardtestcase'] = \
+ "yaksh.bash_code_evaluator.BashCodeEvaluator"
+ settings.SERVER_POOL_PORT = 53578
+ code_server_pool = ServerPool(ports=settings.SERVER_PORTS, pool_port=settings.SERVER_POOL_PORT)
+ cls.code_server_pool = code_server_pool
+ cls.code_server_thread = t = Thread(target=code_server_pool.run)
+ t.start()
+
+ demo_course_setup = create_demo_course()
+
+ @classmethod
+ def tearDownClass(cls):
+ # User.objects.all().delete()
+ # Question.objects.all().delete()
+ # Quiz.objects.all().delete()
+ # Course.objects.all().delete()
+
+ settings.SERVER_POOL_PORT = 53579
+
+ cls.code_server_pool.stop()
+ cls.code_server_thread.join()
+
+ super(MySeleniumTests, cls).tearDownClass()
+
+ def test_load(self):
+ url = '%s%s' % (self.live_server_url, '/exam/login/')
+ quiz_name = "Demo_quiz"
+ selenium_test = SeleniumTest(url=url, quiz_name=quiz_name)
+ selenium_test.run_load_test(url=url, username='demo_student', password='demo_student')
diff --git a/yaksh/tests/selenium_test.py b/yaksh/tests/selenium_test.py
index 15d730e..01ccc96 100644
--- a/yaksh/tests/selenium_test.py
+++ b/yaksh/tests/selenium_test.py
@@ -126,7 +126,6 @@ def user_gen(url, ids):
def wrap_run_load_test(args):
url = "http://yaksh.fossee.aero.iitb.ac.in/exam/"
- quiz_name = "yaksh_demo_quiz"
selenium_test = SeleniumTest(url=url, quiz_name=quiz_name)
return selenium_test.run_load_test(*args)
diff --git a/yaksh/tests/test_load.py b/yaksh/tests/test_load.py
deleted file mode 100644
index 27ae750..0000000
--- a/yaksh/tests/test_load.py
+++ /dev/null
@@ -1,57 +0,0 @@
-import os
-import signal
-import subprocess
-from datetime import datetime
-import pytz
-from threading import Thread
-from selenium.webdriver.firefox.webdriver import WebDriver
-
-from django.contrib.staticfiles.testing import StaticLiveServerTestCase
-
-from yaksh.models import User, Profile, Question, Quiz, Course, QuestionPaper, TestCase
-from selenium_test import SeleniumTest
-
-from yaksh.code_server import ServerPool, SERVER_POOL_PORT, SERVER_PORTS
-from yaksh import settings
-from yaksh.xmlrpc_clients import CodeServerProxy
-from django.core.management import call_command
-
-
-CUR_DIR = os.path.dirname(os.path.abspath(__file__))
-
-
-class MySeleniumTests(StaticLiveServerTestCase):
- @classmethod
- def setUpClass(cls):
- super(MySeleniumTests, cls).setUpClass()
- # setup a demo code server
- settings.code_evaluators['python']['standardtestcase'] = \
- "yaksh.python_assertion_evaluator.PythonAssertionEvaluator"
- settings.code_evaluators['c']['standardtestcase'] = \
- "yaksh.cpp_code_evaluator.CppCodeEvaluator"
- settings.code_evaluators['bash']['standardtestcase'] = \
- "yaksh.bash_code_evaluator.BashCodeEvaluator"
- code_server_pool = ServerPool(ports=SERVER_PORTS, pool_port=SERVER_POOL_PORT)
- cls.code_server_pool = code_server_pool
- cls.code_server_thread = t = Thread(target=code_server_pool.run)
- t.start()
-
- call_command('create_demo_course')
-
- @classmethod
- def tearDownClass(cls):
- User.objects.all().delete()
- Question.objects.all().delete()
- Quiz.objects.all().delete()
- Course.objects.all().delete()
-
- cls.code_server_pool.stop()
- cls.code_server_thread.join()
-
- super(MySeleniumTests, cls).tearDownClass()
-
- def test_load(self):
- url = '%s%s' % (self.live_server_url, '/exam/login/')
- quiz_name = "Demo_quiz"
- selenium_test = SeleniumTest(url=url, quiz_name=quiz_name)
- selenium_test.run_load_test(url=url, username='demo_student', password='demo_student')
--
cgit
From bf1986b58ce0e5619a2af221d5897f5f7fc708f0 Mon Sep 17 00:00:00 2001
From: ankitjavalkar
Date: Sun, 18 Sep 2016 10:21:18 +0530
Subject: Remove commented code
---
yaksh/tests/load_test.py | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
(limited to 'yaksh')
diff --git a/yaksh/tests/load_test.py b/yaksh/tests/load_test.py
index fd90b11..05fd02f 100644
--- a/yaksh/tests/load_test.py
+++ b/yaksh/tests/load_test.py
@@ -20,10 +20,10 @@ from yaksh.management.commands.create_demo_course import create_demo_course
CUR_DIR = os.path.dirname(os.path.abspath(__file__))
-class MySeleniumTests(StaticLiveServerTestCase):
+class YakshSeleniumTests(StaticLiveServerTestCase):
@classmethod
def setUpClass(cls):
- super(MySeleniumTests, cls).setUpClass()
+ super(YakshSeleniumTests, cls).setUpClass()
# setup a demo code server
settings.code_evaluators['python']['standardtestcase'] = \
"yaksh.python_assertion_evaluator.PythonAssertionEvaluator"
@@ -41,17 +41,17 @@ class MySeleniumTests(StaticLiveServerTestCase):
@classmethod
def tearDownClass(cls):
- # User.objects.all().delete()
- # Question.objects.all().delete()
- # Quiz.objects.all().delete()
- # Course.objects.all().delete()
+ User.objects.all().delete()
+ Question.objects.all().delete()
+ Quiz.objects.all().delete()
+ Course.objects.all().delete()
settings.SERVER_POOL_PORT = 53579
cls.code_server_pool.stop()
cls.code_server_thread.join()
- super(MySeleniumTests, cls).tearDownClass()
+ super(YakshSeleniumTests, cls).tearDownClass()
def test_load(self):
url = '%s%s' % (self.live_server_url, '/exam/login/')
--
cgit
From 48f5117a0a0f7f712d3bafabf06e1c63de56e9fa Mon Sep 17 00:00:00 2001
From: ankitjavalkar
Date: Wed, 21 Sep 2016 15:51:19 +0530
Subject: Place selenium script and unit tests in live_server_tests dir
---
yaksh/live_server_tests/__init__.py | 0
yaksh/live_server_tests/load_test.py | 77 ++++++++++++++++
yaksh/live_server_tests/selenium_test.py | 145 +++++++++++++++++++++++++++++++
yaksh/tests/load_test.py | 60 -------------
yaksh/tests/selenium_test.py | 145 -------------------------------
5 files changed, 222 insertions(+), 205 deletions(-)
create mode 100644 yaksh/live_server_tests/__init__.py
create mode 100644 yaksh/live_server_tests/load_test.py
create mode 100644 yaksh/live_server_tests/selenium_test.py
delete mode 100644 yaksh/tests/load_test.py
delete mode 100644 yaksh/tests/selenium_test.py
(limited to 'yaksh')
diff --git a/yaksh/live_server_tests/__init__.py b/yaksh/live_server_tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/yaksh/live_server_tests/load_test.py b/yaksh/live_server_tests/load_test.py
new file mode 100644
index 0000000..17934d4
--- /dev/null
+++ b/yaksh/live_server_tests/load_test.py
@@ -0,0 +1,77 @@
+import os
+import signal
+import subprocess
+from datetime import datetime
+import pytz
+from threading import Thread
+from selenium.webdriver.firefox.webdriver import WebDriver
+
+from django.contrib.staticfiles.testing import StaticLiveServerTestCase
+
+from yaksh.models import User, Profile, Question, Quiz, Course, QuestionPaper, TestCase
+from selenium_test import SeleniumTest
+
+from yaksh.code_server import ServerPool
+from yaksh import settings
+
+
+class YakshSeleniumTests(StaticLiveServerTestCase):
+ @classmethod
+ def setUpClass(cls):
+ super(YakshSeleniumTests, cls).setUpClass()
+ # setup a demo code server
+ settings.code_evaluators['python']['standardtestcase'] = \
+ "yaksh.python_assertion_evaluator.PythonAssertionEvaluator"
+ settings.code_evaluators['c']['standardtestcase'] = \
+ "yaksh.cpp_code_evaluator.CppCodeEvaluator"
+ settings.code_evaluators['bash']['standardtestcase'] = \
+ "yaksh.bash_code_evaluator.BashCodeEvaluator"
+ settings.SERVER_POOL_PORT = 53578
+ code_server_pool = ServerPool(ports=settings.SERVER_PORTS, pool_port=settings.SERVER_POOL_PORT)
+ cls.code_server_pool = code_server_pool
+ cls.code_server_thread = t = Thread(target=code_server_pool.run)
+ t.start()
+
+ demo_student = User.objects.create_user(username='demo_student',
+ password='demo_student',
+ email='demo_student@test.com'
+ )
+ demo_student_profile = Profile.objects.create(user=demo_student,
+ roll_number=3, institute='IIT',
+ department='Chemical', position='Student'
+ )
+
+ demo_mod = User.objects.create_user(username='demo_mod',
+ password='demo_mod',
+ email='demo_mod@test.com'
+ )
+ demo_mod_profile = Profile.objects.create(user=demo_mod,
+ roll_number=0, institute='IIT',
+ department='Chemical', position='Moderator'
+ )
+
+ course_obj = Course()
+ course_obj.create_demo(demo_mod)
+ demo_course = Course.objects.get(id=1)
+
+ demo_course.students.add(demo_student)
+
+ @classmethod
+ def tearDownClass(cls):
+ User.objects.all().delete()
+ Question.objects.all().delete()
+ Quiz.objects.all().delete()
+ Course.objects.all().delete()
+
+ settings.SERVER_POOL_PORT = 53579
+
+ cls.code_server_pool.stop()
+ cls.code_server_thread.join()
+
+ super(YakshSeleniumTests, cls).tearDownClass()
+
+ def test_load(self):
+ url = '%s%s' % (self.live_server_url, '/exam/login/')
+ quiz_name = "Yaksh Demo quiz"
+ selenium_test = SeleniumTest(url=url, quiz_name=quiz_name)
+ selenium_test.run_load_test(url=url, username='demo_student', password='demo_student')
diff --git a/yaksh/live_server_tests/selenium_test.py b/yaksh/live_server_tests/selenium_test.py
new file mode 100644
index 0000000..01ccc96
--- /dev/null
+++ b/yaksh/live_server_tests/selenium_test.py
@@ -0,0 +1,145 @@
+from selenium import webdriver
+from selenium.webdriver.common.keys import Keys
+from selenium.webdriver.common.by import By
+from selenium.webdriver.support.ui import WebDriverWait
+from selenium.webdriver.support import expected_conditions as EC
+from selenium.common.exceptions import WebDriverException
+
+import multiprocessing
+import argparse
+
+class SeleniumTest():
+ def __init__(self, url, quiz_name):
+ self.driver = webdriver.Firefox()
+ self.quiz_name = quiz_name
+ self.url = url
+
+ def run_load_test(self, url, username, password):
+ try:
+ self.driver.delete_all_cookies()
+ self.driver.get(self.url)
+ self.login(username, password)
+ self.open_quiz()
+ self.close_quiz()
+ self.logout()
+ self.driver.close()
+ except Exception as e:
+ with open("/tmp/yaksh_load_test_log.txt", "ab") as f:
+ f.write('Username: {0}\nError: {1}\n'.format(username, e))
+ self.driver.close()
+
+ def login(self, username, password):
+ # get the username, password and submit form elements
+ username_elem = self.driver.find_element_by_id("id_username")
+ password_elem = self.driver.find_element_by_id("id_password")
+ submit_login_elem = self.driver.find_element_by_css_selector('button.btn')
+
+ # Type in the username, password and submit form
+ username_elem.send_keys(username)
+ password_elem.send_keys(password)
+ submit_login_elem.click()
+
+ def submit_answer(self, question_label, answer, loop_count=1):
+ self.driver.implicitly_wait(2)
+ for count in range(loop_count):
+ self.driver.find_element_by_link_text(question_label).click()
+ submit_answer_elem = self.driver.find_element_by_id("check")
+ self.driver.execute_script('editor.setValue({})'.format(answer))
+ submit_answer_elem.click()
+
+ def test_c_question(self, question_label):
+ # Incorrect Answer
+ loop_count = 10
+ answer = '\"int add(int a, int b, int c)\\n{return;}\"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ # Infinite Loop
+ loop_count = 3
+ answer = '\"int add(int a, int b, int c)\\n{while(1){}}\"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ # Correct Answer
+ loop_count = 1
+ answer = '\"int add(int a, int b, int c)\\n{return a + b + c;}\"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ def test_python_question(self, question_label):
+ # Incorrect Answer
+ loop_count = 10
+ answer = '\"def is_palindrome(s):\\n return s\"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ # Infinite Loop
+ loop_count = 3
+ answer = '\"while True:\\n pass"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ # Correct Answer
+ loop_count = 1
+ answer = '\"def is_palindrome(s):\\n return s[::-1] == s\"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ def test_bash_question(self, question_label):
+ # Incorrect Answer
+ loop_count = 10
+ answer = '\"#!/bin/bash\\nls\"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ # Infinite Loop
+ loop_count = 3
+ answer = '\"#!/bin/bash\\nwhile [ 1 ]; do : ; done\"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ # Correct Answer
+ loop_count = 1
+ answer = '\"#!/bin/bash\\ncat $1 | cut -d: -f2 | paste -d: $3 - $2\"'
+ self.submit_answer(question_label, answer, loop_count)
+
+ def open_quiz(self):
+ # open quiz link
+ quiz_link_elem = self.driver.find_element_by_link_text(self.quiz_name).click()
+
+ # Get page elements
+ start_exam_elem = WebDriverWait(self.driver, 5).until(
+ EC.presence_of_element_located((By.NAME, "start"))
+ )
+ start_exam_elem.click()
+
+ self.test_c_question(question_label=1)
+ self.test_python_question(question_label=3)
+ self.test_bash_question(question_label=2)
+
+ def close_quiz(self):
+ quit_link_elem = WebDriverWait(self.driver, 5).until(
+ EC.presence_of_element_located((By.ID, "login_again"))
+ )
+ quit_link_elem.click()
+
+ def logout(self):
+ logout_link_elem = WebDriverWait(self.driver, 5).until(
+ EC.presence_of_element_located((By.ID, "logout"))
+ )
+ logout_link_elem.click()
+
+def user_gen(url, ids):
+ return [(url, 'User%d'%x, 'User%d'%x) for x in ids]
+
+def wrap_run_load_test(args):
+ url = "http://yaksh.fossee.aero.iitb.ac.in/exam/"
+ selenium_test = SeleniumTest(url=url, quiz_name=quiz_name)
+ return selenium_test.run_load_test(*args)
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser()
+ parser.add_argument('url', type=str, help="url of the website being tested")
+ parser.add_argument('start', type=int, help="Starting user id")
+ parser.add_argument("-n", "--number", type=int, default=10, help="number of users")
+ opts = parser.parse_args()
+
+ quiz_name = "Demo quiz"
+ selenium_test = SeleniumTest(url=opts.url, quiz_name=quiz_name)
+ pool = multiprocessing.Pool(opts.number)
+ pool.map(wrap_run_load_test, user_gen(opts.url, range(opts.start, opts.start + opts.number)))
+ pool.close()
+ pool.join()
+
diff --git a/yaksh/tests/load_test.py b/yaksh/tests/load_test.py
deleted file mode 100644
index 05fd02f..0000000
--- a/yaksh/tests/load_test.py
+++ /dev/null
@@ -1,60 +0,0 @@
-import os
-import signal
-import subprocess
-from datetime import datetime
-import pytz
-from threading import Thread
-from selenium.webdriver.firefox.webdriver import WebDriver
-
-from django.contrib.staticfiles.testing import StaticLiveServerTestCase
-
-from yaksh.models import User, Profile, Question, Quiz, Course, QuestionPaper, TestCase
-from selenium_test import SeleniumTest
-
-from yaksh.code_server import ServerPool #SERVER_POOL_PORT, SERVER_PORTS
-from yaksh import settings
-# from django.core.management import call_command
-from yaksh.management.commands.create_demo_course import create_demo_course
-
-
-CUR_DIR = os.path.dirname(os.path.abspath(__file__))
-
-
-class YakshSeleniumTests(StaticLiveServerTestCase):
- @classmethod
- def setUpClass(cls):
- super(YakshSeleniumTests, cls).setUpClass()
- # setup a demo code server
- settings.code_evaluators['python']['standardtestcase'] = \
- "yaksh.python_assertion_evaluator.PythonAssertionEvaluator"
- settings.code_evaluators['c']['standardtestcase'] = \
- "yaksh.cpp_code_evaluator.CppCodeEvaluator"
- settings.code_evaluators['bash']['standardtestcase'] = \
- "yaksh.bash_code_evaluator.BashCodeEvaluator"
- settings.SERVER_POOL_PORT = 53578
- code_server_pool = ServerPool(ports=settings.SERVER_PORTS, pool_port=settings.SERVER_POOL_PORT)
- cls.code_server_pool = code_server_pool
- cls.code_server_thread = t = Thread(target=code_server_pool.run)
- t.start()
-
- demo_course_setup = create_demo_course()
-
- @classmethod
- def tearDownClass(cls):
- User.objects.all().delete()
- Question.objects.all().delete()
- Quiz.objects.all().delete()
- Course.objects.all().delete()
-
- settings.SERVER_POOL_PORT = 53579
-
- cls.code_server_pool.stop()
- cls.code_server_thread.join()
-
- super(YakshSeleniumTests, cls).tearDownClass()
-
- def test_load(self):
- url = '%s%s' % (self.live_server_url, '/exam/login/')
- quiz_name = "Demo_quiz"
- selenium_test = SeleniumTest(url=url, quiz_name=quiz_name)
- selenium_test.run_load_test(url=url, username='demo_student', password='demo_student')
diff --git a/yaksh/tests/selenium_test.py b/yaksh/tests/selenium_test.py
deleted file mode 100644
index 01ccc96..0000000
--- a/yaksh/tests/selenium_test.py
+++ /dev/null
@@ -1,145 +0,0 @@
-from selenium import webdriver
-from selenium.webdriver.common.keys import Keys
-from selenium.webdriver.common.by import By
-from selenium.webdriver.support.ui import WebDriverWait
-from selenium.webdriver.support import expected_conditions as EC
-from selenium.common.exceptions import WebDriverException
-
-import multiprocessing
-import argparse
-
-class SeleniumTest():
- def __init__(self, url, quiz_name):
- self.driver = webdriver.Firefox()
- self.quiz_name = quiz_name
- self.url = url
-
- def run_load_test(self, url, username, password):
- try:
- self.driver.delete_all_cookies()
- self.driver.get(self.url)
- self.login(username, password)
- self.open_quiz()
- self.close_quiz()
- self.logout()
- self.driver.close()
- except Exception as e:
- with open("/tmp/yaksh_load_test_log.txt", "ab") as f:
- f.write('Username: {0}\nError: {1}\n'.format(username, e))
- self.driver.close()
-
- def login(self, username, password):
- # get the username, password and submit form elements
- username_elem = self.driver.find_element_by_id("id_username")
- password_elem = self.driver.find_element_by_id("id_password")
- submit_login_elem = self.driver.find_element_by_css_selector('button.btn')
-
- # Type in the username, password and submit form
- username_elem.send_keys(username)
- password_elem.send_keys(password)
- submit_login_elem.click()
-
- def submit_answer(self, question_label, answer, loop_count=1):
- self.driver.implicitly_wait(2)
- for count in range(loop_count):
- self.driver.find_element_by_link_text(question_label).click()
- submit_answer_elem = self.driver.find_element_by_id("check")
- self.driver.execute_script('editor.setValue({})'.format(answer))
- submit_answer_elem.click()
-
- def test_c_question(self, question_label):
- # Incorrect Answer
- loop_count = 10
- answer = '\"int add(int a, int b, int c)\\n{return;}\"'
- self.submit_answer(question_label, answer, loop_count)
-
- # Infinite Loop
- loop_count = 3
- answer = '\"int add(int a, int b, int c)\\n{while(1){}}\"'
- self.submit_answer(question_label, answer, loop_count)
-
- # Correct Answer
- loop_count = 1
- answer = '\"int add(int a, int b, int c)\\n{return a + b + c;}\"'
- self.submit_answer(question_label, answer, loop_count)
-
- def test_python_question(self, question_label):
- # Incorrect Answer
- loop_count = 10
- answer = '\"def is_palindrome(s):\\n return s\"'
- self.submit_answer(question_label, answer, loop_count)
-
- # Infinite Loop
- loop_count = 3
- answer = '\"while True:\\n pass"'
- self.submit_answer(question_label, answer, loop_count)
-
- # Correct Answer
- loop_count = 1
- answer = '\"def is_palindrome(s):\\n return s[::-1] == s\"'
- self.submit_answer(question_label, answer, loop_count)
-
- def test_bash_question(self, question_label):
- # Incorrect Answer
- loop_count = 10
- answer = '\"#!/bin/bash\\nls\"'
- self.submit_answer(question_label, answer, loop_count)
-
- # Infinite Loop
- loop_count = 3
- answer = '\"#!/bin/bash\\nwhile [ 1 ]; do : ; done\"'
- self.submit_answer(question_label, answer, loop_count)
-
- # Correct Answer
- loop_count = 1
- answer = '\"#!/bin/bash\\ncat $1 | cut -d: -f2 | paste -d: $3 - $2\"'
- self.submit_answer(question_label, answer, loop_count)
-
- def open_quiz(self):
- # open quiz link
- quiz_link_elem = self.driver.find_element_by_link_text(self.quiz_name).click()
-
- # Get page elements
- start_exam_elem = WebDriverWait(self.driver, 5).until(
- EC.presence_of_element_located((By.NAME, "start"))
- )
- start_exam_elem.click()
-
- self.test_c_question(question_label=1)
- self.test_python_question(question_label=3)
- self.test_bash_question(question_label=2)
-
- def close_quiz(self):
- quit_link_elem = WebDriverWait(self.driver, 5).until(
- EC.presence_of_element_located((By.ID, "login_again"))
- )
- quit_link_elem.click()
-
- def logout(self):
- logout_link_elem = WebDriverWait(self.driver, 5).until(
- EC.presence_of_element_located((By.ID, "logout"))
- )
- logout_link_elem.click()
-
-def user_gen(url, ids):
- return [(url, 'User%d'%x, 'User%d'%x) for x in ids]
-
-def wrap_run_load_test(args):
- url = "http://yaksh.fossee.aero.iitb.ac.in/exam/"
- selenium_test = SeleniumTest(url=url, quiz_name=quiz_name)
- return selenium_test.run_load_test(*args)
-
-if __name__ == '__main__':
- parser = argparse.ArgumentParser()
- parser.add_argument('url', type=str, help="url of the website being tested")
- parser.add_argument('start', type=int, help="Starting user id")
- parser.add_argument("-n", "--number", type=int, default=10, help="number of users")
- opts = parser.parse_args()
-
- quiz_name = "Demo quiz"
- selenium_test = SeleniumTest(url=opts.url, quiz_name=quiz_name)
- pool = multiprocessing.Pool(opts.number)
- pool.map(wrap_run_load_test, user_gen(opts.url, range(opts.start, opts.start + opts.number)))
- pool.close()
- pool.join()
-
--
cgit