API Documentation

Warning

The API is for now considered completely internal and could change at any time

In order to support report edition (bisector edit) and more stable serialized format, new steps constructors must be written in a similar way to exisiting ones.

bisector.main.mask_signals(unblock=False)[source]
bisector.main.filter_keys(mapping, remove=None, keep=None)[source]
bisector.main.natural_sort_key(s)[source]

Key suitable for alphanumeric sort, but sorts numbers contained in the string as numbers.

bisector.main.raise_sig_exception(sig, frame)[source]

Turn some signals into exceptions that can be caught by user code.

class bisector.main.MLString(lines=None, empty=False)[source]

Bases: object

Efficient multiline string, behaving mostly like an str.

Such string can be called to append a line to it, and str methods can be used. Note that these methods will return a rendered string and will not modify the object itself.

tabulate(separator=' ', filler=None)[source]

Return a new MLString with the lines formatted so that the columns are properly aligned.

separator is a regex so splitting on multiple delimiters at once is possible.

__call__(line='')[source]

Append a line by simply calling the object.

__getattr__(attr)[source]

Make all strings methods available.

class bisector.main.BisectRet(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]

Bases: Enum

Git bisect return code as described in git bisect run documentation.

NA = -1
UNTESTABLE = 125
GOOD = 0
BAD = 1
ABORT = 253
YIELD = 252
property lower_name

Make the lowercase name available through a property so that it can be used directly from format strings (they cannot call functions).

classmethod to_yaml(representer, node)[source]
classmethod from_yaml(constructor, node)[source]
yaml_tag = '!git-bisect'
bisector.main.parse_step_options(opts_seq)[source]

Parse the steps options passed with -o command line parameters.

Parameters:

opts_seq – sequence of command line options as returned by argparse. Their format is: <name or category pattern>.<key>=<value> If <name or cat pattern> is missing, ‘*’ is assumed. It will also be passed to all functions. The pattern is matched using fnmatch. If <value> is missing, True is assumed.

Returns:

An OrderedDict that maps steps name pattern to a dict of key and values.

bisector.main.parse_iterations(opt)[source]

Parse a string representing the number of iterations to be run. Special value “inf” means infinite number of iterations.

bisector.main.parse_timeout(timeout)[source]

Parse a string representing a timeout.

It handles “inf” for infinite timeout (i.e. no timeout), and the s, m, h suffixes. Default unit is seconds.

class bisector.main.Param(desc='')[source]

Bases: ABC

Abstract Base Class of steps parameter.

Such parameters take care of parsing strings specified on the command line and convert them to the right type before they are passed to the method.

When no value is specified for such parameter, True boolean is assumed. Subclasses need to handle that with a default value, or raise an argparse.ArgumentTypeError exception as appropriate.

type_desc = None

Short description of the type. It will be displayed in the help.

parse(val)[source]

Parse an arbitrary value.

Some types will be accepted without modification, str will undergo parsing.

validate_val(val)[source]

Validate an object to be used as the value of the parameter.

The validation is done after string parsing. That will catch non-string objects passed to the function, or non-string objects coming from the YAML file.

Returns:

True if the object satisfies the properties, False otherwise

abstract parse_str(val)[source]

Parse a string argument.

Strings are passed when the option is specified on the command line so that it is converted to the right type before being handled to the methods.

class bisector.main.TimeoutParam(desc='')[source]

Bases: Param

Step parameter holding a timeout value.

type_desc = 'int or "inf"'

Short description of the type. It will be displayed in the help.

parse_str(val)[source]

Parse a string argument.

Strings are passed when the option is specified on the command line so that it is converted to the right type before being handled to the methods.

validate_val(val)[source]

Validate an object to be used as the value of the parameter.

The validation is done after string parsing. That will catch non-string objects passed to the function, or non-string objects coming from the YAML file.

Returns:

True if the object satisfies the properties, False otherwise

class bisector.main.IterationParam(desc='')[source]

Bases: Param

Step parameter holding a number of iterations.

type_desc = 'int or "inf"'

Short description of the type. It will be displayed in the help.

parse_str(val)[source]

Parse a string argument.

Strings are passed when the option is specified on the command line so that it is converted to the right type before being handled to the methods.

validate_val(val)[source]

Validate an object to be used as the value of the parameter.

The validation is done after string parsing. That will catch non-string objects passed to the function, or non-string objects coming from the YAML file.

Returns:

True if the object satisfies the properties, False otherwise

class bisector.main.BoolOrStrParam(*args, allow_empty=False, **kwargs)[source]

Bases: Param

Step parameter holding a string.

property type_desc
parse_str(val)[source]

Parse a string argument.

Strings are passed when the option is specified on the command line so that it is converted to the right type before being handled to the methods.

validate_val(val)[source]

Validate an object to be used as the value of the parameter.

The validation is done after string parsing. That will catch non-string objects passed to the function, or non-string objects coming from the YAML file.

Returns:

True if the object satisfies the properties, False otherwise

class bisector.main.CommaListParam(desc='')[source]

Bases: Param

Step parameter holding a comma-separated list of strings.

type_desc = 'comma-separated list'

Short description of the type. It will be displayed in the help.

parse_str(val)[source]

Parse a string argument.

Strings are passed when the option is specified on the command line so that it is converted to the right type before being handled to the methods.

validate_val(val)[source]

Validate an object to be used as the value of the parameter.

The validation is done after string parsing. That will catch non-string objects passed to the function, or non-string objects coming from the YAML file.

Returns:

True if the object satisfies the properties, False otherwise

class bisector.main.CommaListRangesParam(desc='')[source]

Bases: CommaListParam

type_desc = 'comma-separated list of integer ranges'

