~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/plugins/launchpad/test_lp_directory.py

merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007-2010 Canonical Ltd
 
1
# Copyright (C) 2007-2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
20
20
import xmlrpclib
21
21
 
22
22
from bzrlib import (
 
23
    debug,
23
24
    errors,
24
25
    tests,
25
26
    transport,
37
38
from bzrlib.plugins.launchpad.lp_directory import (
38
39
    LaunchpadDirectory)
39
40
from bzrlib.plugins.launchpad.account import get_lp_login, set_lp_login
40
 
from bzrlib.tests import (
41
 
    http_server,
42
 
    http_utils,
43
 
    )
 
41
from bzrlib.tests import http_server
44
42
 
45
43
 
46
44
def load_tests(standard_tests, module, loader):
65
63
 
66
64
 
67
65
class FakeResolveFactory(object):
 
66
 
68
67
    def __init__(self, test, expected_path, result):
69
68
        self._test = test
70
69
        self._expected_path = expected_path
71
70
        self._result = result
 
71
        self._submitted = False
72
72
 
73
73
    def __call__(self, path):
74
74
        self._test.assertEqual(self._expected_path, path)
76
76
 
77
77
    def submit(self, service):
78
78
        self._service_url = service.service_url
 
79
        self._submitted = True
79
80
        return self._result
80
81
 
81
82
 
 
83
class LocalDirectoryURLTests(TestCaseInTempDir):
 
84
    """Tests for branch urls that we try to pass through local resolution."""
 
85
 
 
86
    def assertResolve(self, expected, url, submitted=False):
 
87
        path = url[url.index(':')+1:].lstrip('/')
 
88
        factory = FakeResolveFactory(self, path,
 
89
                    dict(urls=['bzr+ssh://fake-resolved']))
 
90
        directory = LaunchpadDirectory()
 
91
        self.assertEqual(expected,
 
92
            directory._resolve(url, factory, _lp_login='user'))
 
93
        # We are testing local resolution, and the fallback when necessary.
 
94
        self.assertEqual(submitted, factory._submitted)
 
95
 
 
96
    def test_short_form(self):
 
97
        self.assertResolve('bzr+ssh://bazaar.launchpad.net/+branch/apt',
 
98
                           'lp:apt')
 
99
 
 
100
    def test_two_part_form(self):
 
101
        self.assertResolve('bzr+ssh://bazaar.launchpad.net/+branch/apt/2.2',
 
102
                           'lp:apt/2.2')
 
103
 
 
104
    def test_two_part_plus_subdir(self):
 
105
        # We allow you to pass more than just what resolves. That way you can
 
106
        # do things like "bzr log lp:apt/2.2/BUGS"
 
107
        # Though the virtual FS implementation currently aborts when given a
 
108
        # URL like this, rather than letting you recurse upwards to find the
 
109
        # real branch at lp:apt/2.2
 
110
        self.assertResolve('bzr+ssh://bazaar.launchpad.net/+branch/apt/2.2/BUGS',
 
111
                           'lp:apt/2.2/BUGS')
 
112
 
 
113
    def test_user_expansion(self):
 
114
        self.assertResolve('bzr+ssh://bazaar.launchpad.net/~user/apt/foo',
 
115
                           'lp:~/apt/foo')
 
116
 
 
117
    def test_ubuntu(self):
 
118
        # Confirmed against xmlrpc. If you don't have a ~user, xmlrpc doesn't
 
119
        # care that you are asking for 'ubuntu'
 
120
        self.assertResolve('bzr+ssh://bazaar.launchpad.net/+branch/ubuntu',
 
121
                           'lp:ubuntu')
 
122
 
 
123
    def test_ubuntu_apt(self):
 
124
        self.assertResolve('bzr+ssh://bazaar.launchpad.net/+branch/ubuntu/apt',
 
125
                           'lp:ubuntu/apt')
 
126
 
 
127
    def test_ubuntu_natty_apt(self):
 
128
        self.assertResolve(
 
129
            'bzr+ssh://bazaar.launchpad.net/+branch/ubuntu/natty/apt',
 
130
            'lp:ubuntu/natty/apt')
 
131
 
 
132
    def test_ubuntu_natty_apt_filename(self):
 
133
        self.assertResolve(
 
134
            'bzr+ssh://bazaar.launchpad.net/+branch/ubuntu/natty/apt/filename',
 
135
            'lp:ubuntu/natty/apt/filename')
 
136
 
 
137
    def test_user_two_part(self):
 
138
        # We fall back to the ResolveFactory. The real Launchpad one will raise
 
139
        # InvalidURL for this case.
 
140
        self.assertResolve('bzr+ssh://fake-resolved', 'lp:~jameinel/apt',
 
141
                           submitted=True)
 
142
 
 
143
    def test_user_three_part(self):
 
144
        self.assertResolve('bzr+ssh://bazaar.launchpad.net/~jameinel/apt/foo',
 
145
                           'lp:~jameinel/apt/foo')
 
146
 
 
147
    def test_user_three_part_plus_filename(self):
 
148
        self.assertResolve(
 
149
            'bzr+ssh://bazaar.launchpad.net/~jameinel/apt/foo/fname',
 
150
            'lp:~jameinel/apt/foo/fname')
 
151
 
 
152
    def test_user_ubuntu_two_part(self):
 
153
        self.assertResolve('bzr+ssh://fake-resolved', 'lp:~jameinel/ubuntu',
 
154
                           submitted=True)
 
155
        self.assertResolve('bzr+ssh://fake-resolved', 'lp:~jameinel/debian',
 
156
                           submitted=True)
 
157
 
 
158
    def test_user_ubuntu_three_part(self):
 
159
        self.assertResolve('bzr+ssh://fake-resolved',
 
160
                           'lp:~jameinel/ubuntu/natty', submitted=True)
 
161
        self.assertResolve('bzr+ssh://fake-resolved',
 
162
                           'lp:~jameinel/debian/sid', submitted=True)
 
163
 
 
164
    def test_user_ubuntu_four_part(self):
 
165
        self.assertResolve('bzr+ssh://fake-resolved',
 
166
                           'lp:~jameinel/ubuntu/natty/project', submitted=True)
 
167
        self.assertResolve('bzr+ssh://fake-resolved',
 
168
                           'lp:~jameinel/debian/sid/project', submitted=True)
 
169
 
 
170
    def test_user_ubuntu_five_part(self):
 
171
        self.assertResolve(
 
172
            'bzr+ssh://bazaar.launchpad.net/~jameinel/ubuntu/natty/apt/branch',
 
173
            'lp:~jameinel/ubuntu/natty/apt/branch')
 
174
        self.assertResolve(
 
175
            'bzr+ssh://bazaar.launchpad.net/~jameinel/debian/sid/apt/branch',
 
176
            'lp:~jameinel/debian/sid/apt/branch')
 
177
 
 
178
    def test_user_ubuntu_five_part_plus_subdir(self):
 
179
        self.assertResolve(
 
180
            'bzr+ssh://bazaar.launchpad.net/~jameinel/ubuntu/natty/apt/branch/f',
 
181
            'lp:~jameinel/ubuntu/natty/apt/branch/f')
 
182
        self.assertResolve(
 
183
            'bzr+ssh://bazaar.launchpad.net/~jameinel/debian/sid/apt/branch/f',
 
184
            'lp:~jameinel/debian/sid/apt/branch/f')
 
185
 
 
186
    def test_handles_special_lp(self):
 
187
        self.assertResolve('bzr+ssh://bazaar.launchpad.net/+branch/apt', 'lp:apt')
 
188
        self.assertResolve('bzr+ssh://bazaar.launchpad.net/+branch/apt',
 
189
                           'lp:///apt')
 
190
        self.assertResolve('bzr+ssh://bazaar.launchpad.net/+branch/apt',
 
191
                           'lp://production/apt')
 
192
        self.assertResolve('bzr+ssh://bazaar.launchpad.dev/+branch/apt',
 
193
                           'lp://dev/apt')
 
194
        self.assertResolve('bzr+ssh://bazaar.staging.launchpad.net/+branch/apt',
 
195
                           'lp://staging/apt')
 
196
        self.assertResolve('bzr+ssh://bazaar.qastaging.launchpad.net/+branch/apt',
 
197
                           'lp://qastaging/apt')
 
198
        self.assertResolve('bzr+ssh://bazaar.demo.launchpad.net/+branch/apt',
 
199
                           'lp://demo/apt')
 
200
 
 
201
    def test_debug_launchpad_uses_resolver(self):
 
202
        self.assertResolve('bzr+ssh://bazaar.launchpad.net/+branch/bzr',
 
203
                           'lp:bzr', submitted=False)
 
204
        debug.debug_flags.add('launchpad')
 
205
        self.addCleanup(debug.debug_flags.discard, 'launchpad')
 
206
        self.assertResolve('bzr+ssh://fake-resolved', 'lp:bzr', submitted=True)
 
207
 
 
208
 
82
209
class DirectoryUrlTests(TestCaseInTempDir):
83
210
    """Tests for branch urls through Launchpad.net directory"""
84
211
 
94
221
        self.assertEquals('https://xmlrpc.launchpad.net/bazaar/',
95
222
                          factory._service_url)
96
223
 
 
224
    def test_qastaging(self):
 
225
        """A launchpad url should map to a http url"""
 
226
        factory = FakeResolveFactory(
 
227
            self, 'apt', dict(urls=[
 
228
                    'http://bazaar.qastaging.launchpad.net/~apt/apt/devel']))
 
229
        url = 'lp://qastaging/apt'
 
230
        directory = LaunchpadDirectory()
 
231
        self.assertEquals('http://bazaar.qastaging.launchpad.net/~apt/apt/devel',
 
232
                          directory._resolve(url, factory))
 
233
        # Make sure that resolve went to the qastaging server.
 
234
        self.assertEquals('https://xmlrpc.qastaging.launchpad.net/bazaar/',
 
235
                          factory._service_url)
 
236
 
97
237
    def test_staging(self):
98
238
        """A launchpad url should map to a http url"""
99
239
        factory = FakeResolveFactory(
170
310
        self.assertEquals('http://bazaar.launchpad.net/~apt/apt/devel',
171
311
                          directory._resolve('lp:///apt', factory))
172
312
 
173
 
    def test_rewrite_bzr_ssh_launchpad_net(self):
 
313
    def test_with_login_avoid_resolve_factory(self):
174
314
        # Test that bzr+ssh URLs get rewritten to include the user's
175
315
        # Launchpad ID (assuming we know the Launchpad ID).
176
316
        factory = FakeResolveFactory(
177
317
            self, 'apt', dict(urls=[
178
 
                    'bzr+ssh://bazaar.launchpad.net/~apt/apt/devel',
 
318
                    'bzr+ssh://my-super-custom/special/devel',
179
319
                    'http://bazaar.launchpad.net/~apt/apt/devel']))
180
320
        directory = LaunchpadDirectory()
181
321
        self.assertEquals(
182
 
            'bzr+ssh://bazaar.launchpad.net/~apt/apt/devel',
 
322
            'bzr+ssh://bazaar.launchpad.net/+branch/apt',
183
323
            directory._resolve('lp:///apt', factory, _lp_login='username'))
184
324
 
185
325
    def test_no_rewrite_of_other_bzr_ssh(self):
202
342
    def test_resolve_tilde_to_user(self):
203
343
        factory = FakeResolveFactory(
204
344
            self, '~username/apt/test', dict(urls=[
205
 
                    'bzr+ssh://bazaar.launchpad.net/~username/apt/test']))
 
345
                'bzr+ssh://bazaar.launchpad.net/~username/apt/test']))
