Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
It looks like all the cache constants (DRUPAL_CACHE_PER_ROLE, etc.) have the same effect for block caching as DRUPAL_CACHE_GLOBAL. In other words, the granularity for block caching is broken. I'm currently writing some tests to verify this.
Comment | File | Size | Author |
---|---|---|---|
#33 | block-cache-tests-plus-fix.5.patch | 9.52 KB | carlos8f |
#26 | block-cache-tests-plus-fix.4.patch | 8.89 KB | carlos8f |
#24 | block-cache-tests-plus-fix.3.patch | 8.76 KB | carlos8f |
#22 | block-cache-tests-plus-fix.2.patch | 8.86 KB | carlos8f |
#21 | block-cache-test.patch | 8.76 KB | mr.baileys |
Comments
Comment #1
tstoecklerIs this related or duplicate to/of: #235673: Changes to block caching mode not caught?
Comment #2
carlos8f CreditAttribution: carlos8f commentedThat is a separate issue, but related. In HEAD, block caching seems to be "all or nothing", even when the proper cache value is stored in the {block} table.
Comment #3
carlos8f CreditAttribution: carlos8f commentedNo test coverage exists for block caching yet. Here are some I've written, indicating that per-user, per-role and per-page block caching are broken. DRUPAL_CACHE_GLOBAL and DRUPAL_NO_CACHE are working.
The next step is to debug the actual issue with the granularity. Setting to 'needs review' to record the fails (there should be 4).
Comment #4
carlos8f CreditAttribution: carlos8f commented...and the patch :)
Comment #5
carlos8f CreditAttribution: carlos8f commentedComment #6
tstoecklerI don't see how that is going to work. Since you're getting the text right from the database, the text you're asserting on is always going to be the non-cached one, so I don't see why this is a "assertNoText". An "assertText" wouldn't make sense here either, you should assert on $old_content, except then you should move the cache_clear_all() to after that.
I think.
Haven't tried it out. Please ignore if that was complete nonsense.
Comment #7
tstoecklerCross-post.
Fixing title
Comment #9
carlos8f CreditAttribution: carlos8f commentedI may have messed up on that assert, I'll check that later. Regardless, I think it's clear that there is a critical bug here.
Comment #10
moshe weitzman CreditAttribution: moshe weitzman commentedsubscribe
Comment #11
carlos8f CreditAttribution: carlos8f commentedTurns out that this is a really trivial fix:
ptah. += isn't appropriate here on the numeric array.
Looks like the last thing to figure out is, why a user with the same role-set isn't seeing the per-role cache. It might be a quirk in the way SimpleTest generates users and roles. I already had to manually copy $normal_user->roles to $normal_user_alt->roles, since DWTC->drupalCreateUser() generates new roles for each user, regardless of the permission set passed. Possibly $user->uid is getting added to the cache cid.
Comment #12
Dries CreditAttribution: Dries commentedNice catch. I'd be very interested to see how that affects our benchmarks.
Comment #13
carlos8f CreditAttribution: carlos8f commentedTo be clear, there is no expected effect on benchmarks. In HEAD, the cache is at least served, but the granularity is broken. That's a functionality-breaking bug rather than a performance one.
One example is that blocks cached for a certain user (DRUPAL_CACHE_PER_USER) would get shown to all other users, creating a security problem. Also, blocks whose content is dynamic based on the current path (DRUPAL_CACHE_PER_PAGE) would have their content all mixed up. Things like that :)
Comment #14
Dries CreditAttribution: Dries commentedGot it. Committed to CVS HEAD. Thanks for writing tests.
Comment #15
carlos8f CreditAttribution: carlos8f commentedWhoa Dries! This wasn't ready yet. This was also an incomplete commit: the tests depend on the new block_test.module, in the new tests directory, which wasn't committed. The new tests also have one fail, which needs to be addressed. See http://qa.drupal.org/pifr/test/26444. Please roll back the commit!
Comment #16
carlos8f CreditAttribution: carlos8f commentedadding to RTBC queue, for the roll-back :)
Comment #17
carlos8f CreditAttribution: carlos8f commentedbroke HEAD:
http://qa.drupal.org/head-status
Comment #18
Dries CreditAttribution: Dries commentedSorry about that. I rolled it back for now.
Comment #19
int CreditAttribution: int commentedComment #20
marcingy CreditAttribution: marcingy commentedresetting status
Comment #21
mr.baileysThis won't work as it only alters the in-memory copy of the account.
Attached updates the patch so the role synchronization is persisted, all tests now pass. I have not reviewed the rest of the patch.
Powered by Dreditor.
Comment #22
carlos8f CreditAttribution: carlos8f commentedThanks, that would definitely explain it.
I added back the
$this->normal_user_alt->roles = $this->normal_user->roles
line since we might as well maintain the same roles in memory as well.Also tweaked a couple of the code comments and removed the call to _block_rehash() in BlockCacheTestCase::setCacheMode() since it was unnecessary.
Now just need someone to review.
Comment #23
tstoecklerMinor: Is there any reason this user needs 'administer filters'?
All in all, the tests look good and it seems like they cover everything. They pass locally and I didn't really know what to test manually.
So, from my view, RTBC if the test bot agrees, but I'll let someone more knowledgeable than me, make the decision.
Powered by Dreditor.
Comment #24
carlos8f CreditAttribution: carlos8f commentedRemoved 'administer filters'. It was only there because I copied it from BlockTestCase.
Comment #25
mr.baileysLooks pretty good to me... Some minor nitpicks:
I would add an additional positive assertion here to make sure the new, non-cached, content *is* displayed.
Should be 'info' => t('Test block caching'),
Should be package = Testing similar to how other test modules are set up.
Powered by Dreditor.
Comment #26
carlos8f CreditAttribution: carlos8f commentedThanks for the input, mr.baileys. I incorporated your changes.
Comment #27
mr.baileysOk, one final question from me and then I think this is RTBC (and I might be totally missing something here):
User 1 is always excluded from block caching:
This means it should not be used to check caching per role (as it will never see cached content, irregardless of role). I think it's ok to just drop those three lines alltogether, since I think we have full coverage between the "anonymous user" role and the normal_user/normal_user_alt role, right?
On the other hand, we probably want to add a couple of lines to each test to verify that admin user never gets to see cached content, even though for example caching is set to DRUPAL_CACHE_PAGE and the admin user visits a page which has cached blocks on it.
Does that make sense?
In light of the above, I don't understand why the following test case succeeds:
Since the first page is requested as "admin" (set in setUp), no blocks should be cached, and the second page request should serve fresh content instead of cached content. No?
Powered by Dreditor.
Comment #28
carlos8f CreditAttribution: carlos8f commentedmr.baileys, as far as my knowledge goes, user #1 is created as part of SimpleTest's DWTC::setUp(), so technically the user I'm creating called $admin_user is user #2, which is subject to permission limitations. This is correct for test cases so permissions can figure into the tests. It verifies that 'administer blocks' and 'access administration pages' are actually the permissions needed to administer blocks.
I think it's valuable to test block cache functionality for user #2 (administer blocks), user #3 (access content) and user #4 (same as #3) as well as the anonymous user. Just testing the difference between #3 and anonymous doesn't really test PER_ROLE in my opinion, since we treat the anonymous user specially in a lot of cases, especially when it comes to caching. Comparing #2 to #3 makes sense to test PER_ROLE for authenticated users.
That said, I could add a part to test if user #1 is not seeing cached blocks. I'm not sure if that's really important though. It's the other situations that are broken :)
Comment #29
mr.baileysI knew I was missing something obvious, thanks for clearing that up!
A one line fix and an impressive 200 lines of tests to prove that the fix works and to make sure this doesn't get broken again, RTBC!
Comment #30
Dries CreditAttribution: Dries commentedNice work! Great tests. Some feedback -- nothing major:
Wishlist: would be nice if drupalCreateUser() would take a role as input, instead of permissions. That would avoid these kind of hacks and would align with how Drupal works. Not for this issue though.
Mmm, it looks like we're mixing booleans and integers.
Maybe we can tidy that up too?
Small code optimization: this could be moved up as it would avoid the previous variable_get(). This pattern occurs a few times.
Inconsistent documentation. You don't use the defines in the other phpdoc comments.
Comment #31
mr.baileysMaybe worthwile to revisit #463354: Support custom role name in drupalCreateUser()?
Comment #32
catchLooks like this needs a quick re-roll for the rest.
Comment #33
carlos8f CreditAttribution: carlos8f commentedLet's give this one a try.
Comment #34
carlos8f CreditAttribution: carlos8f commentedCreated #727964: Test users in SimpleTest can't share roles to address the role problem.
Comment #35
Dries CreditAttribution: Dries commentedCommitted to CVS HEAD. Thanks carlos8f and mr.baileys.
Comment #36
Damien Tournoud CreditAttribution: Damien Tournoud commentedSeems like HEAD is broken:
Comment #37
Damien Tournoud CreditAttribution: Damien Tournoud commentedHEAD is broken because the helper test module has not been committed:
Comment #38
Damien Tournoud CreditAttribution: Damien Tournoud commentedNow fixed. Thanks, Dries.