[TASK] Speed up functional tests 75/29575/6
authorChristian Kuhn <lolli@schwarzbu.ch>
Sat, 19 Apr 2014 23:18:38 +0000 (01:18 +0200)
committerAnja Leichsenring <aleichsenring@ab-softlab.de>
Fri, 2 May 2014 19:10:04 +0000 (21:10 +0200)
Optimize functional test bootstrap to improve performance:

* Database schema for single tests of a test case are always
  identical by design. So a database can be re-used between
  single tests to save the table creation overhead. Database
  tables are truncated instead which is quicker.
* Load less extensions by default, so less tables are created.
* Enable class loader caches.

Typically, tests instances with mysql on a ramdisk, tests are ~25%
quicker, for native mysql on hdd the performance impact is ~50%.

Change-Id: Ife1ea755c5336f7d4362b2affe7bba9e94862e92
Resolves: #58433
Releases: 6.2
Reviewed-on: https://review.typo3.org/29575
Reviewed-by: Christian Kuhn
Tested-by: Christian Kuhn
Reviewed-by: Anja Leichsenring
Tested-by: Anja Leichsenring
typo3/sysext/core/Build/Configuration/FunctionalTestsConfiguration.php
typo3/sysext/core/Tests/FunctionalTestCase.php
typo3/sysext/core/Tests/FunctionalTestCaseBootstrapUtility.php
typo3/sysext/frontend/Tests/Functional/ContentObject/FluidTemplateContentObjectTest.php
typo3/sysext/workspaces/Tests/Functional/DataHandling/Group/AbstractActionTestCase.php
typo3/sysext/workspaces/Tests/Functional/DataHandling/IRRE/AbstractTestCase.php
typo3/sysext/workspaces/Tests/Functional/DataHandling/IRRE/CSV/AbstractActionTestCase.php
typo3/sysext/workspaces/Tests/Functional/DataHandling/IRRE/ForeignField/AbstractActionTestCase.php
typo3/sysext/workspaces/Tests/Functional/DataHandling/ManyToMany/AbstractActionTestCase.php
typo3/sysext/workspaces/Tests/Functional/DataHandling/Regular/AbstractActionTestCase.php
typo3/sysext/workspaces/Tests/Functional/DataHandling/Select/AbstractActionTestCase.php

index da25c98..1208432 100644 (file)
@@ -3,15 +3,5 @@ return array(
        'SYS' => array(
                'displayErrors' => '1',
                'debugExceptionHandler' => '',
-               'caching' => array(
-                       'cacheConfigurations' => array(
-                               'cache_core' => array(
-                                       'backend' => 'TYPO3\\CMS\\Core\\Cache\\Backend\\NullBackend'
-                               ),
-                               'cache_classes' => array(
-                                       'backend' => 'TYPO3\\CMS\\Core\\Cache\\Backend\\TransientMemoryBackend'
-                               ),
-                       )
-               )
        )
 );
