Add tests of offloading single bond interface

Closes-Bug: #1518236

Change-Id: I3283695bbd9b98cb19706daa5343931987167181
This commit is contained in:
zatserklyany 2015-11-19 14:04:25 +02:00 committed by tatyana-leontovich
parent a179380d35
commit 8f6472dc47
7 changed files with 323 additions and 56 deletions

View File

@ -31,6 +31,11 @@ Test Bonding
.. automodule:: fuelweb_test.tests.test_bonding
:members:
Test Bond offloading types
--------------------------
.. automodule:: fuelweb_test.tests.test_bond_offloading
:members:
Test By Tempest
---------------
.. automodule:: fuelweb_test.tests.test_by_tempest

View File

@ -1164,3 +1164,13 @@ def check_client_smoke(remote):
'fuel2 env list')['stdout'][3].split('|')[3].strip()
assert_equal(fuel_output, fuel_2_output,
"The fuel: {0} and fuel2: {1} outputs are not equal")
def check_offload(node, interface, offload_type):
command = "ethtool --show-offload %s | awk '/%s/ {print $2}'"
offload_status = node.execute(command % (interface, offload_type))
assert_equal(offload_status['exit_code'], 0,
"Failed to get Offload {0} "
"on node {1}".format(offload_type, node))
return ''.join(node.execute(
command % (interface, offload_type))['stdout']).rstrip()

View File

@ -1309,6 +1309,24 @@ class FuelWebClient(object):
for node in nailgun_nodes:
self.update_node_networks(node['id'], assigned_networks)
@logwrap
def update_offloads(self, node_id, update_values, interface_to_update):
interfaces = self.client.get_node_interfaces(node_id)
for i in interfaces:
if i['name'] == interface_to_update:
for new_mode in update_values['offloading_modes']:
is_mode_exist = False
for mode in i['offloading_modes']:
if mode['name'] == new_mode['name']:
is_mode_exist = True
mode.update(new_mode)
break
if not is_mode_exist:
i['offloading_modes'].append(new_mode)
self.client.put_node_interfaces(
[{'id': node_id, 'interfaces': interfaces}])
def change_default_network_settings(self):
api_version = self.client.get_api_version()
if int(api_version["release"][0]) < 6:

View File

@ -96,6 +96,7 @@ def import_tests():
from tests.tests_upgrade import test_upgrade_chains # noqa
from tests import test_bonding # noqa
from tests import test_offloading_types # noqa
from tests import test_bond_offloading # noqa
from tests.tests_strength import test_neutron # noqa
from tests import test_zabbix # noqa
from tests.plugins.plugin_emc import test_plugin_emc # noqa

View File

