~bzr-pqm/bzr/bzr.dev

3251.4.2 by Aaron Bentley
Clean up Launchpad directory service code
1
# Copyright (C) 2007, 2008 Canonical Ltd
2245.8.1 by Martin Pool
Start adding tests for launchpad indirection
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
3251.4.3 by Aaron Bentley
More renames and cleanups
17
"""Tests for directory lookup through Launchpad.net"""
2245.8.1 by Martin Pool
Start adding tests for launchpad indirection
18
2898.4.4 by James Henstridge
Changes to account for modifications to the XMLRPC API.
19
import xmlrpclib
20
2245.8.3 by Martin Pool
Start adding indirection transport
21
from bzrlib import (
2245.8.4 by Martin Pool
lp:/// indirection works
22
    errors,
2245.8.3 by Martin Pool
Start adding indirection transport
23
    )
2898.4.17 by James Henstridge
Add a test that the redirect actually occurs when opening an lp: URL.
24
from bzrlib.branch import Branch
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
25
from bzrlib.directory_service import directories
2898.4.17 by James Henstridge
Add a test that the redirect actually occurs when opening an lp: URL.
26
from bzrlib.tests import TestCase, TestCaseWithMemoryTransport
27
from bzrlib.transport import get_transport
3251.4.2 by Aaron Bentley
Clean up Launchpad directory service code
28
from bzrlib.plugins.launchpad import _register_directory
3251.4.3 by Aaron Bentley
More renames and cleanups
29
from bzrlib.plugins.launchpad.lp_directory import (
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
30
    LaunchpadDirectory)
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
31
from bzrlib.plugins.launchpad.account import get_lp_login
2898.4.3 by James Henstridge
Make launchpad_transport_indirect() use XMLRPC to resolve the lp: URL.
32
33
34
class FakeResolveFactory(object):
35
    def __init__(self, test, expected_path, result):
36
        self._test = test
37
        self._expected_path = expected_path
38
        self._result = result
39
40
    def __call__(self, path):
41
        self._test.assertEqual(self._expected_path, path)
42
        return self
43
44
    def submit(self, service):
3193.5.2 by Tim Penhey
Updated the tests to handle unknown launchpad instances.
45
        self._service_url = service.service_url
2898.4.3 by James Henstridge
Make launchpad_transport_indirect() use XMLRPC to resolve the lp: URL.
46
        return self._result
2245.8.1 by Martin Pool
Start adding tests for launchpad indirection
47
2245.8.7 by Martin Pool
small review cleanups
48
3251.4.3 by Aaron Bentley
More renames and cleanups
49
class DirectoryUrlTests(TestCase):
50
    """Tests for branch urls through Launchpad.net directory"""
2245.8.1 by Martin Pool
Start adding tests for launchpad indirection
51
2245.8.5 by Martin Pool
Add short-form lp:PRODUCT url form
52
    def test_short_form(self):
53
        """A launchpad url should map to a http url"""
2898.4.3 by James Henstridge
Make launchpad_transport_indirect() use XMLRPC to resolve the lp: URL.
54
        factory = FakeResolveFactory(
2898.4.4 by James Henstridge
Changes to account for modifications to the XMLRPC API.
55
            self, 'apt', dict(urls=[
56
                    'http://bazaar.launchpad.net/~apt/apt/devel']))
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
57
        directory = LaunchpadDirectory()
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
58
        self.assertEquals('http://bazaar.launchpad.net/~apt/apt/devel',
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
59
                          directory._resolve('lp:apt', factory))
3193.5.2 by Tim Penhey
Updated the tests to handle unknown launchpad instances.
60
        # Make sure that resolve went to the production server.
3221.1.12 by Martin Pool
Update Launchpad indirection tests to allow for xmlrpcs being sent to edge by default
61
        self.assertEquals('https://xmlrpc.edge.launchpad.net/bazaar/',
3193.5.2 by Tim Penhey
Updated the tests to handle unknown launchpad instances.
62
                          factory._service_url)
63
64
    def test_staging(self):
65
        """A launchpad url should map to a http url"""
66
        factory = FakeResolveFactory(
67
            self, 'apt', dict(urls=[
68
                    'http://bazaar.staging.launchpad.net/~apt/apt/devel']))
69
        url = 'lp://staging/apt'
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
70
        directory = LaunchpadDirectory()
3193.5.2 by Tim Penhey
Updated the tests to handle unknown launchpad instances.
71
        self.assertEquals('http://bazaar.staging.launchpad.net/~apt/apt/devel',
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
72
                          directory._resolve(url, factory))
