VariationCacheTest.php
Same filename in other branches
Namespace
Drupal\Tests\Core\CacheFile
-
core/
tests/ Drupal/ Tests/ Core/ Cache/ VariationCacheTest.php
View source
<?php
declare (strict_types=1);
namespace Drupal\Tests\Core\Cache;
use Drupal\Component\Datetime\Time;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Cache\CacheRedirect;
use Drupal\Core\Cache\Context\CacheContextsManager;
use Drupal\Core\Cache\Context\ContextCacheKeys;
use Drupal\Core\Cache\MemoryBackend;
use Drupal\Core\Cache\VariationCache;
use Drupal\Tests\UnitTestCase;
use Prophecy\Argument;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* @coversDefaultClass \Drupal\Core\Cache\VariationCache
* @group Cache
*/
class VariationCacheTest extends UnitTestCase {
/**
* The prophesized request stack.
*
* @var \Symfony\Component\HttpFoundation\RequestStack|\Prophecy\Prophecy\ProphecyInterface
*/
protected $requestStack;
/**
* The backend used by the variation cache.
*
* @var \Drupal\Core\Cache\MemoryBackend
*/
protected $memoryBackend;
/**
* The prophesized cache contexts manager.
*
* @var \Drupal\Core\Cache\Context\CacheContextsManager|\Prophecy\Prophecy\ProphecyInterface
*/
protected $cacheContextsManager;
/**
* The variation cache instance.
*
* @var \Drupal\Core\Cache\VariationCacheInterface
*/
protected $variationCache;
/**
* The cache keys this test will store things under.
*
* @var string[]
*/
protected $cacheKeys = [
'your',
'housing',
'situation',
];
/**
* The cache ID for the cache keys, without taking contexts into account.
*
* @var string
*/
protected $cacheIdBase = 'your:housing:situation';
/**
* The simulated current user's housing type.
*
* For use in tests with cache contexts.
*
* @var string
*/
protected $housingType;
/**
* The cacheability for something that only varies per housing type.
*
* @var \Drupal\Core\Cache\CacheableMetadata
*/
protected $housingTypeCacheability;
/**
* The simulated current user's garden type.
*
* For use in tests with cache contexts.
*
* @var string
*/
protected $gardenType;
/**
* The cacheability for something that varies per housing and garden type.
*
* @var \Drupal\Core\Cache\CacheableMetadata
*/
protected $gardenTypeCacheability;
/**
* The simulated current user's house's orientation.
*
* For use in tests with cache contexts.
*
* @var string
*/
protected $houseOrientation;
/**
* The cacheability for varying per housing, garden and orientation.
*
* @var \Drupal\Core\Cache\CacheableMetadata
*/
protected $houseOrientationCacheability;
/**
* The simulated current user's solar panel type.
*
* For use in tests with cache contexts.
*
* @var string
*/
protected $solarType;
/**
* {@inheritdoc}
*/
protected function setUp() : void {
parent::setUp();
$this->requestStack = $this->prophesize(RequestStack::class);
$this->memoryBackend = new MemoryBackend(new Time());
$this->cacheContextsManager = $this->prophesize(CacheContextsManager::class);
$housing_type =& $this->housingType;
$garden_type =& $this->gardenType;
$house_orientation =& $this->houseOrientation;
$solar_type =& $this->solarType;
$this->cacheContextsManager
->convertTokensToKeys(Argument::any())
->will(function ($args) use (&$housing_type, &$garden_type, &$house_orientation, &$solar_type) {
$keys = [];
foreach ($args[0] as $context_id) {
switch ($context_id) {
case 'house.type':
$keys[] = "ht.{$housing_type}";
break;
case 'garden.type':
$keys[] = "gt.{$garden_type}";
break;
case 'house.orientation':
$keys[] = "ho.{$house_orientation}";
break;
case 'solar.type':
$keys[] = "st.{$solar_type}";
break;
default:
$keys[] = $context_id;
}
}
return new ContextCacheKeys($keys);
});
$this->variationCache = new VariationCache($this->requestStack
->reveal(), $this->memoryBackend, $this->cacheContextsManager
->reveal());
$this->housingTypeCacheability = (new CacheableMetadata())->setCacheTags([
'foo',
])
->setCacheContexts([
'house.type',
]);
$this->gardenTypeCacheability = (new CacheableMetadata())->setCacheTags([
'bar',
])
->setCacheContexts([
'house.type',
'garden.type',
]);
$this->houseOrientationCacheability = (new CacheableMetadata())->setCacheTags([
'baz',
])
->setCacheContexts([
'house.type',
'garden.type',
'house.orientation',
]);
}
/**
* Tests a cache item that has no variations.
*
* @covers ::get
* @covers ::set
*/
public function testNoVariations() : void {
$data = 'You have a nice house!';
$cacheability = (new CacheableMetadata())->setCacheTags([
'bar',
'foo',
]);
$initial_cacheability = (new CacheableMetadata())->setCacheTags([
'foo',
]);
$this->setVariationCacheItem($data, $cacheability, $initial_cacheability);
$this->assertVariationCacheItem($data, $cacheability, $initial_cacheability);
}
/**
* Tests a cache item that only ever varies by one context.
*
* @covers ::get
* @covers ::set
*/
public function testSingleVariation() : void {
$cacheability = $this->housingTypeCacheability;
$house_data = [
'apartment' => 'You have a nice apartment',
'house' => 'You have a nice house',
];
foreach ($house_data as $housing_type => $data) {
$this->housingType = $housing_type;
$this->assertVariationCacheMiss($cacheability);
$this->setVariationCacheItem($data, $cacheability, $cacheability);
$this->assertVariationCacheItem($data, $cacheability, $cacheability);
$this->assertCacheBackendItem("{$this->cacheIdBase}:ht.{$housing_type}", $data, $cacheability);
}
}
/**
* Tests a cache item that has nested variations.
*
* @covers ::get
* @covers ::set
*/
public function testNestedVariations() : void {
// We are running this scenario in the best possible outcome: The redirects
// are stored in expanding order, meaning the simplest one is stored first
// and the nested ones are stored in subsequent ::set() calls. This means no
// self-healing takes place where overly specific redirects are overwritten
// with simpler ones.
$possible_outcomes = [
'apartment' => 'You have a nice apartment!',
'house|no-garden' => 'You have a nice house!',
'house|garden|east' => 'You have a nice house with an east-facing garden!',
'house|garden|south' => 'You have a nice house with a south-facing garden!',
'house|garden|west' => 'You have a nice house with a west-facing garden!',
'house|garden|north' => 'You have a nice house with a north-facing garden!',
];
foreach ($possible_outcomes as $cache_context_values => $data) {
[
$this->housingType,
$this->gardenType,
$this->houseOrientation,
] = explode('|', $cache_context_values . '||');
$cacheability = $this->housingTypeCacheability;
if (!empty($this->houseOrientation)) {
$cacheability = $this->houseOrientationCacheability;
}
elseif (!empty($this->gardenType)) {
$cacheability = $this->gardenTypeCacheability;
}
$this->assertVariationCacheMiss($this->housingTypeCacheability);
$this->setVariationCacheItem($data, $cacheability, $this->housingTypeCacheability);
$this->assertVariationCacheItem($data, $cacheability, $this->housingTypeCacheability);
$cache_id_parts = [
"ht.{$this->housingType}",
];
if (!empty($this->gardenType)) {
$this->assertCacheBackendItem($this->getSortedCacheId($cache_id_parts), new CacheRedirect($this->gardenTypeCacheability));
$cache_id_parts[] = "gt.{$this->gardenType}";
}
if (!empty($this->houseOrientation)) {
$this->assertCacheBackendItem($this->getSortedCacheId($cache_id_parts), new CacheRedirect($this->houseOrientationCacheability));
$cache_id_parts[] = "ho.{$this->houseOrientation}";
}
$this->assertCacheBackendItem($this->getSortedCacheId($cache_id_parts), $data, $cacheability);
}
}
/**
* Tests a cache item that has nested variations that trigger self-healing.
*
* @covers ::get
* @covers ::set
*
* @depends testNestedVariations
*/
public function testNestedVariationsSelfHealing() : void {
// This is the worst possible scenario: A very specific item was stored
// first, followed by a less specific one. This means an overly specific
// cache redirect was stored that needs to be dumbed down. After this
// process, the first ::get() for the more specific item will fail as we
// have effectively destroyed the path to said item. Setting an item of the
// same specificity will restore the path for all items of said specificity.
$cache_id_parts = [
'ht.house',
];
$possible_outcomes = [
'house|garden|east' => 'You have a nice house with an east-facing garden!',
'house|garden|south' => 'You have a nice house with a south-facing garden!',
'house|garden|west' => 'You have a nice house with a west-facing garden!',
'house|garden|north' => 'You have a nice house with a north-facing garden!',
];
foreach ($possible_outcomes as $cache_context_values => $data) {
[
$this->housingType,
$this->gardenType,
$this->houseOrientation,
] = explode('|', $cache_context_values . '||');
$this->setVariationCacheItem($data, $this->houseOrientationCacheability, $this->housingTypeCacheability);
}
// Verify that the overly specific redirect is stored at the first possible
// redirect location, i.e.: The base cache ID.
$this->assertCacheBackendItem($this->getSortedCacheId($cache_id_parts), new CacheRedirect($this->houseOrientationCacheability));
// Store a simpler variation and verify that the first cache redirect is now
// the one redirecting to the simplest known outcome.
[
$this->housingType,
$this->gardenType,
$this->houseOrientation,
] = [
'house',
'no-garden',
NULL,
];
$this->setVariationCacheItem('You have a nice house', $this->gardenTypeCacheability, $this->housingTypeCacheability);
$this->assertCacheBackendItem($this->getSortedCacheId($cache_id_parts), new CacheRedirect($this->gardenTypeCacheability));
// Verify that the previously set outcomes are all inaccessible now.
foreach ($possible_outcomes as $cache_context_values => $data) {
[
$this->housingType,
$this->gardenType,
$this->houseOrientation,
] = explode('|', $cache_context_values . '||');
$this->assertVariationCacheMiss($this->housingTypeCacheability);
}
// Set at least one more specific item in the cache again.
$this->setVariationCacheItem($data, $this->houseOrientationCacheability, $this->housingTypeCacheability);
// Verify that the previously set outcomes are all accessible again.
foreach ($possible_outcomes as $cache_context_values => $data) {
[
$this->housingType,
$this->gardenType,
$this->houseOrientation,
] = explode('|', $cache_context_values . '||');
$this->assertVariationCacheItem($data, $this->houseOrientationCacheability, $this->housingTypeCacheability);
}
// Verify that the more specific cache redirect is now stored one step after
// the less specific one.
$cache_id_parts[] = 'gt.garden';
$this->assertCacheBackendItem($this->getSortedCacheId($cache_id_parts), new CacheRedirect($this->houseOrientationCacheability));
}
/**
* Tests self-healing for a cache item that has split variations.
*
* @covers ::get
* @covers ::set
*/
public function testSplitVariationsSelfHealing() : void {
// This is an edge case. Something varies by AB where some values of B
// trigger the whole to vary by either C, D or nothing extra. But due to an
// unfortunate series of requests, only ABC and ABD variations were cached.
//
// In this case, the cache should be smart enough to generate a redirect for
// AB, followed by redirects for ABC and ABD.
//
// For the sake of this test, we'll vary by housing and orientation, but:
// - Only vary by garden type for south-facing houses.
// - Only vary by solar panel type for north-facing houses.
$this->housingType = 'house';
$this->gardenType = 'garden';
$this->solarType = 'solar';
$initial_cacheability = (new CacheableMetadata())->setCacheTags([
'foo',
])
->setCacheContexts([
'house.type',
]);
$south_cacheability = (new CacheableMetadata())->setCacheTags([
'foo',
])
->setCacheContexts([
'house.type',
'house.orientation',
'garden.type',
]);
$north_cacheability = (new CacheableMetadata())->setCacheTags([
'foo',
])
->setCacheContexts([
'house.type',
'house.orientation',
'solar.type',
]);
$common_cacheability = (new CacheableMetadata())->setCacheContexts([
'house.type',
'house.orientation',
]);
// Calculate the cache IDs once beforehand for readability.
$cache_id = $this->getSortedCacheId([
'ht.house',
]);
$cache_id_north = $this->getSortedCacheId([
'ht.house',
'ho.north',
]);
$cache_id_south = $this->getSortedCacheId([
'ht.house',
'ho.south',
]);
// Set the first scenario.
$this->houseOrientation = 'south';
$this->setVariationCacheItem('You have a south-facing house with a garden!', $south_cacheability, $initial_cacheability);
// Verify that the overly specific redirect is stored at the first possible
// redirect location, i.e.: The base cache ID.
$this->assertCacheBackendItem($cache_id, new CacheRedirect($south_cacheability));
// Store a split variation, and verify that the common contexts are now used
// for the first cache redirect and the actual contexts for the next step of
// the redirect chain.
$this->houseOrientation = 'north';
$this->setVariationCacheItem('You have a north-facing house with solar panels!', $north_cacheability, $initial_cacheability);
$this->assertCacheBackendItem($cache_id, new CacheRedirect($common_cacheability));
$this->assertCacheBackendItem($cache_id_north, new CacheRedirect($north_cacheability));
// Verify that the initially set scenario is inaccessible now.
$this->houseOrientation = 'south';
$this->assertVariationCacheMiss($initial_cacheability);
// Reset the initial scenario and verify that its redirects are accessible.
$this->setVariationCacheItem('You have a south-facing house with a garden!', $south_cacheability, $initial_cacheability);
$this->assertCacheBackendItem($cache_id, new CacheRedirect($common_cacheability));
$this->assertCacheBackendItem($cache_id_south, new CacheRedirect($south_cacheability));
// Double-check that the split scenario redirects are left untouched.
$this->houseOrientation = 'north';
$this->assertCacheBackendItem($cache_id, new CacheRedirect($common_cacheability));
$this->assertCacheBackendItem($cache_id_north, new CacheRedirect($north_cacheability));
}
/**
* Tests exception for a cache item that has incomplete variations.
*
* @covers ::get
* @covers ::set
*/
public function testIncompleteVariationsException() : void {
// This should never happen. When someone first stores something in the
// cache using context A and then tries to store something using context B,
// something is wrong. There should always be at least one shared context at
// the top level or else the cache cannot do its job.
$this->expectException(\LogicException::class);
$this->expectExceptionMessage("The complete set of cache contexts for a variation cache item must contain all of the initial cache contexts, missing: garden.type.");
$this->housingType = 'house';
$house_cacheability = (new CacheableMetadata())->setCacheContexts([
'house.type',
]);
$this->gardenType = 'garden';
$garden_cacheability = (new CacheableMetadata())->setCacheContexts([
'garden.type',
]);
$this->setVariationCacheItem('You have a nice garden!', $garden_cacheability, $garden_cacheability);
$this->setVariationCacheItem('You have a nice house!', $house_cacheability, $garden_cacheability);
}
/**
* Tests exception for a cache item that has an incomplete redirect.
*
* @covers ::get
* @covers ::set
*/
public function testIncompleteRedirectException() : void {
// @todo Remove in Drupal 12.0.0. For more information, see:
// https://www.drupal.org/project/drupal/issues/3468921
set_error_handler(static function (int $errno, string $errstr) : never {
throw new \LogicException($errstr, $errno);
}, E_USER_WARNING);
// This should never happen. When we have a cache redirect at address A,
// pointing to 'A,B:foo' and then someone tries to store a cache redirect at
// A pointing to 'A,B', something is wrong. The cache contexts leading up to
// a cache redirect should always be present on the redirect itself. In this
// example, the final cache redirect should be for 'A,B:foo,B'.
$this->expectException(\LogicException::class);
$this->expectExceptionMessage('Trying to overwrite a cache redirect with one that has nothing in common, old one at address "house.type" was pointing to "garden.type:zen", new one points to "garden.type".');
$this->housingType = 'house';
$house_cacheability = (new CacheableMetadata())->setCacheContexts([
'house.type',
]);
$this->gardenType = '1';
$calculated_garden_cacheability = (new CacheableMetadata())->setCacheContexts([
'house.type',
'garden.type:zen',
]);
$this->setVariationCacheItem('You have a house with zen garden!', $calculated_garden_cacheability, $house_cacheability);
$this->gardenType = 'baroque garden';
$garden_cacheability = (new CacheableMetadata())->setCacheContexts([
'house.type',
'garden.type',
]);
try {
$this->setVariationCacheItem('You have a house with a baroque garden!', $garden_cacheability, $house_cacheability);
} finally {
restore_error_handler();
}
}
/**
* Tests exception for a cache item that has incompatible cache redirects.
*
* @covers ::get
* @covers ::set
*/
public function testIncompatibleRedirectsException() : void {
// @todo Remove in Drupal 12.0.0. For more information, see:
// https://www.drupal.org/project/drupal/issues/3468921
set_error_handler(static function (int $errno, string $errstr) : never {
throw new \LogicException($errstr, $errno);
}, E_USER_WARNING);
// This should never happen. When someone first triggers the storing of a
// redirect using context A and then tries to store another redirect in the
// same spot using context B, something is wrong. The cache contexts of all
// previous redirects should always be present on the next redirect or item
// you're trying to store.
$this->expectException(\LogicException::class);
$this->expectExceptionMessage('Trying to overwrite a cache redirect with one that has nothing in common, old one at address "house.type" was pointing to "garden.type", new one points to "house.orientation".');
$this->housingType = 'house';
$house_cacheability = (new CacheableMetadata())->setCacheContexts([
'house.type',
]);
$this->gardenType = 'garden';
$garden_cacheability = (new CacheableMetadata())->setCacheContexts([
'house.type',
'garden.type',
]);
$this->houseOrientation = 'north';
$orientation_cacheability = (new CacheableMetadata())->setCacheContexts([
'house.type',
'house.orientation',
]);
$this->setVariationCacheItem('You have a nice house with a garden!', $garden_cacheability, $house_cacheability);
try {
$this->setVariationCacheItem('You have a nice north-facing house!', $orientation_cacheability, $house_cacheability);
} finally {
restore_error_handler();
}
}
/**
* Tests the same as above, but with more redirects.
*
* @covers ::get
* @covers ::set
*
* @depends testIncompatibleRedirectsException
*/
public function testIncompatibleChainedRedirectsException() : void {
// @todo Remove in Drupal 12.0.0. For more information, see:
// https://www.drupal.org/project/drupal/issues/3468921
set_error_handler(static function (int $errno, string $errstr) : never {
throw new \LogicException($errstr, $errno);
}, E_USER_WARNING);
$this->expectException(\LogicException::class);
$this->expectExceptionMessage('Trying to overwrite a cache redirect with one that has nothing in common, old one at address "house.type, garden.type" was pointing to "house.orientation", new one points to "solar.type".');
$this->housingType = 'house';
$house_cacheability = (new CacheableMetadata())->setCacheContexts([
'house.type',
]);
$this->gardenType = 'no-garden';
$garden_cacheability = (new CacheableMetadata())->setCacheContexts([
'house.type',
'garden.type',
]);
// This should set a redirect at ht.house specifying garden.type. So the
// redirects below should find this redirect to be fine before getting to
// the problematic one.
$this->setVariationCacheItem('You have a nice house with no garden!', $garden_cacheability, $house_cacheability);
$this->gardenType = 'garden';
$this->houseOrientation = 'north';
$orientation_cacheability = (new CacheableMetadata())->setCacheContexts([
'house.type',
'garden.type',
'house.orientation',
]);
$this->solarType = 'solar';
$solar_cacheability = (new CacheableMetadata())->setCacheContexts([
'house.type',
'garden.type',
'solar.type',
]);
$this->setVariationCacheItem('You have a nice north-facing house with a garden!', $orientation_cacheability, $house_cacheability);
try {
$this->setVariationCacheItem('You have a nice house with solar panels and a garden!', $solar_cacheability, $house_cacheability);
} finally {
restore_error_handler();
}
}
/**
* Tests the same as above, but even more complex.
*
* @covers ::get
* @covers ::set
*
* @depends testIncompatibleChainedRedirectsException
*/
public function testIncompatibleChainedRedirectsComplexException() : void {
// @todo Remove in Drupal 12.0.0. For more information, see:
// https://www.drupal.org/project/drupal/issues/3468921
set_error_handler(static function (int $errno, string $errstr) : never {
throw new \LogicException($errstr, $errno);
}, E_USER_WARNING);
$this->expectException(\LogicException::class);
$this->expectExceptionMessage('Trying to overwrite a cache redirect with one that has nothing in common, old one at address "house.type, garden.type" was pointing to "house.orientation", new one points to "solar.type".');
$this->housingType = 'house';
$house_cacheability = (new CacheableMetadata())->setCacheContexts([
'house.type',
]);
$this->gardenType = 'garden';
$this->houseOrientation = 'north';
$orientation_cacheability = (new CacheableMetadata())->setCacheContexts([
'house.type',
'garden.type',
'house.orientation',
]);
$this->solarType = 'solar';
$solar_cacheability = (new CacheableMetadata())->setCacheContexts([
'house.type',
'garden.type',
'solar.type',
]);
// This time, nothing primes the redirects so the first set will create a
// redirect at ht.house, pointing to house.type, garden.type and solar.type.
$this->setVariationCacheItem('You have a nice house with solar panels and a garden!', $solar_cacheability, $house_cacheability);
// The second set will try to store a redirect at ht.house, pointing to
// house.type, garden.type and house.orientation. This will trigger the
// creation of a common redirect at ht.house, pointing to garden.type.
$this->setVariationCacheItem('You have a nice north-facing house with a garden!', $orientation_cacheability, $house_cacheability);
// Now we arrive at the same scenario as the test above. We have a redirect
// chain at house.type of garden.type and finally house.orientation, but are
// trying to set solar.type at that last address.
try {
$this->setVariationCacheItem('You have a nice house with solar panels and a garden!', $solar_cacheability, $house_cacheability);
} finally {
restore_error_handler();
}
}
/**
* Creates the sorted cache ID from cache ID parts.
*
* When core optimizes cache contexts it returns the keys alphabetically. To
* make testing easier, we replicate said sorting here.
*
* @param string[] $cache_id_parts
* The parts to add to the base cache ID, will be sorted.
*
* @return string
* The correct cache ID.
*/
protected function getSortedCacheId($cache_id_parts) : string {
sort($cache_id_parts);
array_unshift($cache_id_parts, $this->cacheIdBase);
return implode(':', $cache_id_parts);
}
/**
* Stores an item in the variation cache.
*
* @param mixed $data
* The data that should be stored.
* @param \Drupal\Core\Cache\CacheableMetadata $cacheability
* The cacheability that should be used.
* @param \Drupal\Core\Cache\CacheableMetadata $initial_cacheability
* The initial cacheability that should be used.
*/
protected function setVariationCacheItem($data, CacheableMetadata $cacheability, CacheableMetadata $initial_cacheability) : void {
$this->variationCache
->set($this->cacheKeys, $data, $cacheability, $initial_cacheability);
}
/**
* Asserts that an item was properly stored in the variation cache.
*
* @param mixed $data
* The data that should have been stored.
* @param \Drupal\Core\Cache\CacheableMetadata $cacheability
* The cacheability that should have been used.
* @param \Drupal\Core\Cache\CacheableMetadata $initial_cacheability
* The initial cacheability that should be used.
*/
protected function assertVariationCacheItem($data, CacheableMetadata $cacheability, CacheableMetadata $initial_cacheability) : void {
$cache_item = $this->variationCache
->get($this->cacheKeys, $initial_cacheability);
$this->assertNotFalse($cache_item, 'Variable data was stored and retrieved successfully.');
$this->assertEquals($data, $cache_item->data, 'Variable cache item contains the right data.');
$this->assertSame($cacheability->getCacheTags(), $cache_item->tags, 'Variable cache item uses the right cache tags.');
}
/**
* Asserts that an item could not be retrieved from the variation cache.
*
* @param \Drupal\Core\Cache\CacheableMetadata $initial_cacheability
* The initial cacheability that should be used.
*/
protected function assertVariationCacheMiss(CacheableMetadata $initial_cacheability) : void {
$this->assertFalse($this->variationCache
->get($this->cacheKeys, $initial_cacheability), 'Nothing could be retrieved for the active cache contexts.');
}
/**
* Asserts that an item was properly stored in the cache backend.
*
* @param string $cid
* The cache ID that should have been used.
* @param mixed $data
* The data that should have been stored.
* @param \Drupal\Core\Cache\CacheableMetadata|null $cacheability
* (optional) The cacheability that should have been used. Does not apply
* when checking for cache redirects.
*/
protected function assertCacheBackendItem(string $cid, $data, ?CacheableMetadata $cacheability = NULL) : void {
$cache_backend_item = $this->memoryBackend
->get($cid);
$this->assertNotFalse($cache_backend_item, 'The data was stored and retrieved successfully.');
$this->assertEquals($data, $cache_backend_item->data, 'Cache item contains the right data.');
if ($data instanceof CacheRedirect) {
$this->assertSame([], $cache_backend_item->tags, 'A cache redirect does not use cache tags.');
$this->assertSame(-1, $cache_backend_item->expire, 'A cache redirect is stored indefinitely.');
}
else {
$this->assertSame($cacheability->getCacheTags(), $cache_backend_item->tags, 'Cache item uses the right cache tags.');
}
}
}
Classes
Title | Deprecated | Summary |
---|---|---|
VariationCacheTest | @coversDefaultClass \Drupal\Core\Cache\VariationCache @group Cache |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.