Blame cloudinit/tests/test_netinfo.py

Packit Service a04d08
# This file is part of cloud-init. See LICENSE file for license information.
Packit Service a04d08
Packit Service a04d08
"""Tests netinfo module functions and classes."""
Packit Service a04d08
Packit Service a04d08
from copy import copy
Packit Service a04d08
Packit Service a04d08
from cloudinit.netinfo import netdev_info, netdev_pformat, route_pformat
Packit Service a04d08
from cloudinit.tests.helpers import CiTestCase, mock, readResource
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
# Example ifconfig and route output
Packit Service a04d08
SAMPLE_OLD_IFCONFIG_OUT = readResource("netinfo/old-ifconfig-output")
Packit Service a04d08
SAMPLE_NEW_IFCONFIG_OUT = readResource("netinfo/new-ifconfig-output")
Packit Service a04d08
SAMPLE_FREEBSD_IFCONFIG_OUT = readResource("netinfo/freebsd-ifconfig-output")
Packit Service a04d08
SAMPLE_IPADDRSHOW_OUT = readResource("netinfo/sample-ipaddrshow-output")
Packit Service a04d08
SAMPLE_ROUTE_OUT_V4 = readResource("netinfo/sample-route-output-v4")
Packit Service a04d08
SAMPLE_ROUTE_OUT_V6 = readResource("netinfo/sample-route-output-v6")
Packit Service a04d08
SAMPLE_IPROUTE_OUT_V4 = readResource("netinfo/sample-iproute-output-v4")
Packit Service a04d08
SAMPLE_IPROUTE_OUT_V6 = readResource("netinfo/sample-iproute-output-v6")
Packit Service a04d08
NETDEV_FORMATTED_OUT = readResource("netinfo/netdev-formatted-output")
Packit Service a04d08
ROUTE_FORMATTED_OUT = readResource("netinfo/route-formatted-output")
Packit Service a04d08
FREEBSD_NETDEV_OUT = readResource("netinfo/freebsd-netdev-formatted-output")
Packit Service a04d08
Packit Service a04d08
Packit Service a04d08
class TestNetInfo(CiTestCase):
Packit Service a04d08
Packit Service a04d08
    maxDiff = None
Packit Service a04d08
    with_logs = True
Packit Service a04d08
Packit Service 751c4a
    @mock.patch('cloudinit.netinfo.subp.which')
Packit Service 751c4a
    @mock.patch('cloudinit.netinfo.subp.subp')
Packit Service a04d08
    def test_netdev_old_nettools_pformat(self, m_subp, m_which):
Packit Service a04d08
        """netdev_pformat properly rendering old nettools info."""
Packit Service a04d08
        m_subp.return_value = (SAMPLE_OLD_IFCONFIG_OUT, '')
Packit Service a04d08
        m_which.side_effect = lambda x: x if x == 'ifconfig' else None
Packit Service a04d08
        content = netdev_pformat()
Packit Service a04d08
        self.assertEqual(NETDEV_FORMATTED_OUT, content)
Packit Service a04d08
Packit Service 751c4a
    @mock.patch('cloudinit.netinfo.subp.which')
Packit Service 751c4a
    @mock.patch('cloudinit.netinfo.subp.subp')
Packit Service a04d08
    def test_netdev_new_nettools_pformat(self, m_subp, m_which):
Packit Service a04d08
        """netdev_pformat properly rendering netdev new nettools info."""
Packit Service a04d08
        m_subp.return_value = (SAMPLE_NEW_IFCONFIG_OUT, '')
Packit Service a04d08
        m_which.side_effect = lambda x: x if x == 'ifconfig' else None
Packit Service a04d08
        content = netdev_pformat()
Packit Service a04d08
        self.assertEqual(NETDEV_FORMATTED_OUT, content)
Packit Service a04d08
Packit Service 751c4a
    @mock.patch('cloudinit.netinfo.subp.which')
Packit Service 751c4a
    @mock.patch('cloudinit.netinfo.subp.subp')
Packit Service a04d08
    def test_netdev_freebsd_nettools_pformat(self, m_subp, m_which):
Packit Service a04d08
        """netdev_pformat properly rendering netdev new nettools info."""
Packit Service a04d08
        m_subp.return_value = (SAMPLE_FREEBSD_IFCONFIG_OUT, '')
Packit Service a04d08
        m_which.side_effect = lambda x: x if x == 'ifconfig' else None
Packit Service a04d08
        content = netdev_pformat()
Packit Service a04d08
        print()
Packit Service a04d08
        print(content)
Packit Service a04d08
        print()
Packit Service a04d08
        self.assertEqual(FREEBSD_NETDEV_OUT, content)
Packit Service a04d08
Packit Service 751c4a
    @mock.patch('cloudinit.netinfo.subp.which')
