~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_http.py

  • Committer: Rory Yorke
  • Date: 2010-10-20 14:38:53 UTC
  • mto: This revision was merged to the branch mainline in revision 5519.
  • Revision ID: rory.yorke@gmail.com-20101020143853-9kfd2ldcjfroh8jw
Show missing files in bzr status (bug 134168).

"bzr status" will now show missing files, that is, those added with "bzr
add" and then removed by non bzr means (e.g., rm).

Blackbox tests were added for this case, and tests were also added to
test_delta, since the implementation change is in bzrlib.delta.

Might also affect bug 189709.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2011 Canonical Ltd
 
1
# Copyright (C) 2005-2010 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
32
32
import bzrlib
33
33
from bzrlib import (
34
34
    bzrdir,
35
 
    cethread,
36
35
    config,
37
36
    errors,
38
37
    osutils,
179
178
        self._sock.bind(('127.0.0.1', 0))
180
179
        self.host, self.port = self._sock.getsockname()
181
180
        self._ready = threading.Event()
182
 
        self._thread = test_server.TestThread(
183
 
            sync_event=self._ready, target=self._accept_read_and_reply)
 
181
        self._thread = test_server.ThreadWithException(
 
182
            event=self._ready, target=self._accept_read_and_reply)
184
183
        self._thread.start()
185
184
        if 'threads' in tests.selftest_debug_flags:
186
185
            sys.stderr.write('Thread started: %s\n' % (self._thread.ident,))
255
254
        self.assertEqual('realm="Thou should not pass"', remainder)
256
255
 
257
256
 
258
 
class TestHTTPRangeParsing(tests.TestCase):
259
 
 
260
 
    def setUp(self):
261
 
        super(TestHTTPRangeParsing, self).setUp()
262
 
        # We focus on range  parsing here and ignore everything else
263
 
        class RequestHandler(http_server.TestingHTTPRequestHandler):
264
 
            def setup(self): pass
265
 
            def handle(self): pass
266
 
            def finish(self): pass
267
 
 
268
 
        self.req_handler = RequestHandler(None, None, None)
269
 
 
270
 
    def assertRanges(self, ranges, header, file_size):
271
 
        self.assertEquals(ranges,
272
 
                          self.req_handler._parse_ranges(header, file_size))
273
 
 
274
 
    def test_simple_range(self):
275
 
        self.assertRanges([(0,2)], 'bytes=0-2', 12)
276
 
 
277
 
    def test_tail(self):
278
 
        self.assertRanges([(8, 11)], 'bytes=-4', 12)
279
 
 
280
 
    def test_tail_bigger_than_file(self):
281
 
        self.assertRanges([(0, 11)], 'bytes=-99', 12)
282
 
 
283
 
    def test_range_without_end(self):
284
 
        self.assertRanges([(4, 11)], 'bytes=4-', 12)
285
 
 
286
 
    def test_invalid_ranges(self):
287
 
        self.assertRanges(None, 'bytes=12-22', 12)
288
 
        self.assertRanges(None, 'bytes=1-3,12-22', 12)
289
 
        self.assertRanges(None, 'bytes=-', 12)
290
 
 
291
 
 
292
257
class TestHTTPServer(tests.TestCase):
293
258
    """Test the HTTP servers implementations."""
294
259
 
389
354
 
390
355
    def test_abs_url(self):
391
356
        """Construction of absolute http URLs"""
392
 
        t = self._transport('http://example.com/bzr/bzr.dev/')
 
357
        t = self._transport('http://bazaar-vcs.org/bzr/bzr.dev/')
393
358
        eq = self.assertEqualDiff
394
 
        eq(t.abspath('.'), 'http://example.com/bzr/bzr.dev')
395
 
        eq(t.abspath('foo/bar'), 'http://example.com/bzr/bzr.dev/foo/bar')
396
 
        eq(t.abspath('.bzr'), 'http://example.com/bzr/bzr.dev/.bzr')
 
359
        eq(t.abspath('.'), 'http://bazaar-vcs.org/bzr/bzr.dev')
 
360
        eq(t.abspath('foo/bar'), 'http://bazaar-vcs.org/bzr/bzr.dev/foo/bar')
 
361
        eq(t.abspath('.bzr'), 'http://bazaar-vcs.org/bzr/bzr.dev/.bzr')
397
362
        eq(t.abspath('.bzr/1//2/./3'),
398
 
           'http://example.com/bzr/bzr.dev/.bzr/1/2/3')
 
363
           'http://bazaar-vcs.org/bzr/bzr.dev/.bzr/1/2/3')