206
346
        directory = LaunchpadDirectory()
207
347
        self.assertEquals(
208
348
            'bzr+ssh://bazaar.launchpad.net/~username/apt/test',
219
359
                    'bzr+ssh://bazaar.launchpad.net/~username/apt/test']))
220
360
        self.assertIs(None, get_lp_login())
221
361
        directory = LaunchpadDirectory()
222
 
        e = self.assertRaises(errors.InvalidURL,
223
 
            directory._resolve, 'lp:~/apt/test', factory)
 
362
        self.assertRaises(errors.InvalidURL,
 
363
                          directory._resolve, 'lp:~/apt/test', factory)
224
364
 
225
365
 
226
366
class DirectoryOpenBranchTests(TestCaseWithMemoryTransport):
237
377
                return '!unexpected look_up value!'
238
378
 
239
379
        directories.remove('lp:')
 
380
        directories.remove('ubuntu:')
 
381
        directories.remove('debianlp:')
240
382
        directories.register('lp:', FooService, 'Map lp URLs to local urls')
241
383
        self.addCleanup(_register_directory)
242
384
        self.addCleanup(directories.remove, 'lp:')
259
401
    def handle_one_request(self):
260
402
        tcs = self.server.test_case_server
261
403
        requestline = self.rfile.readline()
