/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2052.3.1 by John Arbash Meinel
Add tests to cleanup the copyright of all source files
1
# Copyright (C) 2005, 2006 Canonical Ltd
1540.3.24 by Martin Pool
Add new protocol 'http+pycurl' that always uses PyCurl.
2
#
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
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.
1540.3.24 by Martin Pool
Add new protocol 'http+pycurl' that always uses PyCurl.
7
#
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
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.
1540.3.24 by Martin Pool
Add new protocol 'http+pycurl' that always uses PyCurl.
12
#
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
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
1185.16.68 by Martin Pool
- http url fixes suggested by Robey Pointer, and tests
16
1540.3.3 by Martin Pool
Review updates of pycurl transport
17
# FIXME: This test should be repeated for each available http client
18
# implementation; at the moment we have urllib and pycurl.
19
1540.3.22 by Martin Pool
[patch] Add TestCase.assertIsInstance
20
# TODO: Should be renamed to bzrlib.transport.http.tests?
21
2018.2.9 by Andrew Bennetts
(Andrew Bennetts, Robert Collins) Add test_http.RecordingServer, and use it to
22
import errno
23
import select
2000.2.2 by John Arbash Meinel
Update the urllib.has test.
24
import socket
2018.2.9 by Andrew Bennetts
(Andrew Bennetts, Robert Collins) Add test_http.RecordingServer, and use it to
25
import threading
2000.2.2 by John Arbash Meinel
Update the urllib.has test.
26
1553.1.2 by James Henstridge
Add a test to make sure the user-agent header is being sent correctly.
27
import bzrlib
2018.2.9 by Andrew Bennetts
(Andrew Bennetts, Robert Collins) Add test_http.RecordingServer, and use it to
28
from bzrlib.errors import DependencyNotPresent, UnsupportedProtocol
1540.3.30 by Martin Pool
Fix up bogus-url tests for broken dns servers, and error imports
29
from bzrlib.tests import TestCase, TestSkipped
2018.2.9 by Andrew Bennetts
(Andrew Bennetts, Robert Collins) Add test_http.RecordingServer, and use it to
30
from bzrlib.transport import get_transport, Transport
1786.1.23 by John Arbash Meinel
Move offset_to_http_ranges back onto HttpTransportBase, clarify tests.
31
from bzrlib.transport.http import extract_auth, HttpTransportBase
1540.3.26 by Martin Pool
[merge] bzr.dev; pycurl not updated for readv yet
32
from bzrlib.transport.http._urllib import HttpTransport_urllib
1553.1.3 by James Henstridge
Make bzrlib.transport.http.HttpServer output referer and user agent as in
33
from bzrlib.tests.HTTPTestUtil import TestCaseWithWebserver
1185.40.20 by Robey Pointer
allow user:pass@ info in http urls to be used for auth; this should be easily expandable later to use auth config files
34
1786.1.8 by John Arbash Meinel
[merge] Johan Rydberg test updates
35
2018.2.9 by Andrew Bennetts
(Andrew Bennetts, Robert Collins) Add test_http.RecordingServer, and use it to
36
class FakeManager(object):
1786.1.8 by John Arbash Meinel
[merge] Johan Rydberg test updates
37
1185.40.20 by Robey Pointer
allow user:pass@ info in http urls to be used for auth; this should be easily expandable later to use auth config files
38
    def __init__(self):
39
        self.credentials = []
40
        
41
    def add_password(self, realm, host, username, password):
42
        self.credentials.append([realm, host, username, password])
43
1553.1.2 by James Henstridge
Add a test to make sure the user-agent header is being sent correctly.
44
2018.2.9 by Andrew Bennetts
(Andrew Bennetts, Robert Collins) Add test_http.RecordingServer, and use it to
45
class RecordingServer(object):
46
    """A fake HTTP server.
47
    
48
    It records the bytes sent to it, and replies with a 200.
49
    """
50
51
    def __init__(self, expect_body_tail=None):
