Statistics
| Branch: | Revision:

root / tests / qemu-iotests / 040 @ 915365a9

History | View | Annotate | Download (11.4 kB)

1 747051cd Jeff Cody
#!/usr/bin/env python
2 747051cd Jeff Cody
#
3 747051cd Jeff Cody
# Tests for image block commit.
4 747051cd Jeff Cody
#
5 747051cd Jeff Cody
# Copyright (C) 2012 IBM, Corp.
6 747051cd Jeff Cody
# Copyright (C) 2012 Red Hat, Inc.
7 747051cd Jeff Cody
#
8 747051cd Jeff Cody
# This program is free software; you can redistribute it and/or modify
9 747051cd Jeff Cody
# it under the terms of the GNU General Public License as published by
10 747051cd Jeff Cody
# the Free Software Foundation; either version 2 of the License, or
11 747051cd Jeff Cody
# (at your option) any later version.
12 747051cd Jeff Cody
#
13 747051cd Jeff Cody
# This program is distributed in the hope that it will be useful,
14 747051cd Jeff Cody
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15 747051cd Jeff Cody
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 747051cd Jeff Cody
# GNU General Public License for more details.
17 747051cd Jeff Cody
#
18 747051cd Jeff Cody
# You should have received a copy of the GNU General Public License
19 747051cd Jeff Cody
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 747051cd Jeff Cody
#
21 747051cd Jeff Cody
# Test for live block commit
22 747051cd Jeff Cody
# Derived from Image Streaming Test 030
23 747051cd Jeff Cody
24 747051cd Jeff Cody
import time
25 747051cd Jeff Cody
import os
26 747051cd Jeff Cody
import iotests
27 747051cd Jeff Cody
from iotests import qemu_img, qemu_io
28 747051cd Jeff Cody
import struct
29 6bf0d1f4 Jeff Cody
import errno
30 747051cd Jeff Cody
31 747051cd Jeff Cody
backing_img = os.path.join(iotests.test_dir, 'backing.img')
32 747051cd Jeff Cody
mid_img = os.path.join(iotests.test_dir, 'mid.img')
33 747051cd Jeff Cody
test_img = os.path.join(iotests.test_dir, 'test.img')
34 747051cd Jeff Cody
35 747051cd Jeff Cody
class ImageCommitTestCase(iotests.QMPTestCase):
36 747051cd Jeff Cody
    '''Abstract base class for image commit test cases'''
37 747051cd Jeff Cody
38 747051cd Jeff Cody
    def assert_no_active_commit(self):
39 747051cd Jeff Cody
        result = self.vm.qmp('query-block-jobs')
40 747051cd Jeff Cody
        self.assert_qmp(result, 'return', [])
41 747051cd Jeff Cody
42 747051cd Jeff Cody
    def cancel_and_wait(self, drive='drive0'):
43 747051cd Jeff Cody
        '''Cancel a block job and wait for it to finish'''
44 747051cd Jeff Cody
        result = self.vm.qmp('block-job-cancel', device=drive)
45 747051cd Jeff Cody
        self.assert_qmp(result, 'return', {})
46 747051cd Jeff Cody
47 747051cd Jeff Cody
        cancelled = False
48 747051cd Jeff Cody
        while not cancelled:
49 747051cd Jeff Cody
            for event in self.vm.get_qmp_events(wait=True):
50 747051cd Jeff Cody
                if event['event'] == 'BLOCK_JOB_CANCELLED':
51 747051cd Jeff Cody
                    self.assert_qmp(event, 'data/type', 'commit')
52 747051cd Jeff Cody
                    self.assert_qmp(event, 'data/device', drive)
53 747051cd Jeff Cody
                    cancelled = True
54 747051cd Jeff Cody
55 747051cd Jeff Cody
        self.assert_no_active_commit()
56 747051cd Jeff Cody
57 747051cd Jeff Cody
class TestSingleDrive(ImageCommitTestCase):
58 747051cd Jeff Cody
    image_len = 1 * 1024 * 1024
59 747051cd Jeff Cody
    test_len = 1 * 1024 * 256
60 747051cd Jeff Cody
61 747051cd Jeff Cody
    def setUp(self):
62 915365a9 Fam Zheng
        iotests.create_image(backing_img, TestSingleDrive.image_len)
63 747051cd Jeff Cody
        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, mid_img)
64 747051cd Jeff Cody
        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % mid_img, test_img)
65 747051cd Jeff Cody
        qemu_io('-c', 'write -P 0xab 0 524288', backing_img)
