#!/usr/bin/env python3
#
# Tests that "bdrv_drain_all" doesn't drain block jobs
#
# Copyright (C) 2015 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 os
import iotests
import time

class TestStopWithBlockJob(iotests.QMPTestCase):
    test_img = os.path.join(iotests.test_dir, 'test.img')
    target_img = os.path.join(iotests.test_dir, 'target.img')
    base_img = os.path.join(iotests.test_dir, 'base.img')

    def setUp(self):
        iotests.qemu_img('create', '-f', iotests.imgfmt, self.base_img, "1G")
        iotests.qemu_img('create', '-f', iotests.imgfmt, self.test_img,
                         "-b", self.base_img, '-F', iotests.imgfmt)
        iotests.qemu_io('-f', iotests.imgfmt, '-c', 'write -P0x5d 1M 128M', self.test_img)
        self.vm = iotests.VM().add_drive(self.test_img)
        self.vm.launch()

    def tearDown(self):
        params = {"device": "drive0",
                  "bps": 0,
                  "bps_rd": 0,
                  "bps_wr": 0,
                  "iops": 0,
                  "iops_rd": 0,
                  "iops_wr": 0,
                 }
        result = self.vm.qmp("block_set_io_throttle", conv_keys=False,
                             **params)
        self.vm.shutdown()

    def do_test_stop(self, cmd, **args):
        """Test 'stop' while block job is running on a throttled drive.
        The 'stop' command shouldn't drain the job"""
        params = {"device": "drive0",
                  "bps": 1024,
                  "bps_rd": 0,
                  "bps_wr": 0,
                  "iops": 0,
                  "iops_rd": 0,
                  "iops_wr": 0,
                 }
        result = self.vm.qmp("block_set_io_throttle", conv_keys=False,
                             **params)
        self.assert_qmp(result, 'return', {})
        result = self.vm.qmp(cmd, **args)
        self.assert_qmp(result, 'return', {})
        result = self.vm.qmp("stop")
        self.assert_qmp(result, 'return', {})
        result = self.vm.qmp("query-block-jobs")
        self.assert_qmp(result, 'return[0]/busy', True)
        self.assert_qmp(result, 'return[0]/ready', False)

    def test_drive_mirror(self):
        self.do_test_stop("drive-mirror", device="drive0",
                          target=self.target_img,
                          sync="full")

    def test_drive_backup(self):
        self.do_test_stop("drive-backup", device="drive0",
                          target=self.target_img,
                          sync="full")

    def test_block_commit(self):
        self.do_test_stop("block-commit", device="drive0")

if __name__ == '__main__':
    iotests.main(supported_fmts=["qcow2"],
                 supported_protocols=["file"])
