Commit cb2de5e2 authored by Mariusz Felisiak's avatar Mariusz Felisiak Committed by Tim Graham
Browse files

[1.8.x] Fixed #25421 -- Fixed test --keepdb option on Oracle.

Backport of a3a6def8 from master
parent 4dcd4ef1
Loading
Loading
Loading
Loading
+35 −17
Original line number Diff line number Diff line
@@ -17,7 +17,7 @@ class DatabaseCreation(BaseDatabaseCreation):
        cursor = self.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.
@@ -45,7 +45,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)
@@ -57,8 +57,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(
@@ -71,7 +74,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)
@@ -149,7 +152,7 @@ class DatabaseCreation(BaseDatabaseCreation):
            self._execute_test_db_destruction(cursor, parameters, verbosity)
        self.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 = [
@@ -162,9 +165,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 = [
@@ -181,18 +186,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:
        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.")
            else:
                raise

    def _execute_test_db_destruction(self, cursor, parameters, verbosity):
        if verbosity >= 2:
@@ -224,6 +225,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(),
+2 −0
Original line number Diff line number Diff line
@@ -50,3 +50,5 @@ Bugfixes
* Allowed using ORM write methods after disabling autocommit with
  :func:`set_autocommit(False) <django.db.transaction.set_autocommit>`
  (:ticket:`24921`).

* Fixed the ``manage.py test --keepdb`` option on Oracle (:ticket:`25421`).