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