#!/usr/bin/env python3
#
# 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_image_format(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.command('blockdev-create', job_id='job1',
                       options={
                           'driver': 'file',
                           'filename': filepath,
                           'size': 0,
                       }))
        vm.run_job('job1')
        log(vm.command('blockdev-add', driver='file',
                       node_name=nodename, filename=filepath))
        log(vm.command('blockdev-create', job_id='job2',
                       options={
                           'driver': iotests.imgfmt,
                           'file': nodename,
                           'size': size,
                       }))
        vm.run_job('job2')
        log(vm.command('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-pci,id=scsi0,iothread=iothread0')
    vm.add_device('virtio-scsi-pci,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()