Short description of the type. It will be displayed in the help.

parse_str(val)[source]

Parse a string argument.

Strings are passed when the option is specified on the command line so that it is converted to the right type before being handled to the methods.

validate_val(val)[source]

Validate an object to be used as the value of the parameter.

The validation is done after string parsing. That will catch non-string objects passed to the function, or non-string objects coming from the YAML file.

Returns:

True if the object satisfies the properties, False otherwise

class bisector.main.EnvListParam(desc='')[source]

Bases: Param

Step parameter holding a list of environment variables values.

type_desc = 'env var list'

Short description of the type. It will be displayed in the help.

parse(val)[source]

Parse an arbitrary value.

Some types will be accepted without modification, str will undergo parsing.

parse_str(val)[source]

Parse a string argument.

Strings are passed when the option is specified on the command line so that it is converted to the right type before being handled to the methods.

validate_val(val)[source]

Validate an object to be used as the value of the parameter.

The validation is done after string parsing. That will catch non-string objects passed to the function, or non-string objects coming from the YAML file.

Returns:

True if the object satisfies the properties, False otherwise

class bisector.main.IntParam(desc='')[source]

Bases: Param

Step parameter holding an integer.

type_desc = 'int'

Short description of the type. It will be displayed in the help.

parse_str(val)[source]

Parse a string argument.

Strings are passed when the option is specified on the command line so that it is converted to the right type before being handled to the methods.

validate_val(val)[source]

Validate an object to be used as the value of the parameter.

The validation is done after string parsing. That will catch non-string objects passed to the function, or non-string objects coming from the YAML file.

Returns:

True if the object satisfies the properties, False otherwise

class bisector.main.BoolParam(desc='')[source]

Bases: Param

Step parameter holding a boolean value.

type_desc = 'bool'

Short description of the type. It will be displayed in the help.

parse_str(val)[source]

Parse a string argument.

Strings are passed when the option is specified on the command line so that it is converted to the right type before being handled to the methods.

validate_val(val)[source]

Validate an object to be used as the value of the parameter.

The validation is done after string parsing. That will catch non-string objects passed to the function, or non-string objects coming from the YAML file.

Returns:

True if the object satisfies the properties, False otherwise

class bisector.main.ChoiceOrBoolParam(choices, *args, **kwargs)[source]

Bases: Param

Step parameter holding a boolean value or an item chosen among a predefined set.

property type_desc
parse_str(val)[source]

Parse a string argument.

Strings are passed when the option is specified on the command line so that it is converted to the right type before being handled to the methods.

validate_val(val)[source]

Validate an object to be used as the value of the parameter.

The validation is done after string parsing. That will catch non-string objects passed to the function, or non-string objects coming from the YAML file.

Returns:

True if the object satisfies the properties, False otherwise

bisector.main.info(msg)[source]

Write a log message at the INFO level.

bisector.main.debug(msg)[source]

Write a log message at the DEBUG level.

bisector.main.warn(msg)[source]

Write a log message at the WARNING level.

bisector.main.error(msg)[source]

Write a log message at the ERROR level.

class bisector.main.SerializableMeta(*args, **kwargs)[source]

Bases: type

Metaclass for all serializable classes.

It ensures the class will always have a name and cat attributes, as well as constructing a ChainMap from the attr_init dictionaries of its base classes. That means that usual inheritance rules will apply to the content of attr_init .

set_attr_init(attr, val)[source]

Set an initial value for instance attributes.

class bisector.main.Serializable(*args, **kwargs)[source]

Bases: object

Base class of all serializable classes.

Subclasses MUST implement a yaml_tag class attribute, in order to have a stable tag associated with them that can survive accross class renames and refactoring.

attr_init = ChainMap({'name': None})

All keys of this dictionary will be copied into fresh instance attributes when the class is instantiated.

dont_save = []

Attributes that will not be saved to the Pickle or YAML file.

static __new__(cls, *args, **kwargs)[source]
__setattr__(attr, val)[source]

Use the default value if the attribute does not exist yet.

__getstate__()[source]

Determine what state must be preserved when the instance is serialized.

Attributes with a value equal to the corresponding value in attr_init will not be serialized, since they will be recreated when the instance is deserialized. That limits the number of attributes that are actually stored, thereby limiting the scope of backward compatibility issues. It also means that an update to the code could change the default value, so the deserialized instance will not necessarily be equal to the serialized one.

Attributes listed in dont_save will not be serialized.

cat = None
name = 'Serializable'
class bisector.main.StepResultBase(*args, **kwargs)[source]

Bases: Serializable

Base class of all step results.

Step results are returned by the StepBase.run() method of steps. It must implement bisect_ret containing a value of BisectRet .

filtered_bisect_ret(steps_filter=None)[source]

Dummy implementation to simplify bisect status aggreagation code.

attr_init = ChainMap({}, {'name': None})

All keys of this dictionary will be copied into fresh instance attributes when the class is instantiated.

cat = None
name = 'StepResultBase'
class bisector.main.StepResult(*args, **kwargs)[source]

Bases: StepResultBase

Basic step result.

This step results support storing the return values of multiple trials of a step, along its corresponding logs.

yaml_tag = '!basic-step-result'
property ret

The meaningful return value is the one from the last trial.

property log

Get the log that goes with the return code.

attr_init = ChainMap({}, {}, {'name': None})

All keys of this dictionary will be copied into fresh instance attributes when the class is instantiated.

cat = None
name = 'StepResult'
bisector.main.terminate_process(p, kill_timeout)[source]

Attempt to terminate a process p, and kill it after kill_timeout if it is not dead yet.

bisector.main.read_stdout(p, timeout=None, kill_timeout=3)[source]

Read the standard output of a given process, and terminates it when the timeout expires.

Note that it will not close stdout file descriptor, so the caller needs to take care of that, since it created the process.

bisector.main.write_stdout(txt)[source]
bisector.main.call_process(cmd, *args, merge_stderr=True, **kwargs)[source]

Call a given command with the given arguments and return its standard output.

Parameters:
  • cmd – name of the command to run

  • args – command line arguments passed to the command

  • merge_stderr – merge stderr with stdout.

Variable keyword arguments:

Forwarded to subprocess.check_output()

bisector.main.git_cleanup(repo='./')[source]

Forcefully clean and reset a git repository.

bisector.main.enforce_git_cleanup(do_cleanup=True, repo='./')[source]

Context manager allowing to cleanup a git repository at entry and exit.

Parameters:

do_cleanup – does the cleanup if True, otherwise does nothing.

bisector.main.get_git_sha1(repo='./', ref='HEAD', abbrev=12)[source]

Get the SHA1 of given ref in the given git repository.

Parameters:

abbrev – length of the SHA1 returned.

bisector.main.get_steps_kwarg_parsers(cls, method_name)[source]

Analyze a method to extract the parameters with command line parsers.

The parser must be a Param so it handles parsing of arguments coming from the command line. It must be specified in the options class attribute.

Parameters:
  • method_name – name of the method to analyze

  • cls – class of the method to analyze

Returns:

map of parameter names to their Param object

bisector.main.get_step_kwargs(step_cat, step_name, cls, method_name, user_options)[source]

Compute the keyword arguments map for a given method that belongs to a specific step.

Parameters:
  • step_cat – category of the step the method belongs to

  • step_name – name of the step the method belongs to

  • user_options – Map of steps categories or names patterns to options.

Returns:

A map suitable to pass as **kwargs to the method. Note that the option values are not modified, the method is expected to apply its own processing to convert strings to the expected types if necessary.

class bisector.main.StepMeta(name, bases, dct)[source]

Bases: ABCMeta, SerializableMeta

Metaclass of all steps.

Wraps __init__() and report() to preprocess the values of the parameters annotated with a command line option parser.

static __new__(meta_cls, name, bases, dct)[source]
static wrap_method(dct, method_name)[source]

Wrap a method to preprocess argument values using the parser given in dct[‘options’].

class bisector.main.IterationCounterStack(iterable=(), /)[source]

Bases: list

list subclass that can be pretty printed as dot-separated list. This is intended to be used for nested iteration counters.

__format__(fmt)[source]

Default object formatter.

class bisector.main.StepABC(*args, **kwargs)[source]

Bases: Serializable

Abstract Base Class of all steps.

Keyword-only parameters can be annotated with an instance of Param in order to support step-specific cmd-line parameters.

options = {'__init__': {}, 'report': {'verbose': BoolParam<bool>}}
abstract run(i_stack, service_hub)[source]

Run the step.

The return values of this method will be collected and stored.

abstract report(step_res_seq, verbose=True)[source]

Display the list of results gathered when executing run().

Keyword-only parameters are supported as for __init__()

attr_init = ChainMap({}, {'name': None})

All keys of this dictionary will be copied into fresh instance attributes when the class is instantiated.

cat = None
name = 'StepABC'
class bisector.main.StepBase(*args, **kwargs)[source]

Bases: StepABC

Base class of most steps.

It supports running shell commands, saving their stdout and stderr as well as their exit status.

Keyword-only parameters can be annotated with an instance of Param in order to support step-specific cmd-line parameters.

attr_init = ChainMap({'cat': '<no category>', 'name': '<no name>', 'shell': '/bin/bash', 'trials': 1, 'cmd': '', 'timeout': 0, 'kill_timeout': 3, 'bail_out': True, 'use_systemd_run': False, 'env': OrderedDict()}, {}, {'name': None})

All keys of this dictionary will be copied into fresh instance attributes when the class is instantiated.

options = {'__init__': {'bail_out': BoolParam<bool>, 'cmd': BoolOrStrParam<non-empty str>, 'env': EnvListParam<env var list>, 'kill_timeout': TimeoutParam<int or "inf">, 'shell': BoolOrStrParam<non-empty str>, 'timeout': TimeoutParam<int or "inf">, 'trials': IntParam<int>, 'use_systemd_run': BoolParam<bool>}, 'report': {'export_logs': BoolOrStrParam<non-empty str>, 'ignore_non_issue': BoolParam<bool>, 'iterations': CommaListRangesParam<comma-separated list of integer ranges>, 'show_basic': BoolParam<bool>, 'verbose': BoolParam<bool>}}
cat = '<no category>'
name = '<no name>'
reinit(*args, **kwargs)[source]
classmethod help()[source]
run(i_stack, service_hub)[source]

Run the step.

The return values of this method will be collected and stored.

report(step_res_seq, service_hub, verbose=False, show_basic=True, ignore_non_issue=False, iterations=[], export_logs=False)[source]

Print out a report for a list of executions results created using the run() method.

class bisector.main.YieldStep(*args, **kwargs)[source]

Bases: StepBase

Abort current iteration with the yield return code.

If the specified command returns a non-zero return code, bisector will abort the current iteration with the yield return code.

Note

This step can only be used under the main macrostep (it cannot be used in nested macrosteps).

Keyword-only parameters can be annotated with an instance of Param in order to support step-specific cmd-line parameters.

yaml_tag = '!yield-step'
attr_init = ChainMap({'cat': 'yield', 'name': 'yield', 'every_n_iterations': 1, 'cmd': 'exit 1'}, {'cat': '<no category>', 'name': '<no name>', 'shell': '/bin/bash', 'trials': 1, 'cmd': '', 'timeout': 0, 'kill_timeout': 3, 'bail_out': True, 'use_systemd_run': False, 'env': OrderedDict()}, {}, {'name': None})

All keys of this dictionary will be copied into fresh instance attributes when the class is instantiated.

options = {'__init__': {'bail_out': BoolParam<bool>, 'cmd': BoolOrStrParam<non-empty str>, 'env': EnvListParam<env var list>, 'every_n_iterations': IntParam<int>, 'kill_timeout': TimeoutParam<int or "inf">, 'shell': BoolOrStrParam<non-empty str>, 'timeout': TimeoutParam<int or "inf">, 'trials': IntParam<int>, 'use_systemd_run': BoolParam<bool>}}
run(i_stack, service_hub)[source]

Run the step.

The return values of this method will be collected and stored.

cat = 'yield'
name = 'yield'
class bisector.main.ShellStep(*args, **kwargs)[source]

Bases: StepBase

Execute a command in a shell.

Stdout and stderr are merged and logged. The exit status of the command will have no influence of the bisect status.

Keyword-only parameters can be annotated with an instance of Param in order to support step-specific cmd-line parameters.

yaml_tag = '!shell-step'
attr_init = ChainMap({'cat': 'shell', 'name': 'shell'}, {'cat': '<no category>', 'name': '<no name>', 'shell': '/bin/bash', 'trials': 1, 'cmd': '', 'timeout': 0, 'kill_timeout': 3, 'bail_out': True, 'use_systemd_run': False, 'env': OrderedDict()}, {}, {'name': None})

All keys of this dictionary will be copied into fresh instance attributes when the class is instantiated.

cat = 'shell'
name = 'shell'
class bisector.main.TestShellStep(*args, **kwargs)[source]

Bases: ShellStep

Similar to ShellStep .

Non-zero exit status of the command will be interpreted as a bisect bad status, and zero exit status as bisect good.

Keyword-only parameters can be annotated with an instance of Param in order to support step-specific cmd-line parameters.

yaml_tag = '!test-step'
attr_init = ChainMap({'cat': 'test', 'name': 'test'}, {'cat': 'shell', 'name': 'shell'}, {'cat': '<no category>', 'name': '<no name>', 'shell': '/bin/bash', 'trials': 1, 'cmd': '', 'timeout': 0, 'kill_timeout': 3, 'bail_out': True, 'use_systemd_run': False, 'env': OrderedDict()}, {}, {'name': None})

All keys of this dictionary will be copied into fresh instance attributes when the class is instantiated.

run(i_stack, service_hub)[source]

Run the step.

The return values of this method will be collected and stored.

cat = 'test'
name = 'test'
class bisector.main.BuildStep(*args, **kwargs)[source]

Bases: ShellStep

Similar to ShellStep .

Non-zero exit status of the command will be interpreted as a bisect untestable status, and zero exit status as bisect good.

Keyword-only parameters can be annotated with an instance of Param in order to support step-specific cmd-line parameters.

yaml_tag = '!build-step'
attr_init = ChainMap({'cat': 'build', 'name': 'build'}, {'cat': 'shell', 'name': 'shell'}, {'cat': '<no category>', 'name': '<no name>', 'shell': '/bin/bash', 'trials': 1, 'cmd': '', 'timeout': 0, 'kill_timeout': 3, 'bail_out': True, 'use_systemd_run': False, 'env': OrderedDict()}, {}, {'name': None})

All keys of this dictionary will be copied into fresh instance attributes when the class is instantiated.

run(i_stack, service_hub)[source]

Run the step.

The return values of this method will be collected and stored.

cat = 'build'
name = 'build'
class bisector.main.FlashStep(*args, **kwargs)[source]

Bases: ShellStep

Similar to ShellStep .

Non-zero exit status of the command will be interpreted as a bisect abort, and zero exit status ignored.

Keyword-only parameters can be annotated with an instance of Param in order to support step-specific cmd-line parameters.

yaml_tag = '!flash-step'
attr_init = ChainMap({'cat': 'flash', 'name': 'flash'}, {'cat': 'shell', 'name': 'shell'}, {'cat': '<no category>', 'name': '<no name>', 'shell': '/bin/bash', 'trials': 1, 'cmd': '', 'timeout': 0, 'kill_timeout': 3, 'bail_out': True, 'use_systemd_run': False, 'env': OrderedDict()}, {}, {'name': None})

All keys of this dictionary will be copied into fresh instance attributes when the class is instantiated.

run(i_stack, service_hub)[source]

Run the step.

The return values of this method will be collected and stored.

cat = 'flash'
name = 'flash'
class bisector.main.RebootStep(*args, **kwargs)[source]

Bases: ShellStep

Similar to ShellStep .

Non-zero exit status of the command will be interpreted as a bisect abort, and zero exit status as bisect good.

Keyword-only parameters can be annotated with an instance of Param in order to support step-specific cmd-line parameters.

yaml_tag = '!reboot-step'
attr_init = ChainMap({'cat': 'boot', 'name': 'reboot'}, {'cat': 'shell', 'name': 'shell'}, {'cat': '<no category>', 'name': '<no name>', 'shell': '/bin/bash', 'trials': 1, 'cmd': '', 'timeout': 0, 'kill_timeout': 3, 'bail_out': True, 'use_systemd_run': False, 'env': OrderedDict()}, {}, {'name': None})

All keys of this dictionary will be copied into fresh instance attributes when the class is instantiated.

run(i_stack, service_hub)[source]

Run the step.

The return values of this method will be collected and stored.

cat = 'boot'
name = 'reboot'
class bisector.main.ExekallStepResult(*args, **kwargs)[source]

Bases: StepResult

Result of a LISA (exekall) step.

It collects an exekall.engine.ValueDB, as well as the path of the LISA result directory in addition than to what is collected by StepResult .

yaml_tag = '!exekall-step-result'
attr_init = ChainMap({'name': 'LISA-test'}, {}, {}, {'name': None})

All keys of this dictionary will be copied into fresh instance attributes when the class is instantiated.

cat = None
name = 'LISA-test'
class bisector.main.Deprecated[source]

Bases: object

Base class to inherit from to mark a subclass as deprecated.

This removes it from the documented classes, and will generally mask it.

class bisector.main.LISATestStepResult(*args, **kwargs)[source]

Bases: ExekallStepResult, Deprecated

Deprecated since version 1.0: Deprecated alias for ExekallStepResult, it is only kept around to be able to reload old YAML and pickle reports.

yaml_tag = '!LISA-test-step-result'
attr_init = ChainMap({}, {'name': 'LISA-test'}, {}, {}, {'name': None})

All keys of this dictionary will be copied into fresh instance attributes when the class is instantiated.

cat = None
name = 'LISATestStepResult'
class bisector.main.LISATestStep(*args, **kwargs)[source]

Bases: ShellStep

Execute an exekall LISA test command and collect exekall.engine.ValueDB. Also compress the result directory and record its path. It will also define some environment variables that are expected to be used by the command to be able to locate resources to collect.

Keyword-only parameters can be annotated with an instance of Param in order to support step-specific cmd-line parameters.

yaml_tag = '!exekall-LISA-test-step'
attr_init = ChainMap({'cat': 'test', 'name': 'LISA-test', 'delete_artifact_hidden': True, 'compress_artifact': True, 'upload_artifact': False, 'delete_artifact': False, 'prune_db': True, 'cmd': 'lisa-test'}, {'cat': 'shell', 'name': 'shell'}, {'cat': '<no category>', 'name': '<no name>', 'shell': '/bin/bash', 'trials': 1, 'cmd': '', 'timeout': 0, 'kill_timeout': 3, 'bail_out': True, 'use_systemd_run': False, 'env': OrderedDict()}, {}, {'name': None})

All keys of this dictionary will be copied into fresh instance attributes when the class is instantiated.

options = {'__init__': {'bail_out': BoolParam<bool>, 'cmd': BoolOrStrParam<non-empty str>, 'compress_artifact': BoolParam<bool>, 'delete_artifact': BoolParam<bool>, 'delete_artifact_hidden': BoolParam<bool>, 'env': EnvListParam<env var list>, 'kill_timeout': TimeoutParam<int or "inf">, 'prune_db': BoolParam<bool>, 'shell': BoolOrStrParam<non-empty str>, 'timeout': TimeoutParam<int or "inf">, 'upload_artifact': BoolParam<bool>, 'use_systemd_run': BoolParam<bool>}, 'report': {'download': BoolParam<bool>, 'dump_artifact_dirs': BoolOrStrParam<non-empty str>, 'export_db': BoolOrStrParam<non-empty str>, 'export_logs': BoolOrStrParam<non-empty str>, 'ignore_excep': CommaListParam<comma-separated list>, 'ignore_non_error': BoolParam<bool>, 'ignore_non_issue': BoolParam<bool>, 'ignore_testcase': CommaListParam<comma-separated list>, 'iterations': CommaListRangesParam<comma-separated list of integer ranges>, 'result_uuid': CommaListParam<comma-separated list>, 'show_artifact_dirs': BoolParam<bool>, 'show_basic': BoolParam<bool>, 'show_details': ChoiceOrBoolParam<"msg" or bool>, 'show_dist': BoolParam<bool>, 'show_pass_rate': BoolParam<bool>, 'show_rates': BoolParam<bool>, 'testcase': CommaListParam<comma-separated list>, 'upload_artifact': BoolParam<bool>, 'verbose': BoolParam<bool>}}
run(i_stack, service_hub)[source]

Run the step.

The return values of this method will be collected and stored.

report(step_res_seq, service_hub, verbose=False, show_basic=False, show_rates=True, show_dist=False, show_details=False, show_pass_rate=False, show_artifact_dirs=False, testcase=[], result_uuid=[], ignore_testcase=[], iterations=[], ignore_non_issue=False, ignore_non_error=False, ignore_excep=[], dump_artifact_dirs=False, export_db=False, export_logs=False, download=True, upload_artifact=False)[source]

Print out a report for a list of executions artifact created using the run() method.

cat = 'test'
name = 'LISA-test'
class bisector.main.ExekallLISATestStep(*args, **kwargs)[source]

Bases: LISATestStep, Deprecated

Deprecated since version 1.0: Deprecated alias for LISATestStep, it is only kept around to be able to reload old pickle reports.

Keyword-only parameters can be annotated with an instance of Param in order to support step-specific cmd-line parameters.

attr_init = ChainMap(ChainMap({'cat': 'test', 'name': 'exekall-LISA-test', 'delete_artifact_hidden': True, 'compress_artifact': True, 'upload_artifact': False, 'delete_artifact': False, 'prune_db': True, 'cmd': 'lisa-test'}, {'cat': 'shell', 'name': 'shell'}, {'cat': '<no category>', 'name': '<no name>', 'shell': '/bin/bash', 'trials': 1, 'cmd': '', 'timeout': 0, 'kill_timeout': 3, 'bail_out': True, 'use_systemd_run': False, 'env': OrderedDict()}, {}, {'name': None}), {'cat': 'test', 'name': 'LISA-test', 'delete_artifact_hidden': True, 'compress_artifact': True, 'upload_artifact': False, 'delete_artifact': False, 'prune_db': True, 'cmd': 'lisa-test'}, {'cat': 'shell', 'name': 'shell'}, {'cat': '<no category>', 'name': '<no name>', 'shell': '/bin/bash', 'trials': 1, 'cmd': '', 'timeout': 0, 'kill_timeout': 3, 'bail_out': True, 'use_systemd_run': False, 'env': OrderedDict()}, {}, {'name': None})

All keys of this dictionary will be copied into fresh instance attributes when the class is instantiated.

cat = 'test'
name = 'exekall-LISA-test'
class bisector.main.StepNotifService(slave_manager)[source]

Bases: object

Allows steps to send notifications.

notif(step, msg, display_time=3)[source]
bisector.main.urlretrieve(url, path)[source]
class bisector.main.ArtifactsService[source]

Bases: ABC

abstract upload(path, url)[source]

Upload a file

abstract download(url, path)[source]

Download a file

class bisector.main.ArtifactorialService(token=None)[source]

Bases: ArtifactsService

Upload/download files to/from Artifactorial.

Parameters:

token – Token granting the read & write access to the url It is not mandatory for the download service.

upload(path, url=None)[source]

Upload a file to Artifactorial.

Parameters:
  • path – path to the file to upload

  • url – URL of the Artifactorial folder to upload to, or env var ARTIFACTORIAL_FOLDER

download(url, path)[source]

Download a file from Artifactorial: anonymous access.

Parameters:
  • url – URL of the Artifactorial file to download

  • path – path to the downloaded file

class bisector.main.ArtifactoryService(token=None)[source]

Bases: ArtifactsService

Upload/download files to/from Artifactory.

Parameters:

token – Token granting the read & write access to the url, or env var ARTIFACTORY_TOKEN

upload(path, url=None)[source]

Upload a file to Artifactory.

Parameters:
  • path – path to the file to upload

  • url – URL of the Artifactory folder to upload to, or env var ARTIFACTORY_FOLDER

download(url, path)[source]

Download a file from an Artifacts service.

Parameters:

path – path to the file to download

bisector.main.update_json(path, mapping)[source]

Update a JSON file with the given mapping.

That allows accumulation of keys coming from different sources in one file. Newly inserted keys will override existing keys with the same name.

bisector.main.load_steps_list(yaml_path)[source]
bisector.main.load_yaml(yaml_path)[source]

Load the sequence of steps from a YAML file.

bisector.main.get_class(full_qual_name)[source]

Parse the class name of an entry in a YAML steps map file and return the module name and the class name. It will also append the necessary directories to PYTHONPATH if the class comes from another module.

Parameters:

full_qual_name – The qualified name of the class that is suitable for serialization, e.g.: /path/to/mod.py:mymodule.LISA-step Note: the name is not the Python class name, but the value of the name attribute of the class. The path to the script can be omitted if the module is directly importable (i.e. in sys.path). The module can be omitted for class names that are already imported in the script namespace.

bisector.main.import_file(script_name, name=None)[source]
bisector.main.import_files(src_files)[source]
bisector.main.get_subclasses(cls)[source]

Get the subclasses recursively.

bisector.main.get_step_by_name(name)[source]
bisector.main.instantiate_step(spec, step_options)[source]

Find the right Step* class using Step*.name attribute and build an instance of it.

class bisector.main.StepSeqResult(*args, **kwargs)[source]

Bases: StepResultBase

Result of a sequence of steps.

The main purpose is to store the results of one iteration of a MacroStep .

yaml_tag = '!step-seq-result'
attr_init = ChainMap({'step_res_run_times': {}}, {}, {'name': None})

All keys of this dictionary will be copied into fresh instance attributes when the class is instantiated.

property bisect_ret
cat = None
name = 'StepSeqResult'
class bisector.main.ServiceHub(**kwargs)[source]

Bases: object

__getattr__(attr)[source]

If a service is missing, None is returned.

register_service(name, service)[source]
unregister_service(name)[source]
class bisector.main.MacroStepResult(*args, **kwargs)[source]

Bases: StepResultBase

Result of the execution of a MacroStep .

It mainly contains a sequence of StepSeqResult instances, each of them corresponding to one iteration of the MacroStep .

yaml_tag = '!macro-step-result'
attr_init = ChainMap({'name': 'macro'}, {}, {'name': None})

All keys of this dictionary will be copied into fresh instance attributes when the class is instantiated.

property avg_run_time
property bisect_ret
filtered_bisect_ret(steps_filter=None, ignore_yield=False)[source]

Dummy implementation to simplify bisect status aggreagation code.

cat = None
name = 'macro'
bisector.main.match_step_name(name, pattern_list)[source]

Find the patterns matching the step name, and return them in a list.

class bisector.main.StepFilter(skip={}, only={})[source]

Bases: object

Filter the steps of a MacroStep . This allows restricting the display to a subset of steps.

filter(steps_list)[source]
class bisector.main.MacroStep(*args, **kwargs)[source]

Bases: StepBase

Provide a loop-like construct to the steps definitions.

All sub-steps will be executed in order. This sequence will be repeated for the given number of iterations or until it times out. The steps definition YAML configuration file is interpreted assuming an implicit toplevel MacroStep that is parameterized using command line options.

Keyword-only parameters can be annotated with an instance of Param in order to support step-specific cmd-line parameters.

yaml_tag = '!macro-step'
attr_init = ChainMap({'name': 'macro', 'cat': 'macro', 'timeout': 0, 'iterations': 'inf', 'steps_list': [], 'bail_out_early': False}, {'cat': '<no category>', 'name': '<no name>', 'shell': '/bin/bash', 'trials': 1, 'cmd': '', 'timeout': 0, 'kill_timeout': 3, 'bail_out': True, 'use_systemd_run': False, 'env': OrderedDict()}, {}, {'name': None})

All keys of this dictionary will be copied into fresh instance attributes when the class is instantiated.

options = {'__init__': {'bail_out_early': BoolParam<bool>, 'iterations': IterationParam<int or "inf">, 'timeout': TimeoutParam<int or "inf">}, 'report': {}}

Groups a set of steps in a logical sequence.

name = 'macro'
cat = 'macro'
reinit(*args, steps=None, step_options=None, **kwargs)[source]
iteration_range(start=1)[source]
filter_steps(steps_filter=None)[source]
run(i_stack, service_hub)[source]

Run the step.

The return values of this method will be collected and stored.

toplevel_run(report_options, slave_manager=None, previous_res=None, service_hub=None)[source]

Equivalent of run() method with additional signal handling and report generation at every step. Must only be called once for the root MacroStep .

report(macrostep_res_seq, service_hub, steps_filter=None, step_options={})[source]

Report the results of nested steps.

get_step_src_files(src_file_set=None)[source]
class bisector.main.StatTestMeta(name, bases, namespace, /, **kwargs)[source]

Bases: ABCMeta, SerializableMeta

Metaclass of all statistical tests.

class bisector.main.StatTestABC(*args, **kwargs)[source]

Bases: Serializable

Abstract Base Class of all statistical tests.

abstract test(failure_rate, iteration_n)[source]

failure_rate ranges in [0;1] and is the number of failed iterations divided by the number of properly executed iterations. iteration_n is the number of iterations that executed with a clear bisect return value (GOOD or BAD). It returns a BisectRet value.

attr_init = ChainMap({}, {'name': None})

All keys of this dictionary will be copied into fresh instance attributes when the class is instantiated.

cat = None
name = 'StatTestABC'
class bisector.main.BasicStatTest(*args, **kwargs)[source]

Bases: StatTestABC

Basic statistical test using a threshold for the failure rate.

yaml_tag = '!bad-percentage-stat-test'
test(failure_rate, iteration_n)[source]

failure_rate ranges in [0;1] and is the number of failed iterations divided by the number of properly executed iterations. iteration_n is the number of iterations that executed with a clear bisect return value (GOOD or BAD). It returns a BisectRet value.

attr_init = ChainMap({}, {}, {'name': None})

All keys of this dictionary will be copied into fresh instance attributes when the class is instantiated.

cat = None
name = 'BasicStatTest'
class bisector.main.BinomStatTest(*args, **kwargs)[source]

Bases: BasicStatTest

Binomial test on the failure rate.

TODO: replace that with a Fisher exact test

yaml_tag = '!binomial-stat-test'
test(failure_rate, iteration_n)[source]

failure_rate ranges in [0;1] and is the number of failed iterations divided by the number of properly executed iterations. iteration_n is the number of iterations that executed with a clear bisect return value (GOOD or BAD). It returns a BisectRet value.

attr_init = ChainMap({}, {}, {}, {'name': None})

All keys of this dictionary will be copied into fresh instance attributes when the class is instantiated.

cat = None
name = 'BinomStatTest'
bisector.main.do_steps_help(cls_list)[source]

Print out the help for the given steps classes.

bisector.main.do_run(slave_manager, iteration_n, stat_test, steps_filter=None, bail_out_early=False, inline_step_list=[], steps_path=None, report_options=None, overall_timeout=0, step_options=None, git_clean=False, resume_path=None, service_hub=None)[source]

Run the specified list of steps.

class bisector.main.ReportPreamble(*args, **kwargs)[source]

Bases: Serializable

Informations split out from the Report so that they can be used to prepare the environment before loading the report body. It is useful to make sure all the modules are imported prior to steps results restoration.

yaml_tag = '!report-preamble'
attr_init = ChainMap({'src_files': []}, {'name': None})

All keys of this dictionary will be copied into fresh instance attributes when the class is instantiated.

cat = None
name = 'ReportPreamble'
bisector.main.check_report_path(path, probe_file)[source]
bisector.main.disable_gc(f)[source]

Decorator to disable garbage collection during the execution of the decorated function.

This can speed-up code that creates a lot of objects in a short amount of time.

class bisector.main.Report(*args, **kwargs)[source]

Bases: Serializable

Report body containg the result of the top level MacroStep .

yaml_tag = '!report'
dont_save = ['preamble', 'path']

Attributes that will not be saved to the Pickle or YAML file.

REPORT_CACHE_TEMPLATE = '{report_filename}.cache.pickle'
save(path=None, upload_service=None)[source]

Save the report to the specified path.

Parameters:

path – Used to save the report is not None, otherwise use the existing path attribute.

classmethod load(path, steps_path=None, use_cache=False, service_hub=None)[source]

Restore a serialized Report from the given file.

Parameters:
  • path – Path to the Report to load. Can be an http URL or a local filename.

  • steps_path – Path to the steps definition YAML file. It is only needed if the report contains foreign classes that must be imported before restoring the report.

  • use_cache – If True, will generate a cached version of the report using the fastest on-disk format available. The cache is invalidated if the modification time of the file is newer than that of the cache.

property bisect_ret
filtered_bisect_ret(*args, **kwargs)[source]
show(*args, service_hub=None, stat_test=None, steps_filter=None, **kwargs)[source]

Show the report results.

attr_init = ChainMap({}, {'name': None})

All keys of this dictionary will be copied into fresh instance attributes when the class is instantiated.

cat = None
name = 'Report'
bisector.main.ensure_dir(file_path)[source]

Ensure that the parent directory of the file_path exists and creates if necessary.

bisector.main.format_placeholders(string, placeholder_map)[source]
bisector.main.DBUS_SERVER_BUS_NAME = 'org.bisector.Server'

