Add human_to_bytes isbits arg unit tests&docstring

PR #58623

Co-Authored-By: Sviatoslav Sydorenko <webknjaz@redhat.com>
Co-Authored-By: Sviatoslav Sydorenko <wk.cvs.github@sydorenko.org.ua>
This commit is contained in:
Andrey Klychkov 2019-07-23 15:56:56 +03:00 committed by Sviatoslav Sydorenko
parent 133cb945ae
commit 333953117c
3 changed files with 164 additions and 44 deletions

View file

@ -38,7 +38,21 @@ def lenient_lowercase(lst):
def human_to_bytes(number, default_unit=None, isbits=False): def human_to_bytes(number, default_unit=None, isbits=False):
"""Convert number in string format into bytes (ex: '2K' => 2048) or using unit argument. """Convert number in string format into bytes (ex: '2K' => 2048) or using unit argument.
example: human_to_bytes('10M') <=> human_to_bytes(10, 'M')
example: human_to_bytes('10M') <=> human_to_bytes(10, 'M').
When isbits is False (default), converts bytes from a human-readable format to integer.
example: human_to_bytes('1MB') returns 1048576 (int).
The function expects 'B' (uppercase) as a byte identifier passed
as a part of 'name' param string or 'unit', e.g. 'MB'/'KB'/etc.
(except when the identifier is single 'b', it is perceived as a byte identifier too).
if 'Mb'/'Kb'/... is passed, the ValueError will be rased.
When isbits is True, converts bits from a human-readable format to integer.
example: human_to_bytes('1Mb', isbits=True) returns 1048576 (int) -
string bits representation was passed and return as a number or bits.
The function expects 'b' (lowercase) as a bit identifier, e.g. 'Mb'/'Kb'/etc.
if 'MB'/'KB'/... is passed, the ValueError will be rased.
""" """
m = re.search(r'^\s*(\d*\.?\d*)\s*([A-Za-z]+)?', str(number), flags=re.IGNORECASE) m = re.search(r'^\s*(\d*\.?\d*)\s*([A-Za-z]+)?', str(number), flags=re.IGNORECASE)
if m is None: if m is None:

View file

@ -521,9 +521,11 @@ def check_type_bytes(value):
def check_type_bits(value): def check_type_bits(value):
"""Convert a human-readable string value to bits """Convert a human-readable string bits value to bits in integer.
Raises TypeError if unable to covert the value Example: check_type_bits('1Mb') returns integer 1048576.
Raises TypeError if unable to covert the value.
""" """
try: try:
return human_to_bytes(value, isbits=True) return human_to_bytes(value, isbits=True)

