From 553b0ec49bc64fc4b7df4358cd31396a87276d2b Mon Sep 17 00:00:00 2001 From: Gilad Arnold Date: Sat, 26 Jan 2013 01:00:39 -0800 Subject: Update payload library + command-line tool An initial implementation of a Python module for parsing, checking and applying a Chrome OS update payload. Comes with a command-line tool (paycheck.py) for applying such operations on payload files, and a test script (test_paycheck.sh) for ensuring that the library and tool are working correctly. Since update_payload is introduced as a package, we're moving some previously merged utilities into the package's directory. (Unit testing for this code will be uploaded on a separate CL; see chromium-os:39663) BUG=chromium-os:34911,chromium-os:33607,chromium-os:7597 TEST=test_paycheck.sh successful on MP-signed payloads CQ-DEPEND=I5746a1d80e822a575f0d96f94d0b4e765fc64507 Change-Id: I77123a1fffbb2059c239b7145c6922968fdffb6a Reviewed-on: https://gerrit.chromium.org/gerrit/43041 Reviewed-by: Gilad Arnold Tested-by: Gilad Arnold Reviewed-by: Chris Sosa Reviewed-by: Jay Srinivasan Reviewed-by: Don Garrett Commit-Queue: Gilad Arnold --- scripts/update_payload/format_utils.py | 93 ++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 scripts/update_payload/format_utils.py (limited to 'scripts/update_payload/format_utils.py') diff --git a/scripts/update_payload/format_utils.py b/scripts/update_payload/format_utils.py new file mode 100644 index 000000000..2c82f32f9 --- /dev/null +++ b/scripts/update_payload/format_utils.py @@ -0,0 +1,93 @@ +# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Various formatting functions.""" + + +def NumToPercent(num, total, min_precision=1, max_precision=5): + """Returns the percentage (string) of |num| out of |total|. + + If the percentage includes a fraction, it will be computed down to the least + precision that yields a non-zero and ranging between |min_precision| and + |max_precision|. Values are always rounded down. All arithmetic operations + are integer built-ins. Examples (using default precision): + + (1, 1) => 100% + (3, 10) => 30% + (3, 9) => 33.3% + (3, 900) => 0.3% + (3, 9000000) => 0.00003% + (3, 900000000) => 0% + (5, 2) => 250% + + Args: + num: the value of the part + total: the value of the whole + min_precision: minimum precision for fractional percentage + max_precision: maximum precision for fractional percentage + Returns: + Percentage string. + + """ + percent = 0 + precision = min(min_precision, max_precision) + factor = 10 ** precision + while precision <= max_precision: + percent = num * 100 * factor / total + if percent: + break + factor *= 10 + precision += 1 + + whole, frac = divmod(percent, factor) + while frac and not frac % 10: + frac /= 10 + precision -= 1 + + return '%d%s%%' % (whole, '.%0*d' % (precision, frac) if frac else '') + + +def BytesToHumanReadable(size, precision=1, decimal=False): + """Returns a human readable representation of a given |size|. + + The returned string includes unit notations in either binary (KiB, MiB, etc) + or decimal (kB, MB, etc), based on the value of |decimal|. The chosen unit is + the largest that yields a whole (or mixed) number. It may contain up to + |precision| fractional digits. Values are always rounded down. Largest unit + is an exabyte. All arithmetic operations are integer built-ins. Examples + (using default precision and binary units): + + 4096 => 4 KiB + 5000 => 4.8 KiB + 500000 => 488.2 KiB + 5000000 => 4.7 MiB + + Args: + size: the size in bytes + precision: the number of digits past the decimal point + decimal: whether to compute/present decimal or binary units + Returns: + Readable size string, or None if no conversion is applicable (i.e. size is + less than the smallest unit). + + """ + constants = ( + (('KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB'), 1024), + (('kB', 'MB', 'GB', 'TB', 'PB', 'EB'), 1000) + ) + suffixes, base = constants[decimal] + exp, magnitude = 0, 1 + while exp < len(suffixes): + next_magnitude = magnitude * base + if size < next_magnitude: + break + exp += 1 + magnitude = next_magnitude + + if exp != 0: + whole = size / magnitude + frac = (size % magnitude) * (10 ** precision) / magnitude + while frac and not frac % 10: + frac /= 10 + return '%d%s %s' % (whole, '.%d' % frac if frac else '', suffixes[exp - 1]) -- cgit v1.2.3 From 6a3a3878daddc2536a2ac9033189274cfc5ef52d Mon Sep 17 00:00:00 2001 From: Gilad Arnold Date: Fri, 4 Oct 2013 18:18:45 -0700 Subject: paycheck: fix errors around percentage / formatting of zero sizes This fixes two problems, both having to do with histogram generation: * When the total number of elements is zero, paycheck would crash due to a division by zero; further, even if the crash is fixed (returning, say, None) the histogram will contain a meaningless value in parenthesis, which we might as well drop. Both are fixed here. * When some size (say, bytes) is zero, its formatter (bytes-to-human-readable) returns None, which shows up as is in the final report. This should be checked and avoided. BUG=None TEST=Crash fixed; None percentage/formatted value omitted. Change-Id: I8bb5fbc47e1cde9dcbee7f7b96bcb63ef3a0935e Reviewed-on: https://chromium-review.googlesource.com/172046 Reviewed-by: Don Garrett Commit-Queue: Gilad Arnold Tested-by: Gilad Arnold --- scripts/update_payload/format_utils.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'scripts/update_payload/format_utils.py') diff --git a/scripts/update_payload/format_utils.py b/scripts/update_payload/format_utils.py index 2c82f32f9..2c3775c42 100644 --- a/scripts/update_payload/format_utils.py +++ b/scripts/update_payload/format_utils.py @@ -27,9 +27,13 @@ def NumToPercent(num, total, min_precision=1, max_precision=5): min_precision: minimum precision for fractional percentage max_precision: maximum precision for fractional percentage Returns: - Percentage string. + Percentage string, or None if percent cannot be computed (i.e. total is + zero). """ + if total == 0: + return None + percent = 0 precision = min(min_precision, max_precision) factor = 10 ** precision -- cgit v1.2.3