From 81244e10cb0959ede7d570fc89f46a64901ba744 Mon Sep 17 00:00:00 2001 From: Christian Kuhn <lolli@schwarzbu.ch> Date: Wed, 6 Jun 2018 01:12:07 +0200 Subject: [PATCH] [TASK] Functional tests without phpunit process isolation We're finally able to manage our core internal framework state, at least in the backend. This is a huge step. To proof this, functional tests now execute without process isolation. We need a couple of additional reset state methods. Those are for now marked @internal to allow us changing this stuff if needed later. The SystemEnvironmentBuilder also needs a change to not directly rely on PATH_thisScript anymore. composer require --dev typo3/testing-framework ~4.1.0 Change-Id: I37fbee7e4cf6ccb2eec18d057b6b9671d6a85167 Resolves: #85649 Releases: master Reviewed-on: https://review.typo3.org/57129 Tested-by: TYPO3com <no-reply@typo3.com> Reviewed-by: Andreas Fernandez <a.fernandez@scripting-base.de> Tested-by: Andreas Fernandez <a.fernandez@scripting-base.de> Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl> Tested-by: Wouter Wolters <typo3@wouterwolters.nl> --- composer.json | 2 +- composer.lock | 12 ++++---- .../Classes/Core/SystemEnvironmentBuilder.php | 29 +++++++++++++++++-- .../core/Classes/Database/ConnectionPool.php | 12 ++++++++ .../core/Classes/Utility/GeneralUtility.php | 13 +++++++++ .../Cache/Backend/MemcachedBackendTest.php | 3 +- .../Cache/Backend/RedisBackendTest.php | 2 ++ typo3/sysext/core/composer.json | 2 +- 8 files changed, 63 insertions(+), 12 deletions(-) diff --git a/composer.json b/composer.json index 30e4a8987fa3..a5f5e940a8c3 100644 --- a/composer.json +++ b/composer.json @@ -66,7 +66,7 @@ "fiunchinho/phpunit-randomizer": "^4.0", "friendsofphp/php-cs-fixer": "^2.12.2", "typo3/cms-styleguide": "^9.1", - "typo3/testing-framework": "^4.0.2" + "typo3/testing-framework": "~4.1.0" }, "suggest": { "ext-gd": "GDlib/Freetype is required for building images with text (GIFBUILDER) and can also be used to scale images", diff --git a/composer.lock b/composer.lock index 47ba30809019..5e22986778ad 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a71e25c63829d22da3013a310006d675", + "content-hash": "cb674f386df7a9d87641f393120ecbac", "packages": [ { "name": "cogpowered/finediff", @@ -4722,16 +4722,16 @@ }, { "name": "typo3/testing-framework", - "version": "4.0.2", + "version": "4.1.0", "source": { "type": "git", "url": "https://github.com/TYPO3/testing-framework.git", - "reference": "dadfd1c953856429ad2a1b9ab8b8bea779e1f960" + "reference": "f3371a5cedc30ada5bc38a4d3b3d92baea1d2873" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/TYPO3/testing-framework/zipball/dadfd1c953856429ad2a1b9ab8b8bea779e1f960", - "reference": "dadfd1c953856429ad2a1b9ab8b8bea779e1f960", + "url": "https://api.github.com/repos/TYPO3/testing-framework/zipball/f3371a5cedc30ada5bc38a4d3b3d92baea1d2873", + "reference": "f3371a5cedc30ada5bc38a4d3b3d92baea1d2873", "shasum": "" }, "require": { @@ -4778,7 +4778,7 @@ "tests", "typo3" ], - "time": "2018-07-23T11:56:51+00:00" + "time": "2018-07-25T20:17:43+00:00" }, { "name": "webmozart/assert", diff --git a/typo3/sysext/core/Classes/Core/SystemEnvironmentBuilder.php b/typo3/sysext/core/Classes/Core/SystemEnvironmentBuilder.php index 2ed868d234b5..96e3e6e8df46 100644 --- a/typo3/sysext/core/Classes/Core/SystemEnvironmentBuilder.php +++ b/typo3/sysext/core/Classes/Core/SystemEnvironmentBuilder.php @@ -267,18 +267,41 @@ class SystemEnvironmentBuilder */ public static function initializeEnvironment(ApplicationContext $context) { - $sitePath = rtrim(PATH_site, '/'); + $isCli = PHP_SAPI === 'cli'; + // Absolute path of the entry script that was called + $scriptPath = PATH_thisScript; + $rootPath = rtrim(PATH_site, '/'); + if (getenv('TYPO3_PATH_ROOT')) { + $rootPath = GeneralUtility::fixWindowsFilePath(getenv('TYPO3_PATH_ROOT')); + $rootPath = rtrim($rootPath, '/'); + // Check if the root path has been set in the environment (e.g. by the composer installer) + if ($isCli && self::usesComposerClassLoading() && StringUtility::endsWith($scriptPath, 'typo3')) { + // PATH_thisScript is used for various path calculations based on the document root + // Therefore we assume it is always a subdirectory of the document root, which is not the case + // in composer mode on cli, as the binary is in the composer bin directory. + // Because of that, we enforce the document root path of this binary to be set + $scriptName = '/typo3/sysext/core/bin/typo3'; + } else { + // Base the script path on the path taken from the environment + // to make relative path calculations work in case only one of both is symlinked + // or has the real path + $scriptName = substr($scriptPath, strlen($rootPath)); + } + $scriptPath = $rootPath . $scriptName; + } + + $sitePath = rtrim($rootPath, '/'); $projectRootPath = GeneralUtility::fixWindowsFilePath(getenv('TYPO3_PATH_APP')); $isDifferentRootPath = ($projectRootPath && $projectRootPath !== $sitePath); Environment::initialize( $context, - PHP_SAPI === 'cli', + $isCli, self::usesComposerClassLoading(), $isDifferentRootPath ? $projectRootPath : $sitePath, $sitePath, $isDifferentRootPath ? $projectRootPath . '/var' : $sitePath . '/typo3temp/var', $isDifferentRootPath ? $projectRootPath . '/config' : $sitePath . '/typo3conf', - PATH_thisScript, + $scriptPath, self::getTypo3Os() === 'WIN' ? 'WINDOWS' : 'UNIX' ); } diff --git a/typo3/sysext/core/Classes/Database/ConnectionPool.php b/typo3/sysext/core/Classes/Database/ConnectionPool.php index 47e5ced106a2..5f7776634301 100644 --- a/typo3/sysext/core/Classes/Database/ConnectionPool.php +++ b/typo3/sysext/core/Classes/Database/ConnectionPool.php @@ -235,4 +235,16 @@ class ConnectionPool { return $this->customDoctrineTypes; } + + /** + * Reset internal list of connections. This is an internal method (for now) + * currently used in functional tests only to close connections and start + * new ones in between single tests. + * + * @internal May be changed or removed any point in time + */ + public function resetConnections(): void + { + static::$connections = []; + } } diff --git a/typo3/sysext/core/Classes/Utility/GeneralUtility.php b/typo3/sysext/core/Classes/Utility/GeneralUtility.php index f2c8c7eedc54..58aae0174841 100644 --- a/typo3/sysext/core/Classes/Utility/GeneralUtility.php +++ b/typo3/sysext/core/Classes/Utility/GeneralUtility.php @@ -4141,6 +4141,19 @@ class GeneralUtility } } + /** + * For testing purposes only! + * The functional test framework uses this to reset the internal $application context + * variable in between multiple tests before it is re-initialized using presetApplicationContext() + * which otherwise throws an exception if the internal variable is already set. + * + * @internal May be changed or removed any time + */ + public static function resetApplicationContext(): void + { + static::$applicationContext = null; + } + /** * Get the ApplicationContext * diff --git a/typo3/sysext/core/Tests/Functional/Cache/Backend/MemcachedBackendTest.php b/typo3/sysext/core/Tests/Functional/Cache/Backend/MemcachedBackendTest.php index 5ee450e3eae7..c03545b795c8 100644 --- a/typo3/sysext/core/Tests/Functional/Cache/Backend/MemcachedBackendTest.php +++ b/typo3/sysext/core/Tests/Functional/Cache/Backend/MemcachedBackendTest.php @@ -29,7 +29,8 @@ class MemcachedBackendTest extends FunctionalTestCase */ protected function setUp() { - parent::setUp(); + // Note this functional does NOT call parent::setUp() since it does + // not need a full blown instance and database if (!extension_loaded('memcache') && !extension_loaded('memcached')) { $this->markTestSkipped('Neither "memcache" nor "memcached" extension was available'); } diff --git a/typo3/sysext/core/Tests/Functional/Cache/Backend/RedisBackendTest.php b/typo3/sysext/core/Tests/Functional/Cache/Backend/RedisBackendTest.php index 7e9600937acc..45f41a2e4fb9 100644 --- a/typo3/sysext/core/Tests/Functional/Cache/Backend/RedisBackendTest.php +++ b/typo3/sysext/core/Tests/Functional/Cache/Backend/RedisBackendTest.php @@ -32,6 +32,8 @@ class RedisBackendTest extends FunctionalTestCase */ protected function setUp() { + // Note this functional does NOT call parent::setUp() since it does + // not need a full blown instance and database if (!extension_loaded('redis')) { $this->markTestSkipped('redis extension was not available'); } diff --git a/typo3/sysext/core/composer.json b/typo3/sysext/core/composer.json index c81f31707338..0033f27c6d4a 100644 --- a/typo3/sysext/core/composer.json +++ b/typo3/sysext/core/composer.json @@ -47,7 +47,7 @@ "fiunchinho/phpunit-randomizer": "^4.0", "friendsofphp/php-cs-fixer": "^2.12.2", "typo3/cms-styleguide": "^9.1", - "typo3/testing-framework": "^4.0.2" + "typo3/testing-framework": "~4.1.0" }, "suggest": { "ext-fileinfo": "Used for proper file type detection in the file abstraction layer", -- GitLab