Packit Service 751c4a
    @mock.patch('cloudinit.netinfo.subp.subp')
Packit Service a04d08
    def test_netdev_iproute_pformat(self, m_subp, m_which):
Packit Service a04d08
        """netdev_pformat properly rendering ip route info."""
Packit Service a04d08
        m_subp.return_value = (SAMPLE_IPADDRSHOW_OUT, '')
Packit Service a04d08
        m_which.side_effect = lambda x: x if x == 'ip' else None
Packit Service a04d08
        content = netdev_pformat()
Packit Service a04d08
        new_output = copy(NETDEV_FORMATTED_OUT)
Packit Service a04d08
        # ip route show describes global scopes on ipv4 addresses
Packit Service a04d08
        # whereas ifconfig does not. Add proper global/host scope to output.
Packit Service a04d08
        new_output = new_output.replace('|   .    | 50:7b', '| global | 50:7b')
Packit Service a04d08
        new_output = new_output.replace(
Packit Service a04d08
            '255.0.0.0   |   .    |', '255.0.0.0   |  host  |')
Packit Service a04d08
        self.assertEqual(new_output, content)
Packit Service a04d08
Packit Service 751c4a
    @mock.patch('cloudinit.netinfo.subp.which')
Packit Service 751c4a
    @mock.patch('cloudinit.netinfo.subp.subp')
Packit Service a04d08
    def test_netdev_warn_on_missing_commands(self, m_subp, m_which):
Packit Service a04d08
        """netdev_pformat warns when missing both ip and 'netstat'."""
Packit Service a04d08
        m_which.return_value = None  # Niether ip nor netstat found
Packit Service a04d08
        content = netdev_pformat()
Packit Service a04d08
        self.assertEqual('\n', content)
Packit Service a04d08
        self.assertEqual(
Packit Service a04d08
            "WARNING: Could not print networks: missing 'ip' and 'ifconfig'"
Packit Service a04d08
            " commands\n",
Packit Service a04d08
            self.logs.getvalue())
Packit Service a04d08
        m_subp.assert_not_called()
Packit Service a04d08
Packit Service 751c4a
    @mock.patch('cloudinit.netinfo.subp.which')
Packit Service 751c4a
    @mock.patch('cloudinit.netinfo.subp.subp')
Packit Service a04d08
    def test_netdev_info_nettools_down(self, m_subp, m_which):
Packit Service a04d08
        """test netdev_info using nettools and down interfaces."""
Packit Service a04d08
        m_subp.return_value = (
Packit Service a04d08
            readResource("netinfo/new-ifconfig-output-down"), "")
Packit Service a04d08
        m_which.side_effect = lambda x: x if x == 'ifconfig' else None
Packit Service a04d08
        self.assertEqual(
Packit Service a04d08
            {'eth0': {'ipv4': [], 'ipv6': [],
Packit Service a04d08
                      'hwaddr': '00:16:3e:de:51:a6', 'up': False},
Packit Service a04d08
             'lo': {'ipv4': [{'ip': '127.0.0.1', 'mask': '255.0.0.0'}],
Packit Service a04d08
                    'ipv6': [{'ip': '::1/128', 'scope6': 'host'}],
Packit Service a04d08
                    'hwaddr': '.', 'up': True}},
Packit Service a04d08
            netdev_info("."))
Packit Service a04d08
Packit Service 751c4a
    @mock.patch('cloudinit.netinfo.subp.which')
Packit Service 751c4a
    @mock.patch('cloudinit.netinfo.subp.subp')
Packit Service a04d08
    def test_netdev_info_iproute_down(self, m_subp, m_which):
Packit Service a04d08
        """Test netdev_info with ip and down interfaces."""
Packit Service a04d08
        m_subp.return_value = (
Packit Service a04d08
            readResource("netinfo/sample-ipaddrshow-output-down"), "")
Packit Service a04d08
        m_which.side_effect = lambda x: x if x == 'ip' else None
Packit Service a04d08
        self.assertEqual(
Packit Service a04d08
            {'lo': {'ipv4': [{'ip': '127.0.0.1', 'bcast': '.',
Packit Service a04d08
                              'mask': '255.0.0.0', 'scope': 'host'}],
Packit Service a04d08
                    'ipv6': [{'ip': '::1/128', 'scope6': 'host'}],
Packit Service a04d08
                    'hwaddr': '.', 'up': True},
Packit Service a04d08
             'eth0': {'ipv4': [], 'ipv6': [],
Packit Service a04d08
                      'hwaddr': '00:16:3e:de:51:a6', 'up': False}},
Packit Service a04d08
            netdev_info("."))
Packit Service a04d08
Packit Service a04d08
    @mock.patch('cloudinit.netinfo.netdev_info')