66 747051cd Jeff Cody
        qemu_io('-c', 'write -P 0xef 524288 524288', mid_img)
67 747051cd Jeff Cody
        self.vm = iotests.VM().add_drive(test_img)
68 747051cd Jeff Cody
        self.vm.launch()
69 747051cd Jeff Cody
70 747051cd Jeff Cody
    def tearDown(self):
71 747051cd Jeff Cody
        self.vm.shutdown()
72 747051cd Jeff Cody
        os.remove(test_img)
73 747051cd Jeff Cody
        os.remove(mid_img)
74 747051cd Jeff Cody
        os.remove(backing_img)
75 747051cd Jeff Cody
76 747051cd Jeff Cody
    def test_commit(self):
77 747051cd Jeff Cody
        self.assert_no_active_commit()
78 747051cd Jeff Cody
        result = self.vm.qmp('block-commit', device='drive0', top='%s' % mid_img)
79 747051cd Jeff Cody
        self.assert_qmp(result, 'return', {})
80 747051cd Jeff Cody
81 747051cd Jeff Cody
        completed = False
82 747051cd Jeff Cody
        while not completed:
83 747051cd Jeff Cody
            for event in self.vm.get_qmp_events(wait=True):
84 747051cd Jeff Cody
                if event['event'] == 'BLOCK_JOB_COMPLETED':
85 747051cd Jeff Cody
                    self.assert_qmp(event, 'data/type', 'commit')
86 747051cd Jeff Cody
                    self.assert_qmp(event, 'data/device', 'drive0')
87 747051cd Jeff Cody
                    self.assert_qmp(event, 'data/offset', self.image_len)
88 747051cd Jeff Cody
                    self.assert_qmp(event, 'data/len', self.image_len)
89 747051cd Jeff Cody
                    completed = True
90 747051cd Jeff Cody
91 747051cd Jeff Cody
        self.assert_no_active_commit()
92 747051cd Jeff Cody
        self.vm.shutdown()
93 747051cd Jeff Cody
94 747051cd Jeff Cody
        self.assertEqual(-1, qemu_io('-c', 'read -P 0xab 0 524288', backing_img).find("verification failed"))