399
364
 
400
365
    def test_invalid_http_urls(self):
401
366
        """Trap invalid construction of urls"""
402
 
        self._transport('http://example.com/bzr/bzr.dev/')
 
367
        self._transport('http://bazaar-vcs.org/bzr/bzr.dev/')
403
368
        self.assertRaises(errors.InvalidURL,
404
369
                          self._transport,
405
 
                          'http://http://example.com/bzr/bzr.dev/')
 
370
                          'http://http://bazaar-vcs.org/bzr/bzr.dev/')
406
371
 
407
372
    def test_http_root_urls(self):
408
373
        """Construction of URLs from server root"""
409
 
        t = self._transport('http://example.com/')
 
374
        t = self._transport('http://bzr.ozlabs.org/')
410
375
        eq = self.assertEqualDiff
411
376
        eq(t.abspath('.bzr/tree-version'),
412
 
           'http://example.com/.bzr/tree-version')
 
377
           'http://bzr.ozlabs.org/.bzr/tree-version')
413
378
 
414
379
    def test_http_impl_urls(self):
415
380
        """There are servers which ask for particular clients to connect"""
462
427
    """Test the http connections."""
463
428
 
464
429
    scenarios = multiply_scenarios(
465
 
        vary_by_http_client_implementation(),
 
430
        vary_by_http_client_implementation(), 
466
431
        vary_by_http_protocol_version(),
467
432
        )
468
433
 
527
492
class TestPost(tests.TestCase):
528
493
 
529
494
    scenarios = multiply_scenarios(
530
 
        vary_by_http_client_implementation(),
 
495
        vary_by_http_client_implementation(), 
531
496
        vary_by_http_protocol_version(),
532
497
        )
533
498
 
542
507
        self.assertTrue(
543
508
            server.received_bytes.startswith('POST /.bzr/smart HTTP/1.'))
544
509
        self.assertTrue('content-length: 19\r' in server.received_bytes.lower())
545
 
        self.assertTrue('content-type: application/octet-stream\r'
546
 
                        in server.received_bytes.lower())
547
510
        # The transport should not be assuming that the server can accept
548
511
        # chunked encoding the first time it connects, because HTTP/1.1, so we
549
512
        # check for the literal string.
586
549
    """
587
550
 
588
551
    scenarios = multiply_scenarios(
589
 
        vary_by_http_client_implementation(),
 
552
        vary_by_http_client_implementation(), 
590
553
        vary_by_http_protocol_version(),
591
554
        )
592
555
 
998
961
                return
999
962
            self.send_range_content(file, start, end - start + 1)
1000
963
            cur += 1
1001
 
        # Final boundary
 
964
        # No final boundary
1002
965
        self.wfile.write(boundary_line)
1003
966
 
1004
967
 
1033
996
        # that mode
1034
997
        self.assertEqual('single', t._range_hint)
1035
998
 
1036
 
 
1037
999
class LimitedRangeRequestHandler(http_server.TestingHTTPRequestHandler):
1038
1000
    """Errors out when range specifiers exceed the limit"""
1039
1001
 
1064
1026
    """Tests readv requests against a server erroring out on too much ranges."""
1065
1027
 
1066
1028
    scenarios = multiply_scenarios(
1067
 
        vary_by_http_client_implementation(),
 
1029
        vary_by_http_client_implementation(), 
1068
1030
        vary_by_http_protocol_version(),
1069
1031
        )
1070
1032
 
1108
1070
    Only the urllib implementation is tested here.
1109
1071
    """
1110
1072
 
 
1073
    def setUp(self):
 
1074
        tests.TestCase.setUp(self)
 
1075
        self._old_env = {}
 
1076
        self.addCleanup(self._restore_env)
 
1077
 
 
1078
    def _install_env(self, env):
 
1079
        for name, value in env.iteritems():
 
1080
            self._old_env[name] = osutils.set_or_unset_env(name, value)
 
1081
 
 
1082
    def _restore_env(self):
 
1083
        for name, value in self._old_env.iteritems():
 
1084
            osutils.set_or_unset_env(name, value)
 
1085
 
1111
1086
    def _proxied_request(self):
