~bzr-pqm/bzr/bzr.dev

2245.8.1 by Martin Pool
Start adding tests for launchpad indirection
1
# Copyright (C) 2007 Canonical Ltd
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
17
"""Tests for indirect branch urls through Launchpad.net"""
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
25
from bzrlib.tests import TestCase, TestCaseWithMemoryTransport
26
from bzrlib.transport import get_transport
2898.4.3 by James Henstridge
Make launchpad_transport_indirect() use XMLRPC to resolve the lp: URL.
27
from bzrlib.plugins.launchpad.lp_indirect import (
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
28
    LaunchpadTransport)
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
29
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.
30
31
32
class FakeResolveFactory(object):
33
    def __init__(self, test, expected_path, result):
34
        self._test = test
35
        self._expected_path = expected_path
36
        self._result = result
37
38
    def __call__(self, path):
39
        self._test.assertEqual(self._expected_path, path)
40
        return self
41
42
    def submit(self, service):
43
        return self._result
2245.8.1 by Martin Pool
Start adding tests for launchpad indirection
44
2245.8.7 by Martin Pool
small review cleanups
45
2245.8.1 by Martin Pool
Start adding tests for launchpad indirection
46
class IndirectUrlTests(TestCase):
2245.8.7 by Martin Pool
small review cleanups
47
    """Tests for indirect branch urls through Launchpad.net"""
2245.8.1 by Martin Pool
Start adding tests for launchpad indirection
48
2245.8.5 by Martin Pool
Add short-form lp:PRODUCT url form
49
    def test_short_form(self):
50
        """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.
51
        factory = FakeResolveFactory(
2898.4.4 by James Henstridge
Changes to account for modifications to the XMLRPC API.
52
            self, 'apt', dict(urls=[
53
                    'http://bazaar.launchpad.net/~apt/apt/devel']))
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
54
        transport = LaunchpadTransport('lp:///')
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
55
        self.assertEquals('http://bazaar.launchpad.net/~apt/apt/devel',
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
56
                          transport._resolve('lp:apt', factory))
2245.8.5 by Martin Pool
Add short-form lp:PRODUCT url form
57
2245.8.3 by Martin Pool
Start adding indirection transport
58
    def test_indirect_through_url(self):
59
        """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.
60
        factory = FakeResolveFactory(
2898.4.4 by James Henstridge
Changes to account for modifications to the XMLRPC API.
61
            self, 'apt', dict(urls=[
62
                    'http://bazaar.launchpad.net/~apt/apt/devel']))
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
63
        transport = LaunchpadTransport('lp:///')
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
64
        self.assertEquals('http://bazaar.launchpad.net/~apt/apt/devel',
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
65
                          transport._resolve('lp:///apt', factory))
2898.4.3 by James Henstridge
Make launchpad_transport_indirect() use XMLRPC to resolve the lp: URL.
66
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
67
    def test_indirect_skip_bad_schemes(self):
68
        factory = FakeResolveFactory(
69
            self, 'apt', dict(urls=[
70
                    'bad-scheme://bazaar.launchpad.net/~apt/apt/devel',
71
                    'http://bazaar.launchpad.net/~apt/apt/devel',
72
                    'http://another/location']))
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
73
        transport = LaunchpadTransport('lp:///')
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
74
        self.assertEquals('http://bazaar.launchpad.net/~apt/apt/devel',
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
75
                          transport._resolve('lp:///apt', factory))
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
76
2898.4.3 by James Henstridge
Make launchpad_transport_indirect() use XMLRPC to resolve the lp: URL.
77
    def test_indirect_no_matching_schemes(self):
78
        # If the XMLRPC call does not return any protocols we support,
79
        # invalidURL is raised.
80
        factory = FakeResolveFactory(
2898.4.4 by James Henstridge
Changes to account for modifications to the XMLRPC API.
81
            self, 'apt', dict(urls=[
82
                    'bad-scheme://bazaar.launchpad.net/~apt/apt/devel']))
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
83
        transport = LaunchpadTransport('lp:///')
84
        self.assertRaises(errors.InvalidURL,
85
                          transport._resolve, 'lp:///apt', factory)
2898.4.4 by James Henstridge
Changes to account for modifications to the XMLRPC API.
86
87
    def test_indirect_fault(self):
88
        # Test that XMLRPC faults get converted to InvalidURL errors.
89
        factory = FakeResolveFactory(self, 'apt', None)
90
        def submit(service):
91
            raise xmlrpclib.Fault(42, 'something went wrong')
92
        factory.submit = submit
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
93
        transport = LaunchpadTransport('lp:///')
94
        self.assertRaises(errors.InvalidURL,
95
                          transport._resolve, 'lp:///apt', factory)
