summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openstack/common/fileutils.py12
-rw-r--r--openstack/common/strutils.py39
-rw-r--r--tests/unit/test_fileutils.py13
-rw-r--r--tests/unit/test_strutils.py32
4 files changed, 96 insertions, 0 deletions
diff --git a/openstack/common/fileutils.py b/openstack/common/fileutils.py
index 0c967da..9f8807f 100644
--- a/openstack/common/fileutils.py
+++ b/openstack/common/fileutils.py
@@ -96,3 +96,15 @@ def remove_path_on_error(path):
except Exception:
with excutils.save_and_reraise_exception():
delete_if_exists(path)
+
+
+def file_open(*args, **kwargs):
+ """Open file
+
+ see built-in file() documentation for more details
+
+ Note: The reason this is kept in a separate module is to easily
+ be able to provide a stub module that doesn't alter system
+ state at all (for unit tests)
+ """
+ return file(*args, **kwargs)
diff --git a/openstack/common/strutils.py b/openstack/common/strutils.py
index 6d227c6..8a5367b 100644
--- a/openstack/common/strutils.py
+++ b/openstack/common/strutils.py
@@ -24,6 +24,17 @@ import sys
from openstack.common.gettextutils import _
+# Used for looking up extensions of text
+# to their 'multiplied' byte amount
+BYTE_MULTIPLIERS = {
+ '': 1,
+ 't': 1024 ** 4,
+ 'g': 1024 ** 3,
+ 'm': 1024 ** 2,
+ 'k': 1024,
+}
+
+
TRUE_STRINGS = ('1', 't', 'true', 'on', 'y', 'yes')
FALSE_STRINGS = ('0', 'f', 'false', 'off', 'n', 'no')
@@ -148,3 +159,31 @@ def safe_encode(text, incoming=None,
return text.encode(encoding, errors)
return text
+
+
+def to_bytes(text, default=0):
+ """Try to turn a string into a number of bytes. Looks at the last
+ characters of the text to determine what conversion is needed to
+ turn the input text into a byte number.
+
+ Supports: B/b, K/k, M/m, G/g, T/t (or the same with b/B on the end)
+
+ """
+ # Take off everything not number 'like' (which should leave
+ # only the byte 'identifier' left)
+ mult_key_org = text.lstrip('-1234567890')
+ mult_key = mult_key_org.lower()
+ mult_key_len = len(mult_key)
+ if mult_key.endswith("b"):
+ mult_key = mult_key[0:-1]
+ try:
+ multiplier = BYTE_MULTIPLIERS[mult_key]
+ if mult_key_len:
+ # Empty cases shouldn't cause text[0:-0]
+ text = text[0:-mult_key_len]
+ return int(text) * multiplier
+ except KeyError:
+ msg = _('Unknown byte multiplier: %s') % mult_key_org
+ raise TypeError(msg)
+ except ValueError:
+ return default
diff --git a/tests/unit/test_fileutils.py b/tests/unit/test_fileutils.py
index 030f5f0..4214e83 100644
--- a/tests/unit/test_fileutils.py
+++ b/tests/unit/test_fileutils.py
@@ -132,3 +132,16 @@ class RemovePathOnError(utils.BaseTestCase):
pass
self.assertTrue(os.path.exists(tmpfile))
os.unlink(tmpfile)
+
+
+class UtilsTestCase(utils.BaseTestCase):
+ def test_file_open(self):
+ dst_fd, dst_path = tempfile.mkstemp()
+ try:
+ os.close(dst_fd)
+ with open(dst_path, 'w') as f:
+ f.write('hello')
+ with fileutils.file_open(dst_path, 'r') as fp:
+ self.assertEquals(fp.read(), 'hello')
+ finally:
+ os.unlink(dst_path)
diff --git a/tests/unit/test_strutils.py b/tests/unit/test_strutils.py
index bad50c8..42160a6 100644
--- a/tests/unit/test_strutils.py
+++ b/tests/unit/test_strutils.py
@@ -166,3 +166,35 @@ class StrUtilsTest(utils.BaseTestCase):
# Forcing incoming to ascii so it falls back to utf-8
self.assertEqual('ni\xc3\xb1o', safe_encode('ni\xc3\xb1o',
incoming='ascii'))
+
+ def test_string_conversions(self):
+ working_examples = {
+ '1024KB': 1048576,
+ '1024TB': 1125899906842624,
+ '1024K': 1048576,
+ '1024T': 1125899906842624,
+ '1TB': 1099511627776,
+ '1T': 1099511627776,
+ '1KB': 1024,
+ '1K': 1024,
+ '1B': 1,
+ '1': 1,
+ '1MB': 1048576,
+ '7MB': 7340032,
+ '0MB': 0,
+ '0KB': 0,
+ '0TB': 0,
+ '': 0,
+ }
+ for (in_value, expected_value) in working_examples.items():
+ b_value = strutils.to_bytes(in_value)
+ self.assertEquals(expected_value, b_value)
+ if in_value:
+ in_value = "-" + in_value
+ b_value = strutils.to_bytes(in_value)
+ self.assertEquals(expected_value * -1, b_value)
+ breaking_examples = [
+ 'junk1KB', '1023BBBB',
+ ]
+ for v in breaking_examples:
+ self.assertRaises(TypeError, strutils.to_bytes, v)