1112
1087
        handler = _urllib2_wrappers.ProxyHandler()
1113
 
        request = _urllib2_wrappers.Request('GET', 'http://baz/buzzle')
 
1088
        request = _urllib2_wrappers.Request('GET','http://baz/buzzle')
1114
1089
        handler.set_proxy(request, 'http')
1115
1090
        return request
1116
1091
 
1117
 
    def assertEvaluateProxyBypass(self, expected, host, no_proxy):
1118
 
        handler = _urllib2_wrappers.ProxyHandler()
1119
 
        self.assertEquals(expected,
1120
 
                          handler.evaluate_proxy_bypass(host, no_proxy))
1121
 
 
1122
1092
    def test_empty_user(self):
1123
 
        self.overrideEnv('http_proxy', 'http://bar.com')
1124
 
        request = self._proxied_request()
1125
 
        self.assertFalse(request.headers.has_key('Proxy-authorization'))
1126
 
 
1127
 
    def test_user_with_at(self):
1128
 
        self.overrideEnv('http_proxy',
1129
 
                         'http://username@domain:password@proxy_host:1234')
 
1093
        self._install_env({'http_proxy': 'http://bar.com'})
1130
1094
        request = self._proxied_request()
1131
1095
        self.assertFalse(request.headers.has_key('Proxy-authorization'))
1132
1096
 
1133
1097
    def test_invalid_proxy(self):
1134
1098
        """A proxy env variable without scheme"""
1135
 
        self.overrideEnv('http_proxy', 'host:1234')
 
1099
        self._install_env({'http_proxy': 'host:1234'})
1136
1100
        self.assertRaises(errors.InvalidURL, self._proxied_request)
1137
1101
 
1138
 
    def test_evaluate_proxy_bypass_true(self):
1139
 
        """The host is not proxied"""
1140
 
        self.assertEvaluateProxyBypass(True, 'example.com', 'example.com')
1141
 
        self.assertEvaluateProxyBypass(True, 'bzr.example.com', '*example.com')
1142
 
 
1143
 
    def test_evaluate_proxy_bypass_false(self):
1144
 
        """The host is proxied"""
1145
 
        self.assertEvaluateProxyBypass(False, 'bzr.example.com', None)
1146
 
 
1147
 
    def test_evaluate_proxy_bypass_unknown(self):
1148
 
        """The host is not explicitly proxied"""
1149
 
        self.assertEvaluateProxyBypass(None, 'example.com', 'not.example.com')
1150
 
        self.assertEvaluateProxyBypass(None, 'bzr.example.com', 'example.com')
1151
 
 
1152
 
    def test_evaluate_proxy_bypass_empty_entries(self):
1153
 
        """Ignore empty entries"""
1154
 
        self.assertEvaluateProxyBypass(None, 'example.com', '')
1155
 
        self.assertEvaluateProxyBypass(None, 'example.com', ',')
1156
 
        self.assertEvaluateProxyBypass(None, 'example.com', 'foo,,bar')
1157
 
 
1158
1102
 
1159
1103
class TestProxyHttpServer(http_utils.TestCaseWithTwoWebservers):
1160
1104
    """Tests proxy server.
1166
1110
    """
1167
1111
 
1168
1112
    scenarios = multiply_scenarios(
1169
 
        vary_by_http_client_implementation(),
 
1113
        vary_by_http_client_implementation(), 
1170
1114
        vary_by_http_protocol_version(),
1171
1115
        )
1172
1116
 
1189
1133
            self.no_proxy_host = self.server_host_port
1190
1134
        # The secondary server is the proxy
1191
1135
        self.proxy_url = self.get_secondary_url()
 
1136
        self._old_env = {}
1192
1137
 
1193
1138
    def _testing_pycurl(self):
1194
1139
        # TODO: This is duplicated for lots of the classes in this file
1195
1140
        return (features.pycurl.available()
1196
1141
                and self._transport == PyCurlTransport)
1197
1142
 
1198
 
    def assertProxied(self):
1199
 
        t = self.get_readonly_transport()
1200
 
        self.assertEqual('proxied contents of foo\n', t.get('foo').read())
1201
 
 
1202
 
    def assertNotProxied(self):
1203
 
        t = self.get_readonly_transport()
1204
 
        self.assertEqual('contents of foo\n', t.get('foo').read())
 
1143
    def _install_env(self, env):
 
