#!/usr/bin/env python3
# group: rw quick
#
# Very specific tests for adjacent commit/stream block jobs
#
# 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: Hanna Reitz <hreitz@redhat.com>

import iotests
from iotests import log, qemu_img, qemu_io, \
        filter_qmp_testfiles, filter_qmp_imgfmt

# Returns a node for blockdev-add
def node(node_name, path, backing=None, fmt=None, throttle=None):
    if fmt is None:
        fmt = iotests.imgfmt

    res = {
        'node-name': node_name,
        'driver': fmt,
        'file': {
            'driver': 'file',
            'filename': path
        }
    }

    if backing is not None:
        res['backing'] = backing

    if throttle:
        res['file'] = {
            'driver': 'throttle',
            'throttle-group': throttle,
            'file': res['file']
        }

    return res

# Finds a node in the debug block graph
def find_graph_node(graph, node_id):
    return next(node for node in graph['nodes'] if node['id'] == node_id)


def test_concurrent_finish(write_to_stream_node):
    log('')
    log('=== Commit and stream finish concurrently (letting %s write) ===' % \
        ('stream' if write_to_stream_node else 'commit'))
    log('')

    # All chosen in such a way that when the commit job wants to
    # finish, it polls and thus makes stream finish concurrently --
    # and the other way around, depending on whether the commit job
    # is finalized before stream completes or not.

    with iotests.FilePath('node4.img') as node4_path, \
         iotests.FilePath('node3.img') as node3_path, \
         iotests.FilePath('node2.img') as node2_path, \
         iotests.FilePath('node1.img') as node1_path, \
         iotests.FilePath('node0.img') as node0_path, \
         iotests.VM() as vm:

        # It is important to use raw for the base layer (so that
        # permissions are just handed through to the protocol layer)
        qemu_img('create', '-f', 'raw', node0_path, '64M')

        stream_throttle=None
        commit_throttle=None

        for path in [node1_path, node2_path, node3_path, node4_path]:
            qemu_img('create', '-f', iotests.imgfmt, path, '64M')

        if write_to_stream_node:
            # This is what (most of the time) makes commit finish
            # earlier and then pull in stream
            qemu_io(node2_path,
                    '-c', 'write %iK 64K' % (65536 - 192),
                    '-c', 'write %iK 64K' % (65536 -  64))

            stream_throttle='tg'
        else:
            # And this makes stream finish earlier
            qemu_io(node1_path, '-c', 'write %iK 64K' % (65536 - 64))

            commit_throttle='tg'

        vm.launch()

        vm.qmp_log('object-add',
                   qom_type='throttle-group',
                   id='tg',
                   limits={
                       'iops-write': 1,
                       'iops-write-max': 1
                   })

        vm.qmp_log('blockdev-add',
                   filters=[filter_qmp_testfiles, filter_qmp_imgfmt],
                   **node('node4', node4_path, throttle=stream_throttle,
                     backing=node('node3', node3_path,
                     backing=node('node2', node2_path,
                     backing=node('node1', node1_path,
                     backing=node('node0', node0_path, throttle=commit_throttle,
                                  fmt='raw'))))))

        vm.qmp_log('block-commit',
                   job_id='commit',
                   device='node4',
                   filter_node_name='commit-filter',
                   top_node='node1',
                   base_node='node0',
                   auto_finalize=False)

        vm.qmp_log('block-stream',
                   job_id='stream',
                   device='node3',
                   base_node='commit-filter')

        if write_to_stream_node:
            vm.run_job('commit', auto_finalize=False, auto_dismiss=True)
            vm.run_job('stream', auto_finalize=True, auto_dismiss=True)
        else:
            # No, the jobs do not really finish concurrently here,
            # the stream job does complete strictly before commit.
            # But still, this is close enough for what we want to
            # test.
            vm.run_job('stream', auto_finalize=True, auto_dismiss=True)
            vm.run_job('commit', auto_finalize=False, auto_dismiss=True)

        # Assert that the backing node of node3 is node 0 now
        graph = vm.qmp('x-debug-query-block-graph')['return']
        for edge in graph['edges']:
            if edge['name'] == 'backing' and \
               find_graph_node(graph, edge['parent'])['name'] == 'node3':
                assert find_graph_node(graph, edge['child'])['name'] == 'node0'
                break


def main():
    log('Running tests:')
    test_concurrent_finish(True)
    test_concurrent_finish(False)

if __name__ == '__main__':
    # Need backing file and change-backing-file support
    iotests.script_main(main,
                        supported_fmts=['qcow2', 'qed'],
                        supported_platforms=['linux'])