3193.5.2 by Tim Penhey
Updated the tests to handle unknown launchpad instances.
73
        # Make sure that resolve went to the staging server.
74
        self.assertEquals('https://xmlrpc.staging.launchpad.net/bazaar/',
75
                          factory._service_url)
2245.8.5 by Martin Pool
Add short-form lp:PRODUCT url form
76
3251.4.3 by Aaron Bentley
More renames and cleanups
77
    def test_url_from_directory(self):
2245.8.3 by Martin Pool
Start adding indirection transport
78
        """A launchpad url should map to a http url"""
2898.4.3 by James Henstridge
Make launchpad_transport_indirect() use XMLRPC to resolve the lp: URL.
79
        factory = FakeResolveFactory(
2898.4.4 by James Henstridge
Changes to account for modifications to the XMLRPC API.
80
            self, 'apt', dict(urls=[
81
                    'http://bazaar.launchpad.net/~apt/apt/devel']))
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
82
        directory = LaunchpadDirectory()
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
83
        self.assertEquals('http://bazaar.launchpad.net/~apt/apt/devel',
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
84
                          directory._resolve('lp:///apt', factory))
2898.4.3 by James Henstridge
Make launchpad_transport_indirect() use XMLRPC to resolve the lp: URL.
85
3251.4.3 by Aaron Bentley
More renames and cleanups
86
    def test_directory_skip_bad_schemes(self):
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
87
        factory = FakeResolveFactory(
88
            self, 'apt', dict(urls=[
89
                    'bad-scheme://bazaar.launchpad.net/~apt/apt/devel',
90
                    'http://bazaar.launchpad.net/~apt/apt/devel',
91
                    'http://another/location']))
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
92
        directory = LaunchpadDirectory()
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
93
        self.assertEquals('http://bazaar.launchpad.net/~apt/apt/devel',
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
94
                          directory._resolve('lp:///apt', factory))
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
95
3251.4.3 by Aaron Bentley
More renames and cleanups
96
    def test_directory_no_matching_schemes(self):
2898.4.3 by James Henstridge
Make launchpad_transport_indirect() use XMLRPC to resolve the lp: URL.
97
        # If the XMLRPC call does not return any protocols we support,
98
        # invalidURL is raised.
99
        factory = FakeResolveFactory(
2898.4.4 by James Henstridge
Changes to account for modifications to the XMLRPC API.
100
            self, 'apt', dict(urls=[
101
                    'bad-scheme://bazaar.launchpad.net/~apt/apt/devel']))
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
102
        directory = LaunchpadDirectory()
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
103
        self.assertRaises(errors.InvalidURL,
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
104
                          directory._resolve, 'lp:///apt', factory)
2898.4.4 by James Henstridge
Changes to account for modifications to the XMLRPC API.
105
3251.4.3 by Aaron Bentley
More renames and cleanups
106
    def test_directory_fault(self):
2898.4.4 by James Henstridge
Changes to account for modifications to the XMLRPC API.
107
        # Test that XMLRPC faults get converted to InvalidURL errors.
108
        factory = FakeResolveFactory(self, 'apt', None)
109
        def submit(service):
110
            raise xmlrpclib.Fault(42, 'something went wrong')
111
        factory.submit = submit
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
112
        directory = LaunchpadDirectory()
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
113
        self.assertRaises(errors.InvalidURL,
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
114
                          directory._resolve, 'lp:///apt', factory)
2245.8.4 by Martin Pool
lp:/// indirection works
115
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
116
    def test_skip_bzr_ssh_launchpad_net_when_anonymous(self):
117
        # Test that bzr+ssh://bazaar.launchpad.net gets skipped if
118
        # Bazaar does not know the user's Launchpad ID:
119
        self.assertEqual(None, get_lp_login())
120
        factory = FakeResolveFactory(
121
            self, 'apt', dict(urls=[
122
                    'bzr+ssh://bazaar.launchpad.net/~apt/apt/devel',
123
                    'http://bazaar.launchpad.net/~apt/apt/devel']))
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
124
        directory = LaunchpadDirectory()
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
125
        self.assertEquals('http://bazaar.launchpad.net/~apt/apt/devel',
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
126
                          directory._resolve('lp:///apt', factory))
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
127
3031.2.2 by jml at canonical
Failing test for skipping SFTP.
128
    def test_skip_sftp_launchpad_net_when_anonymous(self):
