]>
Commit | Line | Data |
---|---|---|
cec0242a DP |
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 | |
e435f66b | 23 | import logging |
cec0242a | 24 | |
cec0242a | 25 | from qemu.machine import QEMUMachine |
2283b627 | 26 | from avocado_qemu import QemuSystemTest |
2d6a6e23 | 27 | from avocado import skip |
cec0242a DP |
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 | ||
2283b627 | 43 | class VirtioMaxSegSettingsCheck(QemuSystemTest): |
cec0242a DP |
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 | ||
684750ab VSO |
54 | output = vm.cmd('human-monitor-command', |
55 | command_line = 'info qtree') | |
cec0242a DP |
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): | |
e435f66b PMD |
76 | mt['device'] = dev_type_name # Only for the debug() call. |
77 | logger = logging.getLogger('machine') | |
78 | logger.debug(mt) | |
cec0242a DP |
79 | with QEMUMachine(self.qemu_bin) as vm: |
80 | vm.set_machine(mt["name"]) | |
77f50e82 | 81 | vm.add_args('-nodefaults') |
cec0242a DP |
82 | for s in VM_DEV_PARAMS[dev_type_name]: |
83 | vm.add_args(s) | |
0400937b PMD |
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] | |
cec0242a DP |
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 | ||
2d6a6e23 | 119 | @skip("break multi-arch CI") |
cec0242a DP |
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() | |
684750ab | 124 | machines = [m['name'] for m in vm.cmd('query-machines')] |
cec0242a DP |
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) |