]>
git.proxmox.com Git - mirror_qemu.git/blob - tests/qemu-iotests/163
4 # Tests for shrinking images
6 # Copyright (c) 2016-2017 Parallels International GmbH
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
22 import os
, random
, iotests
, struct
, qcow2
, sys
23 from iotests
import qemu_img
, qemu_io
, image_size
25 test_img
= os
.path
.join(iotests
.test_dir
, 'test.img')
26 check_img
= os
.path
.join(iotests
.test_dir
, 'check.img')
29 suff
= ['B', 'K', 'M', 'G', 'T']
30 return int(str[:-1]) * 1024**suff
.index(str[-1:])
32 class ShrinkBaseClass(iotests
.QMPTestCase
):
38 def __qcow2_check(self
, filename
):
40 entry_size
= 1 << entry_bits
41 l1_mask
= 0x00fffffffffffe00
42 div_roundup
= lambda n
, d
: (n
+ d
- 1) // d
44 def split_by_n(data
, n
):
45 for x
in range(0, len(data
), n
):
46 yield struct
.unpack('>Q', data
[x
:x
+ n
])[0] & l1_mask
48 def check_l1_table(h
, l1_data
):
49 l1_list
= list(split_by_n(l1_data
, entry_size
))
50 real_l1_size
= div_roundup(h
.size
,
51 1 << (h
.cluster_bits
*2 - entry_size
))
52 used
, unused
= l1_list
[:real_l1_size
], l1_list
[real_l1_size
:]
54 self
.assertTrue(len(used
) != 0, "Verifying l1 table content")
55 self
.assertFalse(any(unused
), "Verifying l1 table content")
57 def check_reftable(fd
, h
, reftable
):
58 for offset
in split_by_n(reftable
, entry_size
):
61 cluster
= fd
.read(1 << h
.cluster_bits
)
62 self
.assertTrue(any(cluster
), "Verifying reftable content")
64 with
open(filename
, "rb") as fd
:
65 h
= qcow2
.QcowHeader(fd
)
67 fd
.seek(h
.l1_table_offset
)
68 l1_table
= fd
.read(h
.l1_size
<< entry_bits
)
70 fd
.seek(h
.refcount_table_offset
)
71 reftable
= fd
.read(h
.refcount_table_clusters
<< h
.cluster_bits
)
73 check_l1_table(h
, l1_table
)
74 check_reftable(fd
, h
, reftable
)
76 def __raw_check(self
, filename
):
80 'qcow2' : __qcow2_check
,
85 if iotests
.imgfmt
== 'raw':
86 qemu_img('create', '-f', iotests
.imgfmt
, test_img
, self
.image_len
)
87 qemu_img('create', '-f', iotests
.imgfmt
, check_img
,
90 qemu_img('create', '-f', iotests
.imgfmt
,
91 '-o', 'cluster_size=' + self
.cluster_size
+
92 ',refcount_bits=' + self
.refcount_bits
,
93 test_img
, self
.image_len
)
94 qemu_img('create', '-f', iotests
.imgfmt
,
95 '-o', 'cluster_size=%s'% self
.cluster_size
,
96 check_img
, self
.shrink_size
)
97 qemu_io('-c', 'write -P 0xff 0 ' + self
.shrink_size
, check_img
)
103 def image_verify(self
):
104 self
.assertEqual(image_size(test_img
), image_size(check_img
),
105 "Verifying image size")
106 self
.image_check
[iotests
.imgfmt
](self
, test_img
)
108 if iotests
.imgfmt
== 'raw':
110 qemu_img('check', test_img
)
112 def test_empty_image(self
):
113 qemu_img('resize', '-f', iotests
.imgfmt
, '--shrink', test_img
,
116 qemu_io('-c', f
"read -P 0x00 0 {self.shrink_size}", test_img
)
120 def test_sequential_write(self
):
121 for offs
in range(0, size_to_int(self
.image_len
),
122 size_to_int(self
.chunk_size
)):
123 qemu_io('-c', 'write -P 0xff %d %s' % (offs
, self
.chunk_size
),
126 qemu_img('resize', '-f', iotests
.imgfmt
, '--shrink', test_img
,
129 qemu_img("compare", test_img
, check_img
)
133 def test_random_write(self
):
134 offs_list
= list(range(0, size_to_int(self
.image_len
),
135 size_to_int(self
.chunk_size
)))
136 random
.shuffle(offs_list
)
137 for offs
in offs_list
:
138 qemu_io('-c', 'write -P 0xff %d %s' % (offs
, self
.chunk_size
),
141 qemu_img('resize', '-f', iotests
.imgfmt
, '--shrink', test_img
,
144 qemu_img("compare", test_img
, check_img
)
148 class TestShrink512(ShrinkBaseClass
):
155 class TestShrink64K(ShrinkBaseClass
):
158 class TestShrink1M(ShrinkBaseClass
):
162 ShrinkBaseClass
= None
164 if __name__
== '__main__':
165 iotests
.main(supported_fmts
=['raw', 'qcow2'],
166 supported_protocols
=['file'],
167 unsupported_imgopts
=['compat'])