2018.2.28 by Andrew Bennetts
Changes in response to review: re-use _base_curl, rather than keeping a seperate _post_curl object; add docstring to test_http.RecordingServer, set is_user_error on some new exceptions.
52
        """Constructor.
53
54
        :type expect_body_tail: str
55
        :param expect_body_tail: a reply won't be sent until this string is
56
            received.
57
        """
2018.2.9 by Andrew Bennetts
(Andrew Bennetts, Robert Collins) Add test_http.RecordingServer, and use it to
58
        self._expect_body_tail = expect_body_tail
59
        self.host = None
60
        self.port = None
61
        self.received_bytes = ''
62
63
    def setUp(self):
64
        self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
65
        self._sock.bind(('127.0.0.1', 0))
66
        self.host, self.port = self._sock.getsockname()
67
        self._ready = threading.Event()
68
        self._thread = threading.Thread(target=self._accept_read_and_reply)
69
        self._thread.setDaemon(True)
70
        self._thread.start()
71
        self._ready.wait(5)
72
73
    def _accept_read_and_reply(self):
74
        self._sock.listen(1)
75
        self._ready.set()
76
        self._sock.settimeout(5)
77
        try:
78
            conn, address = self._sock.accept()
79
            # On win32, the accepted connection will be non-blocking to start
80
            # with because we're using settimeout.
81
            conn.setblocking(True)
82
            while not self.received_bytes.endswith(self._expect_body_tail):
83
                self.received_bytes += conn.recv(4096)
84
            conn.sendall('HTTP/1.1 200 OK\r\n')
85
        except socket.timeout:
86
            # Make sure the client isn't stuck waiting for us to e.g. accept.
87
            self._sock.close()
88
89
    def tearDown(self):
90
        try:
91
            self._sock.close()
92
        except socket.error:
93
            # We might have already closed it.  We don't care.
94
            pass
95
        self.host = None
96
        self.port = None
97
98
1185.16.68 by Martin Pool
- http url fixes suggested by Robey Pointer, and tests
99
class TestHttpUrls(TestCase):
1786.1.8 by John Arbash Meinel
[merge] Johan Rydberg test updates
100
1185.40.20 by Robey Pointer
allow user:pass@ info in http urls to be used for auth; this should be easily expandable later to use auth config files
101
    def test_url_parsing(self):
102
        f = FakeManager()
103
        url = extract_auth('http://example.com', f)
104
        self.assertEquals('http://example.com', url)
105
        self.assertEquals(0, len(f.credentials))
1185.50.94 by John Arbash Meinel
Updated web page url to http://bazaar-vcs.org
106
        url = extract_auth('http://user:pass@www.bazaar-vcs.org/bzr/bzr.dev', f)
107
        self.assertEquals('http://www.bazaar-vcs.org/bzr/bzr.dev', url)
1185.40.20 by Robey Pointer
allow user:pass@ info in http urls to be used for auth; this should be easily expandable later to use auth config files
108
        self.assertEquals(1, len(f.credentials))
1185.50.94 by John Arbash Meinel
Updated web page url to http://bazaar-vcs.org
109
        self.assertEquals([None, 'www.bazaar-vcs.org', 'user', 'pass'], f.credentials[0])
1185.40.20 by Robey Pointer
allow user:pass@ info in http urls to be used for auth; this should be easily expandable later to use auth config files
110
        
1185.16.68 by Martin Pool
- http url fixes suggested by Robey Pointer, and tests
111
    def test_abs_url(self):
112
        """Construction of absolute http URLs"""
1185.50.94 by John Arbash Meinel
Updated web page url to http://bazaar-vcs.org
113
        t = HttpTransport_urllib('http://bazaar-vcs.org/bzr/bzr.dev/')
1185.16.68 by Martin Pool
- http url fixes suggested by Robey Pointer, and tests
114
        eq = self.assertEqualDiff
115
        eq(t.abspath('.'),
1185.50.94 by John Arbash Meinel
Updated web page url to http://bazaar-vcs.org
116
           'http://bazaar-vcs.org/bzr/bzr.dev')
1185.16.68 by Martin Pool
- http url fixes suggested by Robey Pointer, and tests
117
        eq(t.abspath('foo/bar'), 
1185.50.94 by John Arbash Meinel
Updated web page url to http://bazaar-vcs.org
118
           'http://bazaar-vcs.org/bzr/bzr.dev/foo/bar')
1185.16.68 by Martin Pool
- http url fixes suggested by Robey Pointer, and tests
119
        eq(t.abspath('.bzr'),
1185.50.94 by John Arbash Meinel
Updated web page url to http://bazaar-vcs.org
120
           'http://bazaar-vcs.org/bzr/bzr.dev/.bzr')
1185.16.68 by Martin Pool
- http url fixes suggested by Robey Pointer, and tests
121
        eq(t.abspath('.bzr/1//2/./3'),
1185.50.94 by John Arbash Meinel
Updated web page url to http://bazaar-vcs.org
122
           'http://bazaar-vcs.org/bzr/bzr.dev/.bzr/1/2/3')
1185.16.68 by Martin Pool
- http url fixes suggested by Robey Pointer, and tests
123
124
    def test_invalid_http_urls(self):
125
        """Trap invalid construction of urls"""
1185.50.94 by John Arbash Meinel
Updated web page url to http://bazaar-vcs.org
126
        t = HttpTransport_urllib('http://bazaar-vcs.org/bzr/bzr.dev/')
1185.16.68 by Martin Pool
- http url fixes suggested by Robey Pointer, and tests
127
        self.assertRaises(ValueError,
128
            t.abspath,
129
            '.bzr/')
130
131
    def test_http_root_urls(self):
132
        """Construction of URLs from server root"""
1540.3.26 by Martin Pool
[merge] bzr.dev; pycurl not updated for readv yet
133
        t = HttpTransport_urllib('http://bzr.ozlabs.org/')
1185.16.68 by Martin Pool
- http url fixes suggested by Robey Pointer, and tests
134
        eq = self.assertEqualDiff
135
        eq(t.abspath('.bzr/tree-version'),
136
           'http://bzr.ozlabs.org/.bzr/tree-version')
1553.1.2 by James Henstridge
Add a test to make sure the user-agent header is being sent correctly.
137
1540.3.24 by Martin Pool
Add new protocol 'http+pycurl' that always uses PyCurl.
138
    def test_http_impl_urls(self):
139
        """There are servers which ask for particular clients to connect"""
140
        try:
141
            from bzrlib.transport.http._pycurl import HttpServer_PyCurl
142
            server = HttpServer_PyCurl()
143
            try:
144
                server.setUp()
145
                url = server.get_url()
146
                self.assertTrue(url.startswith('http+pycurl://'))
147
            finally:
148
                server.tearDown()
1540.3.30 by Martin Pool
Fix up bogus-url tests for broken dns servers, and error imports
149
        except DependencyNotPresent:
1540.3.24 by Martin Pool
Add new protocol 'http+pycurl' that always uses PyCurl.
150
            raise TestSkipped('pycurl not present')
1553.1.2 by James Henstridge
Add a test to make sure the user-agent header is being sent correctly.
151
1786.1.8 by John Arbash Meinel
[merge] Johan Rydberg test updates
152
1540.3.33 by Martin Pool
Fix http tests that were failing to run tearDown when setup got a missing dependency
153
class TestHttpMixins(object):
154
155
    def _prep_tree(self):
156
        self.build_tree(['xxx', 'foo/', 'foo/bar'], line_endings='binary',
157
                        transport=self.get_transport())
1553.1.2 by James Henstridge
Add a test to make sure the user-agent header is being sent correctly.
158
159
    def test_http_has(self):
1185.50.84 by John Arbash Meinel
[merge] bzr.dev, cleanup conflicts, fixup http tests for new TestCase layout.
160
        server = self.get_readonly_server()
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
161
        t = self._transport(server.get_url())
1553.1.2 by James Henstridge
Add a test to make sure the user-agent header is being sent correctly.
162
        self.assertEqual(t.has('foo/bar'), True)
