32bdf127a3530d566478ff8fc3ae66db44fe607f
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Build / UnitTestsBootstrap.php
1 <?php
2 namespace TYPO3\CMS\Core\Build;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Core\Bootstrap;
18
19 /**
20 * This file is defined in UnitTests.xml and called by phpunit
21 * before instantiating the test suites, it must also be included
22 * with phpunit parameter --bootstrap if executing single test case classes.
23 *
24 * For easy access to the PHPUnit and VFS framework, it is recommended to install the phpunit TYPO3 Extension
25 * It does not need to be activated, nor a cli user needs to be present.
26 * But it is also possible to use other installations of PHPUnit and VFS
27 *
28 * * Call whole unit test suite, example:
29 * - cd /var/www/t3master/foo # Document root of TYPO3 CMS sources (location of index.php)
30 * - typo3/../bin/phpunit -c typo3/sysext/core/Build/UnitTests.xml
31 *
32 * Call single test case, example:
33 * - cd /var/www/t3master/foo # Document root of TYPO3 CMS instance (location of index.php)
34 * - typo3/../bin/phpunit \
35 * --bootstrap typo3/sysext/core/Build/UnitTestsBootstrap.php \
36 * typo3/sysext/core/Tests/Uinit/DataHandling/DataHandlerTest.php
37 */
38 class UnitTestsBootstrap
39 {
40 /**
41 * Bootstraps the system for unit tests.
42 *
43 * @return void
44 */
45 public function bootstrapSystem()
46 {
47 $this->enableDisplayErrors()
48 ->checkForCliDispatch()
49 ->defineSitePath()
50 ->setTypo3Context()
51 ->createNecessaryDirectoriesInDocumentRoot()
52 ->includeAndStartCoreBootstrap()
53 ->initializeConfiguration()
54 ->finishCoreBootstrap();
55 }
56
57 /**
58 * Makes sure error messages during the tests get displayed no matter what is set in php.ini.
59 *
60 * @return UnitTestsBootstrap fluent interface
61 */
62 protected function enableDisplayErrors()
63 {
64 @ini_set('display_errors', 1);
65 return $this;
66 }
67
68 /**
69 * Checks whether the tests are run using the CLI dispatcher. If so, echos a helpful message and exits with
70 * an error code 1.
71 *
72 * @return UnitTestsBootstrap fluent interface
73 */
74 protected function checkForCliDispatch()
75 {
76 if (!defined('TYPO3_MODE')) {
77 return $this;
78 }
79
80 array_shift($_SERVER['argv']);
81 $flatArguments = implode(' ', $_SERVER['argv']);
82 echo 'Please run the unit tests using the following command:' . chr(10) .
83 sprintf('typo3/../bin/phpunit %s', $flatArguments) . chr(10) .
84 chr(10);
85
86 exit(1);
87 }
88
89 /**
90 * Defines the PATH_site and PATH_thisScript constant and sets $_SERVER['SCRIPT_NAME'].
91 *
92 * @return UnitTestsBootstrap fluent interface
93 */
94 protected function defineSitePath()
95 {
96 /** @var string */
97 define('PATH_site', $this->getWebRoot());
98 /** @var string */
99 define('PATH_thisScript', PATH_site . 'typo3/cli_dispatch.phpsh');
100 $_SERVER['SCRIPT_NAME'] = PATH_thisScript;
101
102 if (!file_exists(PATH_thisScript)) {
103 die('Unable to determine path to entry script. Please check your path or set an environment variable \'TYPO3_PATH_WEB\' to your root path.');
104 }
105
106 return $this;
107 }
108
109 /**
110 * Returns the absolute path the TYPO3 document root.
111 *
112 * @return string the TYPO3 document root using Unix path separators
113 */
114 protected function getWebRoot()
115 {
116 if (getenv('TYPO3_PATH_WEB')) {
117 $webRoot = getenv('TYPO3_PATH_WEB');
118 } else {
119 $webRoot = getcwd();
120 }
121 return rtrim(strtr($webRoot, '\\', '/'), '/') . '/';
122 }
123
124 /**
125 * Defines TYPO3_MODE and sets the environment variable TYPO3_CONTEXT.
126 *
127 * @return UnitTestsBootstrap fluent interface
128 */
129 protected function setTypo3Context()
130 {
131 /** @var string */
132 define('TYPO3_MODE', 'BE');
133 /** @var string */
134 putenv('TYPO3_CONTEXT=Testing');
135
136 return $this;
137 }
138
139 /**
140 * Creates the following directories in the TYPO3 document root:
141 * - typo3conf
142 * - typo3conf/ext
143 * - typo3temp
144 * - uploads
145 *
146 * @return UnitTestsBootstrap fluent interface
147 */
148 protected function createNecessaryDirectoriesInDocumentRoot()
149 {
150 $this->createDirectory(PATH_site . 'uploads');
151 $this->createDirectory(PATH_site . 'typo3temp/var/tests');
152 $this->createDirectory(PATH_site . 'typo3temp/var/transient');
153 $this->createDirectory(PATH_site . 'typo3conf/ext');
154
155 return $this;
156 }
157
158 /**
159 * Creates the directory $directory (recursively if required).
160 *
161 * If $directory already exists, this method is a no-op.
162 *
163 * @param string $directory absolute path of the directory to be created
164 * @return void
165 * @throws \RuntimeException
166 */
167 protected function createDirectory($directory)
168 {
169 if (is_dir($directory)) {
170 return;
171 }
172 @mkdir($directory, 0777, true);
173 clearstatcache();
174 if (!is_dir($directory)) {
175 throw new \RuntimeException('Directory "' . $directory . '" could not be created', 1423043755);
176 }
177 }
178
179 /**
180 * Includes the Core Bootstrap class and calls its first few functions.
181 *
182 * @return UnitTestsBootstrap fluent interface
183 */
184 protected function includeAndStartCoreBootstrap()
185 {
186 $classLoaderFilepath = __DIR__ . '/../../../../vendor/autoload.php';
187 if (!file_exists($classLoaderFilepath)) {
188 die('ClassLoader can\'t be loaded. Please check your path or set an environment variable \'TYPO3_PATH_WEB\' to your root path.');
189 }
190 $classLoader = require $classLoaderFilepath;
191
192 Bootstrap::getInstance()
193 ->initializeClassLoader($classLoader)
194 ->setRequestType(TYPO3_REQUESTTYPE_BE | TYPO3_REQUESTTYPE_CLI)
195 ->baseSetup();
196
197 return $this;
198 }
199
200 /**
201 * Provides the default configuration in $GLOBALS['TYPO3_CONF_VARS'].
202 *
203 * @return UnitTestsBootstrap fluent interface
204 */
205 protected function initializeConfiguration()
206 {
207 $configurationManager = new \TYPO3\CMS\Core\Configuration\ConfigurationManager();
208 $GLOBALS['TYPO3_CONF_VARS'] = $configurationManager->getDefaultConfiguration();
209
210 // avoid failing tests that rely on HTTP_HOST retrieval
211 $GLOBALS['TYPO3_CONF_VARS']['SYS']['trustedHostsPattern'] = '.*';
212
213 return $this;
214 }
215
216 /**
217 * Finishes the last steps of the Core Bootstrap.
218 *
219 * @return UnitTestsBootstrap fluent interface
220 */
221 protected function finishCoreBootstrap()
222 {
223 Bootstrap::getInstance()
224 ->disableCoreCache()
225 ->initializeCachingFramework()
226 ->initializePackageManagement(\TYPO3\CMS\Core\Package\UnitTestPackageManager::class)
227 ->ensureClassLoadingInformationExists();
228
229 return $this;
230 }
231 }
232
233 if (PHP_SAPI !== 'cli') {
234 die('This script supports command line usage only. Please check your command.');
235 }
236 $bootstrap = new UnitTestsBootstrap();
237 $bootstrap->bootstrapSystem();
238 unset($bootstrap);