3 # Tests for qmp command nbd-server-remove.
5 # Copyright (c) 2017 Virtuozzo International GmbH
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 from iotests
import qemu_img
, qemu_io
, filter_qemu_io
, QemuIoInteractive
28 nbd_uri
= 'nbd+unix:///exp?socket=' + nbd_sock
29 disk
= os
.path
.join(iotests
.test_dir
, 'disk')
32 class TestNbdServerRemove(iotests
.QMPTestCase
):
34 qemu_img('create', '-f', iotests
.imgfmt
, disk
, '1M')
36 self
.vm
= iotests
.VM().add_drive(disk
)
46 result
= self
.vm
.qmp('nbd-server-start', addr
=address
)
47 self
.assert_qmp(result
, 'return', {})
48 result
= self
.vm
.qmp('nbd-server-add', device
='drive0', name
='exp')
49 self
.assert_qmp(result
, 'return', {})
56 def remove_export(self
, name
, mode
=None):
58 return self
.vm
.qmp('nbd-server-remove', name
=name
)
60 return self
.vm
.qmp('nbd-server-remove', name
=name
, mode
=mode
)
62 def assertExportNotFound(self
, name
):
63 result
= self
.vm
.qmp('nbd-server-remove', name
=name
)
64 self
.assert_qmp(result
, 'error/desc', "Export 'exp' is not found")
66 def assertExistingClients(self
, result
):
67 self
.assert_qmp(result
, 'error/desc', "export 'exp' still in use")
69 def assertReadOk(self
, qemu_io_output
):
71 filter_qemu_io(qemu_io_output
).strip(),
72 'read 512/512 bytes at offset 0\n' +
73 '512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)')
75 def assertReadFailed(self
, qemu_io_output
):
76 self
.assertEqual(filter_qemu_io(qemu_io_output
).strip(),
77 'read failed: Input/output error')
79 def assertConnectFailed(self
, qemu_io_output
):
80 self
.assertEqual(filter_qemu_io(qemu_io_output
).strip(),
81 "can't open device " + nbd_uri
+
82 ": Requested export not available\n"
83 "server reported: export 'exp' not present")
85 def do_test_connect_after_remove(self
, mode
=None):
86 args
= ('-r', '-f', 'raw', '-c', 'read 0 512', nbd_uri
)
87 self
.assertReadOk(qemu_io(*args
))
89 result
= self
.remove_export('exp', mode
)
90 self
.assert_qmp(result
, 'return', {})
92 self
.assertExportNotFound('exp')
93 self
.assertConnectFailed(qemu_io(*args
))
95 def test_connect_after_remove_default(self
):
96 self
.do_test_connect_after_remove()
98 def test_connect_after_remove_safe(self
):
99 self
.do_test_connect_after_remove('safe')
101 def test_connect_after_remove_force(self
):
102 self
.do_test_connect_after_remove('hard')
104 def do_test_remove_during_connect_safe(self
, mode
=None):
105 qio
= QemuIoInteractive('-r', '-f', 'raw', nbd_uri
)
106 self
.assertReadOk(qio
.cmd('read 0 512'))
108 result
= self
.remove_export('exp', mode
)
109 self
.assertExistingClients(result
)
111 self
.assertReadOk(qio
.cmd('read 0 512'))
115 result
= self
.remove_export('exp', mode
)
116 self
.assert_qmp(result
, 'return', {})
118 self
.assertExportNotFound('exp')
120 def test_remove_during_connect_default(self
):
121 self
.do_test_remove_during_connect_safe()
123 def test_remove_during_connect_safe(self
):
124 self
.do_test_remove_during_connect_safe('safe')
126 def test_remove_during_connect_hard(self
):
127 qio
= QemuIoInteractive('-r', '-f', 'raw', nbd_uri
)
128 self
.assertReadOk(qio
.cmd('read 0 512'))
130 result
= self
.remove_export('exp', 'hard')
131 self
.assert_qmp(result
, 'return', {})
133 self
.assertReadFailed(qio
.cmd('read 0 512'))
134 self
.assertExportNotFound('exp')
138 def test_remove_during_connect_safe_hard(self
):
139 qio
= QemuIoInteractive('-r', '-f', 'raw', nbd_uri
)
140 self
.assertReadOk(qio
.cmd('read 0 512'))
142 result
= self
.remove_export('exp', 'safe')
143 self
.assertExistingClients(result
)
145 self
.assertReadOk(qio
.cmd('read 0 512'))
147 result
= self
.remove_export('exp', 'hard')
148 self
.assert_qmp(result
, 'return', {})
150 self
.assertExportNotFound('exp')
151 self
.assertReadFailed(qio
.cmd('read 0 512'))
155 if __name__
== '__main__':