Skip to content

Commit 310c307

Browse files
icewind1991artonge
authored andcommitted
test: add some minimal testing for metadata storage
Signed-off-by: Robin Appelman <[email protected]> [skip ci]
1 parent a2584c6 commit 310c307

File tree

4 files changed

+114
-4
lines changed

4 files changed

+114
-4
lines changed

lib/private/FilesMetadata/FilesMetadataManager.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,10 @@ public function refreshMetadata(
8181
try {
8282
/** @var FilesMetadata $metadata */
8383
$metadata = $this->metadataRequestService->getMetadataFromFileId($node->getId());
84-
$metadata->setStorageId($storageId);
8584
} catch (FilesMetadataNotFoundException) {
86-
$metadata = new FilesMetadata($node->getId(), $storageId);
85+
$metadata = new FilesMetadata($node->getId());
8786
}
87+
$metadata->setStorageId($storageId);
8888

8989
// if $process is LIVE, we enforce LIVE
9090
// if $process is NAMED, we go NAMED

lib/private/FilesMetadata/Model/FilesMetadata.php

+9
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class FilesMetadata implements IFilesMetadata {
2727
private bool $updated = false;
2828
private int $lastUpdate = 0;
2929
private string $syncToken = '';
30+
private ?int $storageId = null;
3031

3132
public function __construct(
3233
private int $fileId = 0
@@ -46,6 +47,14 @@ public function getStorageId(): ?int {
4647
return $this->storageId;
4748
}
4849

50+
/**
51+
* Set which storage the file this metadata belongs to.
52+
*
53+
* This helps with sharded filecache setups to know where to store the metadata
54+
*
55+
* @param int $storageId
56+
* @return void
57+
*/
4958
public function setStorageId(int $storageId): void {
5059
$this->storageId = $storageId;
5160
}

lib/private/FilesMetadata/Service/MetadataRequestService.php

+5-2
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,11 @@ public function __construct(
2929
}
3030

3131
private function getStorageId(IFilesMetadata $filesMetadata): int {
32-
if ($filesMetadata instanceof FilesMetadata && $filesMetadata->getStorageId()) {
33-
return $filesMetadata->getStorageId();
32+
if ($filesMetadata instanceof FilesMetadata) {
33+
$storage = $filesMetadata->getStorageId();
34+
if ($storage) {
35+
return $storage;
36+
}
3437
}
3538
// all code paths that lead to saving metadata *should* have the storage id set
3639
// this fallback is there just in case
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
/**
5+
* SPDX-FileCopyrightText: 2024 Robin Appelman <[email protected]>
6+
* SPDX-License-Identifier: AGPL-3.0-or-later
7+
*/
8+
9+
namespace Test\FilesMetadata;
10+
11+
use OC\BackgroundJob\JobList;
12+
use OC\Files\Storage\Temporary;
13+
use OC\FilesMetadata\FilesMetadataManager;
14+
use OC\FilesMetadata\Service\IndexRequestService;
15+
use OC\FilesMetadata\Service\MetadataRequestService;
16+
use OCP\EventDispatcher\Event;
17+
use OCP\EventDispatcher\IEventDispatcher;
18+
use OCP\Files\Folder;
19+
use OCP\Files\IRootFolder;
20+
use OCP\FilesMetadata\AMetadataEvent;
21+
use OCP\IAppConfig;
22+
use OCP\IDBConnection;
23+
use OCP\Server;
24+
use Psr\Log\LoggerInterface;
25+
use Test\TestCase;
26+
use Test\Traits\MountProviderTrait;
27+
use Test\Traits\UserTrait;
28+
29+
/**
30+
* @group DB
31+
*/
32+
class FilesMetadataManagerTest extends TestCase {
33+
use UserTrait;
34+
use MountProviderTrait;
35+
36+
private IEventDispatcher $eventDispatcher;
37+
private JobList $jobList;
38+
private IAppConfig $appConfig;
39+
private LoggerInterface $logger;
40+
private MetadataRequestService $metadataRequestService;
41+
private IndexRequestService $indexRequestService;
42+
private FilesMetadataManager $manager;
43+
private IDBConnection $connection;
44+
private Folder $userFolder;
45+
private array $metadata = [];
46+
47+
protected function setUp(): void {
48+
parent::setUp();
49+
50+
$this->jobList = $this->createMock(JobList::class);
51+
$this->eventDispatcher = $this->createMock(IEventDispatcher::class);
52+
$this->eventDispatcher->method('dispatchTyped')->willReturnCallback(function (Event $event) {
53+
if ($event instanceof AMetadataEvent) {
54+
$name = $event->getNode()->getName();
55+
if (isset($this->metadata[$name])) {
56+
$meta = $event->getMetadata();
57+
foreach ($this->metadata[$name] as $key => $value) {
58+
$meta->setString($key, $value);
59+
}
60+
}
61+
}
62+
});
63+
$this->appConfig = $this->createMock(IAppConfig::class);
64+
$this->logger = $this->createMock(LoggerInterface::class);
65+
66+
$this->connection = Server::get(IDBConnection::class);
67+
$this->metadataRequestService = new MetadataRequestService($this->connection, $this->logger);
68+
$this->indexRequestService = new IndexRequestService($this->connection, $this->logger);
69+
$this->manager = new FilesMetadataManager(
70+
$this->eventDispatcher,
71+
$this->jobList,
72+
$this->appConfig,
73+
$this->logger,
74+
$this->metadataRequestService,
75+
$this->indexRequestService,
76+
);
77+
78+
$this->createUser('metatest', '');
79+
$this->registerMount('metatest', new Temporary([]), '/metatest');
80+
81+
$rootFolder = Server::get(IRootFolder::class);
82+
$this->userFolder = $rootFolder->getUserFolder('metatest');
83+
}
84+
85+
public function testRefreshMetadata(): void {
86+
$this->metadata['test.txt'] = [
87+
'istest' => 'yes'
88+
];
89+
$file = $this->userFolder->newFile('test.txt', 'test');
90+
$stored = $this->manager->refreshMetadata($file);
91+
$this->assertEquals($file->getId(), $stored->getFileId());
92+
$this->assertEquals('yes', $stored->getString('istest'));
93+
94+
$retrieved = $this->manager->getMetadata($file->getId());
95+
$this->assertEquals($file->getId(), $retrieved->getFileId());
96+
$this->assertEquals('yes', $retrieved->getString('istest'));
97+
}
98+
}

0 commit comments

Comments
 (0)