#!/usr/bin/env python # # Tests for qmp command nbd-server-remove. # # Copyright (c) 2017 Virtuozzo International GmbH # # 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 . # import os import sys import iotests import time from iotests import qemu_img_create, qemu_io, filter_qemu_io, QemuIoInteractive nbd_sock = os.path.join(iotests.test_dir, 'nbd_sock') nbd_uri = 'nbd+unix:///exp?socket=' + nbd_sock disk = os.path.join(iotests.test_dir, 'disk') class TestNbdServerRemove(iotests.QMPTestCase): def setUp(self): qemu_img_create('-f', iotests.imgfmt, disk, '1M') self.vm = iotests.VM().add_drive(disk) self.vm.launch() address = { 'type': 'unix', 'data': { 'path': nbd_sock } } result = self.vm.qmp('nbd-server-start', addr=address) self.assert_qmp(result, 'return', {}) result = self.vm.qmp('nbd-server-add', device='drive0', name='exp') self.assert_qmp(result, 'return', {}) def tearDown(self): self.vm.shutdown() os.remove(nbd_sock) os.remove(disk) def remove_export(self, name, mode=None): if mode is None: return self.vm.qmp('nbd-server-remove', name=name) else: return self.vm.qmp('nbd-server-remove', name=name, mode=mode) def assertExportNotFound(self, name): result = self.vm.qmp('nbd-server-remove', name=name) self.assert_qmp(result, 'error/desc', "Export 'exp' is not found") def assertExistingClients(self, result): self.assert_qmp(result, 'error/desc', "export 'exp' still in use") def assertReadOk(self, qemu_io_output): self.assertEqual( filter_qemu_io(qemu_io_output).strip(), 'read 512/512 bytes at offset 0\n' + '512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)') def assertReadFailed(self, qemu_io_output): self.assertEqual(filter_qemu_io(qemu_io_output).strip(), 'read failed: Input/output error') def assertConnectFailed(self, qemu_io_output): self.assertEqual(filter_qemu_io(qemu_io_output).strip(), "qemu-io: can't open device " + nbd_uri + ": Requested export not available\n" "server reported: export 'exp' not present") def do_test_connect_after_remove(self, mode=None): args = ('-r', '-f', 'raw', '-c', 'read 0 512', nbd_uri) self.assertReadOk(qemu_io(*args)) result = self.remove_export('exp', mode) self.assert_qmp(result, 'return', {}) self.assertExportNotFound('exp') self.assertConnectFailed(qemu_io(*args)) def test_connect_after_remove_default(self): self.do_test_connect_after_remove() def test_connect_after_remove_safe(self): self.do_test_connect_after_remove('safe') def test_connect_after_remove_force(self): self.do_test_connect_after_remove('hard') def do_test_remove_during_connect_safe(self, mode=None): qio = QemuIoInteractive('-r', '-f', 'raw', nbd_uri) self.assertReadOk(qio.cmd('read 0 512')) result = self.remove_export('exp', mode) self.assertExistingClients(result) self.assertReadOk(qio.cmd('read 0 512')) qio.close() result = self.remove_export('exp', mode) self.assert_qmp(result, 'return', {}) self.assertExportNotFound('exp') def test_remove_during_connect_default(self): self.do_test_remove_during_connect_safe() def test_remove_during_connect_safe(self): self.do_test_remove_during_connect_safe('safe') def test_remove_during_connect_hard(self): qio = QemuIoInteractive('-r', '-f', 'raw', nbd_uri) self.assertReadOk(qio.cmd('read 0 512')) result = self.remove_export('exp', 'hard') self.assert_qmp(result, 'return', {}) self.assertReadFailed(qio.cmd('read 0 512')) self.assertExportNotFound('exp') qio.close() def test_remove_during_connect_safe_hard(self): qio = QemuIoInteractive('-r', '-f', 'raw', nbd_uri) self.assertReadOk(qio.cmd('read 0 512')) result = self.remove_export('exp', 'safe') self.assertExistingClients(result) self.assertReadOk(qio.cmd('read 0 512')) result = self.remove_export('exp', 'hard') self.assert_qmp(result, 'return', {}) self.assertExportNotFound('exp') self.assertReadFailed(qio.cmd('read 0 512')) qio.close() if __name__ == '__main__': iotests.main(supported_fmts=['generic'])