From 6a0b4faf43db70a35163dde0a5ea626ed4129fa7 Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Fri, 25 Sep 2015 22:35:36 +0200 Subject: [PATCH] [1.9.x] Fixed #25421 -- Fixed test --keepdb option on Oracle. Backport of a3a6def867c61d24dfded6cbfef7f820409dc739 from master --- django/db/backends/oracle/creation.py | 52 ++++++++++++++++++--------- docs/releases/1.8.5.txt | 2 ++ 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/django/db/backends/oracle/creation.py b/django/db/backends/oracle/creation.py index 7f921085244..01b4056b4b7 100644 --- a/django/db/backends/oracle/creation.py +++ b/django/db/backends/oracle/creation.py @@ -35,7 +35,7 @@ class DatabaseCreation(BaseDatabaseCreation): cursor = self._maindb_connection.cursor() if self._test_database_create(): try: - self._execute_test_db_creation(cursor, parameters, verbosity) + 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. @@ -63,7 +63,7 @@ class DatabaseCreation(BaseDatabaseCreation): sys.stderr.write("Got an error destroying the old test database: %s\n" % e) sys.exit(2) try: - self._execute_test_db_creation(cursor, parameters, verbosity) + self._execute_test_db_creation(cursor, parameters, verbosity, keepdb) except Exception as e: sys.stderr.write("Got an error recreating the test database: %s\n" % e) sys.exit(2) @@ -75,8 +75,11 @@ class DatabaseCreation(BaseDatabaseCreation): if verbosity >= 1: print("Creating test user...") try: - self._create_test_user(cursor, parameters, verbosity) + self._create_test_user(cursor, parameters, verbosity, keepdb) except Exception as e: + # If we want to keep the db, then we want to also keep the user. + if keepdb: + return sys.stderr.write("Got an error creating the test user: %s\n" % e) if not autoclobber: confirm = input( @@ -89,7 +92,7 @@ class DatabaseCreation(BaseDatabaseCreation): self._destroy_test_user(cursor, parameters, verbosity) if verbosity >= 1: print("Creating test user...") - self._create_test_user(cursor, parameters, verbosity) + self._create_test_user(cursor, parameters, verbosity, keepdb) except Exception as e: sys.stderr.write("Got an error recreating the test user: %s\n" % e) sys.exit(2) @@ -184,7 +187,7 @@ class DatabaseCreation(BaseDatabaseCreation): self._execute_test_db_destruction(cursor, parameters, verbosity) self._maindb_connection.close() - def _execute_test_db_creation(self, cursor, parameters, verbosity): + def _execute_test_db_creation(self, cursor, parameters, verbosity, keepdb=False): if verbosity >= 2: print("_create_test_db(): dbname = %s" % parameters['user']) statements = [ @@ -197,9 +200,11 @@ class DatabaseCreation(BaseDatabaseCreation): REUSE AUTOEXTEND ON NEXT 10M MAXSIZE %(maxsize_tmp)s """, ] - self._execute_statements(cursor, statements, parameters, verbosity) + # Ignore "tablespace already exists" error when keepdb is on. + acceptable_ora_err = 'ORA-01543' if keepdb else None + self._execute_allow_fail_statements(cursor, statements, parameters, verbosity, acceptable_ora_err) - def _create_test_user(self, cursor, parameters, verbosity): + def _create_test_user(self, cursor, parameters, verbosity, keepdb=False): if verbosity >= 2: print("_create_test_user(): username = %s" % parameters['user']) statements = [ @@ -216,18 +221,14 @@ class DatabaseCreation(BaseDatabaseCreation): CREATE TRIGGER TO %(user)s""", ] - self._execute_statements(cursor, statements, parameters, verbosity) + # Ignore "user already exists" error when keepdb is on + acceptable_ora_err = 'ORA-01920' if keepdb else None + self._execute_allow_fail_statements(cursor, statements, parameters, verbosity, acceptable_ora_err) # Most test-suites can be run without the create-view privilege. But some need it. extra = "GRANT CREATE VIEW TO %(user)s" - try: - self._execute_statements(cursor, [extra], parameters, verbosity, allow_quiet_fail=True) - except DatabaseError as err: - description = str(err) - if 'ORA-01031' in description: - if verbosity >= 2: - print("Failed to grant CREATE VIEW permission to test user. This may be ok.") - else: - raise + success = self._execute_allow_fail_statements(cursor, [extra], parameters, verbosity, 'ORA-01031') + if not success and verbosity >= 2: + print("Failed to grant CREATE VIEW permission to test user. This may be ok.") def _execute_test_db_destruction(self, cursor, parameters, verbosity): if verbosity >= 2: @@ -259,6 +260,23 @@ class DatabaseCreation(BaseDatabaseCreation): sys.stderr.write("Failed (%s)\n" % (err)) raise + def _execute_allow_fail_statements(self, cursor, statements, parameters, verbosity, acceptable_ora_err): + """ + Execute statements which are allowed to fail silently if the Oracle + error code given by `acceptable_ora_err` is raised. Return True if the + statements execute without an exception, or False otherwise. + """ + try: + # Statement can fail when acceptable_ora_err is not None + allow_quiet_fail = acceptable_ora_err is not None and len(acceptable_ora_err) > 0 + self._execute_statements(cursor, statements, parameters, verbosity, allow_quiet_fail=allow_quiet_fail) + return True + except DatabaseError as err: + description = str(err) + if acceptable_ora_err is None or acceptable_ora_err not in description: + raise + return False + def _get_test_db_params(self): return { 'dbname': self._test_database_name(), diff --git a/docs/releases/1.8.5.txt b/docs/releases/1.8.5.txt index d412c4b653a..14893f4a720 100644 --- a/docs/releases/1.8.5.txt +++ b/docs/releases/1.8.5.txt @@ -50,3 +50,5 @@ Bugfixes * Allowed using ORM write methods after disabling autocommit with :func:`set_autocommit(False) ` (:ticket:`24921`). + +* Fixed the ``manage.py test --keepdb`` option on Oracle (:ticket:`25421`).