summaryrefslogtreecommitdiff
path: root/ironic_python_agent
diff options
context:
space:
mode:
authorZuul <zuul@review.openstack.org>2018-06-27 14:09:00 +0000
committerGerrit Code Review <review@openstack.org>2018-06-27 14:09:00 +0000
commit44a27d26bdb90575eaabb764da304e29cb7fb613 (patch)
treec6dec2af58edbbdf72f747af940f24e146ce2c58 /ironic_python_agent
parenta4225beda4cf0f0305972e9cba738e8088c8109d (diff)
parent14ac444f7c8e708ef71ba7d83277768bac0de9c0 (diff)
downloadironic-python-agent-44a27d26bdb90575eaabb764da304e29cb7fb613.tar.gz
Merge "[LLDP] Skip NICs that say they are ready but are unreadable." into stable/pike
Diffstat (limited to 'ironic_python_agent')
-rw-r--r--ironic_python_agent/netutils.py15
-rw-r--r--ironic_python_agent/tests/unit/test_netutils.py45
2 files changed, 56 insertions, 4 deletions
diff --git a/ironic_python_agent/netutils.py b/ironic_python_agent/netutils.py
index 45b85a5d..5d38548d 100644
--- a/ironic_python_agent/netutils.py
+++ b/ironic_python_agent/netutils.py
@@ -182,10 +182,17 @@ def _get_lldp_info(interfaces):
# Create a copy of interfaces to avoid deleting while iterating.
for index, interface in enumerate(list(interfaces)):
if s == interface[1]:
- LOG.info('Found LLDP info for interface: %s',
- interface[0])
- lldp_info[interface[0]] = (
- _receive_lldp_packets(s))
+ try:
+ lldp_info[interface[0]] = _receive_lldp_packets(s)
+ except socket.error:
+ LOG.exception('Socket for network interface %s said '
+ 'that it was ready to read we were '
+ 'unable to read from the socket while '
+ 'trying to get LLDP packet. Skipping '
+ 'this network interface.', interface[0])
+ else:
+ LOG.info('Found LLDP info for interface: %s',
+ interface[0])
# Remove interface from the list, only need one packet
del interfaces[index]
diff --git a/ironic_python_agent/tests/unit/test_netutils.py b/ironic_python_agent/tests/unit/test_netutils.py
index 4237b155..b9b2a11e 100644
--- a/ironic_python_agent/tests/unit/test_netutils.py
+++ b/ironic_python_agent/tests/unit/test_netutils.py
@@ -13,6 +13,7 @@
# limitations under the License.
import binascii
+import socket
import mock
from oslo_config import cfg
@@ -92,6 +93,50 @@ class TestNetutils(base.IronicAgentTest):
@mock.patch('fcntl.ioctl', autospec=True)
@mock.patch('select.select', autospec=True)
@mock.patch('socket.socket', autospec=socket_socket_sig)
+ def test_get_lldp_info_socket_recv_error(self, sock_mock, select_mock,
+ fcntl_mock):
+ expected_lldp = {
+ 'eth1': [
+ (0, b''),
+ (1, b'\x04\x88Z\x92\xecTY'),
+ (2, b'\x05Ethernet1/18'),
+ (3, b'\x00x')]
+ }
+
+ interface_names = ['eth0', 'eth1']
+
+ sock1 = mock.Mock()
+ sock1.recv.side_effect = socket.error("BOOM")
+
+ sock2 = mock.Mock()
+ sock2.recv.return_value = FAKE_LLDP_PACKET
+ sock2.fileno.return_value = 5
+
+ sock_mock.side_effect = [sock1, sock2]
+
+ select_mock.side_effect = [
+ ([sock1], [], []),
+ ([sock2], [], [])
+ ]
+
+ lldp_info = netutils.get_lldp_info(interface_names)
+ self.assertEqual(expected_lldp, lldp_info)
+
+ sock1.bind.assert_called_with(('eth0', netutils.LLDP_ETHERTYPE))
+ sock2.bind.assert_called_with(('eth1', netutils.LLDP_ETHERTYPE))
+
+ sock1.recv.assert_called_with(1600)
+ sock2.recv.assert_called_with(1600)
+
+ self.assertEqual(1, sock1.close.call_count)
+ self.assertEqual(1, sock2.close.call_count)
+
+ # 2 interfaces, 2 calls to enter promiscuous mode, 1 to leave
+ self.assertEqual(6, fcntl_mock.call_count)
+
+ @mock.patch('fcntl.ioctl', autospec=True)
+ @mock.patch('select.select', autospec=True)
+ @mock.patch('socket.socket', autospec=socket_socket_sig)
def test_get_lldp_info_multiple(self, sock_mock, select_mock, fcntl_mock):
expected_lldp = {
'eth1': [