Merge lp:~milo/linaro-image-tools/bug1004199 into lp:linaro-image-tools/11.11

Proposed by Milo Casagrande
Status: Merged
Approved by: Данило Шеган
Approved revision: 527
Merge reported by: Milo Casagrande
Merged at revision: not available
Proposed branch: lp:~milo/linaro-image-tools/bug1004199
Merge into: lp:linaro-image-tools/11.11
Diff against target: 314 lines (+91/-44)
2 files modified
linaro_image_tools/media_create/partitions.py (+34/-12)
linaro_image_tools/media_create/tests/test_media_create.py (+57/-32)
To merge this branch: bzr merge lp:~milo/linaro-image-tools/bug1004199
Reviewer Review Type Date Requested Status
Данило Шеган (community) Approve
Review via email: mp+108747@code.launchpad.net

Description of the change

Hello,

the proposed branch should fix the image size problem.

Thanks to Michael suggestion, and after a brief chat with him on IRC, I reworked the convert_size_to_byte method to address the 1MiB multiple image size problem: I kept only one exit point for the method; added the final check on the size just before returning the value; added the comparable value at the beginning of the file as a constant named ROUND_IMAGE_TO; imported the math.floor function since the final check relies on that.

I added also a new method, _check_min_size, to ensure that we have at least 1MiB image size (this was the bit discussed on IRC).

I reworked and adapted a little bit the tests too. I added a new test for the exception that was not tested before; added a new one for the default size and fixed the other tests in order to address the changes in the function. One test has been removed since it was not really relevant anymore.

Cheers.

To post a comment you must log in.
Revision history for this message
Данило Шеган (danilo) wrote :
Download full text (4.9 KiB)

Hi Milo,

Thanks for working on this fix. Overall, it looks great. A few
suggestions are inline, though.

У уто, 05. 06 2012. у 13:53 +0000, Milo Casagrande пише:

> the proposed branch should fix the image size problem.
>
> Thanks to Michael suggestion, and after a brief chat with him on IRC, I
> reworked the convert_size_to_byte method to address the 1MiB multiple
> image size problem: I kept only one exit point for the method; added
> the final check on the size just before returning the value; added the
> comparable value at the beginning of the file as a constant named
> ROUND_IMAGE_TO; imported the math.floor function since the final check
> relies on that.

With these changes, the name of the method might not make that much
sense anymore. It should be

 round_to_megs_ensure_larger_than_one_meg_and_convert_to_bytes :)

Perhaps use something that describes the nature of the method is now
more appropriate (i.e. "get_partition_size_in_bytes" or something
similar).

> I added also a new method, _check_min_size, to ensure that we have at least 1MiB image size (this was the bit discussed on IRC).

It would be good to add a few minimal tests for it as well :)

> I reworked and adapted a little bit the tests too. I added a new test
> for the exception that was not tested before; added a new one for the
> default size and fixed the other tests in order to address the changes
> in the function. One test has been removed since it was not really
> relevant anymore.

They look great, thanks.

> разлике међу датотекама прилог (review-diff.txt)
> === modified file 'linaro_image_tools/media_create/partitions.py'
...
> @@ -45,6 +45,9 @@
> # Max number of attempts to sleep (total sleep time in seconds =
> # 1+2+...+MAX_TTS)
> MAX_TTS = 10
> +# Image size should be a multiple of 1MiB, expressed in bytes. This is also
> +# the minimum image size possible.
> +ROUND_IMAGE_TO = 2 ** 20

I'd rather if we express this as two separate values, even if one is
defined through the other. Eg.

ROUND_IMAGE_TO = 2 ** 20
MIN_IMAGE_SIZE = ROUND_IMAGE_TO

> @@ -481,11 +484,12 @@
> def convert_size_to_bytes(size):
> """Convert a size string in Kbytes, Mbytes or Gbytes to bytes."""

It'd be nice to extend this to document the new features (min size,
rounding).

>...
> + # Guarantee that is a multiple of 1MiB, defined in ROUND_IMAGE_TO
> + real_size = _check_min_size(floor(real_size / ROUND_IMAGE_TO) *
> + ROUND_IMAGE_TO)

Better way to do the rounding is always to add half of ROUND_IMAGE_TO
and then simply round() it. This will ensure that you've got enough
space at all times.

