diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml index eb6e4ca..befc7a0 100644 --- a/.github/workflows/test-python.yml +++ b/.github/workflows/test-python.yml @@ -63,6 +63,7 @@ jobs: dates datetimes db_functions + dbshell_ delete delete_regress empty diff --git a/tests/dbshell_/__init__.py b/tests/dbshell_/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/dbshell_/tests.py b/tests/dbshell_/tests.py new file mode 100644 index 0000000..e85f25d --- /dev/null +++ b/tests/dbshell_/tests.py @@ -0,0 +1,116 @@ +import signal +from unittest import mock + +from django.db import connection +from django.test import SimpleTestCase + +from django_mongodb.client import DatabaseClient + + +class MongoDbshellTests(SimpleTestCase): + def settings_to_cmd_args_env(self, settings_dict, parameters=None): + if parameters is None: + parameters = [] + return DatabaseClient.settings_to_cmd_args_env(settings_dict, parameters) + + def test_fails_with_keyerror_on_incomplete_config(self): + with self.assertRaises(KeyError): + self.settings_to_cmd_args_env({}) + + def test_basic_params_specified_in_settings(self): + for options_parameters in [(None, None, None), ("value1", "value2", True)]: + with self.subTest(keys=options_parameters): + authentication_database, authentication_mechanism, retry_writes = options_parameters + if authentication_database is not None: + expected_args = [ + "mongosh", + "--host", + "somehost", + "--port", + 444, + "--username", + "someuser", + "--password", + "somepassword", + "--retryWrites", + "true", + "somedbname", + ] + else: + expected_args = [ + "mongosh", + "--host", + "somehost", + "--port", + 444, + "--username", + "someuser", + "--password", + "somepassword", + "somedbname", + ] + + self.assertEqual( + self.settings_to_cmd_args_env( + { + "NAME": "somedbname", + "USER": "someuser", + "PASSWORD": "somepassword", + "HOST": "somehost", + "PORT": 444, + "OPTIONS": { + "authenticationDatabase": authentication_database, + "authenticationMechanism": authentication_mechanism, + "retryWrites": retry_writes, + }, + } + ), + (expected_args, None), + ) + + def test_options_override_settings_proper_values(self): + settings_port = 444 + options_port = 555 + self.assertNotEqual(settings_port, options_port, "test pre-req") + expected_args = [ + "mongosh", + "--host", + "settinghost", + "--port", + 444, + "--username", + "settinguser", + "--password", + "settingpassword", + "settingdbname", + ] + expected_env = None + + self.assertEqual( + self.settings_to_cmd_args_env( + { + "NAME": "settingdbname", + "USER": "settinguser", + "PASSWORD": "settingpassword", + "HOST": "settinghost", + "PORT": settings_port, + "OPTIONS": {"port": options_port}, + } + ), + (expected_args, expected_env), + ) + + def test_sigint_handler(self): + """SIGINT is ignored in Python and passed to Mongodb to abort queries.""" + + def _mock_subprocess_run(*args, **kwargs): # noqa: ARG001 + handler = signal.getsignal(signal.SIGINT) + self.assertEqual(handler, signal.SIG_IGN) + + sigint_handler = signal.getsignal(signal.SIGINT) + # The default handler isn't SIG_IGN. + self.assertNotEqual(sigint_handler, signal.SIG_IGN) + with mock.patch("subprocess.run", new=_mock_subprocess_run): + connection.client.runshell([]) + # dbshell restores the original handler. + self.assertEqual(sigint_handler, signal.getsignal(signal.SIGINT))