1#!/usr/bin/env python3
2# group: rw quick auto
3#
4# Copyright (C) 2023 Red Hat, Inc.
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# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
20
21import asyncio
22import iotests
23
24iotests.script_initialize(supported_fmts=['qcow2'],
25                          supported_platforms=['linux'])
26iotests.verify_virtio_scsi_pci_or_ccw()
27
28with iotests.FilePath('disk1.img') as base1_path, \
29     iotests.FilePath('disk1-snap.img') as snap1_path, \
30     iotests.FilePath('disk2.img') as base2_path, \
31     iotests.FilePath('disk2-snap.img') as snap2_path, \
32     iotests.VM() as vm:
33
34    img_size = '10M'
35
36    # Only one iothread for both disks
37    vm.add_object('iothread,id=iothread0')
38    vm.add_device('virtio-scsi,iothread=iothread0')
39
40    iotests.log('Preparing disks...')
41    for i, base_path, snap_path in ((0, base1_path, snap1_path),
42                                    (1, base2_path, snap2_path)):
43        iotests.qemu_img_create('-f', iotests.imgfmt, base_path, img_size)
44        iotests.qemu_img_create('-f', iotests.imgfmt, '-b', base_path,
45                                '-F', iotests.imgfmt, snap_path)
46
47        iotests.qemu_io_log('-c', f'write 0 {img_size}', base_path)
48
49        vm.add_blockdev(f'file,node-name=disk{i}-base-file,'
50                        f'filename={base_path}')
51        vm.add_blockdev(f'qcow2,node-name=disk{i}-base,file=disk{i}-base-file')
52        vm.add_blockdev(f'file,node-name=disk{i}-file,filename={snap_path}')
53        vm.add_blockdev(f'qcow2,node-name=disk{i},file=disk{i}-file,'
54                        f'backing=disk{i}-base')
55        vm.add_device(f'scsi-hd,drive=disk{i}')
56
57    iotests.log('Launching VM...')
58    vm.launch()
59
60    iotests.log('Starting stream jobs...')
61    iotests.log(vm.qmp('block-stream', device='disk0', job_id='job0'))
62    iotests.log(vm.qmp('block-stream', device='disk1', job_id='job1'))
63
64    finished = 0
65    while True:
66        try:
67            ev = vm.event_wait('JOB_STATUS_CHANGE', timeout=0.1)
68            if ev is not None and ev['data']['status'] == 'null':
69                finished += 1
70                # The test is done once both jobs are gone
71                if finished == 2:
72                    break
73        except asyncio.TimeoutError:
74            pass
75        vm.cmd('query-jobs')
76