Home | History | Annotate | Download | only in hardware_StorageWearoutDetect
      1 # Copyright (c) 2014 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 
      5 import logging, os, re
      6 from autotest_lib.client.bin import test, utils
      7 from autotest_lib.client.common_lib import error
      8 
      9 
     10 class hardware_StorageWearoutDetect(test.test):
     11     """
     12     Check wear out status for storage device available in SMART for SSD and
     13     in ext_csd for eMMC version 5.0 or later. For previous version of eMMC,
     14     it will be treat as data not available.
     15 
     16     The test will be failed if:
     17     - At least one SMART variable has value under its threshold
     18       or
     19     - eMMC wear out status variable is in 90-100% band or higher.
     20     """
     21 
     22     version = 1
     23     STORAGE_INFO_PATH = '/var/log/storage_info.txt'
     24     STORAGE_INFO_UPDATE_PATH = '/usr/share/userfeedback/scripts/storage_info'
     25 
     26     # Example     "   Model Number:    LITEONIT LSS-32L6G-HP"
     27     SSD_DETECT = r"\s*Model Number:\s*(?P<model>.*)\s*$"
     28 
     29     # Example     "   Extended CSD rev 1.7 (MMC 5.0)"
     30     MMC_DETECT = r"\s*Extended CSD rev.*MMC (?P<version>\d+.\d+)"
     31 
     32     # Field meaning and example line that have failing attribute
     33     # ID# ATTRIBUTE_NAME          FLAGS    VALUE WORST THRESH FAIL RAW_VALUE
     34     # 184 End-to-End_Error        PO--CK   001   001   097    NOW  135
     35     SSD_FAIL = r"""\s*(?P<param>\S+\s\S+)      # ID and attribute name
     36                    \s+[P-][O-][S-][R-][C-][K-] # flags
     37                    (\s+\d{3}){3}               # three 3-digits numbers
     38                    \s+NOW                      # fail indicator"""
     39 
     40     # Ex "Device life time estimation type A [DEVICE_LIFE_TIME_EST_TYP_A: 0x01]"
     41     # 0x0a means 90-100% band, 0x0b means over 100% band -> find not digit
     42     MMC_FAIL = r".*(?P<param>DEVICE_LIFE_TIME_EST_TYP_.): 0x0\D"
     43 
     44 
     45     def run_once(self, use_cached_result=True):
     46         """
     47         Run the test
     48 
     49         @param use_cached_result: Use the result that generated when machine
     50                                   booted or generate new one.
     51         """
     52 
     53         if not use_cached_result:
     54             if not os.path.exists(self.STORAGE_INFO_UPDATE_PATH):
     55                 msg = str('Test failed with error: %s not exist'
     56                           % self.STORAGE_INFO_UPDATE_PATH)
     57                 raise error.TestFail(msg)
     58             utils.system(self.STORAGE_INFO_UPDATE_PATH)
     59 
     60         # Check that storage_info file exist.
     61         if not os.path.exists(self.STORAGE_INFO_PATH):
     62             msg = str('Test failed with error: %s not exist'
     63                       % self.STORAGE_INFO_PATH)
     64             raise error.TestFail(msg)
     65 
     66         mmc_detect = False
     67         ssd_detect = False
     68         legacy_mmc = False
     69         fail_msg = ''
     70 
     71         with open(self.STORAGE_INFO_PATH) as f:
     72             for line in f:
     73                 m = re.match(self.SSD_DETECT, line)
     74                 if m:
     75                     model = m.group('model')
     76                     ssd_detect = True
     77                     logging.info('Found SSD model %s', model)
     78 
     79                 m = re.match(self.MMC_DETECT, line)
     80                 if m:
     81                     version = m.group('version')
     82                     if float(version) < 5.0:
     83                         legacy_mmc = True
     84                     mmc_detect = True
     85                     logging.info('Found eMMC version %s', version)
     86 
     87                 m = re.match(self.SSD_FAIL, line, re.X)
     88                 if m:
     89                     param = m.group('param')
     90                     fail_msg += 'SSD failure ' + param
     91 
     92                 m = re.match(self.MMC_FAIL, line)
     93                 if m:
     94                     param = m.group('param')
     95                     fail_msg += 'MMC failure ' + param
     96 
     97         if not ssd_detect and not mmc_detect:
     98             raise error.TestFail('Can not detect storage device.')
     99 
    100         if fail_msg:
    101             msg = 'Detected wearout parameter:%s' % fail_msg
    102             raise error.TestFail(msg)
    103 
    104         if legacy_mmc:
    105             msg = 'eMMC version %s detected. ' % version
    106             msg += 'Wearout attributes are supported in eMMC 5.0 and later.'
    107             logging.info(msg)
    108