#!/usr/bin/env python3
# group: rw auto quick
#
# Test incremental/backup across iothread contexts
#
# Copyright (c) 2019 John Snow for 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/>.
#
# owner=jsnow@redhat.com

import os
import iotests
from iotests import log

iotests.verify_virtio_scsi_pci_or_ccw()

iotests.script_initialize(supported_fmts=['qcow2'])
size = 64 * 1024 * 1024

with iotests.FilePath('img0') as img0_path, \
     iotests.FilePath('img1') as img1_path, \
     iotests.FilePath('img0-full') as img0_full_path, \
     iotests.FilePath('img1-full') as img1_full_path, \
     iotests.FilePath('img0-incr') as img0_incr_path, \
     iotests.FilePath('img1-incr') as img1_incr_path, \
     iotests.VM() as vm:

    def create_target(filepath, name, size):
        basename = os.path.basename(filepath)
        nodename = "file_{}".format(basename)
        log(vm.cmd('blockdev-create', job_id='job1',
                   options={
                       'driver': 'file',
                       'filename': filepath,
                       'size': 0,
                   }))
        vm.run_job('job1')
        log(vm.cmd('blockdev-add', driver='file',
                   node_name=nodename, filename=filepath))
        log(vm.cmd('blockdev-create', job_id='job2',
                   options={
                       'driver': iotests.imgfmt,
                       'file': nodename,
                       'size': size,
                   }))
        vm.run_job('job2')
        log(vm.cmd('blockdev-add', driver=iotests.imgfmt,
                   node_name=name,
                   file=nodename))

    log('--- Preparing images & VM ---\n')
    vm.add_object('iothread,id=iothread0')
    vm.add_object('iothread,id=iothread1')
    vm.add_device('virtio-scsi,id=scsi0,iothread=iothread0')
    vm.add_device('virtio-scsi,id=scsi1,iothread=iothread1')
    iotests.qemu_img_create('-f', iotests.imgfmt, img0_path, str(size))
    iotests.qemu_img_create('-f', iotests.imgfmt, img1_path, str(size))
    vm.add_drive(img0_path, interface='none')
    vm.add_device('scsi-hd,id=device0,drive=drive0,bus=scsi0.0')
    vm.add_drive(img1_path, interface='none')
    vm.add_device('scsi-hd,id=device1,drive=drive1,bus=scsi1.0')

    log('--- Starting VM ---\n')
    vm.launch()

    log('--- Create Targets & Full Backups ---\n')
    create_target(img0_full_path, 'img0-full', size)
    create_target(img1_full_path, 'img1-full', size)
    ret = vm.qmp_log('transaction', indent=2, actions=[
        { 'type': 'block-dirty-bitmap-add',
          'data': { 'node': 'drive0', 'name': 'bitmap0' }},
        { 'type': 'block-dirty-bitmap-add',
          'data': { 'node': 'drive1', 'name': 'bitmap1' }},
        { 'type': 'blockdev-backup',
          'data': { 'device': 'drive0',
                    'target': 'img0-full',
                    'sync': 'full',
                    'job-id': 'j0' }},
        { 'type': 'blockdev-backup',
          'data': { 'device': 'drive1',
                    'target': 'img1-full',
                    'sync': 'full',
                    'job-id': 'j1' }}
    ])
    if "error" in ret:
        raise Exception(ret['error']['desc'])
    vm.run_job('j0', auto_dismiss=True)
    vm.run_job('j1', auto_dismiss=True)

    log('\n--- Create Targets & Incremental Backups ---\n')
    create_target(img0_incr_path, 'img0-incr', size)
    create_target(img1_incr_path, 'img1-incr', size)
    ret = vm.qmp_log('transaction', indent=2, actions=[
        { 'type': 'blockdev-backup',
          'data': { 'device': 'drive0',
                    'target': 'img0-incr',
                    'sync': 'incremental',
                    'bitmap': 'bitmap0',
                    'job-id': 'j2' }},
        { 'type': 'blockdev-backup',
          'data': { 'device': 'drive1',
                    'target': 'img1-incr',
                    'sync': 'incremental',
                    'bitmap': 'bitmap1',
                    'job-id': 'j3' }}
    ])
    if "error" in ret:
        raise Exception(ret['error']['desc'])
    vm.run_job('j2', auto_dismiss=True)
    vm.run_job('j3', auto_dismiss=True)

    log('\n--- Done ---')
    vm.shutdown()
