diff --git a/fs/fsx.py b/fs/fsx.py index f8632a59c..798f09c06 100644 --- a/fs/fsx.py +++ b/fs/fsx.py @@ -11,28 +11,40 @@ # See LICENSE for more details. # Copyright: 2017 IBM # Author: Harish +# Ayush Jain # -import os +import os, re from avocado import Test -from avocado.utils import process, genio +from avocado.utils import process, genio, archive, build from avocado.utils.software_manager.manager import SoftwareManager from avocado.utils.partition import Partition - class Fsx(Test): ''' The Fsx test is a file system exerciser test :avocado: tags=fs ''' + def parse_results(self,results): + pattern = re.compile(r"\b(passed|failed|broken|skipped|warnings)\s+(\d+)") + matches = pattern.findall(results.stderr.decode("utf-8")) + result_dict = dict(matches) + for param,count in result_dict.items(): + self.log.info(f"{str(param)} : {str(count)}") + if(int(result_dict["failed"]) > 0 or int(result_dict["broken"]) > 0): + self.fail('Fsx test failed') + elif(int(result_dict["skipped"]) > 0): + self.cancel(f'Fsx test {result_dict["skipped"]} skipped') + elif(int(result_dict["warnings"]) > 0): + self.log.warn(f'Fsx test {result_dict["warnings"]} warns') @staticmethod - def mount_point(mount_dir): + def mount_point(dir): lines = genio.read_file('/proc/mounts').rstrip('\t\r\0').splitlines() for substr in lines: mop = substr.split(" ")[1] - if mop == mount_dir: + if mop == dir: return True return False @@ -46,63 +58,86 @@ def setup_tmpfs_dir(self): # check for THP page cache self.check_thp() - if not os.path.isdir(self.mount_dir): - os.makedirs(self.mount_dir) + if not os.path.isdir(self.dir): + os.makedirs(self.dir) self.device = None - if not self.mount_point(self.mount_dir): + if not self.mount_point(self.dir): if self.thp: self.device = Partition( - device="none", mountpoint=self.mount_dir, + device=self.disk, mountpoint=self.dir, mount_options="huge=always") else: self.device = Partition( - device="none", mountpoint=self.mount_dir) - self.device.mount(mountpoint=self.mount_dir, fstype="tmpfs") + device=self.disk, mountpoint=self.dir) + self.device.mount(mountpoint=self.dir, fstype="tmpfs", mnt_check=False) def setUp(self): ''' Setup fsx ''' smm = SoftwareManager() - for package in ['gcc', 'make']: + for package in ['gcc', 'make', 'automake']: if not smm.check_installed(package) and not smm.install(package): self.cancel(package + ' is needed for the test to be run') - fsx = self.fetch_asset( - 'https://raw.githubusercontent.com/linux-test-project/ltp/' - 'master/testcases/kernel/fs/fsx-linux/fsx-linux.c', expire='7d') - os.chdir(self.workdir) - process.system('gcc -o fsx %s' % fsx, shell=True, ignore_status=True) - self.thp = False + self.thp_page_cache = self.params.get('thp_page_cache', default=False) + self.disk = self.params.get('disk', default="none") + if self.thp_page_cache: + self.dir = self.params.get('dir', default=self.workdir) + if self.dir: + self.setup_tmpfs_dir() + self.output = os.path.join(self.dir, 'result') + else: + self.cancel("dir not specified") + else: + self.output = self.params.get('output_file', default=None) + if not self.output: + self.output=os.path.join(self.workdir,"result") + + if not os.path.exists(self.output): + os.makedirs(self.output) + + url = self.params.get( + 'url', default='https://github.com/linux-test-project/ltp/archive/master.zip') + match = next((ext for ext in [".zip", ".tar"] if ext in url), None) + tarball = '' + if match: + tarball = self.fetch_asset( + "ltp-master%s" % match, locations=[url], expire='7d') + else: + self.cancel("Provided LTP Url is not valid") + self.ltpdir_parent = os.path.join(self.workdir,'/ltp') + if not os.path.exists(self.ltpdir_parent): + os.mkdir(self.ltpdir_parent) + archive.extract(tarball, self.ltpdir_parent) + self.ltp_dir = os.path.join(self.ltpdir_parent, "ltp-master") + os.chdir(self.ltp_dir) + build.make(self.ltp_dir, extra_args='autotools') + process.system('./configure') + + self.test_file_max_size = self.params.get('test_file_max_size', default='1000000') + self.single_op_max_size = self.params.get('single_op_max_size', default='1000000') + self.total_ops = self.params.get('total_ops', default='1000') + self.num_times = self.params.get('num_times', default='1') def test(self): ''' Run Fsx test for exercising file system ''' - file_ub = self.params.get('file_ub', default='1000000') - op_ub = self.params.get('op_ub', default='1000000') - output = self.params.get('output_file', default='/tmp/result') - num_times = self.params.get('num_times', default='10000') - self.mount_dir = self.params.get('tmpfs_mount_dir', default=None) - thp_page_cache = self.params.get('thp_page_cache', default=None) - - if thp_page_cache: - if self.mount_dir: - self.setup_tmpfs_dir() - output = os.path.join(self.mount_dir, 'result') - else: - self.cancel("tmpfs_mount_dir not specified") - else: - output = self.params.get('output_file', default='/tmp/result') - results = process.system_output( - './fsx -l %s -o %s -n -s 1 -N %s -d %s' - % (file_ub, op_ub, num_times, output)) + fsx_dir=os.path.join(self.ltp_dir,"testcases/kernel/fs/fsx-linux") + os.chdir(fsx_dir) + build.make(fsx_dir) - if b'All operations completed' not in results.splitlines()[-1]: - self.fail('Fsx test failed') + cmd = "TMPDIR=%s ./fsx-linux -l %s -o %s -N %s -i %s -D" \ + % (self.output, self.test_file_max_size, self.single_op_max_size, \ + self.total_ops, self.num_times) + + results = process.run(cmd,shell=True) + self.parse_results(results) def tearDown(self): - if self.mount_dir: - self.device.unmount() + if self.thp_page_cache: + if self.dir: + self.device.unmount() diff --git a/fs/fsx.py.data/fsx-mm.yaml b/fs/fsx.py.data/fsx-mm.yaml index d473e87f1..7bbfc767a 100644 --- a/fs/fsx.py.data/fsx-mm.yaml +++ b/fs/fsx.py.data/fsx-mm.yaml @@ -1,2 +1,13 @@ +url: 'https://github.com/linux-test-project/ltp/archive/master.zip' + thp_page_cache: True -tmpfs_mount_dir: '/mnt/tmpfs/' +disk: +dir: '/mnt/tmpfs' + +#only when mounting is not required +output_file: + +test_file_max_size: +single_op_max_size: +total_ops: +num_times: \ No newline at end of file