fix(watcher): auto-polling sur mounts reseau (NFS/SMB) pour maj temps reel des recents
CI / lint (push) Failing after 25s
CI / test (push) Skipped
CI / build (push) Skipped
CI / e2e (push) Skipped
CI / security (push) Successful in 28s
Desktop Build / build-windows (push) Canceled after 0s
Desktop Build / build-linux (push) Canceled after 0s
CI / lint (push) Failing after 25s
CI / test (push) Skipped
CI / build (push) Skipped
CI / e2e (push) Skipped
CI / security (push) Successful in 28s
Desktop Build / build-windows (push) Canceled after 0s
Desktop Build / build-linux (push) Canceled after 0s
inotify ne voit pas les ecritures faites depuis d'autres clients NFS (Obsidian sur Windows), donc index_updated n'etait jamais emis et la section Recent du sidebar ne se rafraichissait pas. Detection du fstype par vault via /proc/mounts -> PollingObserver (stat-based) sur mounts reseau, Observer natif conserve sur les mounts locaux.
This commit is contained in:
@@ -74,6 +74,80 @@ class TestIsRelevant:
|
||||
assert handler._is_relevant("/vault/Makefile") is True
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
# Network-mount detection (NFS/SMB → polling watcher required)
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
class TestNetworkMountDetection:
|
||||
MOUNTS = [
|
||||
"overlay / overlay rw 0 0",
|
||||
"server:/export/NFS/OBSIDIAN_DOC /vaults/Obsidian_IT nfs4 rw 0 0",
|
||||
"server:/export/home/bruno /vaults/bruno nfs4 rw 0 0",
|
||||
"dev/sda1 /data ext4 rw 0 0",
|
||||
"srv:/share /mnt/smb cifs rw 0 0",
|
||||
]
|
||||
|
||||
def test_nfs_mount_detected(self):
|
||||
from backend.watcher import find_mount_fstype
|
||||
ft = find_mount_fstype("/vaults/Obsidian_IT/note.md", self.MOUNTS)
|
||||
assert ft == "nfs4"
|
||||
|
||||
def test_nested_nfs_mount(self):
|
||||
from backend.watcher import find_mount_fstype
|
||||
ft = find_mount_fstype("/vaults/bruno/sub/dir", self.MOUNTS)
|
||||
assert ft == "nfs4"
|
||||
|
||||
def test_smb_mount_detected(self):
|
||||
from backend.watcher import find_mount_fstype
|
||||
ft = find_mount_fstype("/mnt/smb/file.md", self.MOUNTS)
|
||||
assert ft == "cifs"
|
||||
|
||||
def test_local_fs_not_network(self):
|
||||
from backend.watcher import find_mount_fstype
|
||||
ft = find_mount_fstype("/data/file.md", self.MOUNTS)
|
||||
assert ft == "ext4"
|
||||
|
||||
def test_unmatched_path_returns_empty(self):
|
||||
from backend.watcher import find_mount_fstype
|
||||
assert find_mount_fstype("/nowhere/file.md", self.MOUNTS) == ""
|
||||
|
||||
def test_longest_prefix_wins(self):
|
||||
from backend.watcher import find_mount_fstype
|
||||
lines = self.MOUNTS + ["tmpfs /vaults/Obsidian_IT/tmp tmpfs rw 0 0"]
|
||||
assert find_mount_fstype("/vaults/Obsidian_IT/tmp/x", lines) == "tmpfs"
|
||||
assert find_mount_fstype("/vaults/Obsidian_IT/other", lines) == "nfs4"
|
||||
|
||||
def test_escaped_space_in_mount_point(self):
|
||||
from backend.watcher import find_mount_fstype
|
||||
lines = ["srv:/x /vaults/My\\040Vault nfs rw 0 0"]
|
||||
assert find_mount_fstype("/vaults/My Vault/a.md", lines) == "nfs"
|
||||
|
||||
def test_is_network_mount_false_on_windows(self, monkeypatch):
|
||||
import backend.watcher as w
|
||||
monkeypatch.setattr(w.os, "name", "nt")
|
||||
assert w.is_network_mount("/vaults/x") is False
|
||||
|
||||
def test_watch_vault_uses_polling_for_network_mount(self, monkeypatch):
|
||||
"""_watch_vault must pick PollingObserver when is_network_mount is True."""
|
||||
import asyncio
|
||||
from unittest.mock import MagicMock
|
||||
import backend.watcher as w
|
||||
|
||||
watcher = w.VaultWatcher(on_file_change=MagicMock())
|
||||
monkeypatch.setattr(w, "is_network_mount", lambda p: True)
|
||||
mock_poll = MagicMock()
|
||||
monkeypatch.setattr(w, "PollingObserver", mock_poll)
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
loop.run_until_complete(
|
||||
watcher._watch_vault("NetVault", tmpdir, loop)
|
||||
)
|
||||
mock_poll.assert_called_once()
|
||||
assert "NetVault" in watcher.observers
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
# VaultWatcher (unit tests with mocks)
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
|
||||
Reference in New Issue
Block a user