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 5import os, re, logging 6from autotest_lib.client.common_lib import error 7from autotest_lib.client.bin import test, utils 8 9class 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') 108