summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2017-02-09 23:55:07 +0100
committerTim Graham <timograham@gmail.com>2017-02-09 17:55:07 -0500
commit965f678a39b79f8e0bdc8222df094916fd7f8ed4 (patch)
tree39c05d634c827488ed4573009e168ffa2084721f
parente124d2da94cc1233729d8f0200809589f6c5afc8 (diff)
Fixed #25898 -- Made test database/user creation on Oracle reraise unexpected errors.
Thanks Shai Berger and Tim Graham for review.
-rw-r--r--django/db/backends/oracle/creation.py14
-rw-r--r--tests/backends/test_creation.py80
2 files changed, 85 insertions, 9 deletions
diff --git a/django/db/backends/oracle/creation.py b/django/db/backends/oracle/creation.py
index adbf92b6a3..e3aff97258 100644
--- a/django/db/backends/oracle/creation.py
+++ b/django/db/backends/oracle/creation.py
@@ -35,11 +35,10 @@ class DatabaseCreation(BaseDatabaseCreation):
try:
self._execute_test_db_creation(cursor, parameters, verbosity, keepdb)
except Exception as e:
- # if we want to keep the db, then no need to do any of the below,
- # just return and skip it all.
- if keepdb:
- return
- sys.stderr.write("Got an error creating the test database: %s\n" % e)
+ if 'ORA-01543' not in str(e):
+ # All errors except "tablespace already exists" cancel tests
+ sys.stderr.write("Got an error creating the test database: %s\n" % e)
+ sys.exit(2)
if not autoclobber:
confirm = input(
"It appears the test database, %s, already exists. "
@@ -75,7 +74,10 @@ class DatabaseCreation(BaseDatabaseCreation):
try:
self._create_test_user(cursor, parameters, verbosity, keepdb)
except Exception as e:
- sys.stderr.write("Got an error creating the test user: %s\n" % e)
+ if 'ORA-01920' not in str(e):
+ # All errors except "user already exists" cancel tests
+ sys.stderr.write("Got an error creating the test user: %s\n" % e)
+ sys.exit(2)
if not autoclobber:
confirm = input(
"It appears the test user, %s, already exists. Type "
diff --git a/tests/backends/test_creation.py b/tests/backends/test_creation.py
index d2a615a7e4..9c8c32e043 100644
--- a/tests/backends/test_creation.py
+++ b/tests/backends/test_creation.py
@@ -1,13 +1,19 @@
import copy
import unittest
from contextlib import contextmanager
+from io import StringIO
+from unittest import mock
from django.db import DEFAULT_DB_ALIAS, connection, connections
from django.db.backends.base.creation import (
TEST_DATABASE_PREFIX, BaseDatabaseCreation,
)
-from django.db.backends.postgresql.creation import DatabaseCreation
-from django.test import SimpleTestCase
+from django.db.backends.oracle.creation import \
+ DatabaseCreation as OracleDatabaseCreation
+from django.db.backends.postgresql.creation import \
+ DatabaseCreation as PostgreSQLDatabaseCreation
+from django.db.utils import DatabaseError
+from django.test import SimpleTestCase, TestCase
class TestDbSignatureTests(SimpleTestCase):
@@ -69,7 +75,7 @@ class PostgreSQLDatabaseCreationTests(SimpleTestCase):
def check_sql_table_creation_suffix(self, settings, expected):
with self.changed_test_settings(**settings):
- creation = DatabaseCreation(connection)
+ creation = PostgreSQLDatabaseCreation(connection)
suffix = creation.sql_table_creation_suffix()
self.assertEqual(suffix, expected)
@@ -88,3 +94,71 @@ class PostgreSQLDatabaseCreationTests(SimpleTestCase):
def test_sql_table_creation_suffix_with_encoding_and_template(self):
settings = dict(CHARSET='UTF8', TEMPLATE='template0')
self.check_sql_table_creation_suffix(settings, '''WITH ENCODING 'UTF8' TEMPLATE "template0"''')
+
+
+@unittest.skipUnless(connection.vendor == 'oracle', "Oracle specific tests")
+@mock.patch.object(OracleDatabaseCreation, '_maindb_connection', return_value=connection)
+@mock.patch('sys.stdout', new_callable=StringIO)
+@mock.patch('sys.stderr', new_callable=StringIO)
+class OracleDatabaseCreationTests(TestCase):
+
+ def _execute_raise_user_already_exists(self, cursor, statements, parameters, verbosity, allow_quiet_fail=False):
+ # Raise "user already exists" only in test user creation
+ if statements and statements[0].startswith('CREATE USER'):
+ raise DatabaseError("ORA-01920: user name 'string' conflicts with another user or role name")
+
+ def _execute_raise_tablespace_already_exists(
+ self, cursor, statements, parameters, verbosity, allow_quiet_fail=False
+ ):
+ raise DatabaseError("ORA-01543: tablespace 'string' already exists")
+
+ def _execute_raise_insufficient_privileges(
+ self, cursor, statements, parameters, verbosity, allow_quiet_fail=False
+ ):
+ raise DatabaseError("ORA-01031: insufficient privileges")
+
+ def _test_database_passwd(self):
+ # Mocked to avoid test user password changed
+ return connection.settings_dict['SAVED_PASSWORD']
+
+ def patch_execute_statements(self, execute_statements):
+ return mock.patch.object(OracleDatabaseCreation, '_execute_statements', execute_statements)
+
+ @mock.patch.object(OracleDatabaseCreation, '_test_user_create', return_value=False)
+ def test_create_test_db(self, *mocked_objects):
+ creation = OracleDatabaseCreation(connection)
+ # Simulate test database creation raising "tablespace already exists"
+ with self.patch_execute_statements(self._execute_raise_tablespace_already_exists):
+ with mock.patch('builtins.input', return_value='no'):
+ with self.assertRaises(SystemExit):
+ # SystemExit is raised if the user answers "no" to the
+ # prompt asking if it's okay to delete the test tablespace.
+ creation._create_test_db(verbosity=0, keepdb=False)
+ # "Tablespace already exists" error is ignored when keepdb is on
+ creation._create_test_db(verbosity=0, keepdb=True)
+ # Simulate test database creation raising unexpected error
+ with self.patch_execute_statements(self._execute_raise_insufficient_privileges):
+ with self.assertRaises(SystemExit):
+ creation._create_test_db(verbosity=0, keepdb=False)
+ with self.assertRaises(SystemExit):
+ creation._create_test_db(verbosity=0, keepdb=True)
+
+ @mock.patch.object(OracleDatabaseCreation, '_test_database_create', return_value=False)
+ def test_create_test_user(self, *mocked_objects):
+ creation = OracleDatabaseCreation(connection)
+ with mock.patch.object(OracleDatabaseCreation, '_test_database_passwd', self._test_database_passwd):
+ # Simulate test user creation raising "user already exists"
+ with self.patch_execute_statements(self._execute_raise_user_already_exists):
+ with mock.patch('builtins.input', return_value='no'):
+ with self.assertRaises(SystemExit):
+ # SystemExit is raised if the user answers "no" to the
+ # prompt asking if it's okay to delete the test user.
+ creation._create_test_db(verbosity=0, keepdb=False)
+ # "User already exists" error is ignored when keepdb is on
+ creation._create_test_db(verbosity=0, keepdb=True)
+ # Simulate test user creation raising unexpected error
+ with self.patch_execute_statements(self._execute_raise_insufficient_privileges):
+ with self.assertRaises(SystemExit):
+ creation._create_test_db(verbosity=0, keepdb=False)
+ with self.assertRaises(SystemExit):
+ creation._create_test_db(verbosity=0, keepdb=True)