def init(context, path, template, force, **kwargs): """ Initialize a new tmt tree. By default tree is created in the current directory. Provide a PATH to create it in a different location. \b A tree can be optionally populated with example metadata: * 'mini' template contains a minimal plan and no tests, * 'base' template contains a plan and a beakerlib test, * 'full' template contains a 'full' story, an 'full' plan and a shell test. """ # Check for existing tree path = os.path.realpath(path) try: tree = tmt.Tree(path) # Are we creating a new tree under the existing one? if path == tree.root: echo("Tree '{}' already exists.".format(tree.root)) else: tree = None except tmt.utils.GeneralError: tree = None # Create a new tree if tree is None: try: fmf.Tree.init(path) tree = tmt.Tree(path) except fmf.utils.GeneralError as error: raise tmt.utils.GeneralError( "Failed to initialize tree in '{}': {}".format( path, error)) echo("Tree '{}' initialized.".format(tree.root)) # Populate the tree with example objects if requested if template == 'empty': non_empty_choices = [c for c in _init_template_choices if c != 'empty'] echo("To populate it with example content, use --template with " "{}.".format(listed(non_empty_choices, join='or'))) else: echo("Applying template '{}'.".format(template, _init_templates)) if template == 'mini': tmt.Plan.create('/plans/example', 'mini', tree, force) elif template == 'base': tmt.Test.create('/tests/example', 'beakerlib', tree, force) tmt.Plan.create('/plans/example', 'base', tree, force) elif template == 'full': tmt.Test.create('/tests/example', 'shell', tree, force) tmt.Plan.create('/plans/example', 'full', tree, force) tmt.Story.create('/stories/example', 'full', tree, force)
def main(click_contex, root, context, **kwargs): """ Test Management Tool """ # Show current tmt version and exit if kwargs.get('version'): print(f"tmt version: {tmt.__version__}") raise SystemExit(0) # Disable coloring if NO_COLOR is set if 'NO_COLOR' in os.environ: click_contex.color = False # Save click context and fmf context for future use tmt.utils.Common._save_context(click_contex) click_contex.obj = tmt.utils.Common() click_contex.obj.fmf_context = tmt.utils.context_to_dict(context) # Initialize metadata tree (from given path or current directory) tree = tmt.Tree(root or os.curdir) click_contex.obj.tree = tree # List of enabled steps click_contex.obj.steps = set() # Show overview of available tests, plans and stories if click_contex.invoked_subcommand is None: tmt.Test.overview(tree) tmt.Plan.overview(tree) tmt.Story.overview(tree)
def go(self): """ Discover available tests """ super(DiscoverFmf, self).go() testdir = os.path.join(self.workdir, 'tests') # Clone provided git repository if self.repository: self.info('repository', self.repository, 'green') self.debug(f"Clone '{self.repository}' to '{testdir}'.") self.run(f'git clone {self.repository} {testdir}') # Copy current directory to workdir else: directory = self.step.plan.run.tree.root self.info('directory', directory, 'green') self.debug("Copy '{}' to '{}'.".format(directory, testdir)) shutil.copytree(directory, testdir) # Checkout revision if requested if self.revision: self.info('revision', self.revision, 'green') self.debug(f"Checkout revision '{self.revision}'.") self.run(f"git checkout -f {self.revision}", cwd=testdir) # Initialize the metadata tree self.debug(f"Check metadata tree in '{testdir}'.") if self.opt('dry'): return self.tests_tree = tmt.Tree(testdir)
def finito(*args, **kwargs): tree = tmt.Tree(tree_path) click.echo( click.style('Found {0}.'.format( fmf.utils.listed(tree.testsets, 'testset')), fg='magenta')) for testset in tree.testsets: click.echo(click.style('\nTestset: {0}'.format(testset), fg='green')) testset.go()
def main(context, path): """ Test Management Tool """ # Initialize metadata tree global tree tree = tmt.Tree(path) # Show overview of available tests, plans and stories if context.invoked_subcommand is None: tmt.Test.overview() tmt.Plan.overview() tmt.Story.overview() return 'tmt'
def main(context, root, **kwargs): """ Test Management Tool """ # Initialize metadata tree tree = tmt.Tree(root) tree._context = context context.obj = tmt.utils.Common() context.obj.tree = tree # Show overview of available tests, plans and stories if context.invoked_subcommand is None: tmt.Test.overview(tree) tmt.Plan.overview(tree) tmt.Story.overview(tree)
def init(context, path, mini, full, force, **kwargs): """ Initialize a new tmt tree. By default tree is created in the current directory. Provide a PATH to create it in a different location. """ # Check for existing tree path = os.path.realpath(path) try: tree = tmt.Tree(path) # Are we creating a new tree under the existing one? if path == tree.root: echo("Tree '{}' already exists.".format(tree.root)) else: tree = None except tmt.utils.GeneralError: tree = None # Create a new tree if tree is None: try: fmf.Tree.init(path) tree = tmt.Tree(path) except fmf.utils.GeneralError as error: raise tmt.utils.GeneralError( "Failed to initialize tree in '{}': {}".format( path, error)) echo("Tree '{}' initialized.".format(tree.root)) # Populate the tree with example objects if requested if mini: tmt.Test.create('/tests/example', 'shell', tree, force) tmt.Plan.create('/plans/example', 'mini', tree, force) tmt.Story.create('/stories/example', 'mini', tree, force) if full: tmt.Test.create('/tests/example', 'shell', tree, force) tmt.Plan.create('/plans/example', 'full', tree, force) tmt.Story.create('/stories/example', 'full', tree, force)
def go(self): """ Go and perform the plugin task Discover available tests in this case. """ super().go() print("go() called") # Prepare test environment print("Code should prepare environment for tests.") # Use a tmt.Tree to apply possible command line filters tests = tmt.Tree(tree=tests).tests() self._tests = tests
def main(context, root, **kwargs): """ Test Management Tool """ # Initialize metadata tree root = root or os.curdir tree = tmt.Tree(root) tree._save_context(context) context.obj = tmt.utils.Common() context.obj.tree = tree # List of enabled steps context.obj.steps = set() # Show overview of available tests, plans and stories if context.invoked_subcommand is None: tmt.Test.overview(tree) tmt.Plan.overview(tree) tmt.Story.overview(tree)
def go(self): """ Discover available tests """ super(DiscoverShell, self).go() tests = fmf.Tree(dict(summary='tests')) # Check and process each defined shell test for data in self.data['tests']: # Create data copy (we want to keep original data for save() data = copy.deepcopy(data) # Extract name, make sure it is present try: name = data.pop('name') except KeyError: raise tmt.utils.SpecificationError( f"Missing test name in '{self.step.plan.name}'.") # Make sure that the test script is defined if 'test' not in data: raise tmt.utils.SpecificationError( f"Missing test script in '{self.step.plan.name}'.") # Prepare path to the test working directory (tree root by default) try: data['path'] = f"/tests{data['path']}" except KeyError: data['path'] = f"/tests" # Apply default test duration unless provided if 'duration' not in data: data['duration'] = tmt.base.DEFAULT_TEST_DURATION_L2 # Create a simple fmf node, adjust its name tests.child(name, data) # Copy directory tree (if defined) to the workdir directory = self.step.plan.my_run.tree.root testdir = os.path.join(self.workdir, 'tests') if directory: self.info('directory', directory, 'green') self.debug("Copy '{}' to '{}'.".format(directory, testdir)) shutil.copytree(directory, testdir, symlinks=True) else: os.makedirs(testdir) # Use a tmt.Tree to apply possible command line filters tests = tmt.Tree(tree=tests).tests(conditions=["manual is False"]) self._tests = tests
def main(click_contex, root, context, **kwargs): """ Test Management Tool """ # Save click context and fmf context for future use tmt.utils.Common._save_context(click_contex) click_contex.obj = tmt.utils.Common() click_contex.obj.fmf_context = tmt.utils.context_to_dict(context) # Initialize metadata tree (from given path or current directory) tree = tmt.Tree(root or os.curdir) click_contex.obj.tree = tree # List of enabled steps click_contex.obj.steps = set() # Show overview of available tests, plans and stories if click_contex.invoked_subcommand is None: tmt.Test.overview(tree) tmt.Plan.overview(tree) tmt.Story.overview(tree)
def go(self): """ Discover available tests """ super(DiscoverShell, self).go() tests = fmf.Tree(dict(summary='tests')) # Check and process each defined shell test for data in self.data['tests']: # Create data copy (we want to keep original data for save() data = copy.deepcopy(data) # Extract name, make sure it is present try: name = data.pop('name') except KeyError: raise tmt.utils.SpecificationError( f"Missing test name in '{self.step.plan.name}'.") # Make sure that the test script is defined if 'test' not in data: raise tmt.utils.SpecificationError( f"Missing test script in '{self.step.plan.name}'.") # Prepare path to the test working directory (tree root by default) try: data['path'] = f"/tests{data['path']}" except KeyError: data['path'] = f"/tests" # Apply default test duration unless provided if 'duration' not in data: data['duration'] = tmt.base.DEFAULT_TEST_DURATION_L2 # Create a simple fmf node, adjust its name tests.child(name, data) # Symlink tests directory to the plan work tree testdir = os.path.join(self.workdir, "tests") relative_path = os.path.relpath(self.step.plan.worktree, self.workdir) os.symlink(relative_path, testdir) # Use a tmt.Tree to apply possible command line filters tests = tmt.Tree(tree=tests).tests(conditions=["manual is False"]) self._tests = tests
def go(self): """ Discover available tests """ super(DiscoverShell, self).go() tests = fmf.Tree(dict(summary='tests')) path = False for data in self.data['tests']: # Extract name, make sure it is present try: name = data.pop('name') except KeyError: raise tmt.utils.SpecificationError( f"Missing test name in '{self.step.plan.name}'.") # Make sure that the test script is defined if 'test' not in data: raise tmt.utils.SpecificationError( f"Missing test script in '{self.step.plan.name}'.") # Adjust path if necessary (defaults to '.') try: data['path'] = f"/{self.name}/tests{data['path']}" path = True except KeyError: data['path'] = '.' # Create a simple fmf node, adjust its name tests.child(name, data) # Copy current directory to workdir only if any path specified if path: directory = self.step.plan.run.tree.root testdir = os.path.join(self.workdir, 'tests') self.info('directory', directory, 'green') self.debug("Copy '{}' to '{}'.".format(directory, testdir)) shutil.copytree(directory, testdir) # Use a tmt.Tree to apply possible command line filters tests = tmt.Tree(tree=tests).tests() # Summary of selected tests, test list in verbose mode summary = fmf.utils.listed(len(tests), 'test') + ' selected' self.info('tests', summary, 'green') for test in tests: self.verbose(test.name, color='red', shift=1) self._tests = tests
def go(self): """ Discover available tests """ super(DiscoverFmf, self).go() testdir = os.path.join(self.workdir, 'tests') # Clone provided git repository if self.repository: self.info('repository', self.repository, 'green') self.debug(f"Clone '{self.repository}' to '{testdir}'.") self.run(f'git clone {self.repository} {testdir}') # Copy current directory to workdir else: directory = self.step.plan.run.tree.root self.info('directory', directory, 'green') self.debug("Copy '{}' to '{}'.".format(directory, testdir)) shutil.copytree(directory, testdir) # Checkout revision if requested if self.revision: self.info('revision', self.revision, 'green') self.debug(f"Checkout revision '{self.revision}'.") self.run(f"git checkout -f {self.revision}", cwd=testdir) # Show filters if provided if self.filters: for filter_ in self.filters: self.info('filter', filter_, 'green') # Initialize the metadata tree self.debug(f"Check metadata tree in '{testdir}'.") # Nothing more to do here when in dry mode if self.opt('dry'): return [] tests = tmt.Tree(testdir).tests(filters=self.filters) # Modify test names and paths to make them unique for test in tests: test.name = f"/{self.name}{test.name}" test.path = f"/{self.name}/tests{test.path}" # Summary of selected tests, test list in verbose mode self.info('tests', listed(len(tests), 'test') + ' selected', 'green') for test in tests: self.verbose(test.name, color='red', shift=1) self._tests = tests
def go(self): """ Discover available tests """ super(DiscoverFmf, self).go() # Check url and path, prepare test directory url = self.get('url') path = self.get('path') testdir = os.path.join(self.workdir, 'tests') # Clone provided git repository (if url given) with disabled # prompt to ignore possibly missing or private repositories if url: self.info('url', url, 'green') self.debug(f"Clone '{url}' to '{testdir}'.") self.run(['git', 'clone', url, testdir], shell=False, env={"GIT_ASKPASS": "******"}) # Copy git repository root to workdir else: if path and not os.path.isdir(path): raise tmt.utils.DiscoverError( f"Provided path '{path}' is not a directory.") fmf_root = path or self.step.plan.my_run.tree.root # Check git repository root (use fmf root if not found) try: output = self.run('git rev-parse --show-toplevel', cwd=fmf_root, dry=True) git_root = output[0].strip('\n') except tmt.utils.RunError: self.debug(f"Git root not found, using '{fmf_root}.'") git_root = fmf_root # Set path to relative path from the git root to fmf root path = os.path.relpath(fmf_root, git_root) self.info('directory', git_root, 'green') self.debug(f"Copy '{git_root}' to '{testdir}'.") if not self.opt('dry'): shutil.copytree(git_root, testdir, symlinks=True) # Checkout revision if requested ref = self.get('ref') if ref: self.info('ref', ref, 'green') self.debug(f"Checkout ref '{ref}'.") self.run(['git', 'checkout', '-f', ref], cwd=testdir, shell=False) # Show current commit hash if inside a git repository try: hash_, _ = self.run('git rev-parse --short HEAD', cwd=testdir) self.verbose('hash', hash_.strip(), 'green') except (tmt.utils.RunError, AttributeError): pass # Adjust path and optionally show if path is None or path == '.': path = '' else: self.info('path', path, 'green') # Prepare the whole tree path and test path prefix tree_path = os.path.join(testdir, path.lstrip('/')) if not os.path.isdir(tree_path) and not self.opt('dry'): raise tmt.utils.DiscoverError( f"Metadata tree path '{path}' not found.") prefix_path = os.path.join('/tests', path.lstrip('/')) # Show filters and test names if provided # Check the 'test --filter' option first, then from discover filters = list(tmt.base.Test._opt('filters') or self.get('filter', [])) for filter_ in filters: self.info('filter', filter_, 'green') # Check the 'test --name' option first, then 'test' from discover names = list(tmt.base.Test._opt('names') or self.get('test', [])) if names: self.info('names', fmf.utils.listed(names), 'green') # Filter only modified tests if requested modified_only = self.get('modified-only') modified_url = self.get('modified-url') if modified_url: self.info('modified-url', modified_url, 'green') self.debug(f"Fetch also '{modified_url}' as 'reference'.") self.run(['git', 'remote', 'add', 'reference', modified_url], cwd=testdir, shell=False) self.run(['git', 'fetch', 'reference'], cwd=testdir, shell=False) if modified_only: modified_ref = self.get('modified-ref', tmt.utils.default_branch(testdir)) self.info('modified-ref', modified_ref, 'green') output = self.run([ 'git', 'log', '--format=', '--stat', '--name-only', f"{modified_ref}..HEAD" ], cwd=testdir, shell=False)[0] modified = set(f"^/{re.escape(name)}" for name in map(os.path.dirname, output.split('\n')) if name) self.debug(f"Limit to modified test dirs: {modified}", level=3) names.extend(modified) # Initialize the metadata tree, search for available tests self.debug(f"Check metadata tree in '{tree_path}'.") if self.opt('dry'): self._tests = [] return tree = tmt.Tree(path=tree_path, context=self.step.plan._fmf_context()) self._tests = tree.tests(filters=filters, names=names) # Prefix tests and handle library requires for test in self._tests: # Prefix test path with 'tests' and possible 'path' prefix test.path = os.path.join(prefix_path, test.path.lstrip('/')) # Check for possible required beakerlib libraries if test.require or test.recommend: test.require, test.recommend, _ = tmt.beakerlib.dependencies( test.require, test.recommend, parent=self)
from mock import Mock as MagicMock class Mock(MagicMock): @classmethod def __getattr__(cls, name): return Mock() MOCK_MODULES = ['testcloud', 'testcloud.image', 'testcloud.instance'] sys.modules.update((mod_name, Mock()) for mod_name in MOCK_MODULES) # Generate stories import tmt tree = tmt.Tree('.') areas = { '/stories/docs': 'Documentation', '/stories/cli': 'Command Line', '/stories/install': 'Installation', '/stories/coverage': 'Coverage', '/spec/core': 'Core', '/spec/tests': 'Tests', '/spec/plans': 'Plans', '/spec/steps': 'Steps', '/spec/stories': 'Stories', '/spec/context': 'Context', } os.makedirs('stories', exist_ok=True)
import tmt tree = tmt.Tree('data') def test_root(): root = tree.tests(names=['/root'])[0] assert root.summary == 'Test in the root directory' assert root.path == '/' def test_simple(): simple = tree.tests(names=['/simple'])[0] assert simple.summary == 'Simple test in a separate directory' assert simple.path == '/simple' def test_virtual(): for virtual in tree.tests(names=['/virtual']): assert 'Virtual test' in virtual.summary assert virtual.path == '/virtual'
def go(self): """ Discover available tests """ super(DiscoverFmf, self).go() # Check url and path, prepare test directory url = self.get('url') path = self.get('path') testdir = os.path.join(self.workdir, 'tests') dist_git_source = self.get('dist-git-source', False) # Raise an exception if --fmf-id uses w/o url and git root # doesn't exist for discovered plan if self.opt('fmf_id'): def assert_git_url(plan_name=None): try: subprocess.run('git rev-parse --show-toplevel'.split(), stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, check=True) except subprocess.CalledProcessError: raise tmt.utils.DiscoverError( f"`tmt run discover --fmf-id` without `url` option in " f"plan `{plan_name}` can be used only within" f" git repo.") # It covers only one case, when there is: # 1) no --url on CLI # 2) plan w/o url exists in test run if not self.opt('url'): try: fmf_tree = fmf.Tree(os.getcwd()) except fmf.utils.RootError: raise tmt.utils.DiscoverError( f"No metadata found in the current directory. " f"Use 'tmt init' to get started.") for i, attr in enumerate(fmf_tree.climb()): try: plan_url = attr.data.get('discover').get('url') plan_name = attr.name if not plan_url: assert_git_url(plan_name) except AttributeError: pass # All other cases are covered by this condition if not url: assert_git_url(self.step.plan.name) # Clone provided git repository (if url given) with disabled # prompt to ignore possibly missing or private repositories if url: self.info('url', url, 'green') self.debug(f"Clone '{url}' to '{testdir}'.") self.run(['git', 'clone', url, testdir], env={"GIT_ASKPASS": "******"}) # Copy git repository root to workdir else: # Path for distgit sources cannot be checked until the # tarball is extracted if path and not os.path.isdir(path) and not dist_git_source: raise tmt.utils.DiscoverError( f"Provided path '{path}' is not a directory.") if dist_git_source: git_root = self.step.plan.my_run.tree.root else: fmf_root = path or self.step.plan.my_run.tree.root if fmf_root is None: raise tmt.utils.DiscoverError( f"No metadata found in the current directory.") # Check git repository root (use fmf root if not found) try: output = self.run(["git", "rev-parse", "--show-toplevel"], cwd=fmf_root, dry=True) git_root = output[0].strip('\n') except tmt.utils.RunError: self.debug(f"Git root not found, using '{fmf_root}.'") git_root = fmf_root # Set path to relative path from the git root to fmf root path = os.path.relpath(fmf_root, git_root) self.info('directory', git_root, 'green') self.debug(f"Copy '{git_root}' to '{testdir}'.") if not self.opt('dry'): shutil.copytree(git_root, testdir, symlinks=True) # Checkout revision if requested ref = self.get('ref') if ref: self.info('ref', ref, 'green') self.debug(f"Checkout ref '{ref}'.") self.run(['git', 'checkout', '-f', str(ref)], cwd=testdir) # Show current commit hash if inside a git repository try: hash_, _ = self.run(["git", "rev-parse", "--short", "HEAD"], cwd=testdir) self.verbose('hash', hash_.strip(), 'green') except (tmt.utils.RunError, AttributeError): pass # Fetch and extract distgit sources if dist_git_source: try: self.extract_distgit_source(testdir, testdir, self.get('dist-git-type')) except Exception as error: raise tmt.utils.DiscoverError( f"Failed to process 'dist-git-source'.", original=error) # Adjust path and optionally show if path is None or path == '.': path = '' else: self.info('path', path, 'green') # Prepare the whole tree path and test path prefix tree_path = os.path.join(testdir, path.lstrip('/')) if not os.path.isdir(tree_path) and not self.opt('dry'): raise tmt.utils.DiscoverError( f"Metadata tree path '{path}' not found.") prefix_path = os.path.join('/tests', path.lstrip('/')) # Show filters and test names if provided # Check the 'test --filter' option first, then from discover filters = list(tmt.base.Test._opt('filters') or self.get('filter', [])) for filter_ in filters: self.info('filter', filter_, 'green') # Names of tests selected by --test option names = self.get('test', []) if names: self.info('tests', fmf.utils.listed(names), 'green') # Check the 'test --link' option first, then from discover links = list(tmt.base.Test._opt('link') or self.get('link', [])) for link_ in links: self.info('link', link_, 'green') excludes = list( tmt.base.Test._opt('exclude') or self.get('exclude', [])) # Filter only modified tests if requested modified_only = self.get('modified-only') modified_url = self.get('modified-url') if modified_url: self.info('modified-url', modified_url, 'green') self.debug(f"Fetch also '{modified_url}' as 'reference'.") self.run(['git', 'remote', 'add', 'reference', modified_url], cwd=testdir) self.run(['git', 'fetch', 'reference'], cwd=testdir) if modified_only: modified_ref = self.get('modified-ref', tmt.utils.default_branch(testdir)) self.info('modified-ref', modified_ref, 'green') output = self.run([ 'git', 'log', '--format=', '--stat', '--name-only', f"{modified_ref}..HEAD" ], cwd=testdir)[0] modified = set(f"^/{re.escape(name)}" for name in map(os.path.dirname, output.split('\n')) if name) self.debug(f"Limit to modified test dirs: {modified}", level=3) names.extend(modified) # Initialize the metadata tree, search for available tests self.debug(f"Check metadata tree in '{tree_path}'.") if self.opt('dry'): self._tests = [] return tree = tmt.Tree(path=tree_path, context=self.step.plan._fmf_context()) self._tests = tree.tests(filters=filters, names=names, conditions=["manual is False"], unique=False, links=links, excludes=excludes) # Prefix tests and handle library requires for test in self._tests: # Prefix test path with 'tests' and possible 'path' prefix test.path = os.path.join(prefix_path, test.path.lstrip('/')) # Check for possible required beakerlib libraries if test.require or test.recommend: test.require, test.recommend, _ = tmt.beakerlib.dependencies( test.require, test.recommend, parent=self)
def go(self): """ Discover available tests """ super(DiscoverFmf, self).go() # Check url and path, prepare test directory url = self.get('url') path = self.get('path') testdir = os.path.join(self.workdir, 'tests') # Clone provided git repository (if url given) if url: self.info('url', url, 'green') self.debug(f"Clone '{url}' to '{testdir}'.") self.run(['git', 'clone', url, testdir], shell=False) # Copy git repository root to workdir else: if path and not os.path.isdir(path): raise tmt.utils.DiscoverError( f"Provided path '{path}' is not a directory.") fmf_root = path or self.step.plan.run.tree.root # Check git repository root (use fmf root if not found) try: output = self.run( 'git rev-parse --show-toplevel', cwd=fmf_root, dry=True) git_root = output[0].strip('\n') except tmt.utils.RunError: self.debug(f"Git root not found, using '{fmf_root}.'") git_root = fmf_root # Set path to relative path from the git root to fmf root path = os.path.relpath(fmf_root, git_root) self.info('directory', git_root, 'green') self.debug(f"Copy '{git_root}' to '{testdir}'.") if not self.opt('dry'): shutil.copytree(git_root, testdir) # Checkout revision if requested ref = self.get('ref') if ref: self.info('ref', ref, 'green') self.debug(f"Checkout ref '{ref}'.") self.run(['git', 'checkout', '-f', ref], cwd=testdir, shell=False) # Adjust path and optionally show if path is None or path == '.': path = '' else: self.info('path', path, 'green') # Prepare the whole tree path and test path prefix tree_path = os.path.join(testdir, path.lstrip('/')) if not os.path.isdir(tree_path) and not self.opt('dry'): raise tmt.utils.DiscoverError( f"Metadata tree path '{path}' not found.") prefix_path = os.path.join('/tests', path.lstrip('/')) # Show filters and test names if provided filters = self.get('filter', []) for filter_ in filters: self.info('filter', filter_, 'green') names = self.get('test', []) if names: self.info('names', fmf.utils.listed(names), 'green') # Initialize the metadata tree, search for available tests self.debug(f"Check metadata tree in '{tree_path}'.") if self.opt('dry'): self._tests = [] return self._tests = tmt.Tree(tree_path).tests(filters=filters, names=names) # Prefix tests and handle library requires for test in self._tests: # Prefix test path with 'tests' and possible 'path' prefix test.path = os.path.join(prefix_path, test.path.lstrip('/')) # Check for possible required beakerlib libraries if test.require: test.require, test.recommend, _ = tmt.beakerlib.dependencies( test.require, test.recommend, parent=self)
def go(self): """ Discover available tests """ super(DiscoverFmf, self).go() # Check url and path, prepare test directory url = self.get('url') path = self.get('path') testdir = os.path.join(self.workdir, 'tests') # Clone provided git repository (if url given) if url: self.info('url', url, 'green') self.debug(f"Clone '{url}' to '{testdir}'.") self.run(f'git clone {url} {testdir}') # Copy git repository root to workdir else: if path and not os.path.isdir(path): raise tmt.utils.GeneralError( f"Provided path '{path}' is not a directory.") fmf_root = path or self.step.plan.run.tree.root output = self.run('git rev-parse --show-toplevel', cwd=fmf_root) git_root = output[0].strip('\n') # Set path to relative path from the git root to fmf root path = os.path.relpath(fmf_root, git_root) self.info('directory', git_root, 'green') self.debug(f"Copy '{git_root}' to '{testdir}'.") shutil.copytree(git_root, testdir) # Checkout revision if requested ref = self.get('ref') if ref: self.info('ref', ref, 'green') self.debug(f"Checkout ref '{ref}'.") self.run(f"git checkout -f {ref}", cwd=testdir) # Adjust path and optionally show if path is None or path == '.': path = '' else: self.info('path', path, 'green') # Prepare the whole tree path and test path prefix tree_path = os.path.join(testdir, path.lstrip('/')) if not os.path.isdir(tree_path): raise tmt.utils.GeneralError( f"Metadata tree path '{path}' not found.") prefix_path = os.path.join('/tests', path.lstrip('/')) # Show filters and test names if provided filters = self.get('filter', []) for filter_ in filters: self.info('filter', filter_, 'green') names = self.get('test', []) if names: self.info('names', fmf.utils.listed(names), 'green') # Initialize the metadata tree, search for available tests self.debug(f"Check metadata tree in '{tree_path}'.") if self.opt('dry'): return self._tests = tmt.Tree(tree_path).tests(filters=filters, names=names) # Prefix test path with 'tests' and possible 'path' prefix for test in self._tests: test.path = os.path.join(prefix_path, test.path.lstrip('/'))