PageRenderTime 26ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/web/core/tests/Drupal/KernelTests/Core/DrupalKernel/DrupalKernelTest.php

https://gitlab.com/mohamed_hussein/prodt
PHP | 266 lines | 141 code | 34 blank | 91 comment | 3 complexity | f31310b6197f2a88cb1bf197fb1acf01 MD5 | raw file
  1. <?php
  2. namespace Drupal\KernelTests\Core\DrupalKernel;
  3. use Composer\Autoload\ClassLoader;
  4. use Drupal\Core\DrupalKernel;
  5. use Drupal\Core\DrupalKernelInterface;
  6. use Drupal\KernelTests\KernelTestBase;
  7. use org\bovigo\vfs\vfsStream;
  8. use Prophecy\Argument;
  9. use Symfony\Component\HttpFoundation\Request;
  10. use Symfony\Component\HttpKernel\Event\KernelEvent;
  11. /**
  12. * Tests DIC compilation to disk.
  13. *
  14. * @group DrupalKernel
  15. * @coversDefaultClass \Drupal\Core\DrupalKernel
  16. */
  17. class DrupalKernelTest extends KernelTestBase {
  18. /**
  19. * {@inheritdoc}
  20. */
  21. protected function setUp(): void {
  22. // Do not invoke KernelTestBase::setUp(), since that would set up further
  23. // environment aspects, which would distort this test, because it tests the
  24. // DrupalKernel (re-)building itself.
  25. $this->root = static::getDrupalRoot();
  26. $this->bootEnvironment();
  27. }
  28. /**
  29. * Build a kernel for testings.
  30. *
  31. * Because the bootstrap is in DrupalKernel::boot and that involved loading
  32. * settings from the filesystem we need to go to extra lengths to build a kernel
  33. * for testing.
  34. *
  35. * @param \Symfony\Component\HttpFoundation\Request $request
  36. * A request object to use in booting the kernel.
  37. * @param array $modules_enabled
  38. * A list of modules to enable on the kernel.
  39. *
  40. * @return \Drupal\Core\DrupalKernel
  41. * New kernel for testing.
  42. */
  43. protected function getTestKernel(Request $request, array $modules_enabled = NULL) {
  44. // Manually create kernel to avoid replacing settings.
  45. $class_loader = require $this->root . '/autoload.php';
  46. $kernel = DrupalKernel::createFromRequest($request, $class_loader, 'testing');
  47. $this->setSetting('container_yamls', []);
  48. $this->setSetting('hash_salt', $this->databasePrefix);
  49. if (isset($modules_enabled)) {
  50. $kernel->updateModules($modules_enabled);
  51. }
  52. $kernel->boot();
  53. return $kernel;
  54. }
  55. /**
  56. * Tests KernelEvent class_alias() override.
  57. *
  58. * @todo https://www.drupal.org/project/drupal/issues/3197482 Remove this test
  59. * once Drupal is using Symfony 5.3 or higher.
  60. */
  61. public function testKernelEvent() {
  62. $request = Request::createFromGlobals();
  63. $kernel = $this->getTestKernel($request);
  64. $event = new KernelEvent($kernel, $request, $kernel::MASTER_REQUEST);
  65. $this->assertTrue($event->isMainRequest());
  66. }
  67. /**
  68. * Tests DIC compilation.
  69. */
  70. public function testCompileDIC() {
  71. // @todo: write a memory based storage backend for testing.
  72. $modules_enabled = [
  73. 'system' => 'system',
  74. 'user' => 'user',
  75. ];
  76. $request = Request::createFromGlobals();
  77. $this->getTestKernel($request, $modules_enabled);
  78. // Instantiate it a second time and we should get the compiled Container
  79. // class.
  80. $kernel = $this->getTestKernel($request);
  81. $container = $kernel->getContainer();
  82. $refClass = new \ReflectionClass($container);
  83. $is_compiled_container = !$refClass->isSubclassOf('Symfony\Component\DependencyInjection\ContainerBuilder');
  84. $this->assertTrue($is_compiled_container);
  85. // Verify that the list of modules is the same for the initial and the
  86. // compiled container.
  87. $module_list = array_keys($container->get('module_handler')->getModuleList());
  88. $this->assertEquals(array_values($modules_enabled), $module_list);
  89. // Get the container another time, simulating a "production" environment.
  90. $container = $this->getTestKernel($request, NULL)
  91. ->getContainer();
  92. $refClass = new \ReflectionClass($container);
  93. $is_compiled_container = !$refClass->isSubclassOf('Symfony\Component\DependencyInjection\ContainerBuilder');
  94. $this->assertTrue($is_compiled_container);
  95. // Verify that the list of modules is the same for the initial and the
  96. // compiled container.
  97. $module_list = array_keys($container->get('module_handler')->getModuleList());
  98. $this->assertEquals(array_values($modules_enabled), $module_list);
  99. // Test that our synthetic services are there.
  100. $class_loader = $container->get('class_loader');
  101. $refClass = new \ReflectionClass($class_loader);
  102. $this->assertTrue($refClass->hasMethod('loadClass'), 'Container has a class loader');
  103. // We make this assertion here purely to show that the new container below
  104. // is functioning correctly, i.e. we get a brand new ContainerBuilder
  105. // which has the required new services, after changing the list of enabled
  106. // modules.
  107. $this->assertFalse($container->has('service_provider_test_class'));
  108. // Add another module so that we can test that the new module's bundle is
  109. // registered to the new container.
  110. $modules_enabled['service_provider_test'] = 'service_provider_test';
  111. $this->getTestKernel($request, $modules_enabled);
  112. // Instantiate it a second time and we should not get a ContainerBuilder
  113. // class because we are loading the container definition from cache.
  114. $kernel = $this->getTestKernel($request, $modules_enabled);
  115. $container = $kernel->getContainer();
  116. $refClass = new \ReflectionClass($container);
  117. $is_container_builder = $refClass->isSubclassOf('Symfony\Component\DependencyInjection\ContainerBuilder');
  118. $this->assertFalse($is_container_builder, 'Container is not a builder');
  119. // Assert that the new module's bundle was registered to the new container.
  120. $this->assertTrue($container->has('service_provider_test_class'), 'Container has test service');
  121. // Test that our synthetic services are there.
  122. $class_loader = $container->get('class_loader');
  123. $refClass = new \ReflectionClass($class_loader);
  124. $this->assertTrue($refClass->hasMethod('loadClass'), 'Container has a class loader');
  125. // Check that the location of the new module is registered.
  126. $modules = $container->getParameter('container.modules');
  127. $module_extension_list = $container->get('extension.list.module');
  128. $this->assertEquals(['type' => 'module', 'pathname' => $module_extension_list->getPathname('service_provider_test'), 'filename' => NULL], $modules['service_provider_test']);
  129. // Check that the container itself is not among the persist IDs because it
  130. // does not make sense to persist the container itself.
  131. $persist_ids = $container->getParameter('persist_ids');
  132. $this->assertNotContains('service_container', $persist_ids);
  133. }
  134. /**
  135. * Tests repeated loading of compiled DIC with different environment.
  136. */
  137. public function testRepeatedBootWithDifferentEnvironment() {
  138. $request = Request::createFromGlobals();
  139. $class_loader = require $this->root . '/autoload.php';
  140. $environments = [
  141. 'testing1',
  142. 'testing1',
  143. 'testing2',
  144. 'testing2',
  145. ];
  146. foreach ($environments as $environment) {
  147. $kernel = DrupalKernel::createFromRequest($request, $class_loader, $environment);
  148. $this->setSetting('container_yamls', []);
  149. $this->setSetting('hash_salt', $this->databasePrefix);
  150. $this->assertInstanceOf(DrupalKernelInterface::class, $kernel->boot(), "Environment $environment should boot.");
  151. }
  152. }
  153. /**
  154. * Tests setting of site path after kernel boot.
  155. */
  156. public function testPreventChangeOfSitePath() {
  157. // @todo: write a memory based storage backend for testing.
  158. $modules_enabled = [
  159. 'system' => 'system',
  160. 'user' => 'user',
  161. ];
  162. $request = Request::createFromGlobals();
  163. $kernel = $this->getTestKernel($request, $modules_enabled);
  164. $pass = FALSE;
  165. try {
  166. $kernel->setSitePath('/dev/null');
  167. }
  168. catch (\LogicException $e) {
  169. $pass = TRUE;
  170. }
  171. $this->assertTrue($pass, 'Throws LogicException if DrupalKernel::setSitePath() is called after boot');
  172. // Ensure no LogicException if DrupalKernel::setSitePath() is called with
  173. // identical path after boot.
  174. $path = $kernel->getSitePath();
  175. $kernel->setSitePath($path);
  176. }
  177. /**
  178. * Data provider for self::testClassLoaderAutoDetect.
  179. * @return array
  180. */
  181. public function providerClassLoaderAutoDetect() {
  182. return [
  183. 'TRUE' => [TRUE],
  184. 'FALSE' => [FALSE],
  185. ];
  186. }
  187. /**
  188. * Tests class_loader_auto_detect setting.
  189. *
  190. * This test runs in a separate process since it registers class loaders and
  191. * results in statics being set.
  192. *
  193. * @runInSeparateProcess
  194. * @preserveGlobalState disabled
  195. * @covers ::boot
  196. * @dataProvider providerClassLoaderAutoDetect
  197. *
  198. * @param bool $value
  199. * The value to set class_loader_auto_detect to.
  200. */
  201. public function testClassLoaderAutoDetect($value) {
  202. // Create a virtual file system containing items that should be
  203. // excluded. Exception being modules directory.
  204. vfsStream::setup('root', NULL, [
  205. 'sites' => [
  206. 'default' => [],
  207. ],
  208. 'core' => [
  209. 'lib' => [
  210. 'Drupal' => [
  211. 'Core' => [],
  212. 'Component' => [],
  213. ],
  214. ],
  215. ],
  216. ]);
  217. $this->setSetting('class_loader_auto_detect', $value);
  218. $classloader = $this->prophesize(ClassLoader::class);
  219. // Assert that we call the setApcuPrefix on the classloader if
  220. // class_loader_auto_detect is set to TRUE;
  221. if ($value) {
  222. $classloader->setApcuPrefix(Argument::type('string'))->shouldBeCalled();
  223. }
  224. else {
  225. $classloader->setApcuPrefix(Argument::type('string'))->shouldNotBeCalled();
  226. }
  227. // Create a kernel suitable for testing.
  228. $kernel = new DrupalKernel('test', $classloader->reveal(), FALSE, vfsStream::url('root'));
  229. $kernel->setSitePath(vfsStream::url('root/sites/default'));
  230. $kernel->boot();
  231. }
  232. }