mirror of https://github.com/django/django.git
Fixed #29040 -- Made test database creation messages use a consistent output stream.
This commit is contained in:
parent
1e9b02a4c2
commit
65503ca097
|
@ -1,3 +1,4 @@
|
|||
import os
|
||||
import sys
|
||||
from io import StringIO
|
||||
|
||||
|
@ -26,6 +27,9 @@ class BaseDatabaseCreation:
|
|||
"""
|
||||
return self.connection._nodb_connection
|
||||
|
||||
def log(self, msg):
|
||||
sys.stderr.write(msg + os.linesep)
|
||||
|
||||
def create_test_db(self, verbosity=1, autoclobber=False, serialize=True, keepdb=False):
|
||||
"""
|
||||
Create a test database, prompting the user for confirmation if the
|
||||
|
@ -41,7 +45,7 @@ class BaseDatabaseCreation:
|
|||
if keepdb:
|
||||
action = "Using existing"
|
||||
|
||||
print("%s test database for alias %s..." % (
|
||||
self.log('%s test database for alias %s...' % (
|
||||
action,
|
||||
self._get_database_display_str(verbosity, test_database_name),
|
||||
))
|
||||
|
@ -170,8 +174,7 @@ class BaseDatabaseCreation:
|
|||
if keepdb:
|
||||
return test_database_name
|
||||
|
||||
sys.stderr.write(
|
||||
"Got an error creating the test database: %s\n" % e)
|
||||
self.log('Got an error creating the test database: %s' % e)
|
||||
if not autoclobber:
|
||||
confirm = input(
|
||||
"Type 'yes' if you would like to try deleting the test "
|
||||
|
@ -179,17 +182,16 @@ class BaseDatabaseCreation:
|
|||
if autoclobber or confirm == 'yes':
|
||||
try:
|
||||
if verbosity >= 1:
|
||||
print("Destroying old test database for alias %s..." % (
|
||||
self.log('Destroying old test database for alias %s...' % (
|
||||
self._get_database_display_str(verbosity, test_database_name),
|
||||
))
|
||||
cursor.execute('DROP DATABASE %(dbname)s' % test_db_params)
|
||||
self._execute_create_test_db(cursor, test_db_params, keepdb)
|
||||
except Exception as e:
|
||||
sys.stderr.write(
|
||||
"Got an error recreating the test database: %s\n" % e)
|
||||
self.log('Got an error recreating the test database: %s' % e)
|
||||
sys.exit(2)
|
||||
else:
|
||||
print("Tests cancelled.")
|
||||
self.log('Tests cancelled.')
|
||||
sys.exit(1)
|
||||
|
||||
return test_database_name
|
||||
|
@ -204,7 +206,7 @@ class BaseDatabaseCreation:
|
|||
action = 'Cloning test database'
|
||||
if keepdb:
|
||||
action = 'Using existing clone'
|
||||
print("%s for alias %s..." % (
|
||||
self.log('%s for alias %s...' % (
|
||||
action,
|
||||
self._get_database_display_str(verbosity, source_database_name),
|
||||
))
|
||||
|
@ -246,7 +248,7 @@ class BaseDatabaseCreation:
|
|||
action = 'Destroying'
|
||||
if keepdb:
|
||||
action = 'Preserving'
|
||||
print("%s test database for alias %s..." % (
|
||||
self.log('%s test database for alias %s...' % (
|
||||
action,
|
||||
self._get_database_display_str(verbosity, test_database_name),
|
||||
))
|
||||
|
|
|
@ -33,7 +33,7 @@ class DatabaseCreation(BaseDatabaseCreation):
|
|||
except Exception as e:
|
||||
if len(e.args) < 1 or e.args[0] != 1007:
|
||||
# All errors except "database exists" (1007) cancel tests.
|
||||
sys.stderr.write('Got an error creating the test database: %s\n' % e)
|
||||
self.log('Got an error creating the test database: %s' % e)
|
||||
sys.exit(2)
|
||||
else:
|
||||
raise e
|
||||
|
@ -51,13 +51,13 @@ class DatabaseCreation(BaseDatabaseCreation):
|
|||
except Exception:
|
||||
try:
|
||||
if verbosity >= 1:
|
||||
print("Destroying old test database for alias %s..." % (
|
||||
self.log('Destroying old test database for alias %s...' % (
|
||||
self._get_database_display_str(verbosity, target_database_name),
|
||||
))
|
||||
cursor.execute('DROP DATABASE %(dbname)s' % test_db_params)
|
||||
self._execute_create_test_db(cursor, test_db_params, keepdb)
|
||||
except Exception as e:
|
||||
sys.stderr.write("Got an error recreating the test database: %s\n" % e)
|
||||
self.log('Got an error recreating the test database: %s' % e)
|
||||
sys.exit(2)
|
||||
|
||||
dump_cmd = DatabaseClient.settings_to_cmd_args(self.connection.settings_dict)
|
||||
|
|
|
@ -36,7 +36,7 @@ class DatabaseCreation(BaseDatabaseCreation):
|
|||
except Exception as 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)
|
||||
self.log('Got an error creating the test database: %s' % e)
|
||||
sys.exit(2)
|
||||
if not autoclobber:
|
||||
confirm = input(
|
||||
|
@ -44,7 +44,7 @@ class DatabaseCreation(BaseDatabaseCreation):
|
|||
"Type 'yes' to delete it, or 'no' to cancel: " % parameters['user'])
|
||||
if autoclobber or confirm == 'yes':
|
||||
if verbosity >= 1:
|
||||
print("Destroying old test database for alias '%s'..." % self.connection.alias)
|
||||
self.log("Destroying old test database for alias '%s'..." % self.connection.alias)
|
||||
try:
|
||||
self._execute_test_db_destruction(cursor, parameters, verbosity)
|
||||
except DatabaseError as e:
|
||||
|
@ -53,29 +53,29 @@ class DatabaseCreation(BaseDatabaseCreation):
|
|||
verbosity, autoclobber)
|
||||
else:
|
||||
# Ran into a database error that isn't about leftover objects in the tablespace
|
||||
sys.stderr.write("Got an error destroying the old test database: %s\n" % e)
|
||||
self.log('Got an error destroying the old test database: %s' % e)
|
||||
sys.exit(2)
|
||||
except Exception as e:
|
||||
sys.stderr.write("Got an error destroying the old test database: %s\n" % e)
|
||||
self.log('Got an error destroying the old test database: %s' % e)
|
||||
sys.exit(2)
|
||||
try:
|
||||
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)
|
||||
self.log('Got an error recreating the test database: %s' % e)
|
||||
sys.exit(2)
|
||||
else:
|
||||
print("Tests cancelled.")
|
||||
self.log('Tests cancelled.')
|
||||
sys.exit(1)
|
||||
|
||||
if self._test_user_create():
|
||||
if verbosity >= 1:
|
||||
print("Creating test user...")
|
||||
self.log('Creating test user...')
|
||||
try:
|
||||
self._create_test_user(cursor, parameters, verbosity, keepdb)
|
||||
except Exception as 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)
|
||||
self.log('Got an error creating the test user: %s' % e)
|
||||
sys.exit(2)
|
||||
if not autoclobber:
|
||||
confirm = input(
|
||||
|
@ -84,16 +84,16 @@ class DatabaseCreation(BaseDatabaseCreation):
|
|||
if autoclobber or confirm == 'yes':
|
||||
try:
|
||||
if verbosity >= 1:
|
||||
print("Destroying old test user...")
|
||||
self.log('Destroying old test user...')
|
||||
self._destroy_test_user(cursor, parameters, verbosity)
|
||||
if verbosity >= 1:
|
||||
print("Creating test user...")
|
||||
self.log('Creating test user...')
|
||||
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)
|
||||
self.log('Got an error recreating the test user: %s' % e)
|
||||
sys.exit(2)
|
||||
else:
|
||||
print("Tests cancelled.")
|
||||
self.log('Tests cancelled.')
|
||||
sys.exit(1)
|
||||
self._maindb_connection.close() # done with main user -- test user and tablespaces created
|
||||
self._switch_to_test_user(parameters)
|
||||
|
@ -130,36 +130,38 @@ class DatabaseCreation(BaseDatabaseCreation):
|
|||
def _handle_objects_preventing_db_destruction(self, cursor, parameters, verbosity, autoclobber):
|
||||
# There are objects in the test tablespace which prevent dropping it
|
||||
# The easy fix is to drop the test user -- but are we allowed to do so?
|
||||
print("There are objects in the old test database which prevent its destruction.")
|
||||
print("If they belong to the test user, deleting the user will allow the test "
|
||||
"database to be recreated.")
|
||||
print("Otherwise, you will need to find and remove each of these objects, "
|
||||
"or use a different tablespace.\n")
|
||||
self.log(
|
||||
'There are objects in the old test database which prevent its destruction.\n'
|
||||
'If they belong to the test user, deleting the user will allow the test '
|
||||
'database to be recreated.\n'
|
||||
'Otherwise, you will need to find and remove each of these objects, '
|
||||
'or use a different tablespace.\n'
|
||||
)
|
||||
if self._test_user_create():
|
||||
if not autoclobber:
|
||||
confirm = input("Type 'yes' to delete user %s: " % parameters['user'])
|
||||
if autoclobber or confirm == 'yes':
|
||||
try:
|
||||
if verbosity >= 1:
|
||||
print("Destroying old test user...")
|
||||
self.log('Destroying old test user...')
|
||||
self._destroy_test_user(cursor, parameters, verbosity)
|
||||
except Exception as e:
|
||||
sys.stderr.write("Got an error destroying the test user: %s\n" % e)
|
||||
self.log('Got an error destroying the test user: %s' % e)
|
||||
sys.exit(2)
|
||||
try:
|
||||
if verbosity >= 1:
|
||||
print("Destroying old test database for alias '%s'..." % self.connection.alias)
|
||||
self.log("Destroying old test database for alias '%s'..." % self.connection.alias)
|
||||
self._execute_test_db_destruction(cursor, parameters, verbosity)
|
||||
except Exception as e:
|
||||
sys.stderr.write("Got an error destroying the test database: %s\n" % e)
|
||||
self.log('Got an error destroying the test database: %s' % e)
|
||||
sys.exit(2)
|
||||
else:
|
||||
print("Tests cancelled -- test database cannot be recreated.")
|
||||
self.log('Tests cancelled -- test database cannot be recreated.')
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("Django is configured to use pre-existing test user '%s',"
|
||||
" and will not attempt to delete it.\n" % parameters['user'])
|
||||
print("Tests cancelled -- test database cannot be recreated.")
|
||||
self.log("Django is configured to use pre-existing test user '%s',"
|
||||
" and will not attempt to delete it." % parameters['user'])
|
||||
self.log('Tests cancelled -- test database cannot be recreated.')
|
||||
sys.exit(1)
|
||||
|
||||
def _destroy_test_db(self, test_database_name, verbosity=1):
|
||||
|
@ -174,17 +176,17 @@ class DatabaseCreation(BaseDatabaseCreation):
|
|||
with self._maindb_connection.cursor() as cursor:
|
||||
if self._test_user_create():
|
||||
if verbosity >= 1:
|
||||
print('Destroying test user...')
|
||||
self.log('Destroying test user...')
|
||||
self._destroy_test_user(cursor, parameters, verbosity)
|
||||
if self._test_database_create():
|
||||
if verbosity >= 1:
|
||||
print('Destroying test database tables...')
|
||||
self.log('Destroying test database tables...')
|
||||
self._execute_test_db_destruction(cursor, parameters, verbosity)
|
||||
self._maindb_connection.close()
|
||||
|
||||
def _execute_test_db_creation(self, cursor, parameters, verbosity, keepdb=False):
|
||||
if verbosity >= 2:
|
||||
print("_create_test_db(): dbname = %s" % parameters['user'])
|
||||
self.log('_create_test_db(): dbname = %s' % parameters['user'])
|
||||
statements = [
|
||||
"""CREATE TABLESPACE %(tblspace)s
|
||||
DATAFILE '%(datafile)s' SIZE %(size)s
|
||||
|
@ -201,7 +203,7 @@ class DatabaseCreation(BaseDatabaseCreation):
|
|||
|
||||
def _create_test_user(self, cursor, parameters, verbosity, keepdb=False):
|
||||
if verbosity >= 2:
|
||||
print("_create_test_user(): username = %s" % parameters['user'])
|
||||
self.log('_create_test_user(): username = %s' % parameters['user'])
|
||||
statements = [
|
||||
"""CREATE USER %(user)s
|
||||
IDENTIFIED BY "%(password)s"
|
||||
|
@ -227,11 +229,11 @@ class DatabaseCreation(BaseDatabaseCreation):
|
|||
extra = "GRANT CREATE VIEW TO %(user)s"
|
||||
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.")
|
||||
self.log('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:
|
||||
print("_execute_test_db_destruction(): dbname=%s" % parameters['user'])
|
||||
self.log('_execute_test_db_destruction(): dbname=%s' % parameters['user'])
|
||||
statements = [
|
||||
'DROP TABLESPACE %(tblspace)s INCLUDING CONTENTS AND DATAFILES CASCADE CONSTRAINTS',
|
||||
'DROP TABLESPACE %(tblspace_temp)s INCLUDING CONTENTS AND DATAFILES CASCADE CONSTRAINTS',
|
||||
|
@ -240,8 +242,8 @@ class DatabaseCreation(BaseDatabaseCreation):
|
|||
|
||||
def _destroy_test_user(self, cursor, parameters, verbosity):
|
||||
if verbosity >= 2:
|
||||
print("_destroy_test_user(): user=%s" % parameters['user'])
|
||||
print("Be patient. This can take some time...")
|
||||
self.log('_destroy_test_user(): user=%s' % parameters['user'])
|
||||
self.log('Be patient. This can take some time...')
|
||||
statements = [
|
||||
'DROP USER %(user)s CASCADE',
|
||||
]
|
||||
|
@ -256,7 +258,7 @@ class DatabaseCreation(BaseDatabaseCreation):
|
|||
cursor.execute(stmt)
|
||||
except Exception as err:
|
||||
if (not allow_quiet_fail) or verbosity >= 2:
|
||||
sys.stderr.write("Failed (%s)\n" % (err))
|
||||
self.log('Failed (%s)' % (err))
|
||||
raise
|
||||
|
||||
def _execute_allow_fail_statements(self, cursor, statements, parameters, verbosity, acceptable_ora_err):
|
||||
|
|
|
@ -34,7 +34,7 @@ class DatabaseCreation(BaseDatabaseCreation):
|
|||
except Exception as e:
|
||||
if getattr(e.__cause__, 'pgcode', '') != errorcodes.DUPLICATE_DATABASE:
|
||||
# All errors except "database already exists" cancel tests.
|
||||
sys.stderr.write('Got an error creating the test database: %s\n' % e)
|
||||
self.log('Got an error creating the test database: %s' % e)
|
||||
sys.exit(2)
|
||||
elif not keepdb:
|
||||
# If the database should be kept, ignore "database already
|
||||
|
@ -58,11 +58,11 @@ class DatabaseCreation(BaseDatabaseCreation):
|
|||
except Exception as e:
|
||||
try:
|
||||
if verbosity >= 1:
|
||||
print("Destroying old test database for alias %s..." % (
|
||||
self.log('Destroying old test database for alias %s...' % (
|
||||
self._get_database_display_str(verbosity, target_database_name),
|
||||
))
|
||||
cursor.execute('DROP DATABASE %(dbname)s' % test_db_params)
|
||||
self._execute_create_test_db(cursor, test_db_params, keepdb)
|
||||
except Exception as e:
|
||||
sys.stderr.write("Got an error cloning the test database: %s\n" % e)
|
||||
self.log('Got an error cloning the test database: %s' % e)
|
||||
sys.exit(2)
|
||||
|
|
|
@ -25,7 +25,7 @@ class DatabaseCreation(BaseDatabaseCreation):
|
|||
if not self.is_in_memory_db(test_database_name):
|
||||
# Erase the old test database
|
||||
if verbosity >= 1:
|
||||
print("Destroying old test database for alias %s..." % (
|
||||
self.log('Destroying old test database for alias %s...' % (
|
||||
self._get_database_display_str(verbosity, test_database_name),
|
||||
))
|
||||
if os.access(test_database_name, os.F_OK):
|
||||
|
@ -38,10 +38,10 @@ class DatabaseCreation(BaseDatabaseCreation):
|
|||
try:
|
||||
os.remove(test_database_name)
|
||||
except Exception as e:
|
||||
sys.stderr.write("Got an error deleting the old test database: %s\n" % e)
|
||||
self.log('Got an error deleting the old test database: %s' % e)
|
||||
sys.exit(2)
|
||||
else:
|
||||
print("Tests cancelled.")
|
||||
self.log('Tests cancelled.')
|
||||
sys.exit(1)
|
||||
return test_database_name
|
||||
|
||||
|
@ -64,18 +64,18 @@ class DatabaseCreation(BaseDatabaseCreation):
|
|||
if keepdb:
|
||||
return
|
||||
if verbosity >= 1:
|
||||
print("Destroying old test database for alias %s..." % (
|
||||
self.log('Destroying old test database for alias %s...' % (
|
||||
self._get_database_display_str(verbosity, target_database_name),
|
||||
))
|
||||
try:
|
||||
os.remove(target_database_name)
|
||||
except Exception as e:
|
||||
sys.stderr.write("Got an error deleting the old test database: %s\n" % e)
|
||||
self.log('Got an error deleting the old test database: %s' % e)
|
||||
sys.exit(2)
|
||||
try:
|
||||
shutil.copy(source_database_name, target_database_name)
|
||||
except Exception as e:
|
||||
sys.stderr.write("Got an error cloning the test database: %s\n" % e)
|
||||
self.log('Got an error cloning the test database: %s' % e)
|
||||
sys.exit(2)
|
||||
|
||||
def _destroy_test_db(self, test_database_name, verbosity):
|
||||
|
|
Loading…
Reference in New Issue