Browse Source

[fix] unit tests: call searx.search.initialize in test's setUp

Depending on the order the unit tests are executed, the searx.search module is
initalized or not, issue reported in [1]::

    Traceback (most recent call last):
      File "searxng/tests/unit/test_results.py", line 72, in test_result_merge_by_title
        self.container.extend('stract', [fake_result(engine='stract', title='short title')])
      File "searxng/searx/results.py", line 243, in extend
        histogram_observe(standard_result_count, 'engine', engine_name, 'result', 'count')
      File "searxng/searx/metrics/__init__.py", line 49, in histogram_observe
        histogram_storage.get(*args).observe(duration)
        ^^^^^^^^^^^^^^^^^^^^^
      AttributeError: 'NoneType' object has no attribute 'get'

To ensure that the searx.search module is initialized, the

- searx.engines.load_engines is replace by
- searx.search.initialize

[1] https://github.com/searxng/searxng/pull/3932#discussion_r1822406569

Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
Markus Heiser 6 months ago
parent
commit
bb04699b17

+ 3 - 3
tests/unit/processors/test_online.py

@@ -3,7 +3,7 @@
 
 
 from searx.search import SearchQuery, EngineRef
 from searx.search import SearchQuery, EngineRef
 from searx.search.processors import online
 from searx.search.processors import online
-from searx.engines import load_engines
+import searx.search
 from searx import engines
 from searx import engines
 
 
 from tests import SearxTestCase
 from tests import SearxTestCase
