diff options
Diffstat (limited to 'tests/lib/Cache')
-rw-r--r-- | tests/lib/Cache/CappedMemoryCacheTest.php | 65 | ||||
-rw-r--r-- | tests/lib/Cache/FileCacheTest.php | 160 | ||||
-rw-r--r-- | tests/lib/Cache/TestCache.php | 102 |
3 files changed, 327 insertions, 0 deletions
diff --git a/tests/lib/Cache/CappedMemoryCacheTest.php b/tests/lib/Cache/CappedMemoryCacheTest.php new file mode 100644 index 00000000000..b9731c7cdde --- /dev/null +++ b/tests/lib/Cache/CappedMemoryCacheTest.php @@ -0,0 +1,65 @@ +<?php + +/** + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace Test\Cache; + +use OCP\Cache\CappedMemoryCache; + +/** + * Class CappedMemoryCacheTest + * + * @package Test\Cache + */ +class CappedMemoryCacheTest extends TestCache { + protected function setUp(): void { + parent::setUp(); + $this->instance = new CappedMemoryCache(); + } + + public function testSetOverCap(): void { + $instance = new CappedMemoryCache(3); + + $instance->set('1', 'a'); + $instance->set('2', 'b'); + $instance->set('3', 'c'); + $instance->set('4', 'd'); + $instance->set('5', 'e'); + + $this->assertFalse($instance->hasKey('1')); + $this->assertFalse($instance->hasKey('2')); + $this->assertTrue($instance->hasKey('3')); + $this->assertTrue($instance->hasKey('4')); + $this->assertTrue($instance->hasKey('5')); + } + + public function testClear(): void { + $value = 'ipsum lorum'; + $this->instance->set('1_value1', $value); + $this->instance->set('1_value2', $value); + $this->instance->set('2_value1', $value); + $this->instance->set('3_value1', $value); + + $this->assertTrue($this->instance->clear()); + $this->assertFalse($this->instance->hasKey('1_value1')); + $this->assertFalse($this->instance->hasKey('1_value2')); + $this->assertFalse($this->instance->hasKey('2_value1')); + $this->assertFalse($this->instance->hasKey('3_value1')); + } + + public function testIndirectSet(): void { + $this->instance->set('array', []); + + $this->instance['array'][] = 'foo'; + + $this->assertEquals(['foo'], $this->instance->get('array')); + + $this->instance['array']['bar'] = 'qwerty'; + + $this->assertEquals(['foo', 'bar' => 'qwerty'], $this->instance->get('array')); + } +} diff --git a/tests/lib/Cache/FileCacheTest.php b/tests/lib/Cache/FileCacheTest.php new file mode 100644 index 00000000000..4daa8d3b7ef --- /dev/null +++ b/tests/lib/Cache/FileCacheTest.php @@ -0,0 +1,160 @@ +<?php + +/** + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace Test\Cache; + +use OC\Cache\File; +use OC\Files\Filesystem; +use OC\Files\Storage\Local; +use OC\Files\Storage\Storage; +use OC\Files\Storage\Temporary; +use OC\Files\View; +use OCP\Files\LockNotAcquiredException; +use OCP\Files\Mount\IMountManager; +use OCP\ITempManager; +use OCP\Lock\LockedException; +use OCP\Server; +use Test\Traits\UserTrait; + +/** + * Class FileCacheTest + * + * @group DB + * + * @package Test\Cache + */ +class FileCacheTest extends TestCache { + use UserTrait; + + /** + * @var string + * */ + private $user; + /** + * @var string + * */ + private $datadir; + /** + * @var Storage + * */ + private $storage; + /** + * @var View + * */ + private $rootView; + + public function skip() { + //$this->skipUnless(OC_User::isLoggedIn()); + } + + protected function setUp(): void { + parent::setUp(); + + //login + $this->createUser('test', 'test'); + + $this->user = \OC_User::getUser(); + \OC_User::setUserId('test'); + + //clear all proxies and hooks so we can do clean testing + \OC_Hook::clear('OC_Filesystem'); + + /** @var IMountManager $manager */ + $manager = Server::get(IMountManager::class); + $manager->removeMount('/test'); + + $storage = new Temporary([]); + Filesystem::mount($storage, [], '/test/cache'); + + //set up the users dir + $this->rootView = new View(''); + $this->rootView->mkdir('/test'); + + $this->instance = new File(); + + // forces creation of cache folder for subsequent tests + $this->instance->set('hack', 'hack'); + } + + protected function tearDown(): void { + if ($this->instance) { + $this->instance->remove('hack', 'hack'); + } + + \OC_User::setUserId($this->user); + + if ($this->instance) { + $this->instance->clear(); + $this->instance = null; + } + + parent::tearDown(); + } + + private function setupMockStorage() { + $mockStorage = $this->getMockBuilder(Local::class) + ->onlyMethods(['filemtime', 'unlink']) + ->setConstructorArgs([['datadir' => Server::get(ITempManager::class)->getTemporaryFolder()]]) + ->getMock(); + + Filesystem::mount($mockStorage, [], '/test/cache'); + + return $mockStorage; + } + + public function testGarbageCollectOldKeys(): void { + $mockStorage = $this->setupMockStorage(); + + $mockStorage->expects($this->atLeastOnce()) + ->method('filemtime') + ->willReturn(100); + $mockStorage->expects($this->once()) + ->method('unlink') + ->with('key1') + ->willReturn(true); + + $this->instance->set('key1', 'value1'); + $this->instance->gc(); + } + + public function testGarbageCollectLeaveRecentKeys(): void { + $mockStorage = $this->setupMockStorage(); + + $mockStorage->expects($this->atLeastOnce()) + ->method('filemtime') + ->willReturn(time() + 3600); + $mockStorage->expects($this->never()) + ->method('unlink') + ->with('key1'); + $this->instance->set('key1', 'value1'); + $this->instance->gc(); + } + + public static function lockExceptionProvider(): array { + return [ + [new LockedException('key1')], + [new LockNotAcquiredException('key1', 1)], + ]; + } + + #[\PHPUnit\Framework\Attributes\DataProvider('lockExceptionProvider')] + public function testGarbageCollectIgnoreLockedKeys($testException): void { + $mockStorage = $this->setupMockStorage(); + + $mockStorage->expects($this->atLeastOnce()) + ->method('filemtime') + ->willReturn(100); + $mockStorage->expects($this->atLeastOnce()) + ->method('unlink')->willReturnOnConsecutiveCalls($this->throwException($testException), $this->returnValue(true)); + + $this->instance->set('key1', 'value1'); + $this->instance->set('key2', 'value2'); + + $this->instance->gc(); + } +} diff --git a/tests/lib/Cache/TestCache.php b/tests/lib/Cache/TestCache.php new file mode 100644 index 00000000000..ec150152816 --- /dev/null +++ b/tests/lib/Cache/TestCache.php @@ -0,0 +1,102 @@ +<?php + +/** + * SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace Test\Cache; + +use OCP\ICache; + +abstract class TestCache extends \Test\TestCase { + /** + * @var ICache cache; + */ + protected $instance; + + protected function tearDown(): void { + if ($this->instance) { + $this->instance->clear(); + } + + parent::tearDown(); + } + + public function testSimple(): void { + $this->assertNull($this->instance->get('value1')); + $this->assertFalse($this->instance->hasKey('value1')); + + $value = 'foobar'; + $this->instance->set('value1', $value); + $this->assertTrue($this->instance->hasKey('value1')); + $received = $this->instance->get('value1'); + $this->assertEquals($value, $received, 'Value received from cache not equal to the original'); + $value = 'ipsum lorum'; + $this->instance->set('value1', $value); + $received = $this->instance->get('value1'); + $this->assertEquals($value, $received, 'Value not overwritten by second set'); + + $value2 = 'foobar'; + $this->instance->set('value2', $value2); + $received2 = $this->instance->get('value2'); + $this->assertTrue($this->instance->hasKey('value1')); + $this->assertTrue($this->instance->hasKey('value2')); + $this->assertEquals($value, $received, 'Value changed while setting other variable'); + $this->assertEquals($value2, $received2, 'Second value not equal to original'); + + $this->assertFalse($this->instance->hasKey('not_set')); + $this->assertNull($this->instance->get('not_set'), 'Unset value not equal to null'); + + $this->assertTrue($this->instance->remove('value1')); + $this->assertFalse($this->instance->hasKey('value1')); + } + + public function testClear(): void { + $value = 'ipsum lorum'; + $this->instance->set('1_value1', $value . '1'); + $this->instance->set('1_value2', $value . '2'); + $this->instance->set('2_value1', $value . '3'); + $this->instance->set('3_value1', $value . '4'); + + $this->assertEquals([ + '1_value1' => 'ipsum lorum1', + '1_value2' => 'ipsum lorum2', + '2_value1' => 'ipsum lorum3', + '3_value1' => 'ipsum lorum4', + ], [ + '1_value1' => $this->instance->get('1_value1'), + '1_value2' => $this->instance->get('1_value2'), + '2_value1' => $this->instance->get('2_value1'), + '3_value1' => $this->instance->get('3_value1'), + ]); + $this->assertTrue($this->instance->clear('1_')); + + $this->assertEquals([ + '1_value1' => null, + '1_value2' => null, + '2_value1' => 'ipsum lorum3', + '3_value1' => 'ipsum lorum4', + ], [ + '1_value1' => $this->instance->get('1_value1'), + '1_value2' => $this->instance->get('1_value2'), + '2_value1' => $this->instance->get('2_value1'), + '3_value1' => $this->instance->get('3_value1'), + ]); + + $this->assertTrue($this->instance->clear()); + + $this->assertEquals([ + '1_value1' => null, + '1_value2' => null, + '2_value1' => null, + '3_value1' => null, + ], [ + '1_value1' => $this->instance->get('1_value1'), + '1_value2' => $this->instance->get('1_value2'), + '2_value1' => $this->instance->get('2_value1'), + '3_value1' => $this->instance->get('3_value1'), + ]); + } +} |