diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 9d2e2beb65..c2c56479d0 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -11,16 +11,16 @@ jobs: env: PHP_INI_VALUES: memory_limit=-1, assert.exception=1, zend.assertions=1, error_reporting=-1, log_errors_max_len=0, display_errors=On - TESTS_ZEND_DB_ADAPTER_PDO_MYSQL_ENABLED: true - TESTS_ZEND_DB_ADAPTER_MYSQL_USERNAME: github - TESTS_ZEND_DB_ADAPTER_MYSQL_PASSWORD: github - TESTS_ZEND_DB_ADAPTER_MYSQL_DATABASE: zftest - TESTS_ZEND_DB_ADAPTER_MYSQL_HOSTNAME: 127.0.0.1 - - TESTS_ZEND_DB_ADAPTER_PDO_PGSQL_ENABLED: true - TESTS_ZEND_DB_ADAPTER_PDO_PGSQL_USERNAME: github - TESTS_ZEND_DB_ADAPTER_PDO_PGSQL_PASSWORD: github - TESTS_ZEND_DB_ADAPTER_PDO_PGSQL_DATABASE: zftest +# TESTS_ZEND_DB_ADAPTER_PDO_MYSQL_ENABLED: true +# TESTS_ZEND_DB_ADAPTER_MYSQL_USERNAME: github +# TESTS_ZEND_DB_ADAPTER_MYSQL_PASSWORD: github +# TESTS_ZEND_DB_ADAPTER_MYSQL_DATABASE: zftest +# TESTS_ZEND_DB_ADAPTER_MYSQL_HOSTNAME: 127.0.0.1 +# +# TESTS_ZEND_DB_ADAPTER_PDO_PGSQL_ENABLED: true +# TESTS_ZEND_DB_ADAPTER_PDO_PGSQL_USERNAME: github +# TESTS_ZEND_DB_ADAPTER_PDO_PGSQL_PASSWORD: github +# TESTS_ZEND_DB_ADAPTER_PDO_PGSQL_DATABASE: zftest TESTS_ZEND_CACHE_SQLITE_ENABLED: true TESTS_ZEND_DB_ADAPTER_PDO_SQLITE_ENABLED: true @@ -35,16 +35,16 @@ jobs: TESTS_ZEND_CACHE_APC_ENABLED: true - # https://hub.docker.com/r/bitnami/openldap - LDAP_ROOT: "dc=example,dc=com" - LDAP_ALLOW_ANON_BINDING: false - LDAP_SKIP_DEFAULT_TREE: "yes" - LDAP_ADMIN_USERNAME: "admin" - LDAP_ADMIN_PASSWORD: "insecure" - LDAP_CONFIG_ADMIN_USERNAME: "admin" - LDAP_CONFIG_ADMIN_PASSWORD: "configpassword" - TESTS_ZEND_LDAP_ONLINE_ENABLED: true - TESTS_ZEND_AUTH_ADAPTER_LDAP_ONLINE_ENABLED: true +# # https://hub.docker.com/r/bitnami/openldap +# LDAP_ROOT: "dc=example,dc=com" +# LDAP_ALLOW_ANON_BINDING: false +# LDAP_SKIP_DEFAULT_TREE: "yes" +# LDAP_ADMIN_USERNAME: "admin" +# LDAP_ADMIN_PASSWORD: "insecure" +# LDAP_CONFIG_ADMIN_USERNAME: "admin" +# LDAP_CONFIG_ADMIN_PASSWORD: "configpassword" +# TESTS_ZEND_LDAP_ONLINE_ENABLED: true +# TESTS_ZEND_AUTH_ADAPTER_LDAP_ONLINE_ENABLED: true LOCALES: "fr_FR@euro fr_FR fr_BE.UTF-8 de en_US" OPENSSL_CONF: "./tests/openssl.conf" @@ -54,48 +54,48 @@ jobs: ports: - 11211:11211 - mysql: - image: bitnami/mysql:8.0.31 - env: - MYSQL_ROOT_USER: ${{ env.TESTS_ZEND_DB_ADAPTER_MYSQL_USERNAME }} - MYSQL_ROOT_PASSWORD: ${{ env.TESTS_ZEND_DB_ADAPTER_MYSQL_PASSWORD }} - MYSQL_DATABASE: ${{ env.TESTS_ZEND_DB_ADAPTER_MYSQL_DATABASE }} - MYSQL_AUTHENTICATION_PLUGIN: mysql_native_password - ports: - - 3306:3306 - options: >- - --health-cmd "mysqladmin ping" - --health-interval 10s - --health-timeout 5s - --health-retries 10 - - postgres: - image: postgres:15.1-alpine - ports: - - 5432:5432 - env: - POSTGRES_USER: ${{ env.TESTS_ZEND_DB_ADAPTER_PDO_PGSQL_USERNAME }} - POSTGRES_PASSWORD: ${{ env.TESTS_ZEND_DB_ADAPTER_PDO_PGSQL_PASSWORD }} - POSTGRES_DB: ${{ env.TESTS_ZEND_DB_ADAPTER_PDO_PGSQL_DATABASE }} - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - - openldap: - image: bitnami/openldap:2.5 - ports: - - 1389:1389 - env: - LDAP_ROOT: ${{ env.LDAP_ROOT }} - LDAP_ALLOW_ANON_BINDING: ${{ env.LDAP_ALLOW_ANON_BINDING }} - LDAP_SKIP_DEFAULT_TREE: ${{ env.LDAP_SKIP_DEFAULT_TREE }} - LDAP_ADMIN_USERNAME: ${{ env.LDAP_ADMIN_USERNAME }} - LDAP_ADMIN_PASSWORD: ${{ env.LDAP_ADMIN_PASSWORD }} - LDAP_CONFIG_ADMIN_ENABLED: "yes" - LDAP_CONFIG_ADMIN_USERNAME: ${{ env.LDAP_CONFIG_ADMIN_USERNAME }} - LDAP_CONFIG_ADMIN_PASSWORD: ${{ env.LDAP_CONFIG_ADMIN_PASSWORD }} +# mysql: +# image: bitnami/mysql:8.0.31 +# env: +# MYSQL_ROOT_USER: ${{ env.TESTS_ZEND_DB_ADAPTER_MYSQL_USERNAME }} +# MYSQL_ROOT_PASSWORD: ${{ env.TESTS_ZEND_DB_ADAPTER_MYSQL_PASSWORD }} +# MYSQL_DATABASE: ${{ env.TESTS_ZEND_DB_ADAPTER_MYSQL_DATABASE }} +# MYSQL_AUTHENTICATION_PLUGIN: mysql_native_password +# ports: +# - 3306:3306 +# options: >- +# --health-cmd "mysqladmin ping" +# --health-interval 10s +# --health-timeout 5s +# --health-retries 10 +# +# postgres: +# image: postgres:15.1-alpine +# ports: +# - 5432:5432 +# env: +# POSTGRES_USER: ${{ env.TESTS_ZEND_DB_ADAPTER_PDO_PGSQL_USERNAME }} +# POSTGRES_PASSWORD: ${{ env.TESTS_ZEND_DB_ADAPTER_PDO_PGSQL_PASSWORD }} +# POSTGRES_DB: ${{ env.TESTS_ZEND_DB_ADAPTER_PDO_PGSQL_DATABASE }} +# options: >- +# --health-cmd pg_isready +# --health-interval 10s +# --health-timeout 5s +# --health-retries 5 + +# openldap: +# image: bitnami/openldap:2.5 +# ports: +# - 1389:1389 +# env: +# LDAP_ROOT: ${{ env.LDAP_ROOT }} +# LDAP_ALLOW_ANON_BINDING: ${{ env.LDAP_ALLOW_ANON_BINDING }} +# LDAP_SKIP_DEFAULT_TREE: ${{ env.LDAP_SKIP_DEFAULT_TREE }} +# LDAP_ADMIN_USERNAME: ${{ env.LDAP_ADMIN_USERNAME }} +# LDAP_ADMIN_PASSWORD: ${{ env.LDAP_ADMIN_PASSWORD }} +# LDAP_CONFIG_ADMIN_ENABLED: "yes" +# LDAP_CONFIG_ADMIN_USERNAME: ${{ env.LDAP_CONFIG_ADMIN_USERNAME }} +# LDAP_CONFIG_ADMIN_PASSWORD: ${{ env.LDAP_CONFIG_ADMIN_PASSWORD }} strategy: fail-fast: false @@ -163,19 +163,19 @@ jobs: - name: Install dependencies run: composer install --prefer-dist --no-progress --no-suggest - - name: Lint PHP source files - run: | - bin/parallel-lint --exclude vendor --exclude tests/Zend/Loader/_files/ParseError.php . --checkstyle | cs2pr - - - name: "Run tests on PHP ${{ matrix.php-version }} (Experimental: ${{ matrix.experimental }}) with minimal extensions" - run: | - bin/phpunit -c tests/phpunit.xml - continue-on-error: ${{ matrix.experimental }} - - - name: Setup LDAP - run: | - sudo apt-get install -y libnss-ldap libpam-ldap ldap-utils - tests/resources/openldap/docker-entrypoint-initdb.d/init.sh +# - name: Lint PHP source files +# run: | +# bin/parallel-lint --exclude vendor --exclude tests/Zend/Loader/_files/ParseError.php . --checkstyle | cs2pr +# +# - name: "Run tests on PHP ${{ matrix.php-version }} (Experimental: ${{ matrix.experimental }}) with minimal extensions" +# run: | +# bin/phpunit -c tests/phpunit.xml +# continue-on-error: ${{ matrix.experimental }} + +# - name: Setup LDAP +# run: | +# sudo apt-get install -y libnss-ldap libpam-ldap ldap-utils +# tests/resources/openldap/docker-entrypoint-initdb.d/init.sh - name: Install PHP with extensions uses: shivammathur/setup-php@v2 diff --git a/library/Zend/Cache/Backend/File.php b/library/Zend/Cache/Backend/File.php index 38c8944ef2..551877c015 100644 --- a/library/Zend/Cache/Backend/File.php +++ b/library/Zend/Cache/Backend/File.php @@ -250,6 +250,7 @@ public function save($data, $id, $tags = [], $specificLifetime = false) $this->_recursiveMkdirAndChmod($id); } if (!is_writable($path)) { + $this->_log('Zend_Cache_Backend_File::save() : path ' . $path . ' is not writable'); return false; } } @@ -1011,14 +1012,20 @@ protected function _filePutContents($file, $string) $result = false; $f = @fopen($file, 'ab+'); if ($f) { - if ($this->_options['file_locking']) @flock($f, LOCK_EX); + if ($this->_options['file_locking']) { + @flock($f, LOCK_EX); + } fseek($f, 0); ftruncate($f, 0); $tmp = @fwrite($f, $string); if (!($tmp === FALSE)) { $result = true; + } else { + $this->_log("Zend_Cache_Backend_File::_filePutContents() : failed to write contents"); } @fclose($f); + } else { + $this->_log("Zend_Cache_Backend_File::_filePutContents() : we can't obtain handle"); } @chmod($file, $this->_options['cache_file_perm']); return $result; diff --git a/library/Zend/Cache/Backend/TwoLevels.php b/library/Zend/Cache/Backend/TwoLevels.php index 7f07388d81..422ca53f11 100644 --- a/library/Zend/Cache/Backend/TwoLevels.php +++ b/library/Zend/Cache/Backend/TwoLevels.php @@ -195,23 +195,31 @@ public function test($id) */ public function save($data, $id, $tags = [], $specificLifetime = false, $priority = 8) { + $this->_log('Calling two level save'); $usage = $this->_getFastFillingPercentage('saving'); $boolFast = true; $lifetime = $this->getLifetime($specificLifetime); $preparedData = $this->_prepareData($data, $lifetime, $priority); if (($priority > 0) && (10 * $priority >= $usage)) { + $this->_log('Saving in fast and slow cache'); $fastLifetime = $this->_getFastLifetime($lifetime, $priority); $boolFast = $this->_fastBackend->save($preparedData, $id, [], $fastLifetime); + $this->_log($boolFast ? 'Saving in fast and fast cache is OK' : 'Saving in fast cache is not OK'); $boolSlow = $this->_slowBackend->save($preparedData, $id, $tags, $lifetime); + $this->_log($boolSlow ? 'Saving in fast and slow cache is OK' : 'Saving in slow cache is not OK'); } else { + $this->_log('Saving in slow cache only'); $boolSlow = $this->_slowBackend->save($preparedData, $id, $tags, $lifetime); + $this->_log($boolSlow ? 'Saving in fast and slow cache is OK' : 'Saving in slow cache is not OK'); if ($boolSlow === true) { + $this->_log('Purging from fast cache on save'); $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; } + $this->_log($boolFast ? 'Successfully purged from fast cache on save' : 'Failed to purge from fast cache on save'); } } @@ -229,6 +237,7 @@ public function save($data, $id, $tags = [], $specificLifetime = false, $priorit */ public function load($id, $doNotTestCacheValidity = false) { + $this->_log('Calling two level load'); $resultFast = $this->_fastBackend->load($id, $doNotTestCacheValidity); $array = null; $isFastResult = is_string($resultFast); @@ -253,6 +262,7 @@ public function load($id, $doNotTestCacheValidity = false) $this->_slowBackend->remove($id); return false; } + $isFastResult = false; } //In case no cache entry was found in the FastCache and auto-filling is enabled, copy data to FastCache diff --git a/tests/Zend/Cache/FileBackendTest.php b/tests/Zend/Cache/FileBackendTest.php index 9a9b7d30f0..6162e6bc51 100644 --- a/tests/Zend/Cache/FileBackendTest.php +++ b/tests/Zend/Cache/FileBackendTest.php @@ -200,4 +200,25 @@ public function testShouldDeleteOldMetadataFiles() $this->assertTrue($this->_instance->clean(Zend_Cache::CLEANING_MODE_ALL)); $this->assertFalse(file_exists($fn)); } + + public function testSaveCorrectCall() + { + $this->_instance->setDirectives(['logging' => false]); + parent::testSaveCorrectCall(); + $this->_instance->setDirectives(['logging' => true]); + } + + public function testSaveWithNullLifeTime() + { + $this->_instance->setDirectives(['logging' => false]); + parent::testSaveWithNullLifeTime(); + $this->_instance->setDirectives(['logging' => true]); + } + + public function testSaveWithSpecificLifeTime() + { + $this->_instance->setDirectives(['logging' => false]); + parent::testSaveWithSpecificLifeTime(); + $this->_instance->setDirectives(['logging' => true]); + } } diff --git a/tests/Zend/Cache/TwoLevelsBackendTest.php b/tests/Zend/Cache/TwoLevelsBackendTest.php index 70cc1d30cd..c803fa5f12 100644 --- a/tests/Zend/Cache/TwoLevelsBackendTest.php +++ b/tests/Zend/Cache/TwoLevelsBackendTest.php @@ -107,22 +107,33 @@ public function testSaveOverwritesIfFastIsFull() ->method('getFillingPercentage') ->will($this->returnValue(90)); - $slowBackendOptions = [ - 'cache_dir' => $this->_cache_dir + 'cache_dir' => $this->_cache_dir, ]; + + $logStream = fopen('php://temp/maxmemory:4194304', 'a+b'); + $logger = new Zend_Log(new Zend_Log_Writer_Stream($logStream)); $cache = new Zend_Cache_Backend_TwoLevels([ 'fast_backend' => $fastBackend, 'slow_backend' => $slowBackend, 'slow_backend_options' => $slowBackendOptions, - 'stats_update_factor' => 1 + 'stats_update_factor' => 1, + 'directives' => ['logging' => true, 'logger' => $logger] ]); $id = 'test' . uniqid(); - $this->assertTrue($cache->save(10, $id)); //fast usage at 0% - - $this->assertTrue($cache->save(100, $id)); //fast usage at 90% - $this->assertEquals(100, $cache->load($id)); + + $saveResult = $cache->save(10, $id); + $failMessage = 'Failed to save when fast usage is 0. Two level logs: ' . "\n" . stream_get_contents($logStream); + $this->assertTrue($saveResult, $failMessage); //fast usage at 0% + + $saveResult = $cache->save(100, $id); + $failMessage = 'Failed to save when fast usage is 90. Two level logs: ' . "\n" . stream_get_contents($logStream); + $this->assertTrue($saveResult, $failMessage); //fast usage at 90% + + $loadResult = $cache->load($id); + $failMessage = 'Failed to load when fast usage is 90. Two level logs: ' . "\n" . stream_get_contents($logStream); + $this->assertEquals(100, $loadResult, $failMessage); } /**