1185.50.84 by John Arbash Meinel
[merge] bzr.dev, cleanup conflicts, fixup http tests for new TestCase layout.
163
        self.assertEqual(len(server.logs), 1)
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
164
        self.assertContainsRe(server.logs[0], 
165
            r'"HEAD /foo/bar HTTP/1.." (200|302) - "-" "bzr/')
1553.1.5 by James Henstridge
Make HTTP transport has() method do HEAD requests, and update test to
166
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
167
    def test_http_has_not_found(self):
168
        server = self.get_readonly_server()
169
        t = self._transport(server.get_url())
1553.1.5 by James Henstridge
Make HTTP transport has() method do HEAD requests, and update test to
170
        self.assertEqual(t.has('not-found'), False)
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
171
        self.assertContainsRe(server.logs[1], 
172
            r'"HEAD /not-found HTTP/1.." 404 - "-" "bzr/')
1553.1.2 by James Henstridge
Add a test to make sure the user-agent header is being sent correctly.
173
174
    def test_http_get(self):
1185.50.84 by John Arbash Meinel
[merge] bzr.dev, cleanup conflicts, fixup http tests for new TestCase layout.
175
        server = self.get_readonly_server()
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
176
        t = self._transport(server.get_url())
1553.1.2 by James Henstridge
Add a test to make sure the user-agent header is being sent correctly.
177
        fp = t.get('foo/bar')
178
        self.assertEqualDiff(
179
            fp.read(),
1553.1.3 by James Henstridge
Make bzrlib.transport.http.HttpServer output referer and user agent as in
180
            'contents of foo/bar\n')
1185.50.84 by John Arbash Meinel
[merge] bzr.dev, cleanup conflicts, fixup http tests for new TestCase layout.
181
        self.assertEqual(len(server.logs), 1)
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
182
        self.assertTrue(server.logs[0].find(
183
            '"GET /foo/bar HTTP/1.1" 200 - "-" "bzr/%s' % bzrlib.__version__) > -1)
184
2018.2.3 by Andrew Bennetts
Starting factoring out the smart server client "medium" from the protocol.
185
    def test_get_smart_medium(self):
186
        # For HTTP, get_smart_medium should return the transport object.
187
        server = self.get_readonly_server()
188
        http_transport = self._transport(server.get_url())
189
        medium = http_transport.get_smart_medium()
2018.2.26 by Andrew Bennetts
Changes prompted by j-a-meinel's review.
190
        self.assertIs(medium, http_transport)
2018.2.6 by Andrew Bennetts
HTTP client starting to work (pycurl for the moment).
191
        
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
192
1540.3.33 by Martin Pool
Fix http tests that were failing to run tearDown when setup got a missing dependency
193
class TestHttpConnections_urllib(TestCaseWithWebserver, TestHttpMixins):
1786.1.8 by John Arbash Meinel
[merge] Johan Rydberg test updates
194
1540.3.33 by Martin Pool
Fix http tests that were failing to run tearDown when setup got a missing dependency
195
    _transport = HttpTransport_urllib
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
196
197
    def setUp(self):
1540.3.33 by Martin Pool
Fix http tests that were failing to run tearDown when setup got a missing dependency
198
        TestCaseWithWebserver.setUp(self)
199
        self._prep_tree()
200
2000.2.2 by John Arbash Meinel
Update the urllib.has test.
201
    def test_has_on_bogus_host(self):
202
        import urllib2
203
        # Get a random address, so that we can be sure there is no
204
        # http handler there.
205
        s = socket.socket()
206
        s.bind(('localhost', 0))
207
        t = self._transport('http://%s:%s/' % s.getsockname())
208
        self.assertRaises(urllib2.URLError, t.has, 'foo/bar')
1540.3.33 by Martin Pool
Fix http tests that were failing to run tearDown when setup got a missing dependency
209
210
211
class TestHttpConnections_pycurl(TestCaseWithWebserver, TestHttpMixins):
212
213
    def _get_pycurl_maybe(self):
1540.3.29 by Martin Pool
Prevent selftest failure when pycurl is not installed
214
        try:
215
            from bzrlib.transport.http._pycurl import PyCurlTransport
1612.1.1 by Martin Pool
Raise errors correctly on pycurl connection failure
216
            return PyCurlTransport
1540.3.30 by Martin Pool
Fix up bogus-url tests for broken dns servers, and error imports
217
        except DependencyNotPresent:
1540.3.29 by Martin Pool
Prevent selftest failure when pycurl is not installed
218
            raise TestSkipped('pycurl not present')
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
219
1540.3.33 by Martin Pool
Fix http tests that were failing to run tearDown when setup got a missing dependency
220
    _transport = property(_get_pycurl_maybe)
221
222
    def setUp(self):
223
        TestCaseWithWebserver.setUp(self)
224
        self._prep_tree()
225
226
1540.3.23 by Martin Pool
Allow urls like http+pycurl://host/ to use a particular impl
227
class TestHttpTransportRegistration(TestCase):
228
    """Test registrations of various http implementations"""
229
230
    def test_http_registered(self):
231
        import bzrlib.transport.http._urllib
232
        from bzrlib.transport import get_transport
233
        # urlllib should always be present
234
        t = get_transport('http+urllib://bzr.google.com/')
235
        self.assertIsInstance(t, Transport)
1540.3.26 by Martin Pool
[merge] bzr.dev; pycurl not updated for readv yet
236
        self.assertIsInstance(t, bzrlib.transport.http._urllib.HttpTransport_urllib)
1786.1.23 by John Arbash Meinel
Move offset_to_http_ranges back onto HttpTransportBase, clarify tests.
237
238
239
class TestOffsets(TestCase):
1786.1.28 by John Arbash Meinel
Update and add tests for the HttpTransportBase.range_header
240
    """Test offsets_to_ranges method"""
1786.1.23 by John Arbash Meinel
Move offset_to_http_ranges back onto HttpTransportBase, clarify tests.
241
242
    def test_offsets_to_ranges_simple(self):
243
        to_range = HttpTransportBase.offsets_to_ranges
1786.1.39 by John Arbash Meinel
Remove the ability to read negative offsets from readv()
244
        ranges = to_range([(10, 1)])
1786.1.23 by John Arbash Meinel
Move offset_to_http_ranges back onto HttpTransportBase, clarify tests.
245
        self.assertEqual([[10, 10]], ranges)
1786.1.39 by John Arbash Meinel
Remove the ability to read negative offsets from readv()
246
247
        ranges = to_range([(0, 1), (1, 1)])
248
        self.assertEqual([[0, 1]], ranges)
249
250
        ranges = to_range([(1, 1), (0, 1)])
251
        self.assertEqual([[0, 1]], ranges)
1786.1.23 by John Arbash Meinel
Move offset_to_http_ranges back onto HttpTransportBase, clarify tests.
252
253
    def test_offset_to_ranges_overlapped(self):
254
        to_range = HttpTransportBase.offsets_to_ranges
255
1786.1.39 by John Arbash Meinel
Remove the ability to read negative offsets from readv()
256
        ranges = to_range([(10, 1), (20, 2), (22, 5)])
257
        self.assertEqual([[10, 10], [20, 26]], ranges)
258
259
        ranges = to_range([(10, 1), (11, 2), (22, 5)])
260
        self.assertEqual([[10, 12], [22, 26]], ranges)
1786.1.23 by John Arbash Meinel
Move offset_to_http_ranges back onto HttpTransportBase, clarify tests.
261
1786.1.28 by John Arbash Meinel
Update and add tests for the HttpTransportBase.range_header
262
2018.2.9 by Andrew Bennetts
(Andrew Bennetts, Robert Collins) Add test_http.RecordingServer, and use it to
263
class TestPost(TestCase):
264
265
    def _test_post_body_is_received(self, scheme):
266
        server = RecordingServer(expect_body_tail='end-of-body')
267
        server.setUp()
268
        self.addCleanup(server.tearDown)
269
        url = '%s://%s:%s/' % (scheme, server.host, server.port)
270
        try:
271
            http_transport = get_transport(url)
272
        except UnsupportedProtocol:
273
            raise TestSkipped('%s not available' % scheme)
274
        code, response = http_transport._post('abc def end-of-body')
275
        self.assertTrue(
276
            server.received_bytes.startswith('POST /.bzr/smart HTTP/1.'))
277
        self.assertTrue('content-length: 19\r' in server.received_bytes.lower())
278
        # The transport should not be assuming that the server can accept
279
        # chunked encoding the first time it connects, because HTTP/1.1, so we
280
        # check for the literal string.
281
        self.assertTrue(
282
            server.received_bytes.endswith('\r\n\r\nabc def end-of-body'))
283
284
    def test_post_body_is_received_urllib(self):
285
        self._test_post_body_is_received('http+urllib')
286
287
    def test_post_body_is_received_pycurl(self):
288
        self._test_post_body_is_received('http+pycurl')
289
290
1786.1.28 by John Arbash Meinel
Update and add tests for the HttpTransportBase.range_header
291
class TestRangeHeader(TestCase):
292
    """Test range_header method"""
293
294
    def check_header(self, value, ranges=[], tail=0):
295
        range_header = HttpTransportBase.range_header
296
        self.assertEqual(value, range_header(ranges, tail))
297
298
    def test_range_header_single(self):
1786.1.36 by John Arbash Meinel
pycurl expects us to just set the range of bytes, not including bytes=
299
        self.check_header('0-9', ranges=[[0,9]])
300
        self.check_header('100-109', ranges=[[100,109]])
1786.1.28 by John Arbash Meinel
Update and add tests for the HttpTransportBase.range_header
301
302
    def test_range_header_tail(self):
1786.1.36 by John Arbash Meinel
pycurl expects us to just set the range of bytes, not including bytes=
303
        self.check_header('-10', tail=10)
304
        self.check_header('-50', tail=50)
1786.1.28 by John Arbash Meinel
Update and add tests for the HttpTransportBase.range_header
305
306
    def test_range_header_multi(self):
1786.1.36 by John Arbash Meinel
pycurl expects us to just set the range of bytes, not including bytes=
307
        self.check_header('0-9,100-200,300-5000',
1786.1.28 by John Arbash Meinel
Update and add tests for the HttpTransportBase.range_header
308
                          ranges=[(0,9), (100, 200), (300,5000)])
309
310
    def test_range_header_mixed(self):
1786.1.36 by John Arbash Meinel
pycurl expects us to just set the range of bytes, not including bytes=
311
        self.check_header('0-9,300-5000,-50',
1786.1.28 by John Arbash Meinel
Update and add tests for the HttpTransportBase.range_header
312
                          ranges=[(0,9), (300,5000)],
313
                          tail=50)
2018.2.9 by Andrew Bennetts
(Andrew Bennetts, Robert Collins) Add test_http.RecordingServer, and use it to
314
315
        
316
class TestRecordingServer(TestCase):
317
318
    def test_create(self):
319
        server = RecordingServer(expect_body_tail=None)
320
        self.assertEqual('', server.received_bytes)
321
        self.assertEqual(None, server.host)
322
        self.assertEqual(None, server.port)
323
324
    def test_setUp_and_tearDown(self):
325
        server = RecordingServer(expect_body_tail=None)
326
        server.setUp()
327
        try:
328
            self.assertNotEqual(None, server.host)
329
            self.assertNotEqual(None, server.port)
330
        finally:
331
            server.tearDown()
332
        self.assertEqual(None, server.host)
333
        self.assertEqual(None, server.port)
334
335
    def test_send_receive_bytes(self):
336
        server = RecordingServer(expect_body_tail='c')
337
        server.setUp()
338
        self.addCleanup(server.tearDown)
339
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
340
        sock.connect((server.host, server.port))
341
        sock.sendall('abc')
342
        self.assertEqual('HTTP/1.1 200 OK\r\n',
343
                         sock.recv(4096, socket.MSG_WAITALL))
344
        self.assertEqual('abc', server.received_bytes)