Merge "Catch exceptions on I/O in driver-agent"

This commit is contained in:
Zuul 2022-08-10 18:53:55 +00:00 committed by Gerrit Code Review
commit 489010a054
2 changed files with 177 additions and 9 deletions

View File

@ -50,7 +50,11 @@ class StatusRequestHandler(socketserver.BaseRequestHandler):
def handle(self):
# Get the update data
status = _recv(self.request)
try:
status = _recv(self.request)
except Exception:
LOG.exception("Error while receiving data.")
return
# Process the update
updater = driver_updater.DriverUpdater()
@ -59,15 +63,22 @@ class StatusRequestHandler(socketserver.BaseRequestHandler):
# Send the response
json_data = jsonutils.dump_as_bytes(response)
len_str = '{}\n'.format(len(json_data)).encode('utf-8')
self.request.send(len_str)
self.request.sendall(json_data)
try:
self.request.send(len_str)
self.request.sendall(json_data)
except Exception:
LOG.exception("Error while sending data.")
class StatsRequestHandler(socketserver.BaseRequestHandler):
def handle(self):
# Get the update data
stats = _recv(self.request)
try:
stats = _recv(self.request)
except Exception:
LOG.exception("Error while receiving data.")
return
# Process the update
updater = driver_updater.DriverUpdater()
@ -76,15 +87,22 @@ class StatsRequestHandler(socketserver.BaseRequestHandler):
# Send the response
json_data = jsonutils.dump_as_bytes(response)
len_str = '{}\n'.format(len(json_data)).encode('utf-8')
self.request.send(len_str)
self.request.sendall(json_data)
try:
self.request.send(len_str)
self.request.sendall(json_data)
except Exception:
LOG.exception("Error while sending data.")
class GetRequestHandler(socketserver.BaseRequestHandler):
def handle(self):
# Get the data request
get_data = _recv(self.request)
try:
get_data = _recv(self.request)
except Exception:
LOG.exception("Error while receiving data.")
return
# Process the get
response = driver_get.process_get(get_data)
@ -92,8 +110,11 @@ class GetRequestHandler(socketserver.BaseRequestHandler):
# Send the response
json_data = jsonutils.dump_as_bytes(response)
len_str = '{}\n'.format(len(json_data)).encode('utf-8')
self.request.send(len_str)
self.request.sendall(json_data)
try:
self.request.send(len_str)
self.request.sendall(json_data)
except Exception:
LOG.exception("Error while sending data.")
class ForkingUDSServer(socketserver.ForkingMixIn,

View File

@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import errno
import socket
from unittest import mock
from oslo_config import cfg
@ -82,6 +83,57 @@ class TestDriverListener(base.TestCase):
mock_sendall.assert_called_with(
jsonutils.dumps(TEST_OBJECT).encode('utf-8'))
@mock.patch('octavia.api.drivers.driver_agent.driver_updater.'
'DriverUpdater')
@mock.patch('octavia.api.drivers.driver_agent.driver_listener._recv')
def test_StatusRequestHandler_handle_recv_timeout(self, mock_recv,
mock_driverupdater):
TEST_OBJECT = {"test": "msg"}
mock_recv.side_effect = socket.timeout
mock_updater = mock.MagicMock()
mock_update_loadbalancer_status = mock.MagicMock()
mock_update_loadbalancer_status.return_value = TEST_OBJECT
mock_updater.update_loadbalancer_status = (
mock_update_loadbalancer_status)
mock_driverupdater.return_value = mock_updater
mock_request = mock.MagicMock()
StatusRequestHandler = driver_listener.StatusRequestHandler(
mock_request, 'bogus', 'bogus')
StatusRequestHandler.handle()
mock_recv.assert_called_with(mock_request)
mock_update_loadbalancer_status.assert_not_called()
@mock.patch('octavia.api.drivers.driver_agent.driver_updater.'
'DriverUpdater')
@mock.patch('octavia.api.drivers.driver_agent.driver_listener._recv')
def test_StatusRequestHandler_handle_send_timeout(self, mock_recv,
mock_driverupdater):
TEST_OBJECT = {"test": "msg"}
mock_recv.return_value = 'bogus'
mock_updater = mock.MagicMock()
mock_update_loadbalancer_status = mock.MagicMock()
mock_update_loadbalancer_status.return_value = TEST_OBJECT
mock_updater.update_loadbalancer_status = (
mock_update_loadbalancer_status)
mock_driverupdater.return_value = mock_updater
mock_request = mock.MagicMock()
mock_send = mock.MagicMock()
mock_send.side_effect = socket.timeout
mock_sendall = mock.MagicMock()
mock_request.send = mock_send
mock_request.sendall = mock_sendall
StatusRequestHandler = driver_listener.StatusRequestHandler(
mock_request, 'bogus', 'bogus')
StatusRequestHandler.handle()
mock_recv.assert_called_with(mock_request)
mock_update_loadbalancer_status.assert_called_with('bogus')
mock_send.assert_called_with(b'15\n')
mock_sendall.assert_not_called()
@mock.patch('octavia.api.drivers.driver_agent.driver_updater.'
'DriverUpdater')
@mock.patch('octavia.api.drivers.driver_agent.driver_listener._recv')
@ -108,6 +160,55 @@ class TestDriverListener(base.TestCase):
mock_send.assert_called_with(b'15\n')
mock_sendall.assert_called_with(jsonutils.dump_as_bytes(TEST_OBJECT))
@mock.patch('octavia.api.drivers.driver_agent.driver_updater.'
'DriverUpdater')
@mock.patch('octavia.api.drivers.driver_agent.driver_listener._recv')
def test_StatsRequestHandler_handle_recv_timeout(self, mock_recv,
mock_driverupdater):
TEST_OBJECT = {"test": "msg"}
mock_recv.side_effect = socket.timeout
mock_updater = mock.MagicMock()
mock_update_listener_stats = mock.MagicMock()
mock_update_listener_stats.return_value = TEST_OBJECT
mock_updater.update_listener_statistics = (mock_update_listener_stats)
mock_driverupdater.return_value = mock_updater
mock_request = mock.MagicMock()
StatsRequestHandler = driver_listener.StatsRequestHandler(
mock_request, 'bogus', 'bogus')
StatsRequestHandler.handle()
mock_recv.assert_called_with(mock_request)
mock_update_listener_stats.assert_not_called()
@mock.patch('octavia.api.drivers.driver_agent.driver_updater.'
'DriverUpdater')
@mock.patch('octavia.api.drivers.driver_agent.driver_listener._recv')
def test_StatsRequestHandler_handle_send_timeout(self, mock_recv,
mock_driverupdater):
TEST_OBJECT = {"test": "msg"}
mock_recv.return_value = 'bogus'
mock_updater = mock.MagicMock()
mock_update_listener_stats = mock.MagicMock()
mock_update_listener_stats.return_value = TEST_OBJECT
mock_updater.update_listener_statistics = (mock_update_listener_stats)
mock_driverupdater.return_value = mock_updater
mock_request = mock.MagicMock()
mock_send = mock.MagicMock()
mock_send.side_effect = socket.timeout
mock_sendall = mock.MagicMock()
mock_request.send = mock_send
mock_request.sendall = mock_sendall
StatsRequestHandler = driver_listener.StatsRequestHandler(
mock_request, 'bogus', 'bogus')
StatsRequestHandler.handle()
mock_recv.assert_called_with(mock_request)
mock_update_listener_stats.assert_called_with('bogus')
mock_send.assert_called_with(b'15\n')
mock_sendall.assert_not_called()
@mock.patch('octavia.api.drivers.driver_agent.driver_get.'
'process_get')
@mock.patch('octavia.api.drivers.driver_agent.driver_listener._recv')
@ -133,6 +234,52 @@ class TestDriverListener(base.TestCase):
mock_send.assert_called_with(b'15\n')
mock_sendall.assert_called_with(jsonutils.dump_as_bytes(TEST_OBJECT))
@mock.patch('octavia.api.drivers.driver_agent.driver_get.'
'process_get')
@mock.patch('octavia.api.drivers.driver_agent.driver_listener._recv')
def test_GetRequestHandler_handle_recv_timeout(self, mock_recv,
mock_process_get):
TEST_OBJECT = {"test": "msg"}
mock_recv.side_effect = socket.timeout
mock_process_get.return_value = TEST_OBJECT
mock_request = mock.MagicMock()
GetRequestHandler = driver_listener.GetRequestHandler(
mock_request, 'bogus', 'bogus')
GetRequestHandler.handle()
mock_recv.assert_called_with(mock_request)
mock_process_get.assert_not_called()
@mock.patch('octavia.api.drivers.driver_agent.driver_get.'
'process_get')
@mock.patch('octavia.api.drivers.driver_agent.driver_listener._recv')
def test_GetRequestHandler_handle_send_timeout(self, mock_recv,
mock_process_get):
TEST_OBJECT = {"test": "msg"}
mock_recv.return_value = 'bogus'
mock_process_get.return_value = TEST_OBJECT
mock_request = mock.MagicMock()
mock_send = mock.MagicMock()
mock_send.side_effect = socket.timeout
mock_sendall = mock.MagicMock()
mock_request.send = mock_send
mock_request.sendall = mock_sendall
GetRequestHandler = driver_listener.GetRequestHandler(
mock_request, 'bogus', 'bogus')
GetRequestHandler.handle()
mock_recv.assert_called_with(mock_request)
mock_process_get.assert_called_with('bogus')
mock_send.assert_called_with(b'15\n')
mock_sendall.assert_not_called()
@mock.patch('os.remove')
def test_cleanup_socket_file(self, mock_remove):
mock_remove.side_effect = [mock.DEFAULT, OSError,