def data_constructor(hostname, version, interfaces, **kwargs): # If no data is passed a known error if not hostname and not version and not interfaces: raise NetApiParseError("No data to be parsed") raw_interfaces = list(interfaces.get("interfaces", {}).keys()) parsed_data = dict( hostname=hostname.get("hostname"), os_version=version.get("version"), model=version.get("modelName"), serial_number=version.get("serialNumber"), uptime=pendulum.duration(seconds=version["uptime"]), up_since=pendulum.from_timestamp(version["bootupTimestamp"]), system_mac=version.get("systemMacAddress"), available_memory=kB(version.get("memFree")).Byte, total_memory=kB(version.get("memTotal")).Byte, os_arch=version.get("architecture"), hw_revision=version.get("hardwareRevision"), interfaces=sorted( [interface.interface_converter(x) for x in raw_interfaces], key=interface.sort_interface, ), ) return parsed_data
def test_sort_key_bits(self): """Bitmath types can be sorted by 'bits' attribute""" first = bitmath.kB(0) second = bitmath.kB(1337) third = bitmath.kB(2048) fourth = bitmath.kB(96783) unsorted_list = [fourth, second, first, third] sorted_list = sorted(unsorted_list, key=lambda x: x.bits) self.assertIs(sorted_list[0], first) self.assertIs(sorted_list[1], second) self.assertIs(sorted_list[2], third) self.assertIs(sorted_list[3], fourth)
def test_sort_homogeneous_list(self): """Same types in a list can be sorted properly""" first = bitmath.kB(0) second = bitmath.kB(1337) third = bitmath.kB(2048) fourth = bitmath.kB(96783) # Put the objects into the array in 'random' order unsorted_list = [fourth, second, first, third] sorted_list = sorted(unsorted_list) self.assertIs(sorted_list[0], first) self.assertIs(sorted_list[1], second) self.assertIs(sorted_list[2], third) self.assertIs(sorted_list[3], fourth)
def test_parse_string_unsafe_github_issue_60(self): """parse_string_unsafe can parse the examples reported in issue #60 https://github.com/tbielawa/bitmath/issues/60 """ issue_input1 = '7.5KB' _parsed1 = bitmath.parse_string_unsafe(issue_input1) expected_result1 = bitmath.kB(7.5) self.assertEqual( _parsed1, expected_result1) issue_input2 = '4.7MB' _parsed2 = bitmath.parse_string_unsafe(issue_input2) expected_result2 = bitmath.MB(4.7) self.assertEqual( _parsed2, expected_result2) issue_input3 = '4.7M' _parsed3 = bitmath.parse_string_unsafe(issue_input3) expected_result3 = bitmath.MB(4.7) self.assertEqual( _parsed3, expected_result3)
def test_parse_unsafe_SI(self): """parse_string_unsafe can parse all accepted SI inputs""" # Begin with the kilo unit because it's the most tricky (SI # defines the unit as a lower-case 'k') kilo_inputs = [ '100k', '100K', '100kb', '100KB', '100kB' ] expected_kilo_result = bitmath.kB(100) for ki in kilo_inputs: _parsed = bitmath.parse_string_unsafe(ki) self.assertEqual(_parsed, expected_kilo_result) self.assertIs(type(_parsed), type(expected_kilo_result)) # Now check for other easier to parse prefixes other_inputs = [ '100g', '100G', '100gb', '100gB', '100GB' ] expected_gig_result = bitmath.GB(100) for gi in other_inputs: _parsed = bitmath.parse_string_unsafe(gi) self.assertEqual(_parsed, expected_gig_result) self.assertIs(type(_parsed), type(expected_gig_result))
def test_best_prefix_prefer_NIST_from_SI(self): """NIST: Best prefix honors a NIST preference when starting with an SI unit Start with an SI (kb) unit and prefer a NIST unit as the result (MiB) """ # Start with kB, an SI unit should_be_MiB = bitmath.kB(1600).best_prefix(system=bitmath.NIST) self.assertIs(type(should_be_MiB), bitmath.MiB)
def test_best_prefix_prefer_SI_from_SI(self): """SI: Best prefix honors a SI preference when starting with an SI unit Start with an SI (kb) unit and prefer a SI unit as the result (MB) """ # Start with kB, a SI unit should_be_MB = bitmath.kB(1600).best_prefix(system=bitmath.SI) self.assertIs(type(should_be_MB), bitmath.MB)
def test_sort_key_value(self): """Same types can be sorted by 'value' attribute This does not work on heterogeneous collections! The 'value' attribute varies between different bitmath types even if they are of equivalent size because it is the shortened representation of that prefix unit.""" first = bitmath.kB(0) second = bitmath.kB(1337) third = bitmath.kB(2048) fourth = bitmath.kB(96783) unsorted_list = [fourth, second, first, third] sorted_list = sorted(unsorted_list, key=lambda x: x.value) self.assertIs(sorted_list[0], first) self.assertIs(sorted_list[1], second) self.assertIs(sorted_list[2], third) self.assertIs(sorted_list[3], fourth)
def to_base_10(n): if "K" in n[1]: return int(round(bitmath.kB(n[0]).to_Byte())) elif "M" in n[1]: return int(round(bitmath.MB(n[0]).to_Byte())) elif "G" in n[1]: return int(round(bitmath.GB(n[0]).to_Byte())) elif "T" in n[1]: return int(round(bitmath.TB(n[0]).to_Byte())) else: return int(round(float(n[0])))
def test_parse_unsafe_handles_SI_K_unit(self): """parse_string_unsafe can parse the upper/lowercase SI 'thousand' (k)""" thousand_lower = "100k" thousand_upper = "100K" expected_result = bitmath.kB(100) self.assertEqual( bitmath.parse_string_unsafe(thousand_lower), expected_result) self.assertEqual( bitmath.parse_string_unsafe(thousand_upper), expected_result)
def get_limit_kbytes(qos): """Get kilobytes limit of storage in QoS response.""" qos_limits = qos["qosLimitList"] limit = 0 for item in qos_limits: if item["type"] == "STORAGE_QUOTA_KBYTES": limit = item["value"] break if limit == -1: limit = "Unlimited" else: limit = bitmath.kB(limit).best_prefix() return limit
def setUp(self): self.bit = bitmath.Bit(1) self.byte = bitmath.Byte(1) # NIST units self.kib = bitmath.KiB(1) self.mib = bitmath.MiB(1) self.gib = bitmath.GiB(1) self.tib = bitmath.TiB(1) self.pib = bitmath.PiB(1) self.eib = bitmath.EiB(1) # SI units self.kb = bitmath.kB(1) self.mb = bitmath.MB(1) self.gb = bitmath.GB(1) self.tb = bitmath.TB(1) self.pb = bitmath.PB(1) self.eb = bitmath.EB(1)
def setUp(self): self.kib = bitmath.KiB(1) self.kib_repr = "KiB(1.0)" self.kib_str = "1.0 KiB" self.kib_unit = "KiB" self.kib_system = "NIST" self.kib_bin = "0b10000000000000" self.kib_binary = self.kib_bin self.kib_power = 10 self.kib_base = 2 self.half_mib = bitmath.MiB(0.5) self.half_mib_repr = "MiB(0.5)" self.half_mib_str = "0.5 MiB" self.kB = bitmath.kB(1) self.kB_unit = "kB" self.kb_system = "SI" self.kib_str_changed = "KiB 1.000"
def setUp(self): self.kib = bitmath.KiB(1) self.kib_repr = 'KiB(1.0)' self.kib_str = '1.0 KiB' self.kib_unit = 'KiB' self.kib_system = 'NIST' self.kib_bin = '0b10000000000000' self.kib_binary = self.kib_bin self.kib_power = 10 self.kib_base = 2 self.half_mib = bitmath.MiB(0.5) self.half_mib_repr = 'MiB(0.5)' self.half_mib_str = '0.5 MiB' self.kB = bitmath.kB(1) self.kB_unit = 'kB' self.kb_system = 'SI' self.kib_str_changed = 'KiB 1.000'
def test_multi_oom_round_down(self): """SI: A very small Petabyte rounds down into a Kilobyte""" small_PB = bitmath.PB.from_other(bitmath.kB(1)) self.assertIs(type(small_PB.best_prefix()), bitmath.kB)
def test_getsize_kibibyte_system_SI(self): """SI: getsize reports the correct type and size for kibibyte sized files""" expected = bitmath.kB(bytes=1024) result = bitmath.getsize(self.kibibyte_file, system=bitmath.SI) self.assertEqual(result, expected) self.assertIs(type(result), bitmath.kB)
def parse_k8s_memory_value(memory_value): """Parse and convert Kubernetes specific memory value :param memory_value: memory value from Kubernetes manifest :type memory_value: str :raises NotImplementedError: raised if value postfix is unknown :return: parsed memory value :rtype: int """ # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ # https://medium.com/@betz.mark/understanding-resource-limits-in-kubernetes-memory-6b41e9a955f9 _K8S_MEMORY_SUFFIXES_FIXED = ['E', 'P', 'T', 'G', 'M', 'K'] _K8S_MEMORY_SUFFIXES_POWER = ['Ei', 'Pi', 'Ti', 'Gi', 'Mi', 'Ki'] if type(memory_value) is str: # exponential notation e.g. 3e2 = 300 if 'e' in memory_value: memory_value = float(memory_value) # check if power-of-two notation is used # it is important to check power-of-two first as fixed-point comparison would also match elif [ e for e in _K8S_MEMORY_SUFFIXES_POWER if (e in memory_value) ]: if 'Ki' in memory_value: memory_value = memory_value.strip('Ki') memory_value = KiB(float(memory_value)).to_MB().value elif 'Mi' in memory_value: memory_value = memory_value.strip('Mi') memory_value = MiB(float(memory_value)).to_MB().value elif 'Gi' in memory_value: memory_value = memory_value.strip('Gi') memory_value = GiB(float(memory_value)).to_MB().value elif 'Ti' in memory_value: memory_value = memory_value.strip('Ti') memory_value = TiB(float(memory_value)).to_MB().value elif 'Pi' in memory_value: memory_value = memory_value.strip('Ki') memory_value = PiB(float(memory_value)).to_MB().value elif 'Ei' in memory_value: memory_value = memory_value.strip('Ei') memory_value = EiB(float(memory_value)).to_MB().value else: raise NotImplementedError( 'Memory value unit of {} not implemented'.format( memory_value)) # check if fixed-point integer notation is used elif [ e for e in _K8S_MEMORY_SUFFIXES_FIXED if (e in memory_value) ]: if 'M' in memory_value: memory_value = memory_value.strip('M') elif 'K' in memory_value: memory_value = memory_value.strip('K') memory_value = kB(float(memory_value)).to_MB().value elif 'G' in memory_value: memory_value = memory_value.strip('G') memory_value = GB(float(memory_value)).to_MB().value elif 'T' in memory_value: memory_value = memory_value.strip('T') memory_value = TB(float(memory_value)).to_MB().value elif 'P' in memory_value: memory_value = memory_value.strip('P') memory_value = PB(float(memory_value)).to_MB().value elif 'E' in memory_value: memory_value = memory_value.strip('E') memory_value = EB(float(memory_value)).to_MB().value else: raise NotImplementedError( 'Memory value unit of {} not implemented'.format( memory_value)) # direct definition in bytes - convert to MB else: memory_value = memory_value / float('1e+6') return int(memory_value)