def _DistributionToBackendFormat(dist): """Convert an object size distribution to the format needed by the backend. Args: dist: a distribution, given as a dictionary mapping size to frequency. Size will be a string with a quantity and a unit. Frequency will be a percentage, including a '%' character. dist may also be a string, in which case it represents a single object size which applies to 100% of objects. Returns: A dictionary giving an object size distribution. Sizes will be integers representing bytes. Frequencies will be floating-point numbers in [0,100], representing percentages. Raises: ValueError if dist is not a valid distribution. """ if isinstance(dist, dict): val = { flag_util.StringToBytes(size): flag_util.StringToRawPercent(frequency) for size, frequency in dist.iteritems() } else: # We allow compact notation for point distributions. For instance, # '1KB' is an abbreviation for '{1KB: 100%}'. val = {flag_util.StringToBytes(dist): 100.0} # I'm requiring exact addition to 100, which can always be satisfied # with integer percentages. If we want to allow general decimal # percentages, all we have to do is replace this equality check with # approximate equality. if sum(val.itervalues()) != 100.0: raise ValueError("Frequencies in %s don't add to 100%%!" % dist) return val
def testPercentAbove100(self): with self.assertRaises(ValueError): flag_util.StringToRawPercent('112%')
def testNegativePercent(self): with self.assertRaises(ValueError): flag_util.StringToRawPercent('-12%')
def testNoPercentSign(self): with self.assertRaises(ValueError): flag_util.StringToRawPercent('100')
def testOneCharacterString(self): with self.assertRaises(ValueError): flag_util.StringToRawPercent('%')
def testNullString(self): with self.assertRaises(ValueError): flag_util.StringToRawPercent('')
def testValidPct(self): self.assertEquals(flag_util.StringToRawPercent('50.5%'), 50.5)