qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

virtio_check_params.py (5011B)


      1 #
      2 # Test virtio-scsi and virtio-blk queue settings for all machine types
      3 #
      4 # Copyright (c) 2019 Virtuozzo International GmbH
      5 #
      6 # This program is free software; you can redistribute it and/or modify
      7 # it under the terms of the GNU General Public License as published by
      8 # the Free Software Foundation; either version 2 of the License, or
      9 # (at your option) any later version.
     10 #
     11 # This program is distributed in the hope that it will be useful,
     12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 # GNU General Public License for more details.
     15 #
     16 # You should have received a copy of the GNU General Public License
     17 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
     18 #
     19 
     20 import sys
     21 import os
     22 import re
     23 import logging
     24 
     25 from qemu.machine import QEMUMachine
     26 from avocado_qemu import QemuSystemTest
     27 from avocado import skip
     28 
     29 #list of machine types and virtqueue properties to test
     30 VIRTIO_SCSI_PROPS = {'seg_max_adjust': 'seg_max_adjust'}
     31 VIRTIO_BLK_PROPS = {'seg_max_adjust': 'seg-max-adjust'}
     32 
     33 DEV_TYPES = {'virtio-scsi-pci': VIRTIO_SCSI_PROPS,
     34              'virtio-blk-pci': VIRTIO_BLK_PROPS}
     35 
     36 VM_DEV_PARAMS = {'virtio-scsi-pci': ['-device', 'virtio-scsi-pci,id=scsi0'],
     37                  'virtio-blk-pci': ['-device',
     38                                     'virtio-blk-pci,id=scsi0,drive=drive0',
     39                                     '-drive',
     40                                     'driver=null-co,id=drive0,if=none']}
     41 
     42 
     43 class VirtioMaxSegSettingsCheck(QemuSystemTest):
     44     @staticmethod
     45     def make_pattern(props):
     46         pattern_items = ['{0} = \w+'.format(prop) for prop in props]
     47         return '|'.join(pattern_items)
     48 
     49     def query_virtqueue(self, vm, dev_type_name):
     50         query_ok = False
     51         error = None
     52         props = None
     53 
     54         output = vm.command('human-monitor-command',
     55                             command_line = 'info qtree')
     56         props_list = DEV_TYPES[dev_type_name].values();
     57         pattern = self.make_pattern(props_list)
     58         res = re.findall(pattern, output)
     59 
     60         if len(res) != len(props_list):
     61             props_list = set(props_list)
     62             res = set(res)
     63             not_found = props_list.difference(res)
     64             not_found = ', '.join(not_found)
     65             error = '({0}): The following properties not found: {1}'\
     66                      .format(dev_type_name, not_found)
     67         else:
     68             query_ok = True
     69             props = dict()
     70             for prop in res:
     71                 p = prop.split(' = ')
     72                 props[p[0]] = p[1]
     73         return query_ok, props, error
     74 
     75     def check_mt(self, mt, dev_type_name):
     76         mt['device'] = dev_type_name # Only for the debug() call.
     77         logger = logging.getLogger('machine')
     78         logger.debug(mt)
     79         with QEMUMachine(self.qemu_bin) as vm:
     80             vm.set_machine(mt["name"])
     81             vm.add_args('-nodefaults')
     82             for s in VM_DEV_PARAMS[dev_type_name]:
     83                 vm.add_args(s)
     84             try:
     85                 vm.launch()
     86                 query_ok, props, error = self.query_virtqueue(vm, dev_type_name)
     87             except:
     88                 query_ok = False
     89                 error = sys.exc_info()[0]
     90 
     91         if not query_ok:
     92             self.fail('machine type {0}: {1}'.format(mt['name'], error))
     93 
     94         for prop_name, prop_val in props.items():
     95             expected_val = mt[prop_name]
     96             self.assertEqual(expected_val, prop_val)
     97 
     98     @staticmethod
     99     def seg_max_adjust_enabled(mt):
    100         # machine types >= 5.0 should have seg_max_adjust = true
    101         # others seg_max_adjust = false
    102         mt = mt.split("-")
    103 
    104         # machine types with one line name and name like pc-x.x
    105         if len(mt) <= 2:
    106             return False
    107 
    108         # machine types like pc-<chip_name>-x.x[.x]
    109         ver = mt[2]
    110         ver = ver.split(".");
    111 
    112         # versions >= 5.0 goes with seg_max_adjust enabled
    113         major = int(ver[0])
    114 
    115         if major >= 5:
    116             return True
    117         return False
    118 
    119     @skip("break multi-arch CI")
    120     def test_machine_types(self):
    121         # collect all machine types except 'none', 'isapc', 'microvm'
    122         with QEMUMachine(self.qemu_bin) as vm:
    123             vm.launch()
    124             machines = [m['name'] for m in vm.command('query-machines')]
    125             vm.shutdown()
    126         machines.remove('none')
    127         machines.remove('isapc')
    128         machines.remove('microvm')
    129 
    130         for dev_type in DEV_TYPES:
    131             # create the list of machine types and their parameters.
    132             mtypes = list()
    133             for m in machines:
    134                 if self.seg_max_adjust_enabled(m):
    135                     enabled = 'true'
    136                 else:
    137                     enabled = 'false'
    138                 mtypes.append({'name': m,
    139                                DEV_TYPES[dev_type]['seg_max_adjust']: enabled})
    140 
    141             # test each machine type for a device type
    142             for mt in mtypes:
    143                 self.check_mt(mt, dev_type)