From f6dd24377a04cceabea93cd9309726e7f3195295 Mon Sep 17 00:00:00 2001 From: Erwan Rouchet <rouchet@teklia.com> Date: Fri, 7 Sep 2018 11:24:15 +0200 Subject: [PATCH] Add unit tests --- arkindex/project/tests/__init__.py | 1 + arkindex/project/tests/test_elastic.py | 145 +++++++++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 arkindex/project/tests/test_elastic.py diff --git a/arkindex/project/tests/__init__.py b/arkindex/project/tests/__init__.py index 74b0c4a9fc..157fdf885c 100644 --- a/arkindex/project/tests/__init__.py +++ b/arkindex/project/tests/__init__.py @@ -57,6 +57,7 @@ class RedisMockMixin(object): def tearDown(self): for p in self.patches: p.stop() + self.messages.stop() self.redis.flushall() diff --git a/arkindex/project/tests/test_elastic.py b/arkindex/project/tests/test_elastic.py new file mode 100644 index 0000000000..608301e6f4 --- /dev/null +++ b/arkindex/project/tests/test_elastic.py @@ -0,0 +1,145 @@ +from unittest import TestCase +from unittest.mock import patch, MagicMock +from arkindex.project.elastic import ESQuerySet + + +class TestESQuerySet(TestCase): + + @classmethod + def setUpClass(cls): + cls.es_index = 'es_index' + cls.es_type = 'es_type' + cls.query = { + "some": "query" + } + cls.aggs = { + "some": "aggs" + } + cls.sort = { + "some sort of": "sorts" + } + cls.post_process_mock = MagicMock() + + cls.es_mock = patch('arkindex.project.elastic.Elasticsearch').start() + + cls.esqs = ESQuerySet( + es_index=cls.es_index, + es_type=cls.es_type, + post_process=cls.post_process_mock, + query=cls.query, + aggs=cls.aggs, + sort=cls.sort, + ) + + def setUp(self): + self.es_mock.reset_mock() + self.es_mock().reset_mock() + self.post_process_mock.reset_mock() + + def test_count(self): + """ + Check the ESQuerySet supports the count() and __len__ methods and calls ES correctly + """ + self.es_mock().count.return_value = {'count': 42} + + self.assertEqual(self.esqs.count(), 42) + self.assertEqual(len(self.esqs), 42) + + self.assertEqual(self.es_mock().count.call_count, 2) + args, kwargs = self.es_mock().count.call_args + self.assertEqual(len(args), 0) + self.assertDictEqual(kwargs, { + "index": self.es_index, + "doc_type": self.es_type, + "body": { + "query": self.query, + }, + }) + + def test_iter(self): + """ + Check trying to iterate on a ESQuerySet fetches all the results from ES + """ + self.es_mock().count.return_value = {'count': 42} + self.es_mock().search.return_value = {'some': 'results'} + + iter(self.esqs) + + self.assertEqual(self.es_mock().count.call_count, 1) + self.assertEqual(self.es_mock().search.call_count, 1) + self.assertEqual(self.post_process_mock.call_count, 1) + + args, kwargs = self.es_mock().search.call_args + self.assertEqual(len(args), 0) + self.assertEqual(kwargs['body']['from'], 0) + self.assertEqual(kwargs['body']['size'], 42) + + args, kwargs = self.post_process_mock.call_args + self.assertTupleEqual(args, ({'some': 'results'}, )) + + def test_slice(self): + """ + Check retrieving a slice from the ESQuerySEt retrieves only this slice from ES + """ + self.esqs[10:15] + + self.assertEqual(self.es_mock().search.call_count, 1) + self.assertEqual(self.post_process_mock.call_count, 1) + + args, kwargs = self.es_mock().search.call_args + self.assertEqual(len(args), 0) + self.assertDictEqual(kwargs, { + "index": self.es_index, + "doc_type": self.es_type, + "body": { + "from": 10, + "size": 5, + "_source": True, + "query": self.query, + "aggs": self.aggs, + "sort": self.sort, + } + }) + + def test_single_item(self): + """ + Check retrieving a single item by index from the ESQuerySet retrieves a single item from ES + """ + self.esqs[10] + + self.assertEqual(self.es_mock().search.call_count, 1) + self.assertEqual(self.post_process_mock.call_count, 1) + + args, kwargs = self.es_mock().search.call_args + self.assertEqual(len(args), 0) + self.assertDictEqual(kwargs, { + "index": self.es_index, + "doc_type": self.es_type, + "body": { + "from": 10, + "size": 1, + "_source": True, + "query": self.query, + "aggs": self.aggs, + "sort": self.sort, + } + }) + + def test_large_results(self): + """ + Check the ESQuerySet caps to 10,000 results to prevent errors without the scroll API + """ + self.es_mock().count.return_value = {'count': 99999} + self.es_mock().search.return_value = {'some': 'results'} + + self.assertEqual(len(self.esqs), 10000) + self.esqs[500:20000] + + self.assertEqual(self.es_mock().count.call_count, 1) + self.assertEqual(self.es_mock().search.call_count, 1) + self.assertEqual(self.post_process_mock.call_count, 1) + + args, kwargs = self.es_mock().search.call_args + self.assertEqual(len(args), 0) + self.assertEqual(kwargs['body']['from'], 500) + self.assertEqual(kwargs['body']['size'], 10000) -- GitLab