function ContentEntityCacheTest::testCacheInvalidationOnSave
Same name and namespace in other branches
- 11.x core/tests/Drupal/KernelTests/Core/Entity/ContentEntityCacheTest.php \Drupal\KernelTests\Core\Entity\ContentEntityCacheTest::testCacheInvalidationOnSave()
Tests that the correct caches are invalidated when an entity is saved.
File
-
core/
tests/ Drupal/ KernelTests/ Core/ Entity/ ContentEntityCacheTest.php, line 300
Class
- ContentEntityCacheTest
- Tests the entity static cache when used by content entities.
Namespace
Drupal\KernelTests\Core\EntityCode
public function testCacheInvalidationOnSave() : void {
/** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager */
$entity_type_manager = $this->container
->get('entity_type.manager');
/** @var \Drupal\Core\Entity\ContentEntityStorageInterface $storage */
$storage = $entity_type_manager->getStorage($this->revEntityTypeId);
// Create an entity and load it by id and revision to ensure that the
// caches are set.
/** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
$entity = $storage->create();
$entity->save();
$first_revision_id = $entity->getRevisionId();
$storage->loadRevision($first_revision_id);
$loaded_entity = $storage->load($entity->id());
$persistent_cache = \Drupal::cache('entity');
$memory_cache = \Drupal::service('entity.memory_cache');
$assert_cache_exists = function ($cid, $expected_cache_tag = NULL) use ($persistent_cache, $memory_cache) : void {
$cache_item = $persistent_cache->get($cid);
$this->assertNotFalse($cache_item);
if ($expected_cache_tag) {
$expected_cache_tags = [
'entity_field_info',
$expected_cache_tag,
];
$this->assertEquals($expected_cache_tags, $cache_item->tags);
}
$cache_item = $memory_cache->get($cid);
$this->assertNotFalse($cache_item);
if ($expected_cache_tag) {
$expected_cache_tags = [
'entity.memory_cache:' . $this->revEntityTypeId,
$expected_cache_tag,
];
$this->assertEquals($expected_cache_tags, $cache_item->tags);
}
};
$assert_cache_not_exists = function ($cid) use ($persistent_cache, $memory_cache) : void {
$this->assertFalse($persistent_cache->get($cid));
$this->assertFalse($memory_cache->get($cid));
};
$first_revision_cache_id = "values:{$entity->getEntityTypeId()}:revision:" . $first_revision_id;
$assert_cache_exists($first_revision_cache_id);
$cache_id = "values:{$entity->getEntityTypeId()}:" . $entity->id();
$assert_cache_exists($cache_id);
// Create and load a second entity.
$other_entity = $storage->create();
$other_entity->save();
$storage->loadRevision($other_entity->getRevisionId());
$other_entity = $storage->load($other_entity->id());
// Save as a new default revision. Currently, all saves always invalidate
// all caches for this entity, this may be improved in the future.
$loaded_entity->setNewRevision();
$loaded_entity->save();
$assert_cache_not_exists($first_revision_cache_id);
$assert_cache_not_exists($cache_id);
$second_revision_id = $loaded_entity->getRevisionId();
// Populate the revision cache.
$storage->loadMultipleRevisions([
$first_revision_id,
$second_revision_id,
]);
$second_revision_cache_id = "values:{$entity->getEntityTypeId()}:revision:" . $second_revision_id;
$assert_cache_exists($first_revision_cache_id);
$assert_cache_exists($second_revision_cache_id);
// Save as a new non-default revision. This does not need
// to invalidate the previous revisions. Entity caches are currently
// always invalidated, this could be further optimized.
$loaded_entity = $storage->load($entity->id());
$this->assertEquals($second_revision_id, $loaded_entity->getRevisionId());
$loaded_entity->setNewRevision();
$loaded_entity->isDefaultRevision(FALSE);
$loaded_entity->save();
$assert_cache_not_exists($first_revision_cache_id);
$assert_cache_not_exists($second_revision_cache_id);
$assert_cache_not_exists($cache_id);
$this->assertNotEquals($second_revision_id, $loaded_entity->getRevisionId());
// Update that non-default revision, ensure it remains the non-default
// revision and that the revision cache has been invalidated for this
// revision but not the first two revisions.
$loaded_revision = $storage->loadRevision($loaded_entity->getRevisionId());
$this->assertFalse($loaded_revision->isDefaultRevision());
$loaded_revision->isDefaultRevision(FALSE);
$loaded_revision->save();
$assert_cache_not_exists($first_revision_cache_id);
$assert_cache_not_exists($second_revision_cache_id);
$revision_cache_id = "values:{$entity->getEntityTypeId()}:revision:" . $loaded_revision->getRevisionId();
$assert_cache_not_exists($revision_cache_id);
$assert_cache_not_exists($cache_id);
$loaded_revision = $storage->loadRevision($loaded_revision->getRevisionId());
$this->assertFalse($loaded_revision->isDefaultRevision());
// Update that non-default revision to be the new default revision,
// without saving it as a new revision. This has invalidated all revisions
// as an optimization.
$loaded_revision = $storage->loadRevision($loaded_revision->getRevisionId());
$this->assertFalse($loaded_revision->isDefaultRevision());
$loaded_entity->isDefaultRevision(TRUE);
$loaded_entity->save();
$assert_cache_not_exists($first_revision_cache_id);
$assert_cache_not_exists($second_revision_cache_id);
$revision_cache_id = "values:{$entity->getEntityTypeId()}:revision:" . $loaded_revision->getRevisionId();
$assert_cache_not_exists($revision_cache_id);
$assert_cache_not_exists($cache_id);
$loaded_revision = $storage->loadRevision($loaded_revision->getRevisionId());
$this->assertTrue($loaded_revision->isDefaultRevision());
// The other entity is still cached.
$other_revision_cache_id = "values:{$entity->getEntityTypeId()}:revision:" . $other_entity->getRevisionId();
$assert_cache_exists($other_revision_cache_id);
$other_cache_id = "values:{$entity->getEntityTypeId()}:" . $other_entity->id();
$assert_cache_exists($other_cache_id);
// Load revisions of multiple entities, ensure they get the right cache
// tags.
$storage->resetCache();
$storage->loadMultipleRevisions([
$loaded_revision->getRevisionId(),
$other_entity->getRevisionId(),
]);
$assert_cache_exists($revision_cache_id, $this->revEntityTypeId . ":{$loaded_revision->id()}:revisions");
$assert_cache_exists($other_revision_cache_id, $this->revEntityTypeId . ":{$other_entity->id()}:revisions");
// Save the loaded revision, ensure that the other revision is still
// cached.
$loaded_revision->save();
$assert_cache_not_exists($revision_cache_id);
$assert_cache_exists($other_revision_cache_id);
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.