diff --git a/Makefile b/Makefile index 0be8b17d..8e1cfd0a 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,10 @@ -.PHONY: clean quality requirements validate test test-python quality-python +.PHONY: clean quality requirements validate test test-with-es quality-python install-local clean: find . -name '__pycache__' -exec rm -rf {} + find . -name '*.pyc' -exec rm -f {} + find . -name '*.pyo' -exec rm -f {} + - find . -name '*~' -exec rm -f {} + + find . -name '*~' -exec rm -f {} + coverage erase rm -rf coverage htmlcov rm -fr build/ @@ -51,7 +51,8 @@ upgrade: ## update the requirements/*.txt files with the latest packages satisfy sed '/^[dD]jango==/d' requirements/testing.txt > requirements/testing.tmp mv requirements/testing.tmp requirements/testing.txt -test-python: clean ## run tests using pytest and generate coverage report - pytest +test: test_with_es ## run tests and generate coverage report -test: test-python ## run tests and generate coverage report +install-local: ## installs your local edx-search into the LMS and CMS python virtualenvs + docker exec -t edx.devstack.lms bash -c '. /edx/app/edxapp/venvs/edxapp/bin/activate && cd /edx/app/edxapp/edx-platform && pip uninstall -y edx-search && pip install -e /edx/src/edx-search && pip freeze | grep edx-search' + docker exec -t edx.devstack.cms bash -c '. /edx/app/edxapp/venvs/edxapp/bin/activate && cd /edx/app/edxapp/edx-platform && pip uninstall -y edx-search && pip install -e /edx/src/edx-search && pip freeze | grep edx-search' diff --git a/edxsearch/__init__.py b/edxsearch/__init__.py index 0506050a..3af5eb5f 100644 --- a/edxsearch/__init__.py +++ b/edxsearch/__init__.py @@ -1,3 +1,3 @@ """ Container module for testing / demoing search """ -__version__ = '3.6.0' +__version__ = '3.7.0' diff --git a/search/api.py b/search/api.py index 81c26090..177e909a 100644 --- a/search/api.py +++ b/search/api.py @@ -41,7 +41,7 @@ class NoSearchEngineError(Exception): """ -def perform_search( +def perform_course_search( search_term, user=None, size=10, @@ -62,14 +62,16 @@ def perform_search( ) if not searcher: raise NoSearchEngineError("No search engine specified in settings.SEARCH_ENGINE") + log_search_params = getattr(settings, "SEARCH_COURSEWARE_CONTENT_LOG_PARAMS", False) - results = searcher.search_string( - search_term, + results = searcher.search( + query_string=search_term, field_dictionary=field_dictionary, filter_dictionary=filter_dictionary, exclude_dictionary=exclude_dictionary, size=size, from_=from_, + log_search_params=log_search_params, ) # post-process the result diff --git a/search/elastic.py b/search/elastic.py index f895564a..4e38093a 100644 --- a/search/elastic.py +++ b/search/elastic.py @@ -477,6 +477,7 @@ def search(self, aggregation_terms=None, exclude_ids=None, use_field_match=False, + log_search_params=False, **kwargs): # pylint: disable=arguments-differ, unused-argument """ Implements call to search the index for the desired content. @@ -653,6 +654,9 @@ def search(self, if aggregation_terms: body["aggs"] = _process_aggregation_terms(aggregation_terms) + if log_search_params: + log.info(f"full elastic search body {body}") + try: es_response = self._es.search(index=self._prefixed_index_name, body=body, **kwargs) except exceptions.ElasticsearchException as ex: diff --git a/search/search_engine_base.py b/search/search_engine_base.py index e2b9ef1f..49b2e367 100644 --- a/search/search_engine_base.py +++ b/search/search_engine_base.py @@ -48,6 +48,7 @@ def search(self, filter_dictionary=None, exclude_dictionary=None, aggregation_terms=None, + log_search_params=False, **kwargs): # pylint: disable=too-many-arguments """ Search for matching documents within the search index. diff --git a/search/tests/mock_search_engine.py b/search/tests/mock_search_engine.py index 10f243e4..52894800 100644 --- a/search/tests/mock_search_engine.py +++ b/search/tests/mock_search_engine.py @@ -340,6 +340,7 @@ def search(self, filter_dictionary=None, exclude_dictionary=None, aggregation_terms=None, + log_search_params=False, **kwargs): # pylint: disable=too-many-arguments """ Perform search upon documents within index. diff --git a/search/tests/test_engines.py b/search/tests/test_engines.py index 659d4cc9..3340340d 100644 --- a/search/tests/test_engines.py +++ b/search/tests/test_engines.py @@ -13,7 +13,7 @@ from django.test.utils import override_settings from elasticsearch import exceptions from elasticsearch.helpers import BulkIndexError -from search.api import NoSearchEngineError, perform_search +from search.api import NoSearchEngineError, perform_course_search from search.elastic import RESERVED_CHARACTERS from search.tests.mock_search_engine import (MockSearchEngine, json_date_to_datetime) @@ -238,7 +238,7 @@ class TestNone(TestCase): def test_perform_search(self): """ search opertaion should yeild an exception with no search engine """ with self.assertRaises(NoSearchEngineError): - perform_search("abc test") + perform_course_search("abc test") @override_settings(SEARCH_ENGINE="search.elastic.ElasticSearchEngine") diff --git a/search/tests/tests.py b/search/tests/tests.py index 62ea00cd..3fe5047b 100644 --- a/search/tests/tests.py +++ b/search/tests/tests.py @@ -130,6 +130,15 @@ def test_find_string(self): response = self.searcher.search_string(test_string) self.assertEqual(response["total"], 3) + def test_log_params(self): + """ Test that if you turn on detailed logging, search doesn't explode. """ + test_string = "A test string" + self.searcher.index([{"content": {"name": test_string}}]) + + # search string + response = self.searcher.search(query_string=test_string, log_search_params=True) + self.assertEqual(response["total"], 1) + def test_field(self): """ test matching on a field """ test_string = "A test string" diff --git a/search/views.py b/search/views.py index c59f7463..0c30d426 100644 --- a/search/views.py +++ b/search/views.py @@ -10,7 +10,7 @@ from django.views.decorators.http import require_POST from eventtracking import tracker as track -from .api import perform_search, course_discovery_search, course_discovery_filter_fields +from .api import perform_course_search, course_discovery_search, course_discovery_filter_fields from .initializer import SearchInitializer # log appears to be standard name used for logger @@ -96,7 +96,7 @@ def do_search(request, course_id=None): } ) - results = perform_search( + results = perform_course_search( search_term, user=request.user, size=size,