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