1144
        for name, value in env.iteritems():
 
1145
            self._old_env[name] = osutils.set_or_unset_env(name, value)
 
1146
 
 
1147
    def _restore_env(self):
 
1148
        for name, value in self._old_env.iteritems():
 
1149
            osutils.set_or_unset_env(name, value)
 
1150
 
 
1151
    def proxied_in_env(self, env):
 
1152
        self._install_env(env)
 
1153
        t = self.get_readonly_transport()
 
1154
        try:
 
1155
            self.assertEqual('proxied contents of foo\n', t.get('foo').read())
 
1156
        finally:
 
1157
            self._restore_env()
 
1158
 
 
1159
    def not_proxied_in_env(self, env):
 
1160
        self._install_env(env)
 
1161
        t = self.get_readonly_transport()
 
1162
        try:
 
1163
            self.assertEqual('contents of foo\n', t.get('foo').read())
 
1164
        finally:
 
1165
            self._restore_env()
1205
1166
 
1206
1167
    def test_http_proxy(self):
1207
 
        self.overrideEnv('http_proxy', self.proxy_url)
1208
 
        self.assertProxied()
 
1168
        self.proxied_in_env({'http_proxy': self.proxy_url})
1209
1169
 
1210
1170
    def test_HTTP_PROXY(self):
1211
1171
        if self._testing_pycurl():
1214
1174
            # about. Should we ?)
1215
1175
            raise tests.TestNotApplicable(
1216
1176
                'pycurl does not check HTTP_PROXY for security reasons')
1217
 
        self.overrideEnv('HTTP_PROXY', self.proxy_url)
1218
 
        self.assertProxied()
 
1177
        self.proxied_in_env({'HTTP_PROXY': self.proxy_url})
1219
1178
 
1220
1179
    def test_all_proxy(self):
1221
 
        self.overrideEnv('all_proxy', self.proxy_url)
1222
 
        self.assertProxied()
 
1180
        self.proxied_in_env({'all_proxy': self.proxy_url})
1223
1181
 
1224
1182
    def test_ALL_PROXY(self):
1225
 
        self.overrideEnv('ALL_PROXY', self.proxy_url)
1226
 
        self.assertProxied()
 
1183
        self.proxied_in_env({'ALL_PROXY': self.proxy_url})
1227
1184
 
1228
1185
    def test_http_proxy_with_no_proxy(self):
1229
 
        self.overrideEnv('no_proxy', self.no_proxy_host)
1230
 
        self.overrideEnv('http_proxy', self.proxy_url)
1231
 
        self.assertNotProxied()
 
1186
        self.not_proxied_in_env({'http_proxy': self.proxy_url,
 
1187
                                 'no_proxy': self.no_proxy_host})
1232
1188
 
1233
1189
    def test_HTTP_PROXY_with_NO_PROXY(self):
1234
1190
        if self._testing_pycurl():
1235
1191
            raise tests.TestNotApplicable(
1236
1192
                'pycurl does not check HTTP_PROXY for security reasons')
1237
 
        self.overrideEnv('NO_PROXY', self.no_proxy_host)
1238
 
        self.overrideEnv('HTTP_PROXY', self.proxy_url)
1239
 
        self.assertNotProxied()
 
1193
        self.not_proxied_in_env({'HTTP_PROXY': self.proxy_url,
 
1194
                                 'NO_PROXY': self.no_proxy_host})
1240
1195
 
1241
1196
    def test_all_proxy_with_no_proxy(self):
1242
 
        self.overrideEnv('no_proxy', self.no_proxy_host)
1243
 
        self.overrideEnv('all_proxy', self.proxy_url)
1244
 
        self.assertNotProxied()
 
1197
        self.not_proxied_in_env({'all_proxy': self.proxy_url,
 
1198
                                 'no_proxy': self.no_proxy_host})
1245
1199
 
1246
1200
    def test_ALL_PROXY_with_NO_PROXY(self):
1247
 
        self.overrideEnv('NO_PROXY', self.no_proxy_host)
1248
 
        self.overrideEnv('ALL_PROXY', self.proxy_url)
1249
 
        self.assertNotProxied()
 
1201
        self.not_proxied_in_env({'ALL_PROXY': self.proxy_url,
 
1202
                                 'NO_PROXY': self.no_proxy_host})
1250
1203
 
1251
1204
    def test_http_proxy_without_scheme(self):