index c53acd1..61c5bde 100644 (file)
@@ -199,24 +199,6 @@ abstract class FunctionalTestCase extends BaseTestCase {
        }
 
        /**
-        * Tear down destroys the instance and database.
-        *
-        * This method should be called with parent::tearDown() in your test cases!
-        *
-        * @throws Exception
-        * @return void
-        */
-       public function tearDown() {
-               if (!($this->bootstrapUtility instanceof FunctionalTestCaseBootstrapUtility)) {
-                       throw new Exception(
-                               'Bootstrap utility not set. Is parent::setUp() called in setUp()?',
-                               1376826527
-                       );
-               }
-               $this->bootstrapUtility->tearDown();
-       }
-
-       /**
         * Get DatabaseConnection instance - $GLOBALS['TYPO3_DB']
         *
         * This method should be used instead of direct access to
index c697f72..9ee830d 100644 (file)
@@ -58,14 +58,8 @@ class FunctionalTestCaseBootstrapUtility {
                'frontend',
                'cms',
                'lang',
-               'sv',
-               'extensionmanager',
-               'recordlist',
                'extbase',
-               'fluid',
-               'cshmanual',
                'install',
-               'saltedpasswords'
        );
 
        /**
@@ -101,38 +95,40 @@ class FunctionalTestCaseBootstrapUtility {
        ) {
                $this->setUpIdentifier($testCaseClassName);
                $this->setUpInstancePath();
-               $this->removeOldInstanceIfExists();
-               $this->setUpInstanceDirectories($additionalFoldersToCreate);
-               $this->setUpInstanceCoreLinks();
-               $this->linkTestExtensionsToInstance($testExtensionsToLoad);
-               $this->linkPathsInTestInstance($pathsToLinkInTestInstance);
-               $this->setUpLocalConfiguration($configurationToUse);
-               $this->setUpPackageStates($coreExtensionsToLoad, $testExtensionsToLoad);
-               $this->setUpBasicTypo3Bootstrap();
-               $this->setUpTestDatabase();
-               \TYPO3\CMS\Core\Core\Bootstrap::getInstance()->loadExtensionTables(TRUE);
-               $this->createDatabaseStructure();
+               if ($this->recentTestInstanceExists()) {
+                       $this->setUpBasicTypo3Bootstrap();
+                       $this->initializeTestDatabase();
+                       \TYPO3\CMS\Core\Core\Bootstrap::getInstance()->loadExtensionTables(TRUE);
+               } else {
+                       $this->removeOldInstanceIfExists();
+                       $this->setUpInstanceDirectories($additionalFoldersToCreate);
+                       $this->setUpInstanceCoreLinks();
+                       $this->linkTestExtensionsToInstance($testExtensionsToLoad);
+                       $this->linkPathsInTestInstance($pathsToLinkInTestInstance);
+                       $this->setUpLocalConfiguration($configurationToUse);
+                       $this->setUpPackageStates($coreExtensionsToLoad, $testExtensionsToLoad);
+                       $this->setUpBasicTypo3Bootstrap();
+                       $this->setUpTestDatabase();
+                       \TYPO3\CMS\Core\Core\Bootstrap::getInstance()->loadExtensionTables(TRUE);
+                       $this->createDatabaseStructure();
+        }
 
                return $this->instancePath;
        }
 
        /**
-        * Tear down destroys the instance and database.
+        * Checks whether the current test instance exists and is younger than
+        * some minutes.
         *
-        * @throws Exception
-        * @return void
+        * @return bool
         */
