Commit 7eaa1b76 authored by alexpott's avatar alexpott

Issue #2445761 by Wim Leers: Add a X-Drupal-Cache-Contexts header to aid in debugging and testing

parent 28e35f65
......@@ -129,21 +129,25 @@ public function renderResponse(array $main_content, Request $request, RouteMatch
}
$content = $this->renderer->render($html);
// Store the cache tags associated with this page in a X-Drupal-Cache-Tags
// header. Also associate the "rendered" cache tag. This allows us to
// invalidate the entire render cache, regardless of the cache bin.
$cache_tags = Cache::mergeTags(
isset($html['page_top']) ? $html['page_top']['#cache']['tags'] : [],
$html['page']['#cache']['tags'],
isset($html['page_bottom']) ? $html['page_bottom']['#cache']['tags'] : [],
['rendered']
);
// Expose the cache contexts and cache tags associated with this page in a
// X-Drupal-Cache-Contexts and X-Drupal-Cache-Tags header respectively. Also
// associate the "rendered" cache tag. This allows us to invalidate the
// entire render cache, regardless of the cache bin.
$cache_contexts = [];
$cache_tags = ['rendered'];
foreach (['page_top', 'page', 'page_bottom'] as $region) {
if (isset($html[$region])) {
$cache_contexts = Cache::mergeContexts($cache_contexts, $html[$region]['#cache']['contexts']);
$cache_tags = Cache::mergeTags($cache_tags, $html[$region]['#cache']['tags']);
}
}
// Set the generator in the HTTP header.
list($version) = explode('.', \Drupal::VERSION, 2);
return new Response($content, 200,[
'X-Drupal-Cache-Tags' => implode(' ', $cache_tags),
'X-Drupal-Cache-Contexts' => implode(' ', $cache_contexts),
'X-Generator' => 'Drupal ' . $version . ' (http://drupal.org)'
]);
}
......
......@@ -70,8 +70,19 @@ function testPageCacheTags() {
),
));
$cache_contexts = [
'language',
'menu.active_trail:account',
'menu.active_trail:footer',
'menu.active_trail:main',
'menu.active_trail:tools',
'theme',
'timezone',
'user.roles',
];
// Full node page 1.
$this->verifyPageCacheTags($node_1->urlInfo(), array(
$this->assertPageCacheContextsAndTags($node_1->urlInfo(), $cache_contexts, array(
'rendered',
'block_view',
'config:block_list',
......@@ -103,7 +114,7 @@ function testPageCacheTags() {
));
// Full node page 2.
$this->verifyPageCacheTags($node_2->urlInfo(), array(
$this->assertPageCacheContextsAndTags($node_2->urlInfo(), $cache_contexts, array(
'rendered',
'block_view',
'config:block_list',
......@@ -138,27 +149,37 @@ function testPageCacheTags() {
}
/**
* Fills page cache for the given path, verify cache tags on page cache hit.
* Asserts page cache miss, then hit for the given URL; checks cache headers.
*
* @param \Drupal\Core\Url $url
* The url
* @param $expected_tags
* The expected cache tags for the page cache entry of the given $path.
* The URL to test.
* @param string[] $expected_contexts
* The expected cache contexts for the given URL.
* @param string[] $expected_tags
* The expected cache tags for the given URL.
*/
protected function verifyPageCacheTags(Url $url, $expected_tags) {
// @todo Change ->drupalGet() calls to just pass $url when
// https://www.drupal.org/node/2350837 gets committed
protected function assertPageCacheContextsAndTags(Url $url, array $expected_contexts, array $expected_tags) {
$absolute_url = $url->setAbsolute()->toString();
sort($expected_contexts);
sort($expected_tags);
$this->drupalGet($url->setAbsolute()->toString());
// Assert cache miss + expected cache contexts + tags.
$this->drupalGet($absolute_url);
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS');
$actual_contexts = explode(' ', $this->drupalGetHeader('X-Drupal-Cache-Contexts'));
$actual_tags = explode(' ', $this->drupalGetHeader('X-Drupal-Cache-Tags'));
sort($actual_tags);
$this->assertIdentical($actual_contexts, $expected_contexts);
$this->assertIdentical($actual_tags, $expected_tags);
$this->drupalGet($url->setAbsolute()->toString());
// Assert cache hit + expected cache contexts + tags.
$this->drupalGet($absolute_url);
$actual_contexts = explode(' ', $this->drupalGetHeader('X-Drupal-Cache-Contexts'));
$actual_tags = explode(' ', $this->drupalGetHeader('X-Drupal-Cache-Tags'));
sort($actual_tags);
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT');
$this->assertIdentical($actual_contexts, $expected_contexts);
$this->assertIdentical($actual_tags, $expected_tags);
// Assert page cache item + expected cache tags.
$cid_parts = array($url->setAbsolute()->toString(), 'html');
$cid = implode(':', $cid_parts);
$cache_entry = \Drupal::cache('render')->get($cid);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment