Add unit tests for read_keyval, and fix a bug in its handling of
comments+whitespace found while writing the tests.

Risk: Low
Visibility: Adds more unittests.

Signed-off-by: John Admanski <jadmanski@google.com>



git-svn-id: http://test.kernel.org/svn/autotest/trunk@1833 592f7852-d20e-0410-864c-8624ca9c26a4
diff --git a/client/common_lib/utils.py b/client/common_lib/utils.py
index 2d5cb8d..f31fb2f 100644
--- a/client/common_lib/utils.py
+++ b/client/common_lib/utils.py
@@ -25,7 +25,7 @@
         path = os.path.join(path, 'keyval')
     keyval = {}
     for line in open(path):
-        line = re.sub('#.*', '', line.rstrip())
+        line = re.sub('#.*', '', line).rstrip()
         if not re.search(r'^[-\w]+=', line):
             raise ValueError('Invalid format line: %s' % line)
         key, value = line.split('=', 1)
diff --git a/client/common_lib/utils_unittest.py b/client/common_lib/utils_unittest.py
index a68d9cf..6fb5bd3 100644
--- a/client/common_lib/utils_unittest.py
+++ b/client/common_lib/utils_unittest.py
@@ -1,6 +1,6 @@
 #!/usr/bin/python
 
-import unittest, StringIO
+import os, unittest, StringIO
 
 import common
 from autotest_lib.client.common_lib import utils
@@ -97,5 +97,95 @@
         self.assertEqual("\n", self.get_write_one_line_output(""))
 
 
+class test_read_keyval(unittest.TestCase):
+    def setUp(self):
+        self.god = mock.mock_god()
+        self.god.stub_function(utils, "open")
+        self.god.stub_function(os.path, "isdir")
+
+
+    def tearDown(self):
+        self.god.unstub_all()
+
+
+    def create_test_file(self, filename, contents):
+        test_file = StringIO.StringIO(contents)
+        utils.open.expect_call(filename).and_return(test_file)
+
+
+    def read_keyval(self, contents):
+        os.path.isdir.expect_call("file").and_return(False)
+        self.create_test_file("file", contents)
+        keyval = utils.read_keyval("file")
+        self.god.check_playback()
+        return keyval
+
+
+    def test_accesses_files_directly(self):
+        os.path.isdir.expect_call("file").and_return(False)
+        self.create_test_file("file", "")
+        utils.read_keyval("file")
+        self.god.check_playback()
+
+
+    def test_accesses_directories_through_keyval_file(self):
+        os.path.isdir.expect_call("dir").and_return(True)
+        self.create_test_file("dir/keyval", "")
+        utils.read_keyval("dir")
+        self.god.check_playback()
+
+
+    def test_values_are_rstripped(self):
+        keyval = self.read_keyval("a=b   \n")
+        self.assertEquals(keyval, {"a": "b"})
+
+
+    def test_comments_are_ignored(self):
+        keyval = self.read_keyval("a=b # a comment\n")
+        self.assertEquals(keyval, {"a": "b"})
+
+
+    def test_integers_become_ints(self):
+        keyval = self.read_keyval("a=1\n")
+        self.assertEquals(keyval, {"a": 1})
+        self.assertEquals(int, type(keyval["a"]))
+
+
+    def test_float_values_become_floats(self):
+        keyval = self.read_keyval("a=1.5\n")
+        self.assertEquals(keyval, {"a": 1.5})
+        self.assertEquals(float, type(keyval["a"]))
+
+
+    def test_multiple_lines(self):
+        keyval = self.read_keyval("a=one\nb=two\n")
+        self.assertEquals(keyval, {"a": "one", "b": "two"})
+
+
+    def test_the_last_duplicate_line_is_used(self):
+        keyval = self.read_keyval("a=one\nb=two\na=three\n")
+        self.assertEquals(keyval, {"a": "three", "b": "two"})
+
+
+    def test_extra_equals_are_included_in_values(self):
+        keyval = self.read_keyval("a=b=c\n")
+        self.assertEquals(keyval, {"a": "b=c"})
+
+
+    def test_non_alphanumeric_keynames_are_rejected(self):
+        self.assertRaises(ValueError, self.read_keyval, "a$=one\n")
+
+
+    def test_underscores_are_allowed_in_key_names(self):
+        keyval = self.read_keyval("a_b=value\n")
+        self.assertEquals(keyval, {"a_b": "value"})
+
+
+    def test_dashes_are_allowed_in_key_names(self):
+        keyval = self.read_keyval("a-b=value\n")
+        self.assertEquals(keyval, {"a-b": "value"})
+
+
+
 if __name__ == "__main__":
     unittest.main()