diff options
author | Michael Merickel <michael@merickel.org> | 2022-01-17 20:59:07 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-17 20:59:07 -0600 |
commit | 759f4d1ef70789ad490d1c4a900b914b6ce949ba (patch) | |
tree | 2ed955067dfb9fb0b0c129fb211c2e09d3f4cd41 /tests/test_channel.py | |
parent | 7acbb87839f7b26764d59adac5bf0c279e02e9b3 (diff) | |
parent | 1bbdf6cd985028db64b0287c4b6748e94e54cc40 (diff) | |
download | waitress-master.tar.gz |
Merge pull request #364 from Pylons/feature/flush-from-app-threadmaster
Flush data from the application thread
Diffstat (limited to 'tests/test_channel.py')
-rw-r--r-- | tests/test_channel.py | 95 |
1 files changed, 84 insertions, 11 deletions
diff --git a/tests/test_channel.py b/tests/test_channel.py index d86dbbe..b1c317d 100644 --- a/tests/test_channel.py +++ b/tests/test_channel.py @@ -213,6 +213,13 @@ class TestHTTPChannel(unittest.TestCase): def test_write_soon_nonempty_byte(self): inst, sock, map = self._makeOneWithMap() + + # _flush_some will no longer flush + def send(_): + return 0 + + sock.send = send + wrote = inst.write_soon(b"a") self.assertEqual(wrote, 1) self.assertEqual(len(inst.outbufs[0]), 1) @@ -224,14 +231,19 @@ class TestHTTPChannel(unittest.TestCase): wrapper = ReadOnlyFileBasedBuffer(f, 8192) wrapper.prepare() inst, sock, map = self._makeOneWithMap() + + # _flush_some will no longer flush + def send(_): + return 0 + + sock.send = send + outbufs = inst.outbufs - orig_outbuf = outbufs[0] wrote = inst.write_soon(wrapper) self.assertEqual(wrote, 3) - self.assertEqual(len(outbufs), 3) - self.assertEqual(outbufs[0], orig_outbuf) - self.assertEqual(outbufs[1], wrapper) - self.assertEqual(outbufs[2].__class__.__name__, "OverflowableBuffer") + self.assertEqual(len(outbufs), 2) + self.assertEqual(outbufs[0], wrapper) + self.assertEqual(outbufs[1].__class__.__name__, "OverflowableBuffer") def test_write_soon_disconnected(self): from waitress.channel import ClientDisconnected @@ -253,16 +265,29 @@ class TestHTTPChannel(unittest.TestCase): def test_write_soon_rotates_outbuf_on_overflow(self): inst, sock, map = self._makeOneWithMap() + + # _flush_some will no longer flush + def send(_): + return 0 + + sock.send = send + inst.adj.outbuf_high_watermark = 3 inst.current_outbuf_count = 4 wrote = inst.write_soon(b"xyz") self.assertEqual(wrote, 3) - self.assertEqual(len(inst.outbufs), 2) - self.assertEqual(inst.outbufs[0].get(), b"") - self.assertEqual(inst.outbufs[1].get(), b"xyz") + self.assertEqual(len(inst.outbufs), 1) + self.assertEqual(inst.outbufs[0].get(), b"xyz") def test_write_soon_waits_on_backpressure(self): inst, sock, map = self._makeOneWithMap() + + # _flush_some will no longer flush + def send(_): + return 0 + + sock.send = send + inst.adj.outbuf_high_watermark = 3 inst.total_outbufs_len = 4 inst.current_outbuf_count = 4 @@ -275,11 +300,59 @@ class TestHTTPChannel(unittest.TestCase): inst.outbuf_lock = Lock() wrote = inst.write_soon(b"xyz") self.assertEqual(wrote, 3) - self.assertEqual(len(inst.outbufs), 2) - self.assertEqual(inst.outbufs[0].get(), b"") - self.assertEqual(inst.outbufs[1].get(), b"xyz") + self.assertEqual(len(inst.outbufs), 1) + self.assertEqual(inst.outbufs[0].get(), b"xyz") self.assertTrue(inst.outbuf_lock.waited) + def test_write_soon_attempts_flush_high_water_and_exception(self): + from waitress.channel import ClientDisconnected + + inst, sock, map = self._makeOneWithMap() + + # _flush_some will no longer flush, it will raise Exception, which + # disconnects the remote end + def send(_): + inst.connected = False + raise Exception() + + sock.send = send + + inst.adj.outbuf_high_watermark = 3 + inst.total_outbufs_len = 4 + inst.current_outbuf_count = 4 + + inst.outbufs[0].append(b"test") + + class Lock(DummyLock): + def wait(self): + inst.total_outbufs_len = 0 + super().wait() + + inst.outbuf_lock = Lock() + self.assertRaises(ClientDisconnected, lambda: inst.write_soon(b"xyz")) + + # Validate we woke up the main thread to deal with the exception of + # trying to send + self.assertTrue(inst.outbuf_lock.waited) + self.assertTrue(inst.server.trigger_pulled) + + def test_write_soon_flush_and_exception(self): + inst, sock, map = self._makeOneWithMap() + + # _flush_some will no longer flush, it will raise Exception, which + # disconnects the remote end + def send(_): + inst.connected = False + raise Exception() + + sock.send = send + + wrote = inst.write_soon(b"xyz") + self.assertEqual(wrote, 3) + # Validate we woke up the main thread to deal with the exception of + # trying to send + self.assertTrue(inst.server.trigger_pulled) + def test_handle_write_notify_after_flush(self): inst, sock, map = self._makeOneWithMap() inst.requests = [True] |