Add tests for HugePages feature
This testgroup should be run with this parameters: export KVM_USE=True export DRIVER_ENABLE_ACPI=true export NUMA_NODES=2 export SLAVE_NODE_CPU=4 export SLAVE_NODE_MEMORY=5120 Implements: blueprint support-hugepages-tests Change-Id: I3c7f86096743b027a296716c8fa2fecfd321c967
This commit is contained in:
parent
a7e4bd5fca
commit
40db117cd4
@ -12,18 +12,75 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from devops.settings import DRIVER_PARAMETERS
|
||||
from proboscis import asserts
|
||||
from proboscis import test
|
||||
|
||||
from fuelweb_test.helpers.decorators import log_snapshot_after_test
|
||||
from fuelweb_test import settings
|
||||
from fuelweb_test import logger
|
||||
from fuelweb_test.helpers import utils
|
||||
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 gates_tests.helpers import exceptions
|
||||
|
||||
|
||||
@test(groups=["support_hugepages"])
|
||||
class SupportHugepages(TestBasic):
|
||||
"""SupportHugepages."""
|
||||
"""SupportHugepages.
|
||||
|
||||
Required environment variables:
|
||||
* KVM_USE=true
|
||||
* DRIVER_ENABLE_ACPI=true
|
||||
* NUMA_NODES=2
|
||||
* SLAVE_NODE_CPU=4
|
||||
* SLAVE_NODE_MEMORY=5120
|
||||
"""
|
||||
def __init__(self):
|
||||
self.os_conn = None
|
||||
super(SupportHugepages, self).__init__()
|
||||
|
||||
def boot_instance_with_hugepage(self, target_compute_name,
|
||||
flavor_name, flavor_ram, page_size):
|
||||
|
||||
cluster_id = self.fuel_web.get_last_created_cluster()
|
||||
|
||||
logger.info("Creating flavor {}, RAM: {}, PageSize: {}"
|
||||
.format(flavor_name, flavor_ram, page_size))
|
||||
flavor = self.os_conn.nova.flavors.create(
|
||||
name=flavor_name,
|
||||
ram=flavor_ram,
|
||||
vcpus=1,
|
||||
disk=1
|
||||
)
|
||||
flavor.set_keys(metadata={"hw:mem_page_size": page_size})
|
||||
|
||||
target_compute = \
|
||||
self.fuel_web.get_nailgun_node_by_name(target_compute_name)
|
||||
net_name = self.fuel_web.get_cluster_predefined_networks_name(
|
||||
cluster_id)['private_net']
|
||||
|
||||
logger.info("Booting instance on compute {}"
|
||||
.format(target_compute["fqdn"]))
|
||||
server = self.os_conn.create_server_for_migration(
|
||||
neutron=True,
|
||||
label=net_name,
|
||||
availability_zone="nova:{0}".format(target_compute['fqdn']),
|
||||
flavor=flavor.id)
|
||||
|
||||
server = server.to_dict()
|
||||
asserts.assert_equal(
|
||||
server['OS-EXT-SRV-ATTR:host'], target_compute['fqdn'],
|
||||
"Server scheduled on a wrong host, server data: {}".format(server))
|
||||
|
||||
instance_name = server['OS-EXT-SRV-ATTR:instance_name']
|
||||
cmd = "virsh dumpxml {}".format(instance_name)
|
||||
result = "".join(
|
||||
self.ssh_manager.execute(target_compute['ip'], cmd)["stdout"])
|
||||
asserts.assert_true(
|
||||
"page size='{}'".format(page_size) in result,
|
||||
"Virsh xml contain different page size: {}".format(result))
|
||||
|
||||
@test(depends_on=[SetupEnvironment.prepare_slaves_5],
|
||||
groups=["basic_env_for_hugepages"])
|
||||
@ -33,11 +90,10 @@ class SupportHugepages(TestBasic):
|
||||
|
||||
Scenario:
|
||||
1. Create cluster
|
||||
2. Add 3 node with compute role
|
||||
3. Add 1 nodes with controller role
|
||||
4. Check what type of HugePages do support 2M and 1GB
|
||||
5. Verify the same HP size is present in CLI
|
||||
6. Download attributes for computes and check HP size
|
||||
2. Add 3 compute nodes and 1 controller node
|
||||
3. Check what type of HugePages do support 2M and 1GB
|
||||
4. Verify the same HP size is present in CLI
|
||||
5. Download attributes for computes and check HP size
|
||||
|
||||
Snapshot: basic_env_for_hugepages
|
||||
|
||||
@ -46,66 +102,363 @@ class SupportHugepages(TestBasic):
|
||||
self.check_run(snapshot_name)
|
||||
self.env.revert_snapshot("ready_with_5_slaves")
|
||||
|
||||
self.show_step(1, initialize=True)
|
||||
if not settings.KVM_USE:
|
||||
raise exceptions.FuelQAVariableNotSet(
|
||||
'KVM_USE', 'true')
|
||||
|
||||
if not DRIVER_PARAMETERS['enable_acpi']:
|
||||
raise exceptions.FuelQAVariableNotSet(
|
||||
'DRIVER_ENABLE_ACPI', 'true')
|
||||
|
||||
if not settings.HARDWARE['numa_nodes'] == "2":
|
||||
raise exceptions.FuelQAVariableNotSet(
|
||||
'NUMA_NODES', 2)
|
||||
|
||||
if not settings.HARDWARE['slave_node_cpu'] == "4":
|
||||
raise exceptions.FuelQAVariableNotSet(
|
||||
'SLAVE_NODE_CPU', 4)
|
||||
|
||||
if not settings.HARDWARE['slave_node_memory'] == 5120:
|
||||
raise exceptions.FuelQAVariableNotSet(
|
||||
'SLAVE_NODE_MEMORY', 5120)
|
||||
|
||||
if not settings.INTERFACES_DICT['eth0'] == 'ens3':
|
||||
raise exceptions.FuelQAVariableNotSet(
|
||||
'IFACE_0', 'ens3')
|
||||
|
||||
if not settings.INTERFACES_DICT['eth1'] == 'ens4':
|
||||
raise exceptions.FuelQAVariableNotSet(
|
||||
'IFACE_1', 'ens4')
|
||||
|
||||
if not settings.INTERFACES_DICT['eth2'] == 'ens5':
|
||||
raise exceptions.FuelQAVariableNotSet(
|
||||
'IFACE_2', 'ens5')
|
||||
|
||||
if not settings.INTERFACES_DICT['eth3'] == 'ens6':
|
||||
raise exceptions.FuelQAVariableNotSet(
|
||||
'IFACE_3', 'ens6')
|
||||
|
||||
if not settings.INTERFACES_DICT['eth4'] == 'ens7':
|
||||
raise exceptions.FuelQAVariableNotSet(
|
||||
'IFACE_4', 'ens7')
|
||||
|
||||
if not settings.INTERFACES_DICT['eth5'] == 'ens8':
|
||||
raise exceptions.FuelQAVariableNotSet(
|
||||
'IFACE_5', 'ens8')
|
||||
|
||||
self.show_step(1)
|
||||
cluster_id = self.fuel_web.create_cluster(
|
||||
name=self.__class__.__name__,
|
||||
mode=settings.DEPLOYMENT_MODE,
|
||||
settings={
|
||||
"net_provider": 'neutron',
|
||||
"net_segment_type": settings.NEUTRON_SEGMENT_TYPE,
|
||||
"KVM_USE": True
|
||||
"net_segment_type": settings.NEUTRON_SEGMENT_TYPE
|
||||
}
|
||||
)
|
||||
self.show_step(2)
|
||||
self.show_step(3)
|
||||
|
||||
self.show_step(2)
|
||||
self.fuel_web.update_nodes(
|
||||
cluster_id,
|
||||
{
|
||||
'slave-01': ['compute'],
|
||||
'slave-02': ['compute'],
|
||||
'slave-03': ['compute'],
|
||||
'slave-04': ['controller']
|
||||
'slave-04': ['compute', 'cinder'],
|
||||
'slave-05': ['controller']
|
||||
})
|
||||
|
||||
self.show_step(4)
|
||||
log_path = '/proc/cpuinfo'
|
||||
self.show_step(3)
|
||||
computes = self.fuel_web.get_nailgun_cluster_nodes_by_roles(
|
||||
cluster_id, ['compute'])
|
||||
for compt in computes:
|
||||
cluster_id, ['compute'], role_status="pending_roles")
|
||||
for compute in computes:
|
||||
self.ssh_manager.execute_on_remote(
|
||||
ip=compt['ip'],
|
||||
cmd="grep \"pse\" {0}".format(log_path),
|
||||
err_msg="HugePages don't support 2M on {}".format(compt))
|
||||
ip=compute['ip'],
|
||||
cmd="grep \"pse\" /proc/cpuinfo",
|
||||
err_msg="{} compute doesn't support 2Mb HugePages"
|
||||
.format(compute['fqdn']))
|
||||
|
||||
self.ssh_manager.execute_on_remote(
|
||||
ip=compt['ip'],
|
||||
cmd="grep \"pdpe1gb\" {0}".format(log_path),
|
||||
err_msg="HugePages don't support 1GB on {}".format(compt))
|
||||
ip=compute['ip'],
|
||||
cmd="grep \"pdpe1gb\" /proc/cpuinfo",
|
||||
err_msg="{} compute doesn't support 1GB HugePages"
|
||||
.format(compute['fqdn']))
|
||||
|
||||
self.show_step(4)
|
||||
for compute in computes:
|
||||
self.ssh_manager.execute_on_remote(
|
||||
ip=self.ssh_manager.admin_ip,
|
||||
cmd="fuel2 node show {0} | grep hugepages | "
|
||||
"grep 2048".format(compute['id']),
|
||||
err_msg="2Mb HugePages doesn't present in CLI for node "
|
||||
"{0}".format(compute['fqdn']))
|
||||
self.ssh_manager.execute_on_remote(
|
||||
ip=self.ssh_manager.admin_ip,
|
||||
cmd="fuel2 node show {0} | grep hugepages | "
|
||||
"grep 1048576".format(compute['id']),
|
||||
err_msg="1Gb HugePages doesn't present in CLI for node "
|
||||
"{0}".format(compute['fqdn']))
|
||||
|
||||
self.show_step(5)
|
||||
for compt in computes:
|
||||
self.ssh_manager.execute_on_remote(
|
||||
ip=self.ssh_manager.admin_ip,
|
||||
cmd="fuel2 node show {0} | grep hugepages | "
|
||||
"grep 2048".format(compt['id']),
|
||||
err_msg="2M of HugePages isn't present in CLI for "
|
||||
"{0}".format(compt))
|
||||
self.ssh_manager.execute_on_remote(
|
||||
ip=self.ssh_manager.admin_ip,
|
||||
cmd="fuel2 node show {0} | grep hugepages | "
|
||||
"grep 1048576".format(compt['id']),
|
||||
err_msg="2M of HugePages isn't present in CLI for "
|
||||
"{0}".format(compt))
|
||||
|
||||
self.show_step(6)
|
||||
for compt in computes:
|
||||
config = self.fuel_web.client.get_node_attributes(compt['id'])
|
||||
for compute in computes:
|
||||
config = self.fuel_web.client.get_node_attributes(compute['id'])
|
||||
asserts.assert_true(
|
||||
config['hugepages']['nova']['value']['2048'] == 0,
|
||||
"HugePages don't support 2M")
|
||||
"Number of 2Mb HugePages for node {} is not "
|
||||
"0".format(compute['fqdn']))
|
||||
asserts.assert_true(
|
||||
config['hugepages']['nova']['value']['1048576'] == 0,
|
||||
"HugePages don't support 1GB")
|
||||
"Number of 1Gb HugePages for node {} is not "
|
||||
"0".format(compute['fqdn']))
|
||||
|
||||
self.env.make_snapshot("basic_env_for_hugepages", is_make=True)
|
||||
self.env.make_snapshot(snapshot_name, is_make=True)
|
||||
|
||||
@test(depends_on=[basic_env_for_hugepages],
|
||||
groups=["check_hugepages_distribution_per_numa"])
|
||||
@log_snapshot_after_test
|
||||
def check_hugepages_distribution_per_numa(self):
|
||||
"""Deploy environment with different HugePages allocation
|
||||
|
||||
Scenario:
|
||||
1. Revert basic_env_for_hugepages snapshot
|
||||
2. Configure hugepages for three computes
|
||||
3. Deploy cluster
|
||||
4. Validate available huge pages on computes
|
||||
|
||||
Snapshot: check_hugepages_distribution_per_numa
|
||||
"""
|
||||
snapshot_name = "check_hugepages_distribution_per_numa"
|
||||
self.check_run(snapshot_name)
|
||||
|
||||
self.show_step(1)
|
||||
self.env.revert_snapshot("basic_env_for_hugepages")
|
||||
|
||||
self.show_step(2)
|
||||
cluster_id = self.fuel_web.get_last_created_cluster()
|
||||
mixed_host = "slave-01"
|
||||
one_gb_host = "slave-02"
|
||||
two_mb_host = "slave-03"
|
||||
mixed_role_host = "slave-04"
|
||||
|
||||
configs = {
|
||||
mixed_host: {"cpu_pinning": {"nova": {"value": 2}},
|
||||
"hugepages": {"nova": {"value": {"2048": 258,
|
||||
"1048576": 1}}
|
||||
}
|
||||
},
|
||||
one_gb_host: {"cpu_pinning": {"nova": {"value": 2}},
|
||||
"hugepages": {"nova": {"value": {"2048": 0,
|
||||
"1048576": 2}}
|
||||
}
|
||||
},
|
||||
two_mb_host: {"cpu_pinning": {"nova": {"value": 2}},
|
||||
"hugepages": {"nova": {"value": {"2048": 540,
|
||||
"1048576": 0}}
|
||||
}
|
||||
},
|
||||
mixed_role_host: {"cpu_pinning": {"nova": {"value": 2}},
|
||||
"hugepages": {"nova": {"value": {"2048": 258,
|
||||
"1048576": 1}}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
for compute_name, config in configs.items():
|
||||
compute_id = \
|
||||
self.fuel_web.get_nailgun_node_by_name(compute_name)['id']
|
||||
original_config = \
|
||||
self.fuel_web.client.get_node_attributes(compute_id)
|
||||
self.fuel_web.client.upload_node_attributes(
|
||||
utils.dict_merge(original_config, config), compute_id)
|
||||
|
||||
self.show_step(3)
|
||||
self.fuel_web.deploy_cluster_wait(cluster_id)
|
||||
|
||||
self.show_step(4)
|
||||
for compute_name, config in configs.items():
|
||||
two_mb_count = config["hugepages"]["nova"]["value"]["2048"]
|
||||
one_gb_count = config["hugepages"]["nova"]["value"]["1048576"]
|
||||
|
||||
compute = self.fuel_web.get_nailgun_node_by_name(compute_name)
|
||||
cmd = ("cat /sys/devices/system/node/node{}/hugepages/"
|
||||
"hugepages-{}kB/nr_hugepages")
|
||||
|
||||
actual_two_mb_count = 0
|
||||
actual_one_gb_count = 0
|
||||
|
||||
for numa_node in [0, 1]:
|
||||
actual_two_mb_count += int("".join(self.ssh_manager.execute(
|
||||
compute['ip'], cmd.format(numa_node, "2048"))["stdout"]))
|
||||
|
||||
result = "".join(self.ssh_manager.execute(
|
||||
compute['ip'], cmd.format(numa_node, "1048576"))["stdout"])
|
||||
|
||||
result = "0" if not result else result
|
||||
actual_one_gb_count += int(result)
|
||||
|
||||
asserts.assert_equal(
|
||||
two_mb_count, actual_two_mb_count,
|
||||
"Actual number of allocated 2Mb pages is {}, expected {}"
|
||||
.format(actual_two_mb_count, two_mb_count))
|
||||
asserts.assert_equal(
|
||||
one_gb_count, actual_one_gb_count,
|
||||
"Actual number of allocated 1Gb pages is {}, expected {}"
|
||||
.format(actual_one_gb_count, one_gb_count))
|
||||
|
||||
self.env.make_snapshot(snapshot_name, is_make=True)
|
||||
|
||||
@test(depends_on=[check_hugepages_distribution_per_numa],
|
||||
groups=["check_instance_one_gb_page_size_one_gb_host"])
|
||||
@log_snapshot_after_test
|
||||
def check_instance_one_gb_page_size_one_gb_host(self):
|
||||
"""Boot instance with 1 Gb page size on host with only 1 Gb HugePages
|
||||
|
||||
Scenario:
|
||||
1. Revert snapshot "check_hugepages_distribution_per_numa"
|
||||
2. Boot and validate instance on compute with only 1 Gb pages
|
||||
"""
|
||||
self.env.revert_snapshot("check_hugepages_distribution_per_numa")
|
||||
|
||||
cluster_id = self.fuel_web.get_last_created_cluster()
|
||||
controller_ip = self.fuel_web.get_public_vip(cluster_id)
|
||||
self.os_conn = os_actions.OpenStackActions(controller_ip)
|
||||
one_gb_host = "slave-02"
|
||||
|
||||
self.boot_instance_with_hugepage(
|
||||
target_compute_name=one_gb_host,
|
||||
flavor_name="h1.huge.hpgs",
|
||||
flavor_ram=1024,
|
||||
page_size=1048576)
|
||||
|
||||
@test(depends_on=[check_hugepages_distribution_per_numa],
|
||||
groups=["check_instance_two_mb_page_size_two_mb_host"])
|
||||
@log_snapshot_after_test
|
||||
def check_instance_two_mb_page_size_two_mb_host(self):
|
||||
"""Boot instance with 2 Mb page size on host with only 2 Mb HugePages
|
||||
|
||||
Scenario:
|
||||
1. Revert snapshot "check_hugepages_distribution_per_numa"
|
||||
2. Boot and validate instance on compute with only 2 Mb pages
|
||||
"""
|
||||
self.env.revert_snapshot("check_hugepages_distribution_per_numa")
|
||||
|
||||
cluster_id = self.fuel_web.get_last_created_cluster()
|
||||
controller_ip = self.fuel_web.get_public_vip(cluster_id)
|
||||
self.os_conn = os_actions.OpenStackActions(controller_ip)
|
||||
two_mb_host = "slave-03"
|
||||
|
||||
self.boot_instance_with_hugepage(
|
||||
target_compute_name=two_mb_host,
|
||||
flavor_name="h1.small.hpgs",
|
||||
flavor_ram=512,
|
||||
page_size=2048)
|
||||
|
||||
@test(depends_on=[check_hugepages_distribution_per_numa],
|
||||
groups=["check_instance_one_gb_page_size_mixed_size_host"])
|
||||
@log_snapshot_after_test
|
||||
def check_instance_one_gb_page_size_mixed_size_host(self):
|
||||
"""Boot instance with 1 Gb page size on host with both HugePages types
|
||||
|
||||
Scenario:
|
||||
1. Revert snapshot "check_hugepages_distribution_per_numa"
|
||||
2. Boot and validate instance on compute with both pages types
|
||||
"""
|
||||
self.env.revert_snapshot("check_hugepages_distribution_per_numa")
|
||||
|
||||
cluster_id = self.fuel_web.get_last_created_cluster()
|
||||
controller_ip = self.fuel_web.get_public_vip(cluster_id)
|
||||
self.os_conn = os_actions.OpenStackActions(controller_ip)
|
||||
mixed_host = "slave-01"
|
||||
|
||||
self.boot_instance_with_hugepage(
|
||||
target_compute_name=mixed_host,
|
||||
flavor_name="h1.huge_mixed.hpgs",
|
||||
flavor_ram=1024,
|
||||
page_size=1048576)
|
||||
|
||||
@test(depends_on=[check_hugepages_distribution_per_numa],
|
||||
groups=["check_instance_two_mb_page_size_mixed_size_host"])
|
||||
@log_snapshot_after_test
|
||||
def check_instance_two_mb_page_size_mixed_size_host(self):
|
||||
"""Boot instance with 2 Mb page size on host with both HugePages types
|
||||
|
||||
Scenario:
|
||||
1. Revert snapshot "check_hugepages_distribution_per_numa"
|
||||
2. Boot and validate instance on compute with both pages types
|
||||
"""
|
||||
self.env.revert_snapshot("check_hugepages_distribution_per_numa")
|
||||
|
||||
cluster_id = self.fuel_web.get_last_created_cluster()
|
||||
controller_ip = self.fuel_web.get_public_vip(cluster_id)
|
||||
self.os_conn = os_actions.OpenStackActions(controller_ip)
|
||||
mixed_host = "slave-01"
|
||||
|
||||
self.boot_instance_with_hugepage(
|
||||
target_compute_name=mixed_host,
|
||||
flavor_name="h1.small_mixed.hpgs",
|
||||
flavor_ram=128,
|
||||
page_size=2048)
|
||||
|
||||
@test(depends_on=[check_hugepages_distribution_per_numa],
|
||||
groups=["check_hugepages_nova_scheduler"])
|
||||
@log_snapshot_after_test
|
||||
def check_instance_two_mb_page_size_mixed_role_host(self):
|
||||
"""Boot instance with both HP sizes on host with Cinder+Compute role
|
||||
|
||||
Scenario:
|
||||
1. Revert snapshot "check_hugepages_distribution_per_numa"
|
||||
2. Boot and validate instance on compute+mongo node with 2Mb
|
||||
3. Boot and validate instance on compute+mongo node with 1Gb
|
||||
"""
|
||||
self.env.revert_snapshot("check_hugepages_distribution_per_numa")
|
||||
|
||||
cluster_id = self.fuel_web.get_last_created_cluster()
|
||||
controller_ip = self.fuel_web.get_public_vip(cluster_id)
|
||||
self.os_conn = os_actions.OpenStackActions(controller_ip)
|
||||
mixed_role_host = "slave-04"
|
||||
|
||||
self.boot_instance_with_hugepage(
|
||||
target_compute_name=mixed_role_host,
|
||||
flavor_name="h1.small_mixed_roles.hpgs",
|
||||
flavor_ram=128,
|
||||
page_size=2048)
|
||||
|
||||
self.boot_instance_with_hugepage(
|
||||
target_compute_name=mixed_role_host,
|
||||
flavor_name="h1.huge_mixed_roles.hpgs",
|
||||
flavor_ram=1024,
|
||||
page_size=1048576)
|
||||
|
||||
@test(depends_on=[check_hugepages_distribution_per_numa],
|
||||
groups=["check_hugepages_after_reboot"])
|
||||
@log_snapshot_after_test
|
||||
def check_hugepages_after_reboot(self):
|
||||
"""Boot instances with both HP sizes on compute after reboot
|
||||
|
||||
Scenario:
|
||||
1. Revert snapshot "check_hugepages_distribution_per_numa"
|
||||
2. Reboot node with mixed reserved HugePages
|
||||
3. Boot and validate instance with 2Mb page size
|
||||
4. Boot and validate instance with 1Gb page size
|
||||
"""
|
||||
self.env.revert_snapshot("check_hugepages_distribution_per_numa")
|
||||
|
||||
cluster_id = self.fuel_web.get_last_created_cluster()
|
||||
controller_ip = self.fuel_web.get_public_vip(cluster_id)
|
||||
self.os_conn = os_actions.OpenStackActions(controller_ip)
|
||||
mixed_host = "slave-01"
|
||||
|
||||
target_compute = self.fuel_web.get_devops_node_by_nailgun_node(
|
||||
self.fuel_web.get_nailgun_node_by_name(mixed_host))
|
||||
self.fuel_web.cold_restart_nodes([target_compute])
|
||||
|
||||
self.boot_instance_with_hugepage(
|
||||
target_compute_name=mixed_host,
|
||||
flavor_name="h1.small_mixed.hpgs",
|
||||
flavor_ram=128,
|
||||
page_size=2048)
|
||||
|
||||
self.boot_instance_with_hugepage(
|
||||
target_compute_name=mixed_host,
|
||||
flavor_name="h1.huge_mixed.hpgs",
|
||||
flavor_ram=1024,
|
||||
page_size=1048576)
|
||||
|
Loading…
Reference in New Issue
Block a user