Assert that ChunkWriteTimouts are not raised
Follow up for change Ibbc89449e7878fc4215e47e3f7dfe4ae58a2d638 to add a test assertion that the ChunkWriteTimeout contexts are exited without raising the timeout exception in iter_bytes_from_response_part(). Change-Id: I6d323cb26779e457fb5940093a81b349b333a0af
This commit is contained in:
@@ -22,6 +22,7 @@ import math
|
|||||||
import os
|
import os
|
||||||
import pickle
|
import pickle
|
||||||
import sys
|
import sys
|
||||||
|
import traceback
|
||||||
import unittest
|
import unittest
|
||||||
from contextlib import closing, contextmanager
|
from contextlib import closing, contextmanager
|
||||||
from gzip import GzipFile
|
from gzip import GzipFile
|
||||||
@@ -65,7 +66,7 @@ from swift.obj import server as object_server
|
|||||||
from swift.common.middleware import proxy_logging, versioned_writes
|
from swift.common.middleware import proxy_logging, versioned_writes
|
||||||
from swift.common.middleware.acl import parse_acl, format_acl
|
from swift.common.middleware.acl import parse_acl, format_acl
|
||||||
from swift.common.exceptions import ChunkReadTimeout, DiskFileNotExist, \
|
from swift.common.exceptions import ChunkReadTimeout, DiskFileNotExist, \
|
||||||
APIVersionError
|
APIVersionError, ChunkWriteTimeout
|
||||||
from swift.common import utils, constraints
|
from swift.common import utils, constraints
|
||||||
from swift.common.ring import RingData
|
from swift.common.ring import RingData
|
||||||
from swift.common.utils import mkdirs, normalize_timestamp, NullLogger
|
from swift.common.utils import mkdirs, normalize_timestamp, NullLogger
|
||||||
@@ -5827,6 +5828,18 @@ class TestObjectController(unittest.TestCase):
|
|||||||
exp = 'HTTP/1.1 201'
|
exp = 'HTTP/1.1 201'
|
||||||
self.assertEqual(headers[:len(exp)], exp)
|
self.assertEqual(headers[:len(exp)], exp)
|
||||||
|
|
||||||
|
class WrappedTimeout(ChunkWriteTimeout):
|
||||||
|
def __enter__(self):
|
||||||
|
timeouts[self] = traceback.extract_stack()
|
||||||
|
return super(WrappedTimeout, self).__enter__()
|
||||||
|
|
||||||
|
def __exit__(self, typ, value, tb):
|
||||||
|
timeouts[self] = None
|
||||||
|
return super(WrappedTimeout, self).__exit__(typ, value, tb)
|
||||||
|
|
||||||
|
timeouts = {}
|
||||||
|
with mock.patch('swift.proxy.controllers.base.ChunkWriteTimeout',
|
||||||
|
WrappedTimeout):
|
||||||
with mock.patch.object(_test_servers[0], 'client_timeout', new=5):
|
with mock.patch.object(_test_servers[0], 'client_timeout', new=5):
|
||||||
# get object
|
# get object
|
||||||
fd.write('GET /v1/a/ec-discon/test HTTP/1.1\r\n'
|
fd.write('GET /v1/a/ec-discon/test HTTP/1.1\r\n'
|
||||||
@@ -5842,15 +5855,25 @@ class TestObjectController(unittest.TestCase):
|
|||||||
# read most of the object, and disconnect
|
# read most of the object, and disconnect
|
||||||
fd.read(10)
|
fd.read(10)
|
||||||
sock.fd._sock.close()
|
sock.fd._sock.close()
|
||||||
condition = \
|
self._sleep_enough(
|
||||||
lambda: _test_servers[0].logger.get_lines_for_level('warning')
|
lambda:
|
||||||
self._sleep_enough(condition)
|
_test_servers[0].logger.get_lines_for_level('warning'))
|
||||||
|
|
||||||
# check for disconnect message!
|
# check for disconnect message!
|
||||||
expected = ['Client disconnected on read'] * 2
|
expected = ['Client disconnected on read'] * 2
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
_test_servers[0].logger.get_lines_for_level('warning'),
|
_test_servers[0].logger.get_lines_for_level('warning'),
|
||||||
expected)
|
expected)
|
||||||
|
# check that no coro was left waiting to write
|
||||||
|
self.assertTrue(timeouts) # sanity - WrappedTimeout did get called
|
||||||
|
missing_exits = filter(lambda tb: tb is not None, timeouts.values())
|
||||||
|
self.assertFalse(
|
||||||
|
missing_exits, 'Failed to exit all ChunkWriteTimeouts.\n' +
|
||||||
|
''.join(['No exit from ChunkWriteTimeout entered at:\n' +
|
||||||
|
''.join(traceback.format_list(tb)[:-1])
|
||||||
|
for tb in missing_exits]))
|
||||||
|
# and check that the ChunkWriteTimeouts did not raise Exceptions
|
||||||
|
self.assertFalse(_test_servers[0].logger.get_lines_for_level('error'))
|
||||||
|
|
||||||
@unpatch_policies
|
@unpatch_policies
|
||||||
def test_ec_client_put_disconnect(self):
|
def test_ec_client_put_disconnect(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user