Packit Service a04d08
    def test_netdev_pformat_with_down(self, m_netdev_info):
Packit Service a04d08
        """test netdev_pformat when netdev_info returns 'down' interfaces."""
Packit Service a04d08
        m_netdev_info.return_value = (
Packit Service a04d08
            {'lo': {'ipv4': [{'ip': '127.0.0.1', 'mask': '255.0.0.0',
Packit Service a04d08
                              'scope': 'host'}],
Packit Service a04d08
                    'ipv6': [{'ip': '::1/128', 'scope6': 'host'}],
Packit Service a04d08
                    'hwaddr': '.', 'up': True},
Packit Service a04d08
             'eth0': {'ipv4': [], 'ipv6': [],
Packit Service a04d08
                      'hwaddr': '00:16:3e:de:51:a6', 'up': False}})
Packit Service a04d08
        self.assertEqual(
Packit Service a04d08
            readResource("netinfo/netdev-formatted-output-down"),
Packit Service a04d08
            netdev_pformat())
Packit Service a04d08
Packit Service 751c4a
    @mock.patch('cloudinit.netinfo.subp.which')
Packit Service 751c4a
    @mock.patch('cloudinit.netinfo.subp.subp')
Packit Service a04d08
    def test_route_nettools_pformat(self, m_subp, m_which):
Packit Service a04d08
        """route_pformat properly rendering nettools route info."""
Packit Service a04d08
Packit Service a04d08
        def subp_netstat_route_selector(*args, **kwargs):
Packit Service a04d08
            if args[0] == ['netstat', '--route', '--numeric', '--extend']:
Packit Service a04d08
                return (SAMPLE_ROUTE_OUT_V4, '')
Packit Service a04d08
            if args[0] == ['netstat', '-A', 'inet6', '--route', '--numeric']:
Packit Service a04d08
                return (SAMPLE_ROUTE_OUT_V6, '')
Packit Service a04d08
            raise Exception('Unexpected subp call %s' % args[0])
Packit Service a04d08
Packit Service a04d08
        m_subp.side_effect = subp_netstat_route_selector
Packit Service a04d08
        m_which.side_effect = lambda x: x if x == 'netstat' else None
Packit Service a04d08
        content = route_pformat()
Packit Service a04d08
        self.assertEqual(ROUTE_FORMATTED_OUT, content)
Packit Service a04d08
Packit Service 751c4a
    @mock.patch('cloudinit.netinfo.subp.which')
Packit Service 751c4a
    @mock.patch('cloudinit.netinfo.subp.subp')
Packit Service a04d08
    def test_route_iproute_pformat(self, m_subp, m_which):
Packit Service a04d08
        """route_pformat properly rendering ip route info."""
Packit Service a04d08
Packit Service a04d08
        def subp_iproute_selector(*args, **kwargs):
Packit Service a04d08
            if ['ip', '-o', 'route', 'list'] == args[0]:
Packit Service a04d08
                return (SAMPLE_IPROUTE_OUT_V4, '')
Packit Service a04d08
            v6cmd = ['ip', '--oneline', '-6', 'route', 'list', 'table', 'all']
Packit Service a04d08
            if v6cmd == args[0]:
Packit Service a04d08
                return (SAMPLE_IPROUTE_OUT_V6, '')
Packit Service a04d08
            raise Exception('Unexpected subp call %s' % args[0])
Packit Service a04d08
Packit Service a04d08
        m_subp.side_effect = subp_iproute_selector
Packit Service a04d08
        m_which.side_effect = lambda x: x if x == 'ip' else None
Packit Service a04d08
        content = route_pformat()
Packit Service a04d08
        self.assertEqual(ROUTE_FORMATTED_OUT, content)
Packit Service a04d08
Packit Service 751c4a
    @mock.patch('cloudinit.netinfo.subp.which')
Packit Service 751c4a
    @mock.patch('cloudinit.netinfo.subp.subp')
Packit Service a04d08
    def test_route_warn_on_missing_commands(self, m_subp, m_which):
Packit Service a04d08
        """route_pformat warns when missing both ip and 'netstat'."""
Packit Service a04d08
        m_which.return_value = None  # Niether ip nor netstat found
Packit Service a04d08
        content = route_pformat()
Packit Service a04d08
        self.assertEqual('\n', content)
Packit Service a04d08
        self.assertEqual(
Packit Service a04d08
            "WARNING: Could not print routes: missing 'ip' and 'netstat'"
Packit Service a04d08
            " commands\n",
Packit Service a04d08
            self.logs.getvalue())
Packit Service a04d08
        m_subp.assert_not_called()
Packit Service a04d08
Packit Service a04d08
# vi: ts=4 expandtab