Eg.

  round((real_size + ROUND_IMAGE_TO/2)/ROUND_IMAGE_TO) * ROUND_IMAGE_TO

will give you an image size which will be able to fit the requested
number of KBs or MBs (eg. asking for '1024.4K' will give you 2MB which
can really fit the requested number of kilobytes; it'd be even worse if
you ask for 1500K and get 1MB).

> return int(round(real_size))
>
>
> +def _check_min_size(size):
> + """Check that the image size is at least 1MiB (expressed in bytes)."""

Hard-coding a value here which is not really hard-coded doesn't make
much sense. ...

Read more...

review: Needs Fixing
Revision history for this message
Milo Casagrande (milo) wrote :
Download full text (4.0 KiB)

Hello Danilo,

On Wed, Jun 6, 2012 at 9:55 AM, Данило Шеган <email address hidden> wrote:
>
> With these changes, the name of the method might not make that much
> sense anymore.  It should be
>
>  round_to_megs_ensure_larger_than_one_meg_and_convert_to_bytes :)
>
> Perhaps use something that describes the nature of the method is now
> more appropriate (i.e. "get_partition_size_in_bytes" or something
> similar).

I will use your suggestion for the method name. :-)

>> I added also a new method, _check_min_size, to ensure that we have at least 1MiB image size (this was the bit discussed on IRC).
>
> It would be good to add a few minimal tests for it as well :)

Added two new tests: one for a smaller value, one for a bigger one.
I added also a comment on _check_min_size, in order to avoid testing
passing size as a string: in the function "size" is a number. I used
"@param", is it the blessed way or is it better to use ":param"?

> I'd rather if we express this as two separate values, even if one is
> defined through the other. Eg.
>
> ROUND_IMAGE_TO = 2 ** 20
> MIN_IMAGE_SIZE = ROUND_IMAGE_TO

Fixed.

>> @@ -481,11 +484,12 @@
>>  def convert_size_to_bytes(size):
>>      """Convert a size string in Kbytes, Mbytes or Gbytes to bytes."""
>
> It'd be nice to extend this to document the new features (min size,
> rounding).

Added a small description of what is happening, another note on this
follows on the comment below.

>>...
>> +    # Guarantee that is a multiple of 1MiB, defined in ROUND_IMAGE_TO
>> +    real_size = _check_min_size(floor(real_size / ROUND_IMAGE_TO) *
>> +                                ROUND_IMAGE_TO)
>
> Better way to do the rounding is always to add half of ROUND_IMAGE_TO
> and then simply round() it.  This will ensure that you've got enough
> space at all times.
> Eg.
>
>  round((real_size + ROUND_IMAGE_TO/2)/ROUND_IMAGE_TO) * ROUND_IMAGE_TO
>
> will give you an image size which will be able to fit the requested
> number of KBs or MBs (eg. asking for '1024.4K' will give you 2MB which
> can really fit the requested number of kilobytes; it'd be even worse if
> you ask for 1500K and get 1MB).

Hmm... OK, got your point to have always enough space, although in
this case if we ask for '1M' we receive back a size of 2MiB, and
always a little bit more for all the other values. I hope it is not an
issue with space on users side if they want a better precision.

Changing this introduced a regression on another test, specifically
'test_setup_partitions_for_image_file' that tests 'setup_partitions':
image size in bytes here is used with 'dd'.

I changed the behavior of the converting functions, saying also that
the conversion in bytes is "deliberaltey inaccurate" (in the sense
that we add a small delta).
Fixed now, and also the tests and their values. :-)

>> +def _check_min_size(size):
>> +    """Check that the image size is at least 1MiB (expressed in bytes)."""
>
> Hard-coding a value here which is not really hard-coded doesn't make
> much sense.  Why not make it 'is at least MIN_IMAGE_SIZE bytes.'
> instead?

Fixed.

>> === modified file 'linaro_image_tools/media_create/tests/test_media_create.py'
>
> These are not of your doing, bu...

Read more...

Revision history for this message
Данило Шеган (danilo) wrote :

Hi Milo,

Sorry for taking this long to respond: it got off my radar. Please feel
free to ping and poke me to be faster about finishing a review for you.

Thanks for all the fixes, it looks much better now. Just a few small
notes now.

У сре, 06. 06 2012. у 16:22 +0000, Milo Casagrande пише:

> Added two new tests: one for a smaller value, one for a bigger one.
> I added also a comment on _check_min_size, in order to avoid testing
> passing size as a string: in the function "size" is a number. I used
> "@param", is it the blessed way or is it better to use ":param"?

It's better to use :param since it's used in the rest of the code-base.

> Hmm... OK, got your point to have always enough space, although in
> this case if we ask for '1M' we receive back a size of 2MiB, and
> always a little bit more for all the other values. I hope it is not an
> issue with space on users side if they want a better precision.

Let's fix that as well :)

Would doing "- 0.5" (in bytes) before division by ROUND_TO_SIZE and
rounding help with that without breaking anything else? Will this
simplistic formula work for a case where we ask for 1.000001M (when we
do want 2M)?

To clarify the algorithm I proposed though, the "trick" of adding
ROUND_TO_SIZE/2 is a common approach to round up ("ceil"), and that's
all we are doing. So, the docstring should only mention rounding up,
and we should fix it up so that's all it does. Perhaps we can instead
do a math.ceil which I wanted to avoid for no particular reason other
than looking smarter than I am :)

> Changing this introduced a regression on another test, specifically
> 'test_setup_partitions_for_image_file' that tests 'setup_partitions':
> image size in bytes here is used with 'dd'.

Right, we might need to update a test or two with these changes.

> I changed the behavior of the converting functions, saying also that
> the conversion in bytes is "deliberaltey inaccurate" (in the sense
> that we add a small delta).

I'd rather we fix the problem and just describe it as "we round up and
in multiples of 1MB" or something.

Cheers,
Danilo

Revision history for this message
Milo Casagrande (milo) wrote :

Hello Danilo,

thanks for the review!
The final bits for the conversion should now be fixed.

We will use math.ceil, and return the correct rounded-up size for the image.
I added also a new test, based on your example, so that we can see the
difference and the correctness of asking 1M (that will return exactly
1MiB) compared to asking 1.0000001M (that will return 2MiB).

There might be also other changes, since I merged from trunk.
Ciao.

--
Milo Casagrande
Infrastructure Engineer
Linaro.org <www.linaro.org> │ Open source software for ARM SoCs

Revision history for this message
Данило Шеган (danilo) wrote :

Looks good, thanks for all the effort you expended on this bug :)

review: Approve
Revision history for this message
Данило Шеган (danilo) wrote :

Actually, we should simply use ceil, and get rid of the + 0.5 trick altogether.

I.e.

 real_size = _check_min_size(ceil(real_size / ROUND_IMAGE_TO) * ROUND_IMAGE_TO))

review: Needs Fixing
527. By Milo Casagrande

Removed round function.

Revision history for this message
Milo Casagrande (milo) wrote :

On Wed, Jun 13, 2012 at 3:33 PM, Данило Шеган <email address hidden> wrote:
>
> Actually, we should simply use ceil, and get rid of the + 0.5 trick altogether.
>
> I.e.
>
>  real_size = _check_min_size(ceil(real_size / ROUND_IMAGE_TO) * ROUND_IMAGE_TO))

With latest push I removed the "round" function, keeping only the
"int" conversion here, instead of doing it in the return statement,
sice we will execute _check_min_size anyway with MIN_IMAGE_SIZE that
is an int.

--
Milo Casagrande
Infrastructure Engineer
Linaro.org <www.linaro.org> │ Open source software for ARM SoCs

Revision history for this message
Данило Шеган (danilo) wrote :

