2015-04-02 06:55:48 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
'''
|
|
|
|
:codeauthor: :email:`Jayesh Kariya <jayeshk@saltstack.com>`
|
|
|
|
'''
|
|
|
|
|
|
|
|
# Import Python Libs
|
|
|
|
from __future__ import absolute_import
|
2015-04-03 14:28:10 +00:00
|
|
|
import socket
|
|
|
|
import os.path
|
2015-04-02 06:55:48 +00:00
|
|
|
|
|
|
|
# Import Salt Testing Libs
|
|
|
|
from salttesting import TestCase, skipIf
|
|
|
|
from salttesting.mock import (
|
|
|
|
mock_open,
|
|
|
|
MagicMock,
|
|
|
|
patch,
|
|
|
|
NO_MOCK,
|
|
|
|
NO_MOCK_REASON
|
|
|
|
)
|
|
|
|
|
|
|
|
from salttesting.helpers import ensure_in_syspath
|
|
|
|
|
|
|
|
ensure_in_syspath('../../')
|
|
|
|
|
|
|
|
# Import Salt Libs
|
|
|
|
import salt.utils
|
|
|
|
from salt.modules import network
|
|
|
|
from salt.exceptions import CommandExecutionError
|
|
|
|
|
|
|
|
# Globals
|
|
|
|
network.__grains__ = {}
|
|
|
|
network.__salt__ = {}
|
|
|
|
|
|
|
|
|
|
|
|
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
|
|
|
class NetworkTestCase(TestCase):
|
|
|
|
'''
|
|
|
|
Test cases for salt.modules.network
|
|
|
|
'''
|
2015-04-07 17:33:41 +00:00
|
|
|
def test_wol_bad_mac(self):
|
|
|
|
'''
|
|
|
|
tests network.wol with bad mac
|
|
|
|
'''
|
|
|
|
bad_mac = '31337'
|
|
|
|
self.assertRaises(ValueError, network.wol, bad_mac)
|
|
|
|
|
|
|
|
def test_wol_success(self):
|
|
|
|
'''
|
|
|
|
tests network.wol success
|
|
|
|
'''
|
|
|
|
mac = '080027136977'
|
|
|
|
bcast = '255.255.255.255 7'
|
|
|
|
|
|
|
|
class MockSocket(object):
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def __call__(self, *args, **kwargs):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def setsockopt(self, *args, **kwargs):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def sendto(self, *args, **kwargs):
|
|
|
|
pass
|
|
|
|
|
|
|
|
with patch('socket.socket', MockSocket):
|
|
|
|
self.assertTrue(network.wol(mac, bcast))
|
|
|
|
|
2015-04-02 06:55:48 +00:00
|
|
|
def test_ping(self):
|
|
|
|
'''
|
|
|
|
Test for Performs a ping to a host
|
|
|
|
'''
|
|
|
|
with patch.object(salt.utils.network, 'sanitize_host',
|
|
|
|
return_value='A'):
|
|
|
|
mock_all = MagicMock(side_effect=[{'retcode': 1}, {'retcode': 0}])
|
|
|
|
with patch.dict(network.__salt__, {'cmd.run_all': mock_all}):
|
|
|
|
self.assertFalse(network.ping('host', return_boolean=True))
|
|
|
|
|
|
|
|
self.assertTrue(network.ping('host', return_boolean=True))
|
|
|
|
|
|
|
|
with patch.dict(network.__salt__, {'cmd.run':
|
|
|
|
MagicMock(return_value='A')}):
|
|
|
|
self.assertEqual(network.ping('host'), 'A')
|
|
|
|
|
|
|
|
def test_netstat(self):
|
|
|
|
'''
|
|
|
|
Test for return information on open ports and states
|
|
|
|
'''
|
|
|
|
with patch.dict(network.__grains__, {'kernel': 'Linux'}):
|
|
|
|
with patch.object(network, '_netstat_linux', return_value='A'):
|
|
|
|
self.assertEqual(network.netstat(), 'A')
|
|
|
|
|
|
|
|
with patch.dict(network.__grains__, {'kernel': 'OpenBSD'}):
|
|
|
|
with patch.object(network, '_netstat_bsd', return_value='A'):
|
|
|
|
self.assertEqual(network.netstat(), 'A')
|
|
|
|
|
|
|
|
with patch.dict(network.__grains__, {'kernel': 'A'}):
|
|
|
|
self.assertRaises(CommandExecutionError, network.netstat)
|
|
|
|
|
|
|
|
def test_active_tcp(self):
|
|
|
|
'''
|
|
|
|
Test for return a dict containing information on all
|
|
|
|
of the running TCP connections
|
|
|
|
'''
|
|
|
|
with patch.object(salt.utils.network, 'active_tcp', return_value='A'):
|
|
|
|
self.assertEqual(network.active_tcp(), 'A')
|
|
|
|
|
|
|
|
def test_traceroute(self):
|
|
|
|
'''
|
|
|
|
Test for Performs a traceroute to a 3rd party host
|
|
|
|
'''
|
|
|
|
with patch.object(salt.utils, 'which', side_effect=[False, True]):
|
|
|
|
self.assertListEqual(network.traceroute('host'), [])
|
|
|
|
|
|
|
|
with patch.object(salt.utils.network, 'sanitize_host',
|
|
|
|
return_value='A'):
|
|
|
|
with patch.dict(network.__salt__, {'cmd.run':
|
|
|
|
MagicMock(return_value="")}):
|
|
|
|
self.assertListEqual(network.traceroute('host'), [])
|
|
|
|
|
|
|
|
def test_dig(self):
|
|
|
|
'''
|
|
|
|
Test for Performs a DNS lookup with dig
|
|
|
|
'''
|
|
|
|
with patch.object(salt.utils.network, 'sanitize_host',
|
|
|
|
return_value='A'):
|
|
|
|
with patch.dict(network.__salt__, {'cmd.run':
|
|
|
|
MagicMock(return_value='A')}):
|
|
|
|
self.assertEqual(network.dig('host'), 'A')
|
|
|
|
|
2015-04-03 14:28:10 +00:00
|
|
|
@patch('salt.utils.which', MagicMock(return_value=''))
|
2015-04-02 06:55:48 +00:00
|
|
|
def test_arp(self):
|
|
|
|
'''
|
|
|
|
Test for return the arp table from the minion
|
|
|
|
'''
|
|
|
|
with patch.dict(network.__salt__,
|
|
|
|
{'cmd.run':
|
|
|
|
MagicMock(return_value='A,B,C,D\nE,F,G,H\n')}):
|
|
|
|
self.assertDictEqual(network.arp(), {})
|
|
|
|
|
|
|
|
def test_interfaces(self):
|
|
|
|
'''
|
|
|
|
Test for return a dictionary of information about
|
|
|
|
all the interfaces on the minion
|
|
|
|
'''
|
|
|
|
with patch.object(salt.utils.network, 'interfaces', return_value={}):
|
|
|
|
self.assertDictEqual(network.interfaces(), {})
|
|
|
|
|
|
|
|
def test_hw_addr(self):
|
|
|
|
'''
|
|
|
|
Test for return the hardware address (a.k.a. MAC address)
|
|
|
|
for a given interface
|
|
|
|
'''
|
|
|
|
with patch.object(salt.utils.network, 'hw_addr', return_value={}):
|
|
|
|
self.assertDictEqual(network.hw_addr('iface'), {})
|
|
|
|
|
|
|
|
def test_interface(self):
|
|
|
|
'''
|
|
|
|
Test for return the inet address for a given interface
|
|
|
|
'''
|
|
|
|
with patch.object(salt.utils.network, 'interface', return_value={}):
|
|
|
|
self.assertDictEqual(network.interface('iface'), {})
|
|
|
|
|
|
|
|
def test_interface_ip(self):
|
|
|
|
'''
|
|
|
|
Test for return the inet address for a given interface
|
|
|
|
'''
|
|
|
|
with patch.object(salt.utils.network, 'interface_ip', return_value={}):
|
|
|
|
self.assertDictEqual(network.interface_ip('iface'), {})
|
|
|
|
|
|
|
|
def test_subnets(self):
|
|
|
|
'''
|
|
|
|
Test for returns a list of subnets to which the host belongs
|
|
|
|
'''
|
|
|
|
with patch.object(salt.utils.network, 'subnets', return_value={}):
|
|
|
|
self.assertDictEqual(network.subnets(), {})
|
|
|
|
|
|
|
|
def test_in_subnet(self):
|
|
|
|
'''
|
|
|
|
Test for returns True if host is within specified
|
|
|
|
subnet, otherwise False.
|
|
|
|
'''
|
|
|
|
with patch.object(salt.utils.network, 'in_subnet', return_value={}):
|
|
|
|
self.assertDictEqual(network.in_subnet('iface'), {})
|
|
|
|
|
|
|
|
def test_ip_addrs(self):
|
|
|
|
'''
|
|
|
|
Test for returns a list of IPv4 addresses assigned to the host.
|
|
|
|
'''
|
|
|
|
with patch.object(salt.utils.network, 'ip_addrs',
|
|
|
|
return_value=['0.0.0.0']):
|
|
|
|
with patch.object(salt.utils.network, 'in_subnet',
|
|
|
|
return_value=True):
|
|
|
|
self.assertListEqual(network.ip_addrs('interface',
|
|
|
|
'include_loopback',
|
|
|
|
'cidr'), ['0.0.0.0'])
|
|
|
|
|
|
|
|
self.assertListEqual(network.ip_addrs('interface',
|
|
|
|
'include_loopback'),
|
|
|
|
['0.0.0.0'])
|
|
|
|
|
|
|
|
def test_ip_addrs6(self):
|
|
|
|
'''
|
|
|
|
Test for returns a list of IPv6 addresses assigned to the host.
|
|
|
|
'''
|
|
|
|
with patch.object(salt.utils.network, 'ip_addrs6',
|
|
|
|
return_value=['A']):
|
|
|
|
self.assertListEqual(network.ip_addrs6('int', 'include'), ['A'])
|
|
|
|
|
|
|
|
def test_get_hostname(self):
|
|
|
|
'''
|
|
|
|
Test for Get hostname
|
|
|
|
'''
|
|
|
|
with patch.object(network.socket, 'gethostname', return_value='A'):
|
|
|
|
self.assertEqual(network.get_hostname(), 'A')
|
|
|
|
|
|
|
|
def test_mod_hostname(self):
|
|
|
|
'''
|
|
|
|
Test for Modify hostname
|
|
|
|
'''
|
|
|
|
self.assertFalse(network.mod_hostname(None))
|
|
|
|
|
|
|
|
with patch.object(salt.utils, 'which', return_value='hostname'):
|
|
|
|
with patch.dict(network.__salt__,
|
|
|
|
{'cmd.run': MagicMock(return_value=None)}):
|
|
|
|
file_d = '\n'.join(['#', 'A B C D,E,F G H'])
|
|
|
|
with patch('salt.utils.fopen', mock_open(read_data=file_d),
|
|
|
|
create=True) as mfi:
|
|
|
|
mfi.return_value.__iter__.return_value = file_d.splitlines()
|
|
|
|
with patch.dict(network.__grains__, {'os_family': 'A'}):
|
|
|
|
self.assertTrue(network.mod_hostname('hostname'))
|
|
|
|
|
|
|
|
@patch('socket.socket')
|
|
|
|
def test_connect(self, mock_socket):
|
|
|
|
'''
|
|
|
|
Test for Test connectivity to a host using a particular
|
|
|
|
port from the minion.
|
|
|
|
'''
|
|
|
|
self.assertDictEqual(network.connect(False, 'port'),
|
|
|
|
{'comment': 'Required argument, host, is missing.',
|
|
|
|
'result': False})
|
|
|
|
|
|
|
|
self.assertDictEqual(network.connect('host', False),
|
|
|
|
{'comment': 'Required argument, port, is missing.',
|
|
|
|
'result': False})
|
|
|
|
|
|
|
|
ret = 'Unable to connect to host (0) on tcp port port'
|
|
|
|
mock_socket.side_effect = Exception('foo')
|
|
|
|
with patch.object(salt.utils.network, 'sanitize_host',
|
|
|
|
return_value='A'):
|
|
|
|
with patch.object(socket, 'getaddrinfo',
|
|
|
|
return_value=[['ipv4', 'A', 6, 'B', '0.0.0.0']]):
|
|
|
|
self.assertDictEqual(network.connect('host', 'port'),
|
|
|
|
{'comment': ret, 'result': False})
|
|
|
|
|
|
|
|
ret = 'Successfully connected to host (0) on tcp port port'
|
|
|
|
mock_socket.side_effect = MagicMock()
|
|
|
|
mock_socket.settimeout().return_value = None
|
|
|
|
mock_socket.connect().return_value = None
|
|
|
|
mock_socket.shutdown().return_value = None
|
|
|
|
with patch.object(salt.utils.network, 'sanitize_host',
|
|
|
|
return_value='A'):
|
|
|
|
with patch.object(socket,
|
|
|
|
'getaddrinfo',
|
|
|
|
return_value=[['ipv4',
|
|
|
|
'A', 6, 'B', '0.0.0.0']]):
|
|
|
|
self.assertDictEqual(network.connect('host', 'port'),
|
|
|
|
{'comment': ret, 'result': True})
|
|
|
|
|
|
|
|
def test_is_private(self):
|
|
|
|
'''
|
|
|
|
Test for Check if the given IP address is a private address
|
|
|
|
'''
|
2015-05-01 17:34:08 +00:00
|
|
|
with patch.object(salt.ext.ipaddress.IPv4Address, 'is_private',
|
2015-04-02 06:55:48 +00:00
|
|
|
return_value=True):
|
|
|
|
self.assertTrue(network.is_private('0.0.0.0'))
|
2015-05-01 18:29:25 +00:00
|
|
|
with patch.object(salt.ext.ipaddress.IPv6Address, 'is_private',
|
|
|
|
return_value=True):
|
|
|
|
self.assertTrue(network.is_private('::1'))
|
2015-04-02 06:55:48 +00:00
|
|
|
|
|
|
|
def test_is_loopback(self):
|
|
|
|
'''
|
|
|
|
Test for Check if the given IP address is a loopback address
|
|
|
|
'''
|
2015-05-01 17:34:08 +00:00
|
|
|
with patch.object(salt.ext.ipaddress.IPv4Address, 'is_loopback',
|
2015-05-01 18:29:25 +00:00
|
|
|
return_value=True):
|
|
|
|
self.assertTrue(network.is_loopback('127.0.0.1'))
|
|
|
|
with patch.object(salt.ext.ipaddress.IPv6Address, 'is_loopback',
|
|
|
|
return_value=True):
|
|
|
|
self.assertTrue(network.is_loopback('::1'))
|
2015-04-02 06:55:48 +00:00
|
|
|
|
|
|
|
def test_get_bufsize(self):
|
|
|
|
'''
|
|
|
|
Test for return network buffer sizes as a dict
|
|
|
|
'''
|
|
|
|
with patch.dict(network.__grains__, {'kernel': 'Linux'}):
|
|
|
|
with patch.object(os.path, 'exists', return_value=True):
|
|
|
|
with patch.object(network, '_get_bufsize_linux',
|
|
|
|
return_value={'size': 1}):
|
|
|
|
self.assertDictEqual(network.get_bufsize('iface'),
|
|
|
|
{'size': 1})
|
|
|
|
|
|
|
|
with patch.dict(network.__grains__, {'kernel': 'A'}):
|
|
|
|
self.assertDictEqual(network.get_bufsize('iface'), {})
|
|
|
|
|
|
|
|
def test_mod_bufsize(self):
|
|
|
|
'''
|
|
|
|
Test for Modify network interface buffers (currently linux only)
|
|
|
|
'''
|
|
|
|
with patch.dict(network.__grains__, {'kernel': 'Linux'}):
|
|
|
|
with patch.object(os.path, 'exists', return_value=True):
|
|
|
|
with patch.object(network, '_mod_bufsize_linux',
|
|
|
|
return_value={'size': 1}):
|
|
|
|
self.assertDictEqual(network.mod_bufsize('iface'),
|
|
|
|
{'size': 1})
|
|
|
|
|
|
|
|
with patch.dict(network.__grains__, {'kernel': 'A'}):
|
|
|
|
self.assertFalse(network.mod_bufsize('iface'))
|
|
|
|
|
|
|
|
def test_routes(self):
|
|
|
|
'''
|
|
|
|
Test for return currently configured routes from routing table
|
|
|
|
'''
|
|
|
|
self.assertRaises(CommandExecutionError, network.routes, 'family')
|
|
|
|
|
|
|
|
with patch.dict(network.__grains__, {'kernel': 'A', 'os': 'B'}):
|
|
|
|
self.assertRaises(CommandExecutionError, network.routes, 'inet')
|
|
|
|
|
|
|
|
with patch.dict(network.__grains__, {'kernel': 'Linux'}):
|
|
|
|
with patch.object(network, '_netstat_route_linux',
|
|
|
|
side_effect=['A', [{'addr_family': 'inet'}]]):
|
|
|
|
self.assertEqual(network.routes(None), 'A')
|
|
|
|
|
|
|
|
self.assertListEqual(network.routes('inet'),
|
|
|
|
[{'addr_family': 'inet'}])
|
|
|
|
|
|
|
|
def test_default_route(self):
|
|
|
|
'''
|
|
|
|
Test for return default route(s) from routing table
|
|
|
|
'''
|
|
|
|
self.assertRaises(CommandExecutionError, network.default_route,
|
|
|
|
'family')
|
|
|
|
|
|
|
|
with patch.object(network, 'routes',
|
|
|
|
side_effect=[[{'addr_family': 'inet'},
|
|
|
|
{'destination': 'A'}], []]):
|
|
|
|
with patch.dict(network.__grains__, {'kernel': 'A',
|
|
|
|
'os': 'B'}):
|
|
|
|
self.assertRaises(CommandExecutionError,
|
|
|
|
network.default_route, 'inet')
|
|
|
|
|
|
|
|
with patch.dict(network.__grains__, {'kernel': 'Linux'}):
|
|
|
|
self.assertListEqual(network.default_route('inet'), [])
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
from integration import run_tests
|
|
|
|
run_tests(NetworkTestCase, needs_daemon=False)
|