Rev 4710: (robertc) Cleanup end to end SSH connection test, in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Tue Sep 22 06:29:24 BST 2009


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 4710 [merge]
revision-id: pqm at pqm.ubuntu.com-20090922052923-oj9unuqio1uf2f1b
parent: pqm at pqm.ubuntu.com-20090922044632-it92wd7iulmerlxa
parent: robertc at robertcollins.net-20090922042505-bo5m0b5uuajl2igj
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Tue 2009-09-22 06:29:23 +0100
message:
  (robertc) Cleanup end to end SSH connection test,
  	hopefully fixing it on windows too. (Robert Collins,
  	John Arbash Meinel)
modified:
  bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
  bzrlib/tests/blackbox/test_serve.py test_serve.py-20060913064329-8t2pvmsikl4s3xhl-1
  bzrlib/tests/test_transport.py testtransport.py-20050718175618-e5cdb99f4555ddce
=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py	2009-09-19 16:14:10 +0000
+++ b/bzrlib/tests/__init__.py	2009-09-22 04:25:05 +0000
@@ -4203,6 +4203,23 @@
 HTTPSServerFeature = _HTTPSServerFeature()
 
 
+class _ParamikoFeature(Feature):
+    """Is paramiko available?"""
+
+    def _probe(self):
+        try:
+            from bzrlib.transport.sftp import SFTPAbsoluteServer
+            return True
+        except errors.ParamikoNotPresent:
+            return False
+
+    def feature_name(self):
+        return "Paramiko"
+
+
+ParamikoFeature = _ParamikoFeature()
+
+
 class _UnicodeFilename(Feature):
     """Does the filesystem support Unicode filenames?"""
 

=== modified file 'bzrlib/tests/blackbox/test_serve.py'
--- a/bzrlib/tests/blackbox/test_serve.py	2009-09-18 09:09:36 +0000
+++ b/bzrlib/tests/blackbox/test_serve.py	2009-09-22 04:25:05 +0000
@@ -33,12 +33,12 @@
     )
 from bzrlib.branch import Branch
 from bzrlib.bzrdir import BzrDir
-from bzrlib.errors import ParamikoNotPresent
 from bzrlib.smart import client, medium
 from bzrlib.smart.server import BzrServerFactory, SmartTCPServer
 from bzrlib.tests import (
+    ParamikoFeature,
+    TestCaseWithMemoryTransport,
     TestCaseWithTransport,
-    TestCaseWithMemoryTransport,
     TestSkipped,
     )
 from bzrlib.trace import mutter
@@ -166,97 +166,6 @@
         self.make_read_requests(branch)
         self.assertServerFinishesCleanly(process)
 