262
 
        headers = self.MessageClass(self.rfile, 0)
 
404
        self.MessageClass(self.rfile, 0)
263
405
        if requestline.startswith('POST'):
264
406
            # The body should be a single line (or we don't know where it ends
265
407
            # and we don't want to issue a blocking read)
266
 
            body = self.rfile.readline()
 
408
            self.rfile.readline()
267
409
 
268
410
        self.wfile.write(tcs.canned_response)
269
411
 
299
441
        self.server = self.server_class()
300
442
        self.server.start_server()
301
443
        # Ensure we don't clobber env
302
 
        self._captureVar('BZR_LP_XMLRPC_URL', None)
 
444
        self.overrideEnv('BZR_LP_XMLRPC_URL', None)
303
445
 
304
446
    def tearDown(self):
305
447
        self.server.stop_server()
356
498
    # FIXME: we need to test with a real proxy, I can't find a way so simulate
357
499
    # CONNECT without leaving one server hanging the test :-/ Since that maybe
358
500
    # related to the leaking tests problems, I'll punt for now -- vila 20091030
 
501
 
 
502
 
 
503
class TestDebuntuExpansions(TestCaseInTempDir):
 
504
    """Test expansions for ubuntu: and debianlp: schemes."""
 
505
 
 
506
    def setUp(self):
 