@@ -22,10 +22,10 @@ TEST_ENGINE = {
 class TestOnlineProcessor(SearxTestCase):  # pylint: disable=missing-class-docstring
 class TestOnlineProcessor(SearxTestCase):  # pylint: disable=missing-class-docstring
 
 
     def setUp(self):
     def setUp(self):
-        load_engines([TEST_ENGINE])
+        searx.search.initialize([TEST_ENGINE])
 
 
     def tearDown(self):
     def tearDown(self):
-        load_engines([])
+        searx.search.load_engines([])
 
 
     def _get_params(self, online_processor, search_query, engine_category):
     def _get_params(self, online_processor, search_query, engine_category):
         params = online_processor.get_params(search_query, engine_category)
         params = online_processor.get_params(search_query, engine_category)

+ 1 - 16
tests/unit/test_engine_mariadb_server.py

@@ -2,26 +2,11 @@
 # pylint: disable=missing-module-docstring
 # pylint: disable=missing-module-docstring
 
 
 from unittest.mock import MagicMock, Mock
 from unittest.mock import MagicMock, Mock
-from searx.engines import load_engines, mariadb_server
+from searx.engines import mariadb_server
 from tests import SearxTestCase
 from tests import SearxTestCase
 
 
 
 
 class MariadbServerTests(SearxTestCase):  # pylint: disable=missing-class-docstring
 class MariadbServerTests(SearxTestCase):  # pylint: disable=missing-class-docstring
-    def setUp(self):
-        load_engines(
-            [
-                {
-                    'name': 'mariadb server',
-                    'engine': 'mariadb_server',
-                    'shortcut': 'mdb',
-                    'timeout': 9.0,
-                    'disabled': True,
-                }
-            ]
-        )
-
-    def tearDown(self):
-        load_engines([])
 
 
     def test_init_no_query_str_raises(self):
     def test_init_no_query_str_raises(self):
         self.assertRaises(ValueError, lambda: mariadb_server.init({}))
         self.assertRaises(ValueError, lambda: mariadb_server.init({}))

+ 24 - 18
tests/unit/test_engine_tineye.py

@@ -1,28 +1,34 @@
 # SPDX-License-Identifier: AGPL-3.0-or-later
 # SPDX-License-Identifier: AGPL-3.0-or-later
 # pylint: disable=missing-module-docstring
 # pylint: disable=missing-module-docstring
 
 
-
+import logging
 from datetime import datetime
 from datetime import datetime
 from unittest.mock import Mock
 from unittest.mock import Mock
 from requests import HTTPError
 from requests import HTTPError
 from parameterized import parameterized
 from parameterized import parameterized
-from searx.engines import load_engines, tineye
+import searx.search
+import searx.engines
 from tests import SearxTestCase
 from tests import SearxTestCase
 
 
 
 
 class TinEyeTests(SearxTestCase):  # pylint: disable=missing-class-docstring
 class TinEyeTests(SearxTestCase):  # pylint: disable=missing-class-docstring
 
 
     def setUp(self):
     def setUp(self):
-        load_engines([{'name': 'tineye', 'engine': 'tineye', 'shortcut': 'tin', 'timeout': 9.0, 'disabled': True}])
+        searx.search.initialize(
+            [{'name': 'tineye', 'engine': 'tineye', 'shortcut': 'tin', 'timeout': 9.0, 'disabled': True}]
+        )
+
+        self.tineye = searx.engines.engines['tineye']
+        self.tineye.logger.setLevel(logging.CRITICAL)
 
 
     def tearDown(self):
     def tearDown(self):
-        load_engines([])
+        searx.search.load_engines([])
 
 
     def test_status_code_raises(self):
     def test_status_code_raises(self):
         response = Mock()
         response = Mock()
         response.status_code = 401
         response.status_code = 401
         response.raise_for_status.side_effect = HTTPError()
         response.raise_for_status.side_effect = HTTPError()
-        self.assertRaises(HTTPError, lambda: tineye.response(response))
+        self.assertRaises(HTTPError, lambda: self.tineye.response(response))
 
 
     @parameterized.expand([(400), (422)])
     @parameterized.expand([(400), (422)])
     def test_returns_empty_list(self, status_code):
     def test_returns_empty_list(self, status_code):
@@ -30,7 +36,7 @@ class TinEyeTests(SearxTestCase):  # pylint: disable=missing-class-docstring
         response.json.return_value = {}
         response.json.return_value = {}
         response.status_code = status_code
         response.status_code = status_code
         response.raise_for_status.side_effect = HTTPError()
         response.raise_for_status.side_effect = HTTPError()
-        results = tineye.response(response)
+        results = self.tineye.response(response)
         self.assertEqual(0, len(results))
         self.assertEqual(0, len(results))
 
 
     def test_logs_format_for_422(self):
     def test_logs_format_for_422(self):
@@ -39,9 +45,9 @@ class TinEyeTests(SearxTestCase):  # pylint: disable=missing-class-docstring
         response.status_code = 422
         response.status_code = 422
         response.raise_for_status.side_effect = HTTPError()
         response.raise_for_status.side_effect = HTTPError()
 
 
-        with self.assertLogs(tineye.logger) as assert_logs_context:
-            tineye.response(response)
-            self.assertIn(tineye.FORMAT_NOT_SUPPORTED, ','.join(assert_logs_context.output))
+        with self.assertLogs(self.tineye.logger) as assert_logs_context:
+            self.tineye.response(response)
+            self.assertIn(self.tineye.FORMAT_NOT_SUPPORTED, ','.join(assert_logs_context.output))
 
 
     def test_logs_signature_for_422(self):
     def test_logs_signature_for_422(self):
         response = Mock()
         response = Mock()
@@ -49,9 +55,9 @@ class TinEyeTests(SearxTestCase):  # pylint: disable=missing-class-docstring
         response.status_code = 422
         response.status_code = 422
         response.raise_for_status.side_effect = HTTPError()
         response.raise_for_status.side_effect = HTTPError()
 
 
-        with self.assertLogs(tineye.logger) as assert_logs_context:
-            tineye.response(response)
-            self.assertIn(tineye.NO_SIGNATURE_ERROR, ','.join(assert_logs_context.output))
+        with self.assertLogs(self.tineye.logger) as assert_logs_context:
+            self.tineye.response(response)
+            self.assertIn(self.tineye.NO_SIGNATURE_ERROR, ','.join(assert_logs_context.output))
 
 
     def test_logs_download_for_422(self):
     def test_logs_download_for_422(self):
         response = Mock()
         response = Mock()
@@ -59,9 +65,9 @@ class TinEyeTests(SearxTestCase):  # pylint: disable=missing-class-docstring
         response.status_code = 422
         response.status_code = 422
         response.raise_for_status.side_effect = HTTPError()
         response.raise_for_status.side_effect = HTTPError()
 
 
-        with self.assertLogs(tineye.logger) as assert_logs_context:
-            tineye.response(response)
-            self.assertIn(tineye.DOWNLOAD_ERROR, ','.join(assert_logs_context.output))
+        with self.assertLogs(self.tineye.logger) as assert_logs_context:
+            self.tineye.response(response)
+            self.assertIn(self.tineye.DOWNLOAD_ERROR, ','.join(assert_logs_context.output))
 
 
     def test_logs_description_for_400(self):
     def test_logs_description_for_400(self):
         description = 'There was a problem with that request. Error ID: ad5fc955-a934-43c1-8187-f9a61d301645'
         description = 'There was a problem with that request. Error ID: ad5fc955-a934-43c1-8187-f9a61d301645'
@@ -70,8 +76,8 @@ class TinEyeTests(SearxTestCase):  # pylint: disable=missing-class-docstring
         response.status_code = 400
         response.status_code = 400
         response.raise_for_status.side_effect = HTTPError()
         response.raise_for_status.side_effect = HTTPError()
 
 
-        with self.assertLogs(tineye.logger) as assert_logs_context:
-            tineye.response(response)
+        with self.assertLogs(self.tineye.logger) as assert_logs_context:
+            self.tineye.response(response)
             self.assertIn(description, ','.join(assert_logs_context.output))
             self.assertIn(description, ','.join(assert_logs_context.output))
 
 
     def test_crawl_date_parses(self):
     def test_crawl_date_parses(self):
@@ -90,5 +96,5 @@ class TinEyeTests(SearxTestCase):  # pylint: disable=missing-class-docstring
             ]
             ]
         }
         }
         response.status_code = 200
         response.status_code = 200
