tmt.hardware package

Submodules

tmt.hardware.constraints module

class tmt.hardware.constraints.And(constraints: list[BaseConstraint] | None = None)

Bases: CompoundConstraint

Represents constraints that are grouped in and fashion

Hold constraints that are grouped in and fashion.

Parameters:

constraints – list of constraints to group.

variants(members: list[Constraint] | None = None) Iterator[list[Constraint]]

Generate all distinct variants of constraints covered by this one.

Since the and reducer demands all child constraints must be satisfied, and some of these constraints can also be compound constraints, we need to construct a cartesian product of variants yielded by child constraints to include all possible combinations.

Parameters:

members – if specified, each variant generated by this method is prepended with this list.

Yields:

iterator over all variants.

class tmt.hardware.constraints.BaseConstraint

Bases: SpecBasedContainer[Any, Any]

Base class for all classes representing one or more constraints

classmethod from_spec(spec: Any) BaseConstraint

Convert from a specification file or from a CLI option

See https://tmt.readthedocs.io/en/stable/code/classes.html#class-conversions for more details.

See to_spec() for its counterpart.

to_minimal_spec() Any

Convert to specification, skip default values

See https://tmt.readthedocs.io/en/stable/code/classes.html#class-conversions for more details.

See from_spec() for its counterpart.

abstractmethod to_spec() Any

Convert to a form suitable for saving in a specification file

See https://tmt.readthedocs.io/en/stable/code/classes.html#class-conversions for more details.

See from_spec() for its counterpart.

abstractmethod uses_constraint(constraint_name: str, logger: Logger) bool

Inspect constraint whether the constraint or one of its children use a constraint of a given name.

Parameters:
  • constraint_name – constraint name to look for.

  • logger – logger to use for logging.

Raises:

NotImplementedError – method is left for child classes to implement.

variant() list[Constraint]

Pick one of the available variants of this constraints.

As the constraint can yield many variants, often there’s an interest in just one. There can be many different ways for picking the best one, whatever that may mean depending on the context, as a starting point this method is provided. In the future, provision plugins would probably use their own guessing to pick the most suitable variant.

abstractmethod variants(members: list[Constraint] | None = None) Iterator[list[Constraint]]

Generate all distinct variants of constraints covered by this one.

For a trivial constraint, there is only one variant, and that is the constraint itself. In the case of compound constraints, the number of variants would be bigger, depending on the constraint’s reducer.

Parameters:

members – if specified, each variant generated by this method is prepended with this list.

Yields:

iterator over all variants.

tmt.hardware.constraints.CHILDLESS_CONSTRAINTS: tuple[str, ...] = ('arch', 'memory', 'hostname')

A list of constraint names that do not have child properties.

