Test network bonding with DPDK
Test enabling of DPDK for NICs bond which is used
by private network.
Change-Id: Ia6c350b36be10b8172fca4927e709c95e9d9a5a3
Implements: blueprint test-ovs-dpdk
(cherry picked from commit c604e312c9
)
This commit is contained in:
parent
dda97d5a2d
commit
79c6c2bf35
|
@ -35,7 +35,9 @@ class BondingTest(TestBasic):
|
|||
],
|
||||
'state': None,
|
||||
'type': 'bond',
|
||||
'assigned_networks': []
|
||||
'assigned_networks': [],
|
||||
'bond_properties': {'mode': 'active-backup',
|
||||
'type__': 'linux'},
|
||||
},
|
||||
{
|
||||
'mac': None,
|
||||
|
@ -47,7 +49,9 @@ class BondingTest(TestBasic):
|
|||
],
|
||||
'state': None,
|
||||
'type': 'bond',
|
||||
'assigned_networks': []
|
||||
'assigned_networks': [],
|
||||
'bond_properties': {'mode': 'active-backup',
|
||||
'type__': 'linux'},
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -124,3 +128,65 @@ class BondingTest(TestBasic):
|
|||
assert_false(network_settings_changed,
|
||||
"Network settings were changed after environment nodes "
|
||||
"reboot! Please check logs for details!")
|
||||
|
||||
|
||||
class BondingTestDPDK(BondingTest):
|
||||
def __init__(self):
|
||||
super(BondingTestDPDK, self).__init__()
|
||||
self.BOND_CONFIG = [
|
||||
{
|
||||
'mac': None,
|
||||
'mode': 'active-backup',
|
||||
'name': 'bond0',
|
||||
'slaves': [
|
||||
{'name': iface_alias('eth3')},
|
||||
{'name': iface_alias('eth2')}
|
||||
],
|
||||
'state': None,
|
||||
'type': 'bond',
|
||||
'assigned_networks': [],
|
||||
'interface_properties': {'dpdk': {'available': True}},
|
||||
'bond_properties': {'mode': 'active-backup',
|
||||
'type__': 'linux'},
|
||||
},
|
||||
{
|
||||
'mac': None,
|
||||
'mode': 'active-backup',
|
||||
'name': 'bond1',
|
||||
'slaves': [
|
||||
{'name': iface_alias('eth1')},
|
||||
{'name': iface_alias('eth0')}
|
||||
],
|
||||
'state': None,
|
||||
'type': 'bond',
|
||||
'assigned_networks': [],
|
||||
'interface_properties': {'dpdk': {'available': True}},
|
||||
'bond_properties': {'mode': 'active-backup',
|
||||
'type__': 'linux'},
|
||||
},
|
||||
{
|
||||
'mac': None,
|
||||
'mode': 'active-backup',
|
||||
'name': 'bond2',
|
||||
'slaves': [
|
||||
{'name': iface_alias('eth5')},
|
||||
{'name': iface_alias('eth4')},
|
||||
],
|
||||
'state': None,
|
||||
'type': 'bond',
|
||||
'assigned_networks': [],
|
||||
'interface_properties': {'dpdk': {'available': True}},
|
||||
'bond_properties': {'mode': 'active-backup',
|
||||
'type__': 'linux'},
|
||||
},
|
||||
]
|
||||
|
||||
self.INTERFACES = {
|
||||
'bond0': [
|
||||
'public',
|
||||
'management',
|
||||
'storage',
|
||||
],
|
||||
'bond1': ['fuelweb_admin'],
|
||||
'bond2': ['private'],
|
||||
}
|
||||
|
|
|
@ -12,17 +12,19 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from copy import deepcopy
|
||||
import random
|
||||
|
||||
from devops.helpers import helpers as devops_helpers
|
||||
from proboscis.asserts import assert_true
|
||||
from proboscis import before_class
|
||||
from proboscis import test
|
||||
from proboscis import SkipTest
|
||||
|
||||
from fuelweb_test.helpers.decorators import log_snapshot_after_test
|
||||
from fuelweb_test.helpers import os_actions
|
||||
from fuelweb_test.tests.base_test_case import SetupEnvironment
|
||||
from fuelweb_test.tests.base_test_case import TestBasic
|
||||
from fuelweb_test.tests.test_bonding_base import BondingTestDPDK
|
||||
from fuelweb_test import logger
|
||||
from fuelweb_test import settings
|
||||
|
||||
|
@ -33,7 +35,7 @@ class SupportDPDK(TestBasic):
|
|||
|
||||
def check_dpdk_instance_connectivity(self, os_conn, cluster_id,
|
||||
mem_page_size='2048'):
|
||||
"""Boot VM and ping 8.8.8.8
|
||||
"""Boot VM with HugePages and ping it via floating IP
|
||||
|
||||
:param os_conn: an object of connection to openstack services
|
||||
:param cluster_id: an integer number of cluster id
|
||||
|
@ -59,21 +61,10 @@ class SupportDPDK(TestBasic):
|
|||
flavor=flavor_id)
|
||||
os_conn.verify_instance_status(server, 'ACTIVE')
|
||||
|
||||
ip = os_conn.get_nova_instance_ip(server, net_name=net_name,
|
||||
addrtype='fixed')
|
||||
logger.info("Instance {0} has IP {1}".format(server.id, ip))
|
||||
|
||||
float_ip = os_conn.assign_floating_ip(server)
|
||||
logger.info("Floating address {0} associated with instance {1}"
|
||||
.format(float_ip.ip, server.id))
|
||||
|
||||
logger.info("Wait for ping from instance {}".format(server.id))
|
||||
devops_helpers.wait(
|
||||
lambda: devops_helpers.tcp_ping(ip.ip, 22),
|
||||
timeout=300,
|
||||
timeout_msg=("Instance {0} is unreachable for {1} seconds".
|
||||
format(server.id, 300)))
|
||||
|
||||
logger.info("Wait for ping from instance {} "
|
||||
"by floating ip".format(server.id))
|
||||
devops_helpers.wait(
|
||||
|
@ -98,15 +89,22 @@ class SupportDPDK(TestBasic):
|
|||
def check_dpdk(self, nailgun_node, net='private'):
|
||||
compute_net = self.fuel_web.client.get_node_interfaces(
|
||||
nailgun_node['id'])
|
||||
dpdk_available = False
|
||||
dpdk_enabled = False
|
||||
for interface in compute_net:
|
||||
for ids in interface['assigned_networks']:
|
||||
if ids['name'] == net:
|
||||
return {
|
||||
'available': interface['interface_properties']['dpdk'][
|
||||
'available'],
|
||||
'enabled': interface['interface_properties']['dpdk'][
|
||||
'enabled']
|
||||
}
|
||||
if net not in [n['name'] for n in interface['assigned_networks']]:
|
||||
continue
|
||||
if 'dpdk' not in interface['interface_properties']:
|
||||
continue
|
||||
|
||||
dpdk_available = interface['interface_properties']['dpdk'][
|
||||
'available']
|
||||
if 'enabled' in interface['interface_properties']['dpdk']:
|
||||
dpdk_enabled = interface['interface_properties']['dpdk'][
|
||||
'enabled']
|
||||
break
|
||||
|
||||
return {'available': dpdk_available, 'enabled': dpdk_enabled}
|
||||
|
||||
def enable_dpdk(self, nailgun_node, switch_to=True, net='private'):
|
||||
assert_true(self.check_dpdk(nailgun_node, net=net)['available'],
|
||||
|
@ -117,13 +115,27 @@ class SupportDPDK(TestBasic):
|
|||
for interface in compute_net:
|
||||
for ids in interface['assigned_networks']:
|
||||
if ids['name'] == net:
|
||||
interface['interface_properties']['dpdk'][
|
||||
'enabled'] = switch_to
|
||||
if interface['type'] == 'bond':
|
||||
interface['bond_properties']['type__'] = 'ovs'
|
||||
interface['interface_properties']['dpdk'].update(
|
||||
{'enabled': switch_to})
|
||||
else:
|
||||
interface['interface_properties']['dpdk'][
|
||||
'enabled'] = switch_to
|
||||
break
|
||||
|
||||
self.fuel_web.client.put_node_interfaces(
|
||||
[{'id': nailgun_node['id'], 'interfaces': compute_net}])
|
||||
|
||||
return self.check_dpdk(nailgun_node, net=net)['enabled'] == switch_to
|
||||
|
||||
# pylint: disable=no-self-use
|
||||
@before_class
|
||||
def check_requirements(self):
|
||||
assert_true(settings.KVM_USE,
|
||||
'Can not start DPDK test without KVM_USE=True!')
|
||||
# pylint: enable=no-self-use
|
||||
|
||||
@test(depends_on=[SetupEnvironment.prepare_slaves_3],
|
||||
groups=["deploy_cluster_with_dpdk"])
|
||||
@log_snapshot_after_test
|
||||
|
@ -142,15 +154,12 @@ class SupportDPDK(TestBasic):
|
|||
9. Run OSTF
|
||||
10. Reboot compute
|
||||
11. Run OSTF
|
||||
12. Run instance on compute with DPDK and check
|
||||
availability via internal and floating ip
|
||||
12. Run instance on compute with DPDK and check its availability
|
||||
via floating IP
|
||||
|
||||
Snapshot: deploy_cluster_with_dpdk
|
||||
|
||||
"""
|
||||
if not settings.KVM_USE:
|
||||
raise SkipTest('Can not start DPDK test without KVM_USE=True')
|
||||
|
||||
self.env.revert_snapshot("ready_with_3_slaves")
|
||||
|
||||
self.show_step(1)
|
||||
|
@ -223,3 +232,98 @@ class SupportDPDK(TestBasic):
|
|||
self.check_dpdk_instance_connectivity(os_conn, cluster_id)
|
||||
|
||||
self.env.make_snapshot("deploy_cluster_with_dpdk")
|
||||
|
||||
|
||||
@test(groups=["support_dpdk_bond"])
|
||||
class SupportDPDKBond(BondingTestDPDK, SupportDPDK):
|
||||
"""SupportDPDKBond."""
|
||||
|
||||
@before_class
|
||||
def check_requirements(self):
|
||||
super(SupportDPDKBond, self).check_requirements()
|
||||
assert_true(settings.BONDING, 'Bonding is disabled! Aborting test...')
|
||||
|
||||
@test(depends_on=[SetupEnvironment.prepare_slaves_3],
|
||||
groups=["deploy_cluster_with_dpdk_bond"])
|
||||
@log_snapshot_after_test
|
||||
def deploy_cluster_with_dpdk_bond(self):
|
||||
"""Deploy cluster with DPDK, active-backup bonding and Neutron VLAN
|
||||
|
||||
Scenario:
|
||||
1. Create cluster with VLAN for Neutron and KVM
|
||||
2. Add 1 node with controller role
|
||||
3. Add 2 nodes with compute and cinder roles
|
||||
4. Setup bonding for all interfaces: 1 for admin, 1 for private
|
||||
and 1 for public/storage/management networks
|
||||
5. Configure HugePages for compute nodes
|
||||
6. Enable DPDK for bond with private network on all computes
|
||||
7. Run network verification
|
||||
8. Deploy the cluster
|
||||
9. Run network verification
|
||||
10. Run OSTF
|
||||
11. Run instance on compute with DPDK and check its availability
|
||||
via floating IP
|
||||
|
||||
Duration 90m
|
||||
Snapshot deploy_cluster_with_dpdk_bond
|
||||
"""
|
||||
|
||||
self.env.revert_snapshot("ready_with_3_slaves")
|
||||
|
||||
self.show_step(1)
|
||||
cluster_id = self.fuel_web.create_cluster(
|
||||
name=self.__class__.__name__,
|
||||
settings={
|
||||
"net_segment_type": settings.NEUTRON_SEGMENT['vlan'],
|
||||
}
|
||||
)
|
||||
|
||||
self.show_step(2)
|
||||
self.show_step(3)
|
||||
self.fuel_web.update_nodes(
|
||||
cluster_id, {
|
||||
'slave-01': ['controller'],
|
||||
'slave-02': ['compute', 'cinder'],
|
||||
'slave-03': ['compute', 'cinder']
|
||||
}
|
||||
)
|
||||
|
||||
self.show_step(4)
|
||||
nailgun_nodes = self.fuel_web.client.list_cluster_nodes(cluster_id)
|
||||
for node in nailgun_nodes:
|
||||
self.fuel_web.update_node_networks(
|
||||
node['id'], interfaces_dict=deepcopy(self.INTERFACES),
|
||||
raw_data=deepcopy(self.BOND_CONFIG)
|
||||
)
|
||||
|
||||
computes = self.fuel_web.get_nailgun_cluster_nodes_by_roles(
|
||||
cluster_id,
|
||||
roles=['compute'],
|
||||
role_status='pending_roles')
|
||||
|
||||
self.show_step(5)
|
||||
for node in computes:
|
||||
self.setup_hugepages(node, hp_2mb=256, hp_dpdk_mb=128)
|
||||
|
||||
self.show_step(6)
|
||||
for node in computes:
|
||||
self.enable_dpdk(node)
|
||||
|
||||
self.show_step(7)
|
||||
self.fuel_web.verify_network(cluster_id)
|
||||
|
||||
self.show_step(8)
|
||||
self.fuel_web.deploy_cluster_wait(cluster_id)
|
||||
|
||||
self.show_step(9)
|
||||
self.fuel_web.verify_network(cluster_id)
|
||||
|
||||
self.show_step(10)
|
||||
self.fuel_web.run_ostf(cluster_id=cluster_id)
|
||||
|
||||
self.show_step(11)
|
||||
os_conn = os_actions.OpenStackActions(
|
||||
self.fuel_web.get_public_vip(cluster_id))
|
||||
self.check_dpdk_instance_connectivity(os_conn, cluster_id)
|
||||
|
||||
self.env.make_snapshot("deploy_cluster_with_dpdk_bond")
|
||||
|
|
Loading…
Reference in New Issue