-        results = tineye.response(response)
+        results = self.tineye.response(response)
         self.assertEqual(date, results[0]['publishedDate'])
         self.assertEqual(date, results[0]['publishedDate'])

+ 3 - 3
tests/unit/test_query.py

@@ -2,7 +2,7 @@
 # pylint: disable=missing-module-docstring
 # pylint: disable=missing-module-docstring
 
 
 from parameterized.parameterized import parameterized
 from parameterized.parameterized import parameterized
-from searx.engines import load_engines
+import searx.search
 from searx.query import RawTextQuery
 from searx.query import RawTextQuery
 from tests import SearxTestCase
 from tests import SearxTestCase
 
 
@@ -218,10 +218,10 @@ class TestBang(SearxTestCase):  # pylint:disable=missing-class-docstring
     THE_QUERY = 'the query'
     THE_QUERY = 'the query'
 
 
     def setUp(self):
     def setUp(self):
-        load_engines(TEST_ENGINES)
+        searx.search.initialize(TEST_ENGINES)
 
 
     def tearDown(self):
     def tearDown(self):
-        load_engines([])
+        searx.search.load_engines([])
 
 
     @parameterized.expand(SPECIFIC_BANGS)
     @parameterized.expand(SPECIFIC_BANGS)
     def test_bang(self, bang: str):
     def test_bang(self, bang: str):

+ 4 - 5
tests/unit/test_results.py

@@ -2,7 +2,7 @@
 # pylint: disable=missing-module-docstring
 # pylint: disable=missing-module-docstring
 
 
 from searx.results import ResultContainer
 from searx.results import ResultContainer
-from searx.engines import load_engines
+import searx.search
 from tests import SearxTestCase
 from tests import SearxTestCase
 
 
 
 
@@ -36,17 +36,16 @@ def fake_result(url='https://aa.bb/cc?dd=ee#ff', title='aaa', content='bbb', eng
 
 
 
 
 class ResultContainerTestCase(SearxTestCase):  # pylint: disable=missing-class-docstring
 class ResultContainerTestCase(SearxTestCase):  # pylint: disable=missing-class-docstring
+
     def setUp(self) -> None:
     def setUp(self) -> None:
         stract_engine = make_test_engine_dict(name="stract", engine="stract", shortcut="stra")
         stract_engine = make_test_engine_dict(name="stract", engine="stract", shortcut="stra")
         duckduckgo_engine = make_test_engine_dict(name="duckduckgo", engine="duckduckgo", shortcut="ddg")
         duckduckgo_engine = make_test_engine_dict(name="duckduckgo", engine="duckduckgo", shortcut="ddg")
         mojeek_engine = make_test_engine_dict(name="mojeek", engine="mojeek", shortcut="mjk")
         mojeek_engine = make_test_engine_dict(name="mojeek", engine="mojeek", shortcut="mjk")
-
-        load_engines([stract_engine, duckduckgo_engine, mojeek_engine])
-
+        searx.search.initialize([stract_engine, duckduckgo_engine, mojeek_engine])
         self.container = ResultContainer()
         self.container = ResultContainer()
 
 
     def tearDown(self):
     def tearDown(self):
-        load_engines([])
+        searx.search.load_engines([])
 
 
     def test_empty(self):
     def test_empty(self):
         self.assertEqual(self.container.get_ordered_results(), [])
         self.assertEqual(self.container.get_ordered_results(), [])