diff --git a/sshfs/spec.py b/sshfs/spec.py index f8f5940..191bfa6 100644 --- a/sshfs/spec.py +++ b/sshfs/spec.py @@ -8,6 +8,8 @@ from typing import Optional import asyncssh +from asyncssh import ProcessError +from asyncssh.misc import ChannelOpenError from asyncssh.sftp import SFTPOpUnsupported from fsspec.asyn import ( AsyncFileSystem, @@ -343,19 +345,20 @@ async def _rm(self, path, recursive=False, **kwargs): @wrap_exceptions async def _checksum(self, path): - system = await self._get_system() + try: + system = await self._get_system() + except (ChannelOpenError, ProcessError): + system = "Linux" + if system == "Linux": - command = "md5sum" + result = await self._execute(f"md5sum {shlex.quote(path)}") part = 0 elif system == "Darwin": - command = "md5" + result = await self._execute(f"md5 {shlex.quote(path)}") part = -1 else: raise ValueError(f"{system!r} doesn't support checksum operation") - cmd = f"{command} {shlex.quote(path)}" - result = await self._execute(cmd) - parts = result.stdout.strip().split() assert len(parts) >= 1 diff --git a/tests/test_sshfs.py b/tests/test_sshfs.py index 141baf7..d7583b4 100644 --- a/tests/test_sshfs.py +++ b/tests/test_sshfs.py @@ -1,3 +1,4 @@ +import asyncio import hashlib import posixpath import secrets @@ -10,6 +11,7 @@ import fsspec import pytest +from asyncssh.misc import ChannelOpenError from asyncssh.sftp import SFTPAttrs, SFTPFailure from importlib_metadata import entry_points @@ -239,6 +241,25 @@ def test_checksum(fs, remote_dir): assert fs.checksum(remote_dir + "/a.txt") == checksum +def test_checksum_falls_back_to_md5sum_when_uname_session_fails(): + checksum = "0123456789abcdef0123456789abcdef" + calls = [] + + class DummyFS: + async def _get_system(self): + raise ChannelOpenError(None, None) + + async def _execute(self, command): + calls.append(command) + return SimpleNamespace(stdout=f"{checksum} /tmp/a.txt\n") + + assert ( + asyncio.run(SSHFileSystem._checksum(DummyFS(), "/tmp/a.txt")) + == checksum + ) + assert calls == ["md5sum /tmp/a.txt"] + + def test_ls(fs, remote_dir): fs.mkdir(remote_dir + "dir/") files = set()