Problem/Motivation

Blocked on #2512718: EntityManager::getTranslationFromContext() should add the content language cache context to the entity.
#2512718: EntityManager::getTranslationFromContext() should add the content language cache context to the entity introduces MutableCacheableDependencyInterface.

Proposed resolution

Update CacheableMetadata and AccessResult to use it. This is not an API change, because it just means creating an interface for methods they already have.

Remaining tasks

Do it.

User interface changes

None.

API changes

None.

Data model changes

None.

Beta phase evaluation

`

Reference: https://www.drupal.org/core/beta-changes
Issue category Task because nothing is broken, it's just very confusing.
Issue priority Major because this will significantly help DX.
Prioritized changes The main goal of this issue is DX, consistency — setting the right example.
Disruption Zero disruption.

Comments

pfrenssen’s picture

Title: [PP-1] Update CacheableMetadata & AccessResult to use MutableCacheableDependency(Interface|Trait) » [PP-1] Update CacheableMetadata & AccessResult to use RefinableCacheableDependency(Interface|Trait)

An implementation of this was already made for AccessResult in patches #83-#87 of #2524082: Config overrides should provide cacheability metadata. That is going to be removed again from that critical issue so it can move forwards, we can then do the implementation here.

The approach in that issue should be changed though so it is in line with what is done in #2525910: Ensure token replacements have cacheability + attachments metadata and that it is bubbled in any case. See comment #89 of #2524082-89: Config overrides should provide cacheability metadata.

jibran’s picture

berdir’s picture

Title: [PP-1] Update CacheableMetadata & AccessResult to use RefinableCacheableDependency(Interface|Trait) » Update CacheableMetadata & AccessResult to use RefinableCacheableDependency(Interface|Trait)
Status: Active » Needs review

Use the trait, luke!

I was also waiting for #2525910: Ensure token replacements have cacheability + attachments metadata and that it is bubbled in any case to land, since that adds the addCacheableDependency() method to CacheablityMetadata that we also want on this interface.

This will conflict/overlap with #2524082: Config overrides should provide cacheability metadata which adds similar things as commented above and I think it's actually doing quite a bit that overlaps with this I think.

Noticed a few funky things in AccessResult:

* It doesn't initialize the properties but explicitly and manually resets them in the constructor. That seems like a weird pattern that we don't use elsewhere, so removed
* Those reset methods are actually public, they're not used anywhere except in unit tests and I really don't see the point of them. AccessResult seems like the perfect example of a refinable cacheable dependency, why would you even allow to reset those things? The interface was specifically designed to now allow that.
* It has a inheritCacheability() method that *almost* behaves like addCacheableDependency(), but something about the cache max age is different, if you try to just call the new method then some unit tests fail.

AccessResult currently also doesn't validate the cache contexts, so adding them kills tons of unit tests which now need a global container. Some even need that in the data provider, which seems to be called *before* setUp, so we might actually need to initialize that in there. That's just sad. Maybe we can get of those again with some optimizations on empty cache contexts/tags. I'll work on that next and then try to remove those changes again. The thing is that right now, we end up adding almost as much code as we can remove "thanks" to those test changes.

Tests don't fully pass yet but I think the above issue needs to solve the same unit test fail, so not bothering to to that work again here.

berdir’s picture

StatusFileSize
new23.98 KB

And now with the patch.

berdir’s picture

Doing a bit of optimization but it doesn't seem to help much with the test fails, since for example a cachePerUser()/Permission() adds a cache context and then it's calls it anyway.

The last submitted patch, 4: trait-refinable-2526326-4.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 5: trait-refinable-2526326-5.patch, failed testing.

wim leers’s picture

RE: general AccessResult weirdness: it predates CacheableMetadata by many months.

RE: AccessResult::inheritCacheability(): that's because it really is designed for orIf() and andIf(). I wish we hadn't made it public. It first wasn't public.


  1. +++ b/core/lib/Drupal/Core/Access/AccessResult.php
    @@ -215,35 +180,22 @@ public function isNeutral() {
       public function getCacheContexts() {
    -    sort($this->contexts);
    -    return $this->contexts;
    +    sort($this->cacheContexts);
    +    return $this->cacheContexts;
    

    +1 to leaving it unchanged, but please know that this predates the existence of Cache::mergeContexts() (which is what does the sorting for all other places in core).

    So, we should actually be able to remove this sort().

  2. +++ b/core/lib/Drupal/Core/Access/AccessResult.php
    @@ -321,8 +260,7 @@ public function cachePerUser() {
       public function cacheUntilEntityChanges(EntityInterface $entity) {
    -    $this->addCacheTags($entity->getCacheTags());
    -    return $this;
    +    return $this->addCacheableDependency($entity);
       }
     
       /**
    @@ -334,8 +272,7 @@ public function cacheUntilEntityChanges(EntityInterface $entity) {
    
    @@ -334,8 +272,7 @@ public function cacheUntilEntityChanges(EntityInterface $entity) {
        * @return $this
        */
       public function cacheUntilConfigurationChanges(ConfigBase $configuration) {
    -    $this->addCacheTags($configuration->getCacheTags());
    -    return $this;
    +    return $this->addCacheableDependency($configuration);
       }
    

    YAY!


If you want, I can take a look at the remaining test failures?

dawehner’s picture

+++ b/core/modules/content_translation/tests/src/Unit/Access/ContentTranslationManageAccessCheckTest.php
index 6f352ae..c3a9f7a 100644
--- a/core/modules/quickedit/tests/src/Unit/Access/EditEntityFieldAccessCheckTest.php

+++ b/core/modules/quickedit/tests/src/Unit/Access/EditEntityFieldAccessCheckTest.php
@@ -33,6 +34,13 @@ class EditEntityFieldAccessCheckTest extends UnitTestCase {
   protected function setUp() {

This test is problematic, because we access the container in the data provider which is wrong, as it doesn't work when you run it only via phpunit. We need to move the AccessResult object creation into the actual test method.

xano’s picture

I'm fixing the tests.

xano’s picture

Status: Needs work » Needs review
StatusFileSize
new9.24 KB
new32.72 KB

Apart from the obvious test failures, it's good practice to keep the data providers simple, e.g. provide a matrix of plain test data and keep the logic in the testing method. I fixed the methods where this went wrong, and had to mock ::getCacheContexts() and ::getCacheMaxAge() in a few places. I hope those mocks behave correctly, and would appreciate feedback if what I did is wrong.

dawehner’s picture

I could not resist earlier: http://privatepaste.com/ae8285ce8d

wim leers’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/content_translation/tests/src/Unit/Access/ContentTranslationManageAccessCheckTest.php
    index c3a9f7a..5fba2b2 100644
    --- a/core/modules/quickedit/tests/src/Unit/Access/EditEntityFieldAccessCheckTest.php
    

    The clean-up you did here to address #9 is beautiful! Thank you!

  2. +++ b/core/modules/quickedit/tests/src/Unit/Access/EditEntityFieldAccessCheckTest.php
    @@ -84,16 +61,28 @@ public function providerTestAccess() {
    +  public function testAccess($entity_is_editable, $field_storage_access, AccessResult $expected_result) {
    

    s/$field_storage_access/$field_storage_is_accessible/

  3. +++ b/core/tests/Drupal/Tests/Core/Access/AccessResultTest.php
    @@ -856,6 +876,10 @@ public function testAllowedIfHasPermissions($permissions, $conjunction, $expecte
    +    if ($permissions) {
    +      $expected_access->cachePerPermissions();
    +    }
    +
         $access_result = AccessResult::allowedIfHasPermissions($account, $permissions, $conjunction);
         $this->assertEquals($expected_access, $access_result);
       }
    @@ -869,14 +893,14 @@ public function providerTestAllowedIfHasPermissions() {
    
    @@ -869,14 +893,14 @@ public function providerTestAllowedIfHasPermissions() {
         return [
           [[], 'AND', AccessResult::allowedIf(FALSE)],
           [[], 'OR', AccessResult::allowedIf(FALSE)],
    -      [['allowed'], 'OR', AccessResult::allowedIf(TRUE)->addCacheContexts(['user.permissions'])],
    -      [['allowed'], 'AND', AccessResult::allowedIf(TRUE)->addCacheContexts(['user.permissions'])],
    -      [['denied'], 'OR', AccessResult::allowedIf(FALSE)->addCacheContexts(['user.permissions'])],
    -      [['denied'], 'AND', AccessResult::allowedIf(FALSE)->addCacheContexts(['user.permissions'])],
    -      [['allowed', 'denied'], 'OR', AccessResult::allowedIf(TRUE)->addCacheContexts(['user.permissions'])],
    -      [['denied', 'allowed'], 'OR', AccessResult::allowedIf(TRUE)->addCacheContexts(['user.permissions'])],
    -      [['allowed', 'denied', 'other'], 'OR', AccessResult::allowedIf(TRUE)->addCacheContexts(['user.permissions'])],
    -      [['allowed', 'denied'], 'AND', AccessResult::allowedIf(FALSE)->addCacheContexts(['user.permissions'])],
    +      [['allowed'], 'OR', AccessResult::allowedIf(TRUE)],
    +      [['allowed'], 'AND', AccessResult::allowedIf(TRUE)],
    +      [['denied'], 'OR', AccessResult::allowedIf(FALSE)],
    +      [['denied'], 'AND', AccessResult::allowedIf(FALSE)],
    +      [['allowed', 'denied'], 'OR', AccessResult::allowedIf(TRUE)],
    +      [['denied', 'allowed'], 'OR', AccessResult::allowedIf(TRUE)],
    +      [['allowed', 'denied', 'other'], 'OR', AccessResult::allowedIf(TRUE)],
    +      [['allowed', 'denied'], 'AND', AccessResult::allowedIf(FALSE)],
    

    This seems like an unnecessary bit of clean-up, and I'm not sure if it makes things actually cleaner/clearer?

    Can you explain why you made this change?

berdir’s picture

See #9. It's not allowed to call out to the container in a data provider method, or at least a very bad idea.

berdir’s picture

Status: Needs work » Needs review
StatusFileSize
new29.17 KB
new32.81 KB
new14.58 KB

Reroll, this is why I was waiting for that other issue to continue with this :)

Found one small bug there with the AccessResult unit tests ($this->maxAge = 0 when it should be $this->cacheMaxAge), but could remove a lot of code because that issue added it already and also fixed quite a few tests.

Converted one more provider. Still have an error on FormBuilderTest::testChildAccessInheritance. But I only get those errors if I run all the tests in tests/, not if I filter on running just that test.

berdir’s picture

Ignore the first patch, start uploading and then fixed some unit tests...

The last submitted patch, 15: drupal_2526326_15.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 15: drupal_2526326_15.patch, failed testing.

berdir’s picture

Status: Needs work » Needs review
StatusFileSize
new32.31 KB
new510 bytes
wim leers’s picture

StatusFileSize
new34.63 KB
new4.12 KB

#14: Oh, right, that results in indirect container calls. Thanks!


#15:

Reroll, this is why I was waiting for that other issue to continue with this :)

:)


Here's a full review.

  1. +++ b/core/lib/Drupal/Core/Access/AccessResult.php
    @@ -252,20 +203,7 @@ public function addCacheContexts(array $contexts) {
    +    $this->cacheContexts = array();
    
    @@ -275,7 +213,7 @@ public function addCacheTags(array $tags) {
    +    $this->cacheTags = array();
    

    If we're touching these lines anyway, let's also use [].

  2. +++ b/core/lib/Drupal/Core/Access/AccessResult.php
    @@ -343,28 +281,6 @@ public function cacheUntilConfigurationChanges(ConfigBase $configuration) {
    -  public function addCacheableDependency($other_object) {
    

    Yay!

  3. +++ b/core/lib/Drupal/Core/Cache/CacheableMetadata.php
    @@ -128,36 +81,7 @@ public function setCacheMaxAge($max_age) {
    -  public function addCacheableDependency($other_object) {
    

    Yay!

  4. +++ b/core/lib/Drupal/Core/Cache/RefinableCacheableDependencyTrait.php
    @@ -53,7 +53,9 @@ public function addCacheableDependency($other_object) {
    -    $this->cacheContexts = Cache::mergeContexts($this->cacheContexts, $cache_contexts);
    +    if ($cache_contexts) {
    +      $this->cacheContexts = Cache::mergeContexts($this->cacheContexts, $cache_contexts);
    +    }
    
    @@ -61,7 +63,9 @@ public function addCacheContexts(array $cache_contexts) {
    -    $this->cacheTags = Cache::mergeTags($this->cacheTags, $cache_tags);
    +    if ($cache_tags) {
    +      $this->cacheTags = Cache::mergeTags($this->cacheTags, $cache_tags);
    +    }
    

    Sensible optimizations.

  5. +++ b/core/modules/quickedit/tests/src/Unit/Access/EditEntityFieldAccessCheckTest.php
    @@ -33,6 +35,11 @@ class EditEntityFieldAccessCheckTest extends UnitTestCase {
    +    $cache_contexts_manager = $this->prophesize(CacheContextsManager::class)->reveal();
    

    <3

  6. +++ b/core/tests/Drupal/Tests/Core/Access/AccessResultTest.php
    @@ -852,8 +851,16 @@ public function testOrIfCacheabilityMerging() {
    +   *   The conjunction to use when checking for permission. Either 'AND" or
    

    Nit: inconsistent quotes. Fixed. Also reworded to fit on one line.

  7. +++ b/core/tests/Drupal/Tests/Core/Entity/EntityAccessCheckTest.php
    @@ -25,6 +27,12 @@ class EntityAccessCheckTest extends UnitTestCase {
       public function testAccess() {
    +
    +    $cache_contexts_manager = $this->prophesize(CacheContextsManager::class)->reveal();
    

    Nit: needless blank line. Fixed.

  8. +++ b/core/tests/Drupal/Tests/Core/Route/RoleAccessCheckTest.php
    @@ -143,6 +145,12 @@ public function roleAccessProvider() {
       public function testRoleAccess($path, $grant_accounts, $deny_accounts) {
    +
    +    $cache_contexts_manager = $this->prophesize(CacheContextsManager::class)->reveal();
    

    Same nit. Fixed.


RE: the inheritCacheability() confusingness — I propose we deprecate that method in a follow-up (it's clearly out of scope). But what is in scope, is making it not duplicate that much anymore. So, I did that, and added docs explaining the difference. Nevertheless it is still quite confusing, which is why I think we should deprecate it in a follow-up, and remove at least the callers in core.

wim leers’s picture

The patch in #19 is RTBC IMO. In #20, I only simplified and documented inheritCacheability() to the extent that that is reasonably in scope for this issue.

Therefore, if Berdir agrees with the changes I made in #20, I think this is RTBC.

jibran’s picture

Issue tags: +Needs beta evaluation
borisson_’s picture

StatusFileSize
new667 bytes
new33.81 KB

I added a patch to use short-array syntax over the old array syntax in resetCacheContexts and resetCacheTags. This was the only thing I noticed when reviewing the patch.

wim leers’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs beta evaluation

OMG we totally lost track of this!

alexpott’s picture

Status: Reviewed & tested by the community » Needs review

@borisson_ short array syntax is preferred not required, just recommended.

  1. 1) Warning
    The data provider specified for Drupal\Tests\Core\Form\FormBuilderTest::testChildAccessInheritance is invalid.
    \Drupal::$container is not initialized yet. \Drupal::setContainer() must be called with a real container.
    
    2) Warning
    The data provider specified for Drupal\Tests\system\Unit\Menu\MenuLinkTreeTest::testBuildCacheability is invalid.
    \Drupal::$container is not initialized yet. \Drupal::setContainer() must be called with a real container.
    
    3) Warning
    The data provider specified for Drupal\Tests\user\Unit\PermissionAccessCheckTest::testAccess is invalid.
    \Drupal::$container is not initialized yet. \Drupal::setContainer() must be called with a real container.
    

    Lucky I run phpunit on commit :)

  2. diff --git a/core/modules/content_translation/tests/src/Unit/Access/ContentTranslationManageAccessCheckTest.php b/core/modules/content_translation/tests/src/Unit/Access/ContentTranslationManageAccessCheckTest.php
    index 266a89b..0818be2 100644
    --- a/core/modules/content_translation/tests/src/Unit/Access/ContentTranslationManageAccessCheckTest.php
    +++ b/core/modules/content_translation/tests/src/Unit/Access/ContentTranslationManageAccessCheckTest.php
    @@ -11,7 +11,6 @@
     use Drupal\Core\Access\AccessResult;
     use Drupal\Core\DependencyInjection\ContainerBuilder;
     use Drupal\Core\Cache\Cache;
    -use Drupal\Core\DependencyInjection\Container;
     use Drupal\Core\Language\Language;
     use Drupal\Tests\UnitTestCase;
     use Symfony\Component\Routing\Route;
    diff --git a/core/modules/quickedit/tests/src/Unit/Access/EditEntityFieldAccessCheckTest.php b/core/modules/quickedit/tests/src/Unit/Access/EditEntityFieldAccessCheckTest.php
    index 8b91791..26a1c86 100644
    --- a/core/modules/quickedit/tests/src/Unit/Access/EditEntityFieldAccessCheckTest.php
    +++ b/core/modules/quickedit/tests/src/Unit/Access/EditEntityFieldAccessCheckTest.php
    @@ -12,8 +12,6 @@
     use Drupal\Core\DependencyInjection\Container;
     use Drupal\quickedit\Access\EditEntityFieldAccessCheck;
     use Drupal\Tests\UnitTestCase;
    -use Drupal\field\FieldStorageConfigInterface;
    -use Drupal\Core\Entity\EntityInterface;
     use Drupal\Core\Language\LanguageInterface;
     
     /**
    

    Unused use statements.

alexpott queued 23: update-2526326-23.patch for re-testing.

borisson_’s picture

StatusFileSize
new3.97 KB
new36.44 KB

The failures seem to originate from this line: \Drupal::service('cache_contexts_manager')->validateTokens($cache_contexts); in \Drupal\Core\Cache\Cache::mergeContexts

<?php
$this->container = new ContainerBuilder();
$cache_contexts_manager = $this->prophesize(CacheContextsManager::class)->reveal();
$this->container->set('cache_contexts_manager', $cache_contexts_manager);
\Drupal::setContainer($this->container);
?>

This piece of code was already added in a bunch of tests (RoleAccessCheckTest, DefaultMenuLinkTreeManipulatorsTest, EntityCreateAccessCheckTest, EntityAccessCheckTest, AccessManagerTest, UserAccessControlHandlerTest, EditEntityFieldAccessCheckTest), so I added that in PermissionAccessCheckTest and FormBuilderTest. MenuLinkTreeTest already had similar code (but it doesn't use prophecy yet, I can change that but that might be out of scope for this patch),

Attached patch also fixes the unused uses.

wim leers’s picture

Status: Needs review » Reviewed & tested by the community
borisson_’s picture

Status: Reviewed & tested by the community » Needs work

Test still fail when running phpunit -c core, so shouldn't be RTBC yet.

wim leers’s picture

Oh. I misread.

borisson_’s picture

StatusFileSize
new2.07 KB
new38.2 KB

So the reason those tests fail is because the *provider methods call out to the service container. Making sure that the calls to the container (that happen in ->addCacheContexts($contexts).

Attached patch fixes PermissionAccessCheckTest.

FormBuilderTest and MenuLinkTreeTest still fail, but those *providers are not as straightforward as the one in PermissionAccessCheckTest.

wim leers’s picture

Status: Needs work » Needs review
borisson_’s picture

StatusFileSize
new3.66 KB
new41.6 KB

This should fix all the tests.

borisson_’s picture

I'm not really happy with how "easy" it was to fix FormBuilderTest, filed a followup to look at that in more detail: #2550933: Refactor FormBuilderTest::testChildAccessInheritance

wim leers’s picture

Status: Needs review » Needs work
  1. --- a/core/modules/system/tests/src/Unit/Menu/MenuLinkTreeTest.php
    +++ b/core/modules/system/tests/src/Unit/Menu/MenuLinkTreeTest.php
    

    Changes here look great.

  2. +++ b/core/modules/system/tests/src/Unit/Menu/MenuLinkTreeTest.php
    --- a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
    +++ b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
    

    Like you indicated on IRC, the changes here look spotty.

  3. +++ b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
    @@ -592,7 +592,7 @@ public function providerTestChildAccessInheritance() {
    -    $access_result = AccessResult::forbidden()->addCacheContexts(['user']);
    +    $access_result = AccessResult::forbidden();
         $clone['#access'] = $access_result;
     
         $expected_access = [];
    @@ -624,11 +624,9 @@ public function providerTestChildAccessInheritance() {
    
    @@ -624,11 +624,9 @@ public function providerTestChildAccessInheritance() {
     
         // Allow access on the most outer level but forbid otherwise.
         $clone = $element;
    -    $access_result_allowed = AccessResult::allowed()
    -      ->addCacheContexts(['user']);
    +    $access_result_allowed = AccessResult::allowed();
         $clone['#access'] = $access_result_allowed;
    -    $access_result_forbidden = AccessResult::forbidden()
    -      ->addCacheContexts(['user']);
    +    $access_result_forbidden = AccessResult::forbidden();
    

    However, these changes are merely changing both the input and the expected output to not have cache contexts. That's it.

    Since this test is really only about testing the behavior of #access set to a forbidden access result at the root of a render tree, that is totally fine. The cacheability metadata is not essential for testing here. It's #access's support for AccessResultInterface objects that we're testing.

    However, we can even continue to test cacheability here. Just don't test with cache contexts, which use an external service. Use max-age instead :)

    NW for changing these from using the user cache context to max-age (pick any value you like, I'd say pick a fun number :)).

Then, we should be able to finally get this in :)

borisson_’s picture

Status: Needs work » Needs review
StatusFileSize
new1.8 KB
new42.29 KB

Changed to use max-age, also testing if max-age is set.

wim leers’s picture

  1. +++ b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
    @@ -19,6 +19,8 @@
    +use Drupal\Core\Cache\Context\CacheContextsManager;
    +use Symfony\Component\DependencyInjection\ContainerBuilder;
    
    @@ -27,6 +29,25 @@
       /**
    +   * The dependency injection container.
    +   *
    +   * @var \Symfony\Component\DependencyInjection\ContainerBuilder
    +   */
    +  protected $container;
    +
    +  /**
    +   * {@inheritdoc}
    +   */
    +  protected function setUp() {
    +    parent::setUp();
    +
    +    $this->container = new ContainerBuilder();
    +    $cache_contexts_manager = $this->prophesize(CacheContextsManager::class)->reveal();
    +    $this->container->set('cache_contexts_manager', $cache_contexts_manager);
    +    \Drupal::setContainer($this->container);
    +  }
    +
    +  /**
    

    These changes can now be reverted.

  2. +++ b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
    @@ -521,6 +542,14 @@ public function testChildAccessInheritance($element, $access_checks) {
    +
    +      if ($actual_access instanceof AccessResult) {
    +        $this->assertEquals(42, $actual_access->getCacheMaxAge());
    +      }
    +    }
    +
    +    if ($element['#access'] instanceof AccessResult) {
    +      $this->assertEquals(42, $element['#access']->getCacheMaxAge());
         }
    

    This is again specifically testing cacheability. We don't want to do that here, that's not what the test is about. So, then, let's remove the max-age stuff altogether, just like you had in the previous patch.

borisson_’s picture

StatusFileSize
new41.6 KB

I discussed this in IRC with @Wim Leers, the patch in #36 is testing side effects and that shouldn't be needed. Reverted back to #33 and reuploading patch.

The last submitted patch, 36: update-2526326-36.patch, failed testing.

wim leers’s picture

Status: Needs review » Reviewed & tested by the community

Came back green on DrupalCI, let's get this in finally :)

Hurray for more consistency in dealing with cacheability metadata!

Thanks for your patience, @borisson_!

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 38: update-2526326-33.patch, failed testing.

wim leers’s picture

Status: Needs work » Reviewed & tested by the community

Crazy errors like

PHP Fatal error:  Uncaught exception 'ReflectionException' with message 'Class Twig_ExtensionInterface does not exist' in /var/lib/drupaltestbot/sites/default/files/checkout/core/lib/Drupal/Core/DependencyInjection/Compiler/TaggedHandlersPass.php:99

Looks like testbot was temporarily broken. Re-testing.

Wim Leers queued 38: update-2526326-33.patch for re-testing.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed 9435942 and pushed to 8.0.x. Thanks!

Thanks for adding the beta evaluation to the issue summary.

  • alexpott committed 9435942 on 8.0.x
    Issue #2526326 by borisson_, Berdir, Wim Leers, Xano: Update...
wim leers’s picture

YAY! :)

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.