Looks good, thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'linaro_image_tools/media_create/partitions.py'
2--- linaro_image_tools/media_create/partitions.py 2012-05-09 21:25:20 +0000
3+++ linaro_image_tools/media_create/partitions.py 2012-06-13 13:45:20 +0000
4@@ -17,15 +17,16 @@
5 # You should have received a copy of the GNU General Public License
6 # along with Linaro Image Tools. If not, see <http://www.gnu.org/licenses/>.
7
8+from contextlib import contextmanager
9+from math import ceil
10 import atexit
11-from contextlib import contextmanager
12+import dbus
13 import glob
14 import logging
15 import re
16 import subprocess
17 import time
18
19-import dbus
20 from parted import (
21 Device,
22 Disk,
23@@ -35,7 +36,6 @@
24
25 from linaro_image_tools import cmd_runner
26
27-
28 HEADS = 128
29 SECTORS = 32
30 SECTOR_SIZE = 512 # bytes
31@@ -45,13 +45,17 @@
32 # Max number of attempts to sleep (total sleep time in seconds =
33 # 1+2+...+MAX_TTS)
34 MAX_TTS = 10
35+# Image size should be a multiple of 1MiB, expressed in bytes. This is also
36+# the minimum image size possible.
37+ROUND_IMAGE_TO = 2 ** 20
38+MIN_IMAGE_SIZE = ROUND_IMAGE_TO
39
40
41 def setup_android_partitions(board_config, media, image_size, bootfs_label,
42 should_create_partitions, should_align_boot_part=False):
43 cylinders = None
44 if not media.is_block_device:
45- image_size_in_bytes = convert_size_to_bytes(image_size)
46+ image_size_in_bytes = get_partition_size_in_bytes(image_size)
47 cylinders = image_size_in_bytes / CYLINDER_SIZE
48 proc = cmd_runner.run(
49 ['dd', 'of=%s' % media.path,
50@@ -131,7 +135,7 @@
51 """
52 cylinders = None
53 if not media.is_block_device:
54- image_size_in_bytes = convert_size_to_bytes(image_size)
55+ image_size_in_bytes = get_partition_size_in_bytes(image_size)
56 cylinders = image_size_in_bytes / CYLINDER_SIZE
57 proc = cmd_runner.run(
58 ['dd', 'of=%s' % media.path,
59@@ -478,14 +482,20 @@
60 path, 'DeviceFile', dbus_interface=DBUS_PROPERTIES))
61
62
63-def convert_size_to_bytes(size):
64- """Convert a size string in Kbytes, Mbytes or Gbytes to bytes."""
65+def get_partition_size_in_bytes(size):
66+ """Convert a size string in Kbytes, Mbytes or Gbytes to bytes.
67+
68+ The conversion rounds-up the size to the nearest MiB, considering a minimum
69+ size of MIN_IMAGE_SIZE bytes. The conversion always assures to have a big
70+ enough size for the partition.
71+ """
72 unit = size[-1].upper()
73+ real_size = float(size[:-1])
74+
75 # no unit? (ends with a digit)
76 if unit in '0123456789':
77- return int(round(float(size)))
78- real_size = float(size[:-1])
79- if unit == 'K':
80+ real_size = float(size)
81+ elif unit == 'K':
82 real_size = real_size * 1024
83 elif unit == 'M':
84 real_size = real_size * 1024 * 1024
85@@ -494,8 +504,20 @@
86 else:
87 raise ValueError("Unknown size format: %s. Use K[bytes], M[bytes] "
88 "or G[bytes]" % size)
89-
90- return int(round(real_size))
91+ # Guarantee that is a multiple of ROUND_IMAGE_TO
92+ real_size = _check_min_size(int(ceil(real_size / ROUND_IMAGE_TO) *
93+ ROUND_IMAGE_TO))
94+ return real_size
95+
96+
97+def _check_min_size(size):
98+ """Check that the image size is at least MIN_IMAGE_SIZE bytes.
99+
100+ :param size: The size of the image to check, as a number.
101+ """
102+ if (size < MIN_IMAGE_SIZE):
103+ size = MIN_IMAGE_SIZE
104+ return size
105
106
107 def run_sfdisk_commands(commands, heads, sectors, cylinders, device,
108
109=== modified file 'linaro_image_tools/media_create/tests/test_media_create.py'
110--- linaro_image_tools/media_create/tests/test_media_create.py 2012-06-07 13:12:42 +0000
111+++ linaro_image_tools/media_create/tests/test_media_create.py 2012-06-13 13:45:20 +0000
112@@ -38,11 +38,11 @@
113 from linaro_image_tools import cmd_runner
114 import linaro_image_tools.media_create
115 from linaro_image_tools.media_create import (
116+ android_boards,
117+ boards,
118 check_device,
119- boards,
120 partitions,
121 rootfs,
122- android_boards,
123 )
124 from linaro_image_tools.media_create.boards import (
125 SECTOR_SIZE,
126@@ -64,8 +64,8 @@
127 BoardConfig,
128 )
129 from linaro_image_tools.media_create.android_boards import (
130+ AndroidSnowballEmmcConfig,
131 android_board_configs,
132- AndroidSnowballEmmcConfig,
133 )
134 from linaro_image_tools.media_create.chroot_utils import (
135 copy_file,
136@@ -79,23 +79,25 @@
137 )
138 from linaro_image_tools.media_create.partitions import (
139 HEADS,
140+ MIN_IMAGE_SIZE,
141+ Media,
142 SECTORS,
143+ _check_min_size,
144+ _get_device_file_for_partition_number,
145+ _parse_blkid_output,
146+ calculate_android_partition_size_and_offset,
147 calculate_partition_size_and_offset,
148- calculate_android_partition_size_and_offset,
149- convert_size_to_bytes,
150 create_partitions,
151 ensure_partition_is_not_mounted,
152+ get_android_loopback_devices,
153 get_boot_and_root_loopback_devices,
154- get_android_loopback_devices,
155 get_boot_and_root_partitions_for_media,
156- Media,
157+ get_partition_size_in_bytes,
158+ get_uuid,
159 partition_mounted,
160 run_sfdisk_commands,
161 setup_partitions,
162- get_uuid,
163- _parse_blkid_output,
164 wait_partition_to_settle,
165- _get_device_file_for_partition_number,
166 )
167 from linaro_image_tools.media_create.rootfs import (
168 append_to_fstab,
169@@ -104,8 +106,8 @@
170 move_contents,
171 populate_rootfs,
172 rootfs_mount_options,
173+ update_network_interfaces,
174 write_data_to_protected_file,
175- update_network_interfaces,
176 )
177 from linaro_image_tools.media_create.tests.fixtures import (
178 CreateTarballFixture,
179@@ -492,7 +494,9 @@
180
181 class config(BoardConfig):
182 pass
183- self.assertRaises(AssertionError, config.set_metadata, 'ahwpack.tar.gz')
184+ self.assertRaises(AssertionError,
185+ config.set_metadata,
186+ 'ahwpack.tar.gz')
187
188
189 class TestGetMLOFile(TestCaseWithFixtures):
190@@ -767,8 +771,11 @@
191 uboot_file = os.path.join(uboot_dir, 'u-boot.bin')
192 uboot_relative_file = uboot_file.replace(self.tempdir, '')
193 with open(cfg_file, 'w') as f:
194- f.write('%s %s %i %#x %s\n' % ('NORMAL', uboot_relative_file, 0,
195- 0xBA0000, '9'))
196+ f.write('%s %s %i %#x %s\n' % ('NORMAL',
197+ uboot_relative_file,
198+ 0,
199+ 0xBA0000,
200+ '9'))
201 with open(uboot_file, 'w') as f:
202 file_info = boards.SnowballEmmcConfig.get_file_info(
203 self.tempdir, self.temp_bootdir_path)
204@@ -781,8 +788,10 @@
205 with open(cfg_file, 'w') as f:
206 f.write('%s %s %i %#x %s\n' % ('NORMAL', 'u-boot.bin', 0,
207 0xBA0000, '9'))
208- self.assertRaises(AssertionError, boards.SnowballEmmcConfig.get_file_info,
209- self.tempdir, self.temp_bootdir_path)
210+ self.assertRaises(AssertionError,
211+ boards.SnowballEmmcConfig.get_file_info,
212+ self.tempdir,
213+ self.temp_bootdir_path)
214
215 def test_file_name_size(self):
216 ''' Test using a to large toc file '''
217@@ -961,7 +970,8 @@
218 super(TestBootSteps, self).setUp()
219 self.funcs_calls = []
220 self.mock_all_boards_funcs()
221- linaro_image_tools.media_create.boards.BoardConfig.hwpack_format = '1.0'
222+ linaro_image_tools.media_create.boards.BoardConfig.hwpack_format = \
223+ '1.0'
224
225 def mock_all_boards_funcs(self):
226 """Mock functions of boards module with a call tracer."""
227@@ -1037,8 +1047,8 @@
228 lambda: '1.0')
229 self.make_boot_files(boards.SMDKV310Config)
230 expected = [
231- 'install_samsung_boot_loader', 'make_flashable_env', '_dd', 'make_uImage',
232- 'make_uInitrd', 'make_boot_script']
233+ 'install_samsung_boot_loader', 'make_flashable_env', '_dd',
234+ 'make_uImage', 'make_uInitrd', 'make_boot_script']
235 self.assertEqual(expected, self.funcs_calls)
236
237 def test_origen_steps(self):
238@@ -1058,8 +1068,8 @@
239 lambda: '1.0')
240 self.make_boot_files(boards.OrigenConfig)
241 expected = [
242- 'install_samsung_boot_loader', 'make_flashable_env', '_dd', 'make_uImage',
243- 'make_uInitrd', 'make_boot_script']
244+ 'install_samsung_boot_loader', 'make_flashable_env', '_dd',
245+ 'make_uImage', 'make_uInitrd', 'make_boot_script']
246 self.assertEqual(expected, self.funcs_calls)
247
248 def test_ux500_steps(self):
249@@ -2424,32 +2434,46 @@
250 '98367,-,E\n98367,65536,L\n294975,131072,L\n' \
251 '426047,,,-', '%s' % self.android_image_size)
252
253+ def test_check_min_size_small(self):
254+ """Check that we get back the minimum size as expeceted."""
255+ self.assertEqual(MIN_IMAGE_SIZE, _check_min_size(12345))
256+
257+ def test_check_min_size_big(self):
258+ """Check that we get back the same value we pass."""
259+ self.assertEqual(MIN_IMAGE_SIZE * 3, _check_min_size(3145728))
260+
261+ def test_convert_size_wrong_suffix(self):
262+ self.assertRaises(ValueError, get_partition_size_in_bytes, "123456H")
263+
264 def test_convert_size_no_suffix(self):
265- self.assertEqual(524288, convert_size_to_bytes('524288'))
266+ self.assertEqual(2 ** 20, get_partition_size_in_bytes('123456'))
267+
268+ def test_convert_size_one_mbyte(self):
269+ self.assertEqual(2 ** 20, get_partition_size_in_bytes('1M'))
270
271 def test_convert_size_in_kbytes_to_bytes(self):
272- self.assertEqual(512 * 1024, convert_size_to_bytes('512K'))
273+ self.assertEqual(2 * 2 ** 20, get_partition_size_in_bytes('2048K'))
274
275 def test_convert_size_in_mbytes_to_bytes(self):
276- self.assertEqual(100 * 1024 ** 2, convert_size_to_bytes('100M'))
277+ self.assertEqual(100 * 2 ** 20, get_partition_size_in_bytes('100M'))
278
279 def test_convert_size_in_gbytes_to_bytes(self):
280- self.assertEqual(12 * 1024 ** 3, convert_size_to_bytes('12G'))
281+ self.assertEqual(12 * 2 ** 30, get_partition_size_in_bytes('12G'))
282
283 def test_convert_size_float_no_suffix(self):
284- self.assertEqual(1539, convert_size_to_bytes('1539.49'))
285-
286- def test_convert_size_float_round_up(self):
287- self.assertEqual(1540, convert_size_to_bytes('1539.50'))
288+ self.assertEqual(3 * 2 ** 20, get_partition_size_in_bytes('2348576.91'))
289
290 def test_convert_size_float_in_kbytes_to_bytes(self):
291- self.assertEqual(int(round(234.8 * 1024)), convert_size_to_bytes('234.8K'))
292+ self.assertEqual(3 * 2 ** 20, get_partition_size_in_bytes('2345.8K'))
293+
294+ def test_convert_size_float_in_mbytes_to_bytes_double(self):
295+ self.assertEqual(2 * 2 ** 20, get_partition_size_in_bytes('1.0000001M'))
296
297 def test_convert_size_float_in_mbytes_to_bytes(self):
298- self.assertEqual(int(round(876.123 * 1024 ** 2)), convert_size_to_bytes('876.123M'))
299+ self.assertEqual(877 * 2 ** 20, get_partition_size_in_bytes('876.123M'))
300
301 def test_convert_size_float_in_gbytes_to_bytes(self):
302- self.assertEqual(int(round(1.9 * 1024 ** 3)), convert_size_to_bytes('1.9G'))
303+ self.assertEqual(1946 * 2 ** 20, get_partition_size_in_bytes('1.9G'))
304
305 def test_calculate_partition_size_and_offset(self):
306 tmpfile = self._create_tmpfile()
307@@ -3400,6 +3424,7 @@
308
309 # Ensure the list of cleanup functions gets cleared to make sure tests
310 # don't interfere with one another.
311+
312 def clear_atexits():
313 linaro_image_tools.media_create.chroot_utils.local_atexit = []
314 self.addCleanup(clear_atexits)

Subscribers

People subscribed via source and target branches