@ -0,0 +1,232 @@
# Copyright 2015 Mirantis, 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.
from copy import deepcopy
from proboscis.asserts import assert_equal
from proboscis import test
from fuelweb_test.helpers.checkers import check_offload
from fuelweb_test.helpers.decorators import log_snapshot_after_test
from fuelweb_test.settings import DEPLOYMENT_MODE_HA
from fuelweb_test.tests.base_test_case import SetupEnvironment
from fuelweb_test.tests.test_bonding_base import BondingTest
@test(groups=["bonding_ha_one_controller", "bonding"])
class TestOffloading(BondingTest):
bond0_offloading_types = ['generic-receive-offload',
'generic-segmentation-offload',
'tcp-segmentation-offload']
bond1_offloading_types = ['tx-udp_tnl-segmentation']
def prepare_offloading_modes(self, interfaces, offloading_types, state):
modes = [{'name': name, 'state': state, 'sub': []}
for name in offloading_types]
return [{'name': interface, 'offloading_modes': deepcopy(modes)}
for interface in interfaces]
@test(depends_on=[SetupEnvironment.prepare_slaves_3],
groups=["offloading_bond_neutron_vlan", "bonding"])
@log_snapshot_after_test
def offloading_bond_neutron_vlan(self):
"""Verify offloading types for the logical bonded interfaces and
neutron VLAN
Scenario:
1. Create cluster with neutron VLAN
2. Add 1 node with controller role
3. Add 1 node with compute role and 1 node with cinder role
4. Configure offloading modes for bonded interfaces
5. Setup offloading types
6. Run network verification
7. Deploy the cluster
8. Run network verification
9. Verify offloading types for the bonded interfaces
10. Run OSTF
Duration 60m
Snapshot offloading_bond_neutron_vlan
"""
self.env.revert_snapshot("ready_with_3_slaves")
self.show_step(1)
cluster_id = self.fuel_web.create_cluster(
name=self.__class__.__name__,
mode=DEPLOYMENT_MODE_HA,
settings={
"net_provider": 'neutron',
"net_segment_type": 'vlan',
}
)
self.show_step(2)
self.show_step(3)
self.fuel_web.update_nodes(
cluster_id, {
'slave-01': ['controller'],
'slave-02': ['compute'],
'slave-03': ['cinder']
}
)
self.show_step(4)
bond0_interfaces = self.get_bond_interfaces(self.BOND_CONFIG, 'bond0')
offloading_modes = self.prepare_offloading_modes(
bond0_interfaces, self.bond0_offloading_types, 'false')
bond1_interfaces = self.get_bond_interfaces(self.BOND_CONFIG, 'bond1')
offloading_modes += self.prepare_offloading_modes(
bond1_interfaces, self.bond1_offloading_types, 'true')
nodes = self.fuel_web.client.list_cluster_nodes(cluster_id)
self.show_step(5)
for node in nodes:
self.fuel_web.update_node_networks(
node['id'],
interfaces_dict=deepcopy(self.INTERFACES),
raw_data=deepcopy(self.BOND_CONFIG))
for offloading in offloading_modes:
self.fuel_web.update_offloads(
node['id'], deepcopy(offloading), offloading['name'])
self.show_step(6)
self.fuel_web.verify_network(cluster_id)
self.show_step(7)
self.fuel_web.deploy_cluster_wait(cluster_id)
self.show_step(8)
self.fuel_web.verify_network(cluster_id)
self.show_step(9)
for node in nodes:
for eth in bond0_interfaces:
for name in self.bond0_offloading_types:
with self.env.d_env.get_ssh_to_remote(node['ip']) as host:
result = check_offload(host, eth, name)
assert_equal(
result, 'off',
"Offload type '{0}': '{1}' - node-{2}, {3}".format(
name, result, node['id'], eth))
for eth in bond1_interfaces:
for name in self.bond1_offloading_types:
with self.env.d_env.get_ssh_to_remote(node['ip']) as host:
result = check_offload(host, eth, name)
assert_equal(
result, 'on',
"Offload type '{0}': '{1}' - node-{2}, {3}".format(
name, result, node['id'], eth))
self.show_step(10)
self.fuel_web.run_ostf(cluster_id=cluster_id)
self.env.make_snapshot("offloading_bond_neutron_vlan")
@test(depends_on=[SetupEnvironment.prepare_slaves_3],
groups=["offloading_bond_neutron_vxlan", "bonding"])
@log_snapshot_after_test
def offloading_bond_neutron_vxlan(self):
"""Verify setting offloading types for the logical bonded interfaces
and neutron VXLAN
Scenario:
1. Create cluster with neutron VXLAN
2. Add 1 node with controller role
3. Add 1 node with compute role and 1 node with cinder role
4. Configure offloading modes for bonded interfaces
5. Setup offloading types
6. Run network verification
7. Deploy the cluster
8. Run network verification
9. Verify offloading types for the bonded interfaces
10. Run OSTF
Duration 60m
Snapshot offloading_bond_neutron_vxlan
"""
self.env.revert_snapshot("ready_with_3_slaves")
self.show_step(1)
cluster_id = self.fuel_web.create_cluster(
name=self.__class__.__name__,
mode=DEPLOYMENT_MODE_HA,
settings={
"net_provider": 'neutron',
"net_segment_type": 'vlan',
}
)
self.show_step(2)
self.show_step(3)
self.fuel_web.update_nodes(
cluster_id, {
'slave-01': ['controller'],
'slave-02': ['compute'],
'slave-03': ['cinder']
}
)
self.show_step(4)
bond0_interfaces = self.get_bond_interfaces(self.BOND_CONFIG, 'bond0')
offloading_modes = self.prepare_offloading_modes(
bond0_interfaces, self.bond0_offloading_types, 'false')
bond1_interfaces = self.get_bond_interfaces(self.BOND_CONFIG, 'bond1')
offloading_modes += self.prepare_offloading_modes(
bond1_interfaces, self.bond1_offloading_types, 'true')
nodes = self.fuel_web.client.list_cluster_nodes(cluster_id)
self.show_step(5)
for node in nodes:
self.fuel_web.update_node_networks(
node['id'],
interfaces_dict=deepcopy(self.INTERFACES),
raw_data=deepcopy(self.BOND_CONFIG))
for offloading in offloading_modes:
self.fuel_web.update_offloads(
node['id'], deepcopy(offloading), offloading['name'])
self.show_step(6)
self.fuel_web.verify_network(cluster_id)
self.show_step(7)
self.fuel_web.deploy_cluster_wait(cluster_id)
self.show_step(8)
self.fuel_web.verify_network(cluster_id)
self.show_step(9)
for node in nodes:
for eth in bond0_interfaces:
for name in self.bond0_offloading_types:
with self.env.d_env.get_ssh_to_remote(node['ip']) as host:
result = check_offload(host, eth, name)
assert_equal(
result, 'off',
"Offload type '{0}': '{1}' - node-{2}, {3}".format(
name, result, node['id'], eth))
for eth in bond1_interfaces:
for name in self.bond1_offloading_types:
with self.env.d_env.get_ssh_to_remote(node['ip']) as host:
result = check_offload(host, eth, name)
assert_equal(
result, 'on',
"Offload type '{0}': '{1}' - node-{2}, {3}".format(
name, result, node['id'], eth))
self.show_step(10)
self.fuel_web.run_ostf(cluster_id=cluster_id)
self.env.make_snapshot("offloading_bond_neutron_vxlan")