-    def test_bzr_connect_to_bzr_ssh(self):
-        """User acceptance that get_transport of a bzr+ssh:// behaves correctly.
-
-        bzr+ssh:// should cause bzr to run a remote bzr smart server over SSH.
-        """
-        try:
-            # SFTPFullAbsoluteServer has a get_url method, and doesn't
-            # override the interface (doesn't change self._vendor).
-            from bzrlib.transport.sftp import SFTPFullAbsoluteServer
-        except ParamikoNotPresent:
-            raise TestSkipped('Paramiko not installed')
-        from bzrlib.tests.stub_sftp import StubServer
-
-        # Make a branch
-        self.make_branch('a_branch')
-
-        # Start an SSH server
-        self.command_executed = []
-        # XXX: This is horrible -- we define a really dumb SSH server that
-        # executes commands, and manage the hooking up of stdin/out/err to the
-        # SSH channel ourselves.  Surely this has already been implemented
-        # elsewhere?
-        class StubSSHServer(StubServer):
-
-            test = self
-
-            def check_channel_exec_request(self, channel, command):
-                self.test.command_executed.append(command)
-                proc = subprocess.Popen(
-                    command, shell=True, stdin=subprocess.PIPE,
-                    stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-
-                # XXX: horribly inefficient, not to mention ugly.
-                # Start a thread for each of stdin/out/err, and relay bytes from
-                # the subprocess to channel and vice versa.
-                def ferry_bytes(read, write, close):
-                    while True:
-                        bytes = read(1)
-                        if bytes == '':
-                            close()
-                            break
-                        write(bytes)
-
-                file_functions = [
-                    (channel.recv, proc.stdin.write, proc.stdin.close),
-                    (proc.stdout.read, channel.sendall, channel.close),
-                    (proc.stderr.read, channel.sendall_stderr, channel.close)]
-                for read, write, close in file_functions:
-                    t = threading.Thread(
-                        target=ferry_bytes, args=(read, write, close))
-                    t.start()
-
-                return True
-
-        ssh_server = SFTPFullAbsoluteServer(StubSSHServer)
-        # XXX: We *don't* want to override the default SSH vendor, so we set
-        # _vendor to what _get_ssh_vendor returns.
-        self.start_server(ssh_server)
-        port = ssh_server._listener.port
-
-        # Access the branch via a bzr+ssh URL.  The BZR_REMOTE_PATH environment
-        # variable is used to tell bzr what command to run on the remote end.
-        path_to_branch = osutils.abspath('a_branch')
-
-        orig_bzr_remote_path = os.environ.get('BZR_REMOTE_PATH')
-        bzr_remote_path = self.get_bzr_path()
-        if sys.platform == 'win32':
-            bzr_remote_path = sys.executable + ' ' + self.get_bzr_path()
-        os.environ['BZR_REMOTE_PATH'] = bzr_remote_path
-        try:
-            if sys.platform == 'win32':
-                path_to_branch = os.path.splitdrive(path_to_branch)[1]
-            url_suffix = '@localhost:%d%s' % (port, path_to_branch)
-            self.permit_url('bzr+ssh://fred' + url_suffix)
-            branch = Branch.open('bzr+ssh://fred:secret' + url_suffix)
-            self.make_read_requests(branch)
-            # Check we can perform write operations
-            branch.bzrdir.root_transport.mkdir('foo')
-        finally:
-            # Restore the BZR_REMOTE_PATH environment variable back to its
-            # original state.
-            if orig_bzr_remote_path is None:
-                del os.environ['BZR_REMOTE_PATH']
-            else:
-                os.environ['BZR_REMOTE_PATH'] = orig_bzr_remote_path
-
-        self.assertEqual(
-            ['%s serve --inet --directory=/ --allow-writes'
-             % bzr_remote_path],
-            self.command_executed)
-
 
 class TestCmdServeChrooting(TestCaseWithTransport):
 

=== modified file 'bzrlib/tests/test_transport.py'
--- a/bzrlib/tests/test_transport.py	2009-09-18 07:16:36 +0000
+++ b/bzrlib/tests/test_transport.py	2009-09-22 04:25:05 +0000
@@ -16,11 +16,16 @@
 
 
 from cStringIO import StringIO
+import os
+import subprocess
+import sys
+import threading
 
 import bzrlib
 from bzrlib import (
     errors,
     osutils,
+    tests,
     urlutils,
     )
 from bzrlib.errors import (DependencyNotPresent,
@@ -31,7 +36,7 @@
                            ReadError,
                            UnsupportedProtocol,
                            )
-from bzrlib.tests import TestCase, TestCaseInTempDir
+from bzrlib.tests import ParamikoFeature, TestCase, TestCaseInTempDir
 from bzrlib.transport import (_clear_protocol_handlers,
                               _CoalescedOffset,
                               ConnectedTransport,
@@ -876,3 +881,89 @@
         # readv records the supplied offset request
         expected_result.append(('readv', 'foo', [(0, 1), (3, 2)], True, 6))
         self.assertEqual(expected_result, transport._activity)
+
+
+class TestSSHConnections(tests.TestCaseWithTransport):
+
+    def test_bzr_connect_to_bzr_ssh(self):
+        """User acceptance that get_transport of a bzr+ssh:// behaves correctly.
+
+        bzr+ssh:// should cause bzr to run a remote bzr smart server over SSH.
+        """
+        # This test actually causes a bzr instance to be invoked, which is very
+        # expensive: it should be the only such test in the test suite.
+        # A reasonable evolution for this would be to simply check inside
+        # check_channel_exec_request that the command is appropriate, and then
+        # satisfy requests in-process.
+        self.requireFeature(ParamikoFeature)
+        # SFTPFullAbsoluteServer has a get_url method, and doesn't
+        # override the interface (doesn't change self._vendor).
+        # Note that this does encryption, so can be slow.
+        from bzrlib.transport.sftp import SFTPFullAbsoluteServer
+        from bzrlib.tests.stub_sftp import StubServer
+
+        # Start an SSH server
+        self.command_executed = []
+        # XXX: This is horrible -- we define a really dumb SSH server that
+        # executes commands, and manage the hooking up of stdin/out/err to the
+        # SSH channel ourselves.  Surely this has already been implemented
+        # elsewhere?
+        class StubSSHServer(StubServer):
+
+            test = self
+
+            def check_channel_exec_request(self, channel, command):
+                self.test.command_executed.append(command)
+                proc = subprocess.Popen(
+                    command, shell=True, stdin=subprocess.PIPE,
+                    stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+
+                # XXX: horribly inefficient, not to mention ugly.
+                # Start a thread for each of stdin/out/err, and relay bytes from
+                # the subprocess to channel and vice versa.
+                def ferry_bytes(read, write, close):
+                    while True:
+                        bytes = read(1)
+                        if bytes == '':
+                            close()
+                            break
+                        write(bytes)
+
+                file_functions = [
+                    (channel.recv, proc.stdin.write, proc.stdin.close),
+                    (proc.stdout.read, channel.sendall, channel.close),
+                    (proc.stderr.read, channel.sendall_stderr, channel.close)]
+                for read, write, close in file_functions:
+                    t = threading.Thread(
+                        target=ferry_bytes, args=(read, write, close))
+                    t.start()
+
+                return True
+
+        ssh_server = SFTPFullAbsoluteServer(StubSSHServer)
+        # We *don't* want to override the default SSH vendor: the detected one
+        # is the one to use.
+        self.start_server(ssh_server)
+        port = ssh_server._listener.port
+
+        if sys.platform == 'win32':
+            bzr_remote_path = sys.executable + ' ' + self.get_bzr_path()
+        else:
+            bzr_remote_path = self.get_bzr_path()
+        os.environ['BZR_REMOTE_PATH'] = bzr_remote_path
+
+        # Access the branch via a bzr+ssh URL.  The BZR_REMOTE_PATH environment
+        # variable is used to tell bzr what command to run on the remote end.
+        path_to_branch = osutils.abspath('.')
+        if sys.platform == 'win32':
+            # On Windows, we export all drives as '/C:/, etc. So we need to
+            # prefix a '/' to get the right path.
+            path_to_branch = '/' + path_to_branch
+        url = 'bzr+ssh://fred:secret@localhost:%d%s' % (port, path_to_branch)
+        t = get_transport(url)
+        self.permit_url(t.base)
+        t.mkdir('foo')
+
+        self.assertEqual(
+            ['%s serve --inet --directory=/ --allow-writes' % bzr_remote_path],
+            self.command_executed)




More information about the bazaar-commits mailing list