507
        super(TestDebuntuExpansions, self).setUp()
 
508
        self.directory = LaunchpadDirectory()
 
509
 
 
510
    def _make_factory(self, package='foo', distro='ubuntu', series=None):
 
511
        if series is None:
 
512
            path = '%s/%s' % (distro, package)
 
513
            url_suffix = '~branch/%s/%s' % (distro, package)
 
514
        else:
 
515
            path = '%s/%s/%s' % (distro, series, package)
 
516
            url_suffix = '~branch/%s/%s/%s' % (distro, series, package)
 
517
        return FakeResolveFactory(
 
518
            self, path, dict(urls=[
 
519
                'http://bazaar.launchpad.net/' + url_suffix]))
 
520
 
 
521
    def assertURL(self, expected_url, shortcut, package='foo', distro='ubuntu',
 
522
                  series=None):
 
523
        factory = self._make_factory(package=package, distro=distro,
 
524
                                     series=series)
 
525
        self.assertEqual('http://bazaar.launchpad.net/~branch/' + expected_url,
 
526
                         self.directory._resolve(shortcut, factory))
 
527
 
 
528
    # Bogus distro.
 
529
 
 
530
    def test_bogus_distro(self):
 
531
        self.assertRaises(errors.InvalidURL,
 
532
                          self.directory._resolve, 'gentoo:foo')
 
533
 
 
534
    def test_trick_bogus_distro_u(self):
 
535
        self.assertRaises(errors.InvalidURL,
 
536
                          self.directory._resolve, 'utube:foo')
 
537
 
 
538
    def test_trick_bogus_distro_d(self):
 
539
        self.assertRaises(errors.InvalidURL,
 
540
                          self.directory._resolve, 'debuntu:foo')
 
541
 
 
542
    def test_missing_ubuntu_distroseries_without_project(self):
 
543
        # Launchpad does not hold source packages for Intrepid.  Missing or
 
544
        # bogus distroseries with no project name is treated like a project.
 
545
        self.assertURL('ubuntu/intrepid', 'ubuntu:intrepid', package='intrepid')
 
546
 
 
547
    def test_missing_ubuntu_distroseries_with_project(self):
 
548
        # Launchpad does not hold source packages for Intrepid.  Missing or
 
549
        # bogus distroseries with a project name is treated like an unknown
 
550
        # series (i.e. we keep it verbatim).
 
