2021-04-01 23:24:39 +01:00
< ? php
2021-10-10 09:26:18 +01:00
declare ( strict_types = 1 );
2021-04-01 23:24:39 +01:00
// {{{ License
// This file is part of GNU social - https://www.gnu.org/software/social
//
// GNU social is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// GNU social is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
// }}}
2022-03-14 18:33:47 +00:00
namespace App\Test\Core ;
2021-04-01 23:24:39 +01:00
use App\Core\Cache ;
use App\Util\Common ;
2022-03-14 18:33:47 +00:00
use App\Util\GNUsocialTestCase ;
2021-10-10 09:26:18 +01:00
use ReflectionClass ;
2021-04-01 23:24:39 +01:00
use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface ;
2022-03-14 18:33:47 +00:00
class CacheTest extends GNUsocialTestCase
2021-04-01 23:24:39 +01:00
{
2021-10-10 09:26:18 +01:00
private function doTest ( array $adapters , $result_pool , $throws = null , $recompute = \INF )
2021-04-01 23:24:39 +01:00
{
static :: bootKernel ();
// Setup Common::config to have the values in $conf
2021-07-20 15:08:19 +01:00
$conf = [ 'cache' => [ 'adapters' => $adapters , 'early_recompute' => $recompute ]];
2021-04-01 23:24:39 +01:00
$cb = $this -> createMock ( ContainerBagInterface :: class );
2022-03-14 18:33:47 +00:00
static :: assertInstanceOf ( ContainerBagInterface :: class , $cb );
2021-04-01 23:24:39 +01:00
$cb -> method ( 'get' )
2021-10-10 09:26:18 +01:00
-> willReturnMap ([[ 'gnusocial' , $conf ], [ 'gnusocial_defaults' , $conf ]]);
2021-04-01 23:24:39 +01:00
Common :: setupConfig ( $cb );
if ( $throws != null ) {
$this -> expectException ( $throws );
}
Cache :: setupCache ();
2021-10-10 09:26:18 +01:00
$reflector = new ReflectionClass ( 'App\Core\Cache' );
2021-04-01 23:24:39 +01:00
$pools = $reflector -> getStaticPropertyValue ( 'pools' );
foreach ( $result_pool as $name => $type ) {
static :: assertInstanceOf ( $type , $pools [ $name ]);
}
}
2021-07-20 15:08:19 +01:00
public function testConfigurationParsingSingle ()
2021-04-01 23:24:39 +01:00
{
self :: doTest ([ 'default' => 'redis://redis' ], [ 'default' => \Symfony\Component\Cache\Adapter\RedisAdapter :: class ]);
2021-07-20 15:08:19 +01:00
}
public function testConfigurationParsingCluster1 ()
{
2021-04-01 23:24:39 +01:00
self :: doTest ([ 'default' => 'redis://redis;redis://redis' ], [ 'default' => \Symfony\Component\Cache\Adapter\RedisAdapter :: class ], \App\Util\Exception\ConfigurationException :: class );
2021-07-20 15:08:19 +01:00
}
// /**
// * This requires extra server configuration, but the code was tested
// * manually and works, so it'll be excluded from automatic tests, for now, at least
// */
// public function testConfigurationParsingCluster2()
// {
// self::doTest(['default' => 'redis://redis:6379;redis://redis:6379'], ['default' => \Symfony\Component\Cache\Adapter\RedisAdapter::class]);
// }
public function testConfigurationParsingFallBack ()
{
2021-04-01 23:24:39 +01:00
self :: doTest ([ 'default' => 'redis://redis,filesystem' ], [ 'default' => \Symfony\Component\Cache\Adapter\ChainAdapter :: class ]);
2021-07-20 15:08:19 +01:00
}
public function testConfigurationParsingMultiple ()
{
2021-04-01 23:24:39 +01:00
self :: doTest ([ 'default' => 'redis://redis' , 'file' => 'filesystem://test' ], [ 'default' => \Symfony\Component\Cache\Adapter\RedisAdapter :: class , 'file' => \Symfony\Component\Cache\Adapter\FilesystemAdapter :: class ]);
}
public function testGeneralImplementation ()
{
// Need a connection to run the tests
self :: doTest ([ 'default' => 'redis://redis' ], [ 'default' => \Symfony\Component\Cache\Adapter\RedisAdapter :: class ]);
2021-10-10 09:26:18 +01:00
static :: assertSame ( 'value' , Cache :: get ( 'test' , fn ( $i ) => 'value' ));
2021-04-01 23:24:39 +01:00
Cache :: set ( 'test' , 'other_value' );
2021-10-10 09:26:18 +01:00
static :: assertSame ( 'other_value' , Cache :: get ( 'test' , fn ( $i ) => 'value' ));
2021-04-01 23:24:39 +01:00
static :: assertTrue ( Cache :: delete ( 'test' ));
}
2021-10-10 09:26:18 +01:00
private function _testRedis ( $recompute = \INF )
2021-04-01 23:24:39 +01:00
{
2021-07-20 15:08:19 +01:00
self :: doTest ([ 'default' => 'redis://redis' ], [ 'default' => \Symfony\Component\Cache\Adapter\RedisAdapter :: class ], throws : null , recompute : $recompute );
2021-04-01 23:24:39 +01:00
// Redis supports lists directly, uses different implementation
2021-07-20 15:08:19 +01:00
$key = 'test' . time ();
2021-10-28 18:05:28 +01:00
static :: assertSame ([], Cache :: getList ( $key . '0' , fn ( $i ) => []));
static :: assertSame ([ 'foo' ], Cache :: getList ( $key . '1' , fn ( $i ) => [ 'foo' ]));
2021-10-10 09:26:18 +01:00
static :: assertSame ([ 'foo' , 'bar' ], Cache :: getList ( $key , fn ( $i ) => [ 'foo' , 'bar' ]));
2021-10-28 18:05:28 +01:00
static :: assertSame ([ 'foo' , 'bar' ], Cache :: getList ( $key , function () { $this -> assertFalse ( 'should not be called' ); })); // Repeat to test no recompute lrange
2022-02-27 00:29:26 +00:00
Cache :: listPushLeft ( $key , 'quux' );
2021-10-28 18:05:28 +01:00
static :: assertSame ([ 'quux' , 'foo' , 'bar' ], Cache :: getList ( $key , function ( $i ) { $this -> assertFalse ( 'should not be called' ); }));
2022-02-27 00:29:26 +00:00
Cache :: listPushLeft ( $key , 'foobar' , max_count : 2 );
2021-10-28 18:05:28 +01:00
static :: assertSame ([ 'foobar' , 'quux' ], Cache :: getList ( $key , function ( $i ) { $this -> assertFalse ( 'should not be called' ); }));
2022-02-27 00:29:26 +00:00
Cache :: listPushRight ( $key , 'foo' );
static :: assertSame ([ 'foobar' , 'quux' , 'foo' ], Cache :: getList ( $key , function ( $i ) { $this -> assertFalse ( 'should not be called' ); }));
Cache :: listPushRight ( $key , 'bar' , max_count : 2 );
static :: assertSame ([ 'foo' , 'bar' ], Cache :: getList ( $key , function ( $i ) { $this -> assertFalse ( 'should not be called' ); }));
2021-07-20 15:08:19 +01:00
static :: assertTrue ( Cache :: deleteList ( $key ));
}
public function testRedisImplementation ()
{
$this -> _testRedis ();
}
public function testRedisImplementationNoEarlyRecompute ()
{
$this -> _testRedis ( null );
2021-04-01 23:24:39 +01:00
}
public function testNonRedisImplementation ()
{
self :: doTest ([ 'file' => 'filesystem://test' ], [ 'file' => \Symfony\Component\Cache\Adapter\FilesystemAdapter :: class ]);
$key = 'test' . time ();
2021-11-15 19:27:39 +00:00
static :: assertSame ([], Cache :: getList ( $key . '0' , fn ( $i ) => [], pool : 'file' ));
static :: assertSame ([ 'foo' ], Cache :: getList ( $key . '1' , fn ( $i ) => [ 'foo' ], pool : 'file' ));
2021-07-20 15:08:19 +01:00
static :: assertSame ([ 'foo' , 'bar' ], Cache :: getList ( $key , fn ( $i ) => [ 'foo' , 'bar' ], pool : 'file' ));
2021-11-15 19:27:39 +00:00
static :: assertSame ([ 'foo' , 'bar' ], Cache :: getList ( $key , function () { $this -> assertFalse ( 'should not be called' ); }, pool : 'file' )); // Repeat to test no recompute lrange
2022-02-27 00:29:26 +00:00
Cache :: listPushLeft ( $key , 'quux' , pool : 'file' );
2021-11-15 19:27:39 +00:00
static :: assertSame ([ 'quux' , 'foo' , 'bar' ], Cache :: getList ( $key , function ( $i ) { $this -> assertFalse ( 'should not be called' ); }, pool : 'file' ));
2022-02-27 00:29:26 +00:00
Cache :: listPushLeft ( $key , 'foobar' , max_count : 2 , pool : 'file' );
2021-11-15 19:27:39 +00:00
static :: assertSame ([ 'foobar' , 'quux' ], Cache :: getList ( $key , function ( $i ) { $this -> assertFalse ( 'should not be called' ); }, pool : 'file' ));
2022-03-07 13:44:49 +00:00
Cache :: listPushRight ( $key , 'foo' , pool : 'file' );
static :: assertSame ([ 'foobar' , 'quux' , 'foo' ], Cache :: getList ( $key , function ( $i ) { $this -> assertFalse ( 'should not be called' ); }, pool : 'file' ));
Cache :: listPushRight ( $key , 'bar' , max_count : 2 , pool : 'file' );
static :: assertSame ([ 'foo' , 'bar' ], Cache :: getList ( $key , function ( $i ) { $this -> assertFalse ( 'should not be called' ); }, pool : 'file' ));
2021-04-01 23:24:39 +01:00
static :: assertTrue ( Cache :: deleteList ( $key , pool : 'file' ));
}
}