From d590baa49f273619ab8ad067aa02362ff83b9d5b Mon Sep 17 00:00:00 2001 From: Martin Ficzel Date: Sat, 18 Nov 2023 21:19:19 +0100 Subject: [PATCH] FEATURE: Extract `LowLevelFrontendInterface` and implement PSR-6 and PSR-16 cache frontends While Neos had methods to create PSR caches those were seldomly used as they worked quite differently to other caches that were configured via `Caches.yaml`. This change introduces implementations of PSR-6 Cache and PSR-16 SimpleCache that can be used as normal flow cache-frontends. To make this possible the low level functionality of object instantiation and garbage collection and flushing was extracted into a `LowLevelFrontendInterface` while the `FrontenInterface` on to defines the interaction with the caches. The old methods for creating psr caches are deprecated and marked for removal with Neos Flow 10. --- .../Classes/Backend/AbstractBackend.php | 8 +- Neos.Cache/Classes/Backend/ApcuBackend.php | 10 +- .../Classes/Backend/BackendInterface.php | 6 +- Neos.Cache/Classes/Backend/FileBackend.php | 6 +- .../Classes/Backend/MemcachedBackend.php | 10 +- Neos.Cache/Classes/Backend/PdoBackend.php | 4 +- .../Classes/Backend/SimpleFileBackend.php | 6 +- .../Backend/TransientMemoryBackend.php | 4 +- Neos.Cache/Classes/CacheFactory.php | 12 +- Neos.Cache/Classes/CacheFactoryInterface.php | 6 +- .../Classes/Frontend/AbstractFrontend.php | 155 +---------- .../Frontend/AbstractLowLevelFrontend.php | 160 ++++++++++++ .../Classes/Frontend/CacheEntryIterator.php | 6 +- .../Classes/Frontend/FrontendInterface.php | 79 +----- .../Frontend/LowLevelFrontendInterface.php | 99 +++++++ .../Classes/Frontend/Psr/Cache/CacheItem.php | 136 ++++++++++ .../Psr/Cache/CacheItemPoolFrontend.php | 209 +++++++++++++++ .../Psr/Cache/InvalidArgumentException.php | 21 ++ .../SimpleCache/InvalidArgumentException.php | 21 ++ .../Psr/SimpleCache/SimpleCacheFrontend.php | 198 ++++++++++++++ .../Classes/Frontend/VariableFrontend.php | 1 - Neos.Cache/Classes/Psr/Cache/CacheFactory.php | 1 + Neos.Cache/Classes/Psr/Cache/CacheItem.php | 1 + Neos.Cache/Classes/Psr/Cache/CachePool.php | 1 + .../Classes/Psr/SimpleCache/SimpleCache.php | 1 + .../Psr/SimpleCache/SimpleCacheFactory.php | 1 + .../Functional/Backend/PdoBackendTest.php | 6 +- .../Functional/Backend/RedisBackendTest.php | 6 +- .../Tests/Unit/Backend/ApcuBackendTest.php | 8 +- .../Tests/Unit/Backend/FileBackendTest.php | 56 ++-- .../Unit/Backend/MemcachedBackendTest.php | 10 +- .../Tests/Unit/Backend/PdoBackendTest.php | 10 +- .../Tests/Unit/Backend/RedisBackendTest.php | 6 +- .../Unit/Backend/SimpleFileBackendTest.php | 10 +- .../Backend/TransientMemoryBackendTest.php | 22 +- .../Unit/Frontend/Psr/Cache/CachePoolTest.php | 210 +++++++++++++++ .../Psr/SimpleCache/SimpleCacheTest.php | 247 ++++++++++++++++++ .../Unit/Psr/SimpleCache/SimpleCacheTest.php | 4 +- Neos.Flow/Classes/Cache/CacheFactory.php | 8 +- Neos.Flow/Classes/Cache/CacheManager.php | 19 +- .../Cache/NonMatchingCacheClassException.php | 11 + .../Classes/Mvc/Routing/Dto/RouteTags.php | 2 +- .../Persistence/Doctrine/CacheAdapter.php | 8 +- Neos.Flow/Classes/Session/Session.php | 4 +- .../TheDefinitiveGuide/PartIII/Caching.rst | 19 +- .../Tests/Unit/Cache/CacheManagerTest.php | 32 +-- .../Security/Cryptography/HashServiceTest.php | 5 +- 47 files changed, 1480 insertions(+), 385 deletions(-) create mode 100644 Neos.Cache/Classes/Frontend/AbstractLowLevelFrontend.php create mode 100644 Neos.Cache/Classes/Frontend/LowLevelFrontendInterface.php create mode 100644 Neos.Cache/Classes/Frontend/Psr/Cache/CacheItem.php create mode 100644 Neos.Cache/Classes/Frontend/Psr/Cache/CacheItemPoolFrontend.php create mode 100644 Neos.Cache/Classes/Frontend/Psr/Cache/InvalidArgumentException.php create mode 100644 Neos.Cache/Classes/Frontend/Psr/SimpleCache/InvalidArgumentException.php create mode 100644 Neos.Cache/Classes/Frontend/Psr/SimpleCache/SimpleCacheFrontend.php create mode 100644 Neos.Cache/Tests/Unit/Frontend/Psr/Cache/CachePoolTest.php create mode 100644 Neos.Cache/Tests/Unit/Frontend/Psr/SimpleCache/SimpleCacheTest.php create mode 100644 Neos.Flow/Classes/Cache/NonMatchingCacheClassException.php diff --git a/Neos.Cache/Classes/Backend/AbstractBackend.php b/Neos.Cache/Classes/Backend/AbstractBackend.php index b6ea0aa72c..5345e2542e 100644 --- a/Neos.Cache/Classes/Backend/AbstractBackend.php +++ b/Neos.Cache/Classes/Backend/AbstractBackend.php @@ -14,7 +14,7 @@ */ use Neos\Cache\EnvironmentConfiguration; -use Neos\Cache\Frontend\FrontendInterface; +use Neos\Cache\Frontend\LowLevelFrontendInterface; /** * An abstract caching backend @@ -28,7 +28,7 @@ abstract class AbstractBackend implements BackendInterface /** * Reference to the cache frontend which uses this backend - * @var FrontendInterface + * @var LowLevelFrontendInterface */ protected $cache; @@ -109,11 +109,11 @@ protected function setProperty(string $propertyName, $propertyValue): bool /** * Sets a reference to the cache frontend which uses this backend * - * @param FrontendInterface $cache The frontend for this backend + * @param LowLevelFrontendInterface $cache The frontend for this backend * @return void * @api */ - public function setCache(FrontendInterface $cache): void + public function setCache(LowLevelFrontendInterface $cache): void { $this->cache = $cache; $this->cacheIdentifier = $this->cache->getIdentifier(); diff --git a/Neos.Cache/Classes/Backend/ApcuBackend.php b/Neos.Cache/Classes/Backend/ApcuBackend.php index 8b5524eb75..2661fa461d 100644 --- a/Neos.Cache/Classes/Backend/ApcuBackend.php +++ b/Neos.Cache/Classes/Backend/ApcuBackend.php @@ -16,7 +16,7 @@ use Neos\Cache\Backend\AbstractBackend as IndependentAbstractBackend; use Neos\Cache\EnvironmentConfiguration; use Neos\Cache\Exception; -use Neos\Cache\Frontend\FrontendInterface; +use Neos\Cache\Frontend\LowLevelFrontendInterface; /** * A caching backend which stores cache entries by using APCu. @@ -76,10 +76,10 @@ public function __construct(EnvironmentConfiguration $environmentConfiguration, /** * Initializes the identifier prefix when setting the cache. * - * @param FrontendInterface $cache + * @param LowLevelFrontendInterface $cache * @return void */ - public function setCache(FrontendInterface $cache): void + public function setCache(LowLevelFrontendInterface $cache): void { parent::setCache($cache); @@ -119,7 +119,7 @@ public function getPrefixedIdentifier(string $entryIdentifier): string */ public function set(string $entryIdentifier, string $data, array $tags = [], int $lifetime = null): void { - if (!$this->cache instanceof FrontendInterface) { + if (!$this->cache instanceof LowLevelFrontendInterface) { throw new Exception('No cache frontend has been set yet via setCache().', 1232986818); } @@ -222,7 +222,7 @@ protected function findTagsByIdentifier(string $identifier): array */ public function flush(): void { - if (!$this->cache instanceof FrontendInterface) { + if (!$this->cache instanceof LowLevelFrontendInterface) { throw new Exception('Yet no cache frontend has been set via setCache().', 1232986971); } $this->flushByTag('%APCUBE%' . $this->cacheIdentifier); diff --git a/Neos.Cache/Classes/Backend/BackendInterface.php b/Neos.Cache/Classes/Backend/BackendInterface.php index a7929913cf..1e970de556 100644 --- a/Neos.Cache/Classes/Backend/BackendInterface.php +++ b/Neos.Cache/Classes/Backend/BackendInterface.php @@ -13,7 +13,7 @@ * source code. */ -use Neos\Cache\Frontend\FrontendInterface; +use Neos\Cache\Frontend\LowLevelFrontendInterface; /** * A contract for a Cache Backend @@ -25,11 +25,11 @@ interface BackendInterface /** * Sets a reference to the cache frontend which uses this backend * - * @param FrontendInterface $cache The frontend for this backend + * @param LowLevelFrontendInterface $cache The frontend for this backend * @return void * @api */ - public function setCache(FrontendInterface $cache): void; + public function setCache(LowLevelFrontendInterface $cache): void; /** * Returns the internally used, prefixed entry identifier for the given public diff --git a/Neos.Cache/Classes/Backend/FileBackend.php b/Neos.Cache/Classes/Backend/FileBackend.php index 1d9699111c..802c620744 100644 --- a/Neos.Cache/Classes/Backend/FileBackend.php +++ b/Neos.Cache/Classes/Backend/FileBackend.php @@ -14,7 +14,7 @@ */ use Neos\Cache\Exception; -use Neos\Cache\Frontend\FrontendInterface; +use Neos\Cache\Frontend\LowLevelFrontendInterface; use Neos\Utility\Exception\FilesException; use Neos\Utility\Files; use Neos\Utility\OpcodeCacheHelper; @@ -115,11 +115,11 @@ public function isFrozen(): bool * This method also detects if this backend is frozen and sets the internal * flag accordingly. * - * @param FrontendInterface $cache The cache frontend + * @param LowLevelFrontendInterface $cache The cache frontend * @return void * @throws Exception */ - public function setCache(FrontendInterface $cache): void + public function setCache(LowLevelFrontendInterface $cache): void { parent::setCache($cache); diff --git a/Neos.Cache/Classes/Backend/MemcachedBackend.php b/Neos.Cache/Classes/Backend/MemcachedBackend.php index dacf7ce832..f157bd9be4 100644 --- a/Neos.Cache/Classes/Backend/MemcachedBackend.php +++ b/Neos.Cache/Classes/Backend/MemcachedBackend.php @@ -16,7 +16,7 @@ use Neos\Cache\Backend\AbstractBackend as IndependentAbstractBackend; use Neos\Cache\EnvironmentConfiguration; use Neos\Cache\Exception; -use Neos\Cache\Frontend\FrontendInterface; +use Neos\Cache\Frontend\LowLevelFrontendInterface; /** * A caching backend which stores cache entries by using Memcache/Memcached. @@ -158,10 +158,10 @@ protected function setCompression(bool $useCompression) /** * Initializes the identifier prefix when setting the cache. * - * @param FrontendInterface $cache + * @param LowLevelFrontendInterface $cache * @return void */ - public function setCache(FrontendInterface $cache): void + public function setCache(LowLevelFrontendInterface $cache): void { parent::setCache($cache); @@ -204,7 +204,7 @@ public function set(string $entryIdentifier, string $data, array $tags = [], int if (strlen($this->getPrefixedIdentifier($entryIdentifier)) > 250) { throw new \InvalidArgumentException('Could not set value. Key more than 250 characters (' . $this->getPrefixedIdentifier($entryIdentifier) . ').', 1232969508); } - if (!$this->cache instanceof FrontendInterface) { + if (!$this->cache instanceof LowLevelFrontendInterface) { throw new Exception('No cache frontend has been set yet via setCache().', 1207149215); } @@ -342,7 +342,7 @@ protected function findTagsByIdentifier(string $identifier): array */ public function flush(): void { - if (!$this->cache instanceof FrontendInterface) { + if (!$this->cache instanceof LowLevelFrontendInterface) { throw new Exception('Yet no cache frontend has been set via setCache().', 1204111376); } diff --git a/Neos.Cache/Classes/Backend/PdoBackend.php b/Neos.Cache/Classes/Backend/PdoBackend.php index 77a7e89244..3160d060f7 100644 --- a/Neos.Cache/Classes/Backend/PdoBackend.php +++ b/Neos.Cache/Classes/Backend/PdoBackend.php @@ -15,7 +15,7 @@ use Neos\Cache\Backend\AbstractBackend as IndependentAbstractBackend; use Neos\Cache\Exception; -use Neos\Cache\Frontend\FrontendInterface; +use Neos\Cache\Frontend\LowLevelFrontendInterface; use Neos\Error\Messages\Error; use Neos\Error\Messages\Notice; use Neos\Error\Messages\Result; @@ -186,7 +186,7 @@ public function set(string $entryIdentifier, string $data, array $tags = [], int { $this->connect(); - if (!$this->cache instanceof FrontendInterface) { + if (!$this->cache instanceof LowLevelFrontendInterface) { throw new Exception('No cache frontend has been set yet via setCache().', 1259515600); } diff --git a/Neos.Cache/Classes/Backend/SimpleFileBackend.php b/Neos.Cache/Classes/Backend/SimpleFileBackend.php index c0173326ef..6fef85f974 100644 --- a/Neos.Cache/Classes/Backend/SimpleFileBackend.php +++ b/Neos.Cache/Classes/Backend/SimpleFileBackend.php @@ -21,7 +21,7 @@ use Neos\Utility\Files; use Neos\Cache\Exception; use Neos\Cache\Frontend\PhpFrontend; -use Neos\Cache\Frontend\FrontendInterface; +use Neos\Cache\Frontend\LowLevelFrontendInterface; use Neos\Utility\Exception\FilesException; use Neos\Utility\OpcodeCacheHelper; @@ -99,11 +99,11 @@ public function __construct(EnvironmentConfiguration $environmentConfiguration, * Sets a reference to the cache frontend which uses this backend and * initializes the default cache directory. * - * @param FrontendInterface $cache The cache frontend + * @param LowLevelFrontendInterface $cache The cache frontend * @return void * @throws Exception */ - public function setCache(FrontendInterface $cache): void + public function setCache(LowLevelFrontendInterface $cache): void { parent::setCache($cache); $this->cacheEntryFileExtension = ($cache instanceof PhpFrontend) ? '.php' : ''; diff --git a/Neos.Cache/Classes/Backend/TransientMemoryBackend.php b/Neos.Cache/Classes/Backend/TransientMemoryBackend.php index 92580fe27d..19f90e9e12 100644 --- a/Neos.Cache/Classes/Backend/TransientMemoryBackend.php +++ b/Neos.Cache/Classes/Backend/TransientMemoryBackend.php @@ -15,7 +15,7 @@ use Neos\Cache\Backend\AbstractBackend as IndependentAbstractBackend; use Neos\Cache\Exception; -use Neos\Cache\Frontend\FrontendInterface; +use Neos\Cache\Frontend\LowLevelFrontendInterface; /** * A caching backend which stores cache entries during one script run. @@ -47,7 +47,7 @@ class TransientMemoryBackend extends IndependentAbstractBackend implements Tagga */ public function set(string $entryIdentifier, string $data, array $tags = [], int $lifetime = null): void { - if (!$this->cache instanceof FrontendInterface) { + if (!$this->cache instanceof LowLevelFrontendInterface) { throw new Exception('No cache frontend has been set yet via setCache().', 1238244992); } diff --git a/Neos.Cache/Classes/CacheFactory.php b/Neos.Cache/Classes/CacheFactory.php index 7ce4e225db..76b2089a37 100644 --- a/Neos.Cache/Classes/CacheFactory.php +++ b/Neos.Cache/Classes/CacheFactory.php @@ -14,7 +14,7 @@ use Neos\Cache\Backend\BackendInterface; use Neos\Cache\Exception\InvalidBackendException; use Neos\Cache\Exception\InvalidCacheException; -use Neos\Cache\Frontend\FrontendInterface; +use Neos\Cache\Frontend\LowLevelFrontendInterface; /** * This cache factory takes care of instantiating a cache frontend and injecting @@ -50,12 +50,12 @@ public function __construct(EnvironmentConfiguration $environmentConfiguration) * @param string $cacheObjectName Object name of the cache frontend * @param string $backendObjectName Object name of the cache backend * @param array $backendOptions (optional) Array of backend options - * @return FrontendInterface The created cache frontend + * @return LowLevelFrontendInterface The created cache frontend * @throws InvalidBackendException * @throws InvalidCacheException * @api */ - public function create(string $cacheIdentifier, string $cacheObjectName, string $backendObjectName, array $backendOptions = []): FrontendInterface + public function create(string $cacheIdentifier, string $cacheObjectName, string $backendObjectName, array $backendOptions = []): LowLevelFrontendInterface { $backend = $this->instantiateBackend($backendObjectName, $backendOptions, $this->environmentConfiguration); $cache = $this->instantiateCache($cacheIdentifier, $cacheObjectName, $backend); @@ -68,13 +68,13 @@ public function create(string $cacheIdentifier, string $cacheObjectName, string * @param string $cacheIdentifier * @param string $cacheObjectName * @param BackendInterface $backend - * @return FrontendInterface + * @return LowLevelFrontendInterface * @throws InvalidCacheException */ - protected function instantiateCache(string $cacheIdentifier, string $cacheObjectName, BackendInterface $backend): FrontendInterface + protected function instantiateCache(string $cacheIdentifier, string $cacheObjectName, BackendInterface $backend): LowLevelFrontendInterface { $cache = new $cacheObjectName($cacheIdentifier, $backend); - if (!$cache instanceof FrontendInterface) { + if (!$cache instanceof LowLevelFrontendInterface) { throw new InvalidCacheException('"' . $cacheObjectName . '" is not a valid cache frontend object.', 1216304300); } diff --git a/Neos.Cache/Classes/CacheFactoryInterface.php b/Neos.Cache/Classes/CacheFactoryInterface.php index 3bc72b7fef..01416eda16 100644 --- a/Neos.Cache/Classes/CacheFactoryInterface.php +++ b/Neos.Cache/Classes/CacheFactoryInterface.php @@ -12,7 +12,7 @@ */ use Neos\Cache\Exception\InvalidCacheException; use Neos\Cache\Exception\InvalidBackendException; -use Neos\Cache\Frontend\FrontendInterface; +use Neos\Cache\Frontend\LowLevelFrontendInterface; /** * This cache factory takes care of instantiating a cache frontend and injecting @@ -31,10 +31,10 @@ interface CacheFactoryInterface * @param string $cacheObjectName Object name of the cache frontend * @param string $backendObjectName Object name of the cache backend * @param array $backendOptions (optional) Array of backend options - * @return \Neos\Cache\Frontend\FrontendInterface The created cache frontend + * @return \Neos\Cache\Frontend\LowLevelFrontendInterface The created cache frontend * @throws InvalidBackendException * @throws InvalidCacheException * @api */ - public function create(string $cacheIdentifier, string $cacheObjectName, string $backendObjectName, array $backendOptions = []): FrontendInterface; + public function create(string $cacheIdentifier, string $cacheObjectName, string $backendObjectName, array $backendOptions = []): LowLevelFrontendInterface; } diff --git a/Neos.Cache/Classes/Frontend/AbstractFrontend.php b/Neos.Cache/Classes/Frontend/AbstractFrontend.php index a03f464686..10e3ab5abe 100644 --- a/Neos.Cache/Classes/Frontend/AbstractFrontend.php +++ b/Neos.Cache/Classes/Frontend/AbstractFrontend.php @@ -13,81 +13,14 @@ * source code. */ -use Neos\Cache\Backend\BackendInterface; -use Neos\Cache\Backend\TaggableBackendInterface; /** * An abstract cache * * @api */ -abstract class AbstractFrontend implements FrontendInterface +abstract class AbstractFrontend extends AbstractLowLevelFrontend implements FrontendInterface { - /** - * Identifies this cache - * @var string - */ - protected $identifier; - - /** - * @var BackendInterface - */ - protected $backend; - - /** - * Constructs the cache - * - * @param string $identifier A identifier which describes this cache - * @param BackendInterface $backend Backend to be used for this cache - * @throws \InvalidArgumentException if the identifier doesn't match PATTERN_ENTRYIDENTIFIER - */ - public function __construct(string $identifier, BackendInterface $backend) - { - if (preg_match(self::PATTERN_ENTRYIDENTIFIER, $identifier) !== 1) { - throw new \InvalidArgumentException('"' . $identifier . '" is not a valid cache identifier.', 1203584729); - } - $this->identifier = $identifier; - $this->backend = $backend; - } - - /** - * Initializes this frontend - * - * The backend is connected with this frontend in initializeObject(), not in __construct(), because the Cache Factory - * needs an opportunity to register the cache before the backend's setCache() method is called. See - * CacheFactory::create() for details. A backend (for example the SimpleFileBackend) may rely on the cache already - * being registered at the CacheManager when its setCache() method is called. - * - * @return void - */ - public function initializeObject() - { - // FIXME: This can be removed in next major, since the Backend gets the Frontend set in the cache factory now. - $this->backend->setCache($this); - } - - /** - * Returns this cache's identifier - * - * @return string The identifier for this cache - * @api - */ - public function getIdentifier(): string - { - return $this->identifier; - } - - /** - * Returns the backend used by this cache - * - * @return BackendInterface The backend used by this cache - * @api - */ - public function getBackend(): BackendInterface - { - return $this->backend; - } - /** * Checks if a cache entry with the specified identifier exists. * @@ -121,90 +54,4 @@ public function remove(string $entryIdentifier): bool return $this->backend->remove($entryIdentifier); } - - /** - * Removes all cache entries of this cache. - * - * @return void - * @api - */ - public function flush() - { - $this->backend->flush(); - } - - /** - * Removes all cache entries of this cache which are tagged by the specified tag. - * - * @param string $tag The tag the entries must have - * @return integer The number of entries which have been affected by this flush - * @throws \InvalidArgumentException - * @api - */ - public function flushByTag(string $tag): int - { - if (!$this->isValidTag($tag)) { - throw new \InvalidArgumentException('"' . $tag . '" is not a valid tag for a cache entry.', 1233057359); - } - if ($this->backend instanceof TaggableBackendInterface) { - return $this->backend->flushByTag($tag); - } - return 0; - } - - /** - * Removes all cache entries of this cache which are tagged by any of the specified tags. - * - * @param array $tags The tags the entries must have - * @return integer The number of entries which have been affected by this flush - * @throws \InvalidArgumentException - * @api - */ - public function flushByTags(array $tags): int - { - foreach ($tags as $tag) { - if (!$this->isValidTag($tag)) { - throw new \InvalidArgumentException('"' . $tag . '" is not a valid tag for a cache entry.', 1646209443); - } - } - if ($this->backend instanceof TaggableBackendInterface) { - return $this->backend->flushByTags($tags); - } - return 0; - } - - /** - * Does garbage collection - * - * @return void - * @api - */ - public function collectGarbage() - { - $this->backend->collectGarbage(); - } - - /** - * Checks the validity of an entry identifier. Returns true if it's valid. - * - * @param string $identifier An identifier to be checked for validity - * @return boolean - * @api - */ - public function isValidEntryIdentifier(string $identifier): bool - { - return preg_match(self::PATTERN_ENTRYIDENTIFIER, $identifier) === 1; - } - - /** - * Checks the validity of a tag. Returns true if it's valid. - * - * @param string $tag An identifier to be checked for validity - * @return boolean - * @api - */ - public function isValidTag(string $tag): bool - { - return preg_match(self::PATTERN_TAG, $tag) === 1; - } } diff --git a/Neos.Cache/Classes/Frontend/AbstractLowLevelFrontend.php b/Neos.Cache/Classes/Frontend/AbstractLowLevelFrontend.php new file mode 100644 index 0000000000..61ff5f1d66 --- /dev/null +++ b/Neos.Cache/Classes/Frontend/AbstractLowLevelFrontend.php @@ -0,0 +1,160 @@ +identifier = $identifier; + $this->backend = $backend; + } + + /** + * Returns this cache's identifier + * + * @return string The identifier for this cache + * @api + */ + public function getIdentifier(): string + { + return $this->identifier; + } + + /** + * Returns the backend used by this cache + * + * @return BackendInterface The backend used by this cache + * @api + */ + public function getBackend(): BackendInterface + { + return $this->backend; + } + + /** + * Removes all cache entries of this cache. + * + * @return void + * @api + */ + public function flush() + { + $this->backend->flush(); + } + + /** + * Removes all cache entries of this cache which are tagged by the specified tag. + * + * @param string $tag The tag the entries must have + * @return integer The number of entries which have been affected by this flush + * @throws \InvalidArgumentException + * @api + */ + public function flushByTag(string $tag): int + { + if (!$this->isValidTag($tag)) { + throw new \InvalidArgumentException('"' . $tag . '" is not a valid tag for a cache entry.', 1233057359); + } + if ($this->backend instanceof TaggableBackendInterface) { + return $this->backend->flushByTag($tag); + } + return 0; + } + + /** + * Removes all cache entries of this cache which are tagged by any of the specified tags. + * + * @param array $tags The tags the entries must have + * @return integer The number of entries which have been affected by this flush + * @throws \InvalidArgumentException + * @api + */ + public function flushByTags(array $tags): int + { + foreach ($tags as $tag) { + if (!$this->isValidTag($tag)) { + throw new \InvalidArgumentException('"' . $tag . '" is not a valid tag for a cache entry.', 1646209443); + } + } + if ($this->backend instanceof TaggableBackendInterface) { + return $this->backend->flushByTags($tags); + } + return 0; + } + + /** + * Does garbage collection + * + * @return void + * @api + */ + public function collectGarbage() + { + $this->backend->collectGarbage(); + } + + /** + * Checks the validity of an entry identifier. Returns true if it's valid. + * + * @param string $identifier An identifier to be checked for validity + * @return boolean + * @api + */ + public function isValidEntryIdentifier(string $identifier): bool + { + return preg_match(self::PATTERN_ENTRYIDENTIFIER, $identifier) === 1; + } + + /** + * Checks the validity of a tag. Returns true if it's valid. + * + * @param string $tag An identifier to be checked for validity + * @return boolean + * @api + */ + public function isValidTag(string $tag): bool + { + return preg_match(self::PATTERN_TAG, $tag) === 1; + } +} diff --git a/Neos.Cache/Classes/Frontend/CacheEntryIterator.php b/Neos.Cache/Classes/Frontend/CacheEntryIterator.php index 45ae20e2c1..f2f7c57ff5 100644 --- a/Neos.Cache/Classes/Frontend/CacheEntryIterator.php +++ b/Neos.Cache/Classes/Frontend/CacheEntryIterator.php @@ -23,7 +23,7 @@ class CacheEntryIterator implements \Iterator { /** - * @var FrontendInterface + * @var LowLevelFrontendInterface */ protected $frontend; @@ -35,10 +35,10 @@ class CacheEntryIterator implements \Iterator /** * Constructs this Iterator * - * @param FrontendInterface $frontend Frontend of the cache to iterate over + * @param LowLevelFrontendInterface $frontend Frontend of the cache to iterate over * @param IterableBackendInterface $backend Backend of the cache */ - public function __construct(FrontendInterface $frontend, IterableBackendInterface $backend) + public function __construct(LowLevelFrontendInterface $frontend, IterableBackendInterface $backend) { $this->frontend = $frontend; $this->backend = $backend; diff --git a/Neos.Cache/Classes/Frontend/FrontendInterface.php b/Neos.Cache/Classes/Frontend/FrontendInterface.php index 2b4ac9408b..b45c31d0ce 100644 --- a/Neos.Cache/Classes/Frontend/FrontendInterface.php +++ b/Neos.Cache/Classes/Frontend/FrontendInterface.php @@ -18,34 +18,8 @@ * * @api */ -interface FrontendInterface +interface FrontendInterface extends LowLevelFrontendInterface { - /** - * Pattern an entry identifier must match. - */ - const PATTERN_ENTRYIDENTIFIER = '/^[a-zA-Z0-9_%\-&]{1,250}$/'; - - /** - * Pattern a tag must match. - */ - const PATTERN_TAG = '/^[a-zA-Z0-9_%\-&]{1,250}$/'; - - /** - * Returns this cache's identifier - * - * @return string The identifier for this cache - * @api - */ - public function getIdentifier(); - - /** - * Returns the backend used by this cache - * - * @return \Neos\Cache\Backend\BackendInterface The backend used by this cache - * @api - */ - public function getBackend(); - /** * Saves data in the cache. * @@ -92,55 +66,4 @@ public function has(string $entryIdentifier): bool; * @return boolean true if such an entry exists, false if not */ public function remove(string $entryIdentifier): bool; - - /** - * Removes all cache entries of this cache. - * - * @return void - */ - public function flush(); - - /** - * Removes all cache entries of this cache which are tagged by the specified tag. - * - * @param string $tag The tag the entries must have - * @return integer The number of entries which have been affected by this flush - * @api - */ - public function flushByTag(string $tag): int; - - /** - * Removes all cache entries of this cache which are tagged by any of the specified tags. - * - * @param array $tags The tags the entries must have - * @return integer The number of entries which have been affected by this flush - * @api - */ - public function flushByTags(array $tags): int; - - /** - * Does garbage collection - * - * @return void - * @api - */ - public function collectGarbage(); - - /** - * Checks the validity of an entry identifier. Returns true if it's valid. - * - * @param string $identifier An identifier to be checked for validity - * @return boolean - * @api - */ - public function isValidEntryIdentifier(string $identifier): bool; - - /** - * Checks the validity of a tag. Returns true if it's valid. - * - * @param string $tag A tag to be checked for validity - * @return boolean - * @api - */ - public function isValidTag(string $tag): bool; } diff --git a/Neos.Cache/Classes/Frontend/LowLevelFrontendInterface.php b/Neos.Cache/Classes/Frontend/LowLevelFrontendInterface.php new file mode 100644 index 0000000000..dd361a9d04 --- /dev/null +++ b/Neos.Cache/Classes/Frontend/LowLevelFrontendInterface.php @@ -0,0 +1,99 @@ + $tags The tags the entries must have + * @return integer The number of entries which have been affected by this flush + * @api + */ + public function flushByTags(array $tags): int; + + /** + * Does garbage collection + * + * @return void + * @api + */ + public function collectGarbage(); + + /** + * Checks the validity of an entry identifier. Returns true if it's valid. + * + * @param string $identifier An identifier to be checked for validity + * @return boolean + * @api + */ + public function isValidEntryIdentifier(string $identifier): bool; + + /** + * Checks the validity of a tag. Returns true if it's valid. + * + * @param string $tag A tag to be checked for validity + * @return boolean + * @api + */ + public function isValidTag(string $tag): bool; +} diff --git a/Neos.Cache/Classes/Frontend/Psr/Cache/CacheItem.php b/Neos.Cache/Classes/Frontend/Psr/Cache/CacheItem.php new file mode 100644 index 0000000000..4d342696e4 --- /dev/null +++ b/Neos.Cache/Classes/Frontend/Psr/Cache/CacheItem.php @@ -0,0 +1,136 @@ +key = $key; + $this->hit = $hit; + if ($hit === false) { + $value = null; + } + $this->value = $value; + } + + /** + * @return string + */ + public function getKey(): string + { + return $this->key; + } + + /** + * @return mixed + */ + public function get(): mixed + { + return $this->value; + } + + /** + * @return bool + */ + public function isHit(): bool + { + return $this->hit; + } + + /** + * @param mixed $value + * @return static + */ + public function set(mixed $value): static + { + $this->value = $value; + return $this; + } + + /** + * @param ?\DateTimeInterface $expiration + * @return static + */ + public function expiresAt(?\DateTimeInterface $expiration): static + { + $this->expirationDate = null; + if ($expiration instanceof \DateTimeInterface) { + $this->expirationDate = $expiration; + } + + return $this; + } + + /** + * @param \DateInterval|int|null $time + * @return CacheItem|static + */ + public function expiresAfter(int|\DateInterval|null $time): static + { + $expiresAt = null; + if ($time instanceof \DateInterval) { + $expiresAt = (new \DateTime())->add($time); + } + + if (is_int($time)) { + $expiresAt = new \DateTime('@' . (time() + $time)); + } + + return $this->expiresAt($expiresAt); + } + + /** + * @return \DateTime|null + */ + public function getExpirationDate() + { + return $this->expirationDate; + } +} diff --git a/Neos.Cache/Classes/Frontend/Psr/Cache/CacheItemPoolFrontend.php b/Neos.Cache/Classes/Frontend/Psr/Cache/CacheItemPoolFrontend.php new file mode 100644 index 0000000000..4cc86046b3 --- /dev/null +++ b/Neos.Cache/Classes/Frontend/Psr/Cache/CacheItemPoolFrontend.php @@ -0,0 +1,209 @@ +isValidEntryIdentifier($key)) { + throw new InvalidArgumentException('"' . $key . '" is not a valid cache entry identifier.', 1514738649629); + } + + $rawResult = $this->backend->get($key); + if ($rawResult === false) { + return new CacheItem($key, false); + } + + $value = unserialize($rawResult); + return new CacheItem($key, true, $value); + } + + /** + * Returns a traversable set of cache items. + * + * @param string[] $keys + * @return array + * @throws InvalidArgumentException + */ + public function getItems(array $keys = []): iterable + { + return array_map(function ($key) { + return $this->getItem($key); + }, $keys); + } + + /** + * Confirms if the cache contains specified cache item. + * + * @param string $key + * @return bool + * @throws InvalidArgumentException + */ + public function hasItem(string $key): bool + { + if (!$this->isValidEntryIdentifier($key)) { + throw new InvalidArgumentException('"' . $key . '" is not a valid cache entry identifier.', 1514738924982); + } + + return $this->backend->has($key); + } + + /** + * Deletes all items in the pool. + * + * @return bool + */ + public function clear(): bool + { + $this->backend->flush(); + return true; + } + + /** + * Removes the item from the pool. + * + * @param string $key + * @return bool + * @throws InvalidArgumentException + */ + public function deleteItem(string $key): bool + { + if (!$this->isValidEntryIdentifier($key)) { + throw new InvalidArgumentException('"' . $key . '" is not a valid cache entry identifier.', 1514741469583); + } + + return $this->backend->remove($key); + } + + /** + * Removes multiple items from the pool. + * + * @param string[] $keys + * @return bool + * @throws InvalidArgumentException + */ + public function deleteItems(array $keys): bool + { + $deleted = true; + foreach ($keys as $key) { + $deleted = $this->deleteItem($key) ? $deleted : false; + } + + return $deleted; + } + + /** + * Persists a cache item immediately. + * + * @param CacheItemInterface $item + * @return bool + * @throws \Neos\Cache\Exception + */ + public function save(CacheItemInterface $item): bool + { + $lifetime = null; + $expiresAt = null; + if ($item instanceof CacheItem) { + $expiresAt = $item->getExpirationDate(); + } + + if ($expiresAt instanceof \DateTimeInterface) { + $lifetime = $expiresAt->getTimestamp() - (new \DateTime())->getTimestamp(); + } + + $this->backend->set($item->getKey(), serialize($item->get()), [], $lifetime); + return true; + } + + /** + * Sets a cache item to be persisted later. + * + * @param CacheItemInterface $item + * @return bool + */ + public function saveDeferred(CacheItemInterface $item): bool + { + $this->deferredItems[] = $item; + return true; + } + + /** + * Persists any deferred cache items. + * + * @return bool + * @throws \Neos\Cache\Exception + */ + public function commit(): bool + { + foreach ($this->deferredItems as $item) { + $this->save($item); + } + + $this->deferredItems = []; + + return true; + } + + /** + * Checks the validity of an entry identifier. Returns true if it's valid. + * + * @param string $identifier An identifier to be checked for validity + * @return boolean + * @api + */ + public function isValidEntryIdentifier($identifier): bool + { + return preg_match(self::PATTERN_ENTRYIDENTIFIER, $identifier) === 1; + } +} diff --git a/Neos.Cache/Classes/Frontend/Psr/Cache/InvalidArgumentException.php b/Neos.Cache/Classes/Frontend/Psr/Cache/InvalidArgumentException.php new file mode 100644 index 0000000000..cf875c60ba --- /dev/null +++ b/Neos.Cache/Classes/Frontend/Psr/Cache/InvalidArgumentException.php @@ -0,0 +1,21 @@ +ensureValidEntryIdentifier($key); + + try { + if ($ttl instanceof \DateInterval) { + $lifetime = $this->calculateLifetimeFromDateInterval($ttl); + } else { + $lifetime = $ttl; + } + $this->backend->set($key, serialize($value), [], $lifetime); + } catch (\Throwable $throwable) { + throw new Exception('An exception was thrown in retrieving the key from the cache backend.', 1515193492062, $throwable); + } + return true; + } + + /** + * Finds and returns a variable value from the cache. + * + * @param string $key Identifier of the cache entry to fetch + * @param mixed $default + * @return mixed The value or the defaultValue if entry was not found + * @throws Exception + * @throws InvalidArgumentException + */ + public function get(string $key, mixed $default = null): mixed + { + $this->ensureValidEntryIdentifier($key); + try { + $rawResult = $this->backend->get($key); + } catch (\Throwable $throwable) { + throw new Exception('An exception was thrown in retrieving the key from the cache backend.', 1515193339722, $throwable); + } + if ($rawResult === false) { + return $default; + } + + return unserialize((string)$rawResult); + } + + /** + * @param string $key + * @return bool + * @throws Exception + * @throws InvalidArgumentException + */ + public function delete(string $key): bool + { + $this->ensureValidEntryIdentifier($key); + try { + return $this->backend->remove($key); + } catch (\Throwable $throwable) { + throw new Exception('An exception was thrown in removing the key from the cache backend.', 1515193384076, $throwable); + } + } + + /** + * @return bool + */ + public function clear(): bool + { + $this->backend->flush(); + return true; + } + + /** + * @param iterable $keys + * @param mixed $default + * @return iterable + * @throws InvalidArgumentException + * @throws Exception + */ + public function getMultiple(iterable $keys, mixed $default = null): iterable + { + $result = []; + foreach ($keys as $key) { + $result[$key] = $this->get($key, $default); + } + return $result; + } + + /** + * @param iterable $values + * @param null|int|\DateInterval $ttl + * @return bool + * @throws Exception + * @throws InvalidArgumentException + */ + public function setMultiple(iterable $values, null|int|\DateInterval $ttl = null): bool + { + $allSet = true; + if ($ttl instanceof \DateInterval) { + $lifetime = $this->calculateLifetimeFromDateInterval($ttl); + } else { + $lifetime = $ttl; + } + foreach ($values as $key => $value) { + $allSet = $this->set($key, $value, $lifetime) && $allSet; + } + + return $allSet; + } + + /** + * @param iterable $keys + * @return bool + * @throws InvalidArgumentException + * @throws Exception + */ + public function deleteMultiple(iterable $keys): bool + { + foreach ($keys as $key) { + $this->delete($key); + }; + + return true; + } + + /** + * @param string $key + * @return bool + * @throws InvalidArgumentException + */ + public function has(string $key): bool + { + $this->ensureValidEntryIdentifier($key); + return $this->backend->has($key); + } + + + /** + * @param string $key + * @return void + * @throws InvalidArgumentException + */ + protected function ensureValidEntryIdentifier($key): void + { + if (preg_match(self::PATTERN_ENTRYIDENTIFIER, $key) !== 1) { + throw new InvalidArgumentException('"' . $key . '" is not a valid cache key.', 1515192768083); + } + } + + /** + * @param \DateInterval $ttl + * @return int + */ + protected function calculateLifetimeFromDateInterval(\DateInterval $ttl): int + { + $lifetime = (int)( + ((int)$ttl->format('a')) * 86400 + + $ttl->h * 3600 + + $ttl->m * 60 + + $ttl->s + ); + return $lifetime; + } +} diff --git a/Neos.Cache/Classes/Frontend/VariableFrontend.php b/Neos.Cache/Classes/Frontend/VariableFrontend.php index 6498f081b8..a09e30265f 100644 --- a/Neos.Cache/Classes/Frontend/VariableFrontend.php +++ b/Neos.Cache/Classes/Frontend/VariableFrontend.php @@ -40,7 +40,6 @@ class VariableFrontend extends AbstractFrontend public function initializeObject() { $this->useIgBinary = extension_loaded('igbinary'); - parent::initializeObject(); } /** diff --git a/Neos.Cache/Classes/Psr/Cache/CacheFactory.php b/Neos.Cache/Classes/Psr/Cache/CacheFactory.php index 9b2d73d6e9..48537472bd 100644 --- a/Neos.Cache/Classes/Psr/Cache/CacheFactory.php +++ b/Neos.Cache/Classes/Psr/Cache/CacheFactory.php @@ -22,6 +22,7 @@ /** * A factory for the PSR-6 compatible cache pool. + * @deprecated will be removed with Neos Flow 10. Use CacheManager and Caches.yaml instead. */ class CacheFactory { diff --git a/Neos.Cache/Classes/Psr/Cache/CacheItem.php b/Neos.Cache/Classes/Psr/Cache/CacheItem.php index 810c40b824..4c6f16286d 100644 --- a/Neos.Cache/Classes/Psr/Cache/CacheItem.php +++ b/Neos.Cache/Classes/Psr/Cache/CacheItem.php @@ -19,6 +19,7 @@ * A cache item (entry). * This is not to be created by user libraries. Instead request an item from the pool (frontend). * @see CachePool + * @deprecated will be removed with Neos Flow 10. Use \Neos\Cache\Frontend\Psr\Cache\CacheItem instead. */ class CacheItem implements CacheItemInterface { diff --git a/Neos.Cache/Classes/Psr/Cache/CachePool.php b/Neos.Cache/Classes/Psr/Cache/CachePool.php index 998b0f4653..bacf3f45c1 100644 --- a/Neos.Cache/Classes/Psr/Cache/CachePool.php +++ b/Neos.Cache/Classes/Psr/Cache/CachePool.php @@ -21,6 +21,7 @@ /** * An implementation of the CacheItemPoolInterface from the PSR-6 specification to be used with our provided backends. * @see CacheFactory + * @deprecated will be removed with Neos Flow 10. Use \Neos\Cache\Frontend\Psr\Cache\CacheItemPoolFrontend instead. */ class CachePool implements CacheItemPoolInterface { diff --git a/Neos.Cache/Classes/Psr/SimpleCache/SimpleCache.php b/Neos.Cache/Classes/Psr/SimpleCache/SimpleCache.php index 4666860c6c..d5923c80f4 100644 --- a/Neos.Cache/Classes/Psr/SimpleCache/SimpleCache.php +++ b/Neos.Cache/Classes/Psr/SimpleCache/SimpleCache.php @@ -21,6 +21,7 @@ /** * A simple cache frontend * Note: This does not follow the \Neos\Cache\Frontend\FrontendInterface this package provides. + * @deprecated will be removed with Neos Flow 10. Use \Neos\Cache\Frontend\Psr\SimpleCache\SimpleCacheFrontend instead. */ class SimpleCache implements CacheInterface { diff --git a/Neos.Cache/Classes/Psr/SimpleCache/SimpleCacheFactory.php b/Neos.Cache/Classes/Psr/SimpleCache/SimpleCacheFactory.php index 9daeb39c82..7660eba886 100644 --- a/Neos.Cache/Classes/Psr/SimpleCache/SimpleCacheFactory.php +++ b/Neos.Cache/Classes/Psr/SimpleCache/SimpleCacheFactory.php @@ -22,6 +22,7 @@ /** * A factory for PSR-16 simple caches. + * @deprecated will be removed with Neos Flow 10. Use CacheManager and Caches.yaml instead. */ class SimpleCacheFactory { diff --git a/Neos.Cache/Tests/Functional/Backend/PdoBackendTest.php b/Neos.Cache/Tests/Functional/Backend/PdoBackendTest.php index 6777c88488..c96e60b2f1 100644 --- a/Neos.Cache/Tests/Functional/Backend/PdoBackendTest.php +++ b/Neos.Cache/Tests/Functional/Backend/PdoBackendTest.php @@ -17,7 +17,7 @@ use Neos\Cache\Backend\PdoBackend; use Neos\Cache\EnvironmentConfiguration; use Neos\Cache\Tests\BaseTestCase; -use Neos\Cache\Frontend\FrontendInterface; +use Neos\Cache\Frontend\LowLevelFrontendInterface; /** * Testcase for the PDO cache backend @@ -36,7 +36,7 @@ class PdoBackendTest extends BaseTestCase private $backends = []; /** - * @var \PHPUnit\Framework\MockObject\MockObject|FrontendInterface + * @var \PHPUnit\Framework\MockObject\MockObject|LowLevelFrontendInterface */ private $cache; @@ -49,7 +49,7 @@ protected function tearDown(): void public function backendsToTest(): array { - $this->cache = $this->createMock(FrontendInterface::class); + $this->cache = $this->createMock(LowLevelFrontendInterface::class); $this->cache->method('getIdentifier')->willReturn('TestCache'); $this->setupBackends(); return $this->backends; diff --git a/Neos.Cache/Tests/Functional/Backend/RedisBackendTest.php b/Neos.Cache/Tests/Functional/Backend/RedisBackendTest.php index 2a387b8574..858f2cea88 100644 --- a/Neos.Cache/Tests/Functional/Backend/RedisBackendTest.php +++ b/Neos.Cache/Tests/Functional/Backend/RedisBackendTest.php @@ -16,7 +16,7 @@ use Neos\Cache\Backend\RedisBackend; use Neos\Cache\EnvironmentConfiguration; use Neos\Cache\Tests\BaseTestCase; -use Neos\Cache\Frontend\FrontendInterface; +use Neos\Cache\Frontend\LowLevelFrontendInterface; /** * Testcase for the redis cache backend @@ -37,7 +37,7 @@ class RedisBackendTest extends BaseTestCase private $backend; /** - * @var \PHPUnit\Framework\MockObject\MockObject|FrontendInterface + * @var \PHPUnit\Framework\MockObject\MockObject|LowLevelFrontendInterface */ private $cache; @@ -63,7 +63,7 @@ protected function setUp(): void new EnvironmentConfiguration('Redis a wonderful color Testing', '/some/path', PHP_MAXPATHLEN), ['hostname' => '127.0.0.1', 'database' => 0] ); - $this->cache = $this->createMock(FrontendInterface::class); + $this->cache = $this->createMock(LowLevelFrontendInterface::class); $this->cache->expects(self::any())->method('getIdentifier')->will(self::returnValue('TestCache')); $this->backend->setCache($this->cache); $this->backend->flush(); diff --git a/Neos.Cache/Tests/Unit/Backend/ApcuBackendTest.php b/Neos.Cache/Tests/Unit/Backend/ApcuBackendTest.php index 90c258fbca..38dfe9599b 100644 --- a/Neos.Cache/Tests/Unit/Backend/ApcuBackendTest.php +++ b/Neos.Cache/Tests/Unit/Backend/ApcuBackendTest.php @@ -17,7 +17,7 @@ use Neos\Cache\EnvironmentConfiguration; use Neos\Cache\Exception; use Neos\Cache\Tests\BaseTestCase; -use Neos\Cache\Frontend\FrontendInterface; +use Neos\Cache\Frontend\LowLevelFrontendInterface; use Neos\Cache\Frontend\VariableFrontend; /** @@ -227,12 +227,12 @@ public function flushRemovesAllCacheEntries() */ public function flushRemovesOnlyOwnEntries() { - $thisCache = $this->createMock(FrontendInterface::class); + $thisCache = $this->createMock(LowLevelFrontendInterface::class); $thisCache->expects(self::any())->method('getIdentifier')->will(self::returnValue('thisCache')); $thisBackend = new ApcuBackend($this->getEnvironmentConfiguration(), []); $thisBackend->setCache($thisCache); - $thatCache = $this->createMock(FrontendInterface::class); + $thatCache = $this->createMock(LowLevelFrontendInterface::class); $thatCache->expects(self::any())->method('getIdentifier')->will(self::returnValue('thatCache')); $thatBackend = new ApcuBackend($this->getEnvironmentConfiguration(), []); $thatBackend->setCache($thatCache); @@ -422,7 +422,7 @@ public function iterationResetsWhenDataGetsRemoved() */ protected function setUpBackend() { - $cache = $this->createMock(FrontendInterface::class); + $cache = $this->createMock(LowLevelFrontendInterface::class); $backend = new ApcuBackend($this->getEnvironmentConfiguration(), []); $backend->setCache($cache); $backend->flush(); // I'd rather start with a clean directory in the first place, but I can't get the "vfs" thing to work diff --git a/Neos.Cache/Tests/Unit/Backend/FileBackendTest.php b/Neos.Cache/Tests/Unit/Backend/FileBackendTest.php index 30c382ac08..6c685fa000 100644 --- a/Neos.Cache/Tests/Unit/Backend/FileBackendTest.php +++ b/Neos.Cache/Tests/Unit/Backend/FileBackendTest.php @@ -19,7 +19,7 @@ use Neos\Cache\Exception; use Neos\Cache\Tests\BaseTestCase; use org\bovigo\vfs\vfsStream; -use Neos\Cache\Frontend\AbstractFrontend; +use Neos\Cache\Frontend\AbstractLowLevelFrontend; use Neos\Cache\Frontend\PhpFrontend; use Neos\Cache\Frontend\VariableFrontend; use PHPUnit\Framework\MockObject\MockObject; @@ -42,7 +42,7 @@ protected function setUp(): void public function setCacheThrowsExceptionOnNonWritableDirectory() { $this->expectException(Exception::class); - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockEnvironmentConfiguration = $this->createEnvironmentConfigurationMock([__DIR__ . '~Testing', 'http://localhost/', PHP_MAXPATHLEN]); @@ -61,7 +61,7 @@ public function setCacheThrowsExceptionOnNonWritableDirectory() */ public function setCacheDirectoryAllowsToSetTheCurrentCacheDirectory() { - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockCache->expects(self::any())->method('getIdentifier')->will(self::returnValue('SomeCache')); $mockEnvironmentConfiguration = $this->createEnvironmentConfigurationMock([ @@ -86,7 +86,7 @@ public function setCacheDirectoryAllowsToSetTheCurrentCacheDirectory() */ public function getCacheDirectoryReturnsTheCurrentCacheDirectory() { - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockCache->expects(self::any())->method('getIdentifier')->will(self::returnValue('SomeCache')); // We need to create the directory here because vfs doesn't support touch() which is used by @@ -120,7 +120,7 @@ public function aDedicatedCacheDirectoryIsUsedForCodeCaches() */ public function setReallySavesToTheSpecifiedDirectory() { - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockCache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('UnitTestCache')); $data = 'some data' . microtime(); @@ -142,7 +142,7 @@ public function setReallySavesToTheSpecifiedDirectory() */ public function setOverwritesAnAlreadyExistingCacheEntryForTheSameIdentifier() { - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockCache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('UnitTestCache')); $data1 = 'some data' . microtime(); @@ -166,7 +166,7 @@ public function setOverwritesAnAlreadyExistingCacheEntryForTheSameIdentifier() */ public function setAlsoSavesSpecifiedTags() { - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockCache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('UnitTestCache')); $data = 'some data' . microtime(); @@ -217,7 +217,7 @@ public function setThrowsExceptionIfCachePathLengthExceedsMaximumPathLength() */ public function setCacheDetectsAndLoadsAFrozenCache() { - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockCache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('UnitTestCache')); $mockEnvironmentConfiguration = $this->createEnvironmentConfigurationMock([ @@ -256,7 +256,7 @@ public function setCacheDetectsAndLoadsAFrozenCache() */ public function getReturnsContentOfTheCorrectCacheFile() { - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockCache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('UnitTestCache')); $mockEnvironmentConfiguration = $this->createEnvironmentConfigurationMock([ @@ -290,7 +290,7 @@ public function getReturnsContentOfTheCorrectCacheFile() */ public function getReturnsFalseForExpiredEntries() { - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockCache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('UnitTestCache')); $backend = $this->prepareDefaultBackend(['dummy'], [ @@ -313,7 +313,7 @@ public function getReturnsFalseForExpiredEntries() */ public function getDoesUseInternalGetIfTheCacheIsFrozen() { - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockCache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('UnitTestCache')); /** @var MockObject $backend */ $backend = $this->prepareDefaultBackend(['internalGet'], [ @@ -336,7 +336,7 @@ public function getDoesUseInternalGetIfTheCacheIsFrozen() */ public function hasReturnsTrueIfAnEntryExists() { - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockCache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('UnitTestCache')); $backend = $this->prepareDefaultBackend(); @@ -368,7 +368,7 @@ public function hasReturnsFalseForExpiredEntries() */ public function hasDoesNotCheckIfAnEntryIsExpiredIfTheCacheIsFrozen() { - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockCache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('UnitTestCache')); $backend = $this->prepareDefaultBackend(['isCacheFileExpired'], [ @@ -392,7 +392,7 @@ public function hasDoesNotCheckIfAnEntryIsExpiredIfTheCacheIsFrozen() */ public function removeReallyRemovesACacheEntry() { - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockCache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('UnitTestCache')); $data = 'some data' . microtime(); @@ -436,7 +436,7 @@ public function invalidEntryIdentifiers() public function setThrowsExceptionForInvalidIdentifier($identifier) { $this->expectException(\InvalidArgumentException::class); - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockCache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('UnitTestCache')); $backend = $this->prepareDefaultBackend(); $backend->setCache($mockCache); @@ -451,7 +451,7 @@ public function setThrowsExceptionForInvalidIdentifier($identifier) public function getThrowsExceptionForInvalidIdentifier($identifier) { $this->expectException(\InvalidArgumentException::class); - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockCache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('UnitTestCache')); $backend = $this->prepareDefaultBackend(['isCacheFileExpired']); @@ -479,7 +479,7 @@ public function hasThrowsExceptionForInvalidIdentifier($identifier) public function removeThrowsExceptionForInvalidIdentifier($identifier) { $this->expectException(\InvalidArgumentException::class); - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockCache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('UnitTestCache')); $backend = $this->prepareDefaultBackend(); @@ -495,7 +495,7 @@ public function removeThrowsExceptionForInvalidIdentifier($identifier) public function requireOnceThrowsExceptionForInvalidIdentifier($identifier) { $this->expectException(\InvalidArgumentException::class); - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockCache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('UnitTestCache')); $backend = $this->prepareDefaultBackend(); @@ -509,7 +509,7 @@ public function requireOnceThrowsExceptionForInvalidIdentifier($identifier) */ public function requireOnceIncludesAndReturnsResultOfIncludedPhpFile() { - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockCache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('UnitTestCache')); $backend = $this->prepareDefaultBackend(); @@ -529,7 +529,7 @@ public function requireOnceIncludesAndReturnsResultOfIncludedPhpFile() */ public function requireOnceDoesNotCheckExpiryTimeIfBackendIsFrozen() { - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockCache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('UnitTestCache')); $backend = $this->prepareDefaultBackend(['isCacheFileExpired']); @@ -552,7 +552,7 @@ public function requireOnceDoesNotCheckExpiryTimeIfBackendIsFrozen() public function requireOnceDoesNotSwallowExceptionsOfTheIncludedFile() { $this->expectException(\Exception::class); - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockCache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('UnitTestCache')); $backend = $this->prepareDefaultBackend(); @@ -569,7 +569,7 @@ public function requireOnceDoesNotSwallowExceptionsOfTheIncludedFile() public function requireOnceDoesNotSwallowPhpWarningsOfTheIncludedFile() { $this->expectWarning(); - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockCache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('UnitTestCache')); $backend = $this->prepareDefaultBackend(); @@ -586,7 +586,7 @@ public function requireOnceDoesNotSwallowPhpWarningsOfTheIncludedFile() public function requireOnceDoesNotSwallowPhpNoticesOfTheIncludedFile() { $this->expectNotice(); - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockCache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('UnitTestCache')); $backend = $this->prepareDefaultBackend(); @@ -602,7 +602,7 @@ public function requireOnceDoesNotSwallowPhpNoticesOfTheIncludedFile() */ public function findIdentifiersByTagFindsCacheEntriesWithSpecifiedTag() { - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockCache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('UnitTestCache')); $backend = $this->prepareDefaultBackend(); @@ -626,7 +626,7 @@ public function findIdentifiersByTagFindsCacheEntriesWithSpecifiedTag() */ public function findIdentifiersByTagReturnsEmptyArrayForExpiredEntries() { - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockCache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('UnitTestCache')); $backend = $this->prepareDefaultBackend(); @@ -646,7 +646,7 @@ public function findIdentifiersByTagReturnsEmptyArrayForExpiredEntries() */ public function flushRemovesAllCacheEntries() { - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockCache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('UnitTestCache')); $backend = $this->prepareDefaultBackend(); @@ -696,7 +696,7 @@ public function flushByTagsRemovesCacheEntriesWithSpecifiedTags() */ public function collectGarbageRemovesExpiredCacheEntries() { - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockCache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('UnitTestCache')); $backend = $this->prepareDefaultBackend(['isCacheFileExpired']); @@ -720,7 +720,7 @@ public function collectGarbageRemovesExpiredCacheEntries() */ public function flushUnfreezesTheCache() { - $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache = $this->createMock(AbstractLowLevelFrontend::class); $mockCache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('UnitTestCache')); $backend = $this->prepareDefaultBackend(); diff --git a/Neos.Cache/Tests/Unit/Backend/MemcachedBackendTest.php b/Neos.Cache/Tests/Unit/Backend/MemcachedBackendTest.php index a87cc1b5f2..7df1863777 100644 --- a/Neos.Cache/Tests/Unit/Backend/MemcachedBackendTest.php +++ b/Neos.Cache/Tests/Unit/Backend/MemcachedBackendTest.php @@ -17,8 +17,8 @@ use Neos\Cache\EnvironmentConfiguration; use Neos\Cache\Exception; use Neos\Cache\Tests\BaseTestCase; -use Neos\Cache\Frontend\AbstractFrontend; -use Neos\Cache\Frontend\FrontendInterface; +use Neos\Cache\Frontend\AbstractLowLevelFrontend; +use Neos\Cache\Frontend\LowLevelFrontendInterface; /** * Testcase for the cache to memcached backend @@ -233,12 +233,12 @@ public function flushRemovesOnlyOwnEntries() { $backendOptions = ['servers' => ['localhost:11211']]; - $thisCache = $this->getMockBuilder(AbstractFrontend::class)->disableOriginalConstructor()->getMock(); + $thisCache = $this->getMockBuilder(AbstractLowLevelFrontend::class)->disableOriginalConstructor()->getMock(); $thisCache->expects(self::any())->method('getIdentifier')->will(self::returnValue('thisCache')); $thisBackend = new MemcachedBackend($this->getEnvironmentConfiguration(), $backendOptions); $thisBackend->setCache($thisCache); - $thatCache = $this->getMockBuilder(AbstractFrontend::class)->disableOriginalConstructor()->getMock(); + $thatCache = $this->getMockBuilder(AbstractLowLevelFrontend::class)->disableOriginalConstructor()->getMock(); $thatCache->expects(self::any())->method('getIdentifier')->will(self::returnValue('thatCache')); $thatBackend = new MemcachedBackend($this->getEnvironmentConfiguration(), $backendOptions); $thatBackend->setCache($thatCache); @@ -276,7 +276,7 @@ public function largeDataIsStored() */ protected function setUpBackend(array $backendOptions = []) { - $cache = $this->createMock(FrontendInterface::class, [], [], '', false); + $cache = $this->createMock(LowLevelFrontendInterface::class, [], [], '', false); if ($backendOptions == []) { $backendOptions = ['servers' => ['localhost:11211']]; } diff --git a/Neos.Cache/Tests/Unit/Backend/PdoBackendTest.php b/Neos.Cache/Tests/Unit/Backend/PdoBackendTest.php index 1433f3bf17..9088fc18c5 100644 --- a/Neos.Cache/Tests/Unit/Backend/PdoBackendTest.php +++ b/Neos.Cache/Tests/Unit/Backend/PdoBackendTest.php @@ -16,7 +16,7 @@ use Neos\Cache\Backend\PdoBackend; use Neos\Cache\EnvironmentConfiguration; use Neos\Cache\Exception; -use Neos\Cache\Frontend\FrontendInterface; +use Neos\Cache\Frontend\LowLevelFrontendInterface; use Neos\Cache\Tests\BaseTestCase; use PHPUnit\Framework\MockObject\MockObject; @@ -218,12 +218,12 @@ public function flushRemovesAllCacheEntries() */ public function flushRemovesOnlyOwnEntries() { - $thisCache = $this->getMockBuilder(FrontendInterface::class)->disableOriginalConstructor()->getMock(); + $thisCache = $this->getMockBuilder(LowLevelFrontendInterface::class)->disableOriginalConstructor()->getMock(); $thisCache->expects(self::any())->method('getIdentifier')->will(self::returnValue('thisCache')); $thisBackend = $this->setUpBackend(); $thisBackend->setCache($thisCache); - $thatCache = $this->getMockBuilder(FrontendInterface::class)->disableOriginalConstructor()->getMock(); + $thatCache = $this->getMockBuilder(LowLevelFrontendInterface::class)->disableOriginalConstructor()->getMock(); $thatCache->expects(self::any())->method('getIdentifier')->will(self::returnValue('thatCache')); $thatBackend = $this->setUpBackend(); $thatBackend->setCache($thatCache); @@ -338,8 +338,8 @@ public function iterationResetsWhenDataGetsRemoved() */ protected function setUpBackend() { - /** @var FrontendInterface|MockObject $mockCache */ - $mockCache = $this->getMockBuilder(FrontendInterface::class)->disableOriginalConstructor()->getMock(); + /** @var LowLevelFrontendInterface|MockObject $mockCache */ + $mockCache = $this->getMockBuilder(LowLevelFrontendInterface::class)->disableOriginalConstructor()->getMock(); $mockCache->expects(self::any())->method('getIdentifier')->will(self::returnValue('TestCache')); $mockEnvironmentConfiguration = $this->getMockBuilder(EnvironmentConfiguration::class)->setConstructorArgs([ diff --git a/Neos.Cache/Tests/Unit/Backend/RedisBackendTest.php b/Neos.Cache/Tests/Unit/Backend/RedisBackendTest.php index 1025510628..5e42ce5c75 100644 --- a/Neos.Cache/Tests/Unit/Backend/RedisBackendTest.php +++ b/Neos.Cache/Tests/Unit/Backend/RedisBackendTest.php @@ -16,7 +16,7 @@ use Neos\Cache\Backend\RedisBackend; use Neos\Cache\EnvironmentConfiguration; -use Neos\Cache\Frontend\FrontendInterface; +use Neos\Cache\Frontend\LowLevelFrontendInterface; use Neos\Cache\Tests\BaseTestCase; /** @@ -38,7 +38,7 @@ class RedisBackendTest extends BaseTestCase private $backend; /** - * @var \PHPUnit\Framework\MockObject\MockObject|FrontendInterface + * @var \PHPUnit\Framework\MockObject\MockObject|LowLevelFrontendInterface */ private $cache; @@ -54,7 +54,7 @@ protected function setUp(): void } $this->redis = $this->getMockBuilder(\Redis::class)->disableOriginalConstructor()->getMock(); - $this->cache = $this->createMock(FrontendInterface::class); + $this->cache = $this->createMock(LowLevelFrontendInterface::class); $this->cache->method('getIdentifier') ->willReturn('Foo_Cache'); diff --git a/Neos.Cache/Tests/Unit/Backend/SimpleFileBackendTest.php b/Neos.Cache/Tests/Unit/Backend/SimpleFileBackendTest.php index 9d5dd33dec..b3282f389e 100644 --- a/Neos.Cache/Tests/Unit/Backend/SimpleFileBackendTest.php +++ b/Neos.Cache/Tests/Unit/Backend/SimpleFileBackendTest.php @@ -18,7 +18,7 @@ use Neos\Cache\Exception; use Neos\Cache\Tests\BaseTestCase; use org\bovigo\vfs\vfsStream; -use Neos\Cache\Frontend\FrontendInterface; +use Neos\Cache\Frontend\LowLevelFrontendInterface; use Neos\Cache\Frontend\PhpFrontend; /** @@ -27,7 +27,7 @@ class SimpleFileBackendTest extends BaseTestCase { /** - * @var FrontendInterface|\PHPUnit\Framework\MockObject\MockObject + * @var LowLevelFrontendInterface|\PHPUnit\Framework\MockObject\MockObject */ protected $mockCacheFrontend; @@ -51,17 +51,17 @@ protected function setUp(): void 1024 ])->getMock(); - $this->mockCacheFrontend = $this->createMock(FrontendInterface::class); + $this->mockCacheFrontend = $this->createMock(LowLevelFrontendInterface::class); } /** * Convenience function to retrieve an instance of SimpleFileBackend with required dependencies * * @param array $options - * @param FrontendInterface $mockCacheFrontend + * @param LowLevelFrontendInterface $mockCacheFrontend * @return SimpleFileBackend */ - protected function getSimpleFileBackend(array $options = [], FrontendInterface $mockCacheFrontend = null) + protected function getSimpleFileBackend(array $options = [], LowLevelFrontendInterface $mockCacheFrontend = null) { $simpleFileBackend = new SimpleFileBackend($this->mockEnvironmentConfiguration, $options); diff --git a/Neos.Cache/Tests/Unit/Backend/TransientMemoryBackendTest.php b/Neos.Cache/Tests/Unit/Backend/TransientMemoryBackendTest.php index c21752ffde..77fafd088c 100644 --- a/Neos.Cache/Tests/Unit/Backend/TransientMemoryBackendTest.php +++ b/Neos.Cache/Tests/Unit/Backend/TransientMemoryBackendTest.php @@ -18,7 +18,7 @@ use Neos\Cache\Exception; use Neos\Cache\Frontend\StringFrontend; use Neos\Cache\Tests\BaseTestCase; -use Neos\Cache\Frontend\FrontendInterface; +use Neos\Cache\Frontend\LowLevelFrontendInterface; /** * Testcase for the Transient Memory Backend @@ -44,7 +44,7 @@ public function setThrowsExceptionIfNoFrontEndHasBeenSet(): void */ public function itIsPossibleToSetAndCheckExistenceInCache(): void { - $cache = $this->createMock(FrontendInterface::class); + $cache = $this->createMock(LowLevelFrontendInterface::class); $backend = new TransientMemoryBackend($this->getEnvironmentConfiguration()); $backend->setCache($cache); @@ -60,7 +60,7 @@ public function itIsPossibleToSetAndCheckExistenceInCache(): void */ public function itIsPossibleToSetAndGetEntry(): void { - $cache = $this->createMock(FrontendInterface::class); + $cache = $this->createMock(LowLevelFrontendInterface::class); $backend = new TransientMemoryBackend($this->getEnvironmentConfiguration()); $backend->setCache($cache); @@ -76,7 +76,7 @@ public function itIsPossibleToSetAndGetEntry(): void */ public function itIsPossibleToRemoveEntryFromCache(): void { - $cache = $this->createMock(FrontendInterface::class); + $cache = $this->createMock(LowLevelFrontendInterface::class); $backend = new TransientMemoryBackend($this->getEnvironmentConfiguration()); $backend->setCache($cache); @@ -93,7 +93,7 @@ public function itIsPossibleToRemoveEntryFromCache(): void */ public function itIsPossibleToOverwriteAnEntryInTheCache(): void { - $cache = $this->createMock(FrontendInterface::class); + $cache = $this->createMock(LowLevelFrontendInterface::class); $backend = new TransientMemoryBackend($this->getEnvironmentConfiguration()); $backend->setCache($cache); @@ -111,7 +111,7 @@ public function itIsPossibleToOverwriteAnEntryInTheCache(): void */ public function findIdentifiersByTagFindsCacheEntriesWithSpecifiedTag(): void { - $cache = $this->createMock(FrontendInterface::class); + $cache = $this->createMock(LowLevelFrontendInterface::class); $backend = new TransientMemoryBackend($this->getEnvironmentConfiguration()); $backend->setCache($cache); @@ -168,7 +168,7 @@ public function usingNumbersAsCacheIdentifiersWorksWhenUsingFlushTag(): void */ public function hasReturnsFalseIfTheEntryDoesntExist(): void { - $cache = $this->createMock(FrontendInterface::class); + $cache = $this->createMock(LowLevelFrontendInterface::class); $backend = new TransientMemoryBackend($this->getEnvironmentConfiguration()); $backend->setCache($cache); @@ -182,7 +182,7 @@ public function hasReturnsFalseIfTheEntryDoesntExist(): void */ public function removeReturnsFalseIfTheEntryDoesntExist(): void { - $cache = $this->createMock(FrontendInterface::class); + $cache = $this->createMock(LowLevelFrontendInterface::class); $backend = new TransientMemoryBackend($this->getEnvironmentConfiguration()); $backend->setCache($cache); @@ -196,7 +196,7 @@ public function removeReturnsFalseIfTheEntryDoesntExist(): void */ public function flushByTagRemovesCacheEntriesWithSpecifiedTag(): void { - $cache = $this->createMock(FrontendInterface::class); + $cache = $this->createMock(LowLevelFrontendInterface::class); $backend = new TransientMemoryBackend($this->getEnvironmentConfiguration()); $backend->setCache($cache); @@ -217,7 +217,7 @@ public function flushByTagRemovesCacheEntriesWithSpecifiedTag(): void */ public function flushByTagsRemovesCacheEntriesWithSpecifiedTags(): void { - $cache = $this->createMock(FrontendInterface::class); + $cache = $this->createMock(LowLevelFrontendInterface::class); $backend = new TransientMemoryBackend($this->getEnvironmentConfiguration()); $backend->setCache($cache); @@ -238,7 +238,7 @@ public function flushByTagsRemovesCacheEntriesWithSpecifiedTags(): void */ public function flushRemovesAllCacheEntries(): void { - $cache = $this->createMock(FrontendInterface::class); + $cache = $this->createMock(LowLevelFrontendInterface::class); $backend = new TransientMemoryBackend($this->getEnvironmentConfiguration()); $backend->setCache($cache); diff --git a/Neos.Cache/Tests/Unit/Frontend/Psr/Cache/CachePoolTest.php b/Neos.Cache/Tests/Unit/Frontend/Psr/Cache/CachePoolTest.php new file mode 100644 index 0000000000..528d9ad663 --- /dev/null +++ b/Neos.Cache/Tests/Unit/Frontend/Psr/Cache/CachePoolTest.php @@ -0,0 +1,210 @@ +getMockBuilder(BackendInterface::class)->getMock(); + $cachePool = new CacheItemPoolFrontend('CacheItemPool', $mockBackend); + self::assertTrue($cachePool->isValidEntryIdentifier($identifier)); + } + + public function invalidIdentifiersDataProvider(): array + { + return [ + [''], + ['späcialcharacters'], + ['a-string-that-exceeds-the-maximum-allowed-length-of-twohundredandfifty-characters-which-is-pretty-large-as-it-turns-out-so-i-repeat-a-string-that-exceeds-the-maximum-allowed-length-of-twohundredandfifty-characters-still-not-there-wow-crazy-flow-rocks-though'], + ]; + } + + /** + * @test + * @dataProvider invalidIdentifiersDataProvider + */ + public function invalidIdentifiers(string $identifier): void + { + $mockBackend = $this->getMockBuilder(BackendInterface::class)->getMock(); + $cachePool = new CacheItemPoolFrontend('CacheItemPool', $mockBackend); + $this->assertFalse($cachePool->isValidEntryIdentifier($identifier)); + } + + + + /** + * @test + */ + public function getItemChecksIfTheIdentifierIsValid() + { + $this->expectException(InvalidArgumentException::class); + /** @var PsrFrontend|\PHPUnit\Framework\MockObject\MockObject $cache */ + $cache = $this->getMockBuilder(CacheItemPoolFrontend::class) + ->setMethods(['isValidEntryIdentifier']) + ->disableOriginalConstructor() + ->getMock(); + $cache->expects(self::once())->method('isValidEntryIdentifier')->with('foo')->willReturn(false); + $cache->getItem('foo'); + } + + /** + * @test + */ + public function savePassesSerializedStringToBackend() + { + $theString = 'Just some value'; + $cacheItem = new CacheItem('PsrCacheTest', true, $theString); + $backend = $this->prepareDefaultBackend(); + $backend->expects(self::once())->method('set')->with(self::equalTo('PsrCacheTest'), self::equalTo(serialize($theString))); + + $cache = new CacheItemPoolFrontend('CachePool', $backend); + $cache->save($cacheItem); + } + + /** + * @test + */ + public function savePassesSerializedArrayToBackend() + { + $theArray = ['Just some value', 'and another one.']; + $cacheItem = new CacheItem('PsrCacheTest', true, $theArray); + $backend = $this->prepareDefaultBackend(); + $backend->expects(self::once())->method('set')->with(self::equalTo('PsrCacheTest'), self::equalTo(serialize($theArray))); + + $cache = new CacheItemPoolFrontend('CachePool', $backend); + $cache->save($cacheItem); + } + + /** + * @test + */ + public function savePassesLifetimeToBackend() + { + // Note that this test can fail due to fraction of second problems in the calculation of lifetime vs. expiration date. + $theString = 'Just some value'; + $theLifetime = 1234; + $cacheItem = new CacheItem('PsrCacheTest', true, $theString); + $cacheItem->expiresAfter($theLifetime); + $backend = $this->prepareDefaultBackend(); + $backend->expects(self::once())->method('set')->with(self::equalTo('PsrCacheTest'), self::equalTo(serialize($theString)), self::equalTo([]), self::equalTo($theLifetime, 1)); + + $cache = new CacheItemPoolFrontend('CachePool', $backend); + $cache->save($cacheItem); + } + + /** + * @test + */ + public function getItemFetchesValueFromBackend() + { + $theString = 'Just some value'; + $backend = $this->prepareDefaultBackend(); + $backend->expects(self::any())->method('get')->willReturn(serialize($theString)); + + $cache = new CacheItemPoolFrontend('CachePool', $backend); + self::assertEquals(true, $cache->getItem('PsrCacheTest')->isHit(), 'The item should have been a hit but is not'); + self::assertEquals($theString, $cache->getItem('PsrCacheTest')->get(), 'The returned value was not the expected string.'); + } + + /** + * @test + */ + public function getItemFetchesFalseBooleanValueFromBackend() + { + $backend = $this->prepareDefaultBackend(); + $backend->expects(self::once())->method('get')->willReturn(serialize(false)); + + $cache = new CacheItemPoolFrontend('CachePool', $backend); + $retrievedItem = $cache->getItem('PsrCacheTest'); + self::assertEquals(true, $retrievedItem->isHit(), 'The item should have been a hit but is not'); + self::assertEquals(false, $retrievedItem->get(), 'The returned value was not the false.'); + } + + /** + * @test + */ + public function hasItemReturnsResultFromBackend() + { + $backend = $this->prepareDefaultBackend(); + $backend->expects(self::once())->method('has')->with(self::equalTo('PsrCacheTest'))->willReturn(true); + + $cache = new CacheItemPoolFrontend('CachePool', $backend); + self::assertTrue($cache->hasItem('PsrCacheTest'), 'hasItem() did not return true.'); + } + + /** + * @test + */ + public function deleteItemCallsBackend() + { + $cacheIdentifier = 'someCacheIdentifier'; + $backend = $this->prepareDefaultBackend(); + + $backend->expects(self::once())->method('remove')->with(self::equalTo($cacheIdentifier))->willReturn(true); + + $cache = new CacheItemPoolFrontend('CachePool', $backend); + self::assertTrue($cache->deleteItem($cacheIdentifier), 'deleteItem() did not return true'); + } + + /** + * @return AbstractBackend|\PHPUnit\Framework\MockObject\MockObject + */ + protected function prepareDefaultBackend() + { + return $this->getMockBuilder(AbstractBackend::class) + ->setMethods([ + 'get', + 'set', + 'has', + 'remove', + 'findIdentifiersByTag', + 'flush', + 'flushByTag', + 'collectGarbage' + ]) + ->disableOriginalConstructor() + ->getMock(); + } +} diff --git a/Neos.Cache/Tests/Unit/Frontend/Psr/SimpleCache/SimpleCacheTest.php b/Neos.Cache/Tests/Unit/Frontend/Psr/SimpleCache/SimpleCacheTest.php new file mode 100644 index 0000000000..120e31ff2f --- /dev/null +++ b/Neos.Cache/Tests/Unit/Frontend/Psr/SimpleCache/SimpleCacheTest.php @@ -0,0 +1,247 @@ +mockBackend = $this->getMockBuilder(BackendInterface::class)->getMock(); + } + + /** + * @param string $identifier + * @return SimpleCacheFrontend + */ + protected function createSimpleCache($identifier = 'SimpleCacheTest') + { + return new SimpleCacheFrontend($identifier, $this->mockBackend); + } + + /** + * @test + */ + public function constructingWithInvalidIdentifierThrowsInvalidArgumentException() + { + $this->expectException(\InvalidArgumentException::class); + $this->createSimpleCache('Invalid #*<>/()=?!'); + } + + /** + * @test + */ + public function setThrowsInvalidArgumentExceptionOnInvalidIdentifier() + { + $this->expectException(InvalidArgumentException::class); + $simpleCache = $this->createSimpleCache(); + $simpleCache->set('Invalid #*<>/()=?!', 'does not matter'); + } + + /** + * @test + */ + public function setThrowsExceptionOnBackendError() + { + $this->expectException(Exception::class); + $this->mockBackend->expects(self::any())->method('set')->willThrowException(new Exception\InvalidDataException('Some other exception', 1234)); + $simpleCache = $this->createSimpleCache(); + $simpleCache->set('validkey', 'valid data'); + } + + /** + * @test + */ + public function setWillSetInBackendAndReturnBackendResponse() + { + $this->mockBackend->expects(self::any())->method('set'); + $simpleCache = $this->createSimpleCache(); + $result = $simpleCache->set('validkey', 'valid data'); + self::assertEquals(true, $result); + } + + /** + * @test + */ + public function getThrowsInvalidArgumentExceptionOnInvalidIdentifier() + { + $this->expectException(InvalidArgumentException::class); + $simpleCache = $this->createSimpleCache(); + $simpleCache->get('Invalid #*<>/()=?!', false); + } + + /** + * @test + */ + public function getThrowsExceptionOnBackendError() + { + $this->expectException(Exception::class); + $this->mockBackend->expects(self::any())->method('get')->willThrowException(new Exception\InvalidDataException('Some other exception', 1234)); + $simpleCache = $this->createSimpleCache(); + $simpleCache->get('validkey', false); + } + + /** + * @test + */ + public function getReturnsDefaultValueIfBackendFoundNoEntry() + { + $defaultValue = 'fallback'; + $this->mockBackend->expects(self::any())->method('get')->willReturn(false); + $simpleCache = $this->createSimpleCache(); + $result = $simpleCache->get('validkey', $defaultValue); + self::assertEquals($defaultValue, $result); + } + + /** + * Somewhat brittle test as we know that the cache serializes. Might want to extract that to a separate Serializer? + * @test + */ + public function getReturnsBackendResponseAfterUnserialising() + { + $cachedValue = [1, 2, 3]; + $this->mockBackend->expects(self::any())->method('get')->willReturn(serialize($cachedValue)); + $simpleCache = $this->createSimpleCache(); + $result = $simpleCache->get('validkey'); + self::assertEquals($cachedValue, $result); + } + + /** + * @test + */ + public function deleteThrowsInvalidArgumentExceptionOnInvalidIdentifier() + { + $this->expectException(InvalidArgumentException::class); + $simpleCache = $this->createSimpleCache(); + $simpleCache->delete('Invalid #*<>/()=?!'); + } + + /** + * @test + */ + public function deleteThrowsExceptionOnBackendError() + { + $this->expectException(Exception::class); + $this->mockBackend->expects(self::any())->method('remove')->willThrowException(new Exception\InvalidDataException('Some other exception', 1234)); + $simpleCache = $this->createSimpleCache(); + $simpleCache->delete('validkey'); + } + + /** + * @test + */ + public function getMultipleThrowsInvalidArgumentExceptionOnInvalidIdentifier() + { + $this->expectException(InvalidArgumentException::class); + $simpleCache = $this->createSimpleCache(); + $simpleCache->getMultiple(['validKey', 'Invalid #*<>/()=?!']); + } + + /** + * @test + */ + public function getMultipleGetsMultipleValues() + { + $this->mockBackend->expects(self::any())->method('get')->willReturnMap([ + ['validKey', serialize('entry1')], + ['another', serialize('entry2')] + ]); + $simpleCache = $this->createSimpleCache(); + $result = $simpleCache->getMultiple(['validKey', 'another']); + self::assertEquals(['validKey' => 'entry1', 'another' => 'entry2'], $result); + } + + /** + * @test + */ + public function getMultipleFillsWithDefault() + { + $this->mockBackend->expects(self::any())->method('get')->willReturnMap([ + ['validKey', serialize('entry1')], + ['notExistingEntry', false] + ]); + $simpleCache = $this->createSimpleCache(); + $result = $simpleCache->getMultiple(['validKey', 'notExistingEntry'], 'FALLBACK'); + self::assertEquals(['validKey' => 'entry1', 'notExistingEntry' => 'FALLBACK'], $result); + } + + /** + * @test + */ + public function setMultipleThrowsInvalidArgumentExceptionOnInvalidIdentifier() + { + $this->expectException(InvalidArgumentException::class); + $simpleCache = $this->createSimpleCache(); + $simpleCache->setMultiple(['validKey' => 'value', 'Invalid #*<>/()=?!' => 'value']); + } + + /** + * Moot test at the momment, as our backends never return so this is always true. + * + * @test + */ + public function setMultipleReturnsResult() + { + $this->mockBackend->expects(self::any())->method('set')->willReturnMap([ + ['validKey', 'value', true], + ['another', 'value', true] + ]); + + $simpleCache = $this->createSimpleCache(); + $result = $simpleCache->setMultiple(['validKey' => 'value', 'another' => 'value']); + self::assertEquals(true, $result); + } + + /** + * @test + */ + public function deleteMultipleThrowsInvalidArgumentExceptionOnInvalidIdentifier() + { + $this->expectException(InvalidArgumentException::class); + $simpleCache = $this->createSimpleCache(); + $simpleCache->deleteMultiple(['validKey', 'Invalid #*<>/()=?!']); + } + + /** + * @test + */ + public function hasThrowsInvalidArgumentExceptionOnInvalidIdentifier() + { + $this->expectException(InvalidArgumentException::class); + $simpleCache = $this->createSimpleCache(); + $simpleCache->has('Invalid #*<>/()=?!'); + } + + /** + * @test + */ + public function hasReturnsWhatTheBackendSays() + { + $this->mockBackend->expects(self::any())->method('has')->willReturnMap([ + ['existing', true], + ['notExisting', false] + ]); + + $simpleCache = $this->createSimpleCache(); + $result = $simpleCache->has('existing'); + self::assertEquals(true, $result); + + $result = $simpleCache->has('notExisting'); + self::assertEquals(false, $result); + } +} diff --git a/Neos.Cache/Tests/Unit/Psr/SimpleCache/SimpleCacheTest.php b/Neos.Cache/Tests/Unit/Psr/SimpleCache/SimpleCacheTest.php index 1706f7350e..8b7d8a0672 100644 --- a/Neos.Cache/Tests/Unit/Psr/SimpleCache/SimpleCacheTest.php +++ b/Neos.Cache/Tests/Unit/Psr/SimpleCache/SimpleCacheTest.php @@ -37,9 +37,9 @@ protected function createSimpleCache($identifier = 'SimpleCacheTest') /** * @test */ - public function constructingWithInvalidIdentifierThrowsPsrInvalidArgumentException() + public function constructingWithInvalidIdentifierThrowsInvalidArgumentException() { - $this->expectException(InvalidArgumentException::class); + $this->expectException(\InvalidArgumentException::class); $this->createSimpleCache('Invalid #*<>/()=?!'); } diff --git a/Neos.Flow/Classes/Cache/CacheFactory.php b/Neos.Flow/Classes/Cache/CacheFactory.php index 123bd70731..73a2ac107e 100644 --- a/Neos.Flow/Classes/Cache/CacheFactory.php +++ b/Neos.Flow/Classes/Cache/CacheFactory.php @@ -14,7 +14,7 @@ use Neos\Cache\Backend\BackendInterface; use Neos\Cache\Backend\SimpleFileBackend; use Neos\Cache\EnvironmentConfiguration; -use Neos\Cache\Frontend\FrontendInterface; +use Neos\Cache\Frontend\LowLevelFrontendInterface; use Neos\Flow\Annotations as Flow; use Neos\Cache\Exception\InvalidBackendException; use Neos\Flow\Core\ApplicationContext; @@ -102,9 +102,9 @@ public function __construct(ApplicationContext $context, Environment $environmen * @param string $backendObjectName * @param array $backendOptions * @param bool $persistent - * @return FrontendInterface + * @return LowLevelFrontendInterface */ - public function create(string $cacheIdentifier, string $cacheObjectName, string $backendObjectName, array $backendOptions = [], bool $persistent = false): FrontendInterface + public function create(string $cacheIdentifier, string $cacheObjectName, string $backendObjectName, array $backendOptions = [], bool $persistent = false): LowLevelFrontendInterface { $backend = $this->instantiateBackend($backendObjectName, $backendOptions, $this->environmentConfiguration, $persistent); $cache = $this->instantiateCache($cacheIdentifier, $cacheObjectName, $backend); @@ -116,7 +116,7 @@ public function create(string $cacheIdentifier, string $cacheObjectName, string /** * {@inheritdoc} */ - protected function instantiateCache(string $cacheIdentifier, string $cacheObjectName, BackendInterface $backend): FrontendInterface + protected function instantiateCache(string $cacheIdentifier, string $cacheObjectName, BackendInterface $backend): LowLevelFrontendInterface { $cache = parent::instantiateCache($cacheIdentifier, $cacheObjectName, $backend); diff --git a/Neos.Flow/Classes/Cache/CacheManager.php b/Neos.Flow/Classes/Cache/CacheManager.php index 1ca19ca382..d860491cee 100644 --- a/Neos.Flow/Classes/Cache/CacheManager.php +++ b/Neos.Flow/Classes/Cache/CacheManager.php @@ -15,7 +15,7 @@ use Neos\Cache\Backend\FileBackend; use Neos\Cache\Exception\DuplicateIdentifierException; use Neos\Cache\Exception\NoSuchCacheException; -use Neos\Cache\Frontend\FrontendInterface; +use Neos\Cache\Frontend\LowLevelFrontendInterface; use Neos\Cache\Frontend\VariableFrontend; use Neos\Flow\Configuration\ConfigurationManager; use Neos\Flow\Log\Utility\LogEnvironment; @@ -57,7 +57,7 @@ class CacheManager protected $environment; /** - * @var FrontendInterface[] + * @var LowLevelFrontendInterface[] */ protected $caches = []; @@ -156,13 +156,13 @@ public function setCacheConfigurations(array $cacheConfigurations): void /** * Registers a cache so it can be retrieved at a later point. * - * @param FrontendInterface $cache The cache frontend to be registered + * @param LowLevelFrontendInterface $cache The cache frontend to be registered * @param bool $persistent * @return void * @throws DuplicateIdentifierException if a cache with the given identifier has already been registered. * @api */ - public function registerCache(FrontendInterface $cache, bool $persistent = false): void + public function registerCache(LowLevelFrontendInterface $cache, bool $persistent = false): void { $identifier = $cache->getIdentifier(); if (isset($this->caches[$identifier])) { @@ -178,11 +178,12 @@ public function registerCache(FrontendInterface $cache, bool $persistent = false * Returns the cache specified by $identifier * * @param string $identifier Identifies which cache to return - * @return FrontendInterface The specified cache frontend + * @param class-string|null $className The expected CacheManager for the cache frontend + * @return LowLevelFrontendInterface The specified cache frontend * @throws NoSuchCacheException * @api */ - public function getCache(string $identifier): FrontendInterface + public function getCache(string $identifier): LowLevelFrontendInterface { if ($this->hasCache($identifier) === false) { throw new NoSuchCacheException('A cache with identifier "' . $identifier . '" does not exist.', 1203699034); @@ -199,6 +200,7 @@ public function getCache(string $identifier): FrontendInterface * * @param string $identifier * @return CacheInterface + * @deprecated will be removed with Neos Flow 10. Use Caches.yaml with \Neos\Cache\Frontend\Psr\SimpleCache\SimpleCacheFrontend. */ public function getSimpleCache(string $identifier): CacheInterface { @@ -217,6 +219,7 @@ public function getSimpleCache(string $identifier): CacheInterface * * @param string $identifier * @return CacheItemPoolInterface + * @deprecated will be removed with Neos Flow 10. Use Caches.yaml with \Neos\Cache\Frontend\Psr\CachePool\CachePoolFrontend. */ public function getCacheItemPool(string $identifier): CacheItemPoolInterface { @@ -263,7 +266,7 @@ public function isCachePersistent(string $identifier): bool public function flushCaches(bool $flushPersistentCaches = false): void { $this->createAllCaches(); - /** @var FrontendInterface $cache */ + /** @var LowLevelFrontendInterface $cache */ foreach ($this->caches as $identifier => $cache) { if (!$flushPersistentCaches && $this->isCachePersistent($identifier)) { continue; @@ -287,7 +290,7 @@ public function flushCaches(bool $flushPersistentCaches = false): void public function flushCachesByTag(string $tag, bool $flushPersistentCaches = false): void { $this->createAllCaches(); - /** @var FrontendInterface $cache */ + /** @var LowLevelFrontendInterface $cache */ foreach ($this->caches as $identifier => $cache) { if (!$flushPersistentCaches && $this->isCachePersistent($identifier)) { continue; diff --git a/Neos.Flow/Classes/Cache/NonMatchingCacheClassException.php b/Neos.Flow/Classes/Cache/NonMatchingCacheClassException.php new file mode 100644 index 0000000000..3113032d60 --- /dev/null +++ b/Neos.Flow/Classes/Cache/NonMatchingCacheClassException.php @@ -0,0 +1,11 @@ +cache = $cache; } diff --git a/Neos.Flow/Classes/Session/Session.php b/Neos.Flow/Classes/Session/Session.php index 382912b62f..01d5a41ee1 100644 --- a/Neos.Flow/Classes/Session/Session.php +++ b/Neos.Flow/Classes/Session/Session.php @@ -24,7 +24,7 @@ use Neos\Flow\Utility\Algorithms; use Neos\Flow\Http\Cookie; use Neos\Flow\Security\Authentication\TokenInterface; -use Neos\Cache\Frontend\FrontendInterface; +use Neos\Cache\Frontend\LowLevelFrontendInterface; use Psr\Log\LoggerInterface; /** @@ -513,7 +513,7 @@ public function addTag($tag) throw new Exception\SessionNotStartedException('Tried to tag a session which has not been started yet.', 1355143533); } if (!$this->metaDataCache->isValidTag($tag)) { - throw new \InvalidArgumentException(sprintf('The tag used for tagging session %s contained invalid characters. Make sure it matches this regular expression: "%s"', $this->sessionIdentifier, FrontendInterface::PATTERN_TAG)); + throw new \InvalidArgumentException(sprintf('The tag used for tagging session %s contained invalid characters. Make sure it matches this regular expression: "%s"', $this->sessionIdentifier, LowLevelFrontendInterface::PATTERN_TAG)); } if (!in_array($tag, $this->tags)) { $this->tags[] = $tag; diff --git a/Neos.Flow/Documentation/TheDefinitiveGuide/PartIII/Caching.rst b/Neos.Flow/Documentation/TheDefinitiveGuide/PartIII/Caching.rst index f19665561a..3316191d5b 100644 --- a/Neos.Flow/Documentation/TheDefinitiveGuide/PartIII/Caching.rst +++ b/Neos.Flow/Documentation/TheDefinitiveGuide/PartIII/Caching.rst @@ -293,22 +293,27 @@ which can be stored using a specific frontend. The PHP frontend can only be used to cache PHP files, it does not work with strings, arrays or objects. -PSR Cache Interfaces -==================== -The implementations of the PSR Cache Interfaces allow to provide caches for external +PSR Cache Frontends +=================== + +The implementations of the PSR Cache Interfaces as cache frontends allows to provide caches for external libraries that do not know the flow cache interfaces. -PSR-6 Caching Interface ------------------------ +PSR-6 Cache Interface +--------------------- + +``Neos\Cache\Frontend\Psr\Cache\CacheItemPoolFrontend`` -The classes ``\Neos\Cache\Psr\Cache\CachePool`` and ``\Neos\Cache\Psr\Cache\CacheItem`` +The classes ``\Neos\Cache\Frontend\Psr\Cache\CacheItemPoolFrontend`` and ``\Neos\Cache\Frontend\Psr\Cache\CacheItem`` implement the Caching Interface as specified in https://www.php-fig.org/psr/psr-6/ PSR-16 Simple Cache Interface ----------------------------- -The class ``\Neos\Cache\Psr\SimpleCache\SimpleCache`` implements the SimpleCacheInterface +``Neos\Cache\Frontend\Psr\SimpleCache\SimpleCacheFrontend`` + +The class ``\Neos\Cache\Frontend\Psr\SimpleCache\SimpleCacheFrontend`` implements the SimpleCacheInterface that is specified in https://www.php-fig.org/psr/psr-16/ Cache Backends diff --git a/Neos.Flow/Tests/Unit/Cache/CacheManagerTest.php b/Neos.Flow/Tests/Unit/Cache/CacheManagerTest.php index 232e8e577a..e7f32950f7 100644 --- a/Neos.Flow/Tests/Unit/Cache/CacheManagerTest.php +++ b/Neos.Flow/Tests/Unit/Cache/CacheManagerTest.php @@ -83,10 +83,10 @@ protected function registerCache($cacheIdentifier) public function managerThrowsExceptionOnCacheRegistrationWithAlreadyExistingIdentifier() { $this->expectException(Cache\Exception\DuplicateIdentifierException::class); - $cache1 = $this->getMockBuilder(Cache\Frontend\AbstractFrontend::class)->disableOriginalConstructor()->getMock(); + $cache1 = $this->getMockBuilder(Cache\Frontend\AbstractLowLevelFrontend::class)->disableOriginalConstructor()->getMock(); $cache1->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('test')); - $cache2 = $this->getMockBuilder(Cache\Frontend\AbstractFrontend::class)->disableOriginalConstructor()->getMock(); + $cache2 = $this->getMockBuilder(Cache\Frontend\AbstractLowLevelFrontend::class)->disableOriginalConstructor()->getMock(); $cache2->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('test')); $this->cacheManager->registerCache($cache1); @@ -98,10 +98,10 @@ public function managerThrowsExceptionOnCacheRegistrationWithAlreadyExistingIden */ public function managerReturnsThePreviouslyRegisteredCached() { - $cache1 = $this->getMockBuilder(Cache\Frontend\AbstractFrontend::class)->disableOriginalConstructor()->getMock(); + $cache1 = $this->getMockBuilder(Cache\Frontend\AbstractLowLevelFrontend::class)->disableOriginalConstructor()->getMock(); $cache1->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('cache1')); - $cache2 = $this->getMockBuilder(Cache\Frontend\AbstractFrontend::class)->disableOriginalConstructor()->getMock(); + $cache2 = $this->getMockBuilder(Cache\Frontend\AbstractLowLevelFrontend::class)->disableOriginalConstructor()->getMock(); $cache2->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('cache2')); $this->cacheManager->registerCache($cache1); @@ -122,7 +122,7 @@ public function managerReturnsThePreviouslyRegisteredCached() public function getCacheThrowsExceptionForNonExistingIdentifier() { $this->expectException(Cache\Exception\NoSuchCacheException::class); - $cache = $this->getMockBuilder(Cache\Frontend\AbstractFrontend::class)->disableOriginalConstructor()->getMock(); + $cache = $this->getMockBuilder(Cache\Frontend\AbstractLowLevelFrontend::class)->disableOriginalConstructor()->getMock(); $cache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('someidentifier')); $this->cacheManager->registerCache($cache); @@ -137,7 +137,7 @@ public function getCacheThrowsExceptionForNonExistingIdentifier() public function getCacheItemPoolThrowsExceptionForNonExistingIdentifier() { $this->expectException(Cache\Exception\NoSuchCacheException::class); - $cache = $this->getMockBuilder(Cache\Frontend\AbstractFrontend::class)->disableOriginalConstructor()->getMock(); + $cache = $this->getMockBuilder(Cache\Frontend\AbstractLowLevelFrontend::class)->disableOriginalConstructor()->getMock(); $cache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('someidentifier')); $this->cacheManager->registerCache($cache); @@ -152,7 +152,7 @@ public function getCacheItemPoolThrowsExceptionForNonExistingIdentifier() public function getSimpleCacheThrowsExceptionForNonExistingIdentifier() { $this->expectException(Cache\Exception\NoSuchCacheException::class); - $cache = $this->getMockBuilder(Cache\Frontend\AbstractFrontend::class)->disableOriginalConstructor()->getMock(); + $cache = $this->getMockBuilder(Cache\Frontend\AbstractLowLevelFrontend::class)->disableOriginalConstructor()->getMock(); $cache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('someidentifier')); $this->cacheManager->registerCache($cache); @@ -166,7 +166,7 @@ public function getSimpleCacheThrowsExceptionForNonExistingIdentifier() */ public function hasCacheReturnsCorrectResult() { - $cache1 = $this->getMockBuilder(Cache\Frontend\AbstractFrontend::class)->disableOriginalConstructor()->getMock(); + $cache1 = $this->getMockBuilder(Cache\Frontend\AbstractLowLevelFrontend::class)->disableOriginalConstructor()->getMock(); $cache1->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('cache1')); $this->cacheManager->registerCache($cache1); @@ -179,11 +179,11 @@ public function hasCacheReturnsCorrectResult() */ public function isCachePersistentReturnsCorrectResult() { - $cache1 = $this->getMockBuilder(Cache\Frontend\AbstractFrontend::class)->disableOriginalConstructor()->getMock(); + $cache1 = $this->getMockBuilder(Cache\Frontend\AbstractLowLevelFrontend::class)->disableOriginalConstructor()->getMock(); $cache1->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('cache1')); $this->cacheManager->registerCache($cache1); - $cache2 = $this->getMockBuilder(Cache\Frontend\AbstractFrontend::class)->disableOriginalConstructor()->getMock(); + $cache2 = $this->getMockBuilder(Cache\Frontend\AbstractLowLevelFrontend::class)->disableOriginalConstructor()->getMock(); $cache2->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('cache2')); $this->cacheManager->registerCache($cache2, true); @@ -196,17 +196,17 @@ public function isCachePersistentReturnsCorrectResult() */ public function flushCachesByTagCallsTheFlushByTagMethodOfAllRegisteredCaches() { - $cache1 = $this->getMockBuilder(Cache\Frontend\AbstractFrontend::class)->disableOriginalConstructor()->getMock(); + $cache1 = $this->getMockBuilder(Cache\Frontend\AbstractLowLevelFrontend::class)->disableOriginalConstructor()->getMock(); $cache1->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('cache1')); $cache1->expects(self::once())->method('flushByTag')->with(self::equalTo('theTag')); $this->cacheManager->registerCache($cache1); - $cache2 = $this->getMockBuilder(Cache\Frontend\AbstractFrontend::class)->disableOriginalConstructor()->getMock(); + $cache2 = $this->getMockBuilder(Cache\Frontend\AbstractLowLevelFrontend::class)->disableOriginalConstructor()->getMock(); $cache2->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('cache2')); $cache2->expects(self::once())->method('flushByTag')->with(self::equalTo('theTag')); $this->cacheManager->registerCache($cache2); - $persistentCache = $this->getMockBuilder(Cache\Frontend\AbstractFrontend::class)->disableOriginalConstructor()->getMock(); + $persistentCache = $this->getMockBuilder(Cache\Frontend\AbstractLowLevelFrontend::class)->disableOriginalConstructor()->getMock(); $persistentCache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('persistentCache')); $persistentCache->expects(self::never())->method('flushByTag')->with(self::equalTo('theTag')); $this->cacheManager->registerCache($persistentCache, true); @@ -219,17 +219,17 @@ public function flushCachesByTagCallsTheFlushByTagMethodOfAllRegisteredCaches() */ public function flushCachesCallsTheFlushMethodOfAllRegisteredCaches() { - $cache1 = $this->getMockBuilder(Cache\Frontend\AbstractFrontend::class)->disableOriginalConstructor()->getMock(); + $cache1 = $this->getMockBuilder(Cache\Frontend\AbstractLowLevelFrontend::class)->disableOriginalConstructor()->getMock(); $cache1->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('cache1')); $cache1->expects(self::once())->method('flush'); $this->cacheManager->registerCache($cache1); - $cache2 = $this->getMockBuilder(Cache\Frontend\AbstractFrontend::class)->disableOriginalConstructor()->getMock(); + $cache2 = $this->getMockBuilder(Cache\Frontend\AbstractLowLevelFrontend::class)->disableOriginalConstructor()->getMock(); $cache2->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('cache2')); $cache2->expects(self::once())->method('flush'); $this->cacheManager->registerCache($cache2); - $persistentCache = $this->getMockBuilder(Cache\Frontend\AbstractFrontend::class)->disableOriginalConstructor()->getMock(); + $persistentCache = $this->getMockBuilder(Cache\Frontend\AbstractLowLevelFrontend::class)->disableOriginalConstructor()->getMock(); $persistentCache->expects(self::atLeastOnce())->method('getIdentifier')->will(self::returnValue('persistentCache')); $persistentCache->expects(self::never())->method('flush'); $this->cacheManager->registerCache($persistentCache, true); diff --git a/Neos.Flow/Tests/Unit/Security/Cryptography/HashServiceTest.php b/Neos.Flow/Tests/Unit/Security/Cryptography/HashServiceTest.php index 218f015c66..fcbc4be5db 100644 --- a/Neos.Flow/Tests/Unit/Security/Cryptography/HashServiceTest.php +++ b/Neos.Flow/Tests/Unit/Security/Cryptography/HashServiceTest.php @@ -64,8 +64,9 @@ class HashServiceTest extends UnitTestCase */ protected function setUp(): void { - $this->cache = new StringFrontend('TestCache', new TransientMemoryBackend(new EnvironmentConfiguration('Hash Testing', '/some/path', PHP_MAXPATHLEN))); - $this->cache->initializeObject(); + $cacheBackend = new TransientMemoryBackend(new EnvironmentConfiguration('Hash Testing', '/some/path', PHP_MAXPATHLEN)); + $this->cache = new StringFrontend('TestCache', $cacheBackend); + $cacheBackend->setCache($this->cache); $this->mockObjectManager = $this->getMockBuilder(ObjectManagerInterface::class)->getMock();