Commit 95df3888 by Tim Babych

add test with ES completely disabled

parent 8783c076
...@@ -16,5 +16,6 @@ after_success: ...@@ -16,5 +16,6 @@ after_success:
- coveralls - coveralls
env: env:
- ESVER=-
- ESVER=0.90.11 - ESVER=0.90.11
- ESVER=1.4.2 - ESVER=1.4.2
...@@ -3,9 +3,17 @@ PACKAGES = notesserver notesapi ...@@ -3,9 +3,17 @@ PACKAGES = notesserver notesapi
validate: test.requirements test coverage validate: test.requirements test coverage
ifeq ($(ESVER),-)
test_settings = notesserver.settings.test_es_disabled
else
test_settings = notesserver.settings.test
endif
test: clean test: clean
./manage.py test --settings=notesserver.settings.test --with-coverage --with-ignore-docstrings \ ./manage.py test --settings=$(test_settings) --with-coverage --with-ignore-docstrings \
--exclude-dir=notesserver/settings --cover-inclusive --cover-branches \ --exclude-dir=notesserver/settings --cover-inclusive --cover-branches \
--ignore-files=search_indexes.py \
--cover-html --cover-html-dir=build/coverage/html/ \ --cover-html --cover-html-dir=build/coverage/html/ \
--cover-xml --cover-xml-file=build/coverage/coverage.xml \ --cover-xml --cover-xml-file=build/coverage/coverage.xml \
$(foreach package,$(PACKAGES),--cover-package=$(package)) \ $(foreach package,$(PACKAGES),--cover-package=$(package)) \
......
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import jwt import jwt
import unittest
from calendar import timegm from calendar import timegm
from datetime import datetime, timedelta from datetime import datetime, timedelta
from mock import patch from mock import patch
from django.core.management import call_command from django.core.management import call_command
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.core.exceptions import ImproperlyConfigured
from django.conf import settings from django.conf import settings
from django.http import QueryDict from django.http import QueryDict
...@@ -15,9 +17,14 @@ from rest_framework.test import APITestCase ...@@ -15,9 +17,14 @@ from rest_framework.test import APITestCase
from .helpers import get_id_token from .helpers import get_id_token
from notesapi.v1.models import Note from notesapi.v1.models import Note
TEST_USER = "test_user_id" TEST_USER = "test_user_id"
if not settings.ES_DISABLED:
import haystack
else:
def call_command(*args, **kwargs):
pass
class BaseAnnotationViewTests(APITestCase): class BaseAnnotationViewTests(APITestCase):
""" """
...@@ -111,31 +118,6 @@ class AnnotationViewTests(BaseAnnotationViewTests): ...@@ -111,31 +118,6 @@ class AnnotationViewTests(BaseAnnotationViewTests):
self.assertEqual(response.data['user'], TEST_USER) self.assertEqual(response.data['user'], TEST_USER)
# @patch('django.conf.settings.ES_DISABLED', True)
# def test_create_es_disabled(self):
# """
# Ensure we can create note in database when elasticsearch is disabled.
# """
# url = reverse('api:v1:annotations')
# response = self.client.post(url, self.payload, format='json')
# self.assertEqual(response.status_code, status.HTTP_201_CREATED)
# Note.objects.get(id=response.data['id'])
# self.assertEqual(note_searcher.filter(id=response.data['id']).count(), 0)
# def test_delete_es_disabled(self):
# """
# Ensure we can delete note in database when elasticsearch is disabled.
# """
# url = reverse('api:v1:annotations')
# response = self.client.post(url, self.payload, format='json')
# call_command('update_index')
# self.assertEqual(note_searcher.filter(id=response.data['id']).count(), 1)
# with patch('django.conf.settings.ES_DISABLED', True):
# Note.objects.get(id=response.data['id']).delete()
# self.assertEqual(note_searcher.filter(id=response.data['id']).count(), 1)
def test_create_ignore_created(self): def test_create_ignore_created(self):
""" """
Test if annotation 'created' field is not used by API. Test if annotation 'created' field is not used by API.
...@@ -350,6 +332,7 @@ class AnnotationViewTests(BaseAnnotationViewTests): ...@@ -350,6 +332,7 @@ class AnnotationViewTests(BaseAnnotationViewTests):
self.assertEqual(len(results['rows']), 1) self.assertEqual(len(results['rows']), 1)
self.assertEqual(results['rows'][0]['text'], 'Second note') self.assertEqual(results['rows'][0]['text'], 'Second note')
@unittest.skipIf(settings.ES_DISABLED, "MySQL does not do highlighing")
def test_search_highlight(self): def test_search_highlight(self):
""" """
Tests highlighting. Tests highlighting.
...@@ -381,6 +364,7 @@ class AnnotationViewTests(BaseAnnotationViewTests): ...@@ -381,6 +364,7 @@ class AnnotationViewTests(BaseAnnotationViewTests):
self.assertEqual(results['rows'][1]['text'], 'Second note') self.assertEqual(results['rows'][1]['text'], 'Second note')
self.assertEqual(results['rows'][2]['text'], 'First one') self.assertEqual(results['rows'][2]['text'], 'First one')
@unittest.skipIf(settings.ES_DISABLED, "Unicode support in MySQL is limited")
def test_search_unicode(self): def test_search_unicode(self):
""" """
Tests searching of unicode strings. Tests searching of unicode strings.
......
import logging import logging
import json import json
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
...@@ -9,7 +11,9 @@ from rest_framework.response import Response ...@@ -9,7 +11,9 @@ from rest_framework.response import Response
from rest_framework.views import APIView from rest_framework.views import APIView
from notesapi.v1.models import Note from notesapi.v1.models import Note
from haystack.query import SearchQuerySet
if not settings.ES_DISABLED:
from haystack.query import SearchQuerySet
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -18,10 +22,33 @@ class AnnotationSearchView(APIView): ...@@ -18,10 +22,33 @@ class AnnotationSearchView(APIView):
""" """
Search annotations. Search annotations.
""" """
def get(self, *args, **kwargs): # pylint: disable=unused-argument def get(self, *args, **kwargs): # pylint: disable=unused-argument
if settings.ES_DISABLED:
results = self.get_from_db(*args, **kwargs)
else:
results = self.get_from_es(*args, **kwargs)
return Response({'total': len(results), 'rows': results})
def get_from_db(self, *args, **kwargs): # pylint: disable=unused-argument
""" """
Search annotations. Search annotations in database
"""
params = self.request.QUERY_PARAMS.dict()
query = Note.objects.filter(
**{f: v for (f, v) in params.items() if f in ('course_id', 'usage_id')}
).order_by('-updated')
if 'user' in params:
query = query.filter(user_id=params['user'])
if 'text' in params:
query = query.filter(text__icontains=params['text'])
return [note.as_dict() for note in query]
def get_from_es(self, *args, **kwargs): # pylint: disable=unused-argument
"""
Search annotations in ElasticSearch
""" """
params = self.request.QUERY_PARAMS.dict() params = self.request.QUERY_PARAMS.dict()
query = SearchQuerySet().models(Note).filter( query = SearchQuerySet().models(Note).filter(
...@@ -40,7 +67,7 @@ class AnnotationSearchView(APIView): ...@@ -40,7 +67,7 @@ class AnnotationSearchView(APIView):
note_dict['text'] = item.highlighted[0] note_dict['text'] = item.highlighted[0]
results.append(note_dict) results.append(note_dict)
return Response({'total': len(results), 'rows': results}) return results
class AnnotationListView(APIView): class AnnotationListView(APIView):
......
...@@ -18,6 +18,7 @@ SECRET_KEY = '*^owi*4%!%9=#h@app!l^$jz8(c*q297^)4&4yn^#_m#fq=z#l' ...@@ -18,6 +18,7 @@ SECRET_KEY = '*^owi*4%!%9=#h@app!l^$jz8(c*q297^)4&4yn^#_m#fq=z#l'
CLIENT_ID = 'edx-notes-id' CLIENT_ID = 'edx-notes-id'
CLIENT_SECRET = 'edx-notes-secret' CLIENT_SECRET = 'edx-notes-secret'
ES_DISABLED = False
HAYSTACK_CONNECTIONS = { HAYSTACK_CONNECTIONS = {
'default': { 'default': {
'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine', 'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
...@@ -41,7 +42,7 @@ MIDDLEWARE_CLASSES = ( ...@@ -41,7 +42,7 @@ MIDDLEWARE_CLASSES = (
'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.csrf.CsrfViewMiddleware',
) )
INSTALLED_APPS = ( INSTALLED_APPS = [
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'rest_framework', 'rest_framework',
'rest_framework_swagger', 'rest_framework_swagger',
...@@ -49,7 +50,7 @@ INSTALLED_APPS = ( ...@@ -49,7 +50,7 @@ INSTALLED_APPS = (
'haystack', 'haystack',
'notesapi', 'notesapi',
'notesapi.v1', 'notesapi.v1',
) ]
STATIC_URL = '/static/' STATIC_URL = '/static/'
......
...@@ -17,3 +17,7 @@ with open(CONFIG_ROOT / "edx-notes-api.yml") as yaml_file: ...@@ -17,3 +17,7 @@ with open(CONFIG_ROOT / "edx-notes-api.yml") as yaml_file:
config_from_yaml = yaml.load(yaml_file) config_from_yaml = yaml.load(yaml_file)
vars().update(config_from_yaml) vars().update(config_from_yaml)
if ES_DISABLED:
HAYSTACK_CONNECTIONS = {}
INSTALLED_APPS.remove('haystack')
...@@ -2,17 +2,27 @@ import traceback ...@@ -2,17 +2,27 @@ import traceback
import datetime import datetime
from django.db import connection from django.db import connection
from django.conf import settings
from rest_framework import status from rest_framework import status
from rest_framework.permissions import AllowAny from rest_framework.permissions import AllowAny
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.decorators import api_view, permission_classes from rest_framework.decorators import api_view, permission_classes
from elasticsearch.exceptions import TransportError from elasticsearch.exceptions import TransportError
from haystack import connections
if not settings.ES_DISABLED:
from haystack import connections
def get_es(): def get_es():
return connections['default'].get_backend().conn return connections['default'].get_backend().conn
else:
from mock import Mock
def get_es():
return Mock(
ping=lambda: True,
info=lambda: {},
)
@api_view(['GET']) @api_view(['GET'])
......
...@@ -6,6 +6,11 @@ ...@@ -6,6 +6,11 @@
set -e set -e
echo "Installing Elasticsearch $ESVER" >&2 if [[ $ESVER == "-" ]];
then
exit 0
fi
echo "Installing ElasticSearch $ESVER" >&2
wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-$ESVER.tar.gz wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-$ESVER.tar.gz
tar xzvf elasticsearch-$ESVER.tar.gz tar xzvf elasticsearch-$ESVER.tar.gz
...@@ -7,7 +7,12 @@ ...@@ -7,7 +7,12 @@
set -e set -e
echo "Starting Elasticsearch $ESVER" >&2 if [[ $ESVER == "-" ]];
then
exit 0
fi
echo "Starting ElasticSearch $ESVER" >&2
pushd elasticsearch-$ESVER pushd elasticsearch-$ESVER
# Elasticsearch 0.90 daemonizes automatically, but 1.0+ requires # Elasticsearch 0.90 daemonizes automatically, but 1.0+ requires
# a -d argument. # a -d argument.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment