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