95 747051cd Jeff Cody
        self.assertEqual(-1, qemu_io('-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed"))
96 747051cd Jeff Cody
97 747051cd Jeff Cody
    def test_device_not_found(self):
98 747051cd Jeff Cody
        result = self.vm.qmp('block-commit', device='nonexistent', top='%s' % mid_img)
99 747051cd Jeff Cody
        self.assert_qmp(result, 'error/class', 'DeviceNotFound')
100 747051cd Jeff Cody
101 747051cd Jeff Cody
    def test_top_same_base(self):
102 747051cd Jeff Cody
        self.assert_no_active_commit()
103 747051cd Jeff Cody
        result = self.vm.qmp('block-commit', device='drive0', top='%s' % backing_img, base='%s' % backing_img)
104 747051cd Jeff Cody
        self.assert_qmp(result, 'error/class', 'GenericError')
105 d5208c45 Jeff Cody
        self.assert_qmp(result, 'error/desc', 'Base \'%s\' not found' % backing_img)
106 747051cd Jeff Cody
107 747051cd Jeff Cody
    def test_top_invalid(self):
108 747051cd Jeff Cody
        self.assert_no_active_commit()
109 747051cd Jeff Cody
        result = self.vm.qmp('block-commit', device='drive0', top='badfile', base='%s' % backing_img)
110 747051cd Jeff Cody
        self.assert_qmp(result, 'error/class', 'GenericError')
111 747051cd Jeff Cody
        self.assert_qmp(result, 'error/desc', 'Top image file badfile not found')
112 747051cd Jeff Cody
113 747051cd Jeff Cody
    def test_base_invalid(self):
114 747051cd Jeff Cody
        self.assert_no_active_commit()
115 747051cd Jeff Cody
        result = self.vm.qmp('block-commit', device='drive0', top='%s' % mid_img, base='badfile')
116 747051cd Jeff Cody
        self.assert_qmp(result, 'error/class', 'GenericError')
117 747051cd Jeff Cody
        self.assert_qmp(result, 'error/desc', 'Base \'badfile\' not found')
118 747051cd Jeff Cody
119 747051cd Jeff Cody
    def test_top_is_active(self):
120 747051cd Jeff Cody
        self.assert_no_active_commit()
121 747051cd Jeff Cody
        result = self.vm.qmp('block-commit', device='drive0', top='%s' % test_img, base='%s' % backing_img)
122 747051cd Jeff Cody
        self.assert_qmp(result, 'error/class', 'GenericError')
123 747051cd Jeff Cody
        self.assert_qmp(result, 'error/desc', 'Top image as the active layer is currently unsupported')
124 747051cd Jeff Cody
125 747051cd Jeff Cody
    def test_top_and_base_reversed(self):
126 747051cd Jeff Cody
        self.assert_no_active_commit()
127 747051cd Jeff Cody
        result = self.vm.qmp('block-commit', device='drive0', top='%s' % backing_img, base='%s' % mid_img)
128 747051cd Jeff Cody
        self.assert_qmp(result, 'error/class', 'GenericError')
129 d5208c45 Jeff Cody
        self.assert_qmp(result, 'error/desc', 'Base \'%s\' not found' % mid_img)
130 747051cd Jeff Cody
131 747051cd Jeff Cody
    def test_top_omitted(self):
132 747051cd Jeff Cody
        self.assert_no_active_commit()
133 747051cd Jeff Cody
        result = self.vm.qmp('block-commit', device='drive0')
134 747051cd Jeff Cody
        self.assert_qmp(result, 'error/class', 'GenericError')
135 747051cd Jeff Cody
        self.assert_qmp(result, 'error/desc', "Parameter 'top' is missing")
136 747051cd Jeff Cody
137 6bf0d1f4 Jeff Cody
class TestRelativePaths(ImageCommitTestCase):
138 6bf0d1f4 Jeff Cody
    image_len = 1 * 1024 * 1024
139 6bf0d1f4 Jeff Cody
    test_len = 1 * 1024 * 256
140 6bf0d1f4 Jeff Cody
141 6bf0d1f4 Jeff Cody
    dir1 = "dir1"
142 6bf0d1f4 Jeff Cody
    dir2 = "dir2/"
143 6bf0d1f4 Jeff Cody
    dir3 = "dir2/dir3/"
144 6bf0d1f4 Jeff Cody
145 6bf0d1f4 Jeff Cody
    test_img = os.path.join(iotests.test_dir, dir3, 'test.img')
146 6bf0d1f4 Jeff Cody
    mid_img = "../mid.img"
147 6bf0d1f4 Jeff Cody
    backing_img = "../dir1/backing.img"
148 6bf0d1f4 Jeff Cody
149 6bf0d1f4 Jeff Cody
    backing_img_abs = os.path.join(iotests.test_dir, dir1, 'backing.img')
150 6bf0d1f4 Jeff Cody
    mid_img_abs = os.path.join(iotests.test_dir, dir2, 'mid.img')
151 6bf0d1f4 Jeff Cody
152 6bf0d1f4 Jeff Cody
    def setUp(self):
153 6bf0d1f4 Jeff Cody
        try:
154 6bf0d1f4 Jeff Cody
            os.mkdir(os.path.join(iotests.test_dir, self.dir1))
155 6bf0d1f4 Jeff Cody
            os.mkdir(os.path.join(iotests.test_dir, self.dir2))
156 6bf0d1f4 Jeff Cody
            os.mkdir(os.path.join(iotests.test_dir, self.dir3))
157 6bf0d1f4 Jeff Cody
        except OSError as exception:
158 6bf0d1f4 Jeff Cody
            if exception.errno != errno.EEXIST:
159 6bf0d1f4 Jeff Cody
                raise
160 915365a9 Fam Zheng
        iotests.create_image(self.backing_img_abs, TestRelativePaths.image_len)
161 6bf0d1f4 Jeff Cody
        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.backing_img_abs, self.mid_img_abs)
162 6bf0d1f4 Jeff Cody
        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.mid_img_abs, self.test_img)
163 6bf0d1f4 Jeff Cody
        qemu_img('rebase', '-u', '-b', self.backing_img, self.mid_img_abs)
164 6bf0d1f4 Jeff Cody
        qemu_img('rebase', '-u', '-b', self.mid_img, self.test_img)
165 6bf0d1f4 Jeff Cody
        qemu_io('-c', 'write -P 0xab 0 524288', self.backing_img_abs)
166 6bf0d1f4 Jeff Cody
        qemu_io('-c', 'write -P 0xef 524288 524288', self.mid_img_abs)
167 6bf0d1f4 Jeff Cody
        self.vm = iotests.VM().add_drive(self.test_img)
168 6bf0d1f4 Jeff Cody
        self.vm.launch()
