From 508995511c70c525fe0c40269510dee35e2ef5f1 Mon Sep 17 00:00:00 2001 From: Josh Date: Sun, 19 Jul 2026 12:01:20 -0400 Subject: [PATCH 1/2] test(files): make watcher propagation regression test deterministic - The existing watcher regression test could pass if the cached mtime and request timestamp land in the same second. - The test now uses a fixed root mtime and etag before accessing the folder. - Checking the etag as well is valid, because an unwanted propagation can invalidate ancestor etags. Assisted-by: GitHubCopilot:GPT-5 Signed-off-by: Josh --- tests/lib/Files/ViewTest.php | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/tests/lib/Files/ViewTest.php b/tests/lib/Files/ViewTest.php index c21bf6fc40c9d..8c824a492260b 100644 --- a/tests/lib/Files/ViewTest.php +++ b/tests/lib/Files/ViewTest.php @@ -473,23 +473,33 @@ public function testWatcherDoesNotPropagateWhenStorageMtimeUnchanged(): void { $rootView = new View(''); - // Note the root mtime right after the initial scan. - $rootMtimeBefore = $storage->getCache()->get('')['mtime']; + // Use an mtime that cannot accidentally equal the current timestamp. This makes + // the test fail reliably if propagateChange() is called during this request. + $rootEntry = $storage->getCache()->get(''); + $storage->getCache()->update($rootEntry->getId(), [ + 'mtime' => 1, + 'etag' => 'unchanged-root-etag', + ]); // Access a subfolder. The watcher will fire (hasUpdated always returns true), // but the scanner leaves the cached metadata for 'folder' unchanged. // getCacheEntry must therefore NOT call propagateChange('folder', time()), - // which would update the root entry's mtime to the current timestamp. + // which would update the root entry's mtime and etag. $rootView->getFileInfo('folder'); - // Read the root mtime directly from the cache to avoid triggering another watcher cycle. - $rootMtimeAfter = $storage->getCache()->get('')['mtime']; + // Read the root entry directly from the cache to avoid triggering another watcher cycle. + $rootEntryAfter = $storage->getCache()->get(''); - $this->assertEquals( - $rootMtimeBefore, - $rootMtimeAfter, - 'Root folder mtime must not be updated when the watcher fires but cached metadata has not changed' + $this->assertSame( + 1, + $rootEntryAfter->getMTime(), + 'Root folder mtime must not change when the watcher finds no metadata change' ); + $this->assertSame( + 'unchanged-root-etag', + $rootEntryAfter->getEtag(), + 'Root folder etag must not change when the watcher finds no metadata change' + ); } public function testCopyBetweenStorageNoCross(): void { From db628034bd65b06750a090dc6296642b95506e15 Mon Sep 17 00:00:00 2001 From: Josh Date: Mon, 20 Jul 2026 11:22:08 -0400 Subject: [PATCH 2/2] chore(view): update ViewTest for php-cs/rector Signed-off-by: Josh --- tests/lib/Files/ViewTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/lib/Files/ViewTest.php b/tests/lib/Files/ViewTest.php index 8c824a492260b..3b8718564020e 100644 --- a/tests/lib/Files/ViewTest.php +++ b/tests/lib/Files/ViewTest.php @@ -493,13 +493,13 @@ public function testWatcherDoesNotPropagateWhenStorageMtimeUnchanged(): void { $this->assertSame( 1, $rootEntryAfter->getMTime(), - 'Root folder mtime must not change when the watcher finds no metadata change' + 'Root folder mtime must not change when the watcher finds no metadata change', ); $this->assertSame( 'unchanged-root-etag', $rootEntryAfter->getEtag(), - 'Root folder etag must not change when the watcher finds no metadata change' - ); + 'Root folder etag must not change when the watcher finds no metadata change', + ); } public function testCopyBetweenStorageNoCross(): void {