tbot.machine¶
Machines are tbot’s abstraction over the different computers it can interact
with. This includes the machine it is running on
(LocalLabHost), the lab-host
(LabHost), the device-under-test, as U-Boot
(UBootMachine) and as Linux
(LinuxMachine). Machines are composed of three
different parts:
The
Connectorwhich is responsible for establishing a connection to the machine. This can happen in many different ways, for example using Paramiko, by opening a serial-console, etc…Optionally, any number of
Initializers. These can, step by step, setup the channel into a state until the shell appears. Examples would be theUBootAutobootIntercept(catch the autoboot prompt and press a key) or theLinuxBootLogin(wait for the login prompt and then enter username & password).The
Shellwhich defines how a testcase can interact with this machine. Typically this is an interface of methods for running commands.
Composition is done using multiple-inheritance, like this:
from tbot.machine import connector, linux
class MyLabHost(
# The connector:
connector.ParamikoConnector,
# - No initializers here -
# The shell:
linux.Bash,
):
# Options for the paramiko connector:
hostname = "78.79.32.85"
username = "tbot-user"
# We can override anything we like to customize it
@property
def workdir(self):
return linux.Workdir.static(self, "/opt/tbot-{self.username}")
Machines are used as context-managers. This means you will later on instantiate the above machine like this (if you were to hardcode the machine. You should probably use tbot’s Configuration mechanism instead):
@tbot.testcase
def footest():
with MyLabHost() as lh:
# Run a command:
lh.exec0("uname", "-a")
For more information about the individual parts of a machine, take a look at
tbot.machine.connector, tbot.machine.Initializer, and
tbot.machine.shell. Specifically for interacting with Linux
machines, you should head over to Linux Shells.
Base-Class¶
- class tbot.machine.Machine[source]¶
Bases:
ABCBase class for all machines.
This class contains the necessary code to compose the different parts of a machine into a usable class. You won’t need to use it directly in most cases as
ConnectorandShellboth inherit from it.- ch: Channel¶
Channel to communicate with this machine.
Warning
Please refrain from interacting with the channel directly. Instead, write a
Shellthat wraps around the channel interaction. That way, the state of the channel is only managed in a single place and you won’t have to deal with nasty bugs when multiple parties make assumptions about the state of the channel.
Initializers¶
- class tbot.machine.Initializer[source]¶
Bases:
MachineBase-class for machine initializers.
- abstract _init_machine() ContextManager[source]¶
Run this initializer.
Implementations of this method can make use of
self.chas they will run after the connector has succeeded.Todo
More docs for this …
- class tbot.machine.PreConnectInitializer[source]¶
Bases:
MachineBase-class for pre-connection initializer context.
This initializer is run before connecting to the machine, before
tbot.machine.Initializer._init_machine()- abstract _init_pre_connect() ContextManager[source]¶
Pre-connection initialization context.
- class tbot.machine.PostShellInitializer[source]¶
Bases:
MachineBase-class for post-shell initializer context.
This initializer is run after
tbot.machine.Initializer._init_machine()and after the shell has been initialized.- abstract _init_post_shell() ContextManager[source]¶
Post-shell initialization context.