]> source.dussan.org Git - nextcloud-server.git/commitdiff
test: add some minimal testing for metadata storage metadata-storage-id 48563/head
authorRobin Appelman <robin@icewind.nl>
Thu, 3 Oct 2024 16:05:43 +0000 (18:05 +0200)
committerRobin Appelman <robin@icewind.nl>
Thu, 7 Nov 2024 15:27:16 +0000 (16:27 +0100)
Signed-off-by: Robin Appelman <robin@icewind.nl>
lib/private/FilesMetadata/FilesMetadataManager.php
lib/private/FilesMetadata/Model/FilesMetadata.php
lib/private/FilesMetadata/Service/MetadataRequestService.php
tests/lib/FilesMetadata/FilesMetadataManagerTest.php [new file with mode: 0644]

index b0a08c4f119cdfacd2e648ced7af698266082615..4846799b3d46c6c28bb2c16408363dd6bdadb217 100644 (file)
@@ -81,10 +81,10 @@ class FilesMetadataManager implements IFilesMetadataManager {
                try {
                        /** @var FilesMetadata $metadata */
                        $metadata = $this->metadataRequestService->getMetadataFromFileId($node->getId());
-                       $metadata->setStorageId($storageId);
                } catch (FilesMetadataNotFoundException) {
-                       $metadata = new FilesMetadata($node->getId(), $storageId);
+                       $metadata = new FilesMetadata($node->getId());
                }
+               $metadata->setStorageId($storageId);
 
                // if $process is LIVE, we enforce LIVE
                // if $process is NAMED, we go NAMED
index d35e4a375e3a13a20fe395bb836346fcbcc89541..b66e1fe3711101b2911bb72bbe52018f45673a49 100644 (file)
@@ -27,10 +27,10 @@ class FilesMetadata implements IFilesMetadata {
        private bool $updated = false;
        private int $lastUpdate = 0;
        private string $syncToken = '';
+       private ?int $storageId = null;
 
        public function __construct(
                private int $fileId = 0,
-               private ?int $storageId = null,
        ) {
        }
 
@@ -47,6 +47,14 @@ class FilesMetadata implements IFilesMetadata {
                return $this->storageId;
        }
 
+       /**
+        * Set which storage the file this metadata belongs to.
+        *
+        * This helps with sharded filecache setups to know where to store the metadata
+        *
+        * @param int $storageId
+        * @return void
+        */
        public function setStorageId(int $storageId): void {
                $this->storageId = $storageId;
        }
index 4d36655cffaba40ac8ced1a9cc5802867464de2d..c308ae1c9c88f5299bf0e5fa2e80f75f93945087 100644 (file)
@@ -29,8 +29,11 @@ class MetadataRequestService {
        }
 
        private function getStorageId(IFilesMetadata $filesMetadata): int {
-               if ($filesMetadata instanceof FilesMetadata && $filesMetadata->getStorageId()) {
-                       return $filesMetadata->getStorageId();
+               if ($filesMetadata instanceof FilesMetadata) {
+                       $storage = $filesMetadata->getStorageId();
+                       if ($storage) {
+                               return $storage;
+                       }
                }
                // all code paths that lead to saving metadata *should* have the storage id set
                // this fallback is there just in case
diff --git a/tests/lib/FilesMetadata/FilesMetadataManagerTest.php b/tests/lib/FilesMetadata/FilesMetadataManagerTest.php
new file mode 100644 (file)
index 0000000..2f9edba
--- /dev/null
@@ -0,0 +1,98 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * SPDX-FileCopyrightText: 2024 Robin Appelman <robin@icewind.nl>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace Test\FilesMetadata;
+
+use OC\BackgroundJob\JobList;
+use OC\Files\Storage\Temporary;
+use OC\FilesMetadata\FilesMetadataManager;
+use OC\FilesMetadata\Service\IndexRequestService;
+use OC\FilesMetadata\Service\MetadataRequestService;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventDispatcher;
+use OCP\Files\Folder;
+use OCP\Files\IRootFolder;
+use OCP\FilesMetadata\AMetadataEvent;
+use OCP\IAppConfig;
+use OCP\IDBConnection;
+use OCP\Server;
+use Psr\Log\LoggerInterface;
+use Test\TestCase;
+use Test\Traits\MountProviderTrait;
+use Test\Traits\UserTrait;
+
+/**
+ * @group DB
+ */
+class FilesMetadataManagerTest extends TestCase {
+       use UserTrait;
+       use MountProviderTrait;
+
+       private IEventDispatcher $eventDispatcher;
+       private JobList $jobList;
+       private IAppConfig $appConfig;
+       private LoggerInterface $logger;
+       private MetadataRequestService $metadataRequestService;
+       private IndexRequestService $indexRequestService;
+       private FilesMetadataManager $manager;
+       private IDBConnection $connection;
+       private Folder $userFolder;
+       private array $metadata = [];
+
+       protected function setUp(): void {
+               parent::setUp();
+
+               $this->jobList = $this->createMock(JobList::class);
+               $this->eventDispatcher = $this->createMock(IEventDispatcher::class);
+               $this->eventDispatcher->method('dispatchTyped')->willReturnCallback(function (Event $event) {
+                       if ($event instanceof AMetadataEvent) {
+                               $name = $event->getNode()->getName();
+                               if (isset($this->metadata[$name])) {
+                                       $meta = $event->getMetadata();
+                                       foreach ($this->metadata[$name] as $key => $value) {
+                                               $meta->setString($key, $value);
+                                       }
+                               }
+                       }
+               });
+               $this->appConfig = $this->createMock(IAppConfig::class);
+               $this->logger = $this->createMock(LoggerInterface::class);
+
+               $this->connection = Server::get(IDBConnection::class);
+               $this->metadataRequestService = new MetadataRequestService($this->connection, $this->logger);
+               $this->indexRequestService = new IndexRequestService($this->connection, $this->logger);
+               $this->manager = new FilesMetadataManager(
+                       $this->eventDispatcher,
+                       $this->jobList,
+                       $this->appConfig,
+                       $this->logger,
+                       $this->metadataRequestService,
+                       $this->indexRequestService,
+               );
+
+               $this->createUser('metatest', '');
+               $this->registerMount('metatest', new Temporary([]), '/metatest');
+
+               $rootFolder = Server::get(IRootFolder::class);
+               $this->userFolder = $rootFolder->getUserFolder('metatest');
+       }
+
+       public function testRefreshMetadata(): void {
+               $this->metadata['test.txt'] = [
+                       'istest' => 'yes'
+               ];
+               $file = $this->userFolder->newFile('test.txt', 'test');
+               $stored = $this->manager->refreshMetadata($file);
+               $this->assertEquals($file->getId(), $stored->getFileId());
+               $this->assertEquals('yes', $stored->getString('istest'));
+
+               $retrieved = $this->manager->getMetadata($file->getId());
+               $this->assertEquals($file->getId(), $retrieved->getFileId());
+               $this->assertEquals('yes', $retrieved->getString('istest'));
+       }
+}