예제 #1
0
def test_tester_smart(Device: pySMART.Device):
    Device.run_selftest = MagicMock(return_value=(0, None, 3))
    Device.update = MagicMock()
    Device.tests = [MagicMock()]
    Device.tests[0].remain = '0%'
    Device.tests[0].hours = '24'
    Device.tests[0].LBA = '0'
    Device.tests[0].type = 'foo-type'
    Device.tests[0].status = 'foo-status'
    Device.attributes = [None] * 256
    Device.attributes[9] = MagicMock()
    Device.attributes[9].raw = 99
    Device.attributes[12] = MagicMock()
    Device.attributes[12].raw = '11'
    Device.assessment = 'PASS'
    r = Tester.smart('/foo/bar', test_type=Smart.short)
    assert r == {
        'lifetime': 24,
        '@type': 'TestHardDrive',
        'error': False,
        'type': 'foo-type',
        'status': 'foo-status',
        'firstError': 0,
        'passedLifetime': 99,
        'assessment': True,
        'powerCycleCount': 11
    }
예제 #2
0
파일: tester.py 프로젝트: eReuse/workbench
    def smart(cls, disk: str, test_type: Smart) -> dict:
        # Enable SMART on hard drive
        with catch_warnings():
            filterwarnings('error')
            try:
                hdd = Device(disk)  # type: Device
            except Warning:
                status = 'SMART cannot be enabled on this device.'
                print(status, file=sys.stderr)
                return {
                    '@type': 'TestHardDrive',
                    'error': True,
                    'status': status
                }
        status_code, status_message, completion_time = hdd.run_selftest(
            test_type.value)
        if status_code > 1:
            print(status_message, file=sys.stderr)
            return {
                '@type': 'TestHardDrive',
                'error': True,
                'status': status_message,
            }

        # get estimated end of the test
        try:
            test_end = parser.parse(completion_time)
        except TypeError:  # completion_time is None, estimate end time
            duration = 2 if test_type == Smart.short else 120
            test_end = datetime.now() + timedelta(minutes=duration)
        print('            It will finish around {}:'.format(test_end))

        # follow progress of test until it ends or the estimated time is reached
        remaining = 100  # test completion pending percentage
        with tqdm(total=remaining, leave=True) as bar:
            while remaining > 0:
                sleep(2)  # wait a few seconds between smart retrievals
                hdd.update()
                try:
                    last_test = hdd.tests[0]
                except (TypeError, IndexError):
                    pass
                    # The suppress: test is None, no tests
                    # work around because SMART has not been initialized
                    # yet but pySMART library doesn't wait
                    # Just ignore the error because we alreaday have an
                    # estimation of the ending time
                else:
                    last = remaining
                    with suppress(ValueError):
                        remaining = int(last_test.remain.strip('%'))
                    completed = last - remaining
                    if completed > 0:
                        bar.update(completed)

                # only allow a few seconds more than the estimated time
                if datetime.now() > test_end + cls.SMART_GRACE_TIME:
                    break
        # show last test
        hdd.update()
        last_test = hdd.tests[0]
        try:
            lba_first_error = int(last_test.LBA,
                                  0)  # accept hex and decimal value
        except ValueError:
            lba_first_error = None
        ret = {
            '@type': 'TestHardDrive',
            'type': last_test.type,
            'error': bool(lba_first_error),
            'status': last_test.status,
            'firstError': lba_first_error,
            'passedLifetime': int(hdd.attributes[9].raw),
            'assessment': True if hdd.assessment == 'PASS' else False
        }
        with suppress(ValueError):
            ret['lifetime'] = int(last_test.hours)
        for key, name in cls.SMART_ATTRIBUTES.items():
            with suppress(AttributeError):
                ret[name] = int(hdd.attributes[key].raw)
        return ret