• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (c) 2010 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 os
6import re
7
8from autotest_lib.client.bin import test, utils
9from autotest_lib.client.common_lib import error
10
11class hardware_SsdDetection(test.test):
12    """Verify that a flash device is present. """
13
14    version = 1
15    # Keep a list of boards that are expected to ship with hard drive.
16    boards_with_hdd = ['butterfly', 'kiev', 'parrot', 'stout']
17
18    def setup(self):
19        """
20        create a empty srcdir to prevent the error that checks
21        .version file
22        """
23        if not os.path.exists(self.srcdir):
24            utils.system('mkdir %s' % self.srcdir)
25
26
27    def run_once(self, check_link_speed=()):
28        """
29        Use rootdev to find the underlying block device even if the
30        system booted to /dev/dm-0.
31        """
32        device = utils.get_root_device()
33
34        def is_fixed(dev):
35            """ Check the device is fixed.
36
37            @param dev: device to check, i.e. 'sda'.
38            """
39            sysfs_path = '/sys/block/%s/removable' % dev
40            return (os.path.exists(sysfs_path) and
41                    open(sysfs_path).read().strip() == '0')
42
43        # Catch device name like sda, mmcblk0, nvme0n1.
44        device_re = re.compile(r'^/dev/([a-zA-Z0-9]+)$')
45        dev = device_re.findall(device)
46        if len(dev) != 1 or not is_fixed(dev[0]):
47            raise error.TestFail('The main disk %s is not fixed' % dev)
48
49        # If it is an mmcblk or nvme device, then it is SSD.
50        # Else run hdparm to check for SSD.
51        if re.search("nvme", device):
52            return
53
54        if re.search("mmcblk", device):
55            return
56
57        type_path = '/sys/block/%s/device/type' % dev[0]
58        type = os.path.realpath(type_path)
59        if re.search("ufs", type):
60            return
61
62        hdparm = utils.run('/sbin/hdparm -I %s' % device)
63
64        # Check if device is a SSD
65        match = re.search(r'Nominal Media Rotation Rate: (.+)$',
66                          hdparm.stdout, re.MULTILINE)
67        if match and match.group(1):
68            if match.group(1) != 'Solid State Device':
69                if utils.get_board() in self.boards_with_hdd:
70                    return
71                raise error.TestFail('The main disk is not a SSD, '
72                    'Rotation Rate: %s' % match.group(1))
73        else:
74            raise error.TestFail(
75                'Rotation Rate not reported from the device, '
76                'unable to ensure it is a SSD')
77
78        # Check if SSD is > 8GB in size
79        match = re.search("device size with M = 1000\*1000: (.+) MBytes",
80                          hdparm.stdout, re.MULTILINE)
81        if match and match.group(1):
82            size = int(match.group(1))
83            self.write_perf_keyval({"mb_ssd_device_size" : size})
84        else:
85            raise error.TestFail(
86                'Device size info missing from the device')
87
88        # Check supported link speed.
89        #
90        # check_link_speed is an empty tuple by default, which does not perform
91        # link speed checking.  You can run the test while specifying
92        # check_link_speed=('1.5Gb/s', '3.0Gb/s') to check the 2 signaling
93        # speeds are both supported.
94        for link_speed in check_link_speed:
95            if not re.search(r'Gen. signaling speed \(%s\)' % link_speed,
96                             hdparm.stdout, re.MULTILINE):
97                raise error.TestFail('Link speed %s not supported' % link_speed)
98