platform_CryptohomeMultiple: add.

Tests multiple concurrent cryptohome mounts.

BUG=chromium-os:20778
TEST=Yes

Change-Id: I78aa1d35a6554d8fda2a1d0980bb1a3d0b9c9f69
Signed-off-by: Elly Jones <ellyjones@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/10588
Reviewed-by: Gaurav Shah <gauravsh@chromium.org>
Reviewed-by: Chris Masone <cmasone@chromium.org>
diff --git a/client/bin/site_utils.py b/client/bin/site_utils.py
index 55e0429..b1421fb 100644
--- a/client/bin/site_utils.py
+++ b/client/bin/site_utils.py
@@ -202,3 +202,21 @@
         return True
     else:
         return False
+
+def mounts():
+    ret = []
+    for line in file('/proc/mounts'):
+        m = re.match(r'(?P<src>\S+) (?P<dest>\S+) (?P<type>\S+) (?P<opts>\S+).*', line)
+        if m:
+            ret.append(m.groupdict())
+    return ret
+
+def is_mountpoint(path):
+    return path in [ m['dest'] for m in mounts() ]
+
+def require_mountpoint(path):
+    """
+    Raises an exception if path is not a mountpoint.
+    """
+    if not is_mountpoint(path):
+        raise error.TestFail('Path not mounted: "%s"' % path)
diff --git a/client/cros/cryptohome.py b/client/cros/cryptohome.py
index cfc70e7..0081e19 100644
--- a/client/cros/cryptohome.py
+++ b/client/cros/cryptohome.py
@@ -60,8 +60,11 @@
     return 'Authentication succeeded' in __run_cmd(cmd)
 
 
-def unmount_vault():
-    """Unmount the directory."""
+def unmount_vault(user=None):
+    """
+    Unmount the directory. Once unmount-by-user is supported, the user
+    parameter will name the target user. See crosbug.com/20778
+    """
     cmd = (CRYPTOHOME_CMD + ' --action=unmount')
     __run_cmd(cmd)
     # Ensure that the user directory is not mounted
@@ -129,3 +132,9 @@
     if (domain == chromeos_constants.SPECIAL_CASE_DOMAIN):
         name = name.replace('.', '')
     return '@'.join([name, domain]).lower()
+
+def user_path(user):
+    return utils.system_output('cryptohome-path user %s' % user)
+
+def system_path(user):
+    return utils.system_output('cryptohome-path system %s' % user)
diff --git a/client/site_tests/platform_CryptohomeMultiple/control b/client/site_tests/platform_CryptohomeMultiple/control
new file mode 100644
index 0000000..3cdd746
--- /dev/null
+++ b/client/site_tests/platform_CryptohomeMultiple/control
@@ -0,0 +1,17 @@
+# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+AUTHOR = "Chromium OS Authors"
+NAME = "platform_CryptohomeMultiple"
+PURPOSE = "Tests the API for mounting multiple cryptohomes at once."
+TIME = "SHORT"
+TEST_CATEGORY = "Security"
+TEST_CLASS = "functional"
+TEST_TYPE = "client"
+
+DOC = """
+Performs functional tests for cryptohome multi-mount.
+"""
+
+job.run_test('platform_CryptohomeMultiple')
diff --git a/client/site_tests/platform_CryptohomeMultiple/platform_CryptohomeMultiple.py b/client/site_tests/platform_CryptohomeMultiple/platform_CryptohomeMultiple.py
new file mode 100644
index 0000000..09f4885
--- /dev/null
+++ b/client/site_tests/platform_CryptohomeMultiple/platform_CryptohomeMultiple.py
@@ -0,0 +1,27 @@
+# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+
+import utils
+from autotest_lib.client.bin import test
+from autotest_lib.client.common_lib import error
+from autotest_lib.client.cros import cryptohome
+
+class platform_CryptohomeMultiple(test.test):
+    version = 1
+    def test_mount_single(self):
+        """
+        Tests mounting a single not-already-existing cryptohome. Ensures that
+        the infrastructure for multiple mounts is present and active.
+        """
+        user = 'cryptohome-multiple-0@example.com'
+        cryptohome.mount_vault(user, 'test', create=True)
+        utils.require_mountpoint(cryptohome.user_path(user))
+        utils.require_mountpoint(cryptohome.system_path(user))
+        cryptohome.unmount_vault(user)
+
+    def run_once(self):
+        if cryptohome.is_mounted(allow_fail=True):
+            raise error.TestFail('Cryptohome already mounted')
+        self.test_mount_single()