borgbackup / borgstore

experimental storage backend
Other
6 stars 2 forks source link

sftp backend test weirdness #61

Open ThomasWaldmann opened 1 day ago

ThomasWaldmann commented 1 day ago

It's not visible on github actions CI (we skip the sftp tests there), but the sftp backend / store test sometimes behaves weird:

Especially the test_scalability_big_values and the test_scalability_size seem to trigger test teardown errors (the .destroy is then failing, not cleaning up the sftp server and then causing more errors in the following tests).

When using pytest -v -rs -k "not big_values and not scalability_size", all works fine.

I am seeing this on macOS 15 with the default macOS sftp server on localhost.

Update: when using a remote sftp server (debian linux based, OpenSSH), it works.

ThomasWaldmann commented 1 day ago

Log output:

(borg-env) tw@MacBook-Pro borgstore % pytest -v -rs                                             
========================================================================== test session starts ===========================================================================
platform darwin -- Python 3.9.20, pytest-8.3.3, pluggy-1.5.0 -- /Users/tw/w/borg-env/bin/python3.9
cachedir: .pytest_cache
benchmark: 4.0.0 (defaults: timer=time.perf_counter disable_gc=False min_rounds=5 min_time=0.000005 max_time=1.0 calibration_precision=10 warmup=False warmup_iterations=100000)
rootdir: /Users/tw/w/borgstore
configfile: pyproject.toml
testpaths: tests
plugins: cov-5.0.0, benchmark-4.0.0, xdist-3.6.1
collected 129 items                                                                                                                                                      