1252
 
        self.overrideEnv('http_proxy', self.server_host_port)
1253
1205
        if self._testing_pycurl():
1254
1206
            # pycurl *ignores* invalid proxy env variables. If that ever change
1255
1207
            # in the future, this test will fail indicating that pycurl do not
1256
1208
            # ignore anymore such variables.
1257
 
            self.assertNotProxied()
 
1209
            self.not_proxied_in_env({'http_proxy': self.server_host_port})
1258
1210
        else:
1259
 
            self.assertRaises(errors.InvalidURL, self.assertProxied)
 
1211
            self.assertRaises(errors.InvalidURL,
 
1212
                              self.proxied_in_env,
 
1213
                              {'http_proxy': self.server_host_port})
1260
1214
 
1261
1215
 
1262
1216
class TestRanges(http_utils.TestCaseWithWebserver):
1263
1217
    """Test the Range header in GET methods."""
1264
1218
 
1265
1219
    scenarios = multiply_scenarios(
1266
 
        vary_by_http_client_implementation(),
 
1220
        vary_by_http_client_implementation(), 
1267
1221
        vary_by_http_protocol_version(),
1268
1222
        )
1269
1223
 
1313
1267
    """Test redirection between http servers."""
1314
1268
 
1315
1269
    scenarios = multiply_scenarios(
1316
 
        vary_by_http_client_implementation(),
 
1270
        vary_by_http_client_implementation(), 
1317
1271
        vary_by_http_protocol_version(),
1318
1272
        )
1319
1273
 
1386
1340
    """
1387
1341
 
1388
1342
    scenarios = multiply_scenarios(
1389
 
        vary_by_http_client_implementation(),
 
1343
        vary_by_http_client_implementation(), 
1390
1344
        vary_by_http_protocol_version(),
1391
1345
        )
1392
1346
 
1441
1395
    """Test transport.do_catching_redirections."""
1442
1396
 
1443
1397
    scenarios = multiply_scenarios(
1444
 
        vary_by_http_client_implementation(),
 
1398
        vary_by_http_client_implementation(), 
1445
1399
        vary_by_http_protocol_version(),
1446
1400
        )
1447
1401
 
1750
1704
 
1751
1705
    def setUp(self):
1752
1706
        super(TestProxyAuth, self).setUp()
 
1707
        self._old_env = {}
 
1708
        self.addCleanup(self._restore_env)
1753
1709
        # Override the contents to avoid false positives
1754
1710
        self.build_tree_contents([('a', 'not proxied contents of a\n'),
1755
1711
                                  ('b', 'not proxied contents of b\n'),
1758
1714
                                  ])
1759
1715
 
1760
1716
    def get_user_transport(self, user, password):
1761
 
        self.overrideEnv('all_proxy', self.get_user_url(user, password))
 
1717
        self._install_env({'all_proxy': self.get_user_url(user, password)})
1762
1718
        return TestAuth.get_user_transport(self, user, password)
1763
1719
 
 
1720
    def _install_env(self, env):
 
1721
        for name, value in env.iteritems():
 
1722
            self._old_env[name] = osutils.set_or_unset_env(name, value)
 
1723
 
 
1724
    def _restore_env(self):
 
1725
        for name, value in self._old_env.iteritems():
 
1726
            osutils.set_or_unset_env(name, value)
 
1727
 
1764
1728
    def test_empty_pass(self):
1765
1729
        if self._testing_pycurl():
1766
1730
            import pycurl
1796
1760
class SmartHTTPTunnellingTest(tests.TestCaseWithTransport):
1797
1761
 
1798
1762
    scenarios = multiply_scenarios(
1799
 
        vary_by_http_client_implementation(),
 
1763
        vary_by_http_client_implementation(), 
1800
1764
        vary_by_http_protocol_version(),
1801
1765
        )
1802
1766
 
1803
1767
    def setUp(self):
1804
1768
        super(SmartHTTPTunnellingTest, self).setUp()
1805
1769
        # We use the VFS layer as part of HTTP tunnelling tests.
1806
 
        self.overrideEnv('BZR_NO_SMART_VFS', None)
 
1770
        self._captureVar('BZR_NO_SMART_VFS', None)
1807
1771
        self.transport_readonly_server = http_utils.HTTPServerWithSmarts
1808
1772
        self.http_server = self.get_readonly_server()
1809
1773