169 6bf0d1f4 Jeff Cody
170 6bf0d1f4 Jeff Cody
    def tearDown(self):
171 6bf0d1f4 Jeff Cody
        self.vm.shutdown()
172 6bf0d1f4 Jeff Cody
        os.remove(self.test_img)
173 6bf0d1f4 Jeff Cody
        os.remove(self.mid_img_abs)
174 6bf0d1f4 Jeff Cody
        os.remove(self.backing_img_abs)
175 6bf0d1f4 Jeff Cody
        try:
176 6bf0d1f4 Jeff Cody
            os.rmdir(os.path.join(iotests.test_dir, self.dir1))
177 6bf0d1f4 Jeff Cody
            os.rmdir(os.path.join(iotests.test_dir, self.dir3))
178 6bf0d1f4 Jeff Cody
            os.rmdir(os.path.join(iotests.test_dir, self.dir2))
179 6bf0d1f4 Jeff Cody
        except OSError as exception:
180 6bf0d1f4 Jeff Cody
            if exception.errno != errno.EEXIST and exception.errno != errno.ENOTEMPTY:
181 6bf0d1f4 Jeff Cody
                raise
182 6bf0d1f4 Jeff Cody
183 6bf0d1f4 Jeff Cody
    def test_commit(self):
184 6bf0d1f4 Jeff Cody
        self.assert_no_active_commit()
185 6bf0d1f4 Jeff Cody
        result = self.vm.qmp('block-commit', device='drive0', top='%s' % self.mid_img)
186 6bf0d1f4 Jeff Cody
        self.assert_qmp(result, 'return', {})
187 6bf0d1f4 Jeff Cody
188 6bf0d1f4 Jeff Cody
        completed = False
189 6bf0d1f4 Jeff Cody
        while not completed:
190 6bf0d1f4 Jeff Cody
            for event in self.vm.get_qmp_events(wait=True):
191 6bf0d1f4 Jeff Cody
                if event['event'] == 'BLOCK_JOB_COMPLETED':
192 6bf0d1f4 Jeff Cody
                    self.assert_qmp(event, 'data/type', 'commit')
193 6bf0d1f4 Jeff Cody
                    self.assert_qmp(event, 'data/device', 'drive0')
194 6bf0d1f4 Jeff Cody
                    self.assert_qmp(event, 'data/offset', self.image_len)
195 6bf0d1f4 Jeff Cody
                    self.assert_qmp(event, 'data/len', self.image_len)
196 6bf0d1f4 Jeff Cody
                    completed = True
197 6bf0d1f4 Jeff Cody
198 6bf0d1f4 Jeff Cody
        self.assert_no_active_commit()
199 6bf0d1f4 Jeff Cody
        self.vm.shutdown()
200 6bf0d1f4 Jeff Cody
201 6bf0d1f4 Jeff Cody
        self.assertEqual(-1, qemu_io('-c', 'read -P 0xab 0 524288', self.backing_img_abs).find("verification failed"))
202 6bf0d1f4 Jeff Cody
        self.assertEqual(-1, qemu_io('-c', 'read -P 0xef 524288 524288', self.backing_img_abs).find("verification failed"))
203 6bf0d1f4 Jeff Cody
204 6bf0d1f4 Jeff Cody
    def test_device_not_found(self):
205 6bf0d1f4 Jeff Cody
        result = self.vm.qmp('block-commit', device='nonexistent', top='%s' % self.mid_img)
206 6bf0d1f4 Jeff Cody
        self.assert_qmp(result, 'error/class', 'DeviceNotFound')
207 6bf0d1f4 Jeff Cody
208 6bf0d1f4 Jeff Cody
    def test_top_same_base(self):
209 6bf0d1f4 Jeff Cody
        self.assert_no_active_commit()
210 6bf0d1f4 Jeff Cody
        result = self.vm.qmp('block-commit', device='drive0', top='%s' % self.mid_img, base='%s' % self.mid_img)
211 6bf0d1f4 Jeff Cody
        self.assert_qmp(result, 'error/class', 'GenericError')
212 6bf0d1f4 Jeff Cody
        self.assert_qmp(result, 'error/desc', 'Base \'%s\' not found' % self.mid_img)
213 6bf0d1f4 Jeff Cody
214 6bf0d1f4 Jeff Cody
    def test_top_invalid(self):
215 6bf0d1f4 Jeff Cody
        self.assert_no_active_commit()
216 6bf0d1f4 Jeff Cody
        result = self.vm.qmp('block-commit', device='drive0', top='badfile', base='%s' % self.backing_img)