Well-known DBus name used by the monitor-server.

bisector.main.DBUS_SLAVE_BOOK_PATH = '/org/bisector/SlaveBook'

DBus path under which the DBusSlaveBook is published by the monitor-server.

bisector.main.DBUS_SLAVE_BUS_NAME_TEMPLATE = 'org.bisector.Slave-{id}'

Template of the DBus well-known name used by slaves.

bisector.main.DBUS_SLAVE_MANAGER_PATH = '/org/bisector/SlaveManager'

DBus path under which the DBusSlaveManager is published by the slaves.

bisector.main.get_dbus_bus()[source]
bisector.main.dbus_variant(v)[source]

Build a gi.repository.GLib.Variant instance out of a Python object.

bisector.main.dbus_variant_dict(dct)[source]

Build a dictionary with gi.repository.GLib.Variant values, so it can be used to create DBus types a{sv} objects.

class bisector.main.dbus_property(fget=None, fset=None, fdel=None, doc=None)[source]

Bases: property

Like standard property decorator, except that signal_prop_change(<prop name>) will be called when the setter function returns, to automatically emit the PropertiesChanged signal.

setter(content=True, iface=None)[source]

Unlike property.setter, this is a decorator with parameters.

class bisector.main.PipeSetter(pipe, attrs)[source]

Bases: object

Write to a pipe when an attribute is set.

__setattr__(attr, val)[source]

Implement setattr(self, name, value).

class bisector.main.DBusSlaveManager(desc, pid, start_ts, start_monotonic_ts, report_path, log_path, path='/org/bisector/SlaveManager')[source]

Bases: object

Object shared between the main process and the DBus slave thread.

It interacts with the bus to influence the execution of the main thread.

prop_iface = 'org.bisector.SlaveManager'
dbus = '\n    <node>\n      <interface name=\'org.bisector.SlaveManager\'>\n        <method name=\'Control\'>\n          <arg type=\'s\' name=\'cmd\' direction=\'in\' />\n          <arg type=\'b\' name=\'response\' direction=\'out\' />\n        </method>\n\n        <property name="State" type="(ss)" access="read">\n          <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="true"/>\n        </property>\n\n        <property name="Iteration" type="t" access="read">\n          <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="true"/>\n        </property>\n\n        <property name="StepNotif" type="(sst)" access="read">\n          <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="true"/>\n        </property>\n\n        <property name="Description" type="s" access="read" />\n        <property name="PID" type="t" access="read" />\n        <property name="RunTime" type="t" access="read" />\n        <property name="StartTs" type="t" access="read" />\n        <property name="StartMonotonicTs" type="t" access="read" />\n        <property name="ReportPath" type="s" access="read" />\n        <property name="LogPath" type="s" access="read" />\n        <property name="SupportedCommands" type="as" access="read" />\n      </interface>\n    </node>\n    '
property ReportPath[source]
property RunTime[source]
property State[source]
property Iteration[source]
property StepNotif[source]
publish(bus, bus_name_template='org.bisector.Slave-{id}')[source]
consume_prop()[source]

This must only be called from the DBus thread, since it emits a DBus signal.

SupportedCommands = ('pause', 'stop', 'continue', 'kill')
Control(cmd)[source]
class bisector.main.DBusSlaveThread(properties)[source]

Bases: object

thread_main(init_done)[source]
quit_thread()[source]
bisector.main.parse_slave_props(slave_props)[source]
bisector.main.send_cmd(slave_id, slave_manager, cmd)[source]
bisector.main.do_monitor(slave_id, args)[source]
bisector.main.do_monitor_server(default_notif)[source]
class bisector.main.DBusSlaveBook(bus, name_lost_callback, bus_name='org.bisector.Server', path='/org/bisector/SlaveBook', default_notif=None)[source]

Bases: object

dbus = "\n    <node>\n      <interface name='org.bisector.SlaveBook'>\n        <method name='RegisterSlave'>\n          <arg type='(so)' name='location' direction='in' />\n        </method>\n\n        <method name='GetSlavesLocation'>\n          <arg type='a(so)' name='locations' direction='out' />\n        </method>\n\n        <method name='SetDesktopNotif'>\n          <arg type='(so)' name='location' direction='in' />\n          <arg type='s' name='prop' direction='in' />\n          <arg type='b' name='enable' direction='in' />\n        </method>\n\n      </interface>\n    </node>\n    "
get_slave_manager(location, timeout=1)[source]

Get the SlaveManager instance of a slave.

unregister_slave(location)[source]
prune_slaves()[source]
GetSlavesLocation()[source]
SetDesktopNotif(location, prop, enable)[source]
consume_slave_prop(location, slave_manager, changed, invalidated)[source]
RegisterSlave(location)[source]
static get_slaves_manager(bus, slave_book)[source]

Helper to get the list of SlaveManager out of a list of slaves location, requesting it from a SlaveBook (DBus object proxy).

class bisector.main.YAMLCLIOptionsAction(option_strings, dest, nargs=None, const=None, default=None, type=None, choices=None, required=False, help=None, metavar=None)[source]

Bases: Action

Custom argparse.Action that extracts command line options from a YAML file. Using “required=True” for any argument will break that since the parser needs to parse partial command lines.

__call__(parser, args, value, option_string)[source]

Call self as a function.

bisector.main.main(argv=['-b', 'html', '-n', '--no-color', '-W', '--keep-going', '-T', '-j', 'auto', '-d', '/home/ubuntu/builds/geaCGQ5B/0/tooling/lisa/tmp/tmp.aN39gaITbs-doctree', '.', '/home/ubuntu/builds/geaCGQ5B/0/tooling/lisa/public/main'])[source]