xref: /qemu/tests/qemu-iotests/205 (revision 2dadedce2b2fbdfdce1de8f108a3d67c2241df87)
1*2dadedceSVladimir Sementsov-Ogievskiy#!/usr/bin/env python
2*2dadedceSVladimir Sementsov-Ogievskiy#
3*2dadedceSVladimir Sementsov-Ogievskiy# Tests for qmp command nbd-server-remove.
4*2dadedceSVladimir Sementsov-Ogievskiy#
5*2dadedceSVladimir Sementsov-Ogievskiy# Copyright (c) 2017 Virtuozzo International GmbH
6*2dadedceSVladimir Sementsov-Ogievskiy#
7*2dadedceSVladimir Sementsov-Ogievskiy# This program is free software; you can redistribute it and/or modify
8*2dadedceSVladimir Sementsov-Ogievskiy# it under the terms of the GNU General Public License as published by
9*2dadedceSVladimir Sementsov-Ogievskiy# the Free Software Foundation; either version 2 of the License, or
10*2dadedceSVladimir Sementsov-Ogievskiy# (at your option) any later version.
11*2dadedceSVladimir Sementsov-Ogievskiy#
12*2dadedceSVladimir Sementsov-Ogievskiy# This program is distributed in the hope that it will be useful,
13*2dadedceSVladimir Sementsov-Ogievskiy# but WITHOUT ANY WARRANTY; without even the implied warranty of
14*2dadedceSVladimir Sementsov-Ogievskiy# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*2dadedceSVladimir Sementsov-Ogievskiy# GNU General Public License for more details.
16*2dadedceSVladimir Sementsov-Ogievskiy#
17*2dadedceSVladimir Sementsov-Ogievskiy# You should have received a copy of the GNU General Public License
18*2dadedceSVladimir Sementsov-Ogievskiy# along with this program.  If not, see <http://www.gnu.org/licenses/>.
19*2dadedceSVladimir Sementsov-Ogievskiy#
20*2dadedceSVladimir Sementsov-Ogievskiy
21*2dadedceSVladimir Sementsov-Ogievskiyimport os
22*2dadedceSVladimir Sementsov-Ogievskiyimport sys
23*2dadedceSVladimir Sementsov-Ogievskiyimport iotests
24*2dadedceSVladimir Sementsov-Ogievskiyimport time
25*2dadedceSVladimir Sementsov-Ogievskiyfrom iotests import qemu_img, qemu_io, filter_qemu_io, QemuIoInteractive
26*2dadedceSVladimir Sementsov-Ogievskiy
27*2dadedceSVladimir Sementsov-Ogievskiynbd_sock = 'nbd_sock'
28*2dadedceSVladimir Sementsov-Ogievskiynbd_uri = 'nbd+unix:///exp?socket=' + nbd_sock
29*2dadedceSVladimir Sementsov-Ogievskiydisk = os.path.join(iotests.test_dir, 'disk')
30*2dadedceSVladimir Sementsov-Ogievskiy
31*2dadedceSVladimir Sementsov-Ogievskiy
32*2dadedceSVladimir Sementsov-Ogievskiyclass TestNbdServerRemove(iotests.QMPTestCase):
33*2dadedceSVladimir Sementsov-Ogievskiy    def setUp(self):
34*2dadedceSVladimir Sementsov-Ogievskiy        qemu_img('create', '-f', iotests.imgfmt, disk, '1M')
35*2dadedceSVladimir Sementsov-Ogievskiy
36*2dadedceSVladimir Sementsov-Ogievskiy        self.vm = iotests.VM().add_drive(disk)
37*2dadedceSVladimir Sementsov-Ogievskiy        self.vm.launch()
38*2dadedceSVladimir Sementsov-Ogievskiy
39*2dadedceSVladimir Sementsov-Ogievskiy        address = {
40*2dadedceSVladimir Sementsov-Ogievskiy            'type': 'unix',
41*2dadedceSVladimir Sementsov-Ogievskiy            'data': {
42*2dadedceSVladimir Sementsov-Ogievskiy                'path': nbd_sock
43*2dadedceSVladimir Sementsov-Ogievskiy            }
44*2dadedceSVladimir Sementsov-Ogievskiy        }
45*2dadedceSVladimir Sementsov-Ogievskiy
46*2dadedceSVladimir Sementsov-Ogievskiy        result = self.vm.qmp('nbd-server-start', addr=address)
47*2dadedceSVladimir Sementsov-Ogievskiy        self.assert_qmp(result, 'return', {})
48*2dadedceSVladimir Sementsov-Ogievskiy        result = self.vm.qmp('nbd-server-add', device='drive0', name='exp')
49*2dadedceSVladimir Sementsov-Ogievskiy        self.assert_qmp(result, 'return', {})
50*2dadedceSVladimir Sementsov-Ogievskiy
51*2dadedceSVladimir Sementsov-Ogievskiy    def tearDown(self):
52*2dadedceSVladimir Sementsov-Ogievskiy        self.vm.shutdown()
53*2dadedceSVladimir Sementsov-Ogievskiy        os.remove(nbd_sock)
54*2dadedceSVladimir Sementsov-Ogievskiy        os.remove(disk)
55*2dadedceSVladimir Sementsov-Ogievskiy
56*2dadedceSVladimir Sementsov-Ogievskiy    def remove_export(self, name, mode=None):
57*2dadedceSVladimir Sementsov-Ogievskiy        if mode is None:
58*2dadedceSVladimir Sementsov-Ogievskiy            return self.vm.qmp('nbd-server-remove', name=name)
59*2dadedceSVladimir Sementsov-Ogievskiy        else:
60*2dadedceSVladimir Sementsov-Ogievskiy            return self.vm.qmp('nbd-server-remove', name=name, mode=mode)
61*2dadedceSVladimir Sementsov-Ogievskiy
62*2dadedceSVladimir Sementsov-Ogievskiy    def assertExportNotFound(self, name):
63*2dadedceSVladimir Sementsov-Ogievskiy        result = self.vm.qmp('nbd-server-remove', name=name)
64*2dadedceSVladimir Sementsov-Ogievskiy        self.assert_qmp(result, 'error/desc', "Export 'exp' is not found")
65*2dadedceSVladimir Sementsov-Ogievskiy
66*2dadedceSVladimir Sementsov-Ogievskiy    def assertExistingClients(self, result):
67*2dadedceSVladimir Sementsov-Ogievskiy        self.assert_qmp(result, 'error/desc', "export 'exp' still in use")
68*2dadedceSVladimir Sementsov-Ogievskiy
69*2dadedceSVladimir Sementsov-Ogievskiy    def assertReadOk(self, qemu_io_output):
70*2dadedceSVladimir Sementsov-Ogievskiy        self.assertEqual(
71*2dadedceSVladimir Sementsov-Ogievskiy                filter_qemu_io(qemu_io_output).strip(),
72*2dadedceSVladimir Sementsov-Ogievskiy                'read 512/512 bytes at offset 0\n' +
73*2dadedceSVladimir Sementsov-Ogievskiy                '512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)')
74*2dadedceSVladimir Sementsov-Ogievskiy
75*2dadedceSVladimir Sementsov-Ogievskiy    def assertReadFailed(self, qemu_io_output):
76*2dadedceSVladimir Sementsov-Ogievskiy        self.assertEqual(filter_qemu_io(qemu_io_output).strip(),
77*2dadedceSVladimir Sementsov-Ogievskiy                         'read failed: Input/output error')
78*2dadedceSVladimir Sementsov-Ogievskiy
79*2dadedceSVladimir Sementsov-Ogievskiy    def assertConnectFailed(self, qemu_io_output):
80*2dadedceSVladimir Sementsov-Ogievskiy        self.assertEqual(filter_qemu_io(qemu_io_output).strip(),
81*2dadedceSVladimir Sementsov-Ogievskiy                         "can't open device " + nbd_uri +
82*2dadedceSVladimir Sementsov-Ogievskiy                         ": Requested export not available\n"
83*2dadedceSVladimir Sementsov-Ogievskiy                         "server reported: export 'exp' not present")
84*2dadedceSVladimir Sementsov-Ogievskiy
85*2dadedceSVladimir Sementsov-Ogievskiy    def do_test_connect_after_remove(self, mode=None):
86*2dadedceSVladimir Sementsov-Ogievskiy        args = ('-r', '-f', 'raw', '-c', 'read 0 512', nbd_uri)
87*2dadedceSVladimir Sementsov-Ogievskiy        self.assertReadOk(qemu_io(*args))
88*2dadedceSVladimir Sementsov-Ogievskiy
89*2dadedceSVladimir Sementsov-Ogievskiy        result = self.remove_export('exp', mode)
90*2dadedceSVladimir Sementsov-Ogievskiy        self.assert_qmp(result, 'return', {})
91*2dadedceSVladimir Sementsov-Ogievskiy
92*2dadedceSVladimir Sementsov-Ogievskiy        self.assertExportNotFound('exp')
93*2dadedceSVladimir Sementsov-Ogievskiy        self.assertConnectFailed(qemu_io(*args))
94*2dadedceSVladimir Sementsov-Ogievskiy
95*2dadedceSVladimir Sementsov-Ogievskiy    def test_connect_after_remove_default(self):
96*2dadedceSVladimir Sementsov-Ogievskiy        self.do_test_connect_after_remove()
97*2dadedceSVladimir Sementsov-Ogievskiy
98*2dadedceSVladimir Sementsov-Ogievskiy    def test_connect_after_remove_safe(self):
99*2dadedceSVladimir Sementsov-Ogievskiy        self.do_test_connect_after_remove('safe')
100*2dadedceSVladimir Sementsov-Ogievskiy
101*2dadedceSVladimir Sementsov-Ogievskiy    def test_connect_after_remove_force(self):
102*2dadedceSVladimir Sementsov-Ogievskiy        self.do_test_connect_after_remove('hard')
103*2dadedceSVladimir Sementsov-Ogievskiy
104*2dadedceSVladimir Sementsov-Ogievskiy    def do_test_remove_during_connect_safe(self, mode=None):
105*2dadedceSVladimir Sementsov-Ogievskiy        qio = QemuIoInteractive('-r', '-f', 'raw', nbd_uri)
106*2dadedceSVladimir Sementsov-Ogievskiy        self.assertReadOk(qio.cmd('read 0 512'))
107*2dadedceSVladimir Sementsov-Ogievskiy
108*2dadedceSVladimir Sementsov-Ogievskiy        result = self.remove_export('exp', mode)
109*2dadedceSVladimir Sementsov-Ogievskiy        self.assertExistingClients(result)
110*2dadedceSVladimir Sementsov-Ogievskiy
111*2dadedceSVladimir Sementsov-Ogievskiy        self.assertReadOk(qio.cmd('read 0 512'))
112*2dadedceSVladimir Sementsov-Ogievskiy
113*2dadedceSVladimir Sementsov-Ogievskiy        qio.close()
114*2dadedceSVladimir Sementsov-Ogievskiy
115*2dadedceSVladimir Sementsov-Ogievskiy        result = self.remove_export('exp', mode)
116*2dadedceSVladimir Sementsov-Ogievskiy        self.assert_qmp(result, 'return', {})
117*2dadedceSVladimir Sementsov-Ogievskiy
118*2dadedceSVladimir Sementsov-Ogievskiy        self.assertExportNotFound('exp')
119*2dadedceSVladimir Sementsov-Ogievskiy
120*2dadedceSVladimir Sementsov-Ogievskiy    def test_remove_during_connect_default(self):
121*2dadedceSVladimir Sementsov-Ogievskiy        self.do_test_remove_during_connect_safe()
122*2dadedceSVladimir Sementsov-Ogievskiy
123*2dadedceSVladimir Sementsov-Ogievskiy    def test_remove_during_connect_safe(self):
124*2dadedceSVladimir Sementsov-Ogievskiy        self.do_test_remove_during_connect_safe('safe')
125*2dadedceSVladimir Sementsov-Ogievskiy
126*2dadedceSVladimir Sementsov-Ogievskiy    def test_remove_during_connect_hard(self):
127*2dadedceSVladimir Sementsov-Ogievskiy        qio = QemuIoInteractive('-r', '-f', 'raw', nbd_uri)
128*2dadedceSVladimir Sementsov-Ogievskiy        self.assertReadOk(qio.cmd('read 0 512'))
129*2dadedceSVladimir Sementsov-Ogievskiy
130*2dadedceSVladimir Sementsov-Ogievskiy        result = self.remove_export('exp', 'hard')
131*2dadedceSVladimir Sementsov-Ogievskiy        self.assert_qmp(result, 'return', {})
132*2dadedceSVladimir Sementsov-Ogievskiy
133*2dadedceSVladimir Sementsov-Ogievskiy        self.assertReadFailed(qio.cmd('read 0 512'))
134*2dadedceSVladimir Sementsov-Ogievskiy        self.assertExportNotFound('exp')
135*2dadedceSVladimir Sementsov-Ogievskiy
136*2dadedceSVladimir Sementsov-Ogievskiy        qio.close()
137*2dadedceSVladimir Sementsov-Ogievskiy
138*2dadedceSVladimir Sementsov-Ogievskiy    def test_remove_during_connect_safe_hard(self):
139*2dadedceSVladimir Sementsov-Ogievskiy        qio = QemuIoInteractive('-r', '-f', 'raw', nbd_uri)
140*2dadedceSVladimir Sementsov-Ogievskiy        self.assertReadOk(qio.cmd('read 0 512'))
141*2dadedceSVladimir Sementsov-Ogievskiy
142*2dadedceSVladimir Sementsov-Ogievskiy        result = self.remove_export('exp', 'safe')
143*2dadedceSVladimir Sementsov-Ogievskiy        self.assertExistingClients(result)
144*2dadedceSVladimir Sementsov-Ogievskiy
145*2dadedceSVladimir Sementsov-Ogievskiy        self.assertReadOk(qio.cmd('read 0 512'))
146*2dadedceSVladimir Sementsov-Ogievskiy
147*2dadedceSVladimir Sementsov-Ogievskiy        result = self.remove_export('exp', 'hard')
148*2dadedceSVladimir Sementsov-Ogievskiy        self.assert_qmp(result, 'return', {})
149*2dadedceSVladimir Sementsov-Ogievskiy
150*2dadedceSVladimir Sementsov-Ogievskiy        self.assertExportNotFound('exp')
151*2dadedceSVladimir Sementsov-Ogievskiy        self.assertReadFailed(qio.cmd('read 0 512'))
152*2dadedceSVladimir Sementsov-Ogievskiy        qio.close()
153*2dadedceSVladimir Sementsov-Ogievskiy
154*2dadedceSVladimir Sementsov-Ogievskiy
155*2dadedceSVladimir Sementsov-Ogievskiyif __name__ == '__main__':
156*2dadedceSVladimir Sementsov-Ogievskiy    iotests.main()
157