Skip to content

Commit

Permalink
Add network case of qos
Browse files Browse the repository at this point in the history
- VIRT-299277 - [Qos][domiftune] Check and tune the bandwidth of a interface
via domiftune

Signed-off-by: Haijiao Zhao <[email protected]>
  • Loading branch information
chloerh committed Jun 25, 2024
1 parent 8575380 commit 3315384
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
- virtual_network.qos.check_bandwidth_by_domiftune:
type = check_bandwidth_by_domiftune
start_vm = no
timeout = 240
host_iface =
net_attrs = {'bandwidth_outbound': {'average': '500', 'peak': '1000', 'burst': '1024'}, 'bandwidth_inbound': {'average': '1000', 'peak': '5000', 'burst': '5120'}}
update_bw = {'inbound': {'average': '100', 'peak': '200', 'burst': '300'}, 'outbound': {'average': '200', 'peak': '300', 'burst': '200'}}
variants iface_type:
- nat:
iface_attrs = {'source': {'network': 'default'}, 'model': 'virtio', 'type_name': 'network'}
bw_with_floor =
update_bw = {'inbound': {'average': '100', 'peak': '200', 'burst': '300', 'floor': '150'}, 'outbound': {'average': '200', 'peak': '300', 'burst': '200'}}
- direct:
iface_attrs = {'source': {'dev': host_iface, 'mode': 'bridge'}, 'model': 'virtio', 'type_name': 'direct'}
- br:
br_type = linux_br
iface_type = bridge
iface_attrs = {'source': {'bridge': br_name}, 'model': 'virtio', 'type_name': 'bridge'}
144 changes: 144 additions & 0 deletions libvirt/tests/src/virtual_network/qos/check_bandwidth_by_domiftune.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import logging

from avocado.utils import process
from virttest import utils_misc
from virttest import utils_net
from virttest import virsh
from virttest.libvirt_xml import vm_xml
from virttest.libvirt_xml.network_xml import NetworkXML
from virttest.utils_libvirt import libvirt_misc
from virttest.utils_libvirt import libvirt_vmxml
from virttest.utils_test import libvirt

from provider.virtual_network import network_base

VIRSH_ARGS = {'ignore_status': False, 'debug': True}

LOG = logging.getLogger('avocado.' + __name__)


def run(test, params, env):
"""
Check and tune the bandwidth of a interface via domiftune
"""
vm_name = params.get('main_vm')
vm = env.get_vm(vm_name)
br_type = params.get('br_type', '')
rand_id = utils_misc.generate_random_string(3)
br_name = br_type + '_' + rand_id
host_iface = params.get('host_iface')
host_iface = host_iface if host_iface else utils_net.get_net_if(
state='UP')[0]
iface_attrs = eval(params.get('iface_attrs', '{}'))
net_attrs = eval(params.get('net_attrs', '{}'))
update_bw = eval(params.get('update_bw', '{}'))

vmxml = vm_xml.VMXML.new_from_inactive_dumpxml(vm_name)
bkxml = vmxml.copy()
net_xml = NetworkXML.new_from_net_dumpxml('default')
bk_net_xml = net_xml.copy()

try:
if br_type == 'linux_br':
utils_net.create_linux_bridge_tmux(br_name, host_iface)
process.run(f'ip l show type bridge {br_name}', shell=True)

net_xml.setup_attrs(**net_attrs)
net_xml.sync()
LOG.debug(f'Network xml of default: {net_xml}')

vmxml.del_device('interface', by_tag=True)

libvirt_vmxml.modify_vm_device(vmxml, 'interface', iface_attrs)
LOG.debug(f'VMXML of {vm_name}:\n{virsh.dumpxml(vm_name).stdout_text}')

vm.start()
session = vm.wait_for_serial_login()

iface = network_base.get_iface_xml_inst(vm_name, 'on vm')
mac = iface.mac_address
tap_device = libvirt.get_ifname_host(vm_name, mac)
LOG.debug(f'tap device on host with mac {mac} is: {tap_device}.')

domiftune_out = virsh.domiftune(
vm_name, tap_device, debug=True).stdout_text
domiftune_ori = libvirt_misc.convert_to_dict(
domiftune_out, '(\S+)\s*:\s*(\d+)')
if not all([v == '0' for v in domiftune_ori.values()]):
test.fail('All value of domiftune output should be "0"')

domiftune_args = {}
bw_in = update_bw['inbound']
inbound = f'{bw_in["average"]},{bw_in["peak"]},{bw_in["burst"]}'
if 'floor' in bw_in:
inbound = inbound + f',{bw_in["floor"]}'
domiftune_args.update({'inbound': inbound})
bw_out = update_bw['outbound']
outbound = f'{bw_out["average"]},{bw_out["peak"]},{bw_out["burst"]}'
domiftune_args.update({'outbound': outbound})
virsh.domiftune(vm_name, tap_device, **domiftune_args, **VIRSH_ARGS)

iface_update = network_base.get_iface_xml_inst(vm_name, 'after update')
LOG.debug(iface_update.bandwidth)
for key in ['inbound', 'outbound']:
if iface_update.fetch_attrs()['bandwidth'][key] != update_bw[key]:
test.fail(
f'Bandwidth of interface xml not correctly updated:\n'
f'{iface_update.fetch_attrs()["bandwidth"][key]} != '
f'{update_bw[key]}')
LOG.debug(f'{key} bandwidth check in xml: PASS')

# For direct interface type, "tc class show dev" will show the outbound
# instead of the inbound setting, and "tc filter show dev" will show
# the inbound instead of the outbound setting
iface_type = iface_attrs['type_name']
class_key = 'outbound' if iface_type == 'direct' else 'inbound'
filter_key = 'inbound' if iface_type == 'direct' else 'outbound'

if iface_type == 'network':
source_br = iface.source['bridge']
bw_floor = update_bw['inbound']['floor']
update_bw['inbound'].pop('floor')
if not utils_net.check_class_rules(
source_br, '1:3', {'floor': bw_floor}):
test.fail('Class rule check (floor) after domiftune failed')
if not utils_net.check_class_rules(
tap_device, '1:1', update_bw[class_key]):
test.fail(
'Class rule check after domiftune failed. Please check log.')
LOG.debug('Class rule check after domiftune: PASS')
if not utils_net.check_filter_rules(
tap_device, update_bw[filter_key]):
test.fail(
'Filter rule check after domiftune failed. Please check log.')
LOG.debug('Filter rule check after domiftune: PASS')

virsh.domiftune(vm_name, tap_device, inbound='0',
outbound='0', **VIRSH_ARGS)
iface_del_bw = network_base.get_iface_xml_inst(
vm_name, 'after delete bandwidth')

if 'bandwidth' in iface_del_bw.fetch_attrs():
test.fail('Bandwidth of interface xml not deleted')
out_c = utils_net.check_class_rules(
tap_device, "1:1", update_bw["inbound"], expect_none=True
)
out_f = utils_net.check_filter_rules(
tap_device, update_bw["outbound"], expect_none=True
)
if not all([out_c, out_f]):
test.fail(
"There should not be output of tc class/filter "
"command when bandwidth settings is deleted."
)
LOG.debug('Class and Filter rule check with "tc" '
'after delete bandwidth with domiftune: PASS')

finally:
if 'session' in locals():
session.close()
bkxml.sync()
bk_net_xml.sync()
if br_type == 'linux_br':
utils_net.delete_linux_bridge_tmux(br_name, host_iface)

0 comments on commit 3315384

Please sign in to comment.