diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 30a530cf9eadd4b92db7349ea4d97f11a1bf14f3..0892fa26d026c822e35003f2e0f26e31ad6fa8b4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -174,6 +174,24 @@ stages: _TARGET_PHP: "8.2" _TARGET_DB: "sqlite-3" +'PHP 8.3 MySQL 8': + <<: [ *default-stage, *run-daily ] + variables: + _TARGET_PHP: "8.3" + _TARGET_DB: "mysql-8" + +'PHP 8.3 PostgreSQL 16': + <<: [ *default-stage, *run-daily ] + variables: + _TARGET_PHP: "8.3" + _TARGET_DB: "pgsql-16" + +'PHP 8.3 SQLite 3': + <<: [ *default-stage, *run-daily ] + variables: + _TARGET_PHP: "8.3" + _TARGET_DB: "sqlite-3" + # Run daily, or manually. # 'PHP 8.1 MariaDB 10.3.22': # <<: [ *default-stage, *run-daily ] diff --git a/core/assets/scaffold/files/example.settings.local.php b/core/assets/scaffold/files/example.settings.local.php index 7cb0e6857735d0493898ef24398b0f2617a91760..bfe061d056517140cf5fe92ed5f2dd2ff25cac2f 100644 --- a/core/assets/scaffold/files/example.settings.local.php +++ b/core/assets/scaffold/files/example.settings.local.php @@ -29,11 +29,7 @@ * It is strongly recommended that you set zend.assertions=1 in the PHP.ini file * (It cannot be changed from .htaccess or runtime) on development machines and * to 0 or -1 in production. - * - * @see https://wiki.php.net/rfc/expectations */ -assert_options(ASSERT_ACTIVE, TRUE); -assert_options(ASSERT_EXCEPTION, TRUE); /** * Enable local development services. diff --git a/core/lib/Drupal/Component/Assertion/Handle.php b/core/lib/Drupal/Component/Assertion/Handle.php index fe94bbf9d0590f619f88353c6c40df80170f80a6..da355aab30cea459fb721d04300857fb74235b13 100644 --- a/core/lib/Drupal/Component/Assertion/Handle.php +++ b/core/lib/Drupal/Component/Assertion/Handle.php @@ -21,9 +21,11 @@ class Handle { */ public static function register() { // Since we're using exceptions, turn error warnings off. + // phpcs:ignore Generic.PHP.DeprecatedFunctions.Deprecated assert_options(ASSERT_WARNING, FALSE); // Turn exception throwing on. + // phpcs:ignore Generic.PHP.DeprecatedFunctions.Deprecated assert_options(ASSERT_EXCEPTION, TRUE); } diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php index c6f0b9846d94290aec7ea3d5ed24e76c81d41916..dd67a2b5416f6c604b6e1062c72926107af8aff5 100644 --- a/core/lib/Drupal/Core/DrupalKernel.php +++ b/core/lib/Drupal/Core/DrupalKernel.php @@ -1058,11 +1058,6 @@ public static function bootEnvironment($app_root = NULL) { // the internal browser. define('DRUPAL_TEST_IN_CHILD_SITE', TRUE); - // Web tests are to be conducted with runtime assertions active. - assert_options(ASSERT_ACTIVE, TRUE); - // Force assertion failures to be thrown as exceptions. - assert_options(ASSERT_EXCEPTION, TRUE); - // Log fatal errors to the test site directory. ini_set('log_errors', 1); ini_set('error_log', $app_root . '/' . $test_db->getTestSitePath() . '/error.log'); diff --git a/core/lib/Drupal/Core/Entity/ContentEntityBase.php b/core/lib/Drupal/Core/Entity/ContentEntityBase.php index fb77dee8c2e6c8253f2286ffad90b99b54c15378..52b96742567625b154cc1d7408c9db43c09fb14e 100644 --- a/core/lib/Drupal/Core/Entity/ContentEntityBase.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityBase.php @@ -469,9 +469,12 @@ public function isTranslatable() { public function preSave(EntityStorageInterface $storage) { // An entity requiring validation should not be saved if it has not been // actually validated. - assert(!$this->validationRequired || $this->validated, 'Entity validation was skipped.'); - - $this->validated = FALSE; + if ($this->validationRequired && !$this->validated) { + throw new \LogicException('Entity validation is required, but was skipped.'); + } + else { + $this->validated = FALSE; + } parent::preSave($storage); } diff --git a/core/modules/jsonapi/src/EventSubscriber/ResourceResponseValidator.php b/core/modules/jsonapi/src/EventSubscriber/ResourceResponseValidator.php index a363e911d76ee8bc2716c26d8310c528ae9385ba..0d1d0cef219c14690bf96f41a772166b3b55b7a4 100644 --- a/core/modules/jsonapi/src/EventSubscriber/ResourceResponseValidator.php +++ b/core/modules/jsonapi/src/EventSubscriber/ResourceResponseValidator.php @@ -105,16 +105,8 @@ public function onResponse(ResponseEvent $event) { return; } - $this->doValidateResponse($response, $event->getRequest()); - } - - /** - * Wraps validation in an assert to prevent execution in production. - * - * @see self::validateResponse - */ - public function doValidateResponse(Response $response, Request $request) { - assert($this->validateResponse($response, $request), 'A JSON:API response failed validation (see the logs for details). Report this in the issue queue on drupal.org'); + // Wraps validation in an assert to prevent execution in production. + assert($this->validateResponse($response, $event->getRequest()), 'A JSON:API response failed validation (see the logs for details). Report this in the Drupal issue queue at https://www.drupal.org/project/issues/drupal'); } /** diff --git a/core/modules/jsonapi/tests/src/Unit/EventSubscriber/ResourceResponseValidatorTest.php b/core/modules/jsonapi/tests/src/Unit/EventSubscriber/ResourceResponseValidatorTest.php index 7a34a41a6252a0d3df0eab283f1177051b5733b4..90b5f5f8bbd4a6c1337d22ca0268fe9605152b65 100644 --- a/core/modules/jsonapi/tests/src/Unit/EventSubscriber/ResourceResponseValidatorTest.php +++ b/core/modules/jsonapi/tests/src/Unit/EventSubscriber/ResourceResponseValidatorTest.php @@ -5,12 +5,10 @@ use Drupal\jsonapi\EventSubscriber\ResourceResponseValidator; use Drupal\jsonapi\ResourceType\ResourceType; use Drupal\jsonapi\Routing\Routes; -use JsonSchema\Validator; use Drupal\Core\Extension\Extension; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\rest\ResourceResponse; use Drupal\Tests\UnitTestCase; -use Prophecy\Argument; use Psr\Log\LoggerInterface; use Drupal\Core\Routing\RouteObjectInterface; use Symfony\Component\HttpFoundation\Request; @@ -54,47 +52,6 @@ protected function setUp(): void { $this->subscriber = $subscriber; } - /** - * @covers ::doValidateResponse - */ - public function testDoValidateResponse() { - $request = $this->createRequest( - 'jsonapi.node--article.individual', - new ResourceType('node', 'article', NULL) - ); - - $response = $this->createResponse('{"data":null}'); - - // Capture the default assert settings. - $zend_assertions_default = ini_get('zend.assertions'); - $assert_active_default = assert_options(ASSERT_ACTIVE); - - // The validator *should* be called when asserts are active. - $validator = $this->prophesize(Validator::class); - $validator->check(Argument::any(), Argument::any())->shouldBeCalled('Validation should be run when asserts are active.'); - $validator->isValid()->willReturn(TRUE); - $this->subscriber->setValidator($validator->reveal()); - - // Ensure asset is active. - ini_set('zend.assertions', 1); - assert_options(ASSERT_ACTIVE, 1); - $this->subscriber->doValidateResponse($response, $request); - - // The validator should *not* be called when asserts are inactive. - $validator = $this->prophesize(Validator::class); - $validator->check(Argument::any(), Argument::any())->shouldNotBeCalled('Validation should not be run when asserts are not active.'); - $this->subscriber->setValidator($validator->reveal()); - - // Ensure asset is inactive. - ini_set('zend.assertions', 0); - assert_options(ASSERT_ACTIVE, 0); - $this->subscriber->doValidateResponse($response, $request); - - // Reset the original assert values. - ini_set('zend.assertions', $zend_assertions_default); - assert_options(ASSERT_ACTIVE, $assert_active_default); - } - /** * @covers ::validateResponse * @dataProvider validateResponseProvider diff --git a/core/modules/system/tests/modules/entity_test/src/EntityTestForm.php b/core/modules/system/tests/modules/entity_test/src/EntityTestForm.php index 4ec687aacd96c055e3a809535c20f98e62302e60..3ea354d54993f929c25c1b625660fdd96896582f 100644 --- a/core/modules/system/tests/modules/entity_test/src/EntityTestForm.php +++ b/core/modules/system/tests/modules/entity_test/src/EntityTestForm.php @@ -80,7 +80,7 @@ public function save(array $form, FormStateInterface $form_state) { $form_state->setRebuild(); } } - catch (\AssertionError $e) { + catch (\Exception $e) { \Drupal::state()->set('entity_test.form.save.exception', get_class($e) . ': ' . $e->getMessage()); } return $status ?? FALSE; diff --git a/core/modules/system/tests/src/Functional/Entity/EntityFormTest.php b/core/modules/system/tests/src/Functional/Entity/EntityFormTest.php index a9ce73618169517c995dd38f079012ef20515d4f..930636ac59c1826c1bd8d3df90c1007d4d64c97a 100644 --- a/core/modules/system/tests/src/Functional/Entity/EntityFormTest.php +++ b/core/modules/system/tests/src/Functional/Entity/EntityFormTest.php @@ -229,7 +229,7 @@ public function testValidationHandlers() { $state->set('entity_test.form.validate.test', 'button-level'); $this->drupalGet('entity_test/add'); $this->submitForm([], 'Save'); - $this->assertEquals('AssertionError: Entity validation was skipped.', $state->get('entity_test.form.save.exception'), 'Button-level validation handlers behave correctly.'); + $this->assertEquals('Drupal\\Core\\Entity\\EntityStorageException: Entity validation is required, but was skipped.', $state->get('entity_test.form.save.exception'), 'Button-level validation handlers behave correctly.'); } /** diff --git a/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php b/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php index 8b75f404e7155aea16d364994288bb58b7dfbc85..38908b9aa605665bb3b1a865e07c2a64c66fee57 100644 --- a/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php @@ -489,8 +489,8 @@ public function testRequiredValidation() { // that trying to save a non-validated entity when validation is required // results in an exception. $this->assertTrue($this->entity->isValidationRequired()); - $this->expectException(\AssertionError::class); - $this->expectExceptionMessage('Entity validation was skipped.'); + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Entity validation is required, but was skipped.'); $this->entity->save(); } diff --git a/core/tests/Drupal/Tests/Core/Field/FieldTypePluginManagerTest.php b/core/tests/Drupal/Tests/Core/Field/FieldTypePluginManagerTest.php index ac286f245656c64b7c679b0248ac2b9dabdf4af3..b0253acc06e56ed4fe2ae21fd961958d8762e901 100644 --- a/core/tests/Drupal/Tests/Core/Field/FieldTypePluginManagerTest.php +++ b/core/tests/Drupal/Tests/Core/Field/FieldTypePluginManagerTest.php @@ -147,17 +147,14 @@ public function testGetGroupedDefinitionsInvalid() { ]); $zend_assertions_default = ini_get('zend.assertions'); - $assert_active_default = assert_options(ASSERT_ACTIVE); // Test behavior when assertions are not enabled. ini_set('zend.assertions', 0); - assert_options(ASSERT_ACTIVE, 0); $grouped_definitions = $this->fieldTypeManager->getGroupedDefinitions(); $this->assertEquals(['General'], array_keys($grouped_definitions)); // Test behavior when assertions are enabled. ini_set('zend.assertions', 1); - assert_options(ASSERT_ACTIVE, 1); $this->expectException(\AssertionError::class); try { $this->fieldTypeManager->getGroupedDefinitions(); @@ -165,7 +162,6 @@ public function testGetGroupedDefinitionsInvalid() { catch (\Exception $e) { // Reset the original assert values. ini_set('zend.assertions', $zend_assertions_default); - assert_options(ASSERT_ACTIVE, $assert_active_default); throw $e; } diff --git a/core/tests/bootstrap.php b/core/tests/bootstrap.php index 295abc42659b33cee336b494dced70d959457e1d..0ea13b0f3937ce4378191810fb2828f998bb8a01 100644 --- a/core/tests/bootstrap.php +++ b/core/tests/bootstrap.php @@ -173,11 +173,6 @@ class_alias('\Drupal\Tests\DocumentElement', '\Behat\Mink\Element\DocumentElemen // reduce the fragility of the testing system in general. date_default_timezone_set('Australia/Sydney'); -// Runtime assertions. PHPUnit follows the php.ini assert.active setting for -// runtime assertions. By default this setting is on. Ensure exceptions are -// thrown if an assert fails. -assert_options(ASSERT_EXCEPTION, TRUE); - // Ensure ignored deprecation patterns listed in .deprecation-ignore.txt are // considered in testing. if (getenv('SYMFONY_DEPRECATIONS_HELPER') === FALSE) { diff --git a/sites/example.settings.local.php b/sites/example.settings.local.php index 7cb0e6857735d0493898ef24398b0f2617a91760..bfe061d056517140cf5fe92ed5f2dd2ff25cac2f 100644 --- a/sites/example.settings.local.php +++ b/sites/example.settings.local.php @@ -29,11 +29,7 @@ * It is strongly recommended that you set zend.assertions=1 in the PHP.ini file * (It cannot be changed from .htaccess or runtime) on development machines and * to 0 or -1 in production. - * - * @see https://wiki.php.net/rfc/expectations */ -assert_options(ASSERT_ACTIVE, TRUE); -assert_options(ASSERT_EXCEPTION, TRUE); /** * Enable local development services.