diff options
Diffstat (limited to 'tests/lib/Files/ObjectStore')
-rw-r--r-- | tests/lib/Files/ObjectStore/AzureTest.php | 28 | ||||
-rw-r--r-- | tests/lib/Files/ObjectStore/FailDeleteObjectStore.php | 28 | ||||
-rw-r--r-- | tests/lib/Files/ObjectStore/FailWriteObjectStore.php | 28 | ||||
-rw-r--r-- | tests/lib/Files/ObjectStore/LocalTest.php | 25 | ||||
-rw-r--r-- | tests/lib/Files/ObjectStore/MapperTest.php | 27 | ||||
-rw-r--r-- | tests/lib/Files/ObjectStore/ObjectStoreScannerTest.php | 24 | ||||
-rw-r--r-- | tests/lib/Files/ObjectStore/ObjectStoreStorageOverwrite.php | 23 | ||||
-rw-r--r-- | tests/lib/Files/ObjectStore/ObjectStoreStorageTest.php | 82 | ||||
-rw-r--r-- | tests/lib/Files/ObjectStore/ObjectStoreStoragesDifferentBucketTest.php | 43 | ||||
-rw-r--r-- | tests/lib/Files/ObjectStore/ObjectStoreStoragesSameBucketTest.php | 35 | ||||
-rw-r--r-- | tests/lib/Files/ObjectStore/ObjectStoreTestCase.php (renamed from tests/lib/Files/ObjectStore/ObjectStoreTest.php) | 57 | ||||
-rw-r--r-- | tests/lib/Files/ObjectStore/PrimaryObjectStoreConfigTest.php | 285 | ||||
-rw-r--r-- | tests/lib/Files/ObjectStore/S3Test.php | 65 | ||||
-rw-r--r-- | tests/lib/Files/ObjectStore/SwiftTest.php | 34 |
14 files changed, 518 insertions, 266 deletions
diff --git a/tests/lib/Files/ObjectStore/AzureTest.php b/tests/lib/Files/ObjectStore/AzureTest.php index 054dc36cce4..52d2b9e8657 100644 --- a/tests/lib/Files/ObjectStore/AzureTest.php +++ b/tests/lib/Files/ObjectStore/AzureTest.php @@ -1,34 +1,22 @@ <?php + /** - * @copyright Copyright (c) 2018 Robin Appelman <robin@icewind.nl> - * - * @license GNU AGPL version 3 or any later version - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Files\ObjectStore; use OC\Files\ObjectStore\Azure; +use OCP\IConfig; +use OCP\Server; /** * @group PRIMARY-azure */ -class AzureTest extends ObjectStoreTest { +class AzureTest extends ObjectStoreTestCase { protected function getInstance() { - $config = \OC::$server->getConfig()->getSystemValue('objectstore'); + $config = Server::get(IConfig::class)->getSystemValue('objectstore'); if (!is_array($config) || $config['class'] !== 'OC\\Files\\ObjectStore\\Azure') { $this->markTestSkipped('objectstore not configured for azure'); } @@ -36,7 +24,7 @@ class AzureTest extends ObjectStoreTest { return new Azure($config['arguments']); } - public function testFseekSize() { + public function testFseekSize(): void { $this->markTestSkipped('azure does not support seeking at the moment'); } } diff --git a/tests/lib/Files/ObjectStore/FailDeleteObjectStore.php b/tests/lib/Files/ObjectStore/FailDeleteObjectStore.php index 5160abe574f..767125d42aa 100644 --- a/tests/lib/Files/ObjectStore/FailDeleteObjectStore.php +++ b/tests/lib/Files/ObjectStore/FailDeleteObjectStore.php @@ -2,23 +2,8 @@ declare(strict_types=1); /** - * @copyright Copyright (c) 2019 Robin Appelman <robin@icewind.nl> - * - * @license GNU AGPL version 3 or any later version - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Files\ObjectStore; @@ -26,10 +11,9 @@ namespace Test\Files\ObjectStore; use OCP\Files\ObjectStore\IObjectStore; class FailDeleteObjectStore implements IObjectStore { - private $objectStore; - - public function __construct(IObjectStore $objectStore) { - $this->objectStore = $objectStore; + public function __construct( + private IObjectStore $objectStore, + ) { } public function getStorageId() { @@ -40,7 +24,7 @@ class FailDeleteObjectStore implements IObjectStore { return $this->objectStore->readObject($urn); } - public function writeObject($urn, $stream, string $mimetype = null) { + public function writeObject($urn, $stream, ?string $mimetype = null) { return $this->objectStore->writeObject($urn, $stream, $mimetype); } diff --git a/tests/lib/Files/ObjectStore/FailWriteObjectStore.php b/tests/lib/Files/ObjectStore/FailWriteObjectStore.php index 559d004cd0c..924bbdada4f 100644 --- a/tests/lib/Files/ObjectStore/FailWriteObjectStore.php +++ b/tests/lib/Files/ObjectStore/FailWriteObjectStore.php @@ -2,23 +2,8 @@ declare(strict_types=1); /** - * @copyright Copyright (c) 2018 Robin Appelman <robin@icewind.nl> - * - * @license GNU AGPL version 3 or any later version - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Files\ObjectStore; @@ -26,10 +11,9 @@ namespace Test\Files\ObjectStore; use OCP\Files\ObjectStore\IObjectStore; class FailWriteObjectStore implements IObjectStore { - private $objectStore; - - public function __construct(IObjectStore $objectStore) { - $this->objectStore = $objectStore; + public function __construct( + private IObjectStore $objectStore, + ) { } public function getStorageId() { @@ -40,7 +24,7 @@ class FailWriteObjectStore implements IObjectStore { return $this->objectStore->readObject($urn); } - public function writeObject($urn, $stream, string $mimetype = null) { + public function writeObject($urn, $stream, ?string $mimetype = null) { // emulate a failed write that didn't throw an error return true; } diff --git a/tests/lib/Files/ObjectStore/LocalTest.php b/tests/lib/Files/ObjectStore/LocalTest.php index ceb21428e4b..d3e9ad56164 100644 --- a/tests/lib/Files/ObjectStore/LocalTest.php +++ b/tests/lib/Files/ObjectStore/LocalTest.php @@ -1,32 +1,19 @@ <?php + /** - * @copyright Copyright (c) 2016 Robin Appelman <robin@icewind.nl> - * - * @license GNU AGPL version 3 or any later version - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Files\ObjectStore; use OC\Files\ObjectStore\StorageObjectStore; use OC\Files\Storage\Temporary; +use OCP\Files\ObjectStore\IObjectStore; -class LocalTest extends ObjectStoreTest { +class LocalTest extends ObjectStoreTestCase { /** - * @return \OCP\Files\ObjectStore\IObjectStore + * @return IObjectStore */ protected function getInstance() { $storage = new Temporary(); diff --git a/tests/lib/Files/ObjectStore/MapperTest.php b/tests/lib/Files/ObjectStore/MapperTest.php index dbe5fe5d32f..6448d5ce1f5 100644 --- a/tests/lib/Files/ObjectStore/MapperTest.php +++ b/tests/lib/Files/ObjectStore/MapperTest.php @@ -1,22 +1,9 @@ <?php + /** - * @author Roeland Jago Douma <rullzer@owncloud.com> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program 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, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace Test\Files\ObjectStore; @@ -43,7 +30,7 @@ class MapperTest extends \Test\TestCase { $this->mapper = new Mapper($this->user, $this->config); } - public function dataGetBucket() { + public static function dataGetBucket(): array { return [ ['user', 64, 0, '17'], ['USER', 64, 0, '0'], @@ -56,12 +43,12 @@ class MapperTest extends \Test\TestCase { } /** - * @dataProvider dataGetBucket * @param string $username * @param int $numBuckets * @param string $expectedBucket */ - public function testGetBucket($username, $numBuckets, $bucketShift, $expectedBucket) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataGetBucket')] + public function testGetBucket($username, $numBuckets, $bucketShift, $expectedBucket): void { $this->user->expects($this->once()) ->method('getUID') ->willReturn($username); diff --git a/tests/lib/Files/ObjectStore/ObjectStoreScannerTest.php b/tests/lib/Files/ObjectStore/ObjectStoreScannerTest.php index 02d72defa92..ea6ac682c70 100644 --- a/tests/lib/Files/ObjectStore/ObjectStoreScannerTest.php +++ b/tests/lib/Files/ObjectStore/ObjectStoreScannerTest.php @@ -1,13 +1,8 @@ <?php + /** - * ownCloud - * - * @author Joas Schilling - * @copyright 2015 Joas Schilling nickvergessen@owncloud.com - * - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. + * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Files\ObjectStore; @@ -37,13 +32,11 @@ class ObjectStoreScannerTest extends TestCase { $this->realScanner = new Scanner($this->storage); } - public function testFile() { + public function testFile(): void { $data = "dummy file data\n"; $this->storage->file_put_contents('foo.txt', $data); - $this->assertEquals( - [], - $this->scanner->scanFile('foo.txt'), + $this->assertNull($this->scanner->scanFile('foo.txt'), 'Asserting that no error occurred while scanFile()' ); } @@ -57,17 +50,16 @@ class ObjectStoreScannerTest extends TestCase { $this->storage->file_put_contents('folder/bar.txt', $textData); } - public function testFolder() { + public function testFolder(): void { $this->fillTestFolders(); - $this->assertEquals( - [], + $this->assertNull( $this->scanner->scan(''), 'Asserting that no error occurred while scan()' ); } - public function testBackgroundScan() { + public function testBackgroundScan(): void { $this->fillTestFolders(); $this->storage->mkdir('folder2'); $this->storage->file_put_contents('folder2/bar.txt', 'foobar'); diff --git a/tests/lib/Files/ObjectStore/ObjectStoreStorageOverwrite.php b/tests/lib/Files/ObjectStore/ObjectStoreStorageOverwrite.php index b85f6289c94..6eaffb6961c 100644 --- a/tests/lib/Files/ObjectStore/ObjectStoreStorageOverwrite.php +++ b/tests/lib/Files/ObjectStore/ObjectStoreStorageOverwrite.php @@ -2,23 +2,8 @@ declare(strict_types=1); /** - * @copyright Copyright (c) 2018 Robin Appelman <robin@icewind.nl> - * - * @license GNU AGPL version 3 or any later version - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Files\ObjectStore; @@ -30,7 +15,7 @@ use OCP\Files\ObjectStore\IObjectStore; * Allow overwriting the object store instance for test purposes */ class ObjectStoreStorageOverwrite extends ObjectStoreStorage { - public function setObjectStore(IObjectStore $objectStore) { + public function setObjectStore(IObjectStore $objectStore): void { $this->objectStore = $objectStore; } @@ -38,7 +23,7 @@ class ObjectStoreStorageOverwrite extends ObjectStoreStorage { return $this->objectStore; } - public function setValidateWrites(bool $validate) { + public function setValidateWrites(bool $validate): void { $this->validateWrites = $validate; } } diff --git a/tests/lib/Files/ObjectStore/ObjectStoreStorageTest.php b/tests/lib/Files/ObjectStore/ObjectStoreStorageTest.php index 2f835747077..3387808445a 100644 --- a/tests/lib/Files/ObjectStore/ObjectStoreStorageTest.php +++ b/tests/lib/Files/ObjectStore/ObjectStoreStorageTest.php @@ -1,21 +1,9 @@ <?php + /** - * @author Jörn Friedrich Dreyer - * @copyright (c) 2014 Jörn Friedrich Dreyer <jfd@owncloud.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library 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 this library. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Files\ObjectStore; @@ -23,6 +11,7 @@ namespace Test\Files\ObjectStore; use OC\Files\ObjectStore\StorageObjectStore; use OC\Files\Storage\Temporary; use OC\Files\Storage\Wrapper\Jail; +use OCP\Constants; use OCP\Files\ObjectStore\IObjectStore; use Test\Files\Storage\Storage; @@ -56,7 +45,7 @@ class ObjectStoreStorageTest extends Storage { parent::tearDown(); } - public function testStat() { + public function testStat(): void { $textFile = \OC::$SERVERROOT . '/tests/data/lorem.txt'; $ctimeStart = time(); $this->instance->file_put_contents('/lorem.txt', file_get_contents($textFile)); @@ -80,29 +69,27 @@ class ObjectStoreStorageTest extends Storage { } } - public function testCheckUpdate() { + public function testCheckUpdate(): void { $this->markTestSkipped('Detecting external changes is not supported on object storages'); } - /** - * @dataProvider copyAndMoveProvider - */ - public function testMove($source, $target) { + #[\PHPUnit\Framework\Attributes\DataProvider('copyAndMoveProvider')] + public function testMove($source, $target): void { $this->initSourceAndTarget($source); - $sourceId = $this->instance->getCache()->getId(ltrim('/', $source)); + $sourceId = $this->instance->getCache()->getId(ltrim($source, '/')); $this->assertNotEquals(-1, $sourceId); $this->instance->rename($source, $target); - $this->assertTrue($this->instance->file_exists($target), $target.' was not created'); - $this->assertFalse($this->instance->file_exists($source), $source.' still exists'); + $this->assertTrue($this->instance->file_exists($target), $target . ' was not created'); + $this->assertFalse($this->instance->file_exists($source), $source . ' still exists'); $this->assertSameAsLorem($target); - $targetId = $this->instance->getCache()->getId(ltrim('/', $target)); + $targetId = $this->instance->getCache()->getId(ltrim($target, '/')); $this->assertSame($sourceId, $targetId, 'fileid must be stable on move or shares will break'); } - public function testRenameDirectory() { + public function testRenameDirectory(): void { $this->instance->mkdir('source'); $this->instance->file_put_contents('source/test1.txt', 'foo'); $this->instance->file_put_contents('source/test2.txt', 'qwerty'); @@ -131,7 +118,7 @@ class ObjectStoreStorageTest extends Storage { $this->assertSame($sourceId, $targetId, 'fileid must be stable on move or shares will break'); } - public function testRenameOverWriteDirectory() { + public function testRenameOverWriteDirectory(): void { $this->instance->mkdir('source'); $this->instance->file_put_contents('source/test1.txt', 'foo'); $sourceId = $this->instance->getCache()->getId('source'); @@ -151,7 +138,7 @@ class ObjectStoreStorageTest extends Storage { $this->assertSame($sourceId, $targetId, 'fileid must be stable on move or shares will break'); } - public function testRenameOverWriteDirectoryOverFile() { + public function testRenameOverWriteDirectoryOverFile(): void { $this->instance->mkdir('source'); $this->instance->file_put_contents('source/test1.txt', 'foo'); $sourceId = $this->instance->getCache()->getId('source'); @@ -168,7 +155,7 @@ class ObjectStoreStorageTest extends Storage { $this->assertSame($sourceId, $targetId, 'fileid must be stable on move or shares will break'); } - public function testWriteObjectSilentFailure() { + public function testWriteObjectSilentFailure(): void { $objectStore = $this->instance->getObjectStore(); $this->instance->setObjectStore(new FailWriteObjectStore($objectStore)); @@ -181,7 +168,7 @@ class ObjectStoreStorageTest extends Storage { $this->assertFalse($this->instance->file_exists('test.txt')); } - public function testWriteObjectSilentFailureNoCheck() { + public function testWriteObjectSilentFailureNoCheck(): void { $objectStore = $this->instance->getObjectStore(); $this->instance->setObjectStore(new FailWriteObjectStore($objectStore)); $this->instance->setValidateWrites(false); @@ -190,7 +177,7 @@ class ObjectStoreStorageTest extends Storage { $this->assertTrue($this->instance->file_exists('test.txt')); } - public function testDeleteObjectFailureKeepCache() { + public function testDeleteObjectFailureKeepCache(): void { $objectStore = $this->instance->getObjectStore(); $this->instance->setObjectStore(new FailDeleteObjectStore($objectStore)); $cache = $this->instance->getCache(); @@ -215,7 +202,7 @@ class ObjectStoreStorageTest extends Storage { $this->assertTrue($cache->inCache('foo/test.txt')); } - public function testCopyBetweenJails() { + public function testCopyBetweenJails(): void { $this->instance->mkdir('a'); $this->instance->mkdir('b'); $jailA = new Jail([ @@ -238,26 +225,26 @@ class ObjectStoreStorageTest extends Storage { $this->assertEquals('3', $this->instance->file_get_contents('b/target/sub/3.txt')); } - public function testCopyPreservesPermissions() { + public function testCopyPreservesPermissions(): void { $cache = $this->instance->getCache(); $this->instance->file_put_contents('test.txt', 'foo'); $this->assertTrue($cache->inCache('test.txt')); - $cache->update($cache->getId('test.txt'), ['permissions' => \OCP\Constants::PERMISSION_READ]); - $this->assertEquals(\OCP\Constants::PERMISSION_READ, $this->instance->getPermissions('test.txt')); + $cache->update($cache->getId('test.txt'), ['permissions' => Constants::PERMISSION_READ]); + $this->assertEquals(Constants::PERMISSION_READ, $this->instance->getPermissions('test.txt')); $this->assertTrue($this->instance->copy('test.txt', 'new.txt')); $this->assertTrue($cache->inCache('new.txt')); - $this->assertEquals(\OCP\Constants::PERMISSION_READ, $this->instance->getPermissions('new.txt')); + $this->assertEquals(Constants::PERMISSION_READ, $this->instance->getPermissions('new.txt')); } /** * Test that copying files will drop permissions like local storage does * TODO: Drop this and fix local storage */ - public function testCopyGrantsPermissions() { + public function testCopyGrantsPermissions(): void { $config['objectstore'] = $this->objectStorage; $config['handleCopiesAsOwned'] = true; $instance = new ObjectStoreStorageOverwrite($config); @@ -267,12 +254,25 @@ class ObjectStoreStorageTest extends Storage { $instance->file_put_contents('test.txt', 'foo'); $this->assertTrue($cache->inCache('test.txt')); - $cache->update($cache->getId('test.txt'), ['permissions' => \OCP\Constants::PERMISSION_READ]); - $this->assertEquals(\OCP\Constants::PERMISSION_READ, $instance->getPermissions('test.txt')); + $cache->update($cache->getId('test.txt'), ['permissions' => Constants::PERMISSION_READ]); + $this->assertEquals(Constants::PERMISSION_READ, $instance->getPermissions('test.txt')); $this->assertTrue($instance->copy('test.txt', 'new.txt')); $this->assertTrue($cache->inCache('new.txt')); - $this->assertEquals(\OCP\Constants::PERMISSION_ALL, $instance->getPermissions('new.txt')); + $this->assertEquals(Constants::PERMISSION_ALL, $instance->getPermissions('new.txt')); + } + + public function testCopyFolderSize(): void { + $cache = $this->instance->getCache(); + + $this->instance->mkdir('source'); + $this->instance->file_put_contents('source/test.txt', 'foo'); + $this->instance->getUpdater()->update('source/test.txt'); + $this->assertEquals(3, $cache->get('source')->getSize()); + + $this->assertTrue($this->instance->copy('source', 'target')); + + $this->assertEquals(3, $cache->get('target')->getSize()); } } diff --git a/tests/lib/Files/ObjectStore/ObjectStoreStoragesDifferentBucketTest.php b/tests/lib/Files/ObjectStore/ObjectStoreStoragesDifferentBucketTest.php new file mode 100644 index 00000000000..d39426ee821 --- /dev/null +++ b/tests/lib/Files/ObjectStore/ObjectStoreStoragesDifferentBucketTest.php @@ -0,0 +1,43 @@ +<?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\Files\ObjectStore; + +use OC\Files\ObjectStore\StorageObjectStore; +use OC\Files\Storage\Temporary; +use OCP\Files\ObjectStore\IObjectStore; +use Test\Files\Storage\StoragesTestCase; + +/** + * @group DB + */ +class ObjectStoreStoragesDifferentBucketTest extends StoragesTestCase { + /** + * @var IObjectStore + */ + private $objectStore1; + + /** + * @var IObjectStore + */ + private $objectStore2; + + protected function setUp(): void { + parent::setUp(); + + $baseStorage1 = new Temporary(); + $this->objectStore1 = new StorageObjectStore($baseStorage1); + $config['objectstore'] = $this->objectStore1; + $this->storage1 = new ObjectStoreStorageOverwrite($config); + + $baseStorage2 = new Temporary(); + $this->objectStore2 = new StorageObjectStore($baseStorage2); + $config['objectstore'] = $this->objectStore2; + $this->storage2 = new ObjectStoreStorageOverwrite($config); + } +} diff --git a/tests/lib/Files/ObjectStore/ObjectStoreStoragesSameBucketTest.php b/tests/lib/Files/ObjectStore/ObjectStoreStoragesSameBucketTest.php new file mode 100644 index 00000000000..4e42668cd3f --- /dev/null +++ b/tests/lib/Files/ObjectStore/ObjectStoreStoragesSameBucketTest.php @@ -0,0 +1,35 @@ +<?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\Files\ObjectStore; + +use OC\Files\ObjectStore\StorageObjectStore; +use OC\Files\Storage\Temporary; +use OCP\Files\ObjectStore\IObjectStore; +use Test\Files\Storage\StoragesTestCase; + +/** + * @group DB + */ +class ObjectStoreStoragesSameBucketTest extends StoragesTestCase { + /** + * @var IObjectStore + */ + private $objectStore; + + protected function setUp(): void { + parent::setUp(); + + $baseStorage = new Temporary(); + $this->objectStore = new StorageObjectStore($baseStorage); + $config['objectstore'] = $this->objectStore; + // storage1 and storage2 share the same object store. + $this->storage1 = new ObjectStoreStorageOverwrite($config); + $this->storage2 = new ObjectStoreStorageOverwrite($config); + } +} diff --git a/tests/lib/Files/ObjectStore/ObjectStoreTest.php b/tests/lib/Files/ObjectStore/ObjectStoreTestCase.php index c5580e4a2bf..03e7b9545e0 100644 --- a/tests/lib/Files/ObjectStore/ObjectStoreTest.php +++ b/tests/lib/Files/ObjectStore/ObjectStoreTestCase.php @@ -1,35 +1,23 @@ <?php /** - * @copyright Copyright (c) 2016 Robin Appelman <robin@icewind.nl> - * - * @license GNU AGPL version 3 or any later version - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Files\ObjectStore; +use OCP\Files\ObjectStore\IObjectStore; use Test\TestCase; -abstract class ObjectStoreTest extends TestCase { +abstract class ObjectStoreTestCase extends TestCase { /** @var string[] */ private $cleanup = []; + private $instance = null; + /** - * @return \OCP\Files\ObjectStore\IObjectStore + * @return IObjectStore */ abstract protected function getInstance(); @@ -37,13 +25,20 @@ abstract class ObjectStoreTest extends TestCase { $this->cleanup[] = $urn; } - public function tearDown(): void { - parent::tearDown(); + public function setUp(): void { + parent::setUp(); - $instance = $this->getInstance(); - foreach ($this->cleanup as $urn) { - $instance->deleteObject($urn); + $this->instance = $this->getInstance(); + } + + public function tearDown(): void { + if ($this->instance) { + foreach ($this->cleanup as $urn) { + $this->instance->deleteObject($urn); + } } + + parent::tearDown(); } protected function stringToStream($data) { @@ -53,7 +48,7 @@ abstract class ObjectStoreTest extends TestCase { return $stream; } - public function testWriteRead() { + public function testWriteRead(): void { $stream = $this->stringToStream('foobar'); $instance = $this->getInstance(); @@ -66,7 +61,7 @@ abstract class ObjectStoreTest extends TestCase { $this->assertEquals('foobar', stream_get_contents($result)); } - public function testDelete() { + public function testDelete(): void { $stream = $this->stringToStream('foobar'); $instance = $this->getInstance(); @@ -85,7 +80,7 @@ abstract class ObjectStoreTest extends TestCase { } } - public function testReadNonExisting() { + public function testReadNonExisting(): void { $instance = $this->getInstance(); try { @@ -97,7 +92,7 @@ abstract class ObjectStoreTest extends TestCase { } } - public function testDeleteNonExisting() { + public function testDeleteNonExisting(): void { $instance = $this->getInstance(); try { @@ -109,7 +104,7 @@ abstract class ObjectStoreTest extends TestCase { } } - public function testExists() { + public function testExists(): void { $stream = $this->stringToStream('foobar'); $instance = $this->getInstance(); @@ -124,7 +119,7 @@ abstract class ObjectStoreTest extends TestCase { $this->assertFalse($instance->objectExists('2')); } - public function testCopy() { + public function testCopy(): void { $this->cleanupAfter('source'); $this->cleanupAfter('target'); @@ -143,7 +138,7 @@ abstract class ObjectStoreTest extends TestCase { $this->assertEquals('foobar', stream_get_contents($instance->readObject('target'))); } - public function testFseekSize() { + public function testFseekSize(): void { $instance = $this->getInstance(); $textFile = \OC::$SERVERROOT . '/tests/data/lorem.txt'; diff --git a/tests/lib/Files/ObjectStore/PrimaryObjectStoreConfigTest.php b/tests/lib/Files/ObjectStore/PrimaryObjectStoreConfigTest.php new file mode 100644 index 00000000000..b60b7ca4f83 --- /dev/null +++ b/tests/lib/Files/ObjectStore/PrimaryObjectStoreConfigTest.php @@ -0,0 +1,285 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2025 Robin Appelman <robin@icewind.nl> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace lib\Files\ObjectStore; + +use OC\Files\ObjectStore\PrimaryObjectStoreConfig; +use OC\Files\ObjectStore\StorageObjectStore; +use OCP\App\IAppManager; +use OCP\IConfig; +use OCP\IUser; +use PHPUnit\Framework\MockObject\MockObject; +use Test\TestCase; + +class PrimaryObjectStoreConfigTest extends TestCase { + private array $systemConfig = []; + private array $userConfig = []; + private IConfig&MockObject $config; + private IAppManager&MockObject $appManager; + private PrimaryObjectStoreConfig $objectStoreConfig; + + protected function setUp(): void { + parent::setUp(); + + $this->systemConfig = []; + $this->config = $this->createMock(IConfig::class); + $this->appManager = $this->createMock(IAppManager::class); + $this->config->method('getSystemValue') + ->willReturnCallback(function ($key, $default = '') { + if (isset($this->systemConfig[$key])) { + return $this->systemConfig[$key]; + } else { + return $default; + } + }); + $this->config->method('getUserValue') + ->willReturnCallback(function ($userId, $appName, $key, $default = '') { + if (isset($this->userConfig[$userId][$appName][$key])) { + return $this->userConfig[$userId][$appName][$key]; + } else { + return $default; + } + }); + $this->config->method('setUserValue') + ->willReturnCallback(function ($userId, $appName, $key, $value) { + $this->userConfig[$userId][$appName][$key] = $value; + }); + + $this->objectStoreConfig = new PrimaryObjectStoreConfig($this->config, $this->appManager); + } + + private function getUser(string $uid): IUser { + $user = $this->createMock(IUser::class); + $user->method('getUID') + ->willReturn($uid); + return $user; + } + + private function setConfig(string $key, $value) { + $this->systemConfig[$key] = $value; + } + + public function testNewUserGetsDefault() { + $this->setConfig('objectstore', [ + 'default' => 'server1', + 'server1' => [ + 'class' => StorageObjectStore::class, + 'arguments' => [ + 'host' => 'server1', + ], + ], + ]); + + $result = $this->objectStoreConfig->getObjectStoreConfigForUser($this->getUser('test')); + $this->assertEquals('server1', $result['arguments']['host']); + + $this->assertEquals('server1', $this->config->getUserValue('test', 'homeobjectstore', 'objectstore', null)); + } + + public function testExistingUserKeepsStorage() { + // setup user with `server1` as storage + $this->testNewUserGetsDefault(); + + $this->setConfig('objectstore', [ + 'default' => 'server2', + 'server1' => [ + 'class' => StorageObjectStore::class, + 'arguments' => [ + 'host' => 'server1', + ], + ], + 'server2' => [ + 'class' => StorageObjectStore::class, + 'arguments' => [ + 'host' => 'server2', + ], + ], + ]); + + $result = $this->objectStoreConfig->getObjectStoreConfigForUser($this->getUser('test')); + $this->assertEquals('server1', $result['arguments']['host']); + + $this->assertEquals('server1', $this->config->getUserValue('test', 'homeobjectstore', 'objectstore', null)); + + $result = $this->objectStoreConfig->getObjectStoreConfigForUser($this->getUser('other-user')); + $this->assertEquals('server2', $result['arguments']['host']); + } + + public function testNestedAliases() { + $this->setConfig('objectstore', [ + 'default' => 'a1', + 'a1' => 'a2', + 'a2' => 'server1', + 'server1' => [ + 'class' => StorageObjectStore::class, + 'arguments' => [ + 'host' => 'server1', + ], + ], + ]); + $this->assertEquals('server1', $this->objectStoreConfig->resolveAlias('default')); + } + + public function testMultibucketChangedConfig() { + $this->setConfig('objectstore', [ + 'default' => 'server1', + 'server1' => [ + 'class' => StorageObjectStore::class, + 'arguments' => [ + 'host' => 'server1', + 'multibucket' => true, + 'num_buckets' => 8, + 'bucket' => 'bucket-' + ], + ], + ]); + + $result = $this->objectStoreConfig->getObjectStoreConfigForUser($this->getUser('test')); + $this->assertEquals('server1', $result['arguments']['host']); + $this->assertEquals('bucket-7', $result['arguments']['bucket']); + + $this->setConfig('objectstore', [ + 'default' => 'server1', + 'server1' => [ + 'class' => StorageObjectStore::class, + 'arguments' => [ + 'host' => 'server1', + 'multibucket' => true, + 'num_buckets' => 64, + 'bucket' => 'bucket-' + ], + ], + ]); + + $result = $this->objectStoreConfig->getObjectStoreConfigForUser($this->getUser('test')); + $this->assertEquals('server1', $result['arguments']['host']); + $this->assertEquals('bucket-7', $result['arguments']['bucket']); + + $result = $this->objectStoreConfig->getObjectStoreConfigForUser($this->getUser('test-foo')); + $this->assertEquals('server1', $result['arguments']['host']); + $this->assertEquals('bucket-40', $result['arguments']['bucket']); + + $this->setConfig('objectstore', [ + 'default' => 'server2', + 'server1' => [ + 'class' => StorageObjectStore::class, + 'arguments' => [ + 'host' => 'server1', + 'multibucket' => true, + 'num_buckets' => 64, + 'bucket' => 'bucket-' + ], + ], + 'server2' => [ + 'class' => StorageObjectStore::class, + 'arguments' => [ + 'host' => 'server2', + 'multibucket' => true, + 'num_buckets' => 16, + 'bucket' => 'bucket-' + ], + ], + ]); + + $result = $this->objectStoreConfig->getObjectStoreConfigForUser($this->getUser('test')); + $this->assertEquals('server1', $result['arguments']['host']); + $this->assertEquals('bucket-7', $result['arguments']['bucket']); + + $result = $this->objectStoreConfig->getObjectStoreConfigForUser($this->getUser('test-bar')); + $this->assertEquals('server2', $result['arguments']['host']); + $this->assertEquals('bucket-4', $result['arguments']['bucket']); + } + + public function testMultibucketOldConfig() { + $this->setConfig('objectstore_multibucket', [ + 'class' => StorageObjectStore::class, + 'arguments' => [ + 'host' => 'server1', + 'multibucket' => true, + 'num_buckets' => 8, + 'bucket' => 'bucket-' + ], + ]); + $configs = $this->objectStoreConfig->getObjectStoreConfigs(); + $this->assertEquals([ + 'default' => 'server1', + 'root' => 'server1', + 'server1' => [ + 'class' => StorageObjectStore::class, + 'arguments' => [ + 'host' => 'server1', + 'multibucket' => true, + 'num_buckets' => 8, + 'bucket' => 'bucket-' + ], + ], + ], $configs); + } + + public function testSingleObjectStore() { + $this->setConfig('objectstore', [ + 'class' => StorageObjectStore::class, + 'arguments' => [ + 'host' => 'server1', + ], + ]); + $configs = $this->objectStoreConfig->getObjectStoreConfigs(); + $this->assertEquals([ + 'default' => 'server1', + 'root' => 'server1', + 'server1' => [ + 'class' => StorageObjectStore::class, + 'arguments' => [ + 'host' => 'server1', + 'multibucket' => false, + ], + ], + ], $configs); + } + + public function testRoot() { + $this->setConfig('objectstore', [ + 'default' => 'server1', + 'server1' => [ + 'class' => StorageObjectStore::class, + 'arguments' => [ + 'host' => 'server1', + ], + ], + 'server2' => [ + 'class' => StorageObjectStore::class, + 'arguments' => [ + 'host' => 'server2', + ], + ], + ]); + + $result = $this->objectStoreConfig->getObjectStoreConfigForRoot(); + $this->assertEquals('server1', $result['arguments']['host']); + + $this->setConfig('objectstore', [ + 'default' => 'server1', + 'root' => 'server2', + 'server1' => [ + 'class' => StorageObjectStore::class, + 'arguments' => [ + 'host' => 'server1', + ], + ], + 'server2' => [ + 'class' => StorageObjectStore::class, + 'arguments' => [ + 'host' => 'server2', + ], + ], + ]); + + $result = $this->objectStoreConfig->getObjectStoreConfigForRoot(); + $this->assertEquals('server2', $result['arguments']['host']); + } +} diff --git a/tests/lib/Files/ObjectStore/S3Test.php b/tests/lib/Files/ObjectStore/S3Test.php index fd451dc3c01..2915ada0aab 100644 --- a/tests/lib/Files/ObjectStore/S3Test.php +++ b/tests/lib/Files/ObjectStore/S3Test.php @@ -1,31 +1,19 @@ <?php + /** - * @copyright Copyright (c) 2016 Robin Appelman <robin@icewind.nl> - * - * @license GNU AGPL version 3 or any later version - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Files\ObjectStore; use Icewind\Streams\Wrapper; use OC\Files\ObjectStore\S3; +use OCP\IConfig; +use OCP\Server; class MultiPartUploadS3 extends S3 { - public function writeObject($urn, $stream, string $mimetype = null) { + public function writeObject($urn, $stream, ?string $mimetype = null) { $this->getConnection()->upload($this->bucket, $urn, $stream, 'private', [ 'mup_threshold' => 1, ]); @@ -59,7 +47,7 @@ class NonSeekableStream extends Wrapper { /** * @group PRIMARY-s3 */ -class S3Test extends ObjectStoreTest { +class S3Test extends ObjectStoreTestCase { public function setUp(): void { parent::setUp(); $s3 = $this->getInstance(); @@ -67,7 +55,7 @@ class S3Test extends ObjectStoreTest { } protected function getInstance() { - $config = \OC::$server->getConfig()->getSystemValue('objectstore'); + $config = Server::get(IConfig::class)->getSystemValue('objectstore'); if (!is_array($config) || $config['class'] !== S3::class) { $this->markTestSkipped('objectstore not configured for s3'); } @@ -75,7 +63,7 @@ class S3Test extends ObjectStoreTest { return new S3($config['arguments']); } - public function testUploadNonSeekable() { + public function testUploadNonSeekable(): void { $this->cleanupAfter('multiparttest'); $s3 = $this->getInstance(); @@ -87,7 +75,7 @@ class S3Test extends ObjectStoreTest { $this->assertEquals(file_get_contents(__FILE__), stream_get_contents($result)); } - public function testSeek() { + public function testSeek(): void { $this->cleanupAfter('seek'); $data = file_get_contents(__FILE__); @@ -106,29 +94,30 @@ class S3Test extends ObjectStoreTest { } public function assertNoUpload($objectUrn) { + /** @var \OC\Files\ObjectStore\S3 */ $s3 = $this->getInstance(); $s3client = $s3->getConnection(); $uploads = $s3client->listMultipartUploads([ 'Bucket' => $s3->getBucket(), 'Prefix' => $objectUrn, ]); - $this->assertArrayNotHasKey('Uploads', $uploads); + $this->assertArrayNotHasKey('Uploads', $uploads, 'Assert is not uploaded'); } - public function testEmptyUpload() { + public function testEmptyUpload(): void { $s3 = $this->getInstance(); - $emptyStream = fopen("php://memory", "r"); - fwrite($emptyStream, null); + $emptyStream = fopen('php://memory', 'r'); + fwrite($emptyStream, ''); $s3->writeObject('emptystream', $emptyStream); $this->assertNoUpload('emptystream'); - $this->assertTrue($s3->objectExists('emptystream')); + $this->assertTrue($s3->objectExists('emptystream'), 'Object exists on S3'); $thrown = false; try { - self::assertFalse($s3->readObject('emptystream')); + self::assertFalse($s3->readObject('emptystream'), 'Reading empty stream object should return false'); } catch (\Exception $e) { // An exception is expected here since 0 byte files are wrapped // to be read from an empty memory stream in the ObjectStoreStorage @@ -140,14 +129,18 @@ class S3Test extends ObjectStoreTest { } /** File size to upload in bytes */ - public function dataFileSizes() { + public static function dataFileSizes(): array { return [ [1000000], [2000000], [5242879], [5242880], [5242881], [10000000] ]; } - /** @dataProvider dataFileSizes */ - public function testFileSizes($size) { + #[\PHPUnit\Framework\Attributes\DataProvider('dataFileSizes')] + public function testFileSizes($size): void { + if (str_starts_with(PHP_VERSION, '8.3') && getenv('CI')) { + $this->markTestSkipped('Test is unreliable and skipped on 8.3'); + } + $this->cleanupAfter('testfilesizes'); $s3 = $this->getInstance(); @@ -163,20 +156,20 @@ class S3Test extends ObjectStoreTest { $s3->writeObject('testfilesizes', $sourceStream); $this->assertNoUpload('testfilesizes'); - self::assertTrue($s3->objectExists('testfilesizes')); + self::assertTrue($s3->objectExists('testfilesizes'), 'Object exists on S3'); $result = $s3->readObject('testfilesizes'); // compare first 100 bytes - self::assertEquals(str_repeat('A', 100), fread($result, 100)); + self::assertEquals(str_repeat('A', 100), fread($result, 100), 'Compare first 100 bytes'); - // compare 100 bytes + // compare last 100 bytes fseek($result, $size - 100); - self::assertEquals(str_repeat('A', 100), fread($result, 100)); + self::assertEquals(str_repeat('A', 100), fread($result, 100), 'Compare last 100 bytes'); // end of file reached fseek($result, $size); - self::assertTrue(feof($result)); + self::assertTrue(feof($result), 'End of file reached'); $this->assertNoUpload('testfilesizes'); } diff --git a/tests/lib/Files/ObjectStore/SwiftTest.php b/tests/lib/Files/ObjectStore/SwiftTest.php index 1ea55a84628..3f919c0dd48 100644 --- a/tests/lib/Files/ObjectStore/SwiftTest.php +++ b/tests/lib/Files/ObjectStore/SwiftTest.php @@ -1,41 +1,35 @@ <?php + /** - * @copyright Copyright (c) 2016 Robin Appelman <robin@icewind.nl> - * - * @license GNU AGPL version 3 or any later version - * - * This program 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. - * - * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\Files\ObjectStore; use OC\Files\ObjectStore\Swift; +use OCP\Files\ObjectStore\IObjectStore; +use OCP\IConfig; +use OCP\Server; /** * @group PRIMARY-swift */ -class SwiftTest extends ObjectStoreTest { +class SwiftTest extends ObjectStoreTestCase { /** - * @return \OCP\Files\ObjectStore\IObjectStore + * @return IObjectStore */ protected function getInstance() { - $config = \OC::$server->getConfig()->getSystemValue('objectstore'); + $config = Server::get(IConfig::class)->getSystemValue('objectstore'); if (!is_array($config) || $config['class'] !== 'OC\\Files\\ObjectStore\\Swift') { $this->markTestSkipped('objectstore not configured for swift'); } return new Swift($config['arguments']); } + + public function testFseekSize(): void { + $this->markTestSkipped('Swift does not support seeking at the moment'); + } } |