tests/test_backends.py::test_file_url[file:///absolute/path-/absolute/path] PASSED                                                                                 [  0%]
tests/test_backends.py::test_file_url[file://relative/path-relative/path] PASSED                                                                                   [  1%]
tests/test_backends.py::test_sftp_url[sftp://username@hostname:2222/some/path-username-hostname-2222-/some/path] PASSED                                            [  2%]
tests/test_backends.py::test_sftp_url[sftp://username@hostname/some/path-username-hostname-0-/some/path] PASSED                                                    [  3%]
tests/test_backends.py::test_sftp_url[sftp://hostname/some/path-None-hostname-0-/some/path] PASSED                                                                 [  3%]
tests/test_backends.py::test_flat[posixfs_backend_created] PASSED                                                                                                  [  4%]
tests/test_backends.py::test_flat[sftp_backend_created] PASSED                                                                                                     [  5%]
tests/test_backends.py::test_flat[rclone_backend_created] PASSED                                                                                                   [  6%]
tests/test_backends.py::test_namespaced[posixfs_backend_created] PASSED                                                                                            [  6%]
tests/test_backends.py::test_namespaced[sftp_backend_created] PASSED                                                                                               [  7%]
tests/test_backends.py::test_namespaced[rclone_backend_created] PASSED                                                                                             [  8%]
tests/test_backends.py::test_invalid_name[posixfs_backend_created] PASSED                                                                                          [  9%]
tests/test_backends.py::test_invalid_name[sftp_backend_created] PASSED                                                                                             [ 10%]
tests/test_backends.py::test_invalid_name[rclone_backend_created] PASSED                                                                                           [ 10%]
tests/test_backends.py::test_list[posixfs_backend_created] PASSED                                                                                                  [ 11%]
tests/test_backends.py::test_list[sftp_backend_created] PASSED                                                                                                     [ 12%]
tests/test_backends.py::test_list[rclone_backend_created] PASSED                                                                                                   [ 13%]
tests/test_backends.py::test_list_temporary_item[posixfs_backend_created] PASSED                                                                                   [ 13%]
tests/test_backends.py::test_list_temporary_item[sftp_backend_created] PASSED                                                                                      [ 14%]
tests/test_backends.py::test_list_temporary_item[rclone_backend_created] PASSED                                                                                    [ 15%]
tests/test_backends.py::test_scalability_size[posixfs_backend_created-0] PASSED                                                                                    [ 16%]
tests/test_backends.py::test_scalability_size[posixfs_backend_created-1] PASSED                                                                                    [ 17%]
tests/test_backends.py::test_scalability_size[posixfs_backend_created-2] PASSED                                                                                    [ 17%]
tests/test_backends.py::test_scalability_size[posixfs_backend_created-3] PASSED                                                                                    [ 18%]
tests/test_backends.py::test_scalability_size[posixfs_backend_created-4] PASSED                                                                                    [ 19%]
tests/test_backends.py::test_scalability_size[posixfs_backend_created-5] PASSED                                                                                    [ 20%]
tests/test_backends.py::test_scalability_size[posixfs_backend_created-6] PASSED                                                                                    [ 20%]
tests/test_backends.py::test_scalability_size[posixfs_backend_created-7] PASSED                                                                                    [ 21%]
tests/test_backends.py::test_scalability_size[posixfs_backend_created-8] PASSED                                                                                    [ 22%]
tests/test_backends.py::test_scalability_size[sftp_backend_created-0] PASSED                                                                                       [ 23%]
tests/test_backends.py::test_scalability_size[sftp_backend_created-1] PASSED                                                                                       [ 24%]
tests/test_backends.py::test_scalability_size[sftp_backend_created-2] PASSED                                                                                       [ 24%]
tests/test_backends.py::test_scalability_size[sftp_backend_created-3] PASSED                                                                                       [ 25%]
tests/test_backends.py::test_scalability_size[sftp_backend_created-4] PASSED                                                                                       [ 26%]
tests/test_backends.py::test_scalability_size[sftp_backend_created-5] PASSED                                                                                       [ 27%]
tests/test_backends.py::test_scalability_size[sftp_backend_created-6] PASSED                                                                                       [ 27%]
tests/test_backends.py::test_scalability_size[sftp_backend_created-7] PASSED                                                                                       [ 28%]
tests/test_backends.py::test_scalability_size[sftp_backend_created-8] FAILED                                                                                       [ 29%]
tests/test_backends.py::test_scalability_size[sftp_backend_created-8] ERROR                                                                                        [ 29%]
tests/test_backends.py::test_scalability_size[rclone_backend_created-0] PASSED                                                                                     [ 30%]
tests/test_backends.py::test_scalability_size[rclone_backend_created-1] PASSED                                                                                     [ 31%]
tests/test_backends.py::test_scalability_size[rclone_backend_created-2] PASSED                                                                                     [ 31%]
tests/test_backends.py::test_scalability_size[rclone_backend_created-3] PASSED                                                                                     [ 32%]
tests/test_backends.py::test_scalability_size[rclone_backend_created-4] PASSED                                                                                     [ 33%]
tests/test_backends.py::test_scalability_size[rclone_backend_created-5] PASSED                                                                                     [ 34%]
tests/test_backends.py::test_scalability_size[rclone_backend_created-6] PASSED                                                                                     [ 34%]
tests/test_backends.py::test_scalability_size[rclone_backend_created-7] PASSED                                                                                     [ 35%]
tests/test_backends.py::test_scalability_size[rclone_backend_created-8] PASSED                                                                                     [ 36%]
tests/test_backends.py::test_load_partial[posixfs_backend_created] PASSED                                                                                          [ 37%]
tests/test_backends.py::test_load_partial[sftp_backend_created] FAILED                                                                                             [ 37%]
tests/test_backends.py::test_load_partial[rclone_backend_created] PASSED                                                                                           [ 38%]
tests/test_backends.py::test_already_exists[posixfs_backend_created] PASSED                                                                                        [ 39%]
tests/test_backends.py::test_already_exists[sftp_backend_created] FAILED                                                                                           [ 40%]
tests/test_backends.py::test_already_exists[rclone_backend_created] PASSED                                                                                         [ 41%]
tests/test_backends.py::test_does_not_exist[posixfs_backend_created] PASSED                                                                                        [ 41%]
tests/test_backends.py::test_does_not_exist[sftp_backend_created] FAILED                                                                                           [ 42%]
tests/test_backends.py::test_does_not_exist[rclone_backend_created] PASSED                                                                                         [ 43%]
tests/test_backends.py::test_must_be_open[posixfs_backend_created] PASSED                                                                                          [ 44%]
tests/test_backends.py::test_must_be_open[sftp_backend_created] FAILED                                                                                             [ 44%]
tests/test_backends.py::test_must_be_open[rclone_backend_created] PASSED                                                                                           [ 45%]
tests/test_backends.py::test_must_not_be_open[posixfs_backend_created] PASSED                                                                                      [ 46%]
tests/test_backends.py::test_must_not_be_open[sftp_backend_created] FAILED                                                                                         [ 47%]
tests/test_backends.py::test_must_not_be_open[rclone_backend_created] PASSED                                                                                       [ 48%]
tests/test_mstore.py::test_bucket_map_invalid[buckets0] PASSED                                                                                                     [ 48%]
tests/test_mstore.py::test_bucket_map_invalid[buckets1] PASSED                                                                                                     [ 49%]
tests/test_mstore.py::test_bucket_map_invalid[buckets2] PASSED                                                                                                     [ 50%]
tests/test_mstore.py::test_bucket_map_invalid[buckets3] PASSED                                                                                                     [ 51%]
tests/test_mstore.py::test_bucket_map_invalid[buckets4] PASSED                                                                                                     [ 51%]
tests/test_mstore.py::test_bucket_map_invalid[buckets5] PASSED                                                                                                     [ 52%]
tests/test_mstore.py::test_bucket_map_valid[buckets0-1] PASSED                                                                                                     [ 53%]
tests/test_mstore.py::test_bucket_map_valid[buckets1-1] PASSED                                                                                                     [ 54%]
tests/test_mstore.py::test_bucket_map_valid[buckets2-2] PASSED                                                                                                     [ 55%]
tests/test_mstore.py::test_bucket_map_valid[buckets3-2] PASSED                                                                                                     [ 55%]
tests/test_mstore.py::test_bucket_map_valid[buckets4-2] PASSED                                                                                                     [ 56%]
tests/test_mstore.py::test_bucket_map_valid[buckets5-1] PASSED                                                                                                     [ 57%]
tests/test_mstore.py::test_bucket_map_valid[buckets6-3] PASSED                                                                                                     [ 58%]
tests/test_mstore.py::test_lookup_bucket[buckets0-0-store0] PASSED                                                                                                 [ 58%]
tests/test_mstore.py::test_lookup_bucket[buckets1-255-store1] PASSED                                                                                               [ 59%]
tests/test_mstore.py::test_lookup_bucket[buckets2-0-store2] PASSED                                                                                                 [ 60%]
tests/test_mstore.py::test_lookup_bucket[buckets3-127-store3] PASSED                                                                                               [ 61%]
tests/test_mstore.py::test_lookup_bucket[buckets4-128-store4] PASSED                                                                                               [ 62%]
tests/test_mstore.py::test_lookup_bucket[buckets5-255-store5] PASSED                                                                                               [ 62%]
tests/test_mstore.py::test_lookup_bucket[buckets6-0-store6] PASSED                                                                                                 [ 63%]
tests/test_mstore.py::test_lookup_bucket[buckets7-127-store7] PASSED                                                                                               [ 64%]
tests/test_mstore.py::test_lookup_bucket[buckets8-128-store8] PASSED                                                                                               [ 65%]
tests/test_mstore.py::test_lookup_bucket[buckets9-255-store9] PASSED                                                                                               [ 65%]
tests/test_mstore.py::test_list PASSED                                                                                                                             [ 66%]
tests/test_mstore.py::test_load_store_list_distribution PASSED                                                                                                     [ 67%]
tests/test_mstore.py::test_load_store_list_redundancy PASSED                                                                                                       [ 68%]
tests/test_mstore.py::test_move_delete_undelete PASSED                                                                                                             [ 68%]
tests/test_mstore.py::test_namespaces PASSED                                                                                                                       [ 69%]
tests/test_mstore.py::test_reduce_prepare PASSED                                                                                                                   [ 70%]
tests/test_nesting.py::test_split_key[12345678-None-12345678] PASSED                                                                                               [ 71%]
tests/test_nesting.py::test_split_key[data/12345678-data-12345678] PASSED                                                                                          [ 72%]
tests/test_nesting.py::test_nest[12345678-0-False-12345678] PASSED                                                                                                 [ 72%]
tests/test_nesting.py::test_nest[12345678-1-False-12/12345678] PASSED                                                                                              [ 73%]
tests/test_nesting.py::test_nest[12345678-2-False-12/34/12345678] PASSED                                                                                           [ 74%]
tests/test_nesting.py::test_nest[12345678-3-False-12/34/56/12345678] PASSED                                                                                        [ 75%]
tests/test_nesting.py::test_nest[12345678-3-True-12/34/56/12345678.del] PASSED                                                                                     [ 75%]
tests/test_nesting.py::test_nest[data/12345678-0-False-data/12345678] PASSED                                                                                       [ 76%]
tests/test_nesting.py::test_nest[data/12345678-1-False-data/12/12345678] PASSED                                                                                    [ 77%]
tests/test_nesting.py::test_nest[data/12345678-2-False-data/12/34/12345678] PASSED                                                                                 [ 78%]
tests/test_nesting.py::test_nest[data/12345678-3-False-data/12/34/56/12345678] PASSED                                                                              [ 79%]
tests/test_nesting.py::test_nest[data/12345678-3-True-data/12/34/56/12345678.del] PASSED                                                                           [ 79%]
tests/test_nesting.py::test_unnest[12345678--False-12345678] PASSED                                                                                                [ 80%]
tests/test_nesting.py::test_unnest[12345678--False-12/12345678] PASSED                                                                                             [ 81%]
tests/test_nesting.py::test_unnest[12345678--False-12/34/12345678] PASSED                                                                                          [ 82%]
tests/test_nesting.py::test_unnest[12345678--False-12/34/56/12345678] PASSED                                                                                       [ 82%]
tests/test_nesting.py::test_unnest[12345678--True-12/34/56/12345678.del] PASSED                                                                                    [ 83%]
tests/test_nesting.py::test_unnest[data/12345678-data-False-data/12345678] PASSED                                                                                  [ 84%]
tests/test_nesting.py::test_unnest[data/12345678-data-False-data/12/12345678] PASSED                                                                               [ 85%]
tests/test_nesting.py::test_unnest[data/12345678-data-False-data/12/34/12345678] PASSED                                                                            [ 86%]
tests/test_nesting.py::test_unnest[data/12345678-data-False-data/12/34/56/12345678] PASSED                                                                         [ 86%]
tests/test_nesting.py::test_unnest[data/12345678-data-True-data/12/34/56/12345678.del] PASSED                                                                      [ 87%]
tests/test_nesting.py::test_unnest_invalid[data/12345678-data-data_xxx/12/12345678] PASSED                                                                         [ 88%]
tests/test_nesting.py::test_unnest_invalid[data/12345678-data-dat/12/34/12345678] PASSED                                                                           [ 89%]
tests/test_store.py::test_basics PASSED                                                                                                                            [ 89%]
tests/test_store.py::test_scalability_count[levels0-100] PASSED                                                                                                    [ 90%]
tests/test_store.py::test_scalability_count[levels1-1000] PASSED                                                                                                   [ 91%]
tests/test_store.py::test_scalability_big_values ERROR                                                                                                             [ 92%]
tests/test_store.py::test_scalability_big_values_rclone PASSED                                                                                                     [ 93%]
tests/test_store.py::test_upgrade_levels PASSED                                                                                                                    [ 93%]
tests/test_store.py::test_downgrade_levels PASSED                                                                                                                  [ 94%]
tests/test_store.py::test_move_delete_undelete PASSED                                                                                                              [ 95%]
tests/test_store.py::test_move_change_level PASSED                                                                                                                 [ 96%]
tests/test_store.py::test_move_generic PASSED                                                                                                                      [ 96%]
tests/test_store.py::test_nesting_config PASSED                                                                                                                    [ 97%]
tests/test_store.py::test_load_partial PASSED                                                                                                                      [ 98%]
tests/test_store.py::test_list_is_sorted PASSED                                                                                                                    [ 99%]
tests/test_store.py::test_stats PASSED                                                                                                                             [100%]

================================================================================= ERRORS =================================================================================
___________________________________________________ ERROR at teardown of test_scalability_size[sftp_backend_created-8] ___________________________________________________

self = <paramiko.Transport at 0x11c818b0 (unconnected)>

    def _check_banner(self):
        # this is slow, but we only have to do it once
        for i in range(100):
            # give them 15 seconds for the first line, then just 2 seconds
            # each additional line.  (some sites have very high latency.)
            if i == 0:
                timeout = self.banner_timeout
            else:
                timeout = 2
            try:
>               buf = self.packetizer.readline(timeout)

../borg-env/lib/python3.9/site-packages/paramiko/transport.py:2369: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../borg-env/lib/python3.9/site-packages/paramiko/packet.py:395: in readline
    buf += self._read_timeout(timeout)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <paramiko.packet.Packetizer object at 0x111be9b20>, timeout = 15

    def _read_timeout(self, timeout):
        start = time.time()
        while True:
            try:
                x = self.__socket.recv(128)
                if len(x) == 0:
>                   raise EOFError()
E                   EOFError

../borg-env/lib/python3.9/site-packages/paramiko/packet.py:665: EOFError

During handling of the above exception, another exception occurred:

    @pytest.fixture(scope="function")
    def sftp_backend_created():
        be = _get_sftp_backend()
        be.create()
        try:
            yield be
        finally:
>           be.destroy()

tests/test_backends.py:94: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
src/borgstore/backends/sftp.py:121: in destroy
    self._connect()
src/borgstore/backends/sftp.py:77: in _connect
    ssh.connect(
../borg-env/lib/python3.9/site-packages/paramiko/client.py:451: in connect
    t.start_client(timeout=timeout)
../borg-env/lib/python3.9/site-packages/paramiko/transport.py:773: in start_client
    raise e
../borg-env/lib/python3.9/site-packages/paramiko/transport.py:2185: in run
    self._check_banner()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <paramiko.Transport at 0x11c818b0 (unconnected)>

    def _check_banner(self):
        # this is slow, but we only have to do it once
        for i in range(100):
            # give them 15 seconds for the first line, then just 2 seconds
            # each additional line.  (some sites have very high latency.)
            if i == 0:
                timeout = self.banner_timeout
            else:
                timeout = 2
            try:
                buf = self.packetizer.readline(timeout)
            except ProxyCommandFailure:
                raise
            except Exception as e:
>               raise SSHException(
                    "Error reading SSH protocol banner" + str(e)
                )
E               paramiko.ssh_exception.SSHException: Error reading SSH protocol banner

../borg-env/lib/python3.9/site-packages/paramiko/transport.py:2373: SSHException
--------------------------------------------------------------------------- Captured log call ----------------------------------------------------------------------------
ERROR    paramiko.transport:transport.py:1944 Exception (client): Error reading SSH protocol banner
ERROR    paramiko.transport:transport.py:1942 Traceback (most recent call last):
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2369, in _check_banner
ERROR    paramiko.transport:transport.py:1942     buf = self.packetizer.readline(timeout)
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/packet.py", line 395, in readline
ERROR    paramiko.transport:transport.py:1942     buf += self._read_timeout(timeout)
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/packet.py", line 665, in _read_timeout
ERROR    paramiko.transport:transport.py:1942     raise EOFError()
ERROR    paramiko.transport:transport.py:1942 EOFError
ERROR    paramiko.transport:transport.py:1942 
ERROR    paramiko.transport:transport.py:1942 During handling of the above exception, another exception occurred:
ERROR    paramiko.transport:transport.py:1942 
ERROR    paramiko.transport:transport.py:1942 Traceback (most recent call last):
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2185, in run
ERROR    paramiko.transport:transport.py:1942     self._check_banner()
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2373, in _check_banner
ERROR    paramiko.transport:transport.py:1942     raise SSHException(
ERROR    paramiko.transport:transport.py:1942 paramiko.ssh_exception.SSHException: Error reading SSH protocol banner
ERROR    paramiko.transport:transport.py:1942
------------------------------------------------------------------------- Captured log teardown --------------------------------------------------------------------------
ERROR    paramiko.transport:transport.py:1944 Exception (client): Error reading SSH protocol banner
ERROR    paramiko.transport:transport.py:1942 Traceback (most recent call last):
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2369, in _check_banner
ERROR    paramiko.transport:transport.py:1942     buf = self.packetizer.readline(timeout)
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/packet.py", line 395, in readline
ERROR    paramiko.transport:transport.py:1942     buf += self._read_timeout(timeout)
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/packet.py", line 665, in _read_timeout
ERROR    paramiko.transport:transport.py:1942     raise EOFError()
ERROR    paramiko.transport:transport.py:1942 EOFError
ERROR    paramiko.transport:transport.py:1942 
ERROR    paramiko.transport:transport.py:1942 During handling of the above exception, another exception occurred:
ERROR    paramiko.transport:transport.py:1942 
ERROR    paramiko.transport:transport.py:1942 Traceback (most recent call last):
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2185, in run
ERROR    paramiko.transport:transport.py:1942     self._check_banner()
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2373, in _check_banner
ERROR    paramiko.transport:transport.py:1942     raise SSHException(
ERROR    paramiko.transport:transport.py:1942 paramiko.ssh_exception.SSHException: Error reading SSH protocol banner
ERROR    paramiko.transport:transport.py:1942
_____________________________________________________________ ERROR at setup of test_scalability_big_values ______________________________________________________________

self = <paramiko.Transport at 0x75c33d0 (unconnected)>

    def _check_banner(self):
        # this is slow, but we only have to do it once
        for i in range(100):
            # give them 15 seconds for the first line, then just 2 seconds
            # each additional line.  (some sites have very high latency.)
            if i == 0:
                timeout = self.banner_timeout
            else:
                timeout = 2
            try:
>               buf = self.packetizer.readline(timeout)

../borg-env/lib/python3.9/site-packages/paramiko/transport.py:2369: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../borg-env/lib/python3.9/site-packages/paramiko/packet.py:395: in readline
    buf += self._read_timeout(timeout)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <paramiko.packet.Packetizer object at 0x111b59970>, timeout = 15

    def _read_timeout(self, timeout):
        start = time.time()
        while True:
            try:
                x = self.__socket.recv(128)
                if len(x) == 0:
>                   raise EOFError()
E                   EOFError

../borg-env/lib/python3.9/site-packages/paramiko/packet.py:665: EOFError

During handling of the above exception, another exception occurred:

    @pytest.fixture(scope="function")
    def sftp_backend_created():
        be = _get_sftp_backend()
>       be.create()

tests/test_backends.py:90: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
src/borgstore/backends/sftp.py:93: in create
    self._connect()
src/borgstore/backends/sftp.py:77: in _connect
    ssh.connect(
../borg-env/lib/python3.9/site-packages/paramiko/client.py:451: in connect
    t.start_client(timeout=timeout)
../borg-env/lib/python3.9/site-packages/paramiko/transport.py:773: in start_client
    raise e
../borg-env/lib/python3.9/site-packages/paramiko/transport.py:2185: in run
    self._check_banner()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <paramiko.Transport at 0x75c33d0 (unconnected)>

    def _check_banner(self):
        # this is slow, but we only have to do it once
        for i in range(100):
            # give them 15 seconds for the first line, then just 2 seconds
            # each additional line.  (some sites have very high latency.)
            if i == 0:
                timeout = self.banner_timeout
            else:
                timeout = 2
            try:
                buf = self.packetizer.readline(timeout)
            except ProxyCommandFailure:
                raise
            except Exception as e:
>               raise SSHException(
                    "Error reading SSH protocol banner" + str(e)
                )
E               paramiko.ssh_exception.SSHException: Error reading SSH protocol banner

../borg-env/lib/python3.9/site-packages/paramiko/transport.py:2373: SSHException
--------------------------------------------------------------------------- Captured log setup ---------------------------------------------------------------------------
ERROR    paramiko.transport:transport.py:1944 Exception (client): Error reading SSH protocol banner
ERROR    paramiko.transport:transport.py:1942 Traceback (most recent call last):
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2369, in _check_banner
ERROR    paramiko.transport:transport.py:1942     buf = self.packetizer.readline(timeout)
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/packet.py", line 395, in readline
ERROR    paramiko.transport:transport.py:1942     buf += self._read_timeout(timeout)
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/packet.py", line 665, in _read_timeout
ERROR    paramiko.transport:transport.py:1942     raise EOFError()
ERROR    paramiko.transport:transport.py:1942 EOFError
ERROR    paramiko.transport:transport.py:1942 
ERROR    paramiko.transport:transport.py:1942 During handling of the above exception, another exception occurred:
ERROR    paramiko.transport:transport.py:1942 
ERROR    paramiko.transport:transport.py:1942 Traceback (most recent call last):
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2185, in run
ERROR    paramiko.transport:transport.py:1942     self._check_banner()
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2373, in _check_banner
ERROR    paramiko.transport:transport.py:1942     raise SSHException(
ERROR    paramiko.transport:transport.py:1942 paramiko.ssh_exception.SSHException: Error reading SSH protocol banner
ERROR    paramiko.transport:transport.py:1942
================================================================================ FAILURES ================================================================================
_____________________________________________________________ test_scalability_size[sftp_backend_created-8] ______________________________________________________________

self = <paramiko.Transport at 0x771bc70 (unconnected)>

    def _check_banner(self):
        # this is slow, but we only have to do it once
        for i in range(100):
            # give them 15 seconds for the first line, then just 2 seconds
            # each additional line.  (some sites have very high latency.)
            if i == 0:
                timeout = self.banner_timeout
            else:
                timeout = 2
            try:
>               buf = self.packetizer.readline(timeout)

../borg-env/lib/python3.9/site-packages/paramiko/transport.py:2369: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../borg-env/lib/python3.9/site-packages/paramiko/packet.py:395: in readline
    buf += self._read_timeout(timeout)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <paramiko.packet.Packetizer object at 0x10773c340>, timeout = 15

    def _read_timeout(self, timeout):
        start = time.time()
        while True:
            try:
                x = self.__socket.recv(128)
                if len(x) == 0:
>                   raise EOFError()
E                   EOFError

../borg-env/lib/python3.9/site-packages/paramiko/packet.py:665: EOFError

During handling of the above exception, another exception occurred:

tested_backends = 'sftp_backend_created', exp = 8, request = <FixtureRequest for <Function test_scalability_size[sftp_backend_created-8]>>

    @pytest.mark.parametrize("exp", range(9))
    def test_scalability_size(tested_backends, exp, request):
>       with get_backend_from_fixture(tested_backends, request) as backend:

tests/test_backends.py:309: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
src/borgstore/backends/_base.py:53: in __enter__
    self.open()
src/borgstore/backends/sftp.py:132: in open
    self._connect()
src/borgstore/backends/sftp.py:77: in _connect
    ssh.connect(
../borg-env/lib/python3.9/site-packages/paramiko/client.py:451: in connect
    t.start_client(timeout=timeout)
../borg-env/lib/python3.9/site-packages/paramiko/transport.py:773: in start_client
    raise e
../borg-env/lib/python3.9/site-packages/paramiko/transport.py:2185: in run
    self._check_banner()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <paramiko.Transport at 0x771bc70 (unconnected)>

    def _check_banner(self):
        # this is slow, but we only have to do it once
        for i in range(100):
            # give them 15 seconds for the first line, then just 2 seconds
            # each additional line.  (some sites have very high latency.)
            if i == 0:
                timeout = self.banner_timeout
            else:
                timeout = 2
            try:
                buf = self.packetizer.readline(timeout)
            except ProxyCommandFailure:
                raise
            except Exception as e:
>               raise SSHException(
                    "Error reading SSH protocol banner" + str(e)
                )
E               paramiko.ssh_exception.SSHException: Error reading SSH protocol banner

../borg-env/lib/python3.9/site-packages/paramiko/transport.py:2373: SSHException
--------------------------------------------------------------------------- Captured log call ----------------------------------------------------------------------------
ERROR    paramiko.transport:transport.py:1944 Exception (client): Error reading SSH protocol banner
ERROR    paramiko.transport:transport.py:1942 Traceback (most recent call last):
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2369, in _check_banner
ERROR    paramiko.transport:transport.py:1942     buf = self.packetizer.readline(timeout)
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/packet.py", line 395, in readline
ERROR    paramiko.transport:transport.py:1942     buf += self._read_timeout(timeout)
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/packet.py", line 665, in _read_timeout
ERROR    paramiko.transport:transport.py:1942     raise EOFError()
ERROR    paramiko.transport:transport.py:1942 EOFError
ERROR    paramiko.transport:transport.py:1942 
ERROR    paramiko.transport:transport.py:1942 During handling of the above exception, another exception occurred:
ERROR    paramiko.transport:transport.py:1942 
ERROR    paramiko.transport:transport.py:1942 Traceback (most recent call last):
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2185, in run
ERROR    paramiko.transport:transport.py:1942     self._check_banner()
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2373, in _check_banner
ERROR    paramiko.transport:transport.py:1942     raise SSHException(
ERROR    paramiko.transport:transport.py:1942 paramiko.ssh_exception.SSHException: Error reading SSH protocol banner
ERROR    paramiko.transport:transport.py:1942
________________________________________________________________ test_load_partial[sftp_backend_created] _________________________________________________________________

self = <paramiko.Transport at 0x11bf5910 (unconnected)>

    def _check_banner(self):
        # this is slow, but we only have to do it once
        for i in range(100):
            # give them 15 seconds for the first line, then just 2 seconds
            # each additional line.  (some sites have very high latency.)
            if i == 0:
                timeout = self.banner_timeout
            else:
                timeout = 2
            try:
>               buf = self.packetizer.readline(timeout)

../borg-env/lib/python3.9/site-packages/paramiko/transport.py:2369: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../borg-env/lib/python3.9/site-packages/paramiko/packet.py:395: in readline
    buf += self._read_timeout(timeout)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <paramiko.packet.Packetizer object at 0x111bfc5b0>, timeout = 15

    def _read_timeout(self, timeout):
        start = time.time()
        while True:
            try:
                x = self.__socket.recv(128)
                if len(x) == 0:
>                   raise EOFError()
E                   EOFError

../borg-env/lib/python3.9/site-packages/paramiko/packet.py:665: EOFError

During handling of the above exception, another exception occurred:

tested_backends = 'sftp_backend_created', request = <FixtureRequest for <Function test_load_partial[sftp_backend_created]>>

    def test_load_partial(tested_backends, request):
>       with get_backend_from_fixture(tested_backends, request) as backend:

tests/test_backends.py:317: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
tests/test_backends.py:120: in get_backend_from_fixture
    return request.getfixturevalue(tested_backends)
../borg-env/lib/python3.9/site-packages/_pytest/fixtures.py:532: in getfixturevalue
    fixturedef = self._get_active_fixturedef(argname)
../borg-env/lib/python3.9/site-packages/_pytest/fixtures.py:617: in _get_active_fixturedef
    fixturedef.execute(request=subrequest)
../borg-env/lib/python3.9/site-packages/_pytest/fixtures.py:1091: in execute
    result = ihook.pytest_fixture_setup(fixturedef=self, request=request)
../borg-env/lib/python3.9/site-packages/pluggy/_hooks.py:513: in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
../borg-env/lib/python3.9/site-packages/pluggy/_manager.py:120: in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
../borg-env/lib/python3.9/site-packages/_pytest/setuponly.py:36: in pytest_fixture_setup
    return (yield)
../borg-env/lib/python3.9/site-packages/_pytest/fixtures.py:1140: in pytest_fixture_setup
    result = call_fixture_func(fixturefunc, request, kwargs)
../borg-env/lib/python3.9/site-packages/_pytest/fixtures.py:891: in call_fixture_func
    fixture_result = next(generator)
tests/test_backends.py:90: in sftp_backend_created
    be.create()
src/borgstore/backends/sftp.py:93: in create
    self._connect()
src/borgstore/backends/sftp.py:77: in _connect
    ssh.connect(
../borg-env/lib/python3.9/site-packages/paramiko/client.py:451: in connect
    t.start_client(timeout=timeout)
../borg-env/lib/python3.9/site-packages/paramiko/transport.py:773: in start_client
    raise e
../borg-env/lib/python3.9/site-packages/paramiko/transport.py:2185: in run
    self._check_banner()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <paramiko.Transport at 0x11bf5910 (unconnected)>

    def _check_banner(self):
        # this is slow, but we only have to do it once
        for i in range(100):
            # give them 15 seconds for the first line, then just 2 seconds
            # each additional line.  (some sites have very high latency.)
            if i == 0:
                timeout = self.banner_timeout
            else:
                timeout = 2
            try:
                buf = self.packetizer.readline(timeout)
            except ProxyCommandFailure:
                raise
            except Exception as e:
>               raise SSHException(
                    "Error reading SSH protocol banner" + str(e)
                )
E               paramiko.ssh_exception.SSHException: Error reading SSH protocol banner

../borg-env/lib/python3.9/site-packages/paramiko/transport.py:2373: SSHException
--------------------------------------------------------------------------- Captured log call ----------------------------------------------------------------------------
ERROR    paramiko.transport:transport.py:1944 Exception (client): Error reading SSH protocol banner
ERROR    paramiko.transport:transport.py:1942 Traceback (most recent call last):
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2369, in _check_banner
ERROR    paramiko.transport:transport.py:1942     buf = self.packetizer.readline(timeout)
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/packet.py", line 395, in readline
ERROR    paramiko.transport:transport.py:1942     buf += self._read_timeout(timeout)
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/packet.py", line 665, in _read_timeout
ERROR    paramiko.transport:transport.py:1942     raise EOFError()
ERROR    paramiko.transport:transport.py:1942 EOFError
ERROR    paramiko.transport:transport.py:1942 
ERROR    paramiko.transport:transport.py:1942 During handling of the above exception, another exception occurred:
ERROR    paramiko.transport:transport.py:1942 
ERROR    paramiko.transport:transport.py:1942 Traceback (most recent call last):
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2185, in run
ERROR    paramiko.transport:transport.py:1942     self._check_banner()
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2373, in _check_banner
ERROR    paramiko.transport:transport.py:1942     raise SSHException(
ERROR    paramiko.transport:transport.py:1942 paramiko.ssh_exception.SSHException: Error reading SSH protocol banner
ERROR    paramiko.transport:transport.py:1942
_______________________________________________________________ test_already_exists[sftp_backend_created] ________________________________________________________________

self = <paramiko.Transport at 0x11f8e580 (unconnected)>

    def _check_banner(self):
        # this is slow, but we only have to do it once
        for i in range(100):
            # give them 15 seconds for the first line, then just 2 seconds
            # each additional line.  (some sites have very high latency.)
            if i == 0:
                timeout = self.banner_timeout
            else:
                timeout = 2
            try:
>               buf = self.packetizer.readline(timeout)

../borg-env/lib/python3.9/site-packages/paramiko/transport.py:2369: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../borg-env/lib/python3.9/site-packages/paramiko/packet.py:395: in readline
    buf += self._read_timeout(timeout)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <paramiko.packet.Packetizer object at 0x107510d90>, timeout = 15

    def _read_timeout(self, timeout):
        start = time.time()
        while True:
            try:
                x = self.__socket.recv(128)
                if len(x) == 0:
>                   raise EOFError()
E                   EOFError

../borg-env/lib/python3.9/site-packages/paramiko/packet.py:665: EOFError

During handling of the above exception, another exception occurred:

tested_backends = 'sftp_backend_created', request = <FixtureRequest for <Function test_already_exists[sftp_backend_created]>>

    def test_already_exists(tested_backends, request):
>       backend = get_backend_from_fixture(tested_backends, request)

tests/test_backends.py:326: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
tests/test_backends.py:120: in get_backend_from_fixture
    return request.getfixturevalue(tested_backends)
../borg-env/lib/python3.9/site-packages/_pytest/fixtures.py:532: in getfixturevalue
    fixturedef = self._get_active_fixturedef(argname)
../borg-env/lib/python3.9/site-packages/_pytest/fixtures.py:617: in _get_active_fixturedef
    fixturedef.execute(request=subrequest)
../borg-env/lib/python3.9/site-packages/_pytest/fixtures.py:1091: in execute
    result = ihook.pytest_fixture_setup(fixturedef=self, request=request)
../borg-env/lib/python3.9/site-packages/pluggy/_hooks.py:513: in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
../borg-env/lib/python3.9/site-packages/pluggy/_manager.py:120: in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
../borg-env/lib/python3.9/site-packages/_pytest/setuponly.py:36: in pytest_fixture_setup
    return (yield)
../borg-env/lib/python3.9/site-packages/_pytest/fixtures.py:1140: in pytest_fixture_setup
    result = call_fixture_func(fixturefunc, request, kwargs)
../borg-env/lib/python3.9/site-packages/_pytest/fixtures.py:891: in call_fixture_func
    fixture_result = next(generator)
tests/test_backends.py:90: in sftp_backend_created
    be.create()
src/borgstore/backends/sftp.py:93: in create
    self._connect()
src/borgstore/backends/sftp.py:77: in _connect
    ssh.connect(
../borg-env/lib/python3.9/site-packages/paramiko/client.py:451: in connect
    t.start_client(timeout=timeout)
../borg-env/lib/python3.9/site-packages/paramiko/transport.py:773: in start_client
    raise e
../borg-env/lib/python3.9/site-packages/paramiko/transport.py:2185: in run
    self._check_banner()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <paramiko.Transport at 0x11f8e580 (unconnected)>

    def _check_banner(self):
        # this is slow, but we only have to do it once
        for i in range(100):
            # give them 15 seconds for the first line, then just 2 seconds
            # each additional line.  (some sites have very high latency.)
            if i == 0:
                timeout = self.banner_timeout
            else:
                timeout = 2
            try:
                buf = self.packetizer.readline(timeout)
            except ProxyCommandFailure:
                raise
            except Exception as e:
>               raise SSHException(
                    "Error reading SSH protocol banner" + str(e)
                )
E               paramiko.ssh_exception.SSHException: Error reading SSH protocol banner

../borg-env/lib/python3.9/site-packages/paramiko/transport.py:2373: SSHException
--------------------------------------------------------------------------- Captured log call ----------------------------------------------------------------------------
ERROR    paramiko.transport:transport.py:1944 Exception (client): Error reading SSH protocol banner
ERROR    paramiko.transport:transport.py:1942 Traceback (most recent call last):
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2369, in _check_banner
ERROR    paramiko.transport:transport.py:1942     buf = self.packetizer.readline(timeout)
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/packet.py", line 395, in readline
ERROR    paramiko.transport:transport.py:1942     buf += self._read_timeout(timeout)
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/packet.py", line 665, in _read_timeout
ERROR    paramiko.transport:transport.py:1942     raise EOFError()
ERROR    paramiko.transport:transport.py:1942 EOFError
ERROR    paramiko.transport:transport.py:1942 
ERROR    paramiko.transport:transport.py:1942 During handling of the above exception, another exception occurred:
ERROR    paramiko.transport:transport.py:1942 
ERROR    paramiko.transport:transport.py:1942 Traceback (most recent call last):
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2185, in run
ERROR    paramiko.transport:transport.py:1942     self._check_banner()
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2373, in _check_banner
ERROR    paramiko.transport:transport.py:1942     raise SSHException(
ERROR    paramiko.transport:transport.py:1942 paramiko.ssh_exception.SSHException: Error reading SSH protocol banner
ERROR    paramiko.transport:transport.py:1942
_______________________________________________________________ test_does_not_exist[sftp_backend_created] ________________________________________________________________

self = <paramiko.Transport at 0x11dc9820 (unconnected)>

    def _check_banner(self):
        # this is slow, but we only have to do it once
        for i in range(100):
            # give them 15 seconds for the first line, then just 2 seconds
            # each additional line.  (some sites have very high latency.)
            if i == 0:
                timeout = self.banner_timeout
            else:
                timeout = 2
            try:
>               buf = self.packetizer.readline(timeout)

../borg-env/lib/python3.9/site-packages/paramiko/transport.py:2369: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../borg-env/lib/python3.9/site-packages/paramiko/packet.py:395: in readline
    buf += self._read_timeout(timeout)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <paramiko.packet.Packetizer object at 0x111b5a8e0>, timeout = 15

    def _read_timeout(self, timeout):
        start = time.time()
        while True:
            try:
                x = self.__socket.recv(128)
                if len(x) == 0:
>                   raise EOFError()
E                   EOFError

../borg-env/lib/python3.9/site-packages/paramiko/packet.py:665: EOFError

During handling of the above exception, another exception occurred:

tested_backends = 'sftp_backend_created', request = <FixtureRequest for <Function test_does_not_exist[sftp_backend_created]>>

    def test_does_not_exist(tested_backends, request):
>       backend = get_backend_from_fixture(tested_backends, request)

tests/test_backends.py:335: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
tests/test_backends.py:120: in get_backend_from_fixture
    return request.getfixturevalue(tested_backends)
../borg-env/lib/python3.9/site-packages/_pytest/fixtures.py:532: in getfixturevalue
    fixturedef = self._get_active_fixturedef(argname)
../borg-env/lib/python3.9/site-packages/_pytest/fixtures.py:617: in _get_active_fixturedef
    fixturedef.execute(request=subrequest)
../borg-env/lib/python3.9/site-packages/_pytest/fixtures.py:1091: in execute
    result = ihook.pytest_fixture_setup(fixturedef=self, request=request)
../borg-env/lib/python3.9/site-packages/pluggy/_hooks.py:513: in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
../borg-env/lib/python3.9/site-packages/pluggy/_manager.py:120: in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
../borg-env/lib/python3.9/site-packages/_pytest/setuponly.py:36: in pytest_fixture_setup
    return (yield)
../borg-env/lib/python3.9/site-packages/_pytest/fixtures.py:1140: in pytest_fixture_setup
    result = call_fixture_func(fixturefunc, request, kwargs)
../borg-env/lib/python3.9/site-packages/_pytest/fixtures.py:891: in call_fixture_func
    fixture_result = next(generator)
tests/test_backends.py:90: in sftp_backend_created
    be.create()
src/borgstore/backends/sftp.py:93: in create
    self._connect()
src/borgstore/backends/sftp.py:77: in _connect
    ssh.connect(
../borg-env/lib/python3.9/site-packages/paramiko/client.py:451: in connect
    t.start_client(timeout=timeout)
../borg-env/lib/python3.9/site-packages/paramiko/transport.py:773: in start_client
    raise e
../borg-env/lib/python3.9/site-packages/paramiko/transport.py:2185: in run
    self._check_banner()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <paramiko.Transport at 0x11dc9820 (unconnected)>

    def _check_banner(self):
        # this is slow, but we only have to do it once
        for i in range(100):
            # give them 15 seconds for the first line, then just 2 seconds
            # each additional line.  (some sites have very high latency.)
            if i == 0:
                timeout = self.banner_timeout
            else:
                timeout = 2
            try:
                buf = self.packetizer.readline(timeout)
            except ProxyCommandFailure:
                raise
            except Exception as e:
>               raise SSHException(
                    "Error reading SSH protocol banner" + str(e)
                )
E               paramiko.ssh_exception.SSHException: Error reading SSH protocol banner

../borg-env/lib/python3.9/site-packages/paramiko/transport.py:2373: SSHException
--------------------------------------------------------------------------- Captured log call ----------------------------------------------------------------------------
ERROR    paramiko.transport:transport.py:1944 Exception (client): Error reading SSH protocol banner
ERROR    paramiko.transport:transport.py:1942 Traceback (most recent call last):
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2369, in _check_banner
ERROR    paramiko.transport:transport.py:1942     buf = self.packetizer.readline(timeout)
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/packet.py", line 395, in readline
ERROR    paramiko.transport:transport.py:1942     buf += self._read_timeout(timeout)
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/packet.py", line 665, in _read_timeout
ERROR    paramiko.transport:transport.py:1942     raise EOFError()
ERROR    paramiko.transport:transport.py:1942 EOFError
ERROR    paramiko.transport:transport.py:1942 
ERROR    paramiko.transport:transport.py:1942 During handling of the above exception, another exception occurred:
ERROR    paramiko.transport:transport.py:1942 
ERROR    paramiko.transport:transport.py:1942 Traceback (most recent call last):
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2185, in run
ERROR    paramiko.transport:transport.py:1942     self._check_banner()
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2373, in _check_banner
ERROR    paramiko.transport:transport.py:1942     raise SSHException(
ERROR    paramiko.transport:transport.py:1942 paramiko.ssh_exception.SSHException: Error reading SSH protocol banner
ERROR    paramiko.transport:transport.py:1942
________________________________________________________________ test_must_be_open[sftp_backend_created] _________________________________________________________________

self = <paramiko.Transport at 0x11cb4520 (unconnected)>

    def _check_banner(self):
        # this is slow, but we only have to do it once
        for i in range(100):
            # give them 15 seconds for the first line, then just 2 seconds
            # each additional line.  (some sites have very high latency.)
            if i == 0:
                timeout = self.banner_timeout
            else:
                timeout = 2
            try:
>               buf = self.packetizer.readline(timeout)

../borg-env/lib/python3.9/site-packages/paramiko/transport.py:2369: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../borg-env/lib/python3.9/site-packages/paramiko/packet.py:395: in readline
    buf += self._read_timeout(timeout)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <paramiko.packet.Packetizer object at 0x107704c40>, timeout = 15

    def _read_timeout(self, timeout):
        start = time.time()
        while True:
            try:
                x = self.__socket.recv(128)
                if len(x) == 0:
>                   raise EOFError()
E                   EOFError

../borg-env/lib/python3.9/site-packages/paramiko/packet.py:665: EOFError

During handling of the above exception, another exception occurred:

tested_backends = 'sftp_backend_created', request = <FixtureRequest for <Function test_must_be_open[sftp_backend_created]>>

    def test_must_be_open(tested_backends, request):
>       backend = get_backend_from_fixture(tested_backends, request)

tests/test_backends.py:346: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
tests/test_backends.py:120: in get_backend_from_fixture
    return request.getfixturevalue(tested_backends)
../borg-env/lib/python3.9/site-packages/_pytest/fixtures.py:532: in getfixturevalue
    fixturedef = self._get_active_fixturedef(argname)
../borg-env/lib/python3.9/site-packages/_pytest/fixtures.py:617: in _get_active_fixturedef
    fixturedef.execute(request=subrequest)
../borg-env/lib/python3.9/site-packages/_pytest/fixtures.py:1091: in execute
    result = ihook.pytest_fixture_setup(fixturedef=self, request=request)
../borg-env/lib/python3.9/site-packages/pluggy/_hooks.py:513: in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
../borg-env/lib/python3.9/site-packages/pluggy/_manager.py:120: in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
../borg-env/lib/python3.9/site-packages/_pytest/setuponly.py:36: in pytest_fixture_setup
    return (yield)
../borg-env/lib/python3.9/site-packages/_pytest/fixtures.py:1140: in pytest_fixture_setup
    result = call_fixture_func(fixturefunc, request, kwargs)
../borg-env/lib/python3.9/site-packages/_pytest/fixtures.py:891: in call_fixture_func
    fixture_result = next(generator)
tests/test_backends.py:90: in sftp_backend_created
    be.create()
src/borgstore/backends/sftp.py:93: in create
    self._connect()
src/borgstore/backends/sftp.py:77: in _connect
    ssh.connect(
../borg-env/lib/python3.9/site-packages/paramiko/client.py:451: in connect
    t.start_client(timeout=timeout)
../borg-env/lib/python3.9/site-packages/paramiko/transport.py:773: in start_client
    raise e
../borg-env/lib/python3.9/site-packages/paramiko/transport.py:2185: in run
    self._check_banner()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <paramiko.Transport at 0x11cb4520 (unconnected)>

    def _check_banner(self):
        # this is slow, but we only have to do it once
        for i in range(100):
            # give them 15 seconds for the first line, then just 2 seconds
            # each additional line.  (some sites have very high latency.)
            if i == 0:
                timeout = self.banner_timeout
            else:
                timeout = 2
            try:
                buf = self.packetizer.readline(timeout)
            except ProxyCommandFailure:
                raise
            except Exception as e:
>               raise SSHException(
                    "Error reading SSH protocol banner" + str(e)
                )
E               paramiko.ssh_exception.SSHException: Error reading SSH protocol banner

../borg-env/lib/python3.9/site-packages/paramiko/transport.py:2373: SSHException
--------------------------------------------------------------------------- Captured log call ----------------------------------------------------------------------------
ERROR    paramiko.transport:transport.py:1944 Exception (client): Error reading SSH protocol banner
ERROR    paramiko.transport:transport.py:1942 Traceback (most recent call last):
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2369, in _check_banner
ERROR    paramiko.transport:transport.py:1942     buf = self.packetizer.readline(timeout)
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/packet.py", line 395, in readline
ERROR    paramiko.transport:transport.py:1942     buf += self._read_timeout(timeout)
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/packet.py", line 665, in _read_timeout
ERROR    paramiko.transport:transport.py:1942     raise EOFError()
ERROR    paramiko.transport:transport.py:1942 EOFError
ERROR    paramiko.transport:transport.py:1942 
ERROR    paramiko.transport:transport.py:1942 During handling of the above exception, another exception occurred:
ERROR    paramiko.transport:transport.py:1942 
ERROR    paramiko.transport:transport.py:1942 Traceback (most recent call last):
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2185, in run
ERROR    paramiko.transport:transport.py:1942     self._check_banner()
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2373, in _check_banner
ERROR    paramiko.transport:transport.py:1942     raise SSHException(
ERROR    paramiko.transport:transport.py:1942 paramiko.ssh_exception.SSHException: Error reading SSH protocol banner
ERROR    paramiko.transport:transport.py:1942
______________________________________________________________ test_must_not_be_open[sftp_backend_created] _______________________________________________________________

self = <paramiko.Transport at 0x11b49310 (unconnected)>

    def _check_banner(self):
        # this is slow, but we only have to do it once
        for i in range(100):
            # give them 15 seconds for the first line, then just 2 seconds
            # each additional line.  (some sites have very high latency.)
            if i == 0:
                timeout = self.banner_timeout
            else:
                timeout = 2
            try:
>               buf = self.packetizer.readline(timeout)

../borg-env/lib/python3.9/site-packages/paramiko/transport.py:2369: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../borg-env/lib/python3.9/site-packages/paramiko/packet.py:395: in readline
    buf += self._read_timeout(timeout)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <paramiko.packet.Packetizer object at 0x111d2d880>, timeout = 15

    def _read_timeout(self, timeout):
        start = time.time()
        while True:
            try:
                x = self.__socket.recv(128)
                if len(x) == 0:
>                   raise EOFError()
E                   EOFError

../borg-env/lib/python3.9/site-packages/paramiko/packet.py:665: EOFError

During handling of the above exception, another exception occurred:

tested_backends = 'sftp_backend_created', request = <FixtureRequest for <Function test_must_not_be_open[sftp_backend_created]>>

    def test_must_not_be_open(tested_backends, request):
>       backend = get_backend_from_fixture(tested_backends, request)

tests/test_backends.py:366: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
tests/test_backends.py:120: in get_backend_from_fixture
    return request.getfixturevalue(tested_backends)
../borg-env/lib/python3.9/site-packages/_pytest/fixtures.py:532: in getfixturevalue
    fixturedef = self._get_active_fixturedef(argname)
../borg-env/lib/python3.9/site-packages/_pytest/fixtures.py:617: in _get_active_fixturedef
    fixturedef.execute(request=subrequest)
../borg-env/lib/python3.9/site-packages/_pytest/fixtures.py:1091: in execute
    result = ihook.pytest_fixture_setup(fixturedef=self, request=request)
../borg-env/lib/python3.9/site-packages/pluggy/_hooks.py:513: in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
../borg-env/lib/python3.9/site-packages/pluggy/_manager.py:120: in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
../borg-env/lib/python3.9/site-packages/_pytest/setuponly.py:36: in pytest_fixture_setup
    return (yield)
../borg-env/lib/python3.9/site-packages/_pytest/fixtures.py:1140: in pytest_fixture_setup
    result = call_fixture_func(fixturefunc, request, kwargs)
../borg-env/lib/python3.9/site-packages/_pytest/fixtures.py:891: in call_fixture_func
    fixture_result = next(generator)
tests/test_backends.py:90: in sftp_backend_created
    be.create()
src/borgstore/backends/sftp.py:93: in create
    self._connect()
src/borgstore/backends/sftp.py:77: in _connect
    ssh.connect(
../borg-env/lib/python3.9/site-packages/paramiko/client.py:451: in connect
    t.start_client(timeout=timeout)
../borg-env/lib/python3.9/site-packages/paramiko/transport.py:773: in start_client
    raise e
../borg-env/lib/python3.9/site-packages/paramiko/transport.py:2185: in run
    self._check_banner()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <paramiko.Transport at 0x11b49310 (unconnected)>

    def _check_banner(self):
        # this is slow, but we only have to do it once
        for i in range(100):
            # give them 15 seconds for the first line, then just 2 seconds
            # each additional line.  (some sites have very high latency.)
            if i == 0:
                timeout = self.banner_timeout
            else:
                timeout = 2
            try:
                buf = self.packetizer.readline(timeout)
            except ProxyCommandFailure:
                raise
            except Exception as e:
>               raise SSHException(
                    "Error reading SSH protocol banner" + str(e)
                )
E               paramiko.ssh_exception.SSHException: Error reading SSH protocol banner

../borg-env/lib/python3.9/site-packages/paramiko/transport.py:2373: SSHException
--------------------------------------------------------------------------- Captured log call ----------------------------------------------------------------------------
ERROR    paramiko.transport:transport.py:1944 Exception (client): Error reading SSH protocol banner
ERROR    paramiko.transport:transport.py:1942 Traceback (most recent call last):
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2369, in _check_banner
ERROR    paramiko.transport:transport.py:1942     buf = self.packetizer.readline(timeout)
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/packet.py", line 395, in readline
ERROR    paramiko.transport:transport.py:1942     buf += self._read_timeout(timeout)
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/packet.py", line 665, in _read_timeout
ERROR    paramiko.transport:transport.py:1942     raise EOFError()
ERROR    paramiko.transport:transport.py:1942 EOFError
ERROR    paramiko.transport:transport.py:1942 
ERROR    paramiko.transport:transport.py:1942 During handling of the above exception, another exception occurred:
ERROR    paramiko.transport:transport.py:1942 
ERROR    paramiko.transport:transport.py:1942 Traceback (most recent call last):
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2185, in run
ERROR    paramiko.transport:transport.py:1942     self._check_banner()
ERROR    paramiko.transport:transport.py:1942   File "/Users/tw/w/borg-env/lib/python3.9/site-packages/paramiko/transport.py", line 2373, in _check_banner
ERROR    paramiko.transport:transport.py:1942     raise SSHException(
ERROR    paramiko.transport:transport.py:1942 paramiko.ssh_exception.SSHException: Error reading SSH protocol banner
ERROR    paramiko.transport:transport.py:1942