#!/usr/bin/env python3
# group: rw quick migration
#
# Copyright (C) 2019 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Creator/Owner: Kevin Wolf <kwolf@redhat.com>
#
# Test migration with filter drivers present. Keep everything in an
# iothread just for fun.

import iotests
import os

iotests.script_initialize(supported_fmts=['qcow2'],
                          supported_platforms=['linux'])

with iotests.FilePath('img') as img_path, \
     iotests.FilePath('mig_fifo') as fifo, \
     iotests.VM(path_suffix='a') as vm_a, \
     iotests.VM(path_suffix='b') as vm_b:

    def add_opts(vm):
        vm.add_object('iothread,id=iothread0')
        vm.add_object('throttle-group,id=tg0,x-bps-total=65536')
        vm.add_blockdev('file,filename=%s,node-name=drive0-file' % (img_path))
        vm.add_blockdev('%s,file=drive0-file,node-name=drive0-fmt' % (iotests.imgfmt))
        vm.add_blockdev('copy-on-read,file=drive0-fmt,node-name=drive0-cor')
        vm.add_blockdev('throttle,file=drive0-cor,node-name=drive0-throttle,throttle-group=tg0')
        vm.add_blockdev('blkdebug,image=drive0-throttle,node-name=drive0-dbg')
        vm.add_blockdev('null-co,node-name=null,read-zeroes=on')
        vm.add_blockdev('blkverify,test=drive0-dbg,raw=null,node-name=drive0-verify')

        if iotests.supports_quorum():
            vm.add_blockdev('quorum,children.0=drive0-verify,vote-threshold=1,node-name=drive0-quorum')
            root = "drive0-quorum"
        else:
            root = "drive0-verify"

        vm.add_device('virtio-blk,drive=%s,iothread=iothread0' % root)

    iotests.qemu_img_create('-f', iotests.imgfmt, img_path, '64M')

    os.mkfifo(fifo)

    iotests.log('Launching destination VM...')
    add_opts(vm_b)
    vm_b.add_incoming("exec: cat '%s'" % (fifo))
    vm_b.launch()

    vm_b.enable_migration_events('B')

    iotests.log('Launching source VM...')
    add_opts(vm_a)
    vm_a.launch()

    vm_a.enable_migration_events('A')

    iotests.log('Starting migration to B...')
    iotests.log(vm_a.qmp('migrate', uri='exec:cat >%s' % (fifo)))
    with iotests.Timeout(3, 'Migration does not complete'):
        # Wait for the source first (which includes setup=setup)
        vm_a.wait_migration('postmigrate')
        # Wait for the destination second (which does not)
        vm_b.wait_migration('running')

    iotests.log(vm_a.qmp('query-migrate')['return']['status'])
    iotests.log(vm_b.qmp('query-migrate')['return']['status'])

    iotests.log(vm_a.qmp('query-status'))
    iotests.log(vm_b.qmp('query-status'))
