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
Connector
which 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
Initializer
s. 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
Shell
which 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:
ABC
Base 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
Connector
andShell
both inherit from it.- ch: Channel¶
Channel to communicate with this machine.
Warning
Please refrain from interacting with the channel directly. Instead, write a
Shell
that 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:
Machine
Base-class for machine initializers.
- abstract _init_machine() AbstractContextManager [source]¶
Run this initializer.
Implementations of this method can make use of
self.ch
as they will run after the connector has succeeded.Todo
More docs for this …
- ch: Channel¶
Channel to communicate with this machine.
Warning
Please refrain from interacting with the channel directly. Instead, write a
Shell
that 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.
- class tbot.machine.PreConnectInitializer[source]¶
Bases:
Machine
Base-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() AbstractContextManager [source]¶
Pre-connection initialization context.
- ch: Channel¶
Channel to communicate with this machine.
Warning
Please refrain from interacting with the channel directly. Instead, write a
Shell
that 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.
- class tbot.machine.PostShellInitializer[source]¶
Bases:
Machine
Base-class for post-shell initializer context.
This initializer is run after
tbot.machine.Initializer._init_machine()
and after the shell has been initialized.- ch: Channel¶
Channel to communicate with this machine.
Warning
Please refrain from interacting with the channel directly. Instead, write a
Shell
that 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.