This module provide utilities for managing “locks” on the lab-host. This can be used in setups where multiple users might try accessing the same host at the same time. Instead of cryptic errors due to busy devices or, even worse, bad behavior because of two running tbot testcases interfering, only one can ever access, for example, a board.

To facilitate this, two parts are needed:

  1. The lab-host configuration must be augmented with the LockManager mixin. This provides a locking “implementation” which board machines can hook into.

  2. To enable locking for a certain board, it should inherit the MachineLock mixin.

class tbot_contrib.locking.MachineLock[source]

Bases: PreConnectInitializer

This is the initializer that is inherited by the board machine. It just calls the lab-host’s locking implementation.

New in version 0.9.1.

lock_expiry: int | None = None

Timeout after which the lock should be considered expired.

This provides a safeguard in case a testcase crashes without unlocking a lock - After the lock has expired, it will be considered unlocked again and a new testcase can acquire it.

property lock_name: str

Prefix from which lock file name is derived.

Defaults to the machine’s name: self.name.

class tbot_contrib.locking.LockManager[source]

Bases: LockManagerBase, PostShellInitializer, LinuxShell

Machine locking implementation based on Python, bash and flock(1)

New in version 0.9.1.

lock_checkpid: bool = True

Make tbot check whether the PID associated with a lockfile is still alive.

If this check is enabled and the PID is found, the lock will be considered active, even if it would otherwise have been assumed expired.

property lock_dir: Path

The directory where tbot locks are stored.

Defaults to /tmp/tbot-locks. If this directory does not exist, it will be created and given 0777 access mode to allow all users to write lockfiles to it.

request_machine_lock(name: str, *, expiry: int | None = None) bool[source]

Request lock for machine named name.

This method will usually be called via the MachineLock mixin.

  • name (str) – Name of the lock to be acquired.

  • expiry (int) – Optional timeout after which a lock should ‘expire’. When a lock is expired, followup locking requests will treat it as unlocked. This can be used as a safeguard if a testcase fails without unlocking.


True if the lock has been acquired successfully and False otherwise.

release_machine_lock(name: str) None[source]

Release lock for machine named name.

If not explicitly released, the LockManager will automatically unlock all locks it is holding when the lab-host machine is deinitialized.

get_active_machine_locks() Set[str][source]

Return the active machine locks managed by this LockManager instance.