Problem/Motivation

#3119761: Replace multiple test methods in InfoParserUnitTest with 1 testInfoException and a dataprovider discovered in because that was converting all the test methods in \Drupal\Tests\Core\Extension\InfoParserUnitTest that thrown an exception into 1 method with a data provider.

\Drupal\Tests\Core\Extension\InfoParserUnitTest::testUnparsableCoreVersionRequirement() did not call the parser twice.

Therefore this call

try {
          $supports_pre_core_version_requirement_version = static::isConstraintSatisfiedByPreviousVersion($parsed_info['core_version_requirement'], static::FIRST_CORE_VERSION_REQUIREMENT_SUPPORTED_VERSION);
        }
        catch (\UnexpectedValueException $e) {
          throw new InfoParserException("The 'core_version_requirement' constraint ({$parsed_info['core_version_requirement']}) is not a valid value in $filename");
        }

in \Drupal\Core\Extension\InfoParserDynamic::parse() did not act as expect on the 2nd call.

isConstraintSatisfiedByPreviousVersion() has static var that caches the results for any $constraint and $version combination.
It assumes false so it sets
$evaluated_constraints[$constraint][$version] = FALSE;
Before it evaluates the combination.

The first time the exception is thrown after this is set. The second time

if (!isset($evaluated_constraints[$constraint][$version])) {
is true because it was set to FALSE before the exception is thrown.

So the method returns false.

This is bad but it is not as bad as it could be further down in the function we have

$core_version_constraint = isset($parsed_info['core_version_requirement']) ? $parsed_info['core_version_requirement'] : $parsed_info['core'];
      $parsed_info['core_incompatible'] = !Semver::satisfies(\Drupal::VERSION, $core_version_constraint);

If core version is invalid but we had the problem above this line still thrown exception because the original exception came from Semver::satisfies() evaluating the same value.

The only problem is that the reason we catch the error in the first place is to make the exception better my mentioning the filename of the info.yml file like all other parser errors, for example for a missing type key.

So the first time the parser is called with a invalid core_version_requirement value then get the exception we make with the filename and the 2nd time you get the exception straight from Semver::satisfies() without the filename

This make clear the importance of #3119761: Replace multiple test methods in InfoParserUnitTest with 1 testInfoException and a dataprovider so all our test methods in this class always call 2x and otherwise act the same.

Proposed resolution

In \Drupal\Core\Extension\InfoParserDynamic::isConstraintSatisfiedByPreviousVersion catch any exceptions and
unset($evaluated_constraints[$constraint][$version]);
Then rethrow the exception. That any exception regardless of type will not result in a cached false value.

Remaining tasks

Do it

User interface changes

API changes

Data model changes

Release notes snippet

Comments

tedbow created an issue. See original summary.

tedbow’s picture

Status: Active » Needs review
StatusFileSize
new3.75 KB
new5.87 KB

Here is test only patch and test + fix patch.

We could fix this in #3119761: Replace multiple test methods in InfoParserUnitTest with 1 testInfoException and a dataprovider since the test method we are updating will be removed(but not the test case) but it seems better to keep that issue a test only issue.

Just to be clear of the importance #3119761. if that issue was done and we were then to add a test case like is covered in testUnparsableCoreVersionRequirement() we would only have to add the yml and expected exception message to the dataProvider. The new test method in that issue would always call the parser 2x times for all the test cases so we couldn't add a new test case and forget to check the case where the parser is called 2x.

We either forgot call the parser 2x in testUnparsableCoreVersionRequirement() or we added that method before we figured we need to test that.

It would be great to get this issue and then #3119761 in so can't find ourselves in this situation again.

The last submitted patch, 2: 3119822-test-only-FAIL.patch, failed testing. View results

tedbow’s picture

StatusFileSize
new3.82 KB
new2.04 KB

Test failed as expected

Drupal\Tests\Core\Extension\InfoParserUnitTest::testUnparsableCoreVersionRequirement
Failed asserting that exception of type "UnexpectedValueException" matches expected exception "Drupal\Core\Extension\InfoParserException". Message was: "Could not parse version constraint not-this-version: Invalid version string "not-this-version""

Important thing to notice here is an exception is still thrown just not the expected type and the message is also different. This is why I didn't mark the issue major.

Here is patch without the Drupalci changes.

damienmckenna’s picture

damienmckenna’s picture

Nope, the patch in #4 doesn't solve this new problem.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

quietone’s picture

Status: Needs review » Closed (outdated)
Issue tags: +Bug Smash Initiative

The method being changed in the patch was removed in #3077703: Remove pre-8.7.7 core compatibility checks in extension parsing. And reading the commit I think the problem has been fixed. But the patch here has a test that is not in core. Comment in #2 refers to #3119761: Replace multiple test methods in InfoParserUnitTest with 1 testInfoException and a dataprovider which has additional tests, including the one here.

Therefore, closing as outdated. If this is incorrect reopen the issue, by setting the status to 'Active', and add a comment explaining what still needs to be done.

Thanks!