View file

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2019, Andrew Klychkov @Andersson007 <aaklychkov@mail.ru> # Copyright 2019, Andrew Klychkov @Andersson007 <aaklychkov@mail.ru>
# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause) # Copyright 2019, Sviatoslav Sydorenko <webknjaz@redhat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function from __future__ import absolute_import, division, print_function
__metaclass__ = type __metaclass__ = type
@ -10,29 +11,41 @@ import pytest
from ansible.module_utils.common.text.formatters import human_to_bytes from ansible.module_utils.common.text.formatters import human_to_bytes
NUM_IN_METRIC = {
'K': 2 ** 10,
'M': 2 ** 20,
'G': 2 ** 30,
'T': 2 ** 40,
'P': 2 ** 50,
'E': 2 ** 60,
'Z': 2 ** 70,
'Y': 2 ** 80,
}
@pytest.mark.parametrize( @pytest.mark.parametrize(
'input_data,expected', 'input_data,expected',
[ [
(0, 0), (0, 0),
(1024, 1024),
(u'1024B', 1024),
(u'0B', 0), (u'0B', 0),
(u'1K', 1024), (1024, NUM_IN_METRIC['K']),
(u'1KB', 1024), (u'1024B', NUM_IN_METRIC['K']),
(u'1MB', 1048576), (u'1K', NUM_IN_METRIC['K']),
(u'1M', 1048576), (u'1KB', NUM_IN_METRIC['K']),
(u'1G', 1073741824), (u'1M', NUM_IN_METRIC['M']),
(u'1GB', 1073741824), (u'1MB', NUM_IN_METRIC['M']),
(u'1T', 1099511627776), (u'1G', NUM_IN_METRIC['G']),
(u'1TB', 1099511627776), (u'1GB', NUM_IN_METRIC['G']),
(u'1P', 1125899906842624), (u'1T', NUM_IN_METRIC['T']),
(u'1PB', 1125899906842624), (u'1TB', NUM_IN_METRIC['T']),
(u'1E', 1152921504606846976), (u'1P', NUM_IN_METRIC['P']),
(u'1EB', 1152921504606846976), (u'1PB', NUM_IN_METRIC['P']),
(u'1Z', 1180591620717411303424), (u'1E', NUM_IN_METRIC['E']),
(u'1ZB', 1180591620717411303424), (u'1EB', NUM_IN_METRIC['E']),
(u'1Y', 1208925819614629174706176), (u'1Z', NUM_IN_METRIC['Z']),
(u'1YB', 1208925819614629174706176), (u'1ZB', NUM_IN_METRIC['Z']),
(u'1Y', NUM_IN_METRIC['Y']),
(u'1YB', NUM_IN_METRIC['Y']),
] ]
) )
def test_human_to_bytes_number(input_data, expected): def test_human_to_bytes_number(input_data, expected):
@ -41,30 +54,30 @@ def test_human_to_bytes_number(input_data, expected):
@pytest.mark.parametrize( @pytest.mark.parametrize(
'input_data,unit,expected', 'input_data,unit',
[ [
(u'1024', u'B', 1024), (u'1024', 'B'),
(1, u'K', 1024), (1, u'K'),
(1, u'KB', 1024), (1, u'KB'),
(u'1', u'M', 1048576), (u'1', u'M'),
(u'1', u'MB', 1048576), (u'1', u'MB'),
(1, u'G', 1073741824), (1, u'G'),
(1, u'GB', 1073741824), (1, u'GB'),
(1, u'T', 1099511627776), (1, u'T'),
(1, u'TB', 1099511627776), (1, u'TB'),
(u'1', u'P', 1125899906842624), (u'1', u'P'),
(u'1', u'PB', 1125899906842624), (u'1', u'PB'),
(u'1', u'E', 1152921504606846976), (u'1', u'E'),
(u'1', u'EB', 1152921504606846976), (u'1', u'EB'),
(u'1', u'Z', 1180591620717411303424), (u'1', u'Z'),
(u'1', u'ZB', 1180591620717411303424), (u'1', u'ZB'),
(u'1', u'Y', 1208925819614629174706176), (u'1', u'Y'),
(u'1', u'YB', 1208925819614629174706176), (u'1', u'YB'),
] ]
) )
def test_human_to_bytes_number_unit(input_data, unit, expected): def test_human_to_bytes_number_unit(input_data, unit):
"""Test of human_to_bytes function, number and default_unit args are passed.""" """Test of human_to_bytes function, number and default_unit args are passed."""
assert human_to_bytes(input_data, default_unit=unit) == expected assert human_to_bytes(input_data, default_unit=unit) == NUM_IN_METRIC.get(unit[0], 1024)
@pytest.mark.parametrize('test_input', [u'1024s', u'1024w', ]) @pytest.mark.parametrize('test_input', [u'1024s', u'1024w', ])
@ -74,8 +87,99 @@ def test_human_to_bytes_wrong_unit(test_input):
human_to_bytes(test_input) human_to_bytes(test_input)
@pytest.mark.parametrize('test_input', [u'b1bbb', u'm2mmm', u'', u' ', ]) @pytest.mark.parametrize('test_input', [u'b1bbb', u'm2mmm', u'', u' ', -1])
def test_human_to_bytes_wrong_number(test_input): def test_human_to_bytes_wrong_number(test_input):
"""Test of human_to_bytes function, nubmer param is invalid string / number.""" """Test of human_to_bytes function, number param is invalid string / number."""
with pytest.raises(ValueError, match="can't interpret"): with pytest.raises(ValueError, match="can't interpret"):
human_to_bytes(test_input) human_to_bytes(test_input)
@pytest.mark.parametrize(
'input_data,expected',
[
(0, 0),
(u'0B', 0),
(u'1024b', 1024),
(u'1024B', 1024),
(u'1K', NUM_IN_METRIC['K']),
(u'1Kb', NUM_IN_METRIC['K']),
(u'1M', NUM_IN_METRIC['M']),
(u'1Mb', NUM_IN_METRIC['M']),
(u'1G', NUM_IN_METRIC['G']),
(u'1Gb', NUM_IN_METRIC['G']),
(u'1T', NUM_IN_METRIC['T']),
(u'1Tb', NUM_IN_METRIC['T']),
(u'1P', NUM_IN_METRIC['P']),
(u'1Pb', NUM_IN_METRIC['P']),
(u'1E', NUM_IN_METRIC['E']),
(u'1Eb', NUM_IN_METRIC['E']),
(u'1Z', NUM_IN_METRIC['Z']),
(u'1Zb', NUM_IN_METRIC['Z']),
(u'1Y', NUM_IN_METRIC['Y']),
(u'1Yb', NUM_IN_METRIC['Y']),
]
)
def test_human_to_bytes_isbits(input_data, expected):
"""Test of human_to_bytes function, isbits = True."""
assert human_to_bytes(input_data, isbits=True) == expected
@pytest.mark.parametrize(
'input_data,unit',
[
(1024, 'b'),
(1024, 'B'),
(1, u'K'),
(1, u'Kb'),
(u'1', u'M'),
(u'1', u'Mb'),
(1, u'G'),
(1, u'Gb'),
(1, u'T'),
(1, u'Tb'),
(u'1', u'P'),
(u'1', u'Pb'),
(u'1', u'E'),
(u'1', u'Eb'),
(u'1', u'Z'),
(u'1', u'Zb'),
(u'1', u'Y'),
(u'1', u'Yb'),
]
)
def test_human_to_bytes_isbits_default_unit(input_data, unit):
"""Test of human_to_bytes function, isbits = True and default_unit args are passed."""
assert human_to_bytes(input_data, default_unit=unit, isbits=True) == NUM_IN_METRIC.get(unit[0], 1024)
@pytest.mark.parametrize(
'test_input,isbits',
[
('1024Kb', False),
('10Mb', False),
('1Gb', False),
('10MB', True),
('2KB', True),
('4GB', True),
]
)
def test_human_to_bytes_isbits_wrong_unit(test_input, isbits):
"""Test of human_to_bytes function, unit identifier is in an invalid format for isbits value."""
with pytest.raises(ValueError, match="Value is not a valid string"):
human_to_bytes(test_input, isbits=isbits)
@pytest.mark.parametrize(
'test_input,unit,isbits',
[
(1024, 'Kb', False),
('10', 'Mb', False),
('10', 'MB', True),
(2, 'KB', True),
('4', 'GB', True),
]
)
def test_human_to_bytes_isbits_wrong_default_unit(test_input, unit, isbits):
"""Test of human_to_bytes function, default_unit is in an invalid format for isbits value."""
with pytest.raises(ValueError, match="Value is not a valid string"):
human_to_bytes(test_input, default_unit=unit, isbits=isbits)