551
        self.assertURL('ubuntu/intrepid/foo',
 
552
                       'ubuntu:intrepid/foo', series='intrepid')
 
553
 
 
554
    def test_missing_debian_distroseries(self):
 
555
        # Launchpad does not hold source packages for unstable.  Missing or
 
556
        # bogus distroseries is treated like a project.
 
557
        self.assertURL('debian/sid',
 
558
                       'debianlp:sid', package='sid', distro='debian')
 
559
 
 
560
    # Ubuntu Default distro series.
 
561
 
 
562
    def test_ubuntu_default_distroseries_expansion(self):
 
563
        self.assertURL('ubuntu/foo', 'ubuntu:foo')
 
564
 
 
565
    def test_ubuntu_natty_distroseries_expansion(self):
 
566
        self.assertURL('ubuntu/natty/foo', 'ubuntu:natty/foo', series='natty')
 
567
 
 
568
    def test_ubuntu_n_distroseries_expansion(self):
 
569
        self.assertURL('ubuntu/natty/foo', 'ubuntu:n/foo', series='natty')
 
570
 
 
571
    def test_ubuntu_maverick_distroseries_expansion(self):
 
572
        self.assertURL('ubuntu/maverick/foo', 'ubuntu:maverick/foo',
 
573
                       series='maverick')
 
574
 
 
575
    def test_ubuntu_m_distroseries_expansion(self):
 
576
        self.assertURL('ubuntu/maverick/foo', 'ubuntu:m/foo', series='maverick')
 
577
 
 
578
    def test_ubuntu_lucid_distroseries_expansion(self):
 
579
        self.assertURL('ubuntu/lucid/foo', 'ubuntu:lucid/foo', series='lucid')
 
580
 
 
581
    def test_ubuntu_l_distroseries_expansion(self):
 
582
        self.assertURL('ubuntu/lucid/foo', 'ubuntu:l/foo', series='lucid')
 
583
 
 
584
    def test_ubuntu_karmic_distroseries_expansion(self):
 
585
        self.assertURL('ubuntu/karmic/foo', 'ubuntu:karmic/foo',
 
586
                       series='karmic')
 
587
 
 
588
    def test_ubuntu_k_distroseries_expansion(self):
 
589
        self.assertURL('ubuntu/karmic/foo', 'ubuntu:k/foo', series='karmic')
 
590
 
 
591
    def test_ubuntu_jaunty_distroseries_expansion(self):
 
592
        self.assertURL('ubuntu/jaunty/foo', 'ubuntu:jaunty/foo',
 
593
                       series='jaunty')
 
594
 
 
595
    def test_ubuntu_j_distroseries_expansion(self):
 
596
        self.assertURL('ubuntu/jaunty/foo', 'ubuntu:j/foo', series='jaunty')
 
597
 
 
598
    def test_ubuntu_hardy_distroseries_expansion(self):
 
599
        self.assertURL('ubuntu/hardy/foo', 'ubuntu:hardy/foo', series='hardy')
 
600
 
 
601
    def test_ubuntu_h_distroseries_expansion(self):
 
602
        self.assertURL('ubuntu/hardy/foo', 'ubuntu:h/foo', series='hardy')
 
603
 
 
604
    def test_ubuntu_dapper_distroseries_expansion(self):
 
605
        self.assertURL('ubuntu/dapper/foo', 'ubuntu:dapper/foo',
 
606
                       series='dapper')
 
607
 
 
608
    def test_ubuntu_d_distroseries_expansion(self):
 
609
        self.assertURL('ubuntu/dapper/foo', 'ubuntu:d/foo', series='dapper')
 
610
 
 
611
    # Debian default distro series.
 
612
 
 
613
    def test_debian_default_distroseries_expansion(self):
 
614
        self.assertURL('debian/foo', 'debianlp:foo', distro='debian')
 
615
 
 
616
    def test_debian_squeeze_distroseries_expansion(self):
 
617
        self.assertURL('debian/squeeze/foo', 'debianlp:squeeze/foo',
 
618
                       distro='debian', series='squeeze')
 
619
 
 
620
    def test_debian_lenny_distroseries_expansion(self):
 
621
        self.assertURL('debian/lenny/foo', 'debianlp:lenny/foo',
 
622
                       distro='debian', series='lenny')