2245.8.4 by Martin Pool
lp:/// indirection works
96
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
97
    def test_skip_bzr_ssh_launchpad_net_when_anonymous(self):
98
        # Test that bzr+ssh://bazaar.launchpad.net gets skipped if
99
        # Bazaar does not know the user's Launchpad ID:
100
        self.assertEqual(None, get_lp_login())
101
        factory = FakeResolveFactory(
102
            self, 'apt', dict(urls=[
103
                    'bzr+ssh://bazaar.launchpad.net/~apt/apt/devel',
104
                    'http://bazaar.launchpad.net/~apt/apt/devel']))
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
105
        transport = LaunchpadTransport('lp:///')
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
106
        self.assertEquals('http://bazaar.launchpad.net/~apt/apt/devel',
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
107
                          transport._resolve('lp:///apt', factory))
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
108
109
    def test_rewrite_bzr_ssh_launchpad_net(self):
110
        # Test that bzr+ssh URLs get rewritten to include the user's
111
        # Launchpad ID (assuming we know the Launchpad ID).
112
        factory = FakeResolveFactory(
113
            self, 'apt', dict(urls=[
114
                    'bzr+ssh://bazaar.launchpad.net/~apt/apt/devel',
115
                    'http://bazaar.launchpad.net/~apt/apt/devel']))
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
116
        transport = LaunchpadTransport('lp:///')
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
117
        self.assertEquals(
118
            'bzr+ssh://username@bazaar.launchpad.net/~apt/apt/devel',
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
119
            transport._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
120
121
    def test_no_rewrite_of_other_bzr_ssh(self):
122
        # Test that we don't rewrite bzr+ssh URLs for other 
123
        self.assertEqual(None, get_lp_login())
124
        factory = FakeResolveFactory(
125
            self, 'apt', dict(urls=[
126
                    'bzr+ssh://example.com/~apt/apt/devel',
127
                    'http://bazaar.launchpad.net/~apt/apt/devel']))
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
128
        transport = LaunchpadTransport('lp:///')
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
129
        self.assertEquals('bzr+ssh://example.com/~apt/apt/devel',
2898.4.11 by James Henstridge
Switch back to RedirectRequested based implementation.
130
                          transport._resolve('lp:///apt', factory))
2898.4.9 by James Henstridge
Add some more tests for the bzr+ssh://bazaar.launchpad.net URL
131
2245.8.4 by Martin Pool
lp:/// indirection works
132
    # TODO: check we get an error if the url is unreasonable
133
    def test_error_for_bad_indirection(self):
134
        self.assertRaises(errors.InvalidURL,
2898.4.8 by James Henstridge
Switch lp: over to a pass-through transport, so that the XMLRPC gets
135
            LaunchpadTransport, 'lp://ratotehunoahu')
2898.4.12 by James Henstridge
Add tests that redirects get issued by appropriate transport methods.
136
137
    def catch_redirect(self, methodname, *args):
138
        transport = LaunchpadTransport('lp:///apt')
139
        def _resolve(abspath):
140
            self.assertEqual('lp:///apt', abspath)
141
            return 'http://example.com/~apt/apt/devel'
142
        transport._resolve = _resolve
143
        try:
144
            getattr(transport, methodname)(*args)
145
        except errors.RedirectRequested, exc:
146
            return exc
147
        else:
148
            raise self.failException('RedirectRequested not raised')
149
150
    def test_redirect_on_get(self):
151
        exc = self.catch_redirect('get', '.bzr/branch-format')
152
        self.assertEqual('lp:///apt/.bzr/branch-format', exc.source)
153
        self.assertEqual(
154
            'http://example.com/~apt/apt/devel/.bzr/branch-format', exc.target)
155
156
    def test_redirect_on_mkdir(self):
157
        exc = self.catch_redirect('mkdir', '.')
158
        self.assertEqual('lp:///apt', exc.source)
159
        self.assertEqual(
160
            'http://example.com/~apt/apt/devel', exc.target)
161
2898.4.17 by James Henstridge
Add a test that the redirect actually occurs when opening an lp: URL.
162
163
class IndirectOpenBranchTests(TestCaseWithMemoryTransport):
164
165
    def test_indirect_open_branch(self):
166
        # Test that opening an lp: branch redirects to the real location.
167
        target_branch = self.make_branch('target')
168
        transport = get_transport('lp:///apt')
169
        def _resolve(abspath):
170
            self.assertEqual('lp:///apt', abspath)
171
            return target_branch.base.rstrip('/')
172
        transport._resolve = _resolve
173
        branch = Branch.open_from_transport(transport)
174
        self.assertEqual(target_branch.base, branch.base)