|
|
@@ -0,0 +1,232 @@ |
|
|
|
# -*- coding: utf-8 -*- |
|
|
|
|
|
|
|
# Copyright 2019 Red Hat, Inc. |
|
|
|
# |
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may |
|
|
|
# not use this file except in compliance with the License. You may obtain |
|
|
|
# a copy of the License at |
|
|
|
# |
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0 |
|
|
|
# |
|
|
|
# Unless required by applicable law or agreed to in writing, software |
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
|
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
|
|
|
# License for the specific language governing permissions and limitations |
|
|
|
# under the License. |
|
|
|
|
|
|
|
import os |
|
|
|
import os.path |
|
|
|
import random |
|
|
|
import shutil |
|
|
|
|
|
|
|
from os_net_config import sriov_config |
|
|
|
from os_net_config.tests import base |
|
|
|
from os_net_config import utils |
|
|
|
|
|
|
|
|
|
|
|
class TestSriovConfig(base.TestCase): |
|
|
|
|
|
|
|
def setUp(self): |
|
|
|
super(TestSriovConfig, self).setUp() |
|
|
|
rand = str(int(random.random() * 100000)) |
|
|
|
|
|
|
|
sriov_config._SYS_CLASS_NET = '/tmp/sys_class_net' |
|
|
|
sriov_config._UDEV_RULE_FILE = '/tmp/etc_udev_rules.d_80-persistent'\ |
|
|
|
'-os-net-config.rules' |
|
|
|
sriov_config._UDEV_LEGACY_RULE_FILE = '/tmp/etc_udev_rules.d_'\ |
|
|
|
'70-os-net-config-sriov.rules' |
|
|
|
sriov_config._IFUP_LOCAL_FILE = '/tmp/sbin_ifup-local' |
|
|
|
sriov_config._RESET_SRIOV_RULES_FILE = '/tmp/etc_udev_rules.d_'\ |
|
|
|
'70-tripleo-reset-sriov.rules' |
|
|
|
sriov_config._ALLOCATE_VFS_FILE = '/tmp/etc_sysconfig_allocate_vfs' |
|
|
|
sriov_config._SRIOV_CONFIG_FILE = '/tmp/sriov_config_' + rand + \ |
|
|
|
'.yaml' |
|
|
|
os.mkdir(sriov_config._SYS_CLASS_NET) |
|
|
|
|
|
|
|
def tearDown(self): |
|
|
|
super(TestSriovConfig, self).tearDown() |
|
|
|
if os.path.isfile(sriov_config._SRIOV_CONFIG_FILE): |
|
|
|
os.remove(sriov_config._SRIOV_CONFIG_FILE) |
|
|
|
if os.path.isfile(sriov_config._IFUP_LOCAL_FILE): |
|
|
|
os.remove(sriov_config._IFUP_LOCAL_FILE) |
|
|
|
shutil.rmtree(sriov_config._SYS_CLASS_NET) |
|
|
|
|
|
|
|
def test_configure_sriov_pf(self): |
|
|
|
exp_udev_content = '# This file is autogenerated by os-net-config\n'\ |
|
|
|
'KERNEL=="p2p1", RUN+="/bin/os-net-config-sriov -n %k:10"\n'\ |
|
|
|
'KERNEL=="p2p2", RUN+="/bin/os-net-config-sriov -n %k:12"\n' |
|
|
|
|
|
|
|
run_cmd = [] |
|
|
|
|
|
|
|
def run_ip_config_cmd_stub(*args, **kwargs): |
|
|
|
run_cmd.append(' '.join(args)) |
|
|
|
self.stub_out('os_net_config.sriov_config.run_ip_config_cmd', |
|
|
|
run_ip_config_cmd_stub) |
|
|
|
|
|
|
|
def udev_monitor_setup_stub(): |
|
|
|
return |
|
|
|
self.stub_out('os_net_config.sriov_config.udev_monitor_setup', |
|
|
|
udev_monitor_setup_stub) |
|
|
|
|
|
|
|
def udev_monitor_start_stub(observer): |
|
|
|
return |
|
|
|
self.stub_out('os_net_config.sriov_config.udev_monitor_start', |
|
|
|
udev_monitor_start_stub) |
|
|
|
|
|
|
|
def udev_monitor_stop_stub(observer): |
|
|
|
return |
|
|
|
self.stub_out('os_net_config.sriov_config.udev_monitor_stop', |
|
|
|
udev_monitor_stop_stub) |
|
|
|
|
|
|
|
def cleanup_puppet_config_stub(): |
|
|
|
return |
|
|
|
self.stub_out('os_net_config.sriov_config.cleanup_puppet_config', |
|
|
|
cleanup_puppet_config_stub) |
|
|
|
|
|
|
|
def trigger_udev_rules_stub(): |
|
|
|
return |
|
|
|
self.stub_out('os_net_config.sriov_config.trigger_udev_rules', |
|
|
|
trigger_udev_rules_stub) |
|
|
|
|
|
|
|
def reload_udev_rules_stub(): |
|
|
|
return |
|
|
|
self.stub_out('os_net_config.sriov_config.reload_udev_rules', |
|
|
|
reload_udev_rules_stub) |
|
|
|
|
|
|
|
def _wait_for_vf_creation_stub(pf_name, numvfs): |
|
|
|
numvfs_pair = {"p2p1": 10, "p2p2": 12} |
|
|
|
self.assertEqual(numvfs_pair[pf_name], numvfs) |
|
|
|
self.stub_out('os_net_config.sriov_config._wait_for_vf_creation', |
|
|
|
_wait_for_vf_creation_stub) |
|
|
|
|
|
|
|
def get_vendor_id_stub(ifname): |
|
|
|
return "0x8086" |
|
|
|
self.stub_out('os_net_config.sriov_config.get_vendor_id', |
|
|
|
get_vendor_id_stub) |
|
|
|
|
|
|
|
pf_config = [{"device_type": "pf", "name": "p2p1", "numvfs": 10, |
|
|
|
"promisc": "on", "link_mode": "legacy"}, |
|
|
|
{"device_type": "pf", "name": "p2p2", "numvfs": 12, |
|
|
|
"promisc": "off", "link_mode": "legacy"}] |
|
|
|
|
|
|
|
os.makedirs(sriov_config._SYS_CLASS_NET + "/p2p1/device") |
|
|
|
os.makedirs(sriov_config._SYS_CLASS_NET + "/p2p2/device") |
|
|
|
f = open(sriov_config._SYS_CLASS_NET + "/p2p1/device/sriov_numvfs", |
|
|
|
"w+") |
|
|
|
f.write("0") |
|
|
|
f.close() |
|
|
|
|
|
|
|
f = open(sriov_config._SYS_CLASS_NET + "/p2p2/device/sriov_numvfs", |
|
|
|
"w+") |
|
|
|
f.write("0") |
|
|
|
f.close() |
|
|
|
|
|
|
|
utils.write_yaml_config(sriov_config._SRIOV_CONFIG_FILE, pf_config) |
|
|
|
sriov_config.configure_logger(debug=True) |
|
|
|
sriov_config.configure_sriov_pf() |
|
|
|
|
|
|
|
f = open(sriov_config._UDEV_LEGACY_RULE_FILE, 'r') |
|
|
|
self.assertEqual(exp_udev_content, f.read()) |
|
|
|
self.assertEqual(10, sriov_config.get_numvfs('p2p1')) |
|
|
|
self.assertEqual(12, sriov_config.get_numvfs('p2p2')) |
|
|
|
|
|
|
|
def test_cleanup_puppet_config_deprecation(self): |
|
|
|
content = '#!/bin/bash\n'\ |
|
|
|
'/etc/sysconfig/allocate_vfs $1' |
|
|
|
f = open(sriov_config._RESET_SRIOV_RULES_FILE, "w+") |
|
|
|
f.close() |
|
|
|
f = open(sriov_config._ALLOCATE_VFS_FILE, "w+") |
|
|
|
f.close() |
|
|
|
f = open(sriov_config._IFUP_LOCAL_FILE, "w+") |
|
|
|
f.write(content) |
|
|
|
f.close() |
|
|
|
|
|
|
|
sriov_config.cleanup_puppet_config() |
|
|
|
self.assertEqual(False, |
|
|
|
os.path.exists(sriov_config._RESET_SRIOV_RULES_FILE)) |
|
|
|
self.assertEqual(False, |
|
|
|
os.path.exists(sriov_config._ALLOCATE_VFS_FILE)) |
|
|
|
self.assertEqual(False, |
|
|
|
os.path.exists(sriov_config._IFUP_LOCAL_FILE)) |
|
|
|
|
|
|
|
def test_cleanup_puppet_config_new(self): |
|
|
|
sriov_config.cleanup_puppet_config() |
|
|
|
self.assertEqual(False, |
|
|
|
os.path.exists(sriov_config._RESET_SRIOV_RULES_FILE)) |
|
|
|
self.assertEqual(False, |
|
|
|
os.path.exists(sriov_config._ALLOCATE_VFS_FILE)) |
|
|
|
self.assertEqual(False, |
|
|
|
os.path.exists(sriov_config._IFUP_LOCAL_FILE)) |
|
|
|
|
|
|
|
def test_cleanup_puppet_config_modified(self): |
|
|
|
content = '#!/bin/bash\n'\ |
|
|
|
'/etc/sysconfig/allocate_vfs $1\n'\ |
|
|
|
'/usr/sbin/ifup eth0' |
|
|
|
mod_content = '#!/bin/bash\n'\ |
|
|
|
'/usr/sbin/ifup eth0' |
|
|
|
f = open(sriov_config._IFUP_LOCAL_FILE, "w+") |
|
|
|
f.write(content) |
|
|
|
f.close() |
|
|
|
|
|
|
|
sriov_config.cleanup_puppet_config() |
|
|
|
self.assertEqual(False, |
|
|
|
os.path.exists(sriov_config._RESET_SRIOV_RULES_FILE)) |
|
|
|
self.assertEqual(False, |
|
|
|
os.path.exists(sriov_config._ALLOCATE_VFS_FILE)) |
|
|
|
self.assertEqual(True, |
|
|
|
os.path.exists(sriov_config._IFUP_LOCAL_FILE)) |
|
|
|
|
|
|
|
f = open(sriov_config._IFUP_LOCAL_FILE, "r") |
|
|
|
self.assertEqual(mod_content, f.read()) |
|
|
|
|
|
|
|
def test_numvfs_config(self): |
|
|
|
os.makedirs(sriov_config._SYS_CLASS_NET + "/p2p1/device") |
|
|
|
f = open(sriov_config._SYS_CLASS_NET + "/p2p1/device/sriov_numvfs", |
|
|
|
"w+") |
|
|
|
f.write("0") |
|
|
|
f.close() |
|
|
|
self.assertEqual(None, sriov_config.main(['ARG0', '-n', 'p2p1:15'])) |
|
|
|
self.assertEqual(15, sriov_config.get_numvfs('p2p1')) |
|
|
|
|
|
|
|
def test_numvfs_invalid_params(self): |
|
|
|
os.makedirs(sriov_config._SYS_CLASS_NET + "/p2p1/device") |
|
|
|
f = open(sriov_config._SYS_CLASS_NET + "/p2p1/device/sriov_numvfs", |
|
|
|
"w+") |
|
|
|
f.write("0") |
|
|
|
f.close() |
|
|
|
self.assertEqual(1, sriov_config.main(['ARG0', '-n', 'p2p1:15a'])) |
|
|
|
self.assertEqual(0, sriov_config.get_numvfs('p2p1')) |
|
|
|
|
|
|
|
def test_numvfs_preconfigured(self): |
|
|
|
os.makedirs(sriov_config._SYS_CLASS_NET + "/p2p1/device") |
|
|
|
f = open(sriov_config._SYS_CLASS_NET + "/p2p1/device/sriov_numvfs", |
|
|
|
"w+") |
|
|
|
f.write("10") |
|
|
|
f.close() |
|
|
|
self.assertEqual(None, sriov_config.main(['ARG0', '-n', 'p2p1:15'])) |
|
|
|
self.assertEqual(10, sriov_config.get_numvfs('p2p1')) |
|
|
|
|
|
|
|
def test_configure_sriov_vf(self): |
|
|
|
vf_config = [{"device_type": "vf", "device": {"name": "p2p1", |
|
|
|
"vfid": 1}, "promisc": "on", "vlan_id": 101, |
|
|
|
"qos": 5, "macaddr": "AA:BB:CC:DD:EE:FF", |
|
|
|
"spoofcheck": "on", "state": "auto", "trust": "on", |
|
|
|
"name": "p2p1_1"}] |
|
|
|
exp_cmds = ["ip link set dev p2p1 vf 1 mac AA:BB:CC:DD:EE:FF", |
|
|
|
"ip link set dev p2p1 vf 1 vlan 101 qos 5", |
|
|
|
"ip link set dev p2p1_1 promisc on", |
|
|
|
"ip link set dev p2p1 vf 1 spoofchk on", |
|
|
|
"ip link set dev p2p1 vf 1 state auto", |
|
|
|
"ip link set dev p2p1 vf 1 trust on"] |
|
|
|
run_cmd = [] |
|
|
|
|
|
|
|
def run_ip_config_cmd_stub(*args, **kwargs): |
|
|
|
run_cmd.append(' '.join(args)) |
|
|
|
self.stub_out('os_net_config.sriov_config.run_ip_config_cmd', |
|
|
|
run_ip_config_cmd_stub) |
|
|
|
|
|
|
|
utils.write_yaml_config(sriov_config._SRIOV_CONFIG_FILE, vf_config) |
|
|
|
sriov_config.configure_sriov_vf() |
|
|
|
|
|
|
|
for cmd in exp_cmds: |
|
|
|
self.assertIn(cmd, run_cmd) |