#!/usr/bin/env python3
# group: rw migration
#
# Migrate a VM with a BDS with backing nodes, which runs
# bdrv_invalidate_cache(), which for qcow2 and qed triggers reading the
# backing file string from the image header.  Check whether this
# interferes with bdrv_backing_overridden().
#
# Copyright (C) 2022 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/>.
#

import json
import os
from typing import Optional

import iotests
from iotests import qemu_img_create, qemu_img_info


image_size = 1 * 1024 * 1024
imgs = [os.path.join(iotests.test_dir, f'{i}.img') for i in range(0, 4)]

mig_sock = os.path.join(iotests.sock_dir, 'mig.sock')


class TestPostMigrateFilename(iotests.QMPTestCase):
    vm_s: Optional[iotests.VM] = None
    vm_d: Optional[iotests.VM] = None

    def setUp(self) -> None:
        # Create backing chain of three images, where the backing file strings
        # are json:{} filenames
        qemu_img_create('-f', iotests.imgfmt, imgs[0], str(image_size))
        for i in range(1, 3):
            backing = {
                'driver': iotests.imgfmt,
                'file': {
                    'driver': 'file',
                    'filename': imgs[i - 1]
                }
            }
            qemu_img_create('-f', iotests.imgfmt, '-F', iotests.imgfmt,
                            '-b', 'json:' + json.dumps(backing),
                            imgs[i], str(image_size))

    def tearDown(self) -> None:
        if self.vm_s is not None:
            self.vm_s.shutdown()
        if self.vm_d is not None:
            self.vm_d.shutdown()

        for img in imgs:
            try:
                os.remove(img)
            except OSError:
                pass
        try:
            os.remove(mig_sock)
        except OSError:
            pass

    def test_migration(self) -> None:
        """
        Migrate a VM with the backing chain created in setUp() attached.  At
        the end of the migration process, the destination will run
        bdrv_invalidate_cache(), which for some image formats (qcow2 and qed)
        means the backing file string is re-read from the image header.  If
        this overwrites bs->auto_backing_file, doing so may cause
        bdrv_backing_overridden() to become true: The image header reports a
        json:{} filename, but when opening it, bdrv_refresh_filename() will
        simplify it to a plain simple filename; and when bs->auto_backing_file
        and bs->backing->bs->filename differ, bdrv_backing_overridden() becomes
        true.
        If bdrv_backing_overridden() is true, the BDS will be forced to get a
        json:{} filename, which in general is not the end of the world, but not
        great.  Check whether that happens, i.e. whether migration changes the
        node's filename.
        """

        blockdev = {
            'node-name': 'node0',
            'driver': iotests.imgfmt,
            'file': {
                'driver': 'file',
                'filename': imgs[2]
            }
        }

        self.vm_s = iotests.VM(path_suffix='a') \
                           .add_blockdev(json.dumps(blockdev))
        self.vm_d = iotests.VM(path_suffix='b') \
                           .add_blockdev(json.dumps(blockdev)) \
                           .add_incoming(f'unix:{mig_sock}')

        assert self.vm_s is not None
        assert self.vm_d is not None

        self.vm_s.launch()
        self.vm_d.launch()

        pre_mig_filename = self.vm_s.node_info('node0')['file']

        self.vm_s.qmp('migrate', uri=f'unix:{mig_sock}')

        # Wait for migration to be done
        self.vm_s.event_wait('STOP')
        self.vm_d.event_wait('RESUME')

        post_mig_filename = self.vm_d.node_info('node0')['file']

        # Verify that the filename hasn't changed from before the migration
        self.assertEqual(pre_mig_filename, post_mig_filename)

        self.vm_s.shutdown()
        self.vm_s = None

        # For good measure, try creating an overlay and check its backing
        # chain below.  This is how the issue was originally found.
        result = self.vm_d.qmp('blockdev-snapshot-sync',
                               format=iotests.imgfmt,
                               snapshot_file=imgs[3],
                               node_name='node0',
                               snapshot_node_name='node0-overlay')
        self.assert_qmp(result, 'return', {})

        self.vm_d.shutdown()
        self.vm_d = None

        # Check the newly created overlay's backing chain
        chain = qemu_img_info('--backing-chain', imgs[3])
        for index, image in enumerate(chain):
            self.assertEqual(image['filename'], imgs[3 - index])


if __name__ == '__main__':
    # These are the image formats that run their open() function from their
    # .bdrv_co_invaliate_cache() implementations, so test them
    iotests.main(supported_fmts=['qcow2', 'qed'],
                 supported_protocols=['file'])
