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