KernelTest.php 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\HttpKernel\Tests;
  11. use PHPUnit\Framework\TestCase;
  12. use Symfony\Component\Config\Loader\LoaderInterface;
  13. use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
  14. use Symfony\Component\DependencyInjection\ContainerBuilder;
  15. use Symfony\Component\Filesystem\Filesystem;
  16. use Symfony\Component\HttpFoundation\Request;
  17. use Symfony\Component\HttpFoundation\Response;
  18. use Symfony\Component\HttpKernel\Bundle\BundleInterface;
  19. use Symfony\Component\HttpKernel\Config\EnvParametersResource;
  20. use Symfony\Component\HttpKernel\DependencyInjection\ResettableServicePass;
  21. use Symfony\Component\HttpKernel\DependencyInjection\ServicesResetter;
  22. use Symfony\Component\HttpKernel\HttpKernelInterface;
  23. use Symfony\Component\HttpKernel\Kernel;
  24. use Symfony\Component\HttpKernel\Tests\Fixtures\KernelForOverrideName;
  25. use Symfony\Component\HttpKernel\Tests\Fixtures\KernelForTest;
  26. use Symfony\Component\HttpKernel\Tests\Fixtures\KernelWithoutBundles;
  27. use Symfony\Component\HttpKernel\Tests\Fixtures\ResettableService;
  28. class KernelTest extends TestCase
  29. {
  30. public static function tearDownAfterClass()
  31. {
  32. $fs = new Filesystem();
  33. $fs->remove(__DIR__.'/Fixtures/cache');
  34. }
  35. public function testConstructor()
  36. {
  37. $env = 'test_env';
  38. $debug = true;
  39. $kernel = new KernelForTest($env, $debug);
  40. $this->assertEquals($env, $kernel->getEnvironment());
  41. $this->assertEquals($debug, $kernel->isDebug());
  42. $this->assertFalse($kernel->isBooted());
  43. $this->assertLessThanOrEqual(microtime(true), $kernel->getStartTime());
  44. $this->assertNull($kernel->getContainer());
  45. }
  46. public function testClone()
  47. {
  48. $env = 'test_env';
  49. $debug = true;
  50. $kernel = new KernelForTest($env, $debug);
  51. $clone = clone $kernel;
  52. $this->assertEquals($env, $clone->getEnvironment());
  53. $this->assertEquals($debug, $clone->isDebug());
  54. $this->assertFalse($clone->isBooted());
  55. $this->assertLessThanOrEqual(microtime(true), $clone->getStartTime());
  56. $this->assertNull($clone->getContainer());
  57. }
  58. public function testInitializeContainerClearsOldContainers()
  59. {
  60. $fs = new Filesystem();
  61. $legacyContainerDir = __DIR__.'/Fixtures/cache/custom/ContainerA123456';
  62. $fs->mkdir($legacyContainerDir);
  63. touch($legacyContainerDir.'.legacy');
  64. $kernel = new CustomProjectDirKernel();
  65. $kernel->boot();
  66. $containerDir = __DIR__.'/Fixtures/cache/custom/'.substr(\get_class($kernel->getContainer()), 0, 16);
  67. $this->assertTrue(unlink(__DIR__.'/Fixtures/cache/custom/FixturesCustomDebugProjectContainer.php.meta'));
  68. $this->assertFileExists($containerDir);
  69. $this->assertFileNotExists($containerDir.'.legacy');
  70. $kernel = new CustomProjectDirKernel(function ($container) { $container->register('foo', 'stdClass')->setPublic(true); });
  71. $kernel->boot();
  72. $this->assertFileExists($containerDir);
  73. $this->assertFileExists($containerDir.'.legacy');
  74. $this->assertFileNotExists($legacyContainerDir);
  75. $this->assertFileNotExists($legacyContainerDir.'.legacy');
  76. }
  77. public function testBootInitializesBundlesAndContainer()
  78. {
  79. $kernel = $this->getKernel(['initializeBundles', 'initializeContainer']);
  80. $kernel->expects($this->once())
  81. ->method('initializeBundles');
  82. $kernel->expects($this->once())
  83. ->method('initializeContainer');
  84. $kernel->boot();
  85. }
  86. public function testBootSetsTheContainerToTheBundles()
  87. {
  88. $bundle = $this->getMockBuilder('Symfony\Component\HttpKernel\Bundle\Bundle')->getMock();
  89. $bundle->expects($this->once())
  90. ->method('setContainer');
  91. $kernel = $this->getKernel(['initializeBundles', 'initializeContainer', 'getBundles']);
  92. $kernel->expects($this->once())
  93. ->method('getBundles')
  94. ->willReturn([$bundle]);
  95. $kernel->boot();
  96. }
  97. public function testBootSetsTheBootedFlagToTrue()
  98. {
  99. // use test kernel to access isBooted()
  100. $kernel = $this->getKernelForTest(['initializeBundles', 'initializeContainer']);
  101. $kernel->boot();
  102. $this->assertTrue($kernel->isBooted());
  103. }
  104. /**
  105. * @group legacy
  106. */
  107. public function testClassCacheIsLoaded()
  108. {
  109. $kernel = $this->getKernel(['initializeBundles', 'initializeContainer', 'doLoadClassCache']);
  110. $kernel->loadClassCache('name', '.extension');
  111. $kernel->expects($this->once())
  112. ->method('doLoadClassCache')
  113. ->with('name', '.extension');
  114. $kernel->boot();
  115. }
  116. public function testClassCacheIsNotLoadedByDefault()
  117. {
  118. $kernel = $this->getKernel(['initializeBundles', 'initializeContainer', 'doLoadClassCache']);
  119. $kernel->expects($this->never())
  120. ->method('doLoadClassCache');
  121. $kernel->boot();
  122. }
  123. /**
  124. * @group legacy
  125. */
  126. public function testClassCacheIsNotLoadedWhenKernelIsNotBooted()
  127. {
  128. $kernel = $this->getKernel(['initializeBundles', 'initializeContainer', 'doLoadClassCache']);
  129. $kernel->loadClassCache();
  130. $kernel->expects($this->never())
  131. ->method('doLoadClassCache');
  132. }
  133. public function testEnvParametersResourceIsAdded()
  134. {
  135. $container = new ContainerBuilder();
  136. $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\Tests\Fixtures\KernelForTest')
  137. ->disableOriginalConstructor()
  138. ->setMethods(['getContainerBuilder', 'prepareContainer', 'getCacheDir', 'getLogDir'])
  139. ->getMock();
  140. $kernel->expects($this->any())
  141. ->method('getContainerBuilder')
  142. ->willReturn($container);
  143. $kernel->expects($this->any())
  144. ->method('prepareContainer')
  145. ->willReturn(null);
  146. $kernel->expects($this->any())
  147. ->method('getCacheDir')
  148. ->willReturn(sys_get_temp_dir());
  149. $kernel->expects($this->any())
  150. ->method('getLogDir')
  151. ->willReturn(sys_get_temp_dir());
  152. $reflection = new \ReflectionClass(\get_class($kernel));
  153. $method = $reflection->getMethod('buildContainer');
  154. $method->setAccessible(true);
  155. $method->invoke($kernel);
  156. $found = false;
  157. foreach ($container->getResources() as $resource) {
  158. if ($resource instanceof EnvParametersResource) {
  159. $found = true;
  160. break;
  161. }
  162. }
  163. $this->assertTrue($found);
  164. }
  165. public function testBootKernelSeveralTimesOnlyInitializesBundlesOnce()
  166. {
  167. $kernel = $this->getKernel(['initializeBundles', 'initializeContainer']);
  168. $kernel->expects($this->once())
  169. ->method('initializeBundles');
  170. $kernel->boot();
  171. $kernel->boot();
  172. }
  173. public function testShutdownCallsShutdownOnAllBundles()
  174. {
  175. $bundle = $this->getMockBuilder('Symfony\Component\HttpKernel\Bundle\Bundle')->getMock();
  176. $bundle->expects($this->once())
  177. ->method('shutdown');
  178. $kernel = $this->getKernel([], [$bundle]);
  179. $kernel->boot();
  180. $kernel->shutdown();
  181. }
  182. public function testShutdownGivesNullContainerToAllBundles()
  183. {
  184. $bundle = $this->getMockBuilder('Symfony\Component\HttpKernel\Bundle\Bundle')->getMock();
  185. $bundle->expects($this->at(3))
  186. ->method('setContainer')
  187. ->with(null);
  188. $kernel = $this->getKernel(['getBundles']);
  189. $kernel->expects($this->any())
  190. ->method('getBundles')
  191. ->willReturn([$bundle]);
  192. $kernel->boot();
  193. $kernel->shutdown();
  194. }
  195. public function testHandleCallsHandleOnHttpKernel()
  196. {
  197. $type = HttpKernelInterface::MASTER_REQUEST;
  198. $catch = true;
  199. $request = new Request();
  200. $httpKernelMock = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernel')
  201. ->disableOriginalConstructor()
  202. ->getMock();
  203. $httpKernelMock
  204. ->expects($this->once())
  205. ->method('handle')
  206. ->with($request, $type, $catch);
  207. $kernel = $this->getKernel(['getHttpKernel']);
  208. $kernel->expects($this->once())
  209. ->method('getHttpKernel')
  210. ->willReturn($httpKernelMock);
  211. $kernel->handle($request, $type, $catch);
  212. }
  213. public function testHandleBootsTheKernel()
  214. {
  215. $type = HttpKernelInterface::MASTER_REQUEST;
  216. $catch = true;
  217. $request = new Request();
  218. $httpKernelMock = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernel')
  219. ->disableOriginalConstructor()
  220. ->getMock();
  221. $kernel = $this->getKernel(['getHttpKernel', 'boot']);
  222. $kernel->expects($this->once())
  223. ->method('getHttpKernel')
  224. ->willReturn($httpKernelMock);
  225. $kernel->expects($this->once())
  226. ->method('boot');
  227. $kernel->handle($request, $type, $catch);
  228. }
  229. public function testStripComments()
  230. {
  231. $source = <<<'EOF'
  232. <?php
  233. $string = 'string should not be modified';
  234. $string = 'string should not be
  235. modified';
  236. $heredoc = <<<HD
  237. Heredoc should not be modified {$a[1+$b]}
  238. HD;
  239. $nowdoc = <<<'ND'
  240. Nowdoc should not be modified
  241. ND;
  242. /**
  243. * some class comments to strip
  244. */
  245. class TestClass
  246. {
  247. /**
  248. * some method comments to strip
  249. */
  250. public function doStuff()
  251. {
  252. // inline comment
  253. }
  254. }
  255. EOF;
  256. $expected = <<<'EOF'
  257. <?php
  258. $string = 'string should not be modified';
  259. $string = 'string should not be
  260. modified';
  261. $heredoc = <<<HD
  262. Heredoc should not be modified {$a[1+$b]}
  263. HD;
  264. $nowdoc = <<<'ND'
  265. Nowdoc should not be modified
  266. ND;
  267. class TestClass
  268. {
  269. public function doStuff()
  270. {
  271. }
  272. }
  273. EOF;
  274. $output = Kernel::stripComments($source);
  275. // Heredocs are preserved, making the output mixing Unix and Windows line
  276. // endings, switching to "\n" everywhere on Windows to avoid failure.
  277. if ('\\' === \DIRECTORY_SEPARATOR) {
  278. $expected = str_replace("\r\n", "\n", $expected);
  279. $output = str_replace("\r\n", "\n", $output);
  280. }
  281. $this->assertEquals($expected, $output);
  282. }
  283. public function testGetRootDir()
  284. {
  285. $kernel = new KernelForTest('test', true);
  286. $this->assertEquals(__DIR__.\DIRECTORY_SEPARATOR.'Fixtures', realpath($kernel->getRootDir()));
  287. }
  288. public function testGetName()
  289. {
  290. $kernel = new KernelForTest('test', true);
  291. $this->assertEquals('Fixtures', $kernel->getName());
  292. }
  293. public function testOverrideGetName()
  294. {
  295. $kernel = new KernelForOverrideName('test', true);
  296. $this->assertEquals('overridden', $kernel->getName());
  297. }
  298. public function testSerialize()
  299. {
  300. $env = 'test_env';
  301. $debug = true;
  302. $kernel = new KernelForTest($env, $debug);
  303. $expected = serialize([$env, $debug]);
  304. $this->assertEquals($expected, $kernel->serialize());
  305. }
  306. /**
  307. * @expectedException \InvalidArgumentException
  308. */
  309. public function testLocateResourceThrowsExceptionWhenNameIsNotValid()
  310. {
  311. $this->getKernel()->locateResource('Foo');
  312. }
  313. /**
  314. * @expectedException \RuntimeException
  315. */
  316. public function testLocateResourceThrowsExceptionWhenNameIsUnsafe()
  317. {
  318. $this->getKernel()->locateResource('@FooBundle/../bar');
  319. }
  320. /**
  321. * @expectedException \InvalidArgumentException
  322. */
  323. public function testLocateResourceThrowsExceptionWhenBundleDoesNotExist()
  324. {
  325. $this->getKernel()->locateResource('@FooBundle/config/routing.xml');
  326. }
  327. /**
  328. * @expectedException \InvalidArgumentException
  329. */
  330. public function testLocateResourceThrowsExceptionWhenResourceDoesNotExist()
  331. {
  332. $kernel = $this->getKernel(['getBundle']);
  333. $kernel
  334. ->expects($this->once())
  335. ->method('getBundle')
  336. ->willReturn([$this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle')])
  337. ;
  338. $kernel->locateResource('@Bundle1Bundle/config/routing.xml');
  339. }
  340. public function testLocateResourceReturnsTheFirstThatMatches()
  341. {
  342. $kernel = $this->getKernel(['getBundle']);
  343. $kernel
  344. ->expects($this->once())
  345. ->method('getBundle')
  346. ->willReturn([$this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle')])
  347. ;
  348. $this->assertEquals(__DIR__.'/Fixtures/Bundle1Bundle/foo.txt', $kernel->locateResource('@Bundle1Bundle/foo.txt'));
  349. }
  350. /**
  351. * @group legacy
  352. */
  353. public function testLocateResourceReturnsTheFirstThatMatchesWithParent()
  354. {
  355. $parent = $this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle');
  356. $child = $this->getBundle(__DIR__.'/Fixtures/Bundle2Bundle');
  357. $kernel = $this->getKernel(['getBundle']);
  358. $kernel
  359. ->expects($this->exactly(2))
  360. ->method('getBundle')
  361. ->willReturn([$child, $parent])
  362. ;
  363. $this->assertEquals(__DIR__.'/Fixtures/Bundle2Bundle/foo.txt', $kernel->locateResource('@ParentAABundle/foo.txt'));
  364. $this->assertEquals(__DIR__.'/Fixtures/Bundle1Bundle/bar.txt', $kernel->locateResource('@ParentAABundle/bar.txt'));
  365. }
  366. /**
  367. * @group legacy
  368. */
  369. public function testLocateResourceReturnsAllMatches()
  370. {
  371. $parent = $this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle');
  372. $child = $this->getBundle(__DIR__.'/Fixtures/Bundle2Bundle');
  373. $kernel = $this->getKernel(['getBundle']);
  374. $kernel
  375. ->expects($this->once())
  376. ->method('getBundle')
  377. ->willReturn([$child, $parent])
  378. ;
  379. $this->assertEquals([
  380. __DIR__.'/Fixtures/Bundle2Bundle/foo.txt',
  381. __DIR__.'/Fixtures/Bundle1Bundle/foo.txt', ],
  382. $kernel->locateResource('@Bundle1Bundle/foo.txt', null, false));
  383. }
  384. /**
  385. * @group legacy
  386. */
  387. public function testLocateResourceReturnsAllMatchesBis()
  388. {
  389. $kernel = $this->getKernel(['getBundle']);
  390. $kernel
  391. ->expects($this->once())
  392. ->method('getBundle')
  393. ->willReturn([
  394. $this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle'),
  395. $this->getBundle(__DIR__.'/Foobar'),
  396. ])
  397. ;
  398. $this->assertEquals(
  399. [__DIR__.'/Fixtures/Bundle1Bundle/foo.txt'],
  400. $kernel->locateResource('@Bundle1Bundle/foo.txt', null, false)
  401. );
  402. }
  403. public function testLocateResourceIgnoresDirOnNonResource()
  404. {
  405. $kernel = $this->getKernel(['getBundle']);
  406. $kernel
  407. ->expects($this->once())
  408. ->method('getBundle')
  409. ->willReturn([$this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle')])
  410. ;
  411. $this->assertEquals(
  412. __DIR__.'/Fixtures/Bundle1Bundle/foo.txt',
  413. $kernel->locateResource('@Bundle1Bundle/foo.txt', __DIR__.'/Fixtures')
  414. );
  415. }
  416. public function testLocateResourceReturnsTheDirOneForResources()
  417. {
  418. $kernel = $this->getKernel(['getBundle']);
  419. $kernel
  420. ->expects($this->once())
  421. ->method('getBundle')
  422. ->willReturn([$this->getBundle(__DIR__.'/Fixtures/FooBundle', null, null, 'FooBundle')])
  423. ;
  424. $this->assertEquals(
  425. __DIR__.'/Fixtures/Resources/FooBundle/foo.txt',
  426. $kernel->locateResource('@FooBundle/Resources/foo.txt', __DIR__.'/Fixtures/Resources')
  427. );
  428. }
  429. /**
  430. * @group legacy
  431. */
  432. public function testLocateResourceReturnsTheDirOneForResourcesAndBundleOnes()
  433. {
  434. $kernel = $this->getKernel(['getBundle']);
  435. $kernel
  436. ->expects($this->once())
  437. ->method('getBundle')
  438. ->willReturn([$this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle', null, null, 'Bundle1Bundle')])
  439. ;
  440. $this->assertEquals([
  441. __DIR__.'/Fixtures/Resources/Bundle1Bundle/foo.txt',
  442. __DIR__.'/Fixtures/Bundle1Bundle/Resources/foo.txt', ],
  443. $kernel->locateResource('@Bundle1Bundle/Resources/foo.txt', __DIR__.'/Fixtures/Resources', false)
  444. );
  445. }
  446. /**
  447. * @group legacy
  448. */
  449. public function testLocateResourceOverrideBundleAndResourcesFolders()
  450. {
  451. $parent = $this->getBundle(__DIR__.'/Fixtures/BaseBundle', null, 'BaseBundle', 'BaseBundle');
  452. $child = $this->getBundle(__DIR__.'/Fixtures/ChildBundle', 'ParentBundle', 'ChildBundle', 'ChildBundle');
  453. $kernel = $this->getKernel(['getBundle']);
  454. $kernel
  455. ->expects($this->exactly(4))
  456. ->method('getBundle')
  457. ->willReturn([$child, $parent])
  458. ;
  459. $this->assertEquals([
  460. __DIR__.'/Fixtures/Resources/ChildBundle/foo.txt',
  461. __DIR__.'/Fixtures/ChildBundle/Resources/foo.txt',
  462. __DIR__.'/Fixtures/BaseBundle/Resources/foo.txt',
  463. ],
  464. $kernel->locateResource('@BaseBundle/Resources/foo.txt', __DIR__.'/Fixtures/Resources', false)
  465. );
  466. $this->assertEquals(
  467. __DIR__.'/Fixtures/Resources/ChildBundle/foo.txt',
  468. $kernel->locateResource('@BaseBundle/Resources/foo.txt', __DIR__.'/Fixtures/Resources')
  469. );
  470. try {
  471. $kernel->locateResource('@BaseBundle/Resources/hide.txt', __DIR__.'/Fixtures/Resources', false);
  472. $this->fail('Hidden resources should raise an exception when returning an array of matching paths');
  473. } catch (\RuntimeException $e) {
  474. }
  475. try {
  476. $kernel->locateResource('@BaseBundle/Resources/hide.txt', __DIR__.'/Fixtures/Resources', true);
  477. $this->fail('Hidden resources should raise an exception when returning the first matching path');
  478. } catch (\RuntimeException $e) {
  479. }
  480. }
  481. public function testLocateResourceOnDirectories()
  482. {
  483. $kernel = $this->getKernel(['getBundle']);
  484. $kernel
  485. ->expects($this->exactly(2))
  486. ->method('getBundle')
  487. ->willReturn([$this->getBundle(__DIR__.'/Fixtures/FooBundle', null, null, 'FooBundle')])
  488. ;
  489. $this->assertEquals(
  490. __DIR__.'/Fixtures/Resources/FooBundle/',
  491. $kernel->locateResource('@FooBundle/Resources/', __DIR__.'/Fixtures/Resources')
  492. );
  493. $this->assertEquals(
  494. __DIR__.'/Fixtures/Resources/FooBundle',
  495. $kernel->locateResource('@FooBundle/Resources', __DIR__.'/Fixtures/Resources')
  496. );
  497. $kernel = $this->getKernel(['getBundle']);
  498. $kernel
  499. ->expects($this->exactly(2))
  500. ->method('getBundle')
  501. ->willReturn([$this->getBundle(__DIR__.'/Fixtures/Bundle1Bundle', null, null, 'Bundle1Bundle')])
  502. ;
  503. $this->assertEquals(
  504. __DIR__.'/Fixtures/Bundle1Bundle/Resources/',
  505. $kernel->locateResource('@Bundle1Bundle/Resources/')
  506. );
  507. $this->assertEquals(
  508. __DIR__.'/Fixtures/Bundle1Bundle/Resources',
  509. $kernel->locateResource('@Bundle1Bundle/Resources')
  510. );
  511. }
  512. /**
  513. * @group legacy
  514. */
  515. public function testInitializeBundles()
  516. {
  517. $parent = $this->getBundle(null, null, 'ParentABundle');
  518. $child = $this->getBundle(null, 'ParentABundle', 'ChildABundle');
  519. // use test kernel so we can access getBundleMap()
  520. $kernel = $this->getKernelForTest(['registerBundles']);
  521. $kernel
  522. ->expects($this->once())
  523. ->method('registerBundles')
  524. ->willReturn([$parent, $child])
  525. ;
  526. $kernel->boot();
  527. $map = $kernel->getBundleMap();
  528. $this->assertEquals([$child, $parent], $map['ParentABundle']);
  529. }
  530. /**
  531. * @group legacy
  532. */
  533. public function testInitializeBundlesSupportInheritanceCascade()
  534. {
  535. $grandparent = $this->getBundle(null, null, 'GrandParentBBundle');
  536. $parent = $this->getBundle(null, 'GrandParentBBundle', 'ParentBBundle');
  537. $child = $this->getBundle(null, 'ParentBBundle', 'ChildBBundle');
  538. // use test kernel so we can access getBundleMap()
  539. $kernel = $this->getKernelForTest(['registerBundles']);
  540. $kernel
  541. ->expects($this->once())
  542. ->method('registerBundles')
  543. ->willReturn([$grandparent, $parent, $child])
  544. ;
  545. $kernel->boot();
  546. $map = $kernel->getBundleMap();
  547. $this->assertEquals([$child, $parent, $grandparent], $map['GrandParentBBundle']);
  548. $this->assertEquals([$child, $parent], $map['ParentBBundle']);
  549. $this->assertEquals([$child], $map['ChildBBundle']);
  550. }
  551. /**
  552. * @group legacy
  553. * @expectedException \LogicException
  554. * @expectedExceptionMessage Bundle "ChildCBundle" extends bundle "FooBar", which is not registered.
  555. */
  556. public function testInitializeBundlesThrowsExceptionWhenAParentDoesNotExists()
  557. {
  558. $child = $this->getBundle(null, 'FooBar', 'ChildCBundle');
  559. $kernel = $this->getKernel([], [$child]);
  560. $kernel->boot();
  561. }
  562. /**
  563. * @group legacy
  564. */
  565. public function testInitializeBundlesSupportsArbitraryBundleRegistrationOrder()
  566. {
  567. $grandparent = $this->getBundle(null, null, 'GrandParentCBundle');
  568. $parent = $this->getBundle(null, 'GrandParentCBundle', 'ParentCBundle');
  569. $child = $this->getBundle(null, 'ParentCBundle', 'ChildCBundle');
  570. // use test kernel so we can access getBundleMap()
  571. $kernel = $this->getKernelForTest(['registerBundles']);
  572. $kernel
  573. ->expects($this->once())
  574. ->method('registerBundles')
  575. ->willReturn([$parent, $grandparent, $child])
  576. ;
  577. $kernel->boot();
  578. $map = $kernel->getBundleMap();
  579. $this->assertEquals([$child, $parent, $grandparent], $map['GrandParentCBundle']);
  580. $this->assertEquals([$child, $parent], $map['ParentCBundle']);
  581. $this->assertEquals([$child], $map['ChildCBundle']);
  582. }
  583. /**
  584. * @group legacy
  585. * @expectedException \LogicException
  586. * @expectedExceptionMessage Bundle "ParentCBundle" is directly extended by two bundles "ChildC2Bundle" and "ChildC1Bundle".
  587. */
  588. public function testInitializeBundlesThrowsExceptionWhenABundleIsDirectlyExtendedByTwoBundles()
  589. {
  590. $parent = $this->getBundle(null, null, 'ParentCBundle');
  591. $child1 = $this->getBundle(null, 'ParentCBundle', 'ChildC1Bundle');
  592. $child2 = $this->getBundle(null, 'ParentCBundle', 'ChildC2Bundle');
  593. $kernel = $this->getKernel([], [$parent, $child1, $child2]);
  594. $kernel->boot();
  595. }
  596. /**
  597. * @group legacy
  598. * @expectedException \LogicException
  599. * @expectedExceptionMessage Trying to register two bundles with the same name "DuplicateName"
  600. */
  601. public function testInitializeBundleThrowsExceptionWhenRegisteringTwoBundlesWithTheSameName()
  602. {
  603. $fooBundle = $this->getBundle(null, null, 'FooBundle', 'DuplicateName');
  604. $barBundle = $this->getBundle(null, null, 'BarBundle', 'DuplicateName');
  605. $kernel = $this->getKernel([], [$fooBundle, $barBundle]);
  606. $kernel->boot();
  607. }
  608. /**
  609. * @group legacy
  610. * @expectedException \LogicException
  611. * @expectedExceptionMessage Bundle "CircularRefBundle" can not extend itself.
  612. */
  613. public function testInitializeBundleThrowsExceptionWhenABundleExtendsItself()
  614. {
  615. $circularRef = $this->getBundle(null, 'CircularRefBundle', 'CircularRefBundle');
  616. $kernel = $this->getKernel([], [$circularRef]);
  617. $kernel->boot();
  618. }
  619. public function testTerminateReturnsSilentlyIfKernelIsNotBooted()
  620. {
  621. $kernel = $this->getKernel(['getHttpKernel']);
  622. $kernel->expects($this->never())
  623. ->method('getHttpKernel');
  624. $kernel->terminate(Request::create('/'), new Response());
  625. }
  626. public function testTerminateDelegatesTerminationOnlyForTerminableInterface()
  627. {
  628. // does not implement TerminableInterface
  629. $httpKernel = new TestKernel();
  630. $kernel = $this->getKernel(['getHttpKernel']);
  631. $kernel->expects($this->once())
  632. ->method('getHttpKernel')
  633. ->willReturn($httpKernel);
  634. $kernel->boot();
  635. $kernel->terminate(Request::create('/'), new Response());
  636. $this->assertFalse($httpKernel->terminateCalled, 'terminate() is never called if the kernel class does not implement TerminableInterface');
  637. // implements TerminableInterface
  638. $httpKernelMock = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernel')
  639. ->disableOriginalConstructor()
  640. ->setMethods(['terminate'])
  641. ->getMock();
  642. $httpKernelMock
  643. ->expects($this->once())
  644. ->method('terminate');
  645. $kernel = $this->getKernel(['getHttpKernel']);
  646. $kernel->expects($this->exactly(2))
  647. ->method('getHttpKernel')
  648. ->willReturn($httpKernelMock);
  649. $kernel->boot();
  650. $kernel->terminate(Request::create('/'), new Response());
  651. }
  652. public function testKernelWithoutBundles()
  653. {
  654. $kernel = new KernelWithoutBundles('test', true);
  655. $kernel->boot();
  656. $this->assertTrue($kernel->getContainer()->getParameter('test_executed'));
  657. }
  658. public function testKernelRootDirNameStartingWithANumber()
  659. {
  660. $dir = __DIR__.'/Fixtures/123';
  661. require_once $dir.'/Kernel123.php';
  662. $kernel = new \Symfony\Component\HttpKernel\Tests\Fixtures\_123\Kernel123('dev', true);
  663. $this->assertEquals('_123', $kernel->getName());
  664. }
  665. /**
  666. * @group legacy
  667. * @expectedDeprecation The "Symfony\Component\HttpKernel\Kernel::getEnvParameters()" method is deprecated as of 3.3 and will be removed in 4.0. Use the %cenv()%c syntax to get the value of any environment variable from configuration files instead.
  668. * @expectedDeprecation The support of special environment variables that start with SYMFONY__ (such as "SYMFONY__FOO__BAR") is deprecated as of 3.3 and will be removed in 4.0. Use the %cenv()%c syntax instead to get the value of environment variables in configuration files.
  669. */
  670. public function testSymfonyEnvironmentVariables()
  671. {
  672. $_SERVER['SYMFONY__FOO__BAR'] = 'baz';
  673. $kernel = $this->getKernel();
  674. $method = new \ReflectionMethod($kernel, 'getEnvParameters');
  675. $method->setAccessible(true);
  676. $envParameters = $method->invoke($kernel);
  677. $this->assertSame('baz', $envParameters['foo.bar']);
  678. unset($_SERVER['SYMFONY__FOO__BAR']);
  679. }
  680. public function testProjectDirExtension()
  681. {
  682. $kernel = new CustomProjectDirKernel();
  683. $kernel->boot();
  684. $this->assertSame('foo', $kernel->getProjectDir());
  685. $this->assertSame('foo', $kernel->getContainer()->getParameter('kernel.project_dir'));
  686. }
  687. public function testKernelReset()
  688. {
  689. (new Filesystem())->remove(__DIR__.'/Fixtures/cache');
  690. $kernel = new CustomProjectDirKernel();
  691. $kernel->boot();
  692. $containerClass = \get_class($kernel->getContainer());
  693. $containerFile = (new \ReflectionClass($kernel->getContainer()))->getFileName();
  694. unlink(__DIR__.'/Fixtures/cache/custom/FixturesCustomDebugProjectContainer.php.meta');
  695. $kernel = new CustomProjectDirKernel();
  696. $kernel->boot();
  697. $this->assertInstanceOf($containerClass, $kernel->getContainer());
  698. $this->assertFileExists($containerFile);
  699. unlink(__DIR__.'/Fixtures/cache/custom/FixturesCustomDebugProjectContainer.php.meta');
  700. $kernel = new CustomProjectDirKernel(function ($container) { $container->register('foo', 'stdClass')->setPublic(true); });
  701. $kernel->boot();
  702. $this->assertNotInstanceOf($containerClass, $kernel->getContainer());
  703. $this->assertFileExists($containerFile);
  704. $this->assertFileExists(\dirname($containerFile).'.legacy');
  705. }
  706. public function testKernelPass()
  707. {
  708. $kernel = new PassKernel();
  709. $kernel->boot();
  710. $this->assertTrue($kernel->getContainer()->getParameter('test.processed'));
  711. }
  712. public function testServicesResetter()
  713. {
  714. $httpKernelMock = $this->getMockBuilder(HttpKernelInterface::class)
  715. ->disableOriginalConstructor()
  716. ->getMock();
  717. $httpKernelMock
  718. ->expects($this->exactly(2))
  719. ->method('handle');
  720. $kernel = new CustomProjectDirKernel(function ($container) {
  721. $container->addCompilerPass(new ResettableServicePass());
  722. $container->register('one', ResettableService::class)
  723. ->setPublic(true)
  724. ->addTag('kernel.reset', ['method' => 'reset']);
  725. $container->register('services_resetter', ServicesResetter::class)->setPublic(true);
  726. }, $httpKernelMock, 'resetting');
  727. ResettableService::$counter = 0;
  728. $request = new Request();
  729. $kernel->handle($request);
  730. $kernel->getContainer()->get('one');
  731. $this->assertEquals(0, ResettableService::$counter);
  732. $this->assertFalse($kernel->getContainer()->initialized('services_resetter'));
  733. $kernel->handle($request);
  734. $this->assertEquals(1, ResettableService::$counter);
  735. }
  736. /**
  737. * @group time-sensitive
  738. */
  739. public function testKernelStartTimeIsResetWhileBootingAlreadyBootedKernel()
  740. {
  741. $kernel = $this->getKernelForTest(['initializeBundles'], true);
  742. $kernel->boot();
  743. $preReBoot = $kernel->getStartTime();
  744. sleep(3600); //Intentionally large value to detect if ClockMock ever breaks
  745. $kernel->reboot(null);
  746. $this->assertGreaterThan($preReBoot, $kernel->getStartTime());
  747. }
  748. /**
  749. * Returns a mock for the BundleInterface.
  750. *
  751. * @return BundleInterface
  752. */
  753. protected function getBundle($dir = null, $parent = null, $className = null, $bundleName = null)
  754. {
  755. $bundle = $this
  756. ->getMockBuilder('Symfony\Component\HttpKernel\Bundle\BundleInterface')
  757. ->setMethods(['getPath', 'getParent', 'getName'])
  758. ->disableOriginalConstructor()
  759. ;
  760. if ($className) {
  761. $bundle->setMockClassName($className);
  762. }
  763. $bundle = $bundle->getMockForAbstractClass();
  764. $bundle
  765. ->expects($this->any())
  766. ->method('getName')
  767. ->willReturn(null === $bundleName ? \get_class($bundle) : $bundleName)
  768. ;
  769. $bundle
  770. ->expects($this->any())
  771. ->method('getPath')
  772. ->willReturn($dir)
  773. ;
  774. $bundle
  775. ->expects($this->any())
  776. ->method('getParent')
  777. ->willReturn($parent)
  778. ;
  779. return $bundle;
  780. }
  781. /**
  782. * Returns a mock for the abstract kernel.
  783. *
  784. * @param array $methods Additional methods to mock (besides the abstract ones)
  785. * @param array $bundles Bundles to register
  786. *
  787. * @return Kernel
  788. */
  789. protected function getKernel(array $methods = [], array $bundles = [])
  790. {
  791. $methods[] = 'registerBundles';
  792. $kernel = $this
  793. ->getMockBuilder('Symfony\Component\HttpKernel\Kernel')
  794. ->setMethods($methods)
  795. ->setConstructorArgs(['test', false])
  796. ->getMockForAbstractClass()
  797. ;
  798. $kernel->expects($this->any())
  799. ->method('registerBundles')
  800. ->willReturn($bundles)
  801. ;
  802. $p = new \ReflectionProperty($kernel, 'rootDir');
  803. $p->setAccessible(true);
  804. $p->setValue($kernel, __DIR__.'/Fixtures');
  805. return $kernel;
  806. }
  807. protected function getKernelForTest(array $methods = [], $debug = false)
  808. {
  809. $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\Tests\Fixtures\KernelForTest')
  810. ->setConstructorArgs(['test', $debug])
  811. ->setMethods($methods)
  812. ->getMock();
  813. $p = new \ReflectionProperty($kernel, 'rootDir');
  814. $p->setAccessible(true);
  815. $p->setValue($kernel, __DIR__.'/Fixtures');
  816. return $kernel;
  817. }
  818. }
  819. class TestKernel implements HttpKernelInterface
  820. {
  821. public $terminateCalled = false;
  822. public function terminate()
  823. {
  824. $this->terminateCalled = true;
  825. }
  826. public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true)
  827. {
  828. }
  829. }
  830. class CustomProjectDirKernel extends Kernel
  831. {
  832. private $baseDir;
  833. private $buildContainer;
  834. private $httpKernel;
  835. public function __construct(\Closure $buildContainer = null, HttpKernelInterface $httpKernel = null, $name = 'custom')
  836. {
  837. parent::__construct($name, true);
  838. $this->baseDir = 'foo';
  839. $this->buildContainer = $buildContainer;
  840. $this->httpKernel = $httpKernel;
  841. }
  842. public function registerBundles()
  843. {
  844. return [];
  845. }
  846. public function registerContainerConfiguration(LoaderInterface $loader)
  847. {
  848. }
  849. public function getProjectDir()
  850. {
  851. return $this->baseDir;
  852. }
  853. public function getRootDir()
  854. {
  855. return __DIR__.'/Fixtures';
  856. }
  857. protected function build(ContainerBuilder $container)
  858. {
  859. if ($build = $this->buildContainer) {
  860. $build($container);
  861. }
  862. }
  863. protected function getHttpKernel()
  864. {
  865. return $this->httpKernel;
  866. }
  867. }
  868. class PassKernel extends CustomProjectDirKernel implements CompilerPassInterface
  869. {
  870. public function __construct()
  871. {
  872. parent::__construct();
  873. Kernel::__construct('pass', true);
  874. }
  875. public function process(ContainerBuilder $container)
  876. {
  877. $container->setParameter('test.processed', true);
  878. }
  879. }