Commit 7b88ea7c authored by webchick's avatar webchick

Issue #1808200 by sun: Fixed Unit test performance significantly decreased...

Issue #1808200 by sun: Fixed Unit test performance significantly decreased since system list config conversion.
parent a41da4e3
......@@ -938,7 +938,7 @@ function drupal_get_filename($type, $name, $filename = NULL) {
// extension, not just the file we are currently looking for. This
// prevents unnecessary scans from being repeated when this function is
// called more than once in the same page request.
$matches = drupal_system_listing("/^" . DRUPAL_PHP_FUNCTION_PATTERN . "\.$extension$/", $dir, 'name', 0);
$matches = drupal_system_listing("/^" . DRUPAL_PHP_FUNCTION_PATTERN . "\.$extension$/", $dir);
foreach ($matches as $matched_name => $file) {
$files[$type][$matched_name] = $file->uri;
}
......
......@@ -5119,17 +5119,17 @@ function drupal_cron_cleanup() {
* depending on what type of object you are looking for. For instance, if you
* are looking for modules and call:
* @code
* drupal_system_listing("/\.module$/", "modules", 'name', 0);
* drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules');
* @endcode
* the function will search the following directories in this order:
* - /core/modules.
* - /core/profiles/testing/modules (only if a test is being run).
* - /core/profiles/active_profile/modules or /profiles/active_profile/modules.
* - /modules (standard directory for your contrib/custom modules).
* - /sites/all/modules (legacy contrib/custom modules directory, see above).
* - /sites/your_site_dir/modules (for multisite installations).
* and return information about all of the files ending in .module in those
* directories.
* this function will search:
* - the core modules directory; i.e., /core/modules
* - the testing profile directory; e.g., /profiles/testing/modules
* - your installation profile's directory; e.g., /profiles/standard/modules
* - the site-wide modules directory; i.e., /modules
* - the all-sites directory; i.e., /sites/all/modules
* - the site-specific directory; i.e., /sites/example.com/modules
* in that order, and return information about all of the files ending in
* .module in those directories.
*
* The information is returned in an associative array, which can be keyed on
* the file name ($key = 'filename'), the file name without the extension ($key
......@@ -5140,21 +5140,28 @@ function drupal_cron_cleanup() {
* files found.
*
* @param string $mask
* The preg_match() regular expression for the files to find.
* The preg_match() regular expression for the files to find. The expression
* must be anchored and use DRUPAL_PHP_FUNCTION_PATTERN for the file name part
* before the extension, since the results could contain matches that do not
* present valid Drupal extensions otherwise.
* @param string $directory
* The subdirectory name in which the files are found. For example,
* 'core/modules' will search in sub-directories of the /core/modules
* directory, sub-directories of /modules/, etc.
* 'modules' will search all 'modules' directories and their sub-directories
* as explained above.
* @param string $key
* The key to be used for the associative array returned. Possible values are
* 'uri', for the file's URI; 'filename', for the basename of the file; and
* 'name' for the name of the file without the extension. If you choose 'name'
* or 'filename', only the highest-precedence file will be returned.
* (optional) The key to be used for the associative array returned. Possible
* values are:
* - 'uri' for the file's URI.
* - 'filename' for the basename of the file.
* - 'name' for the name of the file without the extension.
* For 'name' and 'filename' only the highest-precedence file is returned.
* Defaults to 'name'.
* @param int $min_depth
* Minimum depth of directories to return files from, relative to each
* directory searched. For instance, a minimum depth of 2 would find modules
* inside /core/modules/node/tests, but not modules directly in
* /core/modules/node.
* (optional) Minimum depth of directories to return files from, relative to
* each directory searched. For instance, a directory of 'modules' and a
* minimum depth of 2 would find modules inside /modules/node/tests, but not
* modules directly in /modules/node. Defaults to 1. The default is sufficient
* and suitable for all extension types known by Drupal core.
*
* @return array
* An associative array of file objects, keyed on the chosen key. Each element
......@@ -5204,7 +5211,14 @@ function drupal_system_listing($mask, $directory, $key = 'name', $min_depth = 1)
require_once DRUPAL_ROOT . '/core/includes/file.inc';
}
foreach ($searchdir as $dir) {
$files_to_add = file_scan_directory($dir, $mask, array('key' => $key, 'min_depth' => $min_depth));
$files_to_add = file_scan_directory($dir, $mask, array(
'key' => $key,
'min_depth' => $min_depth,
// Do not recurse into ./lib directories; they cannot contain extensions.
// We also skip templates, css, and js directories.
// @todo Find a way to skip ./config directories (but not modules/config).
'nomask' => '/^(CVS|lib|templates|css|js)$/',
));
// Duplicate files found in later search directories take precedence over
// earlier ones, so we want them to overwrite keys in our resulting
......@@ -5216,7 +5230,7 @@ function drupal_system_listing($mask, $directory, $key = 'name', $min_depth = 1)
foreach (array_intersect_key($files_to_add, $files) as $file_key => $file) {
// If it has no info file, then we just behave liberally and accept the
// new resource on the list for merging.
if (file_exists($info_file = dirname($file->uri) . '/' . $file->name . '.info')) {
if (file_exists($info_file = DRUPAL_ROOT . '/' . dirname($file->uri) . '/' . $file->name . '.info')) {
// Get the .info file for the module or theme this file belongs to.
$info = drupal_parse_info_file($info_file);
......
......@@ -1432,12 +1432,17 @@ function file_download() {
function file_scan_directory($dir, $mask, $options = array(), $depth = 0) {
// Merge in defaults.
$options += array(
'nomask' => '/(\.\.?|CVS)$/',
'nomask' => '/^CVS$/',
'callback' => 0,
'recurse' => TRUE,
'key' => 'uri',
'min_depth' => 0,
);
// Normalize $dir only once.
if ($depth == 0) {
$dir = file_stream_wrapper_uri_normalize($dir);
$dir_has_slash = (substr($dir, -1) === '/');
}
$options['key'] = in_array($options['key'], array('uri', 'filename', 'name')) ? $options['key'] : 'uri';
$files = array();
......@@ -1446,10 +1451,15 @@ function file_scan_directory($dir, $mask, $options = array(), $depth = 0) {
if (is_dir($dir)) {
if($handle = @opendir($dir)) {
while (FALSE !== ($filename = readdir($handle))) {
if (!preg_match($options['nomask'], $filename) && $filename[0] != '.') {
$uri = "$dir/$filename";
$uri = file_stream_wrapper_uri_normalize($uri);
if (is_dir($uri) && $options['recurse']) {
// Skip this file if it matches the nomask or starts with a dot.
if ($filename[0] != '.' && !preg_match($options['nomask'], $filename)) {
if ($depth == 0 && $dir_has_slash) {
$uri = "$dir$filename";
}
else {
$uri = "$dir/$filename";
}
if ($options['recurse'] && is_dir($uri)) {
// Give priority to files in this folder by merging them in after
// any subdirectory files.
$files = array_merge(file_scan_directory($uri, $mask, $options, $depth + 1), $files);
......
......@@ -384,7 +384,7 @@ function drupal_verify_profile($install_state) {
// Get a list of modules that exist in Drupal's assorted subdirectories.
$present_modules = array();
foreach (drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules', 'name', 0) as $present_module) {
foreach (drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules') as $present_module) {
$present_modules[] = $present_module->name;
}
......
......@@ -1006,7 +1006,7 @@ function module_invoke_all($hook) {
* Returns an array of modules required by core.
*/
function drupal_required_modules() {
$files = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info$/', 'modules', 'name', 0);
$files = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info$/', 'modules');
$required = array();
// An installation profile is required and one must always be loaded.
......
......@@ -385,10 +385,20 @@ function simpletest_test_get_all() {
* Registers namespaces for disabled modules.
*/
function simpletest_classloader_register() {
$all_data = system_rebuild_module_data();
$all_data += system_rebuild_theme_data();
foreach ($all_data as $name => $data) {
drupal_classloader_register($name, dirname($data->filename));
// @see drupal_get_filename()
$types = array(
'theme_engine' => array('dir' => 'themes/engines', 'extension' => 'engine'),
'module' => array('dir' => 'modules', 'extension' => 'module'),
'theme' => array('dir' => 'themes', 'extension' => 'info'),
'profile' => array('dir' => 'profiles', 'extension' => 'profile'),
);
foreach ($types as $type => $info) {
$matches = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.' . $info['extension'] . '$/', $info['dir']);
foreach ($matches as $name => $file) {
drupal_classloader_register($name, dirname($file->uri));
// While being there, prime drupal_get_filename().
drupal_get_filename($type, $name, $file->uri);
}
}
}
......
......@@ -22,14 +22,24 @@ public static function getInfo() {
);
}
function setUp() {
parent::setUp();
// Remove the keyvalue service definition, since this test wants to verify
// the filesystem scan fallback of drupal_get_filename().
$this->keyvalue_definition = $this->container->getDefinition('keyvalue');
$this->container->removeDefinition('keyvalue');
}
function tearDown() {
$this->container->setDefinition('keyvalue', $this->keyvalue_definition);
parent::tearDown();
}
/**
* Tests that drupal_get_filename() works when the file is not in database.
*/
function testDrupalGetFilename() {
// Reset the static cache so we can test the "db is not active" code of
// drupal_get_filename().
drupal_static_reset('drupal_get_filename');
// Retrieving the location of a module.
$this->assertIdentical(drupal_get_filename('module', 'php'), 'core/modules/php/php.module', 'Retrieve module location.');
......@@ -50,6 +60,6 @@ function testDrupalGetFilename() {
// Since there is already a core/scripts directory, drupal_get_filename()
// will automatically check there for 'script' files, just as it does
// for (e.g.) 'module' files in core/modules.
$this->assertIdentical(drupal_get_filename('script', 'test'), 'core/scripts/test.script', 'Retrieve test script location.');
$this->assertIdentical(drupal_get_filename('script', 'test'), 'core/scripts/test/test.script');
}
}
......@@ -55,7 +55,7 @@ function testDirectoryPrecedence() {
// Now scan the directories and check that the files take precedence as
// expected.
$files = drupal_system_listing('/\.module$/', 'modules', 'name', 1);
$files = drupal_system_listing('/\.module$/', 'modules');
foreach ($expected_directories as $module => $directories) {
$expected_directory = array_shift($directories);
$expected_filename = "$expected_directory/$module/$module.module";
......
......@@ -2776,10 +2776,10 @@ function system_get_module_info($property) {
*/
function _system_rebuild_module_data() {
// Find modules
$modules = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules', 'name', 0);
$modules = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules');
// Find installation profiles.
$profiles = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.profile$/', 'profiles', 'name', 0);
$profiles = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.profile$/', 'profiles');
// Include the installation profile in modules that are loaded.
$profile = drupal_get_profile();
......
......@@ -28,7 +28,7 @@
}
// Bootstrap to perform initial validation or other operations.
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
drupal_bootstrap(DRUPAL_BOOTSTRAP_CODE);
if (!module_exists('simpletest')) {
simpletest_script_print_error("The simpletest module must be enabled before this script can run.");
exit;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment