Source code for buildtest.cli.inspect

"""This module implements methods for buildtest inspect command that can be used
to retrieve test record from report file in JSON format."""

import re
import sys

from rich.pretty import pprint
from rich.syntax import Syntax
from rich.table import Column, Table

from buildtest.defaults import console
from buildtest.utils.file import read_file, resolve_path
from buildtest.utils.tools import checkColor


[docs]def fetch_test_names(report, names): """Return a list of builders given input test names by search the report file for valid records. If test is found it will be returned as a builder name. If names are specified without test ID then we retrieve latest record for test name. If names are specified with ID we find the first matching test record. Args: report (buildtest.cli.report.Report): An instance of Report class names (list): A list of test names """ query_builders = [] name_lookup = report.lookup() for name in names: # if test includes backslash we need to check if their is an ID match if name.find("/") != -1: test_name, tid = name.split("/")[0], "".join(name.split("/")[1:]) if test_name not in name_lookup.keys(): console.print(f"Unable to find test: {test_name} so skipping test") continue # for list of all TEST IDs corresponding to test name, apply a re.match to acquire builder names for full_ids in name_lookup[test_name]: # if full_ids.startswith(tid): if re.match(tid, full_ids): query_builders.append(f"{test_name}/{full_ids}") # get latest test id for given test name else: tid = report.latest_testid_by_name(name) if tid: query_builders.append(f"{name}/{tid}") query_builders = list(set(query_builders)) if not query_builders: console.print( f"Unable to find any tests by name {names}, please select one of the following tests: {report.get_names()}" ) sys.exit(1) return query_builders
[docs]def inspect_list( report, terse=None, no_header=None, builder=None, color=None, pager=None, row_count=None, ): """This method list an output of test id, name, and buildspec file from the report cache. The default behavior is to display output in table format though this can be changed with terse format which will display in parseable format. This method implements command ``buildtest inspect list`` Args: report (str): Path to report file terse (bool, optional): Print output in terse format no_header (bool, optional): Determine whether to print header in terse format. builder (bool, optional): Print output in builder format which can be done via ``buildtest inspect list --builder`` color (bool, optional): Print table output of ``buildtest inspect list`` with selected color pager (bool, optional): Print output in paging format row_count (bool, optional): Print total number of test runs """ consoleColor = checkColor(color) test_ids = report._testid_lookup() if row_count: print(len(test_ids)) return # implement command 'buildtest inspect list --builder' if builder: if pager: with console.pager(): print_builders(report) return print_builders(report) return table = {"id": [], "name": [], "buildspec": []} for identifier in test_ids.keys(): table["id"].append(identifier) table["name"].append(test_ids[identifier]["name"]) table["buildspec"].append(test_ids[identifier]["buildspec"]) # print output in terse format if terse: if pager: with console.pager(): print_terse(table, no_header, consoleColor) return print_terse(table, no_header, consoleColor) return inspect_table = Table( header_style="blue", title="Test Summary by id, name, buildspec", row_styles=[consoleColor], ) for column in table.keys(): inspect_table.add_column(column, overflow="fold") for identifier, name, buildspec in zip( table["id"], table["name"], table["buildspec"] ): inspect_table.add_row(identifier, name, buildspec) if pager: with console.pager(): console.print(inspect_table) return console.print(inspect_table)
[docs]def inspect_query( report, name, theme=None, output=None, error=None, testpath=None, buildscript=None, buildenv=None, pager=None, ): """Entry point for ``buildtest inspect query`` command. Args: report (buildtest.cli.report.Report): An instance of Report class name (list): List of test names to query theme (str, optional): Specify pygments theme for syntax highlighting output (bool, optional): Print output file when set to True error (bool, optional): Print error file when set to True testpath (bool, optional): Print testpath when set to True buildscript (bool, optional): Print buildscript when set to True buildenv (bool, optional): Print buildenv when set to True pager (bool, optional): Print output in paging format """ if pager: with console.pager(): print_by_query( report, name=name, theme=theme, output=output, error=error, testpath=testpath, buildscript=buildscript, buildenv=buildenv, ) return print_by_query( report, name=name, theme=theme, output=output, error=error, testpath=testpath, buildscript=buildscript, buildenv=buildenv, )
[docs]def inspect_buildspec(report, input_buildspecs, all_records=None, pager=None): """This method implements command ``buildtest inspect buildspec`` Args: report (buildtest.cli.report.Report): An instance of Report class input_buildspecs (list): List of buildspecs to search in report file. This is specified as positional arguments to ``buildtest inspect buildspec`` all_records (bool): Determine whether to display all records for every test that matches the buildspec. By default we retrieve the latest record. pager (bool, optional): Print output in paging format """ search_buildspecs = [] for fname in input_buildspecs: abs_fname = resolve_path(fname) if not abs_fname: print(f"buildspec: {fname} is not valid file") continue search_buildspecs.append(abs_fname) if not search_buildspecs: sys.exit( f"There are no buildspecs in cache based on input buildspecs: {input_buildspecs}" ) # get raw content of test raw_content = report.get() # returns a list of buildspecs from the report cache available_buildspecs = list(report.get_buildspecs()) # filter out buildspecs not found in report search_buildspecs = [ buildspec for buildspec in search_buildspecs if buildspec in available_buildspecs ] # we stop if there are no buildspecs if not search_buildspecs: msg = "Unable to find any buildspecs in cache, please specify one of the following buildspecs: \n" for buildspec in available_buildspecs: msg += buildspec + "\n" sys.exit(msg) # dict used to hold records from records = {} for buildspec in search_buildspecs: records[buildspec] = raw_content[buildspec] # dict holding latest record of each test latest_records = {} if not all_records: for buildspec in records.keys(): latest_records[buildspec] = {} for test in records[buildspec].keys(): # get last element of list latest_records[buildspec][test] = records[buildspec][test][-1] records = latest_records or records if pager: with console.pager(): console.print(records) return pprint(records)
[docs]def inspect_by_name(report, names, pager=None): """Implements command ``buildtest inspect name`` which will print all test records by given name in JSON format. .. code-block:: console # get last run for test exit1_fail buildtest inspect name exit1_fail .. code-block:: console # get record exit1_fail that starts with id 123 buildtest inspect name exit1_fail/123 Args: report (buildtest.cli.report.Report): An instance of Report class names (list): List of test names to search in report file. This is specified as positional arguments to ``buildtest inspect name`` pager (bool, optional): Print output in paging format """ if pager: with console.pager(): print_by_name(report, names) return print_by_name(report, names) return