Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
D
drupal
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Custom Issue Tracker
Custom Issue Tracker
Labels
Merge Requests
221
Merge Requests
221
Requirements
Requirements
List
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Analytics
Analytics
Code Review
Insights
Issue
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
project
drupal
Commits
5b0715d7
Commit
5b0715d7
authored
May 31, 2012
by
catch
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue
#1563620
by sun, Berdir: Fixed All unit tests blow up with a fatal error.
parent
cc8147dd
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
208 additions
and
197 deletions
+208
-197
core/includes/module.inc
core/includes/module.inc
+6
-3
core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
+175
-0
core/modules/simpletest/lib/Drupal/simpletest/UnitTestBase.php
...modules/simpletest/lib/Drupal/simpletest/UnitTestBase.php
+26
-41
core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
.../modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
+1
-153
No files found.
core/includes/module.inc
View file @
5b0715d7
...
...
@@ -79,16 +79,19 @@ function module_list($refresh = FALSE, $bootstrap_refresh = FALSE, $sort = FALSE
// Use the advanced drupal_static() pattern, since this is called very often.
static
$drupal_static_fast
;
if
(
!
isset
(
$drupal_static_fast
))
{
$drupal_static_fast
[
'list'
]
=
&
drupal_static
(
__FUNCTION__
.
':list'
,
array
()
);
$drupal_static_fast
[
'list'
]
=
&
drupal_static
(
__FUNCTION__
.
':list'
);
$drupal_static_fast
[
'sorted_list'
]
=
&
drupal_static
(
__FUNCTION__
.
':sorted_list'
);
}
$list
=
&
$drupal_static_fast
[
'list'
];
$sorted_list
=
&
$drupal_static_fast
[
'sorted_list'
];
if
(
empty
(
$list
)
||
$refresh
||
$fixed_list
)
{
if
(
!
isset
(
$list
)
||
$refresh
||
isset
(
$fixed_list
)
)
{
$list
=
array
();
$sorted_list
=
NULL
;
if
(
$fixed_list
)
{
// The fixed list may be a completely empty array, thus check for isset().
// Calling code may use this to empty out the module list entirely. For
// example, unit tests need to ensure that no modules are invoked.
if
(
isset
(
$fixed_list
))
{
foreach
(
$fixed_list
as
$name
=>
$module
)
{
drupal_get_filename
(
'module'
,
$name
,
$module
[
'filename'
]);
$list
[
$name
]
=
$name
;
...
...
core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
View file @
5b0715d7
...
...
@@ -539,6 +539,181 @@ public function run(array $methods = array()) {
restore_error_handler
();
}
/**
* Generates a database prefix for running tests.
*
* The database prefix is used by prepareEnvironment() to setup a public files
* directory for the test to be run, which also contains the PHP error log,
* which is written to in case of a fatal error. Since that directory is based
* on the database prefix, all tests (even unit tests) need to have one, in
* order to access and read the error log.
*
* @see TestBase::prepareEnvironment()
*
* The generated database table prefix is used for the Drupal installation
* being performed for the test. It is also used as user agent HTTP header
* value by the cURL-based browser of DrupalWebTestCase, which is sent to the
* Drupal installation of the test. During early Drupal bootstrap, the user
* agent HTTP header is parsed, and if it matches, all database queries use
* the database table prefix that has been generated here.
*
* @see WebTestBase::curlInitialize()
* @see drupal_valid_test_ua()
* @see WebTestBase::setUp()
*/
protected
function
prepareDatabasePrefix
()
{
$this
->
databasePrefix
=
'simpletest'
.
mt_rand
(
1000
,
1000000
);
// As soon as the database prefix is set, the test might start to execute.
// All assertions as well as the SimpleTest batch operations are associated
// with the testId, so the database prefix has to be associated with it.
db_update
(
'simpletest_test_id'
)
->
fields
(
array
(
'last_prefix'
=>
$this
->
databasePrefix
))
->
condition
(
'test_id'
,
$this
->
testId
)
->
execute
();
}
/**
* Changes the database connection to the prefixed one.
*
* @see WebTestBase::setUp()
*/
protected
function
changeDatabasePrefix
()
{
if
(
empty
(
$this
->
databasePrefix
))
{
$this
->
prepareDatabasePrefix
();
}
// Clone the current connection and replace the current prefix.
$connection_info
=
Database
::
getConnectionInfo
(
'default'
);
Database
::
renameConnection
(
'default'
,
'simpletest_original_default'
);
foreach
(
$connection_info
as
$target
=>
$value
)
{
$connection_info
[
$target
][
'prefix'
]
=
array
(
'default'
=>
$value
[
'prefix'
][
'default'
]
.
$this
->
databasePrefix
,
);
}
Database
::
addConnectionInfo
(
'default'
,
'default'
,
$connection_info
[
'default'
]);
}
/**
* Prepares the current environment for running the test.
*
* Backups various current environment variables and resets them, so they do
* not interfere with the Drupal site installation in which tests are executed
* and can be restored in TestBase::tearDown().
*
* Also sets up new resources for the testing environment, such as the public
* filesystem and configuration directories.
*
* @see TestBase::tearDown()
*/
protected
function
prepareEnvironment
()
{
global
$user
,
$language_interface
,
$conf
;
// Backup current in-memory configuration.
$this
->
originalConf
=
$conf
;
// Backup statics and globals.
$this
->
originalContainer
=
clone
drupal_container
();
$this
->
originalLanguage
=
$language_interface
;
$this
->
originalConfigDirectory
=
$GLOBALS
[
'config_directory_name'
];
// Save further contextual information.
$this
->
originalFileDirectory
=
variable_get
(
'file_public_path'
,
conf_path
()
.
'/files'
);
$this
->
originalProfile
=
drupal_get_profile
();
$this
->
originalUser
=
$user
;
// Save and clean the shutdown callbacks array because it is static cached
// and will be changed by the test run. Otherwise it will contain callbacks
// from both environments and the testing environment will try to call the
// handlers defined by the original one.
$callbacks
=
&
drupal_register_shutdown_function
();
$this
->
originalShutdownCallbacks
=
$callbacks
;
$callbacks
=
array
();
// Create test directory ahead of installation so fatal errors and debug
// information can be logged during installation process.
// Use temporary files directory with the same prefix as the database.
$this
->
public_files_directory
=
$this
->
originalFileDirectory
.
'/simpletest/'
.
substr
(
$this
->
databasePrefix
,
10
);
$this
->
private_files_directory
=
$this
->
public_files_directory
.
'/private'
;
$this
->
temp_files_directory
=
$this
->
private_files_directory
.
'/temp'
;
// Create the directories
file_prepare_directory
(
$this
->
public_files_directory
,
FILE_CREATE_DIRECTORY
|
FILE_MODIFY_PERMISSIONS
);
file_prepare_directory
(
$this
->
private_files_directory
,
FILE_CREATE_DIRECTORY
);
file_prepare_directory
(
$this
->
temp_files_directory
,
FILE_CREATE_DIRECTORY
);
$this
->
generatedTestFiles
=
FALSE
;
// Create and set a new configuration directory and signature key.
// The child site automatically adjusts the global $config_directory_name to
// a test-prefix-specific directory within the public files directory.
// @see config_get_config_directory()
$GLOBALS
[
'config_directory_name'
]
=
'simpletest/'
.
substr
(
$this
->
databasePrefix
,
10
)
.
'/config'
;
$this
->
configFileDirectory
=
$this
->
originalFileDirectory
.
'/'
.
$GLOBALS
[
'config_directory_name'
];
file_prepare_directory
(
$this
->
configFileDirectory
,
FILE_CREATE_DIRECTORY
|
FILE_MODIFY_PERMISSIONS
);
// Log fatal errors.
ini_set
(
'log_errors'
,
1
);
ini_set
(
'error_log'
,
$this
->
public_files_directory
.
'/error.log'
);
// Set the test information for use in other parts of Drupal.
$test_info
=
&
$GLOBALS
[
'drupal_test_info'
];
$test_info
[
'test_run_id'
]
=
$this
->
databasePrefix
;
$test_info
[
'in_child_site'
]
=
FALSE
;
}
/**
* Deletes created files, database tables, and reverts all environment changes.
*
* This method needs to be invoked for both unit and integration tests.
*
* @see TestBase::prepareDatabasePrefix()
* @see TestBase::changeDatabasePrefix()
* @see TestBase::prepareEnvironment()
*/
protected
function
tearDown
()
{
global
$user
,
$language_interface
,
$conf
;
// In case a fatal error occurred that was not in the test process read the
// log to pick up any fatal errors.
simpletest_log_read
(
$this
->
testId
,
$this
->
databasePrefix
,
get_class
(
$this
),
TRUE
);
$emailCount
=
count
(
variable_get
(
'drupal_test_email_collector'
,
array
()));
if
(
$emailCount
)
{
$message
=
format_plural
(
$emailCount
,
'1 e-mail was sent during this test.'
,
'@count e-mails were sent during this test.'
);
$this
->
pass
(
$message
,
t
(
'E-mail'
));
}
// Delete temporary files directory.
file_unmanaged_delete_recursive
(
$this
->
originalFileDirectory
.
'/simpletest/'
.
substr
(
$this
->
databasePrefix
,
10
));
// Restore original database connection.
Database
::
removeConnection
(
'default'
);
Database
::
renameConnection
(
'simpletest_original_default'
,
'default'
);
// Reset all static variables.
drupal_static_reset
();
// Restore has_run state.
$has_run
=
&
drupal_static
(
'module_load_all'
);
$has_run
=
TRUE
;
// Restore original in-memory configuration.
$conf
=
$this
->
originalConf
;
// Restore original statics and globals.
drupal_container
(
$this
->
originalContainer
);
$language_interface
=
$this
->
originalLanguage
;
$GLOBALS
[
'config_directory_name'
]
=
$this
->
originalConfigDirectory
;
// Restore original shutdown callbacks.
$callbacks
=
&
drupal_register_shutdown_function
();
$callbacks
=
$this
->
originalShutdownCallbacks
;
// Restore original user session.
$user
=
$this
->
originalUser
;
drupal_save_session
(
TRUE
);
}
/**
* Handle errors during test runs.
*
...
...
core/modules/simpletest/lib/Drupal/simpletest/UnitTestBase.php
View file @
5b0715d7
...
...
@@ -38,55 +38,40 @@ function __construct($test_id = NULL) {
protected
function
setUp
()
{
global
$conf
;
//
Store necessary current values before switching to the test environmen
t.
$this
->
originalFileDirectory
=
variable_get
(
'file_public_path'
,
conf_path
()
.
'/files'
);
//
Create the database prefix for this tes
t.
$this
->
prepareDatabasePrefix
(
);
// Reset all statics so that test is performed with a clean environment.
// Prepare the environment for running tests.
$this
->
prepareEnvironment
();
$this
->
originalThemeRegistry
=
theme_get_registry
(
FALSE
);
// Reset all statics and variables to perform tests in a clean environment.
$conf
=
array
();
drupal_static_reset
();
// Generate temporary prefixed database to ensure that tests have a clean starting point.
$this
->
databasePrefix
=
Database
::
getConnection
()
->
prefixTables
(
'{simpletest'
.
mt_rand
(
1000
,
1000000
)
.
'}'
);
// Empty out module list.
module_list
(
TRUE
,
FALSE
,
FALSE
,
array
());
// Prevent module_load_all() from attempting to refresh it.
$has_run
=
&
drupal_static
(
'module_load_all'
);
$has_run
=
TRUE
;
// Re-implant theme registry.
// Required for l() and other functions to work correctly and not trigger
// database lookups.
$theme_get_registry
=
&
drupal_static
(
'theme_get_registry'
);
$theme_get_registry
[
FALSE
]
=
$this
->
originalThemeRegistry
;
// Create test directory.
$public_files_directory
=
$this
->
originalFileDirectory
.
'/simpletest/'
.
substr
(
$this
->
databasePrefix
,
10
);
file_prepare_directory
(
$public_files_directory
,
FILE_CREATE_DIRECTORY
|
FILE_MODIFY_PERMISSIONS
);
$conf
[
'file_public_path'
]
=
$public_files_directory
;
$conf
[
'file_public_path'
]
=
$this
->
public_files_directory
;
// Clone the current connection and replace the current prefix.
$connection_info
=
Database
::
getConnectionInfo
(
'default'
);
Database
::
renameConnection
(
'default'
,
'simpletest_original_default'
);
foreach
(
$connection_info
as
$target
=>
$value
)
{
$connection_info
[
$target
][
'prefix'
]
=
array
(
'default'
=>
$value
[
'prefix'
][
'default'
]
.
$this
->
databasePrefix
,
);
}
Database
::
addConnectionInfo
(
'default'
,
'default'
,
$connection_info
[
'default'
]);
// Change the database prefix.
// All static variables need to be reset before the database prefix is
// changed, since Drupal\Core\Utility\CacheArray implementations attempt to
// write back to persistent caches when they are destructed.
$this
->
changeDatabasePrefix
();
// Set user agent to be consistent with
web test c
ase.
// Set user agent to be consistent with
WebTestB
ase.
$_SERVER
[
'HTTP_USER_AGENT'
]
=
$this
->
databasePrefix
;
// If locale is enabled then t() will try to access the database and
// subsequently will fail as the database is not accessible.
$module_list
=
module_list
();
if
(
isset
(
$module_list
[
'locale'
]))
{
$this
->
originalModuleList
=
$module_list
;
unset
(
$module_list
[
'locale'
]);
module_list
(
TRUE
,
FALSE
,
FALSE
,
$module_list
);
}
$this
->
setup
=
TRUE
;
}
protected
function
tearDown
()
{
global
$conf
;
// Get back to the original connection.
Database
::
removeConnection
(
'default'
);
Database
::
renameConnection
(
'simpletest_original_default'
,
'default'
);
$conf
[
'file_public_path'
]
=
$this
->
originalFileDirectory
;
// Restore modules if necessary.
if
(
isset
(
$this
->
originalModuleList
))
{
module_list
(
TRUE
,
FALSE
,
FALSE
,
$this
->
originalModuleList
);
}
}
}
core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
View file @
5b0715d7
...
...
@@ -534,117 +534,6 @@ protected function drupalLogout() {
}
}
/**
* Generates a database prefix for running tests.
*
* The generated database table prefix is used for the Drupal installation
* being performed for the test. It is also used as user agent HTTP header
* value by the cURL-based browser of Drupal\simpletest\WebTestBase, which is sent
* to the Drupal installation of the test. During early Drupal bootstrap, the
* user agent HTTP header is parsed, and if it matches, all database queries
* use the database table prefix that has been generated here.
*
* @see Drupal\simpletest\WebTestBase::curlInitialize()
* @see drupal_valid_test_ua()
* @see Drupal\simpletest\WebTestBase::setUp()
*/
protected
function
prepareDatabasePrefix
()
{
$this
->
databasePrefix
=
'simpletest'
.
mt_rand
(
1000
,
1000000
);
// As soon as the database prefix is set, the test might start to execute.
// All assertions as well as the SimpleTest batch operations are associated
// with the testId, so the database prefix has to be associated with it.
db_update
(
'simpletest_test_id'
)
->
fields
(
array
(
'last_prefix'
=>
$this
->
databasePrefix
))
->
condition
(
'test_id'
,
$this
->
testId
)
->
execute
();
}
/**
* Changes the database connection to the prefixed one.
*
* @see Drupal\simpletest\WebTestBase::setUp()
*/
protected
function
changeDatabasePrefix
()
{
if
(
empty
(
$this
->
databasePrefix
))
{
$this
->
prepareDatabasePrefix
();
}
// Clone the current connection and replace the current prefix.
$connection_info
=
Database
::
getConnectionInfo
(
'default'
);
Database
::
renameConnection
(
'default'
,
'simpletest_original_default'
);
foreach
(
$connection_info
as
$target
=>
$value
)
{
$connection_info
[
$target
][
'prefix'
]
=
array
(
'default'
=>
$value
[
'prefix'
][
'default'
]
.
$this
->
databasePrefix
,
);
}
Database
::
addConnectionInfo
(
'default'
,
'default'
,
$connection_info
[
'default'
]);
}
/**
* Prepares the current environment for running the test.
*
* Backups various current environment variables and resets them, so they do
* not interfere with the Drupal site installation in which tests are executed
* and can be restored in tearDown().
*
* Also sets up new resources for the testing environment, such as the public
* filesystem and configuration directories.
*
* @see Drupal\simpletest\WebTestBase::setUp()
* @see Drupal\simpletest\WebTestBase::tearDown()
*/
protected
function
prepareEnvironment
()
{
global
$user
,
$language_interface
,
$conf
;
// Store necessary current values before switching to prefixed database.
$this
->
originalContainer
=
clone
drupal_container
();
$this
->
originalLanguage
=
$language_interface
;
$this
->
originalLanguageDefault
=
variable_get
(
'language_default'
);
$this
->
originalConfigDirectory
=
$GLOBALS
[
'config_directory_name'
];
$this
->
originalFileDirectory
=
variable_get
(
'file_public_path'
,
conf_path
()
.
'/files'
);
$this
->
originalProfile
=
drupal_get_profile
();
$this
->
originalUser
=
$user
;
// Save and clean the shutdown callbacks array because it is static cached
// and will be changed by the test run. Otherwise it will contain callbacks
// from both environments and the testing environment will try to call the
// handlers defined by the original one.
$callbacks
=
&
drupal_register_shutdown_function
();
$this
->
originalShutdownCallbacks
=
$callbacks
;
$callbacks
=
array
();
// Create test directory ahead of installation so fatal errors and debug
// information can be logged during installation process.
// Use temporary files directory with the same prefix as the database.
$this
->
public_files_directory
=
$this
->
originalFileDirectory
.
'/simpletest/'
.
substr
(
$this
->
databasePrefix
,
10
);
$this
->
private_files_directory
=
$this
->
public_files_directory
.
'/private'
;
$this
->
temp_files_directory
=
$this
->
private_files_directory
.
'/temp'
;
// Create the directories
file_prepare_directory
(
$this
->
public_files_directory
,
FILE_CREATE_DIRECTORY
|
FILE_MODIFY_PERMISSIONS
);
file_prepare_directory
(
$this
->
private_files_directory
,
FILE_CREATE_DIRECTORY
);
file_prepare_directory
(
$this
->
temp_files_directory
,
FILE_CREATE_DIRECTORY
);
$this
->
generatedTestFiles
=
FALSE
;
// Create and set a new configuration directory and signature key.
// The child site automatically adjusts the global $config_directory_name to
// a test-prefix-specific directory within the public files directory.
// @see config_get_config_directory()
$GLOBALS
[
'config_directory_name'
]
=
'simpletest/'
.
substr
(
$this
->
databasePrefix
,
10
)
.
'/config'
;
$this
->
configFileDirectory
=
$this
->
originalFileDirectory
.
'/'
.
$GLOBALS
[
'config_directory_name'
];
file_prepare_directory
(
$this
->
configFileDirectory
,
FILE_CREATE_DIRECTORY
|
FILE_MODIFY_PERMISSIONS
);
// Log fatal errors.
ini_set
(
'log_errors'
,
1
);
ini_set
(
'error_log'
,
$this
->
public_files_directory
.
'/error.log'
);
// Set the test information for use in other parts of Drupal.
$test_info
=
&
$GLOBALS
[
'drupal_test_info'
];
$test_info
[
'test_run_id'
]
=
$this
->
databasePrefix
;
$test_info
[
'in_child_site'
]
=
FALSE
;
}
/**
* Sets up a Drupal site for running functional and integration tests.
*
...
...
@@ -841,21 +730,6 @@ protected function refreshVariables() {
* and reset the database prefix.
*/
protected
function
tearDown
()
{
global
$user
,
$language_interface
;
// In case a fatal error occurred that was not in the test process read the
// log to pick up any fatal errors.
simpletest_log_read
(
$this
->
testId
,
$this
->
databasePrefix
,
get_class
(
$this
),
TRUE
);
$emailCount
=
count
(
variable_get
(
'drupal_test_email_collector'
,
array
()));
if
(
$emailCount
)
{
$message
=
format_plural
(
$emailCount
,
'1 e-mail was sent during this test.'
,
'@count e-mails were sent during this test.'
);
$this
->
pass
(
$message
,
t
(
'E-mail'
));
}
// Delete temporary files directory.
file_unmanaged_delete_recursive
(
$this
->
originalFileDirectory
.
'/simpletest/'
.
substr
(
$this
->
databasePrefix
,
10
));
// Remove all prefixed tables.
$connection_info
=
Database
::
getConnectionInfo
(
'default'
);
$tables
=
db_find_tables
(
$connection_info
[
'default'
][
'prefix'
][
'default'
]
.
'%'
);
...
...
@@ -872,21 +746,7 @@ protected function tearDown() {
$this
->
fail
(
'Failed to drop all prefixed tables.'
);
}
// Get back to the original connection.
Database
::
removeConnection
(
'default'
);
Database
::
renameConnection
(
'simpletest_original_default'
,
'default'
);
// Restore the original dependency injection container.
drupal_container
(
$this
->
originalContainer
);
// Restore original shutdown callbacks array to prevent original
// environment of calling handlers from test run.
$callbacks
=
&
drupal_register_shutdown_function
();
$callbacks
=
$this
->
originalShutdownCallbacks
;
// Return the user to the original one.
$user
=
$this
->
originalUser
;
drupal_save_session
(
TRUE
);
parent
::
tearDown
();
// Ensure that internal logged in variable and cURL options are reset.
$this
->
loggedInUser
=
FALSE
;
...
...
@@ -903,18 +763,6 @@ protected function tearDown() {
// Rebuild caches.
$this
->
refreshVariables
();
// Reset public files directory.
$GLOBALS
[
'conf'
][
'file_public_path'
]
=
$this
->
originalFileDirectory
;
// Reset configuration globals.
$GLOBALS
[
'config_directory_name'
]
=
$this
->
originalConfigDirectory
;
// Reset language.
$language_interface
=
$this
->
originalLanguage
;
if
(
$this
->
originalLanguageDefault
)
{
$GLOBALS
[
'conf'
][
'language_default'
]
=
$this
->
originalLanguageDefault
;
}
// Close the CURL handler.
$this
->
curlClose
();
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment