1# Copyright 2017 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import logging
6import json
7import tempfile
8
9from autotest_lib.client.bin import test
10from autotest_lib.client.bin import utils
11from autotest_lib.client.common_lib import error
12from autotest_lib.client.cros.cros_disks import CrosDisksTester
13from autotest_lib.client.cros.cros_disks import VirtualFilesystemImage
14from autotest_lib.client.cros.cros_disks import DefaultFilesystemTestContent
15
16
17class CrosDisksRenameTester(CrosDisksTester):
18    """A tester to verify rename support in CrosDisks.
19    """
20    def __init__(self, test, test_configs):
21        super(CrosDisksRenameTester, self).__init__(test)
22        self._test_configs = test_configs
23
24    def _run_test_config(self, config):
25        logging.info('Testing "%s"', config['description'])
26        filesystem_type = config.get('filesystem_type')
27        mount_filesystem_type = config.get('mount_filesystem_type')
28        mount_options = config.get('mount_options')
29        volume_name = config.get('volume_name')
30
31        # Create a zero-filled virtual filesystem image to help simulate
32        # a removable drive and test disk renaming for different file system
33        # types.
34        with VirtualFilesystemImage(
35                block_size=1024,
36                block_count=65536,
37                filesystem_type=filesystem_type,
38                mount_filesystem_type=mount_filesystem_type,
39                mkfs_options=config.get('mkfs_options')) as image:
40            # Create disk with the target file system type.
41            image.format()
42            image.mount(options=['sync'])
43            test_content = DefaultFilesystemTestContent()
44            image.unmount()
45
46            device_file = image.loop_device
47            # Mount through API to assign appropriate group on block device that
48            # depends on file system type.
49            self.cros_disks.mount(device_file, filesystem_type,
50                                  mount_options)
51            expected_mount_completion = {
52                'status': config['expected_mount_status'],
53                'source_path': device_file,
54            }
55
56            if 'expected_mount_path' in config:
57                expected_mount_completion['mount_path'] = \
58                    config['expected_mount_path']
59            result = self.cros_disks.expect_mount_completion(
60                    expected_mount_completion)
61            self.cros_disks.unmount(device_file)
62
63            self.cros_disks.rename(device_file, volume_name)
64            expected_rename_completion = {
65                'path': device_file
66            }
67
68            if 'expected_rename_status' in config:
69                expected_rename_completion['status'] = \
70                        config['expected_rename_status']
71            result = self.cros_disks.expect_rename_completion(
72                expected_rename_completion)
73
74            if result['status'] == 0:
75                # Test creating and verifying content of the renamed device.
76                logging.info("Test filesystem access on renamed device")
77                test_content = DefaultFilesystemTestContent()
78                mount_path = image.mount()
79                if not test_content.create(mount_path):
80                    raise error.TestFail("Failed to create test content")
81                if not test_content.verify(mount_path):
82                    raise error.TestFail("Failed to verify test content")
83                # Verify new volume name
84                if volume_name != image.get_volume_label():
85                    raise error.TestFail("Failed to rename the drive")
86
87    def test_using_virtual_filesystem_image(self):
88        try:
89            for config in self._test_configs:
90                self._run_test_config(config)
91        except RuntimeError:
92            cmd = 'ls -la %s' % tempfile.gettempdir()
93            logging.debug(utils.run(cmd))
94            raise
95
96    def get_tests(self):
97        return [self.test_using_virtual_filesystem_image]
98
99
100class platform_CrosDisksRename(test.test):
101    version = 1
102
103    def run_once(self, *args, **kwargs):
104        test_configs = []
105        config_file = '%s/%s' % (self.bindir, kwargs['config_file'])
106        with open(config_file, 'rb') as f:
107            test_configs.extend(json.load(f))
108
109        tester = CrosDisksRenameTester(self, test_configs)
110        tester.run(*args, **kwargs)
111