129
        # Test that sftp://bazaar.launchpad.net gets skipped if
130
        # Bazaar does not know the user's Launchpad ID:
131
        self.assertEqual(None, get_lp_login())
132
        factory = FakeResolveFactory(
133
            self, 'apt', dict(urls=[
134
                    'sftp://bazaar.launchpad.net/~apt/apt/devel',
135
                    'http://bazaar.launchpad.net/~apt/apt/devel']))
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
136
        directory = LaunchpadDirectory()
3031.2.2 by jml at canonical
Failing test for skipping SFTP.
137
        self.assertEquals('http://bazaar.launchpad.net/~apt/apt/devel',
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
138
                          directory._resolve('lp:///apt', factory))
3031.2.2 by jml at canonical
Failing test for skipping SFTP.
139
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
140
    def test_rewrite_bzr_ssh_launchpad_net(self):
141
        # Test that bzr+ssh URLs get rewritten to include the user's
142
        # Launchpad ID (assuming we know the Launchpad ID).
143
        factory = FakeResolveFactory(
144
            self, 'apt', dict(urls=[
145
                    'bzr+ssh://bazaar.launchpad.net/~apt/apt/devel',
146
                    'http://bazaar.launchpad.net/~apt/apt/devel']))
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
147
        directory = LaunchpadDirectory()
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
148
        self.assertEquals(
149
            'bzr+ssh://username@bazaar.launchpad.net/~apt/apt/devel',
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
150
            directory._resolve('lp:///apt', factory, _lp_login='username'))
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
151
152
    def test_no_rewrite_of_other_bzr_ssh(self):
153
        # Test that we don't rewrite bzr+ssh URLs for other 
154
        self.assertEqual(None, get_lp_login())
155
        factory = FakeResolveFactory(
156
            self, 'apt', dict(urls=[
157
                    'bzr+ssh://example.com/~apt/apt/devel',
158
                    'http://bazaar.launchpad.net/~apt/apt/devel']))
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
159
        directory = LaunchpadDirectory()
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
160
        self.assertEquals('bzr+ssh://example.com/~apt/apt/devel',
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
161
                          directory._resolve('lp:///apt', factory))
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
162
2245.8.4 by Martin Pool
lp:/// indirection works
163
    # TODO: check we get an error if the url is unreasonable
3251.4.3 by Aaron Bentley
More renames and cleanups
164
    def test_error_for_bad_url(self):
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
165
        directory = LaunchpadDirectory()
2245.8.4 by Martin Pool
lp:/// indirection works
166
        self.assertRaises(errors.InvalidURL,
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
167
            directory._resolve, 'lp://ratotehunoahu')
2898.4.12 by James Henstridge
Add tests that redirects get issued by appropriate transport methods.
168
2898.4.17 by James Henstridge
Add a test that the redirect actually occurs when opening an lp: URL.
169
3251.4.3 by Aaron Bentley
More renames and cleanups
170
class DirectoryOpenBranchTests(TestCaseWithMemoryTransport):
2898.4.17 by James Henstridge
Add a test that the redirect actually occurs when opening an lp: URL.
171
3251.4.3 by Aaron Bentley
More renames and cleanups
172
    def test_directory_open_branch(self):
2898.4.17 by James Henstridge
Add a test that the redirect actually occurs when opening an lp: URL.
173
        # Test that opening an lp: branch redirects to the real location.
174
        target_branch = self.make_branch('target')
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
175
        class FooService(object):
176
            """A directory service that maps the name to a FILE url"""
177
178
            def look_up(self, name, url):
179
                if 'lp:///apt' == url:
180
                    return target_branch.base.rstrip('/')
3251.4.2 by Aaron Bentley
Clean up Launchpad directory service code
181
                return '!unexpected look_up value!'
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
182
183
        directories.remove('lp:')
184
        directories.register('lp:', FooService, 'Map lp URLs to local urls')
3251.4.2 by Aaron Bentley
Clean up Launchpad directory service code
185
        self.addCleanup(_register_directory)
3251.4.1 by Aaron Bentley
Convert LP transport into directory service
186
        self.addCleanup(lambda: directories.remove('lp:'))
2898.4.17 by James Henstridge
Add a test that the redirect actually occurs when opening an lp: URL.
187
        transport = get_transport('lp:///apt')
188
        branch = Branch.open_from_transport(transport)
189
        self.assertEqual(target_branch.base, branch.base)