public function __construct(Remote $remote, $id = false, $data = array()) { $this->remote = $remote; $this->data = $data; if ($id === false) { // Generate a UUID for the transaction. \module_load_include('inc', 'uuid'); $this->id = \uuid_generate(); } else { $this->id = $id; } // Set the timeout to a higher number. drupal_set_time_limit(0); }
/** * Prepares the current environment for running the test. * * Also sets up new resources for the testing environment, such as the public * filesystem and configuration directories. * * This method is private as it must only be called once by * BrowserTestBase::setUp() (multiple invocations for the same test would have * unpredictable consequences) and it must not be callable or overridable by * test classes. */ protected function prepareEnvironment() { // Bootstrap Drupal so we can use Drupal's built in functions. $this->classLoader = (require __DIR__ . '/../../../../autoload.php'); $request = Request::createFromGlobals(); $kernel = TestRunnerKernel::createFromRequest($request, $this->classLoader); // TestRunnerKernel expects the working directory to be DRUPAL_ROOT. chdir(DRUPAL_ROOT); $kernel->prepareLegacyRequest($request); $this->prepareDatabasePrefix(); $this->originalSiteDirectory = $kernel->findSitePath($request); // Create test directory ahead of installation so fatal errors and debug // information can be logged during installation process. file_prepare_directory($this->siteDirectory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS); // Prepare filesystem directory paths. $this->publicFilesDirectory = $this->siteDirectory . '/files'; $this->privateFilesDirectory = $this->siteDirectory . '/private'; $this->tempFilesDirectory = $this->siteDirectory . '/temp'; $this->translationFilesDirectory = $this->siteDirectory . '/translations'; // Ensure the configImporter is refreshed for each test. $this->configImporter = NULL; // Unregister all custom stream wrappers of the parent site. $wrappers = \Drupal::service('stream_wrapper_manager')->getWrappers(StreamWrapperInterface::ALL); foreach ($wrappers as $scheme => $info) { stream_wrapper_unregister($scheme); } // Reset statics. drupal_static_reset(); // Ensure there is no service container. $this->container = NULL; \Drupal::unsetContainer(); // Unset globals. unset($GLOBALS['config_directories']); unset($GLOBALS['config']); unset($GLOBALS['conf']); // Log fatal errors. ini_set('log_errors', 1); ini_set('error_log', DRUPAL_ROOT . '/' . $this->siteDirectory . '/error.log'); // Change the database prefix. $this->changeDatabasePrefix(); // After preparing the environment and changing the database prefix, we are // in a valid test environment. drupal_valid_test_ua($this->databasePrefix); // Reset settings. new Settings(array('hash_salt' => $this->databasePrefix)); drupal_set_time_limit($this->timeLimit); }
/** * Generates a random database prefix, runs the install scripts on the * prefixed database and enable the specified modules. After installation * many caches are flushed and the internal browser is setup so that the * page requests will run on the new prefix. A temporary files directory * is created with the same name as the database prefix. * * @param ... * List of modules to enable for the duration of the test. This can be * either a single array or a variable number of string arguments. */ protected function setUp() { global $user, $language, $conf; // Generate a temporary prefixed database to ensure that tests have a clean starting point. $this->databasePrefix = 'simpletest' . mt_rand(1000, 1000000); db_update('simpletest_test_id')->fields(array('last_prefix' => $this->databasePrefix))->condition('test_id', $this->testId)->execute(); // 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']); // Store necessary current values before switching to prefixed database. $this->originalLanguage = $language; $this->originalLanguageDefault = variable_get('language_default'); $this->originalFileDirectory = variable_get('file_public_path', conf_path() . '/files'); $this->originalProfile = drupal_get_profile(); $clean_url_original = variable_get('clean_url', 0); // Set to English to prevent exceptions from utf8_truncate() from t() // during install if the current language is not 'en'. // The following array/object conversion is copied from language_default(). $language = (object) array('language' => 'en', 'name' => 'English', 'native' => 'English', 'direction' => 0, 'enabled' => 1, 'plurals' => 0, 'formula' => '', 'domain' => '', 'prefix' => '', 'weight' => 0, 'javascript' => ''); // Save and clean shutdown callbacks array because it static cached and // will be changed by the test run. If we don't, then it will contain // callbacks from both environments. So testing environment will try // to call handlers from original environment. $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. $public_files_directory = $this->originalFileDirectory . '/simpletest/' . substr($this->databasePrefix, 10); $private_files_directory = $public_files_directory . '/private'; $temp_files_directory = $private_files_directory . '/temp'; // Create the directories file_prepare_directory($public_files_directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS); file_prepare_directory($private_files_directory, FILE_CREATE_DIRECTORY); file_prepare_directory($temp_files_directory, FILE_CREATE_DIRECTORY); $this->generatedTestFiles = FALSE; // Log fatal errors. ini_set('log_errors', 1); ini_set('error_log', $public_files_directory . '/error.log'); // Reset all statics and variables to perform tests in a clean environment. $conf = array(); drupal_static_reset(); // 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; include_once DRUPAL_ROOT . '/includes/install.inc'; drupal_install_system(); $this->preloadRegistry(); // Set path variables. variable_set('file_public_path', $public_files_directory); variable_set('file_private_path', $private_files_directory); variable_set('file_temporary_path', $temp_files_directory); // Include the testing profile. variable_set('install_profile', $this->profile); $profile_details = install_profile_info($this->profile, 'en'); // Install the modules specified by the testing profile. module_enable($profile_details['dependencies'], FALSE); // Install modules needed for this test. This could have been passed in as // either a single array argument or a variable number of string arguments. // @todo Remove this compatibility layer in Drupal 8, and only accept // $modules as a single array argument. $modules = func_get_args(); if (isset($modules[0]) && is_array($modules[0])) { $modules = $modules[0]; } if ($modules) { $success = module_enable($modules, TRUE); $this->assertTrue($success, t('Enabled modules: %modules', array('%modules' => implode(', ', $modules)))); } // Run the profile tasks. $install_profile_module_exists = db_query("SELECT 1 FROM {system} WHERE type = 'module' AND name = :name", array(':name' => $this->profile))->fetchField(); if ($install_profile_module_exists) { module_enable(array($this->profile), FALSE); } // Reset/rebuild all data structures after enabling the modules. $this->resetAll(); // Run cron once in that environment, as install.php does at the end of // the installation process. drupal_cron_run(); // Log in with a clean $user. $this->originalUser = $user; drupal_save_session(FALSE); $user = user_load(1); // Restore necessary variables. variable_set('install_task', 'done'); variable_set('clean_url', $clean_url_original); variable_set('site_mail', '*****@*****.**'); variable_set('date_default_timezone', date_default_timezone_get()); // Set up English language. unset($GLOBALS['conf']['language_default']); $language = language_default(); // Use the test mail class instead of the default mail handler class. variable_set('mail_system', array('default-system' => 'TestingMailSystem')); drupal_set_time_limit($this->timeLimit); }
/** * Sets up a Drupal site for running functional and integration tests. * * Generates a random database prefix and installs Drupal with the specified * installation profile in DrupalWebTestCase::$profile into the * prefixed database. Afterwards, installs any additional modules specified by * the test. * * After installation all caches are flushed and several configuration values * are reset to the values of the parent site executing the test, since the * default values may be incompatible with the environment in which tests are * being executed. * * @param ... * List of modules to enable for the duration of the test. This can be * either a single array or a variable number of string arguments. * * @see DrupalWebTestCase::prepareDatabasePrefix() * @see DrupalWebTestCase::changeDatabasePrefix() * @see DrupalWebTestCase::prepareEnvironment() */ protected function setUp() { global $user, $language, $conf; // Create the database prefix for this test. $this->prepareDatabasePrefix(); // Prepare the environment for running tests. $this->prepareEnvironment(); if (!$this->setupEnvironment) { return FALSE; } // Reset all statics and variables to perform tests in a clean environment. $conf = array(); drupal_static_reset(); // Change the database prefix. // All static variables need to be reset before the database prefix is // changed, since DrupalCacheArray implementations attempt to // write back to persistent caches when they are destructed. $this->changeDatabasePrefix(); if (!$this->setupDatabasePrefix) { return FALSE; } // Preset the 'install_profile' system variable, so the first call into // system_rebuild_module_data() (in drupal_install_system()) will register // the test's profile as a module. Without this, the installation profile of // the parent site (executing the test) is registered, and the test // profile's hook_install() and other hook implementations are never invoked. $conf['install_profile'] = $this->profile; // Perform the actual Drupal installation. include_once DRUPAL_ROOT . '/includes/install.inc'; drupal_install_system(); $this->preloadRegistry(); // Set path variables. variable_set('file_public_path', $this->public_files_directory); variable_set('file_private_path', $this->private_files_directory); variable_set('file_temporary_path', $this->temp_files_directory); // Set the 'simpletest_parent_profile' variable to add the parent profile's // search path to the child site's search paths. // @see drupal_system_listing() // @todo This may need to be primed like 'install_profile' above. variable_set('simpletest_parent_profile', $this->originalProfile); // Include the testing profile. variable_set('install_profile', $this->profile); $profile_details = install_profile_info($this->profile, 'en'); // Install the modules specified by the testing profile. module_enable($profile_details['dependencies'], FALSE); // Install modules needed for this test. This could have been passed in as // either a single array argument or a variable number of string arguments. // @todo Remove this compatibility layer in Drupal 8, and only accept // $modules as a single array argument. $modules = func_get_args(); if (isset($modules[0]) && is_array($modules[0])) { $modules = $modules[0]; } if ($modules) { $success = module_enable($modules, TRUE); $this->assertTrue($success, t('Enabled modules: %modules', array('%modules' => implode(', ', $modules)))); } // Run the profile tasks. $install_profile_module_exists = db_query("SELECT 1 FROM {system} WHERE type = 'module' AND name = :name", array(':name' => $this->profile))->fetchField(); if ($install_profile_module_exists) { module_enable(array($this->profile), FALSE); } // Reset/rebuild all data structures after enabling the modules. $this->resetAll(); // Run cron once in that environment, as install.php does at the end of // the installation process. drupal_cron_run(); // Ensure that the session is not written to the new environment and replace // the global $user session with uid 1 from the new test site. drupal_save_session(FALSE); // Login as uid 1. $user = user_load(1); // Restore necessary variables. variable_set('install_task', 'done'); variable_set('clean_url', $this->originalCleanUrl); variable_set('site_mail', '*****@*****.**'); variable_set('date_default_timezone', date_default_timezone_get()); // Set up English language. unset($conf['language_default']); $language = language_default(); // Use the test mail class instead of the default mail handler class. variable_set('mail_system', array('default-system' => 'TestingMailSystem')); drupal_set_time_limit($this->timeLimit); $this->setup = TRUE; }
/** * Generates a random database prefix, runs the install scripts on the * prefixed database and enable the specified modules. After installation * many caches are flushed and the internal browser is setup so that the * page requests will run on the new prefix. A temporary files directory * is created with the same name as the database prefix. * * @param ... * List of modules to enable for the duration of the test. */ protected function setUp() { global $db_prefix, $user, $language; // Store necessary current values before switching to prefixed database. $this->originalLanguage = $language; $this->originalLanguageDefault = variable_get('language_default'); $this->originalPrefix = $db_prefix; $this->originalFileDirectory = file_directory_path(); $this->originalProfile = drupal_get_profile(); $clean_url_original = variable_get('clean_url', 0); // Generate temporary prefixed database to ensure that tests have a clean starting point. $db_prefix_new = Database::getConnection()->prefixTables('{simpletest' . mt_rand(1000, 1000000) . '}'); db_update('simpletest_test_id')->fields(array('last_prefix' => $db_prefix_new))->condition('test_id', $this->testId)->execute(); $db_prefix = $db_prefix_new; // 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. $public_files_directory = $this->originalFileDirectory . '/simpletest/' . substr($db_prefix, 10); $private_files_directory = $public_files_directory . '/private'; $temp_files_directory = $private_files_directory . '/temp'; // Create the directories file_prepare_directory($public_files_directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS); file_prepare_directory($private_files_directory, FILE_CREATE_DIRECTORY); file_prepare_directory($temp_files_directory, FILE_CREATE_DIRECTORY); $this->generatedTestFiles = FALSE; // Log fatal errors. ini_set('log_errors', 1); ini_set('error_log', $public_files_directory . '/error.log'); // Reset all statics so that test is performed with a clean environment. drupal_static_reset(); include_once DRUPAL_ROOT . '/includes/install.inc'; drupal_install_system(); $this->preloadRegistry(); // Include the default profile variable_set('install_profile', 'standard'); $profile_details = install_profile_info('standard', 'en'); // Install the modules specified by the default profile. drupal_install_modules($profile_details['dependencies'], TRUE); drupal_static_reset('_node_types_build'); if ($modules = func_get_args()) { // Install modules needed for this test. drupal_install_modules($modules, TRUE); } // Because the schema is static cached, we need to flush // it between each run. If we don't, then it will contain // stale data for the previous run's database prefix and all // calls to it will fail. drupal_get_schema(NULL, TRUE); // Run default profile tasks. $install_state = array(); drupal_install_modules(array('standard'), TRUE); // Rebuild caches. node_types_rebuild(); actions_synchronize(); _drupal_flush_css_js(); $this->refreshVariables(); $this->checkPermissions(array(), TRUE); // Log in with a clean $user. $this->originalUser = $user; drupal_save_session(FALSE); $user = user_load(1); // Restore necessary variables. variable_set('install_task', 'done'); variable_set('clean_url', $clean_url_original); variable_set('site_mail', '*****@*****.**'); // Set up English language. unset($GLOBALS['conf']['language_default']); $language = language_default(); // Set path variables variable_set('file_public_path', $public_files_directory); variable_set('file_private_path', $private_files_directory); variable_set('file_temporary_path', $temp_files_directory); // Use the test mail class instead of the default mail handler class. variable_set('mail_system', array('default-system' => 'TestingMailSystem')); drupal_set_time_limit($this->timeLimit); }
/** * 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::restoreEnvironment(). * * Also sets up new resources for the testing environment, such as the public * filesystem and configuration directories. * * This method is private as it must only be called once by TestBase::run() * (multiple invocations for the same test would have unpredictable * consequences) and it must not be callable or overridable by test classes. * * @see TestBase::beforePrepareEnvironment() */ private function prepareEnvironment() { $user = \Drupal::currentUser(); // Allow (base) test classes to backup global state information. $this->beforePrepareEnvironment(); // Create the database prefix for this test. $this->prepareDatabasePrefix(); $language_interface = \Drupal::languageManager()->getCurrentLanguage(); // When running the test runner within a test, back up the original database // prefix. if (DRUPAL_TEST_IN_CHILD_SITE) { $this->originalPrefix = drupal_valid_test_ua(); } // Backup current in-memory configuration. $site_path = \Drupal::service('site.path'); $this->originalSite = $site_path; $this->originalSettings = Settings::getAll(); $this->originalConfig = $GLOBALS['config']; // @todo Remove all remnants of $GLOBALS['conf']. // @see https://www.drupal.org/node/2183323 $this->originalConf = isset($GLOBALS['conf']) ? $GLOBALS['conf'] : NULL; // Backup statics and globals. $this->originalContainer = clone \Drupal::getContainer(); $this->originalLanguage = $language_interface; $this->originalConfigDirectories = $GLOBALS['config_directories']; // Save further contextual information. // Use the original files directory to avoid nesting it within an existing // simpletest directory if a test is executed within a test. $this->originalFileDirectory = Settings::get('file_public_path', $site_path . '/files'); $this->originalProfile = drupal_get_profile(); $this->originalUser = isset($user) ? clone $user : NULL; // Prevent that session data is leaked into the UI test runner by closing // the session and then setting the session-name (i.e. the name of the // session cookie) to a random value. If a test starts a new session, then // it will be associated with a different session-name. After the test-run // it can be safely destroyed. // @see TestBase::restoreEnvironment() if (PHP_SAPI !== 'cli' && session_status() === PHP_SESSION_ACTIVE) { session_write_close(); } $this->originalSessionName = session_name(); session_name('SIMPLETEST' . Crypt::randomBytesBase64()); // 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. file_prepare_directory($this->siteDirectory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS); // Prepare filesystem directory paths. $this->publicFilesDirectory = $this->siteDirectory . '/files'; $this->privateFilesDirectory = $this->siteDirectory . '/private'; $this->tempFilesDirectory = $this->siteDirectory . '/temp'; $this->translationFilesDirectory = $this->siteDirectory . '/translations'; $this->generatedTestFiles = FALSE; // Ensure the configImporter is refreshed for each test. $this->configImporter = NULL; // Unregister all custom stream wrappers of the parent site. // Availability of Drupal stream wrappers varies by test base class: // - KernelTestBase supports and maintains stream wrappers in a custom // way. // - WebTestBase re-initializes Drupal stream wrappers after installation. // The original stream wrappers are restored after the test run. // @see TestBase::restoreEnvironment() $this->originalContainer->get('stream_wrapper_manager')->unregister(); // Reset statics. drupal_static_reset(); // Ensure there is no service container. $this->container = NULL; \Drupal::unsetContainer(); // Unset globals. unset($GLOBALS['config_directories']); unset($GLOBALS['config']); unset($GLOBALS['conf']); // Log fatal errors. ini_set('log_errors', 1); ini_set('error_log', DRUPAL_ROOT . '/' . $this->siteDirectory . '/error.log'); // Change the database prefix. $this->changeDatabasePrefix(); // After preparing the environment and changing the database prefix, we are // in a valid test environment. drupal_valid_test_ua($this->databasePrefix); // Reset settings. new Settings(array('hash_salt' => $this->databasePrefix, 'container_yamls' => [])); drupal_set_time_limit($this->timeLimit); }
/** * {@inheritdoc} */ public function run() { // Allow execution to continue even if the request gets cancelled. @ignore_user_abort(TRUE); // Force the current user to anonymous to ensure consistent permissions on // cron runs. $this->accountSwitcher->switchTo(new AnonymousUserSession()); // Try to allocate enough time to run all the hook_cron implementations. drupal_set_time_limit(240); $return = FALSE; // Try to acquire cron lock. if (!$this->lock->acquire('cron', 900.0)) { // Cron is still running normally. $this->logger->warning('Attempting to re-run cron while it is already running.'); } else { $this->invokeCronHandlers(); $this->setCronLastTime(); // Release cron lock. $this->lock->release('cron'); // Return TRUE so other functions can check if it did run successfully $return = TRUE; } // Process cron queues. $this->processQueues(); // Restore the user. $this->accountSwitcher->switchBack(); return $return; }
/** * Determine when to run against remote environment. */ protected function setUp() { // // BEGIN: Excerpt from DrupalUnitTestCase. // global $conf; // // Set to that verbose mode works properly. $this->originalFileDirectory = variable_get('file_public_path', conf_path() . '/files'); // // spl_autoload_register('db_autoload'); // // // Reset all statics so that test is performed with a clean environment. // 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) . '}'); // $conf['file_public_path'] = $this->originalFileDirectory . '/' . $this->databasePrefix; // // 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']); // // // Set user agent to be consistent with web test case. // $_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); // } // // END: Excerpt from DrupalUnitTestCase. if (!$this->remoteUrl && !($this->remoteUrl = variable_get('simpletest_remote_url', FALSE))) { $this->remoteUrl = url('', array('absolute' => TRUE)); } // Point the internal browser to the staging site. foreach (self::$URL_VARIABLES as $variable) { $this->originalUrls[$variable] = $GLOBALS[$variable]; $GLOBALS[$variable] = $this->remoteUrl; } $GLOBALS['base_secure_url'] = str_replace('http://', 'https://', $GLOBALS['base_secure_url']); // Generate unique remote prefix. self::$REMOTE_PREFIX = 'test' . mt_rand(100, 100000); // Set the time-limit for the test case. drupal_set_time_limit($this->timeLimit); }
/** * Launcher. */ public function launch($job) { $lock_id = $job->lock(); if (!$lock_id) { return FALSE; } if ($this->currentThread) { $init_message = t('Launched in thread @current_thread', array('@current_thread' => $this->currentThread)); } else { $init_message = t('Launched manually'); } $log_entry = $job->startLog($lock_id, $init_message); drupal_set_message(t('@name: @init_message', array('@name' => $job->name, '@init_message' => $init_message))); $class = _ultimate_cron_get_class('lock'); try { // Allocate time for the job's lock if necessary. $settings = $job->getSettings($this->type); $lock_timeout = drupal_set_time_limit($settings['lock_timeout']); // Relock cron thread with proper timeout. if ($this->currentThreadLockId) { $class::reLock($this->currentThreadLockId, $settings['lock_timeout']); } // Run job. $job->run(); } catch (Exception $e) { watchdog('serial_launcher', 'Error executing %job: @error', array('%job' => $job->name, '@error' => (string) $e), WATCHDOG_ERROR); $log_entry->finish(); $job->unlock($lock_id); return FALSE; } $log_entry->finish(); $job->unlock($lock_id); return TRUE; }
/** * Generates a random database prefix, runs the install scripts on the * prefixed database and enable the specified modules. After installation * many caches are flushed and the internal browser is setup so that the * page requests will run on the new prefix. A temporary files directory * is created with the same name as the database prefix. * * @param ... * List of modules to enable for the duration of the test. This can be * either a single array or a variable number of string arguments. */ protected function setUp() { global $user, $language, $conf; // Generate a temporary prefixed database to ensure that tests have a clean starting point. $this->databasePrefix = 'simpletest' . mt_rand(1000, 1000000); db_update('simpletest_test_id')->fields(array('last_prefix' => $this->databasePrefix))->condition('test_id', $this->testId)->execute(); // 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']); // Store necessary current values before switching to prefixed database. $this->originalLanguage = $language; $this->originalLanguageDefault = variable_get('language_default'); $this->originalFileDirectory = file_directory_path(); $this->originalProfile = drupal_get_profile(); $clean_url_original = variable_get('clean_url', 0); // Save and clean shutdown callbacks array because it static cached and // will be changed by the test run. If we don't, then it will contain // callbacks from both environments. So testing environment will try // to call handlers from original environment. $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. $public_files_directory = $this->originalFileDirectory . '/simpletest/' . substr($this->databasePrefix, 10); $private_files_directory = $public_files_directory . '/private'; $temp_files_directory = $private_files_directory . '/temp'; // Create the directories file_prepare_directory($public_files_directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS); file_prepare_directory($private_files_directory, FILE_CREATE_DIRECTORY); file_prepare_directory($temp_files_directory, FILE_CREATE_DIRECTORY); $this->generatedTestFiles = FALSE; // Log fatal errors. ini_set('log_errors', 1); ini_set('error_log', $public_files_directory . '/error.log'); // Reset all statics and variables to perform tests in a clean environment. $conf = array(); drupal_static_reset(); // 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; include_once DRUPAL_ROOT . '/includes/install.inc'; drupal_install_system(); $this->preloadRegistry(); // Set path variables. variable_set('file_public_path', $public_files_directory); variable_set('file_private_path', $private_files_directory); variable_set('file_temporary_path', $temp_files_directory); // Include the default profile. variable_set('install_profile', 'standard'); $profile_details = install_profile_info('standard', 'en'); // Install the modules specified by the default profile. module_enable($profile_details['dependencies'], FALSE); // Install modules needed for this test. This could have been passed in as // either a single array argument or a variable number of string arguments. // @todo Remove this compatibility layer in Drupal 8, and only accept // $modules as a single array argument. $modules = func_get_args(); if (isset($modules[0]) && is_array($modules[0])) { $modules = $modules[0]; } if ($modules) { module_enable($modules, TRUE); } // Run default profile tasks. module_enable(array('standard'), FALSE); // Rebuild caches. drupal_static_reset(); drupal_flush_all_caches(); // Register actions declared by any modules. actions_synchronize(); // Reload global $conf array and permissions. $this->refreshVariables(); $this->checkPermissions(array(), TRUE); // Reset statically cached schema for new database prefix. drupal_get_schema(NULL, TRUE); // Run cron once in that environment, as install.php does at the end of // the installation process. drupal_cron_run(); // Log in with a clean $user. $this->originalUser = $user; drupal_save_session(FALSE); $user = user_load(1); // Restore necessary variables. variable_set('install_task', 'done'); variable_set('clean_url', $clean_url_original); variable_set('site_mail', '*****@*****.**'); variable_set('date_default_timezone', date_default_timezone_get()); // Set up English language. unset($GLOBALS['conf']['language_default']); $language = language_default(); // Use the test mail class instead of the default mail handler class. variable_set('mail_system', array('default-system' => 'TestingMailSystem')); drupal_set_time_limit($this->timeLimit); }
/** * Generates a random database prefix, runs the install scripts on the * prefixed database and enable the specified modules. After installation * many caches are flushed and the internal browser is setup so that the * page requests will run on the new prefix. A temporary files directory * is created with the same name as the database prefix. * * @param ... * List of modules to enable for the duration of the test. */ function setUp() { global $db_prefix, $user, $language; // $language (Drupal 6). global $install_locale; // Store necessary current values before switching to prefixed database. $this->db_prefix_original = $db_prefix; $clean_url_original = variable_get('clean_url', 0); // Generate temporary prefixed database to ensure that tests have a clean starting point. $db_prefix = 'simpletest' . mt_rand(1000, 1000000); include_once './includes/install.inc'; drupal_install_system(); // Add the specified modules to the list of modules in the default profile. $args = func_get_args(); // Add language and basic i18n modules $install_locale = $this->install_locale; $i18n_modules = array('locale', 'translation', 'i18n', 'i18n_test'); $modules = array_unique(array_merge(drupal_verify_profile('default', $this->install_locale), $args, $i18n_modules)); drupal_install_modules($modules); // Install locale if ($this->install_locale != 'en') { $this->addLanguage($this->install_locale, TRUE); } // Run default profile tasks. $task = 'profile'; default_profile_tasks($task, ''); // Rebuild caches. actions_synchronize(); _drupal_flush_css_js(); $this->refreshVariables(); $this->checkPermissions(array(), TRUE); user_access(NULL, NULL, TRUE); // Drupal 6. // Log in with a clean $user. $this->originalUser = $user; // drupal_save_session(FALSE); // $user = user_load(1); session_save_session(FALSE); $user = user_load(1); // Restore necessary variables. variable_set('install_profile', 'default'); variable_set('install_task', 'profile-finished'); variable_set('clean_url', $clean_url_original); variable_set('site_mail', '*****@*****.**'); // Use temporary files directory with the same prefix as database. $this->originalFileDirectory = file_directory_path(); variable_set('file_directory_path', file_directory_path() . '/' . $db_prefix); $directory = file_directory_path(); // Create the files directory. file_check_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS); drupal_set_time_limit($this->timeLimit); // Some more includes require_once 'includes/language.inc'; // Refresh theme $this->initTheme(); // Set path languages so we can retrieve pages in different languages variable_set('language_negotiation', LANGUAGE_NEGOTIATION_PATH); }
/** * Don't create test db via install, instead copy existing db. */ protected function setUp() { // Copy of parent::setUp(); global $user, $language, $conf; // Generate a temporary prefixed database to ensure that tests have a clean starting point. $this->databasePrefix = 'simpletest' . mt_rand(1000, 1000000); db_update('simpletest_test_id')->fields(array('last_prefix' => $this->databasePrefix))->condition('test_id', $this->testId)->execute(); // Store necessary current values before switching to prefixed database. $this->originalLanguage = $language; $this->originalLanguageDefault = variable_get('language_default'); $this->originalFileDirectory = variable_get('file_public_path', conf_path() . '/files'); $this->originalProfile = drupal_get_profile(); $clean_url_original = variable_get('clean_url', 0); // Save and clean shutdown callbacks array because it static cached and // will be changed by the test run. If we don't, then it will contain // callbacks from both environments. So testing environment will try // to call handlers from original environment. $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; // 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; // Rebuild schema based on prefixed database and such. $schemas = drupal_get_schema(NULL, TRUE); // Create a list of prefixed source table names. $sources = array(); foreach ($schemas as $name => $schema) { $sources[$name] = Database::getConnection()->prefixTables('{' . $name . '}'); } // 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']); // Clone each table into the new database. foreach ($schemas as $name => $schema) { $this->cloneTable($name, $sources[$name], $schema); } // Log in with a clean $user. $this->originalUser = $user; drupal_save_session(FALSE); $user = user_load(1); // Set up English language. unset($GLOBALS['conf']['language_default']); $language = language_default(); // Use the test mail class instead of the default mail handler class. variable_set('mail_system', array('default-system' => 'TestingMailSystem')); drupal_set_time_limit($this->timeLimit); $this->resetAll(); $this->refreshVariables(); $this->setup = TRUE; }
/** * Sends the file's binary data to a user via HTTP and updates the database. * * @param $file_user * The file_user object from the uc_file_users. * @param $ip * The string containing the IP address the download is going to. */ protected function transferDownload($file_user, $ip) { // Create the response. $response = new BinaryFileResponse(); // Check if any hook_uc_file_transfer_alter() calls alter the download. $module_handler = $this->moduleHandler(); foreach ($module_handler->getImplementations('uc_file_transfer_alter') as $module) { $name = $module . '_uc_file_transfer_alter'; $file_user->full_path = $name($file_user, $ip, $file_user->fid, $file_user->full_path); } // This could get clobbered, so make a copy. $filename = $file_user->filename; // Gather relevant info about the file. $size = filesize($file_user->full_path); $mimetype = file_get_mimetype($filename); // Workaround for IE filename bug with multiple periods / multiple dots // in filename that adds square brackets to filename - // eg. setup.abc.exe becomes setup[1].abc.exe if (strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE')) { $filename = preg_replace('/\\./', '%2e', $filename, substr_count($filename, '.') - 1); } // Check if HTTP_RANGE is sent by browser (or download manager). $range = NULL; if (isset($_SERVER['HTTP_RANGE'])) { if (substr($_SERVER['HTTP_RANGE'], 0, 6) == 'bytes=') { // Multiple ranges could be specified at the same time, // but for simplicity only serve the first range // See http://tools.ietf.org/id/draft-ietf-http-range-retrieval-00.txt list($range, $extra_ranges) = explode(',', substr($_SERVER['HTTP_RANGE'], 6), 2); } else { $response->headers->set('Status', '416 Requested Range Not Satisfiable'); $response->headers->set('Content-Range', 'bytes */' . $size); return $response; } } // Figure out download piece from range (if set). if (isset($range)) { list($seek_start, $seek_end) = explode('-', $range, 2); } // Set start and end based on range (if set), // else set defaults and check for invalid ranges. $seek_end = intval(empty($seek_end) ? $size - 1 : min(abs(intval($seek_end)), $size - 1)); $seek_start = intval(empty($seek_start) || $seek_end < abs(intval($seek_start)) ? 0 : max(abs(intval($seek_start)), 0)); // Only send partial content header if downloading a piece of the file (IE // workaround). if ($seek_start > 0 || $seek_end < $size - 1) { $response->headers->set('Status', '206 Partial Content'); } // Standard headers, including content-range and length $response->headers->set('Pragma', 'public'); $response->headers->set('Cache-Control', 'cache, must-revalidate'); $response->headers->set('Accept-Ranges', 'bytes'); $response->headers->set('Content-Range', 'bytes ' . $seek_start . '-' . $seek_end . '/' . $size); $response->headers->set('Content-Type', $mimetype); $response->headers->set('Content-Disposition', 'attachment; filename="' . $filename . '"'); $response->headers->set('Content-Length', $seek_end - $seek_start + 1); // Last-Modified is required for content served dynamically. $response->headers->set('Last-Modified', gmdate("D, d M Y H:i:s", filemtime($file_user->full_path)) . " GMT"); // Etag header is required for Firefox3 and other managers. $response->headers->set('ETag', md5($file_user->full_path)); // Open the file and seek to starting byte. $fp = fopen($file_user->full_path, 'rb'); fseek($fp, $seek_start); // Start buffered download. while (!feof($fp)) { // Reset time limit for large files. drupal_set_time_limit(0); // Push the data to the client. print fread($fp, UC_FILE_BYTE_SIZE); flush(); // Suppress PHP notice that occurs when output buffering isn't enabled. // The ob_flush() is needed because if output buffering *is* enabled, // clicking on the file download link won't download anything if the buffer // isn't flushed. @ob_flush(); } // Finished serving the file, close the stream and log the download // to the user table. fclose($fp); $this->logDownload($file_user, $ip); }
/** * {@inheritdoc} */ public function run() { // Allow execution to continue even if the request gets cancelled. @ignore_user_abort(TRUE); // Prevent session information from being saved while cron is running. $original_session_saving = $this->sessionManager->isEnabled(); $this->sessionManager->disable(); // Force the current user to anonymous to ensure consistent permissions on // cron runs. $original_user = $this->currentUser->getAccount(); $this->currentUser->setAccount(new AnonymousUserSession()); // Try to allocate enough time to run all the hook_cron implementations. drupal_set_time_limit(240); $return = FALSE; // Try to acquire cron lock. if (!$this->lock->acquire('cron', 240.0)) { // Cron is still running normally. watchdog('cron', 'Attempting to re-run cron while it is already running.', array(), WATCHDOG_WARNING); } else { $this->invokeCronHandlers(); $this->setCronLastTime(); // Release cron lock. $this->lock->release('cron'); // Return TRUE so other functions can check if it did run successfully $return = TRUE; } // Process cron queues. $this->processQueues(); // Restore the user. $this->currentUser->setAccount($original_user); if ($original_session_saving) { $this->sessionManager->enable(); } return $return; }