#!/usr/bin/env python3
#
# This test covers the basic fleecing workflow, which provides a
# point-in-time snapshot of a node that can be queried over NBD.
#
# Copyright (C) 2018 Red Hat, Inc.
# John helped, too.
#
# 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: John Snow <jsnow@redhat.com>

import iotests
from iotests import log, qemu_img, qemu_io, qemu_io_silent

iotests.verify_platform(['linux'])
iotests.verify_image_format(supported_fmts=['qcow2', 'qcow', 'qed', 'vmdk',
                                            'vhdx', 'raw'])

patterns = [("0x5d", "0",         "64k"),
            ("0xd5", "1M",        "64k"),
            ("0xdc", "32M",       "64k"),
            ("0xcd", "0x3ff0000", "64k")]  # 64M - 64K

overwrite = [("0xab", "0",         "64k"), # Full overwrite
             ("0xad", "0x00f8000", "64k"), # Partial-left (1M-32K)
             ("0x1d", "0x2008000", "64k"), # Partial-right (32M+32K)
             ("0xea", "0x3fe0000", "64k")] # Adjacent-left (64M - 128K)

zeroes = [("0", "0x00f8000", "32k"), # Left-end of partial-left (1M-32K)
          ("0", "0x2010000", "32k"), # Right-end of partial-right (32M+64K)
          ("0", "0x3fe0000", "64k")] # overwrite[3]

remainder = [("0xd5", "0x108000",  "32k"), # Right-end of partial-left [1]
             ("0xdc", "32M",       "32k"), # Left-end of partial-right [2]
             ("0xcd", "0x3ff0000", "64k")] # patterns[3]

with iotests.FilePath('base.img') as base_img_path, \
     iotests.FilePath('fleece.img') as fleece_img_path, \
     iotests.FilePath('nbd.sock', iotests.sock_dir) as nbd_sock_path, \
     iotests.VM() as vm:

    log('--- Setting up images ---')
    log('')

    assert qemu_img('create', '-f', iotests.imgfmt, base_img_path, '64M') == 0
    assert qemu_img('create', '-f', "qcow2", fleece_img_path, '64M') == 0

    for p in patterns:
        qemu_io('-f', iotests.imgfmt,
                '-c', 'write -P%s %s %s' % p, base_img_path)

    log('Done')

    log('')
    log('--- Launching VM ---')
    log('')

    vm.add_drive(base_img_path)
    vm.launch()
    log('Done')

    log('')
    log('--- Setting up Fleecing Graph ---')
    log('')

    src_node = "drive0"
    tgt_node = "fleeceNode"

    # create tgt_node backed by src_node
    log(vm.qmp("blockdev-add", **{
        "driver": "qcow2",
        "node-name": tgt_node,
        "file": {
            "driver": "file",
            "filename": fleece_img_path,
        },
        "backing": src_node,
    }))

    # Establish COW from source to fleecing node
    log(vm.qmp("blockdev-backup",
               device=src_node,
               target=tgt_node,
               sync="none"))

    log('')
    log('--- Setting up NBD Export ---')
    log('')

    nbd_uri = 'nbd+unix:///%s?socket=%s' % (tgt_node, nbd_sock_path)
    log(vm.qmp("nbd-server-start",
               **{"addr": { "type": "unix",
                            "data": { "path": nbd_sock_path } } }))

    log(vm.qmp("nbd-server-add", device=tgt_node))

    log('')
    log('--- Sanity Check ---')
    log('')

    for p in (patterns + zeroes):
        cmd = "read -P%s %s %s" % p
        log(cmd)
        assert qemu_io_silent('-r', '-f', 'raw', '-c', cmd, nbd_uri) == 0

    log('')
    log('--- Testing COW ---')
    log('')

    for p in overwrite:
        cmd = "write -P%s %s %s" % p
        log(cmd)
        log(vm.hmp_qemu_io(src_node, cmd))

    log('')
    log('--- Verifying Data ---')
    log('')

    for p in (patterns + zeroes):
        cmd = "read -P%s %s %s" % p
        log(cmd)
        assert qemu_io_silent('-r', '-f', 'raw', '-c', cmd, nbd_uri) == 0

    log('')
    log('--- Cleanup ---')
    log('')

    log(vm.qmp('block-job-cancel', device=src_node))
    log(vm.event_wait('BLOCK_JOB_CANCELLED'),
        filters=[iotests.filter_qmp_event])
    log(vm.qmp('nbd-server-stop'))
    log(vm.qmp('blockdev-del', node_name=tgt_node))
    vm.shutdown()

    log('')
    log('--- Confirming writes ---')
    log('')

    for p in (overwrite + remainder):
        cmd = "read -P%s %s %s" % p
        log(cmd)
        assert qemu_io_silent(base_img_path, '-c', cmd) == 0

    log('')
    log('Done')
