1. """Tests for django.db.utils."""
    
  2. import unittest
    
  3. 
    
  4. from django.core.exceptions import ImproperlyConfigured
    
  5. from django.db import DEFAULT_DB_ALIAS, ProgrammingError, connection
    
  6. from django.db.utils import ConnectionHandler, load_backend
    
  7. from django.test import SimpleTestCase, TestCase
    
  8. from django.utils.connection import ConnectionDoesNotExist
    
  9. 
    
  10. 
    
  11. class ConnectionHandlerTests(SimpleTestCase):
    
  12.     def test_connection_handler_no_databases(self):
    
  13.         """
    
  14.         Empty DATABASES and empty 'default' settings default to the dummy
    
  15.         backend.
    
  16.         """
    
  17.         for DATABASES in (
    
  18.             {},  # Empty DATABASES setting.
    
  19.             {"default": {}},  # Empty 'default' database.
    
  20.         ):
    
  21.             with self.subTest(DATABASES=DATABASES):
    
  22.                 self.assertImproperlyConfigured(DATABASES)
    
  23. 
    
  24.     def assertImproperlyConfigured(self, DATABASES):
    
  25.         conns = ConnectionHandler(DATABASES)
    
  26.         self.assertEqual(
    
  27.             conns[DEFAULT_DB_ALIAS].settings_dict["ENGINE"], "django.db.backends.dummy"
    
  28.         )
    
  29.         msg = (
    
  30.             "settings.DATABASES is improperly configured. Please supply the "
    
  31.             "ENGINE value. Check settings documentation for more details."
    
  32.         )
    
  33.         with self.assertRaisesMessage(ImproperlyConfigured, msg):
    
  34.             conns[DEFAULT_DB_ALIAS].ensure_connection()
    
  35. 
    
  36.     def test_no_default_database(self):
    
  37.         DATABASES = {"other": {}}
    
  38.         conns = ConnectionHandler(DATABASES)
    
  39.         msg = "You must define a 'default' database."
    
  40.         with self.assertRaisesMessage(ImproperlyConfigured, msg):
    
  41.             conns["other"].ensure_connection()
    
  42. 
    
  43.     def test_databases_property(self):
    
  44.         # The "databases" property is maintained for backwards compatibility
    
  45.         # with 3rd party packages. It should be an alias of the "settings"
    
  46.         # property.
    
  47.         conn = ConnectionHandler({})
    
  48.         self.assertNotEqual(conn.settings, {})
    
  49.         self.assertEqual(conn.settings, conn.databases)
    
  50. 
    
  51.     def test_nonexistent_alias(self):
    
  52.         msg = "The connection 'nonexistent' doesn't exist."
    
  53.         conns = ConnectionHandler(
    
  54.             {
    
  55.                 DEFAULT_DB_ALIAS: {"ENGINE": "django.db.backends.dummy"},
    
  56.             }
    
  57.         )
    
  58.         with self.assertRaisesMessage(ConnectionDoesNotExist, msg):
    
  59.             conns["nonexistent"]
    
  60. 
    
  61. 
    
  62. class DatabaseErrorWrapperTests(TestCase):
    
  63.     @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL test")
    
  64.     def test_reraising_backend_specific_database_exception(self):
    
  65.         with connection.cursor() as cursor:
    
  66.             msg = 'table "X" does not exist'
    
  67.             with self.assertRaisesMessage(ProgrammingError, msg) as cm:
    
  68.                 cursor.execute('DROP TABLE "X"')
    
  69.         self.assertNotEqual(type(cm.exception), type(cm.exception.__cause__))
    
  70.         self.assertIsNotNone(cm.exception.__cause__)
    
  71.         self.assertIsNotNone(cm.exception.__cause__.pgcode)
    
  72.         self.assertIsNotNone(cm.exception.__cause__.pgerror)
    
  73. 
    
  74. 
    
  75. class LoadBackendTests(SimpleTestCase):
    
  76.     def test_load_backend_invalid_name(self):
    
  77.         msg = (
    
  78.             "'foo' isn't an available database backend or couldn't be "
    
  79.             "imported. Check the above exception. To use one of the built-in "
    
  80.             "backends, use 'django.db.backends.XXX', where XXX is one of:\n"
    
  81.             "    'mysql', 'oracle', 'postgresql', 'sqlite3'"
    
  82.         )
    
  83.         with self.assertRaisesMessage(ImproperlyConfigured, msg) as cm:
    
  84.             load_backend("foo")
    
  85.         self.assertEqual(str(cm.exception.__cause__), "No module named 'foo'")