charm-neutron-openvswitch/unit_tests/test_pci_helper.py
James Page acd617f4ca Add support for DPDK userspace networking
Add full support for DPDK; this includes a number of configuration
options to allow the number of cores and memory allocated per
NUMA node to be changed.  By default, the first core and 1024MB of
RAM of each NUMA node will be configured for DPDK use.

When DPDK is enabled, OVS bridges are configured as datapath type
'netdev' rather than type 'system' to allow use of userspace
DPDK packet processing; Security groups are also disabled, as
iptables based rules cannot be applied against userspace sockets.

DPDK device binding is undertaken using /etc/dpdk/interfaces and
the dpdk init script provided as part of the DPDK package; device
resolution is determined using the data-port configuration option
using the <bridge:<mac address> format - MAC addresses are used
to resolve underlying PCI device names for binding with DPDK.

It's assumed that hugepage memory configuration is either done as
part of system boot as kernel command line options (set via MAAS)
or using the hugepages configuration option on the nova-compute
charm.

Change-Id: Ieb2ac522b07e495f1855e304d31eef59c316c0e4
2016-04-07 12:42:16 +01:00

95 lines
2.9 KiB
Python

#!/usr/bin/python
import pci
from test_utils import patch_open
from mock import patch, MagicMock
import pci_responses
import os
def check_device(device, attr_dict):
equal = device.interface_name == attr_dict['interface_name'] and \
device.mac_address == attr_dict['mac_address'] and \
device.pci_address == attr_dict['pci_address'] and \
device.state == attr_dict['state']
return equal
def mocked_subprocess(subproc_map=None):
def _subproc(cmd, stdin=None):
for key in pci_responses.COMMANDS.keys():
if pci_responses.COMMANDS[key] == cmd:
return subproc_map[key]
elif pci_responses.COMMANDS[key] == cmd[:-1]:
return subproc_map[cmd[-1]][key]
if not subproc_map:
subproc_map = pci_responses.NET_SETUP
return _subproc
class mocked_filehandle(object):
def _setfilename(self, fname, omode):
self.FILENAME = fname
def _getfilecontents_read(self):
return pci_responses.FILE_CONTENTS[self.FILENAME]
def _getfilecontents_readlines(self):
return pci_responses.FILE_CONTENTS[self.FILENAME].split('\n')
def mocked_globs(path):
check_path = path.rstrip('*').rstrip('/')
dirs = []
for sdir in pci_responses.SYS_TREE:
if check_path in sdir:
dirs.append(sdir)
return dirs
def mocked_islink(link):
resolved_relpath = mocked_resolve_link(link)
if pci_responses.SYS_TREE.get(resolved_relpath):
return True
else:
return False
def mocked_resolve_link(link):
resolved_relpath = None
for sdir in pci_responses.SYS_TREE:
if sdir in link:
rep_dir = "{}/{}".format(os.path.dirname(sdir),
pci_responses.SYS_TREE[sdir])
resolved_symlink = link.replace(sdir, rep_dir)
resolved_relpath = os.path.abspath(resolved_symlink)
return resolved_relpath
def mocked_realpath(link):
resolved_link = mocked_resolve_link(link)
return pci_responses.SYS_TREE[resolved_link]
@patch('pci.log')
@patch('pci.subprocess.Popen')
@patch('pci.subprocess.check_output')
@patch('pci.glob.glob')
@patch('pci.os.path.islink')
def pci_devs(_osislink, _glob, _check_output, _Popen, _log, subproc_map=None):
_glob.side_effect = mocked_globs
_osislink.side_effect = mocked_islink
_check_output.side_effect = mocked_subprocess(
subproc_map=subproc_map)
with patch_open() as (_open, _file), \
patch('pci.os.path.realpath') as _realpath:
super_fh = mocked_filehandle()
_file.readlines = MagicMock()
_open.side_effect = super_fh._setfilename
_file.read.side_effect = super_fh._getfilecontents_read
_file.readlines.side_effect = super_fh._getfilecontents_readlines
_realpath.side_effect = mocked_realpath
devices = pci.PCINetDevices()
return devices