Skip to content

Commit

Permalink
Enabled testing of APCU for all PHP versions.
Browse files Browse the repository at this point in the history
In order to accomplish successful passing of tests in all supported PHP versions:
- Removed a few instances of erroneous doesNotPerformAssertions annotations.
- Changed the detection from "apc" to "apcu".
- Added protection for classes unserialization in TwoLevels cache and made it remove the ID from both caches if it was corrupted at rest.
- Made the TwoLevel cache attempt to add to fast cache after removing the existing fast cache entry.
  • Loading branch information
boenrobot committed Aug 11, 2023
1 parent de90587 commit 354070c
Show file tree
Hide file tree
Showing 9 changed files with 47 additions and 72 deletions.
12 changes: 7 additions & 5 deletions .github/workflows/phpunit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ jobs:
TESTS_ZEND_CACHE_LIBMEMCACHED_HOST: 127.0.0.1
TESTS_ZEND_CACHE_LIBMEMCACHED_PORT: 11211

TESTS_ZEND_CACHE_APC_ENABLED: true

# https://hub.docker.com/r/bitnami/openldap
LDAP_ROOT: "dc=example,dc=com"
LDAP_ALLOW_ANON_BINDING: false
Expand Down Expand Up @@ -112,15 +114,15 @@ jobs:
#bare for PHP >=7.2
- php-extensions-bare: "none, iconv, json, libxml, xml, dom, simplexml, xmlwriter, tokenizer, mbstring"
#full for PHP <= 8.0
- php-extensions-full: "none, iconv, json, libxml, xml, dom, simplexml, xmlwriter, tokenizer, mbstring, ctype, openssl, curl, gd, posix, pdo_sqlite, pdo_mysql, fileinfo, zip, sqlite, soap, bcmath, igbinary, bz2, lzf, memcached, memcache, ldap, sqlite, mcrypt, rar"
- php-extensions-full: "none, iconv, json, libxml, xml, dom, simplexml, xmlwriter, tokenizer, mbstring, apcu, ctype, openssl, curl, gd, posix, pdo_sqlite, pdo_mysql, fileinfo, zip, sqlite, soap, bcmath, igbinary, bz2, lzf, memcached, memcache, ldap, sqlite, mcrypt, rar"
- php-version: "7.1"
php-extensions-bare: "none, iconv, json, libxml, xml, dom, simplexml, xmlwriter, tokenizer"
- php-version: "8.1"
php-extensions-full: "none, iconv, json, libxml, xml, dom, simplexml, xmlwriter, tokenizer, mbstring, ctype, openssl, curl, gd, posix, pdo_sqlite, pdo_mysql, fileinfo, zip, sqlite, soap, bcmath, igbinary, bz2, lzf, memcached, memcache, ldap, sqlite, mcrypt"
php-extensions-full: "none, iconv, json, libxml, xml, dom, simplexml, xmlwriter, tokenizer, mbstring, apcu, ctype, openssl, curl, gd, posix, pdo_sqlite, pdo_mysql, fileinfo, zip, sqlite, soap, bcmath, igbinary, bz2, lzf, memcached, memcache, ldap, sqlite, mcrypt"
- php-version: "8.2"
php-extensions-full: "none, iconv, json, libxml, xml, dom, simplexml, xmlwriter, tokenizer, mbstring, ctype, openssl, curl, gd, posix, pdo_sqlite, pdo_mysql, fileinfo, zip, sqlite, soap, bcmath, igbinary, bz2, lzf, memcached, memcache, ldap, sqlite, mcrypt"
php-extensions-full: "none, iconv, json, libxml, xml, dom, simplexml, xmlwriter, tokenizer, mbstring, apcu, ctype, openssl, curl, gd, posix, pdo_sqlite, pdo_mysql, fileinfo, zip, sqlite, soap, bcmath, igbinary, bz2, lzf, memcached, memcache, ldap, sqlite, mcrypt"
- php-version: "8.3"
php-extensions-full: "none, iconv, json, libxml, xml, dom, simplexml, xmlwriter, tokenizer, mbstring, ctype, openssl, curl, gd, posix, pdo_sqlite, pdo_mysql, fileinfo, zip, sqlite, soap, bcmath, igbinary, bz2, lzf, memcached, memcache, ldap, sqlite"
php-extensions-full: "none, iconv, json, libxml, xml, dom, simplexml, xmlwriter, tokenizer, mbstring, apcu, ctype, openssl, curl, gd, posix, pdo_sqlite, pdo_mysql, fileinfo, zip, sqlite, soap, bcmath, igbinary, bz2, lzf, memcached, memcache, ldap, sqlite"
experimental: true