tmt.hardware.constraints.CONSTRAINT_COMPONENTS_PATTERN = re.compile('\n    ^                                   # must match the whole string\n    (?P<name>[a-z_+]+)                  # constraint name is mandatory\n    (?:\\[(?P<peer_index>[+-]?\\d+)\\])?   # index is , re.VERBOSE)

Regular expression to match and split a HW constraint into its components. The input consists of a constraint name, (optional) index of the constraint among its peers, (optional) child constraint name, (optional) operator, and value.

  • memory 10 GiB => memory, None, None, None, 10 GiB

  • cpu.processors != 4 => cpu, None, processors, !=, 4

  • disk[1].size <= 1 TiB => disk, 1, size, <=, 1 TiB

tmt.hardware.constraints.CONSTRAINT_NAME_PATTERN = re.compile("\n    (?P<name>[a-z_+]+)                   # constraint name is mandatory\n    (?:\\[(?P<peer_index>[+-]?\\d+)\\])?    # index is optional\n    (?:\\.(?P<child_name>[a-z_]+))?       # child constrain, re.VERBOSE)

Regular expression to match and split a HW constraint name into its components. The input consists of a constraint name, (optional) index of the constraint among its peers, and (optional) child constraint name:

  • memory => memory, None, None

  • cpu.processors => cpu, None, processors

  • disk[1].size => disk, 1, size

tmt.hardware.constraints.CONSTRAINT_VALUE_PATTERN = re.compile('\n    ^                                   # must match the whole string\n    (?P<operator>==|!=|~|!~|=~|=|>=|>|<=|<)?  # optional operator\n    \\s*                                 # operator might b, re.VERBOSE)

Regular expression to match and split the value part of a key:value pair. The input consists of an (optional) operator, the actual value of the constraint, and (optional) units. As a result, pattern yields two groups, operator and value, the latter containing both the value and units.

class tmt.hardware.constraints.CompoundConstraint(reducer: ~typing.Callable[[~collections.abc.Iterable[bool]], bool] = <built-in function any>, constraints: list[~tmt.hardware.constraints.BaseConstraint] | None = None)

Bases: BaseConstraint

Base class for all compound constraints

Construct a compound constraint, constraint imposed to more than one dimension.

Parameters:
  • reducer – a callable reducing a list of results from child constraints into the final answer.

  • constraints – child constraints.

property size: int
to_spec() Any

Convert to a form suitable for saving in a specification file

See https://tmt.readthedocs.io/en/stable/code/classes.html#class-conversions for more details.

See from_spec() for its counterpart.

uses_constraint(constraint_name: str, logger: Logger) bool

Inspect constraint whether it or its children use a constraint of a given name.

Parameters:
  • constraint_name – constraint name to look for.

  • logger – logger to use for logging.

Returns:

True if the given constraint or its children use given constraint name.

abstractmethod variants(members: list[Constraint] | None = None) Iterator[list[Constraint]]

Generate all distinct variants of constraints covered by this one.

Since the and reducer demands all child constraints must be satisfied, and some of these constraints can also be compound constraints, we need to construct a cartesian product of variants yielded by child constraints to include all possible combinations.

Parameters:

members – if specified, each variant generated by this method is prepended with this list.

Yields:

iterator over all variants.

Raises:

NotImplementedError – default implementation is left undefined for compound constraints.

class tmt.hardware.constraints.Constraint(name: str, operator: Operator, operator_handler: Callable[[Any, Any], bool], value: Any, raw_value: str, default_unit: str | None = None, original_constraint: Constraint | None = None)

Bases: BaseConstraint

A constraint imposing a particular limit to one of the guest properties

change_operator(operator: Operator) None

Change operator of this constraint to a given one.

Parameters:

operator – new operator.

default_unit: str | None = None
expand_name() ConstraintNameComponents

Expand constraint name into its components.

Returns:

tuple consisting of constraint name components: name, optional indices, child properties, etc.

name: str
operator: Operator
operator_handler: Callable[[Any, Any], bool]
original_constraint: Constraint | None = None
property printable_name: str
raw_value: str
to_spec() Any

Convert to a form suitable for saving in a specification file

See https://tmt.readthedocs.io/en/stable/code/classes.html#class-conversions for more details.

See from_spec() for its counterpart.

uses_constraint(constraint_name: str, logger: Logger) bool

Inspect constraint whether it or its children use a constraint of a given name.

Parameters:
  • constraint_name – constraint name to look for.

  • logger – logger to use for logging.

Returns:

True if the given constraint or its children use given constraint name.

value: Any
variants(members: list[Constraint] | None = None) Iterator[list[Constraint]]

Generate all distinct variants of constraints covered by this one.

For a trivial constraint, there is only one variant, and that is the constraint itself. In the case of compound constraints, the number of variants would be bigger, depending on the constraint’s reducer.

Parameters:

members – if specified, each variant generated by this method is prepended with this list.

Yields:

iterator over all variants.

class tmt.hardware.constraints.ConstraintComponents(name: str, peer_index: int | None, child_name: str | None, operator: str | None, value: str)

Bases: object

Components of a constraint

child_name: str | None
classmethod from_spec(spec: str) ConstraintComponents
name: str
operator: str | None
peer_index: int | None
value: str
class tmt.hardware.constraints.ConstraintNameComponents(name: str, peer_index: int | None, child_name: str | None)

Bases: NamedTuple

Components of a constraint name

Create new instance of ConstraintNameComponents(name, peer_index, child_name)

child_name: str | None

size of disk[1].size

name: str

disk of disk[1].size

peer_index: int | None

1 of disk[1].size

tmt.hardware.constraints.ConstraintValue = int | ForwardRef('Size') | str | bool | float

A type of constraint values.

class tmt.hardware.constraints.FlagConstraint(name: str, operator: Operator, operator_handler: Callable[[Any, Any], bool], value: Any, raw_value: str, default_unit: str | None = None, original_constraint: Constraint | None = None)

Bases: Constraint

A constraint representing a boolean flag, enabled/disabled, has/has not, etc.

classmethod from_specification(name: str, raw_value: bool, original_constraint: Constraint | None = None, allowed_operators: list[Operator] | None = None) FlagConstraint
value: bool
tmt.hardware.constraints.INDEXABLE_CONSTRAINTS: tuple[str, ...] = ('disk', 'network')

A list of constraint names that operate over sequence of entities.

class tmt.hardware.constraints.IntegerConstraint(name: str, operator: Operator, operator_handler: Callable[[Any, Any], bool], value: Any, raw_value: str, default_unit: str | None = None, original_constraint: Constraint | None = None)

Bases: Constraint

A constraint representing a dimension-less int number

classmethod from_specification(name: str, raw_value: str, original_constraint: Constraint | None = None, allowed_operators: list[Operator] | None = None) IntegerConstraint
value: int
class tmt.hardware.constraints.NumberConstraint(name: str, operator: Operator, operator_handler: Callable[[Any, Any], bool], value: Any, raw_value: str, default_unit: str | None = None, original_constraint: Constraint | None = None)

Bases: Constraint

A constraint representing a float number

classmethod from_specification(name: str, raw_value: str, original_constraint: Constraint | None = None, allowed_operators: list[Operator] | None = None, default_unit: Any | None = None) NumberConstraint
value: Quantity
class tmt.hardware.constraints.Operator(*values)

Bases: Enum

Binary operators defined by specification

CONTAINS = 'contains'

Needle must be present in the haystack.

EQ = '=='
GT = '>'
GTE = '>='
LT = '<'
LTE = '<='
MATCH = '~'
NEQ = '!='
NOTCONTAINS = 'not contains'

Needle must not be present in the haystack.

NOTCONTAINS_EXCLUSIVE = 'not contains exclusive'

Needle may be present in the haystack as long it is not the only item.

NOTMATCH = '!~'
class tmt.hardware.constraints.Or(constraints: list[BaseConstraint] | None = None)

Bases: CompoundConstraint

Represents constraints that are grouped in or fashion

Hold constraints that are grouped in or fashion.

Parameters:

constraints – list of constraints to group.

variants(members: list[Constraint] | None = None) Iterator[list[Constraint]]

Generate all distinct variants of constraints covered by this one.

Since the any reducer allows any child constraints to be satisfied for the whole group to evaluate as True, it is trivial to generate variants - each child constraint shall provide its own “branch”, and there is no need for products or joins of any kind.

Parameters:

members – if specified, each variant generated by this method is prepended with this list.

Yields:

iterator over all variants.

exception tmt.hardware.constraints.ParseError(constraint_name: str, raw_value: str, message: str | None = None)

Bases: MetadataError

Raised when HW requirement parsing fails

Raise when HW requirement parsing fails.

Parameters:
  • constraint_name – name of the constraint that caused issues.

  • raw_value – original raw value.

  • message – optional error message.

tmt.hardware.constraints.ReducerType

A callable reducing a sequence of booleans to a single one. Think any() or all().

alias of Callable[[Iterable[bool]], bool]

class tmt.hardware.constraints.SizeConstraint(name: str, operator: Operator, operator_handler: Callable[[Any, Any], bool], value: Any, raw_value: str, default_unit: str | None = None, original_constraint: Constraint | None = None)

Bases: Constraint

A constraint representing a size of resource, usually a storage

classmethod from_specification(name: str, raw_value: str, original_constraint: Constraint | None = None, allowed_operators: list[Operator] | None = None, default_unit: Any | None = 'bytes') SizeConstraint
value: Size
class tmt.hardware.constraints.TextConstraint(name: str, operator: Operator, operator_handler: Callable[[Any, Any], bool], value: Any, raw_value: str, default_unit: str | None = None, original_constraint: Constraint | None = None)

Bases: Constraint

A constraint representing a string, e.g. a name

classmethod from_specification(name: str, raw_value: str, original_constraint: Constraint | None = None, allowed_operators: list[Operator] | None = None) TextConstraint
value: str
tmt.hardware.constraints.UNITS = <pint.registry.UnitRegistry object>

Unit registry, used and shared by all code.

tmt.hardware.constraints.match(text: str, pattern: str) bool

Match a text against a given regular expression.

Parameters:
  • text – string to examine.

  • pattern – regular expression.

Returns:

True if pattern matches the string.

tmt.hardware.constraints.not_contains(haystack: list[str], needle: str) bool

Find out whether an item is in the given list.

Note

Opposite of operator.contains().

Parameters:
  • haystack – container to examine.

  • needle – item to look for in haystack.

Returns:

True if needle is not in haystack.

tmt.hardware.constraints.not_contains_exclusive(haystack: list[str], needle: str) bool

Find out whether an item is in the given list.

Note

A variant of not_contains(): an item may be present, as long as other items are present.

Parameters:
  • haystack – container to examine.

  • needle – item to look for in haystack.

Returns:

True if needle is not in haystack or if needle is in haystack but other items are there as well.

tmt.hardware.constraints.not_match(text: str, pattern: str) bool

Match a text against a given regular expression.

Parameters:
  • text – string to examine.

  • pattern – regular expression.

Returns:

True if pattern does not matche the string.

tmt.hardware.requirements module

class tmt.hardware.requirements.Hardware(constraint: tmt.hardware.constraints.BaseConstraint | None, spec: Any)

Bases: SpecBasedContainer[Any, Any]

and_(constraint: BaseConstraint) None
constraint: BaseConstraint | None
format_variants() Iterator[str]

Format variants of constraints.

Yields:

for each variant, which is nothing but a list of constraints, method yields a string variant’s serial number and formatted constraints.

classmethod from_spec(spec: Any) Hardware

Convert from a specification file or from a CLI option

See https://tmt.readthedocs.io/en/stable/code/classes.html#class-conversions for more details.

See to_spec() for its counterpart.

report_support(*, names: list[str] | None = None, check: Callable[[Constraint], bool] | None = None, logger: Logger) None

Report all unsupported constraints.

A helper method for plugins: plugin provides a callback which checks whether a given constraint is or is not supported by the plugin, and method calls the callback for each constraint stored in this container.

Both names and check are optional, and both can be used and combined. First, the names list is checked, if a constraint is not found, check is called if it’s defined.

Parameters:
  • names – a list of constraint names. If a constraint name is on this list, it is considered to be supported by the report_support caller. Caller may list both full constraint name, e.g. cpu.cores, or just the subsystem name, cpu, indicating all child constraints are supported.

  • check – a callback to call for each constraint in this container. Accepts a single parameter, a constraint to check, and if its return value is true-ish, the constraint is considered to be supported by the report_support caller.

spec: Any
to_minimal_spec() Any

Convert to specification, skip default values

See https://tmt.readthedocs.io/en/stable/code/classes.html#class-conversions for more details.

See from_spec() for its counterpart.

to_spec() Any

Convert to a form suitable for saving in a specification file

See https://tmt.readthedocs.io/en/stable/code/classes.html#class-conversions for more details.

See from_spec() for its counterpart.

tmt.hardware.requirements.parse_hw_requirements(spec: Any) BaseConstraint

Convert raw specification of HW constraints to our internal representation.

Parameters:

spec – raw constraints specification as stored in an environment.

Returns:

root of HW constraints tree.

tmt.hardware.requirements.ungroupify(fn: Callable[[Any], BaseConstraint]) Callable[[Any], BaseConstraint]

Swap returned single-child compound constraint and that child.

Helps reduce the number of levels in the constraint tree: if the return value is a compound constraint which contains just a single child, return the child instead of the compound constraint.

Meant for constraints that do not have an index, e.g. memory or cpu. For indexable constraints, see ungroupify_indexed().

tmt.hardware.requirements.ungroupify_indexed(fn: Callable[[Any, int], BaseConstraint]) Callable[[Any, int], BaseConstraint]

Swap returned single-child compound constraint and that child.

Helps reduce the number of levels in the constraint tree: if the return value is a compound constraint which contains just a single child, return the child instead of the compound constraint.

Meant for constraints that have an index, e.g. disk or network. For non-indexable constraints, see ungroupify().

Module contents

Guest hardware requirements specification and helpers.

tmt metadata allow to describe various HW requirements a guest needs to satisfy. This package provides useful functions and classes for core functionality and shared across provision plugins.

Parsing of HW requirements

Set of HW requirements, as given by test or plan metadata, is represented by Python structures - lists, mappings, primitive types - when loaded from fmf files. Part of the code below converts this representation to a tree of objects that provide helpful operations for easier evaluation and processing of HW requirements.

Each HW requirement “rule” in original metadata is a constraint, a condition the eventual guest HW must satisfy. Each node of the tree created from HW requirements is therefore called “a constraint”, and represents either a single condition (“trivial” constraints), or a set of such conditions plus a function reducing their individual outcomes to one final answer for the whole set (think any() and all() built-in functions) (“compound” constraints). Components of each constraint - dimension, operator, value, units - are decoupled from the rest, and made available for inspection.

[1] https://tmt.readthedocs.io/en/stable/spec/hardware.html

tmt.hardware.format_compact(quantity: Quantity, digits: int = 1) str