diff options
| author | Chris McDonough <chrism@plope.com> | 2011-12-30 02:06:46 -0500 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2011-12-30 02:06:46 -0500 |
| commit | b33f1aeb9f24010a4e0ed68585dd931efb900531 (patch) | |
| tree | 5f1ec319d3ede92a672ea664301822209fa0b948 | |
| parent | c68c03332f0f2639ceb118c2d0e5e9f1a6c6a7a6 (diff) | |
| download | waitress-pipelinefix.tar.gz | |
coveragepipelinefix
| -rw-r--r-- | docs/differences.rst | 2 | ||||
| -rw-r--r-- | waitress/buffers.py | 10 | ||||
| -rw-r--r-- | waitress/channel.py | 2 | ||||
| -rw-r--r-- | waitress/tests/test_adjustments.py | 4 | ||||
| -rw-r--r-- | waitress/tests/test_buffers.py | 16 | ||||
| -rw-r--r-- | waitress/tests/test_channel.py | 68 | ||||
| -rw-r--r-- | waitress/tests/test_functional.py | 8 | ||||
| -rw-r--r-- | waitress/tests/test_parser.py | 24 | ||||
| -rw-r--r-- | waitress/tests/test_receiver.py | 7 | ||||
| -rw-r--r-- | waitress/tests/test_task.py | 397 |
10 files changed, 329 insertions, 209 deletions
diff --git a/docs/differences.rst b/docs/differences.rst index 94e7e50..99a32af 100644 --- a/docs/differences.rst +++ b/docs/differences.rst @@ -55,4 +55,4 @@ Differences from ``zope.server`` premature channel closes). - Send a 500 error to the client when a task raises an uncaught exception - (with optional traceback rendering). + (with optional traceback rendering via "expose_traceback" adjustment). diff --git a/waitress/buffers.py b/waitress/buffers.py index 6c855ed..6e8eab2 100644 --- a/waitress/buffers.py +++ b/waitress/buffers.py @@ -45,10 +45,10 @@ class FileBasedBuffer(object): def __len__(self): return self.remain - def __bool__(self): - return self.remain >= 0 + def __nonzero__(self): + return self.remain > 0 - __nonzero__ = __bool__ + __bool__ = __nonzero__ # py3 def append(self, s): file = self.file @@ -157,10 +157,10 @@ class OverflowableBuffer(object): else: return len(self.strbuf) - def __bool__(self): + def __nonzero__(self): return bool(len(self)) - __nonzero__ = __bool__ + __bool__ = __nonzero__ # py3 def _create_buffer(self): strbuf = self.strbuf diff --git a/waitress/channel.py b/waitress/channel.py index b00743d..0c3f5a6 100644 --- a/waitress/channel.py +++ b/waitress/channel.py @@ -134,7 +134,7 @@ class HTTPChannel(logging_dispatcher, object): return False chunk = self.inbuf.get(self.adj.recv_bytes) if not chunk: - return + return False if self.request is None: self.request = self.parser_class(self.adj) request = self.request diff --git a/waitress/tests/test_adjustments.py b/waitress/tests/test_adjustments.py index aeaa0d2..7a9767d 100644 --- a/waitress/tests/test_adjustments.py +++ b/waitress/tests/test_adjustments.py @@ -49,7 +49,8 @@ class TestAdjustments(unittest.TestCase): send_bytes='300', outbuf_overflow='400', inbuf_overflow='500', connection_limit='1000', cleanup_interval='1100', channel_timeout='1200', log_socket_errors='true', - max_request_header_size='1300', max_request_body_size='1400') + max_request_header_size='1300', max_request_body_size='1400', + expose_tracebacks='true') self.assertEqual(inst.host, 'host') self.assertEqual(inst.port, 8080) self.assertEqual(inst.threads, 5) @@ -65,6 +66,7 @@ class TestAdjustments(unittest.TestCase): self.assertEqual(inst.log_socket_errors, True) self.assertEqual(inst.max_request_header_size, 1300) self.assertEqual(inst.max_request_body_size, 1400) + self.assertEqual(inst.expose_tracebacks, True) def test_badvar(self): self.assertRaises(ValueError, self._makeOne, nope=True) diff --git a/waitress/tests/test_buffers.py b/waitress/tests/test_buffers.py index 7766536..19d79df 100644 --- a/waitress/tests/test_buffers.py +++ b/waitress/tests/test_buffers.py @@ -24,6 +24,13 @@ class TestFileBasedBuffer(unittest.TestCase): inst.remain = 10 self.assertEqual(len(inst), 10) + def test___nonzero__(self): + inst = self._makeOne() + inst.remain = 10 + self.assertEqual(bool(inst), True) + inst.remain = 0 + self.assertEqual(bool(inst), False) + def test_append(self): f = io.BytesIO(b'data') inst = self._makeOne(f) @@ -137,9 +144,16 @@ class TestOverflowableBuffer(unittest.TestCase): def test___len__buf_is_not_None(self): inst = self._makeOne() - inst.buf = 'abc' + inst.buf = b'abc' self.assertEqual(len(inst), 3) + def test___nonzero__(self): + inst = self._makeOne() + inst.buf = b'abc' + self.assertEqual(bool(inst), True) + inst.buf = b'' + self.assertEqual(bool(inst), False) + def test__create_buffer_large(self): from waitress.buffers import TempfileBasedBuffer inst = self._makeOne() diff --git a/waitress/tests/test_channel.py b/waitress/tests/test_channel.py index 744883d..fffd357 100644 --- a/waitress/tests/test_channel.py +++ b/waitress/tests/test_channel.py @@ -99,6 +99,15 @@ class TestHTTPChannel(unittest.TestCase): inst.task = True self.assertEqual(inst.readable(), False) + def test_readable_with_nonempty_inbuf_calls_received(self): + inst, sock, map = self._makeOneWithMap() + L = [] + inst.received = lambda: L.append(True) + inst.task = None + inst.inbuf = True + self.assertEqual(inst.readable(), True) + self.assertEqual(len(L), 1) + def test_handle_read_no_error(self): inst, sock, map = self._makeOneWithMap() inst.will_close = False @@ -216,6 +225,15 @@ class TestHTTPChannel(unittest.TestCase): self.assertEqual(inst.server.tasks, [inst]) self.assertTrue(inst.task) + def test_received_with_task(self): + inst, sock, map = self._makeOneWithMap() + inst.task = True + self.assertEqual(inst.received(), False) + + def test_received_no_chunk(self): + inst, sock, map = self._makeOneWithMap() + self.assertEqual(inst.received(), False) + def test_received_preq_not_completed(self): inst, sock, map = self._makeOneWithMap() inst.server = DummyServer() @@ -228,7 +246,7 @@ class TestHTTPChannel(unittest.TestCase): self.assertEqual(inst.task, None) self.assertEqual(inst.server.tasks, []) - def test_received_preq_completed(self): + def test_received_preq_completed_empty(self): inst, sock, map = self._makeOneWithMap() inst.server = DummyServer() preq = DummyParser() @@ -240,6 +258,19 @@ class TestHTTPChannel(unittest.TestCase): self.assertEqual(inst.request, None) self.assertEqual(inst.server.tasks, []) + def test_received_preq_error(self): + inst, sock, map = self._makeOneWithMap() + inst.server = DummyServer() + preq = DummyParser() + inst.request = preq + preq.completed = True + preq.error = True + inst.inbuf.append(b'GET / HTTP/1.1\n\n') + inst.received() + self.assertEqual(inst.request, None) + self.assertEqual(len(inst.server.tasks), 1) + self.assertTrue(inst.task) + def test_received_preq_completed_connection_close(self): inst, sock, map = self._makeOneWithMap() inst.server = DummyServer() @@ -248,10 +279,12 @@ class TestHTTPChannel(unittest.TestCase): preq.completed = True preq.empty = True preq.connection_close = True - inst.inbuf.append(b'GET / HTTP/1.1\n\n') + inbuf = inst.inbuf + inbuf.append(b'GET / HTTP/1.1\n\n' + b'a' * 50000) inst.received() self.assertEqual(inst.request, None) self.assertEqual(inst.server.tasks, []) + self.assertNotEqual(inst.inbuf, inbuf) def test_received_preq_completed_n_lt_data(self): inst, sock, map = self._makeOneWithMap() @@ -382,14 +415,45 @@ class TestHTTPChannel(unittest.TestCase): def test_service_with_task_raises(self): inst, sock, map = self._makeOneWithMap() + inst.adj.expose_tracebacks = False + inst.server = DummyServer() + task = DummyTask(ValueError) + task.wrote_header = False + inst.task = task + inst.logger = DummyLogger() + inst.service() + self.assertTrue(task.serviced) + self.assertEqual(inst.task, None) + self.assertEqual(len(inst.logger.exceptions), 1) + self.assertTrue(sock.sent) + + def test_service_with_task_raises_with_expose_tbs(self): + inst, sock, map = self._makeOneWithMap() + inst.adj.expose_tracebacks = True + inst.server = DummyServer() + task = DummyTask(ValueError) + task.wrote_header = False + inst.task = task + inst.logger = DummyLogger() + inst.service() + self.assertTrue(task.serviced) + self.assertEqual(inst.task, None) + self.assertEqual(len(inst.logger.exceptions), 1) + self.assertTrue(sock.sent) + + def test_service_with_task_raises_already_wrote_header(self): + inst, sock, map = self._makeOneWithMap() + inst.adj.expose_tracebacks = False inst.server = DummyServer() task = DummyTask(ValueError) + task.wrote_header = True inst.task = task inst.logger = DummyLogger() inst.service() self.assertTrue(task.serviced) self.assertEqual(inst.task, None) self.assertEqual(len(inst.logger.exceptions), 1) + self.assertFalse(sock.sent) def test_cancel_no_task(self): inst, sock, map = self._makeOneWithMap() diff --git a/waitress/tests/test_functional.py b/waitress/tests/test_functional.py index 87c316e..9016375 100644 --- a/waitress/tests/test_functional.py +++ b/waitress/tests/test_functional.py @@ -791,7 +791,8 @@ def parse_headers(fp): class ConnectionClosed(Exception): pass -def read_http(fp): +# stolen from gevent +def read_http(fp): # pragma: no cover try: response_line = fp.readline() except socket.error as exc: @@ -827,8 +828,9 @@ def read_http(fp): body = fp.read() return response_line, headers, body - -def get_errno(exc): + +# stolen from gevent +def get_errno(exc): # pragma: no cover """ Get the error code out of socket.error objects. socket.error in <2.5 does not have errno attribute socket.error in 3.x does not allow indexing access diff --git a/waitress/tests/test_parser.py b/waitress/tests/test_parser.py index 2e8d469..8111e3f 100644 --- a/waitress/tests/test_parser.py +++ b/waitress/tests/test_parser.py @@ -128,7 +128,7 @@ GET /foobar HTTP/8.4 self.assertEqual(result, 0) def test_received_cl_too_large(self): - from waitress.parser import RequestEntityTooLarge + from waitress.utilities import RequestEntityTooLarge self.parser.adj.max_request_body_size = 2 data = b"""\ GET /foobar HTTP/8.4 @@ -141,7 +141,7 @@ Content-Length: 10 self.assertTrue(isinstance(self.parser.error, RequestEntityTooLarge)) def test_received_headers_too_large(self): - from waitress.parser import RequestHeaderFieldsTooLarge + from waitress.utilities import RequestHeaderFieldsTooLarge self.parser.adj.max_request_header_size = 2 data = b"""\ GET /foobar HTTP/8.4 @@ -154,7 +154,7 @@ X-Foo: 1 RequestHeaderFieldsTooLarge)) def test_received_body_too_large(self): - from waitress.parser import RequestEntityTooLarge + from waitress.utilities import RequestEntityTooLarge self.parser.adj.max_request_body_size = 2 data = b"""\ GET /foobar HTTP/1.1 @@ -171,6 +171,24 @@ This string has 32 characters\r self.assertTrue(isinstance(self.parser.error, RequestEntityTooLarge)) + def test_received_error_from_parser(self): + from waitress.utilities import BadRequest + data = b"""\ +GET /foobar HTTP/1.1 +Transfer-Encoding: chunked +X-Foo: 1 + +garbage +""" + # header + result = self.parser.received(data) + # body + result = self.parser.received(data[result:]) + self.assertEqual(result, 8) + self.assertTrue(self.parser.completed) + self.assertTrue(isinstance(self.parser.error, + BadRequest)) + def test_parse_header_gardenpath(self): data = b"""\ GET /foobar HTTP/8.4 diff --git a/waitress/tests/test_receiver.py b/waitress/tests/test_receiver.py index a331d73..a7b0e93 100644 --- a/waitress/tests/test_receiver.py +++ b/waitress/tests/test_receiver.py @@ -66,6 +66,13 @@ class TestChunkedReceiver(unittest.TestCase): self.assertEqual(result, 1) self.assertEqual(inst.completed, False) + def test_received_control_line_finished_garbage_in_input(self): + buf = DummyBuffer() + inst = self._makeOne(buf) + result = inst.received(b'garbage\n') + self.assertEqual(result, 8) + self.assertTrue(inst.error) + def test_received_control_line_finished_all_chunks_not_received(self): buf = DummyBuffer() inst = self._makeOne(buf) diff --git a/waitress/tests/test_task.py b/waitress/tests/test_task.py index 4429bfc..2c651f1 100644 --- a/waitress/tests/test_task.py +++ b/waitress/tests/test_task.py @@ -91,37 +91,20 @@ class TestThreadedTaskDispatcher(unittest.TestCase): self.assertEqual(inst.shutdown(cancel_pending=False, timeout=.01), False) -class TestWSGITask(unittest.TestCase): +class TestTask(unittest.TestCase): def _makeOne(self, channel=None, request=None): if channel is None: channel = DummyChannel() if request is None: request = DummyParser() - from waitress.task import WSGITask - return WSGITask(channel, request) + from waitress.task import Task + return Task(channel, request) - def test_service(self): - inst = self._makeOne() - def execute(): - inst.executed = True - inst.execute = execute - inst.complete = True - inst.service() - self.assertTrue(inst.start_time) - self.assertTrue(inst.close_on_finish) - self.assertTrue(inst.channel.written) - self.assertEqual(inst.executed, True) - - def test_service_server_raises_socket_error(self): - import socket - inst = self._makeOne() - def execute(): - raise socket.error - inst.execute = execute - self.assertRaises(socket.error, inst.service) - self.assertTrue(inst.start_time) - self.assertTrue(inst.close_on_finish) - self.assertFalse(inst.channel.written) + def test_ctor_version_not_in_known(self): + request = DummyParser() + request.version = '8.4' + inst = self._makeOne(request=request) + self.assertEqual(inst.version, '1.0') def test_cancel(self): inst = self._makeOne() @@ -132,125 +115,6 @@ class TestWSGITask(unittest.TestCase): inst = self._makeOne() self.assertEqual(inst.defer(), None) - def test_execute_app_calls_start_response_twice_wo_exc_info(self): - def app(environ, start_response): - start_response('200 OK', []) - start_response('200 OK', []) - inst = self._makeOne() - inst.channel.server.application = app - self.assertRaises(AssertionError, inst.execute) - - def test_execute_app_calls_start_response_w_exc_info_complete(self): - def app(environ, start_response): - start_response('200 OK', [], [ValueError, ValueError(), None]) - inst = self._makeOne() - inst.complete = True - inst.channel.server.application = app - self.assertRaises(ValueError, inst.execute) - - def test_execute_app_calls_start_response_w_exc_info_incomplete(self): - def app(environ, start_response): - start_response('200 OK', [], [ValueError, None, None]) - return [b'a'] - inst = self._makeOne() - inst.complete = False - inst.channel.server.application = app - inst.execute() - self.assertTrue(inst.complete) - self.assertEqual(inst.status, '200 OK') - self.assertTrue(inst.channel.written) - - def test_execute_bad_header_key(self): - def app(environ, start_response): - start_response('200 OK', [(None, 'a')]) - inst = self._makeOne() - inst.channel.server.application = app - self.assertRaises(AssertionError, inst.execute) - - def test_execute_bad_header_value(self): - def app(environ, start_response): - start_response('200 OK', [('a', None)]) - inst = self._makeOne() - inst.channel.server.application = app - self.assertRaises(AssertionError, inst.execute) - - def test_execute_bad_status_value(self): - def app(environ, start_response): - start_response(None, []) - inst = self._makeOne() - inst.channel.server.application = app - self.assertRaises(AssertionError, inst.execute) - - def test_execute_with_content_length_header(self): - def app(environ, start_response): - start_response('200 OK', [('Content-Length', '1')]) - return [b'a'] - inst = self._makeOne() - inst.channel.server.application = app - inst.execute() - self.assertEqual(inst.content_length, 1) - - def test_execute_app_calls_write(self): - def app(environ, start_response): - write = start_response('200 OK', [('Content-Length', '3')]) - write(b'abc') - return [] - inst = self._makeOne() - inst.channel.server.application = app - inst.execute() - self.assertEqual(inst.channel.written[-3:], b'abc') - - def test_execute_app_returns_len1_chunk_without_cl(self): - def app(environ, start_response): - start_response('200 OK', []) - return [b'abc'] - inst = self._makeOne() - inst.channel.server.application = app - inst.execute() - self.assertEqual(inst.content_length, 3) - - def test_execute_app_returns_empty_chunk_as_first(self): - def app(environ, start_response): - start_response('200 OK', []) - return ['', b'abc'] - inst = self._makeOne() - inst.channel.server.application = app - inst.execute() - self.assertEqual(inst.content_length, -1) - - def test_execute_app_returns_too_many_bytes(self): - def app(environ, start_response): - start_response('200 OK', [('Content-Length', '1')]) - return [b'abc'] - inst = self._makeOne() - inst.channel.server.application = app - inst.execute() - self.assertEqual(inst.close_on_finish, True) - self.assertTrue(inst.channel.server.logged) - - def test_execute_app_returns_too_few_bytes(self): - def app(environ, start_response): - start_response('200 OK', [('Content-Length', '3')]) - return [b'a'] - inst = self._makeOne() - inst.channel.server.application = app - inst.execute() - self.assertEqual(inst.close_on_finish, True) - self.assertTrue(inst.channel.server.logged) - - def test_execute_app_returns_closeable(self): - class closeable(list): - def close(self): - self.closed = True - foo = closeable([b'abc']) - def app(environ, start_response): - start_response('200 OK', [('Content-Length', '3')]) - return foo - inst = self._makeOne() - inst.channel.server.application = app - inst.execute() - self.assertEqual(foo.closed, True) - def test_build_response_header_v10_keepalive_no_content_length(self): inst = self._makeOne() inst.request = DummyParser() @@ -438,6 +302,203 @@ class TestWSGITask(unittest.TestCase): self.assertTrue(lines[2].startswith(b'Date:')) self.assertEqual(lines[3], b'Server: waitress') + def test_start(self): + inst = self._makeOne() + inst.start() + self.assertTrue(inst.start_time) + + def test_finish_didnt_write_header(self): + inst = self._makeOne() + inst.wrote_header = False + inst.complete = True + inst.finish() + self.assertTrue(inst.channel.written) + + def test_finish_wrote_header(self): + inst = self._makeOne() + inst.wrote_header = True + inst.finish() + self.assertFalse(inst.channel.written) + + def test_write_wrote_header(self): + inst = self._makeOne() + inst.wrote_header = True + inst.complete = True + inst.write(b'abc') + self.assertEqual(inst.channel.written, b'abc') + + def test_write_header_not_written(self): + inst = self._makeOne() + inst.wrote_header = False + inst.complete = True + inst.write(b'abc') + self.assertTrue(inst.channel.written) + self.assertEqual(inst.wrote_header, True) + + def test_write_start_response_uncalled(self): + inst = self._makeOne() + self.assertRaises(RuntimeError, inst.write, b'') + + def test_write_preexisting_content_length(self): + inst = self._makeOne() + inst.wrote_header = True + inst.complete = True + inst.content_length = 1 + inst.write(b'abc') + self.assertTrue(inst.channel.written) + self.assertEqual(inst.logged_write_excess, True) + +class TestWSGITask(unittest.TestCase): + def _makeOne(self, channel=None, request=None): + if channel is None: + channel = DummyChannel() + if request is None: + request = DummyParser() + from waitress.task import WSGITask + return WSGITask(channel, request) + + def test_service(self): + inst = self._makeOne() + def execute(): + inst.executed = True + inst.execute = execute + inst.complete = True + inst.service() + self.assertTrue(inst.start_time) + self.assertTrue(inst.close_on_finish) + self.assertTrue(inst.channel.written) + self.assertEqual(inst.executed, True) + + def test_service_server_raises_socket_error(self): + import socket + inst = self._makeOne() + def execute(): + raise socket.error + inst.execute = execute + self.assertRaises(socket.error, inst.service) + self.assertTrue(inst.start_time) + self.assertTrue(inst.close_on_finish) + self.assertFalse(inst.channel.written) + + def test_execute_app_calls_start_response_twice_wo_exc_info(self): + def app(environ, start_response): + start_response('200 OK', []) + start_response('200 OK', []) + inst = self._makeOne() + inst.channel.server.application = app + self.assertRaises(AssertionError, inst.execute) + + def test_execute_app_calls_start_response_w_exc_info_complete(self): + def app(environ, start_response): + start_response('200 OK', [], [ValueError, ValueError(), None]) + inst = self._makeOne() + inst.complete = True + inst.channel.server.application = app + self.assertRaises(ValueError, inst.execute) + + def test_execute_app_calls_start_response_w_exc_info_incomplete(self): + def app(environ, start_response): + start_response('200 OK', [], [ValueError, None, None]) + return [b'a'] + inst = self._makeOne() + inst.complete = False + inst.channel.server.application = app + inst.execute() + self.assertTrue(inst.complete) + self.assertEqual(inst.status, '200 OK') + self.assertTrue(inst.channel.written) + + def test_execute_bad_header_key(self): + def app(environ, start_response): + start_response('200 OK', [(None, 'a')]) + inst = self._makeOne() + inst.channel.server.application = app + self.assertRaises(AssertionError, inst.execute) + + def test_execute_bad_header_value(self): + def app(environ, start_response): + start_response('200 OK', [('a', None)]) + inst = self._makeOne() + inst.channel.server.application = app + self.assertRaises(AssertionError, inst.execute) + + def test_execute_bad_status_value(self): + def app(environ, start_response): + start_response(None, []) + inst = self._makeOne() + inst.channel.server.application = app + self.assertRaises(AssertionError, inst.execute) + + def test_execute_with_content_length_header(self): + def app(environ, start_response): + start_response('200 OK', [('Content-Length', '1')]) + return [b'a'] + inst = self._makeOne() + inst.channel.server.application = app + inst.execute() + self.assertEqual(inst.content_length, 1) + + def test_execute_app_calls_write(self): + def app(environ, start_response): + write = start_response('200 OK', [('Content-Length', '3')]) + write(b'abc') + return [] + inst = self._makeOne() + inst.channel.server.application = app + inst.execute() + self.assertEqual(inst.channel.written[-3:], b'abc') + + def test_execute_app_returns_len1_chunk_without_cl(self): + def app(environ, start_response): + start_response('200 OK', []) + return [b'abc'] + inst = self._makeOne() + inst.channel.server.application = app + inst.execute() + self.assertEqual(inst.content_length, 3) + + def test_execute_app_returns_empty_chunk_as_first(self): + def app(environ, start_response): + start_response('200 OK', []) + return ['', b'abc'] + inst = self._makeOne() + inst.channel.server.application = app + inst.execute() + self.assertEqual(inst.content_length, -1) + + def test_execute_app_returns_too_many_bytes(self): + def app(environ, start_response): + start_response('200 OK', [('Content-Length', '1')]) + return [b'abc'] + inst = self._makeOne() + inst.channel.server.application = app + inst.execute() + self.assertEqual(inst.close_on_finish, True) + self.assertTrue(inst.channel.server.logged) + + def test_execute_app_returns_too_few_bytes(self): + def app(environ, start_response): + start_response('200 OK', [('Content-Length', '3')]) + return [b'a'] + inst = self._makeOne() + inst.channel.server.application = app + inst.execute() + self.assertEqual(inst.close_on_finish, True) + self.assertTrue(inst.channel.server.logged) + + def test_execute_app_returns_closeable(self): + class closeable(list): + def close(self): + self.closed = True + foo = closeable([b'abc']) + def app(environ, start_response): + start_response('200 OK', [('Content-Length', '3')]) + return foo + inst = self._makeOne() + inst.channel.server.application = app + inst.execute() + self.assertEqual(foo.closed, True) + def test_get_environment_already_cached(self): inst = self._makeOne() inst.environ = object() @@ -504,52 +565,6 @@ class TestWSGITask(unittest.TestCase): self.assertEqual(environ['wsgi.input'], 'stream') self.assertEqual(inst.environ, environ) - def test_start(self): - inst = self._makeOne() - inst.start() - self.assertTrue(inst.start_time) - - def test_finish_didnt_write_header(self): - inst = self._makeOne() - inst.wrote_header = False - inst.complete = True - inst.finish() - self.assertTrue(inst.channel.written) - - def test_finish_wrote_header(self): - inst = self._makeOne() - inst.wrote_header = True - inst.finish() - self.assertFalse(inst.channel.written) - - def test_write_wrote_header(self): - inst = self._makeOne() - inst.wrote_header = True - inst.complete = True - inst.write(b'abc') - self.assertEqual(inst.channel.written, b'abc') - - def test_write_header_not_written(self): - inst = self._makeOne() - inst.wrote_header = False - inst.complete = True - inst.write(b'abc') - self.assertTrue(inst.channel.written) - self.assertEqual(inst.wrote_header, True) - - def test_write_start_response_uncalled(self): - inst = self._makeOne() - self.assertRaises(RuntimeError, inst.write, b'') - - def test_write_preexisting_content_length(self): - inst = self._makeOne() - inst.wrote_header = True - inst.complete = True - inst.content_length = 1 - inst.write(b'abc') - self.assertTrue(inst.channel.written) - self.assertEqual(inst.logged_write_excess, True) - class TestErrorTask(unittest.TestCase): def _makeOne(self, channel=None, request=None): if channel is None: @@ -624,8 +639,6 @@ class DummyChannel(object): server = DummyServer() self.server = server self.written = b'' - def close_when_done(self): - self.closed_when_done = True def write(self, data): self.written += data return len(data) |
