<filename>site-packages/mlab/disco/network_test.py
"""Tests for the network module."""

import unittest

# Third-party modules.
import arp
import mock
import netifaces

# Module under test.
import network
import route


@mock.patch.object(netifaces, 'interfaces')
@mock.patch.object(netifaces, 'ifaddresses')
class NetworkLocalTest(unittest.TestCase):
    """Tests for getting local MAC address with the network module."""

    def test_get_local_mac(self, mock_ifaddresses, mock_interfaces):
        mock_interfaces.return_value = ['lo', 'eth0']
        mock_ifaddresses.return_value = {
            netifaces.AF_LINK: [{'addr': '00:11:22:33:44:55'}]
        }

        actual = network.get_local_mac()

        self.assertEqual('00:11:22:33:44:55', actual)
        mock_ifaddresses.assert_called_once_with('eth0')

    def test_get_local_mac_raises_TooFewInterfaces_when_no_macs_found(
            self, mock_ifaddresses, mock_interfaces):
        """Force too few interfaces with an empty interface address."""
        mock_interfaces.return_value = ['eth0']
        mock_ifaddresses.return_value = {}

        with self.assertRaises(network.TooFewInterfaces):
            network.get_local_mac()

    def test_get_local_mac_raises_TooManyInterfaces_when_multiple_macs_found(
            self, mock_ifaddresses, mock_interfaces):
        """Define multiple interfaces to force too many interfaces."""
        mock_interfaces.return_value = ['eth0', 'eth1']
        mock_ifaddresses.side_effect = [
            {netifaces.AF_LINK: [{'addr': '00:11:22:33:44:55'}]},
            {netifaces.AF_LINK: [{'addr': '10:11:22:33:44:55'}]}
        ]

        with self.assertRaises(network.TooManyInterfaces):
            network.get_local_mac()


@mock.patch.object(route, 'gateways')
class NetworkUplinkTest(unittest.TestCase):
    """Tests for getting uplink MAC address with the network module."""

    def test_get_uplink_mac(self, mock_gateways):
        mock_gateways.return_value = {
            'default': {route.AF_INET: ('5.4.3.2', 'eth0')}
        }
        mock_arp_cache = mock.Mock(spec=arp.ArpCache)
        mock_arp_cache.ip_to_mac.return_value = '00:11:22:33:44:55'

        actual_mac = network.get_uplink_mac(mock_arp_cache)

        self.assertEqual('00:11:22:33:44:55', actual_mac)
        mock_arp_cache.ip_to_mac.assert_called_once_with('5.4.3.2')

    def test_get_uplink_mac_raises_NoDefaultGateway_when_gateway_is_empty(
            self, mock_gateways):
        mock_gateways.return_value = {}
        mock_arp_cache = mock.Mock(spec=arp.ArpCache)
        mock_arp_cache.ip_to_mac.side_effect = Exception(
            'Should not be called.')

        with self.assertRaises(network.NoDefaultGateway):
            network.get_uplink_mac(mock_arp_cache)


if __name__ == '__main__':
    unittest.main()
