xref: /openbmc/qemu/tests/qemu-iotests/205 (revision 800485762e6564e04e2ab315132d477069562d91)
1903cb1bfSPhilippe Mathieu-Daudé#!/usr/bin/env python3
29dd003a9SVladimir Sementsov-Ogievskiy# group: rw quick
32dadedceSVladimir Sementsov-Ogievskiy#
42dadedceSVladimir Sementsov-Ogievskiy# Tests for qmp command nbd-server-remove.
52dadedceSVladimir Sementsov-Ogievskiy#
62dadedceSVladimir Sementsov-Ogievskiy# Copyright (c) 2017 Virtuozzo International GmbH
72dadedceSVladimir Sementsov-Ogievskiy#
82dadedceSVladimir Sementsov-Ogievskiy# This program is free software; you can redistribute it and/or modify
92dadedceSVladimir Sementsov-Ogievskiy# it under the terms of the GNU General Public License as published by
102dadedceSVladimir Sementsov-Ogievskiy# the Free Software Foundation; either version 2 of the License, or
112dadedceSVladimir Sementsov-Ogievskiy# (at your option) any later version.
122dadedceSVladimir Sementsov-Ogievskiy#
132dadedceSVladimir Sementsov-Ogievskiy# This program is distributed in the hope that it will be useful,
142dadedceSVladimir Sementsov-Ogievskiy# but WITHOUT ANY WARRANTY; without even the implied warranty of
152dadedceSVladimir Sementsov-Ogievskiy# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
162dadedceSVladimir Sementsov-Ogievskiy# GNU General Public License for more details.
172dadedceSVladimir Sementsov-Ogievskiy#
182dadedceSVladimir Sementsov-Ogievskiy# You should have received a copy of the GNU General Public License
192dadedceSVladimir Sementsov-Ogievskiy# along with this program.  If not, see <http://www.gnu.org/licenses/>.
202dadedceSVladimir Sementsov-Ogievskiy#
212dadedceSVladimir Sementsov-Ogievskiy
222dadedceSVladimir Sementsov-Ogievskiyimport os
232dadedceSVladimir Sementsov-Ogievskiyimport sys
242dadedceSVladimir Sementsov-Ogievskiyimport iotests
252dadedceSVladimir Sementsov-Ogievskiyimport time
2685a353a0SVladimir Sementsov-Ogievskiyfrom iotests import qemu_img_create, qemu_io, filter_qemu_io, QemuIoInteractive
272dadedceSVladimir Sementsov-Ogievskiy
282683ff77SMax Reitznbd_sock = os.path.join(iotests.sock_dir, 'nbd_sock')
292dadedceSVladimir Sementsov-Ogievskiynbd_uri = 'nbd+unix:///exp?socket=' + nbd_sock
302dadedceSVladimir Sementsov-Ogievskiydisk = os.path.join(iotests.test_dir, 'disk')
312dadedceSVladimir Sementsov-Ogievskiy
322dadedceSVladimir Sementsov-Ogievskiy
332dadedceSVladimir Sementsov-Ogievskiyclass TestNbdServerRemove(iotests.QMPTestCase):
342dadedceSVladimir Sementsov-Ogievskiy    def setUp(self):
3585a353a0SVladimir Sementsov-Ogievskiy        qemu_img_create('-f', iotests.imgfmt, disk, '1M')
362dadedceSVladimir Sementsov-Ogievskiy
372dadedceSVladimir Sementsov-Ogievskiy        self.vm = iotests.VM().add_drive(disk)
382dadedceSVladimir Sementsov-Ogievskiy        self.vm.launch()
392dadedceSVladimir Sementsov-Ogievskiy
402dadedceSVladimir Sementsov-Ogievskiy        address = {
412dadedceSVladimir Sementsov-Ogievskiy            'type': 'unix',
422dadedceSVladimir Sementsov-Ogievskiy            'data': {
432dadedceSVladimir Sementsov-Ogievskiy                'path': nbd_sock
442dadedceSVladimir Sementsov-Ogievskiy            }
452dadedceSVladimir Sementsov-Ogievskiy        }
462dadedceSVladimir Sementsov-Ogievskiy
47*b6aed193SVladimir Sementsov-Ogievskiy        self.vm.cmd('nbd-server-start', addr=address)
48*b6aed193SVladimir Sementsov-Ogievskiy        self.vm.cmd('nbd-server-add', device='drive0', name='exp')
492dadedceSVladimir Sementsov-Ogievskiy
502dadedceSVladimir Sementsov-Ogievskiy    def tearDown(self):
512dadedceSVladimir Sementsov-Ogievskiy        self.vm.shutdown()
522dadedceSVladimir Sementsov-Ogievskiy        os.remove(nbd_sock)
532dadedceSVladimir Sementsov-Ogievskiy        os.remove(disk)
542dadedceSVladimir Sementsov-Ogievskiy
552dadedceSVladimir Sementsov-Ogievskiy    def remove_export(self, name, mode=None):
562dadedceSVladimir Sementsov-Ogievskiy        if mode is None:
572dadedceSVladimir Sementsov-Ogievskiy            return self.vm.qmp('nbd-server-remove', name=name)
582dadedceSVladimir Sementsov-Ogievskiy        else:
592dadedceSVladimir Sementsov-Ogievskiy            return self.vm.qmp('nbd-server-remove', name=name, mode=mode)
602dadedceSVladimir Sementsov-Ogievskiy
612dadedceSVladimir Sementsov-Ogievskiy    def assertExportNotFound(self, name):
622dadedceSVladimir Sementsov-Ogievskiy        result = self.vm.qmp('nbd-server-remove', name=name)
632dadedceSVladimir Sementsov-Ogievskiy        self.assert_qmp(result, 'error/desc', "Export 'exp' is not found")
642dadedceSVladimir Sementsov-Ogievskiy
652dadedceSVladimir Sementsov-Ogievskiy    def assertExistingClients(self, result):
662dadedceSVladimir Sementsov-Ogievskiy        self.assert_qmp(result, 'error/desc', "export 'exp' still in use")
672dadedceSVladimir Sementsov-Ogievskiy
682dadedceSVladimir Sementsov-Ogievskiy    def assertReadOk(self, qemu_io_output):
692dadedceSVladimir Sementsov-Ogievskiy        self.assertEqual(
702dadedceSVladimir Sementsov-Ogievskiy                filter_qemu_io(qemu_io_output).strip(),
712dadedceSVladimir Sementsov-Ogievskiy                'read 512/512 bytes at offset 0\n' +
722dadedceSVladimir Sementsov-Ogievskiy                '512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)')
732dadedceSVladimir Sementsov-Ogievskiy
742dadedceSVladimir Sementsov-Ogievskiy    def assertReadFailed(self, qemu_io_output):
752dadedceSVladimir Sementsov-Ogievskiy        self.assertEqual(filter_qemu_io(qemu_io_output).strip(),
762dadedceSVladimir Sementsov-Ogievskiy                         'read failed: Input/output error')
772dadedceSVladimir Sementsov-Ogievskiy
782dadedceSVladimir Sementsov-Ogievskiy    def assertConnectFailed(self, qemu_io_output):
792dadedceSVladimir Sementsov-Ogievskiy        self.assertEqual(filter_qemu_io(qemu_io_output).strip(),
8036b9986bSThomas Huth                         "qemu-io: can't open device " + nbd_uri +
812dadedceSVladimir Sementsov-Ogievskiy                         ": Requested export not available\n"
822dadedceSVladimir Sementsov-Ogievskiy                         "server reported: export 'exp' not present")
832dadedceSVladimir Sementsov-Ogievskiy
842dadedceSVladimir Sementsov-Ogievskiy    def do_test_connect_after_remove(self, mode=None):
852dadedceSVladimir Sementsov-Ogievskiy        args = ('-r', '-f', 'raw', '-c', 'read 0 512', nbd_uri)
866dede6a4SJohn Snow        self.assertReadOk(qemu_io(*args).stdout)
872dadedceSVladimir Sementsov-Ogievskiy
882dadedceSVladimir Sementsov-Ogievskiy        result = self.remove_export('exp', mode)
892dadedceSVladimir Sementsov-Ogievskiy        self.assert_qmp(result, 'return', {})
902dadedceSVladimir Sementsov-Ogievskiy
912dadedceSVladimir Sementsov-Ogievskiy        self.assertExportNotFound('exp')
926dede6a4SJohn Snow        self.assertConnectFailed(qemu_io(*args, check=False).stdout)
932dadedceSVladimir Sementsov-Ogievskiy
942dadedceSVladimir Sementsov-Ogievskiy    def test_connect_after_remove_default(self):
952dadedceSVladimir Sementsov-Ogievskiy        self.do_test_connect_after_remove()
962dadedceSVladimir Sementsov-Ogievskiy
972dadedceSVladimir Sementsov-Ogievskiy    def test_connect_after_remove_safe(self):
982dadedceSVladimir Sementsov-Ogievskiy        self.do_test_connect_after_remove('safe')
992dadedceSVladimir Sementsov-Ogievskiy
1002dadedceSVladimir Sementsov-Ogievskiy    def test_connect_after_remove_force(self):
1012dadedceSVladimir Sementsov-Ogievskiy        self.do_test_connect_after_remove('hard')
1022dadedceSVladimir Sementsov-Ogievskiy
1032dadedceSVladimir Sementsov-Ogievskiy    def do_test_remove_during_connect_safe(self, mode=None):
1042dadedceSVladimir Sementsov-Ogievskiy        qio = QemuIoInteractive('-r', '-f', 'raw', nbd_uri)
1052dadedceSVladimir Sementsov-Ogievskiy        self.assertReadOk(qio.cmd('read 0 512'))
1062dadedceSVladimir Sementsov-Ogievskiy
1072dadedceSVladimir Sementsov-Ogievskiy        result = self.remove_export('exp', mode)
1082dadedceSVladimir Sementsov-Ogievskiy        self.assertExistingClients(result)
1092dadedceSVladimir Sementsov-Ogievskiy
1102dadedceSVladimir Sementsov-Ogievskiy        self.assertReadOk(qio.cmd('read 0 512'))
1112dadedceSVladimir Sementsov-Ogievskiy
1122dadedceSVladimir Sementsov-Ogievskiy        qio.close()
1132dadedceSVladimir Sementsov-Ogievskiy
1142dadedceSVladimir Sementsov-Ogievskiy        result = self.remove_export('exp', mode)
1152dadedceSVladimir Sementsov-Ogievskiy        self.assert_qmp(result, 'return', {})
1162dadedceSVladimir Sementsov-Ogievskiy
1172dadedceSVladimir Sementsov-Ogievskiy        self.assertExportNotFound('exp')
1182dadedceSVladimir Sementsov-Ogievskiy
1192dadedceSVladimir Sementsov-Ogievskiy    def test_remove_during_connect_default(self):
1202dadedceSVladimir Sementsov-Ogievskiy        self.do_test_remove_during_connect_safe()
1212dadedceSVladimir Sementsov-Ogievskiy
1222dadedceSVladimir Sementsov-Ogievskiy    def test_remove_during_connect_safe(self):
1232dadedceSVladimir Sementsov-Ogievskiy        self.do_test_remove_during_connect_safe('safe')
1242dadedceSVladimir Sementsov-Ogievskiy
1252dadedceSVladimir Sementsov-Ogievskiy    def test_remove_during_connect_hard(self):
1262dadedceSVladimir Sementsov-Ogievskiy        qio = QemuIoInteractive('-r', '-f', 'raw', nbd_uri)
1272dadedceSVladimir Sementsov-Ogievskiy        self.assertReadOk(qio.cmd('read 0 512'))
1282dadedceSVladimir Sementsov-Ogievskiy
1292dadedceSVladimir Sementsov-Ogievskiy        result = self.remove_export('exp', 'hard')
1302dadedceSVladimir Sementsov-Ogievskiy        self.assert_qmp(result, 'return', {})
1312dadedceSVladimir Sementsov-Ogievskiy
1322dadedceSVladimir Sementsov-Ogievskiy        self.assertReadFailed(qio.cmd('read 0 512'))
1332dadedceSVladimir Sementsov-Ogievskiy        self.assertExportNotFound('exp')
1342dadedceSVladimir Sementsov-Ogievskiy
1352dadedceSVladimir Sementsov-Ogievskiy        qio.close()
1362dadedceSVladimir Sementsov-Ogievskiy
1372dadedceSVladimir Sementsov-Ogievskiy    def test_remove_during_connect_safe_hard(self):
1382dadedceSVladimir Sementsov-Ogievskiy        qio = QemuIoInteractive('-r', '-f', 'raw', nbd_uri)
1392dadedceSVladimir Sementsov-Ogievskiy        self.assertReadOk(qio.cmd('read 0 512'))
1402dadedceSVladimir Sementsov-Ogievskiy
1412dadedceSVladimir Sementsov-Ogievskiy        result = self.remove_export('exp', 'safe')
1422dadedceSVladimir Sementsov-Ogievskiy        self.assertExistingClients(result)
1432dadedceSVladimir Sementsov-Ogievskiy
1442dadedceSVladimir Sementsov-Ogievskiy        self.assertReadOk(qio.cmd('read 0 512'))
1452dadedceSVladimir Sementsov-Ogievskiy
1462dadedceSVladimir Sementsov-Ogievskiy        result = self.remove_export('exp', 'hard')
1472dadedceSVladimir Sementsov-Ogievskiy        self.assert_qmp(result, 'return', {})
1482dadedceSVladimir Sementsov-Ogievskiy
1492dadedceSVladimir Sementsov-Ogievskiy        self.assertExportNotFound('exp')
1502dadedceSVladimir Sementsov-Ogievskiy        self.assertReadFailed(qio.cmd('read 0 512'))
1512dadedceSVladimir Sementsov-Ogievskiy        qio.close()
1522dadedceSVladimir Sementsov-Ogievskiy
1532dadedceSVladimir Sementsov-Ogievskiy
1542dadedceSVladimir Sementsov-Ogievskiyif __name__ == '__main__':
1557c932a1dSMax Reitz    iotests.main(supported_fmts=['raw'],
1567c932a1dSMax Reitz                 supported_protocols=['nbd'])
157