#!/usr/bin/env python3
# group: quick

# Test hot plugging and unplugging with iothreads
#
# Copyright (C) 2019 Igalia, S.L.
# Author: Alberto Garcia <berto@igalia.com>
#
# 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 iotests
import os

nbd_sock = iotests.file_path('nbd.sock', base_dir=iotests.sock_dir)

class TestCase(iotests.QMPTestCase):
    test_driver = "null-co"

    def required_drivers(self):
        return [self.test_driver]

    @iotests.skip_if_unsupported(required_drivers)
    def setUp(self):
        self.vm = iotests.VM()
        self.vm.launch()

    def tearDown(self):
        self.vm.shutdown()

    def test1(self):
        iotests.log('==Unplug a SCSI disk and then plug it again==')
        self.vm.qmp_log('blockdev-add', driver='null-co', read_zeroes=True, node_name='hd0')
        self.vm.qmp_log('object-add', qom_type='iothread', id="iothread0")
        self.vm.qmp_log('device_add', id='scsi0', driver='virtio-scsi', iothread='iothread0', filters=[iotests.filter_qmp_virtio_scsi])
        self.vm.qmp_log('device_add', id='scsi-hd0', driver='scsi-hd', drive='hd0')
        self.vm.qmp_log('device_del', id='scsi-hd0')
        self.vm.event_wait('DEVICE_DELETED')
        self.vm.qmp_log('device_add', id='scsi-hd0', driver='scsi-hd', drive='hd0')
        self.vm.qmp_log('device_del', id='scsi-hd0')
        self.vm.event_wait('DEVICE_DELETED')
        self.vm.qmp_log('blockdev-del', node_name='hd0')

    def test2(self):
        iotests.log('==Attach two SCSI disks using the same block device and the same iothread==')
        self.vm.qmp_log('blockdev-add', driver='null-co', read_zeroes=True, node_name='hd0', read_only=True)
        self.vm.qmp_log('object-add', qom_type='iothread', id="iothread0")
        self.vm.qmp_log('device_add', id='scsi0', driver='virtio-scsi', iothread='iothread0', filters=[iotests.filter_qmp_virtio_scsi])

        self.vm.qmp_log('device_add', id='scsi-hd0', driver='scsi-hd', drive='hd0')
        self.vm.qmp_log('device_add', id='scsi-hd1', driver='scsi-hd', drive='hd0')
        self.vm.qmp_log('device_del', id='scsi-hd0')
        self.vm.event_wait('DEVICE_DELETED')
        self.vm.qmp_log('device_del', id='scsi-hd1')
        self.vm.event_wait('DEVICE_DELETED')
        self.vm.qmp_log('blockdev-del', node_name='hd0')

    def test3(self):
        iotests.log('==Attach two SCSI disks using the same block device but different iothreads==')

        self.vm.qmp_log('blockdev-add', driver='null-co', read_zeroes=True, node_name='hd0', read_only=True)

        self.vm.qmp_log('object-add', qom_type='iothread', id="iothread0")
        self.vm.qmp_log('object-add', qom_type='iothread', id="iothread1")

        self.vm.qmp_log('device_add', id='scsi0', driver='virtio-scsi', iothread='iothread0', filters=[iotests.filter_qmp_virtio_scsi])
        self.vm.qmp_log('device_add', id='scsi1', driver='virtio-scsi', iothread='iothread1', filters=[iotests.filter_qmp_virtio_scsi])

        self.vm.qmp_log('device_add', id='scsi-hd0', driver='scsi-hd', drive='hd0', bus="scsi0.0")
        self.vm.qmp_log('device_add', id='scsi-hd1', driver='scsi-hd', drive='hd0', bus="scsi1.0")

        self.vm.qmp_log('device_del', id='scsi-hd0')
        self.vm.event_wait('DEVICE_DELETED')
        self.vm.qmp_log('device_add', id='scsi-hd1', driver='scsi-hd', drive='hd0', bus="scsi1.0")

        self.vm.qmp_log('device_del', id='scsi-hd1')
        self.vm.event_wait('DEVICE_DELETED')
        self.vm.qmp_log('blockdev-del', node_name='hd0')

    def test4(self):
        iotests.log('==Attach a SCSI disks using the same block device as a NBD server==')

        self.vm.qmp_log('blockdev-add', driver='null-co', read_zeroes=True, node_name='hd0', read_only=True)

        self.vm.qmp_log('nbd-server-start',
                        filters=[iotests.filter_qmp_testfiles],
                        addr={'type':'unix', 'data':{'path':nbd_sock}})

        self.vm.qmp_log('nbd-server-add', device='hd0')

        self.vm.qmp_log('object-add', qom_type='iothread', id="iothread0")
        self.vm.qmp_log('device_add', id='scsi0', driver='virtio-scsi', iothread='iothread0', filters=[iotests.filter_qmp_virtio_scsi])
        self.vm.qmp_log('device_add', id='scsi-hd0', driver='scsi-hd', drive='hd0')

if __name__ == '__main__':
    iotests.activate_logging()
    iotests.main()