steps:
Expand Down Expand Up @@ -181,7 +183,7 @@ jobs:
php-version: ${{ matrix.php-version }}
tools: cs2pr
extensions: ${{ matrix.php-extensions-full }}
ini-values: ${{ env.PHP_INI_VALUES }}
ini-values: ${{ env.PHP_INI_VALUES }}, apc.enable_cli=1
env:
# https://github.com/shivammathur/setup-php/issues/407#issuecomment-773675741
fail-fast: true
Expand Down
5 changes: 3 additions & 2 deletions library/Zend/Cache/Backend/Apc.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,9 @@ public function load($id, $doNotTestCacheValidity = false)
{
$tmp = apcu_fetch($id);
if (is_array($tmp)) {
return $tmp[0];
return $tmp[0] ?? false;
}
apcu_delete($id);
return false;
}

Expand All @@ -89,7 +90,7 @@ public function test($id)
{
$tmp = apcu_fetch($id);
if (is_array($tmp)) {
return $tmp[1];
return $tmp[1] ?? false;
}
return false;
}
Expand Down
40 changes: 30 additions & 10 deletions library/Zend/Cache/Backend/TwoLevels.php
Original file line number Diff line number Diff line change
Expand Up @@ -199,18 +199,22 @@ public function save($data, $id, $tags = [], $specificLifetime = false, $priorit
$boolFast = true;
$lifetime = $this->getLifetime($specificLifetime);
$preparedData = $this->_prepareData($data, $lifetime, $priority);
$fastLifetime = $this->_getFastLifetime($lifetime, $priority);
if (($priority > 0) && (10 * $priority >= $usage)) {
$fastLifetime = $this->_getFastLifetime($lifetime, $priority);
$boolFast = $this->_fastBackend->save($preparedData, $id, [], $fastLifetime);
$boolSlow = $this->_slowBackend->save($preparedData, $id, $tags, $lifetime);
} else {
$boolSlow = $this->_slowBackend->save($preparedData, $id, $tags, $lifetime);
if ($boolSlow === true) {
$boolFast = $this->_fastBackend->remove($id);
if (!$boolFast && !$this->_fastBackend->test($id)) {
// some backends return false on remove() even if the key never existed. (and it won't if fast is full)
// all we care about is that the key doesn't exist now
$boolFast = true;
// some backends return false on remove() even if the key never existed. (and it won't if fast is full)
// all we care about is that the key doesn't exist now
$boolFast = !$boolFast && !$this->_fastBackend->test($id);
// If removal was successful, attempt to add to fast again.
// We do not care if we succeed, because failure means fast cache is empty,
// while the slow one is filled, which is OK.
if ($boolFast) {
$this->_fastBackend->save($preparedData, $id, [], $fastLifetime);
}
}
}
Expand All @@ -230,17 +234,33 @@ public function save($data, $id, $tags = [], $specificLifetime = false, $priorit
public function load($id, $doNotTestCacheValidity = false)
{
$resultFast = $this->_fastBackend->load($id, $doNotTestCacheValidity);
if ($resultFast === false) {
$array = null;
$isFastResult = is_string($resultFast);
if ($isFastResult) {
$array = unserialize($resultFast, ['allowed_classes' => false]);
}
if (!is_array($array)) {
if ($isFastResult) {
// If the fast result data is not an array, it means it got corrupted somehow at rest.
// Remove it before trying the slow one.
$this->_fastBackend->remove($id);
}
$resultSlow = $this->_slowBackend->load($id, $doNotTestCacheValidity);
if ($resultSlow === false) {
if (!is_string($resultSlow)) {
// there is no cache at all for this id
return false;
}
$array = unserialize($resultSlow, ['allowed_classes' => false]);
if (!is_array($array)) {
// If the slow result data is not an array, it means it got corrupted somehow at rest.
// Remove it and return false.
$this->_slowBackend->remove($id);
return false;
}
}
$array = $resultFast !== false ? unserialize($resultFast) : unserialize($resultSlow);

//In case no cache entry was found in the FastCache and auto-filling is enabled, copy data to FastCache
if ($resultFast === false && $this->_options['auto_fill_fast_cache']) {
if (!$isFastResult && $this->_options['auto_fill_fast_cache']) {
$preparedData = $this->_prepareData($array['data'], $array['lifetime'], $array['priority']);
$this->_fastBackend->save($preparedData, $id, [], $array['lifetime']);
}
Expand Down Expand Up @@ -461,7 +481,7 @@ public function getCapabilities()
}

/**
* Prepare a serialized array to store datas and metadatas informations
* Prepare a serialized array to store data and metadata information
*
* @param string $data data to store
* @param int $lifetime original lifetime
Expand Down
8 changes: 4 additions & 4 deletions tests/Zend/Cache/AllTests.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,9 @@ public static function suite()
$skipTest = new Zend_Cache_ApcBackendTest_SkipTests();
$skipTest->message = 'Tests are not enabled in TestConfiguration.php';
$suite->addTest($skipTest);
} elseif (!extension_loaded('apc')) {
} elseif (!extension_loaded('apcu')) {
$skipTest = new Zend_Cache_ApcBackendTest_SkipTests();
$skipTest->message = "Extension 'APC' is not loaded";
$skipTest->message = "Extension 'apcu' is not loaded";
$suite->addTest($skipTest);
} else {
$suite->addTestSuite('Zend_Cache_ApcBackendTest');
Expand Down Expand Up @@ -218,9 +218,9 @@ public static function suite()
$skipTest = new Zend_Cache_TwoLevelsBackendTest_SkipTests();
$skipTest->message = 'Tests are not enabled in TestConfiguration.php';
$suite->addTest($skipTest);
} elseif (!extension_loaded('apc')) {
} elseif (!extension_loaded('apcu')) {
$skipTest = new Zend_Cache_TwoLevelsBackendTest_SkipTests();
$skipTest->message = "Extension 'APC' is not loaded";
$skipTest->message = "Extension 'apcu' is not loaded";
$suite->addTest($skipTest);
} else {
$suite->addTestSuite('Zend_Cache_TwoLevelsBackendTest');
Expand Down
12 changes: 0 additions & 12 deletions tests/Zend/Cache/ApcBackendTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -175,39 +175,27 @@ public function testGetTags()
{
}

/**
* @doesNotPerformAssertions
*/
public function testSaveCorrectCall()
{
$this->_instance->setDirectives(['logging' => false]);
parent::testSaveCorrectCall();
$this->_instance->setDirectives(['logging' => true]);
}

/**
* @doesNotPerformAssertions
*/
public function testSaveWithNullLifeTime()
{
$this->_instance->setDirectives(['logging' => false]);
parent::testSaveWithNullLifeTime();
$this->_instance->setDirectives(['logging' => true]);
}

/**
* @doesNotPerformAssertions
*/
public function testSaveWithSpecificLifeTime()
{
$this->_instance->setDirectives(['logging' => false]);
parent::testSaveWithSpecificLifeTime();
$this->_instance->setDirectives(['logging' => true]);
}

/**
* @doesNotPerformAssertions
*/
public function testGetMetadatas($notag = true)
{
parent::testGetMetadatas($notag);
Expand Down
12 changes: 0 additions & 12 deletions tests/Zend/Cache/WinCacheBackendTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -198,39 +198,27 @@ public function testGetTags()
$this->markTestSkipped('This test skipped due to limitations in this adapter.');
}

/**
* @doesNotPerformAssertions
*/
public function testSaveCorrectCall()
{
$this->_instance->setDirectives(['logging' => false]);
parent::testSaveCorrectCall();
$this->_instance->setDirectives(['logging' => true]);
}

/**
* @doesNotPerformAssertions
*/
public function testSaveWithNullLifeTime()
{
$this->_instance->setDirectives(['logging' => false]);
parent::testSaveWithNullLifeTime();
$this->_instance->setDirectives(['logging' => true]);
}

/**
* @doesNotPerformAssertions
*/
public function testSaveWithSpecificLifeTime()
{
$this->_instance->setDirectives(['logging' => false]);
parent::testSaveWithSpecificLifeTime();
$this->_instance->setDirectives(['logging' => true]);
}

/**
* @doesNotPerformAssertions
*/
public function testGetMetadatas($notag = true)
{
parent::testGetMetadatas($notag);
Expand Down
10 changes: 1 addition & 9 deletions tests/Zend/Cache/XcacheBackendTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,29 +129,21 @@ public function testCleanModeNotMatchingTags2()
public function testCleanModeNotMatchingTags3()
{
}
/**
* @doesNotPerformAssertions
*/

public function testSaveCorrectCall()
{
$this->_instance->setDirectives(['logging' => false]);
parent::testSaveCorrectCall();
$this->_instance->setDirectives(['logging' => true]);
}

/**
* @doesNotPerformAssertions
*/
public function testSaveWithNullLifeTime()
{
$this->_instance->setDirectives(['logging' => false]);
parent::testSaveWithNullLifeTime();
$this->_instance->setDirectives(['logging' => true]);
}

/**
* @doesNotPerformAssertions
*/
public function testSaveWithSpecificLifeTime()
{
$this->_instance->setDirectives(['logging' => false]);
Expand Down
10 changes: 1 addition & 9 deletions tests/Zend/Cache/ZendServerDiskTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,29 +126,21 @@ public function testCleanModeNotMatchingTags2()
public function testCleanModeNotMatchingTags3()
{
}
/**
* @doesNotPerformAssertions
*/

public function testSaveCorrectCall()
{
$this->_instance->setDirectives(['logging' => false]);
parent::testSaveCorrectCall();
$this->_instance->setDirectives(['logging' => true]);
}

/**
* @doesNotPerformAssertions
*/
public function testSaveWithNullLifeTime()
{
$this->_instance->setDirectives(['logging' => false]);
parent::testSaveWithNullLifeTime();
$this->_instance->setDirectives(['logging' => true]);
}

/**
* @doesNotPerformAssertions
*/
public function testSaveWithSpecificLifeTime()
{
$this->_instance->setDirectives(['logging' => false]);
Expand Down
10 changes: 1 addition & 9 deletions tests/Zend/Cache/ZendServerShMemTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,29 +126,21 @@ public function testCleanModeNotMatchingTags2()
public function testCleanModeNotMatchingTags3()
{
}
/**
* @doesNotPerformAssertions
*/

public function testSaveCorrectCall()
{
$this->_instance->setDirectives(['logging' => false]);
parent::testSaveCorrectCall();
$this->_instance->setDirectives(['logging' => true]);
}

/**
* @doesNotPerformAssertions
*/
public function testSaveWithNullLifeTime()
{
$this->_instance->setDirectives(['logging' => false]);
parent::testSaveWithNullLifeTime();
$this->_instance->setDirectives(['logging' => true]);
}

/**
* @doesNotPerformAssertions
*/
public function testSaveWithSpecificLifeTime()
{
$this->_instance->setDirectives(['logging' => false]);
Expand Down

0 comments on commit 354070c

Please sign in to comment.