Update to Drupal 8.2.0. For more information, see https://www.drupal.org/project/drupal/releases/8.2.0

This commit is contained in:
Pantheon Automation 2016-10-06 15:16:20 -07:00 committed by Greg Anderson
parent 2f563ab520
commit f1c8716f57
1732 changed files with 52334 additions and 11780 deletions

View file

@ -18,9 +18,19 @@ const SIMPLETEST_MINIMUM_PHP_MEMORY_LIMIT = '128M';
function simpletest_requirements($phase) {
$requirements = array();
$has_phpunit = class_exists('\PHPUnit_Framework_TestCase');
$has_curl = function_exists('curl_init');
$open_basedir = ini_get('open_basedir');
$requirements['phpunit'] = array(
'title' => t('PHPUnit dependency'),
'value' => $has_phpunit ? t('Found') : t('Not found'),
);
if (!$has_phpunit) {
$requirements['phpunit']['severity'] = REQUIREMENT_ERROR;
$requirements['phpunit']['description'] = t("The testing framework requires the PHPUnit package. Please run 'composer install --dev' to ensure it is present.");
}
$requirements['curl'] = array(
'title' => t('cURL'),
'value' => $has_curl ? t('Enabled') : t('Not found'),

View file

@ -181,7 +181,7 @@ function simpletest_run_tests($test_list) {
*/
function simpletest_run_phpunit_tests($test_id, array $unescaped_test_classnames, &$status = NULL) {
$phpunit_file = simpletest_phpunit_xml_filepath($test_id);
simpletest_phpunit_run_command($unescaped_test_classnames, $phpunit_file, $status);
simpletest_phpunit_run_command($unescaped_test_classnames, $phpunit_file, $status, $output);
$rows = simpletest_phpunit_xml_to_rows($test_id, $phpunit_file);
// A $status of 0 = passed test, 1 = failed test, > 1 indicates segfault
@ -193,13 +193,27 @@ function simpletest_run_phpunit_tests($test_id, array $unescaped_test_classnames
'test_id' => $test_id,
'test_class' => implode(",", $unescaped_test_classnames),
'status' => 'fail',
'message' => 'PHPunit Test failed to complete',
'message' => 'PHPunit Test failed to complete; Error: ' . implode("\n", $output),
'message_group' => 'Other',
'function' => implode(",", $unescaped_test_classnames),
'line' => '0',
'file' => $phpunit_file,
];
}
if ($status === 1) {
$rows[] = [
'test_id' => $test_id,
'test_class' => implode(",", $unescaped_test_classnames),
'status' => 'fail',
'message' => 'PHPunit Test failed to complete; Error: ' . implode("\n", $output),
'message_group' => 'Other',
'function' => implode(",", $unescaped_test_classnames),
'line' => '0',
'file' => $phpunit_file,
];
}
return $rows;
}
@ -299,11 +313,13 @@ function simpletest_phpunit_configuration_filepath() {
* @param int $status
* (optional) The exit status code of the PHPUnit process will be assigned to
* this variable.
* @param string $output
* (optional) The output by running the phpunit command.
*
* @return string
* The results as returned by exec().
*/
function simpletest_phpunit_run_command(array $unescaped_test_classnames, $phpunit_file, &$status = NULL) {
function simpletest_phpunit_run_command(array $unescaped_test_classnames, $phpunit_file, &$status = NULL, &$output = NULL) {
global $base_url;
// Setup an environment variable containing the database connection so that
// functional tests can connect to the database.
@ -519,7 +535,8 @@ function simpletest_last_test_get($test_id) {
* Whether any fatal errors were found.
*/
function simpletest_log_read($test_id, $database_prefix, $test_class) {
$log = DRUPAL_ROOT . '/sites/simpletest/' . substr($database_prefix, 10) . '/error.log';
$test_db = new TestDatabase($database_prefix);
$log = DRUPAL_ROOT . '/' . $test_db->getTestSitePath() . '/error.log';
$found = FALSE;
if (file_exists($log)) {
foreach (file($log) as $line) {
@ -649,13 +666,12 @@ function simpletest_clean_environment() {
* Removes prefixed tables from the database from crashed tests.
*/
function simpletest_clean_database() {
$tables = db_find_tables(Database::getConnection()->prefixTables('{simpletest}') . '%');
$schema = drupal_get_module_schema('simpletest');
$tables = db_find_tables('test%');
$count = 0;
foreach (array_diff_key($tables, $schema) as $table) {
// Strip the prefix and skip tables without digits following "simpletest",
// e.g. {simpletest_test_id}.
if (preg_match('/simpletest\d+.*/', $table, $matches)) {
foreach ($tables as $table) {
// Only drop tables which begin wih 'test' followed by digits, for example,
// {test12345678node__body}.
if (preg_match('/^test\d+.*/', $table, $matches)) {
db_drop_table($matches[0]);
$count++;
}

View file

@ -117,7 +117,7 @@ trait AssertContentTrait {
/**
* Parse content returned from curlExec using DOM and SimpleXML.
*
* @return \SimpleXMLElement|FALSE
* @return \SimpleXMLElement|false
* A SimpleXMLElement or FALSE on failure.
*/
protected function parse() {

View file

@ -29,7 +29,7 @@ use Symfony\Component\HttpFoundation\Request;
* Additional modules needed in a test may be loaded and added to the fixed
* module list.
*
* @deprecated in Drupal 8.0.x, will be removed before Drupal 8.2.x. Use
* @deprecated in Drupal 8.0.x, will be removed before Drupal 9.0.0. Use
* \Drupal\KernelTests\KernelTestBase instead.
*
* @see \Drupal\simpletest\KernelTestBase::$modules

View file

@ -7,13 +7,11 @@ use Drupal\Component\Render\MarkupInterface;
use Drupal\Component\Utility\Crypt;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Database\Database;
use Drupal\Core\Config\ConfigImporter;
use Drupal\Core\Config\StorageComparer;
use Drupal\Core\Config\StorageInterface;
use Drupal\Core\Site\Settings;
use Drupal\Core\StreamWrapper\PublicStream;
use Drupal\Core\Test\TestDatabase;
use Drupal\Core\Utility\Error;
use Drupal\Tests\ConfigTestTrait;
use Drupal\Tests\RandomGeneratorTrait;
use Drupal\Tests\SessionTestTrait;
@ -27,6 +25,11 @@ abstract class TestBase {
use SessionTestTrait;
use RandomGeneratorTrait;
use AssertHelperTrait;
// For backwards compatibility switch the visbility of the methods to public.
use ConfigTestTrait {
configImporter as public;
copyConfig as public;
}
/**
* The test run ID.
@ -524,7 +527,7 @@ abstract class TestBase {
// The first element is the call. The second element is the caller.
// We skip calls that occurred in one of the methods of our base classes
// or in an assertion function.
while (($caller = $backtrace[1]) &&
while (($caller = $backtrace[1]) &&
((isset($caller['class']) && isset($this->skipClasses[$caller['class']])) ||
substr($caller['function'], 0, 6) == 'assert')) {
// We remove that call.
@ -1105,14 +1108,9 @@ abstract class TestBase {
* @see drupal_valid_test_ua()
*/
private function prepareDatabasePrefix() {
// Ensure that the generated test site directory does not exist already,
// which may happen with a large amount of concurrent threads and
// long-running tests.
do {
$suffix = mt_rand(100000, 999999);
$this->siteDirectory = 'sites/simpletest/' . $suffix;
$this->databasePrefix = 'simpletest' . $suffix;
} while (is_dir(DRUPAL_ROOT . '/' . $this->siteDirectory));
$test_db = new TestDatabase();
$this->siteDirectory = $test_db->getTestSitePath();
$this->databasePrefix = $test_db->getDatabasePrefix();
// 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
@ -1537,51 +1535,6 @@ abstract class TestBase {
chmod($path, 0700);
}
/**
* Returns a ConfigImporter object to import test importing of configuration.
*
* @return \Drupal\Core\Config\ConfigImporter
* The ConfigImporter object.
*/
public function configImporter() {
if (!$this->configImporter) {
// Set up the ConfigImporter object for testing.
$storage_comparer = new StorageComparer(
$this->container->get('config.storage.sync'),
$this->container->get('config.storage'),
$this->container->get('config.manager')
);
$this->configImporter = new ConfigImporter(
$storage_comparer,
$this->container->get('event_dispatcher'),
$this->container->get('config.manager'),
$this->container->get('lock'),
$this->container->get('config.typed'),
$this->container->get('module_handler'),
$this->container->get('module_installer'),
$this->container->get('theme_handler'),
$this->container->get('string_translation')
);
}
// Always recalculate the changelist when called.
return $this->configImporter->reset();
}
/**
* Copies configuration objects from source storage to target storage.
*
* @param \Drupal\Core\Config\StorageInterface $source_storage
* The source config storage service.
* @param \Drupal\Core\Config\StorageInterface $target_storage
* The target config storage service.
*/
public function copyConfig(StorageInterface $source_storage, StorageInterface $target_storage) {
$target_storage->deleteAll();
foreach ($source_storage->listAll() as $name) {
$target_storage->write($name, $source_storage->read($name));
}
}
/**
* Configuration accessor for tests. Returns non-overridden configuration.
*

View file

@ -89,7 +89,7 @@ class SimpleTestBrowserTest extends WebTestBase {
$HTTP_path = $system_path . '/tests/http.php/user/login';
$https_path = $system_path . '/tests/https.php/user/login';
// Generate a valid simpletest User-Agent to pass validation.
$this->assertTrue(preg_match('/simpletest\d+/', $this->databasePrefix, $matches), 'Database prefix contains simpletest prefix.');
$this->assertTrue(preg_match('/test\d+/', $this->databasePrefix, $matches), 'Database prefix contains test prefix.');
$test_ua = drupal_generate_test_ua($matches[0]);
$this->additionalCurlOptions = array(CURLOPT_USERAGENT => $test_ua);
@ -131,7 +131,7 @@ class SimpleTestBrowserTest extends WebTestBase {
// A PHPUnit unit test.
'Drupal\Tests\action\Unit\Menu\ActionLocalTasksTest',
// A PHPUnit functional test.
'Drupal\Tests\simpletest\Functional\BrowserTestBaseTest',
'Drupal\FunctionalTests\BrowserTestBaseTest',
);
foreach ($tests as $test) {

View file

@ -2,6 +2,7 @@
namespace Drupal\simpletest\Tests;
use Drupal\entity_test\Entity\EntityTest;
use Drupal\simpletest\WebTestBase;
/**
@ -25,9 +26,9 @@ class SimpleTestInstallBatchTest extends WebTestBase {
* Tests loading entities created in a batch in simpletest_test_install().
*/
public function testLoadingEntitiesCreatedInBatch() {
$entity1 = entity_load('entity_test', 1);
$entity1 = EntityTest::load(1);
$this->assertNotNull($entity1, 'Successfully loaded entity 1.');
$entity2 = entity_load('entity_test', 2);
$entity2 = EntityTest::load(2);
$this->assertNotNull($entity2, 'Successfully loaded entity 2.');
}

View file

@ -3,6 +3,7 @@
namespace Drupal\simpletest\Tests;
use Drupal\Component\Utility\Crypt;
use Drupal\Core\Test\TestDatabase;
use Drupal\simpletest\WebTestBase;
/**
@ -154,7 +155,8 @@ EOD;
// test in a test since the prefix has changed.
// @see \Drupal\Core\Test\HttpClientMiddleware\TestHttpClientMiddleware::onBeforeSendRequest()
// @see drupal_generate_test_ua();
$key_file = DRUPAL_ROOT . '/sites/simpletest/' . substr($this->databasePrefix, 10) . '/.htkey';
$test_db = new TestDatabase($this->databasePrefix);
$key_file = DRUPAL_ROOT . '/' . $test_db->getTestSitePath() . '/.htkey';
$private_key = Crypt::randomBytesBase64(55);
$site_path = $this->container->get('site.path');
file_put_contents($key_file, $private_key);

View file

@ -5,7 +5,6 @@ namespace Drupal\simpletest;
use Drupal\block\Entity\Block;
use Drupal\Component\FileCache\FileCacheFactory;
use Drupal\Component\Serialization\Json;
use Drupal\Component\Serialization\Yaml;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\NestedArray;
use Drupal\Component\Utility\UrlHelper;
@ -18,13 +17,15 @@ use Drupal\Core\EventSubscriber\AjaxResponseSubscriber;
use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
use Drupal\Core\Extension\MissingDependencyException;
use Drupal\Core\Render\Element;
use Drupal\Core\Serialization\Yaml;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Session\AnonymousUserSession;
use Drupal\Core\Session\UserSession;
use Drupal\Core\Site\Settings;
use Drupal\Core\StreamWrapper\PublicStream;
use Drupal\Core\Test\AssertMailTrait;
use Drupal\Core\Url;
use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
use Drupal\Tests\TestFileCreationTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Yaml\Yaml as SymfonyYaml;
@ -38,6 +39,11 @@ use Zend\Diactoros\Uri;
abstract class WebTestBase extends TestBase {
use AssertContentTrait;
use TestFileCreationTrait {
getTestFiles as drupalGetTestFiles;
compareFiles as drupalCompareFiles;
}
use AssertPageCacheContextsAndTagsTrait;
use BlockCreationTrait {
placeBlock as drupalPlaceBlock;
}
@ -166,11 +172,6 @@ abstract class WebTestBase extends TestBase {
*/
protected $sessionId = NULL;
/**
* Whether the files were copied to the test files directory.
*/
protected $generatedTestFiles = FALSE;
/**
* The maximum number of redirects to follow when handling responses.
*/
@ -331,99 +332,6 @@ abstract class WebTestBase extends TestBase {
return $this->xpath('//div[@id = :id]', array(':id' => 'block-' . $block->id()));
}
/**
* Gets a list of files that can be used in tests.
*
* The first time this method is called, it will call
* simpletest_generate_file() to generate binary and ASCII text files in the
* public:// directory. It will also copy all files in
* core/modules/simpletest/files to public://. These contain image, SQL, PHP,
* JavaScript, and HTML files.
*
* All filenames are prefixed with their type and have appropriate extensions:
* - text-*.txt
* - binary-*.txt
* - html-*.html and html-*.txt
* - image-*.png, image-*.jpg, and image-*.gif
* - javascript-*.txt and javascript-*.script
* - php-*.txt and php-*.php
* - sql-*.txt and sql-*.sql
*
* Any subsequent calls will not generate any new files, or copy the files
* over again. However, if a test class adds a new file to public:// that
* is prefixed with one of the above types, it will get returned as well, even
* on subsequent calls.
*
* @param $type
* File type, possible values: 'binary', 'html', 'image', 'javascript',
* 'php', 'sql', 'text'.
* @param $size
* (optional) File size in bytes to match. Defaults to NULL, which will not
* filter the returned list by size.
*
* @return
* List of files in public:// that match the filter(s).
*/
protected function drupalGetTestFiles($type, $size = NULL) {
if (empty($this->generatedTestFiles)) {
// Generate binary test files.
$lines = array(64, 1024);
$count = 0;
foreach ($lines as $line) {
simpletest_generate_file('binary-' . $count++, 64, $line, 'binary');
}
// Generate ASCII text test files.
$lines = array(16, 256, 1024, 2048, 20480);
$count = 0;
foreach ($lines as $line) {
simpletest_generate_file('text-' . $count++, 64, $line, 'text');
}
// Copy other test files from simpletest.
$original = drupal_get_path('module', 'simpletest') . '/files';
$files = file_scan_directory($original, '/(html|image|javascript|php|sql)-.*/');
foreach ($files as $file) {
file_unmanaged_copy($file->uri, PublicStream::basePath());
}
$this->generatedTestFiles = TRUE;
}
$files = array();
// Make sure type is valid.
if (in_array($type, array('binary', 'html', 'image', 'javascript', 'php', 'sql', 'text'))) {
$files = file_scan_directory('public://', '/' . $type . '\-.*/');
// If size is set then remove any files that are not of that size.
if ($size !== NULL) {
foreach ($files as $file) {
$stats = stat($file->uri);
if ($stats['size'] != $size) {
unset($files[$file->uri]);
}
}
}
}
usort($files, array($this, 'drupalCompareFiles'));
return $files;
}
/**
* Compare two files based on size and file name.
*/
protected function drupalCompareFiles($file1, $file2) {
$compare_size = filesize($file1->uri) - filesize($file2->uri);
if ($compare_size) {
// Sort by file size.
return $compare_size;
}
else {
// The files were the same size, so sort alphabetically.
return strnatcmp($file1->name, $file2->name);
}
}
/**
* Log in a user with the internal browser.
*
@ -1160,9 +1068,7 @@ abstract class WebTestBase extends TestBase {
}
// We set the user agent header on each request so as to use the current
// time and a new uniqid.
if (preg_match('/simpletest\d+/', $this->databasePrefix, $matches)) {
curl_setopt($this->curlHandle, CURLOPT_USERAGENT, drupal_generate_test_ua($matches[0]));
}
curl_setopt($this->curlHandle, CURLOPT_USERAGENT, drupal_generate_test_ua($this->databasePrefix));
}
/**
@ -2707,28 +2613,6 @@ abstract class WebTestBase extends TestBase {
}
}
/**
* Asserts whether an expected cache context was present in the last response.
*
* @param string $expected_cache_context
* The expected cache context.
*/
protected function assertCacheContext($expected_cache_context) {
$cache_contexts = explode(' ', $this->drupalGetHeader('X-Drupal-Cache-Contexts'));
$this->assertTrue(in_array($expected_cache_context, $cache_contexts), "'" . $expected_cache_context . "' is present in the X-Drupal-Cache-Contexts header.");
}
/**
* Asserts that a cache context was not present in the last response.
*
* @param string $not_expected_cache_context
* The expected cache context.
*/
protected function assertNoCacheContext($not_expected_cache_context) {
$cache_contexts = explode(' ', $this->drupalGetHeader('X-Drupal-Cache-Contexts'));
$this->assertFalse(in_array($not_expected_cache_context, $cache_contexts), "'" . $not_expected_cache_context . "' is not present in the X-Drupal-Cache-Contexts header.");
}
/**
* Asserts whether an expected cache tag was present in the last response.
*

View file

@ -1,82 +0,0 @@
<?php
namespace Drupal\Tests\simpletest\Functional;
use Drupal\Core\Url;
use Drupal\Tests\BrowserTestBase;
/**
* Tests BrowserTestBase functionality.
*
* @group simpletest
*/
class BrowserTestBaseTest extends BrowserTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = array('test_page_test', 'form_test');
/**
* Tests basic page test.
*/
public function testGoTo() {
$account = $this->drupalCreateUser();
$this->drupalLogin($account);
// Visit a Drupal page that requires login.
$this->drupalGet('test-page');
$this->assertSession()->statusCodeEquals(200);
// Test page contains some text.
$this->assertSession()->pageTextContains('Test page text.');
// Check that returned plain text is correct.
$text = $this->getTextContent();
$this->assertContains('Test page text.', $text);
$this->assertNotContains('</html>', $text);
// Response includes cache tags that we can assert.
$this->assertSession()->responseHeaderEquals('X-Drupal-Cache-Tags', 'rendered');
// Test that we can read the JS settings.
$js_settings = $this->getDrupalSettings();
$this->assertSame('azAZ09();.,\\\/-_{}', $js_settings['test-setting']);
// Test drupalGet with a url object.
$url = Url::fromRoute('test_page_test.render_title');
$this->drupalGet($url);
$this->assertSession()->statusCodeEquals(200);
// Test page contains some text.
$this->assertSession()->pageTextContains('Hello Drupal');
}
/**
* Tests basic form functionality.
*/
public function testForm() {
// Ensure the proper response code for a _form route.
$this->drupalGet('form-test/object-builder');
$this->assertSession()->statusCodeEquals(200);
// Ensure the form and text field exist.
$this->assertSession()->elementExists('css', 'form#form-test-form-test-object');
$this->assertSession()->fieldExists('bananas');
$edit = ['bananas' => 'green'];
$this->submitForm($edit, 'Save', 'form-test-form-test-object');
$config_factory = $this->container->get('config.factory');
$value = $config_factory->get('form_test.object')->get('bananas');
$this->assertSame('green', $value);
}
public function testError() {
$this->setExpectedException('\Exception', 'User notice: foo');
$this->drupalGet('test-error');
}
}

View file

@ -5,7 +5,7 @@
* Contains \Drupal\Tests\simpletest\Unit\TestInfoParsingTest.
*/
namespace Drupal\Tests\simpletest\Unit {
namespace Drupal\Tests\simpletest\Unit;
use Composer\Autoload\ClassLoader;
use Drupal\Core\Extension\Extension;
@ -60,13 +60,13 @@ class TestInfoParsingTest extends UnitTestCase {
$tests[] = [
// Expected result.
[
'name' => 'Drupal\Tests\simpletest\Functional\BrowserTestBaseTest',
'group' => 'simpletest',
'name' => 'Drupal\FunctionalTests\BrowserTestBaseTest',
'group' => 'browsertestbase',
'description' => 'Tests BrowserTestBase functionality.',
'type' => 'PHPUnit-Functional',
],
// Classname.
'Drupal\Tests\simpletest\Functional\BrowserTestBaseTest',
'Drupal\FunctionalTests\BrowserTestBaseTest',
];
// kernel PHPUnit test.
@ -400,7 +400,7 @@ class TestTestDiscovery extends TestDiscovery {
$data['simpletest-kerneltest'] = ['\Drupal\hal\Tests\FileNormalizeTest', FALSE];
$data['module-unittest'] = [static::class, 'Unit'];
$data['module-kerneltest'] = ['\Drupal\KernelTests\Core\Theme\TwigMarkupInterfaceTest', 'Kernel'];
$data['module-functionaltest'] = ['\Drupal\Tests\simpletest\Functional\BrowserTestBaseTest', 'Functional'];
$data['module-functionaltest'] = ['\Drupal\FunctionalTests\BrowserTestBaseTest', 'Functional'];
$data['module-functionaljavascripttest'] = ['\Drupal\Tests\toolbar\FunctionalJavascript\ToolbarIntegrationTest', 'FunctionalJavascript'];
$data['core-unittest'] = ['\Drupal\Tests\ComposerIntegrationTest', 'Unit'];
$data['core-unittest2'] = ['Drupal\Tests\Core\DrupalTest', 'Unit'];
@ -413,9 +413,7 @@ class TestTestDiscovery extends TestDiscovery {
}
}
namespace Drupal\simpletest\Tests {
namespace Drupal\simpletest\Tests;
use Drupal\simpletest\WebTestBase;
@ -426,5 +424,3 @@ use Drupal\simpletest\WebTestBase;
*/
class ExampleSimpleTest extends WebTestBase {
}
}