Merge "Fix UnixDomainHttpProtocol class to support all eventlet versions"

This commit is contained in:
Zuul 2018-07-17 20:23:49 +00:00 committed by Gerrit Code Review
commit 3be1cd2fc4
2 changed files with 47 additions and 15 deletions

View File

@ -387,24 +387,32 @@ class UnixDomainHTTPConnection(httplib.HTTPConnection):
class UnixDomainHttpProtocol(eventlet.wsgi.HttpProtocol): class UnixDomainHttpProtocol(eventlet.wsgi.HttpProtocol):
def __init__(self, request, client_address, server): def __init__(self, *args):
if not client_address:
client_address = ('<local>', 0)
# NOTE(yamahata): from eventlet v0.22 HttpProtocol.__init__ # NOTE(yamahata): from eventlet v0.22 HttpProtocol.__init__
# signature was changed by changeset of # signature was changed by changeset of
# 7f53465578543156e7251e243c0636e087a8445f # 7f53465578543156e7251e243c0636e087a8445f
# try the new signature first, and then fallback to the old # Both have server as last arg, but first arg(s) differ
# signature for compatibility server = args[-1]
try:
conn_state = [client_address, request, eventlet.wsgi.STATE_CLOSE] # Because the caller is eventlet.wsgi.Server.process_request,
# the number of arguments will dictate if it is new or old style.
if len(args) == 2:
conn_state = args[0]
client_address = conn_state[0]
if not client_address:
conn_state[0] = ('<local>', 0)
# base class is old-style, so super does not work properly # base class is old-style, so super does not work properly
eventlet.wsgi.HttpProtocol.__init__(self, conn_state, server) eventlet.wsgi.HttpProtocol.__init__(self, conn_state, server)
except (AttributeError, TypeError): elif len(args) == 3:
# AttributeError: missing STATE_CLOSE request = args[0]
# TypeError: signature mismatch client_address = args[1]
if not client_address:
client_address = ('<local>', 0)
# base class is old-style, so super does not work properly
eventlet.wsgi.HttpProtocol.__init__( eventlet.wsgi.HttpProtocol.__init__(
self, request, client_address, server) self, request, client_address, server)
else:
eventlet.wsgi.HttpProtocol.__init__(self, *args)
class UnixDomainWSGIServer(wsgi.Server): class UnixDomainWSGIServer(wsgi.Server):

View File

@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import copy
import signal import signal
import socket import socket
@ -483,14 +484,37 @@ class TestUnixDomainHttpConnection(base.BaseTestCase):
class TestUnixDomainHttpProtocol(base.BaseTestCase): class TestUnixDomainHttpProtocol(base.BaseTestCase):
def setUp(self):
super(TestUnixDomainHttpProtocol, self).setUp()
self.ewhi = mock.patch('eventlet.wsgi.HttpProtocol.__init__').start()
def test_init_empty_client(self): def test_init_empty_client(self):
for addr in ('', b''): for addr in ('', b''):
u = utils.UnixDomainHttpProtocol(mock.Mock(), addr, mock.Mock()) utils.UnixDomainHttpProtocol(mock.Mock(), addr, mock.Mock())
self.assertEqual(u.client_address, ('<local>', 0)) self.ewhi.assert_called_once_with(mock.ANY, mock.ANY,
('<local>', 0), mock.ANY)
self.ewhi.reset_mock()
def test_init_with_client(self): def test_init_with_client(self):
u = utils.UnixDomainHttpProtocol(mock.Mock(), 'foo', mock.Mock()) utils.UnixDomainHttpProtocol(mock.Mock(), 'foo', mock.Mock())
self.assertEqual(u.client_address, 'foo') self.ewhi.assert_called_once_with(mock.ANY, mock.ANY, 'foo', mock.ANY)
def test_init_new_style_empty_client(self):
conn_state = ['', mock.Mock(), mock.Mock()]
# have to make a copy since the init will modify what we pass
csc = copy.copy(conn_state)
csc[0] = ('<local>', 0)
utils.UnixDomainHttpProtocol(conn_state, mock.Mock())
self.ewhi.assert_called_once_with(mock.ANY, csc, mock.ANY)
def test_init_new_style_client(self):
conn_state = ['foo', mock.Mock(), mock.Mock()]
utils.UnixDomainHttpProtocol(conn_state, mock.Mock())
self.ewhi.assert_called_once_with(mock.ANY, conn_state, mock.ANY)
def test_init_unknown_client(self):
utils.UnixDomainHttpProtocol('foo')
self.ewhi.assert_called_once_with(mock.ANY, 'foo')
class TestUnixDomainWSGIServer(base.BaseTestCase): class TestUnixDomainWSGIServer(base.BaseTestCase):