Merge "Check connectivity from instance with DPDK via floating IP"
This commit is contained in:
commit
b2e35120ef
@ -733,6 +733,7 @@ class NailgunConfig(object):
|
|||||||
for node in compute_nodes:
|
for node in compute_nodes:
|
||||||
compute_ips.append(node['ip'])
|
compute_ips.append(node['ip'])
|
||||||
LOG.info("COMPUTES IPS %s" % compute_ips)
|
LOG.info("COMPUTES IPS %s" % compute_ips)
|
||||||
|
|
||||||
sriov_physnets = []
|
sriov_physnets = []
|
||||||
compute_ids = [node['id'] for node in online_computes]
|
compute_ids = [node['id'] for node in online_computes]
|
||||||
for compute_id in compute_ids:
|
for compute_id in compute_ids:
|
||||||
@ -745,6 +746,19 @@ class NailgunConfig(object):
|
|||||||
sriov_physnets.append(
|
sriov_physnets.append(
|
||||||
iface['interface_properties']['sriov']['physnet'])
|
iface['interface_properties']['sriov']['physnet'])
|
||||||
self.compute.sriov_physnets = sriov_physnets
|
self.compute.sriov_physnets = sriov_physnets
|
||||||
|
|
||||||
|
# Find first compute with enabled DPDK
|
||||||
|
for compute in online_computes:
|
||||||
|
api_url = '/api/nodes/{}/interfaces'.format(compute['id'])
|
||||||
|
ifaces_resp = self.req_session.get(
|
||||||
|
self.nailgun_url + api_url).json()
|
||||||
|
for iface in ifaces_resp:
|
||||||
|
if 'dpdk' in iface['interface_properties']:
|
||||||
|
if 'enabled' in iface['interface_properties']['dpdk']:
|
||||||
|
if iface['interface_properties']['dpdk']['enabled']:
|
||||||
|
self.compute.dpdk_compute_fqdn = compute['fqdn']
|
||||||
|
break
|
||||||
|
|
||||||
self.compute.compute_nodes = compute_ips
|
self.compute.compute_nodes = compute_ips
|
||||||
ceph_nodes = filter(lambda node: 'ceph-osd' in node['roles'],
|
ceph_nodes = filter(lambda node: 'ceph-osd' in node['roles'],
|
||||||
data)
|
data)
|
||||||
|
@ -1271,7 +1271,7 @@ class SmokeChecksTest(OfficialClientTest):
|
|||||||
super(SmokeChecksTest, self).setUp()
|
super(SmokeChecksTest, self).setUp()
|
||||||
self.check_clients_state()
|
self.check_clients_state()
|
||||||
|
|
||||||
def _create_flavors(self, client, ram, disk, vcpus=1):
|
def _create_flavors(self, client, ram, disk, vcpus=1, use_huge_page=False):
|
||||||
name = rand_name('ost1_test-flavor-')
|
name = rand_name('ost1_test-flavor-')
|
||||||
flavorid = rand_int_id()
|
flavorid = rand_int_id()
|
||||||
exist_ids = [flavor.id for flavor
|
exist_ids = [flavor.id for flavor
|
||||||
@ -1282,6 +1282,14 @@ class SmokeChecksTest(OfficialClientTest):
|
|||||||
flavor = client.flavors.create(name=name, ram=ram, disk=disk,
|
flavor = client.flavors.create(name=name, ram=ram, disk=disk,
|
||||||
vcpus=vcpus, flavorid=flavorid)
|
vcpus=vcpus, flavorid=flavorid)
|
||||||
self.created_flavors.append(flavor)
|
self.created_flavors.append(flavor)
|
||||||
|
|
||||||
|
if use_huge_page:
|
||||||
|
# change flavor settings use hugepage
|
||||||
|
flavor_metadata = flavor.get_keys()
|
||||||
|
logging.debug(flavor_metadata)
|
||||||
|
flavor_metadata['hw:mem_page_size'] = '2048'
|
||||||
|
flavor.set_keys(flavor_metadata)
|
||||||
|
|
||||||
return flavor
|
return flavor
|
||||||
|
|
||||||
def _delete_flavors(self, client, flavor):
|
def _delete_flavors(self, client, flavor):
|
||||||
|
155
fuel_health/tests/smoke/test_dpdk.py
Normal file
155
fuel_health/tests/smoke/test_dpdk.py
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
# Copyright 2016 Mirantis, Inc.
|
||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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 logging
|
||||||
|
|
||||||
|
from fuel_health.common.utils.data_utils import rand_name
|
||||||
|
from fuel_health import neutronmanager
|
||||||
|
from fuel_health import nmanager
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class TestDPDK(neutronmanager.NeutronBaseTest, nmanager.SmokeChecksTest):
|
||||||
|
"""Test suite verifies:
|
||||||
|
- blah-blah
|
||||||
|
"""
|
||||||
|
|
||||||
|
def test_check_dpdk_instance_connectivity(self):
|
||||||
|
"""Check network connectivity from instance with DPDK via floating IP
|
||||||
|
Target component: Neutron
|
||||||
|
|
||||||
|
Scenario:
|
||||||
|
1. Create a new security group (if it doesn`t exist yet).
|
||||||
|
2. Create router
|
||||||
|
3. Create network
|
||||||
|
4. Create subnet
|
||||||
|
5. Uplink subnet to router.
|
||||||
|
6. Create new flavor with huge pages
|
||||||
|
7. Create an instance using the new flavor, security group
|
||||||
|
in created subnet. Boot it on compute with enabled DPDK.
|
||||||
|
8. Create a new floating IP
|
||||||
|
9. Assign the new floating IP to the instance.
|
||||||
|
10. Check connectivity to the floating IP using ping command.
|
||||||
|
11. Check that public IP 8.8.8.8 can be pinged from instance.
|
||||||
|
12. Disassociate server floating ip.
|
||||||
|
13. Delete floating ip
|
||||||
|
14. Delete server.
|
||||||
|
15. Delete flavor
|
||||||
|
16. Remove router.
|
||||||
|
17. Remove subnet
|
||||||
|
18. Remove network
|
||||||
|
Duration: 300 s.
|
||||||
|
|
||||||
|
Deployment tags: dpdk
|
||||||
|
"""
|
||||||
|
if not self.config.compute.dpdk_compute_fqdn:
|
||||||
|
self.skipTest('There are no compute nodes with DPDK')
|
||||||
|
|
||||||
|
self.check_image_exists()
|
||||||
|
if not self.security_groups:
|
||||||
|
self.security_groups[self.tenant_id] = self.verify(
|
||||||
|
25, self._create_security_group, 1,
|
||||||
|
"Security group can not be created.",
|
||||||
|
'security group creation',
|
||||||
|
self.compute_client)
|
||||||
|
|
||||||
|
name = rand_name('ost1_test-server-dpdk-')
|
||||||
|
security_groups = [self.security_groups[self.tenant_id].name]
|
||||||
|
|
||||||
|
router = self.verify(30, self.create_router, 2,
|
||||||
|
'Router can not be created', 'Router creation',
|
||||||
|
name)
|
||||||
|
|
||||||
|
network = self.verify(20, self.create_network, 3,
|
||||||
|
'Network can not be created',
|
||||||
|
'Network creation', name)
|
||||||
|
|
||||||
|
subnet = self.verify(20, self.create_subnet, 4,
|
||||||
|
'Subnet can not be created',
|
||||||
|
'Subnet creation', network)
|
||||||
|
|
||||||
|
self.verify(20, self.uplink_subnet_to_router, 5,
|
||||||
|
'Can not uplink subnet to router',
|
||||||
|
'Uplink subnet to router', router, subnet)
|
||||||
|
|
||||||
|
fail_msg = "Flavor was not created properly."
|
||||||
|
flavor = self.verify(30, self._create_flavors, 6,
|
||||||
|
fail_msg,
|
||||||
|
"flavor creation",
|
||||||
|
self.compute_client, 256, 1, use_huge_page=True)
|
||||||
|
|
||||||
|
server = self.verify(200, self._create_server, 7,
|
||||||
|
"Server can not be created.",
|
||||||
|
"server creation",
|
||||||
|
self.compute_client, name, security_groups,
|
||||||
|
net_id=network['id'], flavor_id=flavor,
|
||||||
|
az_name='nova:{}'.format(
|
||||||
|
self.config.compute.dpdk_compute_fqdn))
|
||||||
|
|
||||||
|
floating_ip = self.verify(
|
||||||
|
20,
|
||||||
|
self._create_floating_ip,
|
||||||
|
8,
|
||||||
|
"Floating IP can not be created.",
|
||||||
|
'floating IP creation')
|
||||||
|
|
||||||
|
self.verify(20, self._assign_floating_ip_to_instance,
|
||||||
|
9, "Floating IP can not be assigned.",
|
||||||
|
'floating IP assignment',
|
||||||
|
self.compute_client, server, floating_ip)
|
||||||
|
|
||||||
|
self.floating_ips.append(floating_ip)
|
||||||
|
|
||||||
|
ip_address = floating_ip.ip
|
||||||
|
LOG.info('is address is {0}'.format(ip_address))
|
||||||
|
LOG.debug(ip_address)
|
||||||
|
|
||||||
|
self.verify(600, self._check_vm_connectivity, 10,
|
||||||
|
"VM connectivity doesn`t function properly.",
|
||||||
|
'VM connectivity checking', ip_address,
|
||||||
|
30, (9, 60))
|
||||||
|
|
||||||
|
self.verify(600, self._check_connectivity_from_vm,
|
||||||
|
11, ("Connectivity to 8.8.8.8 from the VM doesn`t "
|
||||||
|
"function properly."),
|
||||||
|
'public connectivity checking from VM', ip_address,
|
||||||
|
30, (9, 60))
|
||||||
|
|
||||||
|
self.verify(20, self.compute_client.servers.remove_floating_ip,
|
||||||
|
12, "Floating IP cannot be removed.",
|
||||||
|
"removing floating IP", server, floating_ip)
|
||||||
|
|
||||||
|
self.verify(20, self.compute_client.floating_ips.delete,
|
||||||
|
13, "Floating IP cannot be deleted.",
|
||||||
|
"floating IP deletion", floating_ip)
|
||||||
|
|
||||||
|
if self.floating_ips:
|
||||||
|
self.floating_ips.remove(floating_ip)
|
||||||
|
|
||||||
|
self.verify(40, self._delete_server, 14,
|
||||||
|
"Server can not be deleted. ",
|
||||||
|
"server deletion", server)
|
||||||
|
|
||||||
|
self.verify(30, self._delete_flavors, 15,
|
||||||
|
"Flavor failed to be deleted.",
|
||||||
|
"flavor deletion", self.compute_client, flavor)
|
||||||
|
|
||||||
|
self.verify(40, self._remove_router, 16, "Router can not be deleted",
|
||||||
|
"router deletion", router, [subnet['id']])
|
||||||
|
self.verify(20, self._remove_subnet, 17, "Subnet can not be deleted",
|
||||||
|
"Subnet deletion", subnet)
|
||||||
|
self.verify(20, self._remove_network, 18,
|
||||||
|
"Network can not be deleted", "Network deletion", network)
|
@ -161,6 +161,7 @@ def _get_cluster_attrs(cluster_id, token=None):
|
|||||||
nodes_response)
|
nodes_response)
|
||||||
|
|
||||||
sriov_compute_ids = []
|
sriov_compute_ids = []
|
||||||
|
dpdk_compute_ids = [] # Check env has computes with DPDK
|
||||||
compute_ids = [node['id'] for node in nodes_response
|
compute_ids = [node['id'] for node in nodes_response
|
||||||
if "compute" in node['roles']]
|
if "compute" in node['roles']]
|
||||||
for compute_id in compute_ids:
|
for compute_id in compute_ids:
|
||||||
@ -172,10 +173,19 @@ def _get_cluster_attrs(cluster_id, token=None):
|
|||||||
if ('sriov' in iface['interface_properties'] and
|
if ('sriov' in iface['interface_properties'] and
|
||||||
iface['interface_properties']['sriov']['enabled']):
|
iface['interface_properties']['sriov']['enabled']):
|
||||||
sriov_compute_ids.append(compute_id)
|
sriov_compute_ids.append(compute_id)
|
||||||
|
if 'dpdk' in iface['interface_properties']:
|
||||||
|
if 'enabled' in iface['interface_properties']['dpdk']:
|
||||||
|
if iface['interface_properties']['dpdk']['enabled']:
|
||||||
|
dpdk_compute_ids.append(compute_id)
|
||||||
|
|
||||||
deployment_tags = set()
|
deployment_tags = set()
|
||||||
|
|
||||||
if sriov_compute_ids:
|
if sriov_compute_ids:
|
||||||
deployment_tags.add('sriov')
|
deployment_tags.add('sriov')
|
||||||
|
|
||||||
|
if dpdk_compute_ids:
|
||||||
|
deployment_tags.add('dpdk')
|
||||||
|
|
||||||
if not enable_without_ceph:
|
if not enable_without_ceph:
|
||||||
deployment_tags.add('enable_without_ceph')
|
deployment_tags.add('enable_without_ceph')
|
||||||
|
|
||||||
|
@ -188,6 +188,40 @@ CLUSTERS = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
8: {
|
||||||
|
'cluster_meta': {
|
||||||
|
'release_id': 8,
|
||||||
|
'mode': 'ha',
|
||||||
|
'net_provider': 'neutron'
|
||||||
|
},
|
||||||
|
'release_data': {
|
||||||
|
'operating_system': 'rhel',
|
||||||
|
'version': '2015.2-1.0',
|
||||||
|
},
|
||||||
|
'cluster_node': [
|
||||||
|
{
|
||||||
|
"hostname": "node-1",
|
||||||
|
'id': "1",
|
||||||
|
'roles': "compute"
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'node_interfaces': [
|
||||||
|
{
|
||||||
|
'interface_properties': {
|
||||||
|
'dpdk': {
|
||||||
|
'enabled': 'true'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'cluster_attributes': {
|
||||||
|
'editable': {
|
||||||
|
'additional_components': {},
|
||||||
|
'common': {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -77,3 +77,30 @@ class TestDeplTagsGetter(base.BaseUnitTest):
|
|||||||
res = mixins._get_cluster_attrs(expected['cluster_id'])
|
res = mixins._get_cluster_attrs(expected['cluster_id'])
|
||||||
|
|
||||||
self.assertEqual(res, expected['attrs'])
|
self.assertEqual(res, expected['attrs'])
|
||||||
|
|
||||||
|
def test_dpdk_deployment_tag(self):
|
||||||
|
expected = {
|
||||||
|
'cluster_id': 8,
|
||||||
|
'attrs': {
|
||||||
|
'deployment_tags': set(
|
||||||
|
['dpdk', 'neutron', 'enable_without_ceph', 'ha',
|
||||||
|
'public_on_all_nodes', 'rhel']),
|
||||||
|
'release_version': '2015.2-1.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
with requests_mock.Mocker() as m:
|
||||||
|
cluster = base.CLUSTERS[expected['cluster_id']]
|
||||||
|
m.register_uri('GET', '/api/clusters/8',
|
||||||
|
json=cluster['cluster_meta'])
|
||||||
|
m.register_uri('GET', '/api/clusters/8/attributes',
|
||||||
|
json=cluster['cluster_attributes'])
|
||||||
|
m.register_uri('GET', '/api/releases/8',
|
||||||
|
json=cluster['release_data'])
|
||||||
|
m.register_uri('GET', '/api/nodes?cluster_id=8',
|
||||||
|
json=cluster['cluster_node'])
|
||||||
|
m.register_uri('GET', '/api/nodes/1/interfaces',
|
||||||
|
json=cluster['node_interfaces'])
|
||||||
|
res = mixins._get_cluster_attrs(expected['cluster_id'])
|
||||||
|
|
||||||
|
self.assertEqual(res, expected['attrs'])
|
||||||
|
Loading…
Reference in New Issue
Block a user