Alexis Savery | 6b11f57 | 2019-05-01 18:29:39 -0700 | [diff] [blame] | 1 | # Copyright 2019 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 os, re, logging |
| 6 | from autotest_lib.client.common_lib import error |
| 7 | from autotest_lib.client.bin import test, utils |
| 8 | |
| 9 | class blktests(test.test): |
| 10 | """ |
| 11 | Runs the blktests suite. |
| 12 | """ |
| 13 | |
| 14 | version = 1 |
| 15 | |
| 16 | BLKTESTS_PATH = '/mnt/stateful_partition/unencrypted/cache' |
| 17 | BLKTESTS_TEST_DIR = "/usr/local/blktests" |
| 18 | CONFIG_FILE = '/usr/local/blktests/config' |
| 19 | |
| 20 | FAILED_RE = re.compile(r'.*\[failed\].*', re.DOTALL) |
| 21 | DEVICE_RE = re.compile(r'/dev/(sd[a-z]|mmcblk[0-9]+|nvme[0-9]+)p?[0-9]*') |
| 22 | |
| 23 | devs=[] |
| 24 | loop_devs=[] |
| 25 | files=[] |
| 26 | exclude=[] |
| 27 | |
| 28 | def setup_configs(self, devices): |
| 29 | """ |
| 30 | Setup the blk devices to test. |
| 31 | @param devs: The desired blk devices to test (BLK: real blk |
| 32 | device, LOOP_FILE: loop device over file, or LOOP_BLK: |
| 33 | loop device over real blk device). |
| 34 | """ |
| 35 | |
| 36 | for dev in devices: |
| 37 | if dev == 'BLK': |
| 38 | dev_name = utils.get_free_root_partition() |
| 39 | self.devs.append(dev_name) |
| 40 | # block/013 tries to reread the partition table of the device |
| 41 | # This won't work when run on a block device partition, so we |
| 42 | # will exclude the test. |
| 43 | self.exclude.append("block/013") |
| 44 | elif dev == 'LOOP_FILE': |
| 45 | file_name = 'blktests_test' |
| 46 | file_loc = os.path.join(self.BLKTESTS_PATH, file_name) |
| 47 | utils.system('fallocate -l 10M %s' % file_loc) |
| 48 | loop_dev = utils.system_output('losetup -f -P --show %s' |
| 49 | % file_loc) |
| 50 | self.devs.append(loop_dev) |
| 51 | self.loop_devs.append(loop_dev) |
| 52 | self.files.append(file_loc) |
| 53 | elif dev == 'LOOP_BLK': |
| 54 | blk_dev = utils.get_free_root_partition() |
| 55 | loop_dev = utils.system_output('losetup -f -P --show %s' |
| 56 | % blk_dev) |
| 57 | self.devs.append(loop_dev) |
| 58 | self.loop_devs.append(loop_dev) |
| 59 | elif self.DEVICE_RE.match(dev): |
| 60 | if dev == utils.get_root_partition(): |
| 61 | raise error.TestError("Can't run the test on the root " |
| 62 | "partition.") |
| 63 | elif dev == utils.get_kernel_partition(): |
| 64 | raise error.TestError("Can't run the test on the kernel " |
| 65 | "partition.") |
| 66 | elif dev == utils.concat_partition(utils.get_root_device(), 1): |
| 67 | raise error.TestError("Can't run the test on the stateful " |
| 68 | "partition.") |
| 69 | self.devs.append(dev) |
| 70 | else: |
| 71 | raise error.TestError("Invalid device specified") |
| 72 | test_devs = ' '.join(self.devs) |
| 73 | exclusions = "" |
| 74 | if self.exclude: |
| 75 | exclusions = "EXCLUDE=(%s)" % ' '.join(self.exclude) |
| 76 | config = "TEST_DEVS=(%s) %s" % (test_devs, exclusions) |
| 77 | logging.debug("Test config: %s", config) |
| 78 | configFile = open(self.CONFIG_FILE, 'w') |
| 79 | configFile.write(config) |
| 80 | configFile.close() |
| 81 | |
| 82 | def cleanup(self): |
| 83 | """ |
| 84 | Clean up the environment by removing any created files and loop devs. |
| 85 | """ |
| 86 | for dev in self.loop_devs: |
| 87 | utils.system('losetup -d %s' % dev) |
| 88 | for f in self.files: |
| 89 | utils.system('rm %s' % f, ignore_status=True) |
| 90 | if os.path.isfile(self.CONFIG_FILE): |
| 91 | os.remove(self.CONFIG_FILE) |
| 92 | |
| 93 | def run_once(self, devices=['LOOP_FILE']): |
| 94 | """ |
| 95 | Setup the config file and run blktests. |
| 96 | |
| 97 | @param devices: The desired block devices to test (BLK: real block |
| 98 | device, LOOP_FILE: loop device over file, or LOOP_BLK: |
| 99 | loop device over real block device). |
| 100 | """ |
| 101 | os.chdir(self.BLKTESTS_TEST_DIR) |
| 102 | self.setup_configs(devices) |
| 103 | output = utils.system_output('bash ./check', |
| 104 | ignore_status=True, retain_output=True) |
| 105 | if self.FAILED_RE.match(output): |
| 106 | raise error.TestError('Test error, check debug logs for complete ' |
| 107 | 'test output') |