217 6bf0d1f4 Jeff Cody
        self.assert_qmp(result, 'error/class', 'GenericError')
218 6bf0d1f4 Jeff Cody
        self.assert_qmp(result, 'error/desc', 'Top image file badfile not found')
219 6bf0d1f4 Jeff Cody
220 6bf0d1f4 Jeff Cody
    def test_base_invalid(self):
221 6bf0d1f4 Jeff Cody
        self.assert_no_active_commit()
222 6bf0d1f4 Jeff Cody
        result = self.vm.qmp('block-commit', device='drive0', top='%s' % self.mid_img, base='badfile')
223 6bf0d1f4 Jeff Cody
        self.assert_qmp(result, 'error/class', 'GenericError')
224 6bf0d1f4 Jeff Cody
        self.assert_qmp(result, 'error/desc', 'Base \'badfile\' not found')
225 6bf0d1f4 Jeff Cody
226 6bf0d1f4 Jeff Cody
    def test_top_is_active(self):
227 6bf0d1f4 Jeff Cody
        self.assert_no_active_commit()
228 6bf0d1f4 Jeff Cody
        result = self.vm.qmp('block-commit', device='drive0', top='%s' % self.test_img, base='%s' % self.backing_img)
229 6bf0d1f4 Jeff Cody
        self.assert_qmp(result, 'error/class', 'GenericError')
230 6bf0d1f4 Jeff Cody
        self.assert_qmp(result, 'error/desc', 'Top image as the active layer is currently unsupported')
231 6bf0d1f4 Jeff Cody
232 6bf0d1f4 Jeff Cody
    def test_top_and_base_reversed(self):
233 6bf0d1f4 Jeff Cody
        self.assert_no_active_commit()
234 6bf0d1f4 Jeff Cody
        result = self.vm.qmp('block-commit', device='drive0', top='%s' % self.backing_img, base='%s' % self.mid_img)
235 6bf0d1f4 Jeff Cody
        self.assert_qmp(result, 'error/class', 'GenericError')
236 6bf0d1f4 Jeff Cody
        self.assert_qmp(result, 'error/desc', 'Base \'%s\' not found' % self.mid_img)
237 6bf0d1f4 Jeff Cody
238 747051cd Jeff Cody
239 747051cd Jeff Cody
class TestSetSpeed(ImageCommitTestCase):
240 747051cd Jeff Cody
    image_len = 80 * 1024 * 1024 # MB
241 747051cd Jeff Cody
242 747051cd Jeff Cody
    def setUp(self):
243 747051cd Jeff Cody
        qemu_img('create', backing_img, str(TestSetSpeed.image_len))
244 747051cd Jeff Cody
        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, mid_img)
245 747051cd Jeff Cody
        qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % mid_img, test_img)
246 747051cd Jeff Cody
        self.vm = iotests.VM().add_drive(test_img)
247 747051cd Jeff Cody
        self.vm.launch()
248 747051cd Jeff Cody
249 747051cd Jeff Cody
    def tearDown(self):
250 747051cd Jeff Cody
        self.vm.shutdown()
251 747051cd Jeff Cody
        os.remove(test_img)
252 747051cd Jeff Cody
        os.remove(mid_img)
253 747051cd Jeff Cody
        os.remove(backing_img)
254 747051cd Jeff Cody
255 747051cd Jeff Cody
    def test_set_speed(self):
256 747051cd Jeff Cody
        self.assert_no_active_commit()
257 747051cd Jeff Cody
258 747051cd Jeff Cody
        result = self.vm.qmp('block-commit', device='drive0', top=mid_img, speed=1024 * 1024)
259 747051cd Jeff Cody
        self.assert_qmp(result, 'return', {})
260 747051cd Jeff Cody
261 747051cd Jeff Cody
        # Ensure the speed we set was accepted
262 747051cd Jeff Cody
        result = self.vm.qmp('query-block-jobs')
263 747051cd Jeff Cody
        self.assert_qmp(result, 'return[0]/device', 'drive0')
264 747051cd Jeff Cody
        self.assert_qmp(result, 'return[0]/speed', 1024 * 1024)
265 747051cd Jeff Cody
266 747051cd Jeff Cody
        self.cancel_and_wait()
267 747051cd Jeff Cody
268 747051cd Jeff Cody
269 747051cd Jeff Cody
if __name__ == '__main__':
270 747051cd Jeff Cody
    iotests.main(supported_fmts=['qcow2', 'qed'])