View File

@ -61,6 +61,16 @@ class BondingTest(TestBasic):
}
super(BondingTest, self).__init__()
@staticmethod
def get_bond_interfaces(bond_config, bond_name):
bond_slaves = []
for bond in [bond for bond in bond_config]:
if bond['name'] == bond_name:
for slave in bond['slaves']:
bond_slaves.append(slave['name'])
bond_slaves.append(bond_name)
return bond_slaves
def check_interfaces_config_after_reboot(self, cluster_id):
network_settings = dict()
skip_interfaces = {

View File

@ -11,9 +11,13 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from copy import deepcopy
from proboscis.asserts import assert_equal
from proboscis import test
from fuelweb_test.helpers.checkers import check_offload
from fuelweb_test.helpers.decorators import log_snapshot_after_test
from fuelweb_test import logger
from fuelweb_test.settings import DEPLOYMENT_MODE
@ -24,44 +28,11 @@ from fuelweb_test.tests.base_test_case import TestBasic
@test(groups=["offloading"])
class TestOffloading(TestBasic):
def update_offloads(self, node_id, update_values, interface_to_update):
interfaces = self.fuel_web.client.get_node_interfaces(node_id)
modes = None
updated_offloads = None
for i in interfaces:
if i['name'] == interface_to_update:
modes = i['offloading_modes']
for k in update_values:
if k['name'] == interface_to_update:
updated_offloads = k['offloading_modes']
for types_old in modes:
for types_new in updated_offloads:
if types_old['name'] == types_new['name']:
types_old.update(types_new)
for interface in interfaces:
interface.update(modes[0])
self.fuel_web.client.put_node_interfaces(
[{'id': node_id, 'interfaces': interfaces}])
def check_offload(self, node, eth, offload_type):
command = "ethtool --show-offload %s | awk '/%s/ {print $2}'"
offload_status = node.execute(command % (eth, offload_type))
assert_equal(offload_status['exit_code'], 0,
"Failed to get Offload {0} "
"on node {1}".format(offload_type, node))
return ''.join(node.execute(command % (eth,
offload_type))['stdout']).rstrip()
@test(depends_on=[SetupEnvironment.prepare_slaves_3],
groups=["offloading_neutron_vlan", "offloading"])
@log_snapshot_after_test
def offloading_neutron_vlan(self):
"""Deploy cluster with new offload modes and neutron VLAN
"""Deploy cluster with specific offload modes and neutron VLAN
Scenario:
1. Create cluster with neutron VLAN
@ -71,8 +42,8 @@ class TestOffloading(TestBasic):
5. Run network verification
6. Deploy the cluster
7. Run network verification
8. Run OSTF
9. Verify offloading modes on nodes
8. Verify offloading modes on nodes
9. Run OSTF
Duration 30m
Snapshot offloading_neutron_vlan
@ -80,6 +51,7 @@ class TestOffloading(TestBasic):
"""
self.env.revert_snapshot("ready_with_3_slaves")
self.show_step(1)
cluster_id = self.fuel_web.create_cluster(
name=self.__class__.__name__,
mode=DEPLOYMENT_MODE,
@ -111,6 +83,8 @@ class TestOffloading(TestBasic):
'name': 'large-receive-offload',
'sub': []}]}]
self.show_step(2)
self.show_step(3)
self.fuel_web.update_nodes(
cluster_id, {
'slave-01': ['controller'],
@ -120,45 +94,52 @@ class TestOffloading(TestBasic):
)
slave_nodes = self.fuel_web.client.list_cluster_nodes(cluster_id)
self.show_step(4)
for node in slave_nodes:
self.fuel_web.update_node_networks(node['id'], interfaces)
for eth in offloading_modes:
self.update_offloads(node['id'], offloading_modes, eth['name'])
self.fuel_web.update_node_networks(node['id'],
deepcopy(interfaces))
for offloading in offloading_modes:
self.fuel_web.update_offloads(
node['id'], deepcopy(offloading), offloading['name'])
self.show_step(5)
self.fuel_web.verify_network(cluster_id)
self.show_step(6)
self.fuel_web.deploy_cluster_wait(cluster_id)
self.show_step(7)
self.fuel_web.verify_network(cluster_id)
self.fuel_web.run_ostf(cluster_id=cluster_id)
self.show_step(8)
nodes = [self.fuel_web.get_nailgun_node_by_name(node)
for node in ['slave-01', 'slave-02', 'slave-03']]
for node in nodes:
with self.env.d_env.get_ssh_to_remote(node['ip']) as remote:
logger.info("Verify Offload types")
result = self.check_offload(remote, 'eth1', 'rx-vlan-offload')
result = check_offload(remote, 'eth1', 'rx-vlan-offload')
assert_equal(result, "on",
"Offload type {0} is {1} on remote host"
.format('rx-vlan-offload', result))
result = self.check_offload(remote, 'eth1', 'tx-vlan-offload')
result = check_offload(remote, 'eth1', 'tx-vlan-offload')
assert_equal(result, "on",
"Offload type {0} is {1} on remote host"
.format('tx-vlan-offload', result))
result = self.check_offload(remote, 'eth2',
'large-receive-offload')
result = check_offload(remote, 'eth2', 'large-receive-offload')
assert_equal(result, "off",
"Offload type {0} is {1} on remote host"
.format('large-receive-offload', result))
self.show_step(9)
self.fuel_web.run_ostf(cluster_id=cluster_id)
self.env.make_snapshot("offloading_neutron_vlan")
@test(depends_on=[SetupEnvironment.prepare_slaves_3],
groups=["offloading_neutron_vxlan", "offloading"])
@log_snapshot_after_test
def offloading_neutron_vxlan(self):
"""Deploy cluster with new offload modes and neutron VXLAN
"""Deploy cluster with specific offload modes and neutron VXLAN
Scenario:
1. Create cluster with neutron VXLAN
@ -177,12 +158,13 @@ class TestOffloading(TestBasic):
"""
self.env.revert_snapshot("ready_with_3_slaves")
self.show_step(1)
cluster_id = self.fuel_web.create_cluster(
name=self.__class__.__name__,
mode=DEPLOYMENT_MODE,
settings={
"net_provider": 'neutron',
"net_segment_type": 'gre',
"net_segment_type": 'tun',
}
)
@ -208,6 +190,8 @@ class TestOffloading(TestBasic):
'name': 'large-receive-offload',
'sub': []}]}]
self.show_step(2)
self.show_step(3)
self.fuel_web.update_nodes(
cluster_id, {
'slave-01': ['controller'],
@ -217,36 +201,43 @@ class TestOffloading(TestBasic):
)
slave_nodes = self.fuel_web.client.list_cluster_nodes(cluster_id)
self.show_step(4)
for node in slave_nodes:
self.fuel_web.update_node_networks(node['id'], interfaces)
for eth in offloading_modes:
self.update_offloads(node['id'], offloading_modes, eth['name'])
self.fuel_web.update_node_networks(node['id'],
deepcopy(interfaces))
for offloading in offloading_modes:
self.fuel_web.update_offloads(
node['id'], deepcopy(offloading), offloading['name'])
self.show_step(5)
self.fuel_web.verify_network(cluster_id)
self.show_step(6)
self.fuel_web.deploy_cluster_wait(cluster_id)
self.show_step(7)
self.fuel_web.verify_network(cluster_id)
self.fuel_web.run_ostf(cluster_id=cluster_id)
self.show_step(8)
nodes = [self.fuel_web.get_nailgun_node_by_name(node)
for node in ['slave-01', 'slave-02', 'slave-03']]
for node in nodes:
with self.env.d_env.get_ssh_to_remote(node['ip']) as remote:
logger.info("Verify Offload types")
result = self.check_offload(remote, 'eth1', 'rx-vlan-offload')
result = check_offload(remote, 'eth1', 'rx-vlan-offload')
assert_equal(result, "on",
"Offload type {0} is {1} on remote host"
.format('rx-vlan-offload', result))
result = self.check_offload(remote, 'eth1', 'tx-vlan-offload')
result = check_offload(remote, 'eth1', 'tx-vlan-offload')
assert_equal(result, "on",
"Offload type {0} is {1} on remote host"
.format('tx-vlan-offload', result))
result = self.check_offload(remote, 'eth2',
'large-receive-offload')
result = check_offload(remote, 'eth2', 'large-receive-offload')
assert_equal(result, "off",
"Offload type {0} is {1} on remote host"
.format('large-receive-offload', result))
self.show_step(9)
self.fuel_web.run_ostf(cluster_id=cluster_id)
self.env.make_snapshot("offloading_neutron_vxlan")