Add platform_CrosDisksFormat to verify cros-disks formatting support.
BUG=chromium-os:23313
TEST=Ran platform_CrosDisksFormat in a VM.
Change-Id: Ie41055ccc3032ba32722d82762082c68f7d6821c
Reviewed-on: https://gerrit.chromium.org/gerrit/12020
Reviewed-by: Chris Sosa <[email protected]>
Tested-by: Ben Chan <[email protected]>
diff --git a/client/cros/cros_disks.py b/client/cros/cros_disks.py
index 24a21c3..f9c8bb6 100644
--- a/client/cros/cros_disks.py
+++ b/client/cros/cros_disks.py
@@ -116,7 +116,10 @@
interface)
def wait_for_signal(self, signal_name):
- """Waits for the receiption of a signal.
+ """Waits for the reception of a signal.
+
+ Args:
+ signal_name: The name of the signal to wait for.
Returns:
The content of the signal.
@@ -139,6 +142,37 @@
self.__signal_content[signal_name] = None
return content
+ def expect_signal(self, signal_name, expected_content):
+ """Waits the the reception of a signal and verifies its content.
+
+ Args:
+ signal_name: The name of the signal to wait for.
+ expected_content: The expected content of the signal, which can be
+ partially specified. Only specified fields are
+ compared between the actual and expected content.
+
+ Returns:
+ The actual content of the signal.
+
+ Raises:
+ error.TestFail: A test failure when there is a mismatch between the
+ actual and expected content of the signal.
+ """
+ actual_content = self.wait_for_signal(signal_name)
+ logging.debug("%s signal: expected=%s actual=%s",
+ signal_name, expected_content, actual_content)
+ for argument, expected_value in expected_content.iteritems():
+ if argument not in actual_content:
+ raise error.TestFail(
+ ('%s signal missing "%s": expected=%s, actual=%s') %
+ (signal_name, argument, expected_content, actual_content))
+
+ if actual_content[argument] != expected_value:
+ raise error.TestFail(
+ ('%s signal not matched on "%s": expected=%s, actual=%s') %
+ (signal_name, argument, expected_content, actual_content))
+ return actual_content
+
class CrosDisksClient(DBusClient):
"""A DBus proxy client for testing the CrosDisks DBus server.
@@ -149,6 +183,10 @@
CROS_DISKS_OBJECT_PATH = '/org/chromium/CrosDisks'
DBUS_PROPERTIES_INTERFACE = 'org.freedesktop.DBus.Properties'
EXPERIMENTAL_FEATURES_ENABLED_PROPERTY = 'ExperimentalFeaturesEnabled'
+ FORMAT_COMPLETED_SIGNAL = 'FormatCompleted'
+ FORMAT_COMPLETED_SIGNAL_ARGUMENTS = (
+ 'status', 'path'
+ )
MOUNT_COMPLETED_SIGNAL = 'MountCompleted'
MOUNT_COMPLETED_SIGNAL_ARGUMENTS = (
'status', 'source_path', 'source_type', 'mount_path'
@@ -169,6 +207,9 @@
self.properties = dbus.Interface(self.proxy_object,
self.DBUS_PROPERTIES_INTERFACE)
self.handle_signal(self.CROS_DISKS_INTERFACE,
+ self.FORMAT_COMPLETED_SIGNAL,
+ self.FORMAT_COMPLETED_SIGNAL_ARGUMENTS)
+ self.handle_signal(self.CROS_DISKS_INTERFACE,
self.MOUNT_COMPLETED_SIGNAL,
self.MOUNT_COMPLETED_SIGNAL_ARGUMENTS)
@@ -231,6 +272,49 @@
"""
return self.interface.GetDeviceProperties(path)
+ def format(self, path, filesystem_type=None, options=None):
+ """Invokes the CrosDisks Format method.
+
+ Args:
+ path: The device path to format.
+ filesystem_type: The filesystem type used for formatting the device.
+ options: A list of options used for formatting the device.
+ """
+ if filesystem_type is None:
+ filesystem_type = ''
+ if options is None:
+ options = []
+ self.clear_signal_content(self.FORMAT_COMPLETED_SIGNAL)
+ self.interface.Format(path, filesystem_type, options)
+
+ def wait_for_format_completion(self):
+ """Waits for the CrosDisks FormatCompleted signal.
+
+ Returns:
+ The content of the FormatCompleted signal.
+ """
+ return self.wait_for_signal(self.FORMAT_COMPLETED_SIGNAL)
+
+ def expect_format_completion(self, expected_content):
+ """Waits and verifies for the CrosDisks FormatCompleted signal.
+
+ Args:
+ expected_content: The expected content of the FormatCompleted
+ signal, which can be partially specified.
+ Only specified fields are compared between the
+ actual and expected content.
+
+ Returns:
+ The actual content of the FormatCompleted signal.
+
+ Raises:
+ error.TestFail: A test failure when there is a mismatch between the
+ actual and expected content of the FormatCompleted
+ signal.
+ """
+ return self.expect_signal(self.FORMAT_COMPLETED_SIGNAL,
+ expected_content)
+
def mount(self, path, filesystem_type=None, options=None):
"""Invokes the CrosDisks Mount method.
@@ -277,24 +361,13 @@
Returns:
The actual content of the MountCompleted signal.
-
Raises:
error.TestFail: A test failure when there is a mismatch between the
actual and expected content of the MountCompleted
signal.
"""
- actual_content = self.wait_for_mount_completion()
- logging.debug("MountCompleted signal: expected=%s actual=%s",
- expected_content, actual_content)
- for argument in self.MOUNT_COMPLETED_SIGNAL_ARGUMENTS:
- if argument not in expected_content:
- continue
- if actual_content[argument] != expected_content[argument]:
- raise error.TestFail(
- ('MountCompleted signal not matched on "%s": '
- 'expected=%s, actual=%s') %
- (argument, expected_content, actual_content))
- return actual_content
+ return self.expect_signal(self.MOUNT_COMPLETED_SIGNAL,
+ expected_content)
class CrosDisksTester(GenericTesterMainLoop):
diff --git a/client/site_tests/platform_CrosDisksFormat/control b/client/site_tests/platform_CrosDisksFormat/control
new file mode 100644
index 0000000..33cc65c
--- /dev/null
+++ b/client/site_tests/platform_CrosDisksFormat/control
@@ -0,0 +1,21 @@
+# 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 = "ChromeOS Team"
+NAME = "platform_CrosDisksFormat"
+PURPOSE = "Verify that cros-disks can format supported filesystems correctly"
+
+CRITERIA = """
+"""
+TIME = "SHORT"
+TEST_CATEGORY = "Functional"
+TEST_CLASS = "platform"
+TEST_TYPE = "client"
+
+DOC = """
+Calls cros-disks to format supported filesystems
+"""
+
+job.run_test('platform_CrosDisksFormat', timeout_s=10,
+ config_file='vfat_tests', tag='vfat')
diff --git a/client/site_tests/platform_CrosDisksFormat/platform_CrosDisksFormat.py b/client/site_tests/platform_CrosDisksFormat/platform_CrosDisksFormat.py
new file mode 100644
index 0000000..057827d
--- /dev/null
+++ b/client/site_tests/platform_CrosDisksFormat/platform_CrosDisksFormat.py
@@ -0,0 +1,85 @@
+# 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 logging
+import json
+
+from autotest_lib.client.bin import test
+from autotest_lib.client.common_lib import error
+from autotest_lib.client.cros.cros_disks import CrosDisksTester
+from autotest_lib.client.cros.cros_disks import VirtualFilesystemImage
+from autotest_lib.client.cros.cros_disks import DefaultFilesystemTestContent
+
+
+class CrosDisksFormatTester(CrosDisksTester):
+ """A tester to verify format support in CrosDisks.
+ """
+ def __init__(self, test, test_configs):
+ super(CrosDisksFormatTester, self).__init__(test)
+ self._test_configs = test_configs
+
+ def _run_test_config(self, config):
+ logging.info('Testing "%s"', config['description'])
+ is_experimental = config.get('experimental_features_enabled', False)
+ filesystem_type = config['filesystem_type']
+ format_options = config.get('format_options')
+ # Create a zero-filled virtual filesystem image to help stimulate
+ # a removable drive.
+ with VirtualFilesystemImage(
+ block_size=1024,
+ block_count=65536,
+ filesystem_type=filesystem_type) as image:
+ # Attach the zero-filled virtual filesystem image to a loop device
+ # without actually formatting it.
+ device_file = image.attach_to_loop_device()
+
+ self.cros_disks.experimental_features_enabled = is_experimental
+
+ # Format the virtual filesystem image via CrosDisks.
+ self.cros_disks.format(device_file, filesystem_type, format_options)
+ expected_format_completion = {
+ 'path': device_file
+ }
+ if 'expected_format_status' in config:
+ expected_format_completion['status'] = \
+ config['expected_format_status']
+ result = self.cros_disks.expect_format_completion(
+ expected_format_completion)
+
+ if result['status'] == 0:
+ # Test creating and verifying content the formatted device.
+ logging.info("Test filesystem access on formatted device")
+ test_content = DefaultFilesystemTestContent()
+ mount_path = image.mount()
+ if not test_content.create(mount_path):
+ raise error.TestFail("Failed to create test content")
+ if not test_content.verify(mount_path):
+ raise error.TestFail("Failed to verify test content")
+
+ def test_using_virtual_filesystem_image(self):
+ experimental = self.cros_disks.experimental_features_enabled
+ try:
+ for config in self._test_configs:
+ self._run_test_config(config)
+ finally:
+ # Always restore the original value of ExperimentalFeaturesEnabled
+ # property, so cros-disks maintains in the same state of support
+ # experimental features before and after tests.
+ self.cros_disks.experimental_features_enabled = experimental
+
+ def get_tests(self):
+ return [self.test_using_virtual_filesystem_image]
+
+
+class platform_CrosDisksFormat(test.test):
+ version = 1
+
+ def run_once(self, *args, **kwargs):
+ test_configs = []
+ config_file = '%s/%s' % (self.bindir, kwargs['config_file'])
+ with open(config_file, 'rb') as f:
+ test_configs.extend(json.load(f))
+
+ tester = CrosDisksFormatTester(self, test_configs)
+ tester.run(*args, **kwargs)
diff --git a/client/site_tests/platform_CrosDisksFormat/vfat_tests b/client/site_tests/platform_CrosDisksFormat/vfat_tests
new file mode 100644
index 0000000..49214fe
--- /dev/null
+++ b/client/site_tests/platform_CrosDisksFormat/vfat_tests
@@ -0,0 +1,7 @@
+[
+ {
+ "description": "VFAT filesystem",
+ "filesystem_type": "vfat",
+ "expected_format_status": 0
+ }
+]