-       public function tearDown() {
-               $classLoader = \TYPO3\CMS\Core\Core\Bootstrap::getInstance()->getEarlyInstance('TYPO3\\CMS\\Core\\Core\\ClassLoader');
-               spl_autoload_unregister(array($classLoader, 'loadClass'));
-               if (empty($this->identifier)) {
-                       throw new Exception(
-                               'Test identifier not set. Is parent::setUp() called in setUp()?',
-                               1376739702
-                       );
+       protected function recentTestInstanceExists() {
+               if (@file_get_contents($this->instancePath . '/last_run.txt') <= (time() - 300)) {
+                       return FALSE;
+               } else {
+                       // Test instance exists and is pretty young -> re-use
+                       return TRUE;
                }
-               $this->tearDownTestDatabase();
-               $this->removeInstance();
        }
 
        /**
@@ -186,6 +182,9 @@ class FunctionalTestCaseBootstrapUtility {
                                );
                        }
                }
+
+               // Store the time we created this directory
+               file_put_contents($this->instancePath . '/last_run.txt', time());
        }
 
        /**
@@ -438,8 +437,8 @@ class FunctionalTestCaseBootstrapUtility {
                require_once $this->instancePath . '/typo3/sysext/core/Classes/Core/Bootstrap.php';
                \TYPO3\CMS\Core\Core\Bootstrap::getInstance()
                        ->baseSetup('')
-                       ->loadConfigurationAndInitialize(FALSE)
-                       ->loadTypo3LoadedExtAndExtLocalconf(FALSE)
+                       ->loadConfigurationAndInitialize(TRUE)
+                       ->loadTypo3LoadedExtAndExtLocalconf(TRUE)
                        ->applyAdditionalConfigurationSettings();
        }
 
@@ -479,6 +478,32 @@ class FunctionalTestCaseBootstrapUtility {
        }
 
        /**
+        * Populate $GLOBALS['TYPO3_DB'] reusing an existing database with
+        * all tables truncated.
+        *
+        * @throws \TYPO3\CMS\Core\Tests\Exception
+        * @return void
+        */
+       protected function initializeTestDatabase() {
+               \TYPO3\CMS\Core\Core\Bootstrap::getInstance()->initializeTypo3DbGlobal();
+               /** @var \TYPO3\CMS\Core\Database\DatabaseConnection $database */
+               $database = $GLOBALS['TYPO3_DB'];
+               if (!$database->sql_pconnect()) {
+                       throw new Exception(
+                               'TYPO3 Fatal Error: The current username, password or host was not accepted when the'
+                               . ' connection to the database was attempted to be established!',
+                               1377620117
+                       );
+               }
+               $this->databaseName = $GLOBALS['TYPO3_CONF_VARS']['DB']['database'];
+               $database->setDatabaseName($this->databaseName);
+               $database->sql_select_db($this->databaseName);
+               foreach ($database->admin_get_tables() as $table) {
+                       $database->admin_query('TRUNCATE ' . $table['Name'] . ';');
+               }
+       }
+
+       /**
         * Create tables and import static rows
         *
         * @return void
index d6a6d61..02e6adb 100644 (file)
@@ -29,6 +29,8 @@ namespace TYPO3\CMS\Frontend\Tests\Functional\ContentObject;
  */
 class FluidTemplateContentObjectTest extends \TYPO3\CMS\Core\Tests\FunctionalTestCase {
 
+       protected $coreExtensionsToLoad = array('fluid');
+
        /**
         * @test
         */
index ac06543..309c00c 100644 (file)
@@ -42,6 +42,7 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
         * @var array
         */
        protected $coreExtensionsToLoad = array(
+               'fluid',
                'version',
                'workspaces',
        );
index 8b91f2f..578576f 100644 (file)
@@ -48,7 +48,11 @@ abstract class AbstractTestCase extends \TYPO3\CMS\Core\Tests\Functional\DataHan
        const COMMAND_Version_Flush = 'flush';
        const COMMAND_Version_Clear = 'clearWSID';
 
-       protected $coreExtensionsToLoad = array('version', 'workspaces');
+       protected $coreExtensionsToLoad = array(
+               'fluid',
+               'version',
+               'workspaces'
+       );
 
        /**
         * @var integer
index b496523..86d0ef4 100644 (file)
@@ -56,6 +56,7 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
         * @var array
         */
        protected $coreExtensionsToLoad = array(
+               'fluid',
                'version',
                'workspaces',
        );
index a6afbce..306d7a3 100644 (file)
@@ -56,6 +56,7 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
         * @var array
         */
        protected $coreExtensionsToLoad = array(
+               'fluid',
                'version',
                'workspaces',
        );
index 5055bc2..332b23e 100644 (file)
@@ -55,6 +55,7 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
         * @var array
         */
        protected $coreExtensionsToLoad = array(
+               'fluid',
                'version',
                'workspaces',
        );
index c89a51e..3dee69b 100644 (file)
@@ -47,6 +47,7 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
         * @var array
         */
        protected $coreExtensionsToLoad = array(
+               'fluid',
                'version',
                'workspaces',
        );
index af5bf37..b2c814c 100644 (file)
@@ -42,6 +42,7 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
         * @var array
         */
        protected $coreExtensionsToLoad = array(
+               'fluid',
                'version',
                'workspaces',
        );