### Install Testinfra Source: https://testinfra.readthedocs.io/en/latest/index.html Install testinfra using pip. The devel version can be installed directly from GitHub. ```bash $ pip install pytest-testinfra ``` ```bash # or install the devel version $ pip install 'git+https://github.com/pytest-dev/pytest-testinfra@main#egg=pytest-testinfra' ``` -------------------------------- ### Write First Testinfra Tests Source: https://testinfra.readthedocs.io/en/latest/index.html Example of a Python test file using Testinfra to check file properties, package installation, and service status. ```python def test_passwd_file(host): passwd = host.file("/etc/passwd") assert passwd.contains("root") assert passwd.user == "root" assert passwd.group == "root" assert passwd.mode == 0o644 def test_nginx_is_installed(host): nginx = host.package("nginx") assert nginx.is_installed assert nginx.version.startswith("1.2") def test_nginx_running_and_enabled(host): nginx = host.service("nginx") assert nginx.is_running assert nginx.is_enabled ``` -------------------------------- ### Connection API - Get Host Instance Source: https://testinfra.readthedocs.io/en/latest/api.html Demonstrates how to get a host instance dynamically using testinfra.get_host with a specified backend and optional sudo. ```APIDOC ## GET /api/host ### Description Dynamically retrieve a host instance to interact with remote or local systems. ### Method GET (conceptual, as this is a library function) ### Endpoint N/A (Library function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python import testinfra host = testinfra.get_host("paramiko://root@server:2222", sudo=True) ``` ### Response #### Success Response (200) - **host** (object) - A testinfra host object representing the connected system. #### Response Example ```python # Example of using the host object assert host.file("/etc/shadow").mode == 0o640 ``` ``` -------------------------------- ### Install Paramiko for Remote Testing Source: https://testinfra.readthedocs.io/en/latest/invocation.html Install the Paramiko library to enable SSH connections for testing remote systems. ```bash $ pip install paramiko ``` -------------------------------- ### Install Testinfra with extras Source: https://testinfra.readthedocs.io/en/latest/backends.html Install Testinfra with specific backends using pip extras to satisfy Python dependencies. System-packaged tools may still be required. ```bash $ pip install pytest-testinfra[ansible,salt] ``` -------------------------------- ### Get all installed packages Source: https://testinfra.readthedocs.io/en/latest/modules.html List all installed packages and their versions using `pip.get_packages`. You can specify a custom pip path. ```python >>> host.pip.get_packages(pip_path='~/venv/website/bin/pip') {'Django': {'version': '1.10.2'}, 'mywebsite': {'version': '1.0a3', 'path': '/srv/website'}, 'psycopg2': {'version': '2.6.2'}} ``` -------------------------------- ### Get block device start sector Source: https://testinfra.readthedocs.io/en/latest/modules.html Returns the start sector of a block device on its underlying device. Typically zero for full devices and non-zero for partitions. Requires sudo or root. ```python >>> host.block_device("/dev/sda1").start_sector 2048 ``` ```python >>> host.block_device("/dev/md0").start_sector 0 ``` -------------------------------- ### Check if a package is installed Source: https://testinfra.readthedocs.io/en/latest/modules.html Use the `is_installed` property to verify if a package is present on the system. ```python >>> host.package("pip").is_installed True ``` -------------------------------- ### Test Execution Output Source: https://testinfra.readthedocs.io/en/latest/index.html Example output from running Testinfra tests, showing test session start, platform details, and test results (PASSED). ```text ====================== test session starts ====================== platform linux -- Python 2.7.3 -- py-1.4.26 -- pytest-2.6.4 plugins: testinfra collected 3 items test_myinfra.py::test_passwd_file[local] PASSED test_myinfra.py::test_nginx_is_installed[local] PASSED test_myinfra.py::test_nginx_running_and_enabled[local] PASSED =================== 3 passed in 0.66 seconds ==================== ``` -------------------------------- ### Get Package Release Information Source: https://testinfra.readthedocs.io/en/latest/modules.html Retrieve the release-specific information for an installed package. Useful for tracking specific builds or versions. ```python >>> host.package("nginx").release '1.el6' ``` -------------------------------- ### Get package version Source: https://testinfra.readthedocs.io/en/latest/modules.html Retrieve the installed version of a package using the `version` property. ```python >>> host.package("pip").version '18.1' ``` -------------------------------- ### Install Pytest-xdist for Parallel Execution Source: https://testinfra.readthedocs.io/en/latest/invocation.html Install the pytest-xdist plugin to enable parallel test execution across multiple processes. ```bash $ pip install pytest-xdist ``` -------------------------------- ### Get all Facter facts Source: https://testinfra.readthedocs.io/en/latest/modules.html Retrieve all available system facts using Facter by calling `host.facter()`. This returns a dictionary of system information. ```python >>> host.facter() { "operatingsystem": "Debian", "kernel": "linux", [...] } ``` -------------------------------- ### Getting a Host Instance Source: https://testinfra.readthedocs.io/en/latest/modules.html Use the `get_host` class method to obtain a Host instance from a host specification. ```APIDOC ## Getting a Host Instance ### Description Use the `get_host` class method to obtain a Host instance from a host specification. ### Method #### `get_host(hostspec: str, **kwargs: Any) -> Host` ##### Description Return a Host instance from hostspec. ##### Parameters - **hostspec** (str) - Should be like `://?param1=value1¶m2=value2`. - **kwargs** (Any) - Additional parameters can be passed in **kwargs (e.g., `get_host("local://", sudo=True)` is equivalent to `get_host("local://?sudo=true")`). ##### Examples ```python # Example usage of get_host get_host("local://", sudo=True) get_host("paramiko://user@host", ssh_config="/path/my_ssh_config") get_host("ansible://all?ansible_inventory=/etc/ansible/inventory") ``` ``` -------------------------------- ### Manage Podman containers Source: https://testinfra.readthedocs.io/en/latest/modules.html Interact with Podman containers, checking their running status, retrieving IDs, and names. This example shows how to get a specific container object. ```python >>> nginx = host.podman("app_nginx") >>> nginx.is_running True >>> nginx.id '7e67dc7495ca8f451d346b775890bdc0fb561ecdc97b68fb59ff2f77b509a8fe' >>> nginx.name 'app_nginx' ``` -------------------------------- ### Check if Package is Installed Source: https://testinfra.readthedocs.io/en/latest/modules.html Verify whether a specific package is installed on the system. Supports various package managers like apk, apt, brew, and rpm. ```python >>> host.package("nginx").is_installed True ``` -------------------------------- ### Get All Network Interface Names Source: https://testinfra.readthedocs.io/en/latest/modules.html List the names of all available network interfaces on the host. This is useful for inventory and configuration checks. ```python >>> host.interface.names() ['lo', 'tunl0', 'ip6tnl0', 'eth0'] ``` -------------------------------- ### Get All Mount Points Source: https://testinfra.readthedocs.io/en/latest/modules.html List all currently mounted file systems on the host, including their path, device, filesystem type, and options. Provides a complete overview of the system's storage. ```python >>> host.mount_point.get_mountpoints() [, ] ``` -------------------------------- ### Package API Source: https://testinfra.readthedocs.io/en/latest/modules.html Provides methods to check the status and version of installed packages. ```APIDOC ## Package API ### Get Package Status and Version Checks if a package is installed and retrieves its version and release information. ### Method GET ### Endpoint /api/packages/{name} ### Parameters #### Path Parameters - **name** (string) - Required - The name of the package (e.g., "nginx"). ### Response #### Success Response (200) - **is_installed** (boolean) - True if the package is installed. - **version** (string) - The version of the package. - **release** (string) - The release-specific information of the package version. ### Request Example ```json { "example": "host.package('nginx').is_installed" } ``` ### Response Example ```json { "example": "True" } ``` ``` -------------------------------- ### Compare File Content Across Servers Source: https://testinfra.readthedocs.io/en/latest/api.html This example demonstrates comparing the content of a file on two different servers using testinfra. Ensure both servers are accessible via SSH. ```python import testinfra def test_same_passwd(): a = testinfra.get_host("ssh://a") b = testinfra.get_host("ssh://b") assert a.file("/etc/passwd").content == b.file("/etc/passwd").content ``` -------------------------------- ### Get Mount Point Options Source: https://testinfra.readthedocs.io/en/latest/modules.html Retrieve the mount options (e.g., rw, relatime) for a given mount point. Essential for verifying filesystem access and behavior. ```python >>> host.mount_point("/").options ['rw', 'relatime', 'data=ordered'] ``` -------------------------------- ### Pip Package Management API Source: https://testinfra.readthedocs.io/en/latest/modules.html APIs for managing pip packages, checking installation status, versions, and dependencies. ```APIDOC ## Pip Package Management ### Description Provides methods to interact with the pip package manager to check package status, versions, and dependencies. ### Methods #### `is_installed` - **Description**: Test if a package is installed. - **Example**: ```python host.package("pip").is_installed ``` #### `version` - **Description**: Return the installed version of a package. - **Example**: ```python host.package("pip").version ``` #### `check()` - **Description**: Verify installed packages have compatible dependencies. Requires pip version >= 9.0.0. - **Example**: ```python cmd = host.pip.check() print(cmd.rc) print(cmd.stdout) ``` #### `get_packages()` - **Description**: Get a dictionary of all installed packages and their versions. - **Parameters**: - `pip_path` (str) - Optional - Path to the pip executable. - **Example**: ```python host.pip.get_packages(pip_path='~/venv/website/bin/pip') ``` #### `get_outdated_packages()` - **Description**: Get a dictionary of outdated packages with current and latest versions. - **Parameters**: - `pip_path` (str) - Optional - Path to the pip executable. - **Example**: ```python host.pip.get_outdated_packages(pip_path='~/venv/website/bin/pip') ``` ``` -------------------------------- ### Get Docker Version Information Source: https://testinfra.readthedocs.io/en/latest/modules.html Retrieve Docker client and server version information. An optional format string can be provided for custom output. ```python >>> host.docker.version() Client: Docker Engine - Community ... >>> host.docker.version("{{.Client.Context}}")) default ``` -------------------------------- ### Get specific Facter facts Source: https://testinfra.readthedocs.io/en/latest/modules.html Retrieve specific system facts by providing their names as arguments to `host.facter()`. This returns a dictionary containing only the requested facts. ```python >>> host.facter("kernelversion", "is_virtual") { "kernelversion": "3.16.0", "is_virtual": "false" } ``` -------------------------------- ### Recursive Test Discovery Source: https://testinfra.readthedocs.io/en/latest/invocation.html Run Testinfra tests recursively by discovering all files starting with `test_` in the current directory. ```bash # Test recursively all test files (starting with `test_`) in current directory $ py.test ``` -------------------------------- ### Get block device size Source: https://testinfra.readthedocs.io/en/latest/modules.html Retrieves the size of a block device in bytes. Requires sudo or root privileges. ```python >>> host.block_device("/dev/sda1").size 512110190592 ``` -------------------------------- ### Kubectl backend default usage Source: https://testinfra.readthedocs.io/en/latest/backends.html Use the Kubectl backend to test containers in Kubernetes. This example uses the default namespace and default container for the specified pod. ```bash # will use the default namespace and default container $ py.test --hosts='kubectl://mypod-a1b2c3' ``` -------------------------------- ### Read File Content Source: https://testinfra.readthedocs.io/en/latest/modules.html Get the content of a file as bytes or a string. Use '.content' for bytes and '.content_string' for a decoded string. ```python >>> host.file("/tmp/foo").content b'caf\xc3\xa9' >>> host.file("/tmp/foo").content_string 'cafĂ©' ``` -------------------------------- ### Get block device sector size Source: https://testinfra.readthedocs.io/en/latest/modules.html Returns the sector size of a block device in bytes. Use with sudo or root. ```python >>> host.block_device("/dev/sda1").sector_size 512 ``` -------------------------------- ### Get a single matching process Source: https://testinfra.readthedocs.io/en/latest/modules.html Retrieve a single process using `process.get` with filters. Raises `RuntimeError` if no process is found or if multiple processes match the filters. ```python >>> host.process.get(user="root", comm="zsh") ``` -------------------------------- ### Get All IP Addresses for Network Interface Source: https://testinfra.readthedocs.io/en/latest/modules.html Retrieve both IPv4 and IPv6 addresses associated with a network interface. This helps in verifying all network configurations. ```python >>> host.interface("eth0").addresses ['192.168.31.254', '192.168.31.252', 'fe80::e291:f5ff:fe98:6b8c'] ``` -------------------------------- ### Check package dependencies Source: https://testinfra.readthedocs.io/en/latest/modules.html Verify that installed packages have compatible dependencies using the `pip.check` class method. This requires pip version 9.0.0 or later. ```python >>> cmd = host.pip.check() >>> cmd.rc 0 >>> cmd.stdout No broken requirements found. ``` -------------------------------- ### SSH backend with extra arguments Source: https://testinfra.readthedocs.io/en/latest/backends.html Pass extra arguments to the SSH command for the SSH backend. For example, to disable StrictHostKeyChecking. ```bash $ py.test --hosts='ssh://server' --ssh-extra-args='-o StrictHostKeyChecking=no' ``` -------------------------------- ### Get List of Supervisor Managed Services Source: https://testinfra.readthedocs.io/en/latest/modules.html Retrieves a list of all services managed by Supervisor. The path to supervisorctl and its configuration file can be optionally provided. ```python >>> host.supervisor.get_services() [ ] ``` ```python >>> host.supervisor.get_services("/usr/bin/supervisorctl", "/etc/supervisor/supervisord.conf") [ ] ``` -------------------------------- ### Get Package Version Source: https://testinfra.readthedocs.io/en/latest/modules.html Retrieve the exact version string of a package as reported by the system's package manager. Essential for version compliance checks. ```python >>> host.package("nginx").version '1.2.1-2.2+wheezy3' ``` -------------------------------- ### Get block device block size Source: https://testinfra.readthedocs.io/en/latest/modules.html Retrieves the block size of a block device in bytes. Requires sudo or root privileges. ```python >>> host.block_device("/dev/sda").block_size 4096 ``` -------------------------------- ### Get a specific process Source: https://testinfra.readthedocs.io/en/latest/modules.html Retrieve a specific process using `process.get` with filters like user and command name. This is useful for finding parent or worker processes. ```python >>> master = host.process.get(user="root", comm="nginx") # Here is the master nginx process (running as root) >>> master.args 'nginx: master process /usr/sbin/nginx -g daemon on; master_process on;' # Here are the worker processes (Parent PID = master PID) >>> workers = host.process.filter(ppid=master.pid) >>> len(workers) 4 # Nginx don't eat memory >>> sum([w.pmem for w in workers]) 0.8 # But php does ! >>> sum([p.pmem for p in host.process.filter(comm="php5-fpm")]) 19.2 ``` -------------------------------- ### Get Mount Point Device Source: https://testinfra.readthedocs.io/en/latest/modules.html Identify the underlying device (e.g., /dev/sda1) associated with a mount point. Important for storage management and verification. ```python >>> host.mount_point("/").device '/dev/sda1' ``` -------------------------------- ### Get Mount Point Filesystem Type Source: https://testinfra.readthedocs.io/en/latest/modules.html Determine the filesystem type (e.g., ext4, proc) of a mounted path. Useful for verifying storage configurations. ```python >>> host.mount_point("/").filesystem 'ext4' ``` -------------------------------- ### Get All Listening Sockets Source: https://testinfra.readthedocs.io/en/latest/modules.html Retrieves a list of all currently listening sockets on the host. This class method provides a comprehensive overview of active network listeners. ```python >>> host.socket.get_listening_sockets() ['tcp://0.0.0.0:22', 'tcp://:::22', 'unix:///run/systemd/private', ...] ``` -------------------------------- ### Initialize host instance with get_host Source: https://testinfra.readthedocs.io/en/latest/modules.html Create a Host instance using a hostspec string and optional keyword arguments. ```python >>> get_host("local://", sudo=True) >>> get_host("paramiko://user@host", ssh_config="/path/my_ssh_config") >>> get_host("ansible://all?ansible_inventory=/etc/ansible/inventory") ``` -------------------------------- ### Get File Mode and Permissions Source: https://testinfra.readthedocs.io/en/latest/modules.html Retrieve the file mode as an octal integer and check permissions using stat constants. The mode represents the file's permissions. ```python >>> host.file("/etc/shadow").mode 416 # Oo640 octal >>> host.file("/etc/shadow").mode == 0o640 True >>> oct(host.file("/etc/shadow").mode) == '0o640' True >>> import stat >>> host.file("/etc/shadow").mode == stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP True ``` -------------------------------- ### List Directory Contents Source: https://testinfra.readthedocs.io/en/latest/modules.html Get a list of all items (files and subdirectories) within a specified directory. The output is a list of strings representing the names of the items. ```python >>> host.file("/tmp").listdir() ['foo_file', 'bar_dir'] ``` -------------------------------- ### Get IPv6 Addresses for Network Interface Source: https://testinfra.readthedocs.io/en/latest/modules.html Retrieve IPv6 addresses configured on a specific network interface. Useful for testing IPv6 connectivity. ```python >>> host.interface("eth0", "inet6").addresses ['fe80::e291:f5ff:fe98:6b8c'] ``` -------------------------------- ### Get File Owner and User ID Source: https://testinfra.readthedocs.io/en/latest/modules.html Retrieve the owner username and user ID (UID) of a file. The user is returned as a string and the UID as an integer. ```python >>> host.file("/etc/passwd").user 'root' >>> host.file("/etc/passwd").uid 0 ``` -------------------------------- ### Get block device Read Ahead value Source: https://testinfra.readthedocs.io/en/latest/modules.html Returns the Read Ahead value for a block device, measured in 512-byte sectors. Use with sudo or root. ```python >>> host.block_device("/dev/sda").ra 256 ``` -------------------------------- ### Get Default Network Interface (IPv6) Source: https://testinfra.readthedocs.io/en/latest/modules.html Attempt to identify the network interface used for the default IPv6 route. Returns None if no default IPv6 interface is found. ```python >>> host.interface.default("inet6") None ``` -------------------------------- ### Get Network Interface Link Properties Source: https://testinfra.readthedocs.io/en/latest/modules.html Inspect the link properties of a network interface, such as MAC address, MTU, and operational state. This is valuable for low-level network diagnostics. ```python >>> host.interface("lo").link {'address': '00:00:00:00:00:00', 'broadcast': '00:00:00:00:00:00', 'flags': ['LOOPBACK', 'UP', 'LOWER_UP'], 'group': 'default', 'ifindex': 1, 'ifname': 'lo', 'link_type': 'loopback', 'linkmode': 'DEFAULT', 'mtu': 65536, 'operstate': 'UNKNOWN', 'qdisc': 'noqueue', 'txqlen': 1000} ``` -------------------------------- ### Integrate with KitchenCI Source: https://testinfra.readthedocs.io/en/latest/examples.html Configure the shell verifier in .kitchen.yml to use Testinfra. ```yaml verifier: name: shell command: py.test --hosts="paramiko://${KITCHEN_USERNAME}@${KITCHEN_HOSTNAME}:${KITCHEN_PORT}?ssh_identity_file=${KITCHEN_SSH_KEY}" --junit-xml "junit-${KITCHEN_INSTANCE}.xml" "test/integration/${KITCHEN_SUITE}" ``` -------------------------------- ### Configure LXC/LXD Backend Source: https://testinfra.readthedocs.io/en/latest/backends.html Connect to running LXC or LXD containers using the lxc backend. ```bash $ py.test --hosts='lxc://container_name' ``` -------------------------------- ### Get Connected Clients for a Socket Source: https://testinfra.readthedocs.io/en/latest/modules.html Returns a list of clients connected to a listening socket. For TCP and UDP, it returns (address, port) pairs. For Unix sockets, it returns a list of None values. ```python >>> host.socket("tcp://22").clients [('2001:db8:0:1', 44298), ('192.168.31.254', 34866)] >>> host.socket("unix:///var/run/docker.sock") [None, None, None] ``` -------------------------------- ### Configure OpenShift Backend Source: https://testinfra.readthedocs.io/en/latest/backends.html Connect to OpenShift pods using the openshift backend, with options for namespace and container selection. ```bash $ py.test --hosts='openshift://mypod-a1b2c3' ``` ```bash $ py.test --hosts='openshift://somepod-2536ab?container=nginx&namespace=web' ``` ```bash $ py.test --hosts='openshift://somepod-123?kubeconfig=/path/kubeconfig,openshift://otherpod-123?kubeconfig=/other/kubeconfig' ``` -------------------------------- ### Configure Kubernetes Backend with Kubeconfig Source: https://testinfra.readthedocs.io/en/latest/backends.html Use the kubectl backend with multiple configurations by specifying the kubeconfig path. ```bash $ py.test --hosts='kubectl://somepod-123?kubeconfig=/path/kubeconfig,kubectl://otherpod-123?kubeconfig=/other/kubeconfig' ``` -------------------------------- ### Configure WinRM Backend Source: https://testinfra.readthedocs.io/en/latest/backends.html Connect to Windows hosts using WinRM, supporting authentication, SSL configuration, and timeout overrides. ```bash $ py.test --hosts='winrm://Administrator:Password@127.0.0.1' ``` ```bash $ py.test --hosts='winrm://vagrant@127.0.0.1:2200?no_ssl=true&no_verify_ssl=true' ``` ```bash $ py.test --hosts='winrm://vagrant@127.0.0.1:2200?read_timeout_sec=120&operation_timeout_sec=100' ``` -------------------------------- ### Get Ansible variables Source: https://testinfra.readthedocs.io/en/latest/modules.html Retrieves a dictionary of Ansible variables available on the host. ```python >>> host.ansible.get_variables() { 'inventory_hostname': 'localhost', 'group_names': ['ungrouped'], 'foo': 'bar', } ``` -------------------------------- ### Integrate with Vagrant Source: https://testinfra.readthedocs.io/en/latest/examples.html Run Testinfra tests against a running Vagrant machine. ```bash vagrant ssh-config > .vagrant/ssh-config py.test --hosts=default --ssh-config=.vagrant/ssh-config tests.py ``` -------------------------------- ### Salt backend host selection Source: https://testinfra.readthedocs.io/en/latest/backends.html Use the Salt backend to connect to minions. Hosts can be selected using glob and compound matchers. ```bash $ py.test --hosts='salt://*' ``` ```bash $ py.test --hosts='salt://minion1,salt://minion2' ``` ```bash $ py.test --hosts='salt://web*' ``` ```bash $ py.test --hosts='salt://G@os:Debian' ``` -------------------------------- ### Execute commands with host.run Source: https://testinfra.readthedocs.io/en/latest/modules.html Run shell commands and inspect the resulting CommandResult object. ```python >>> cmd = host.run("ls -l /etc/passwd") >>> cmd.rc 0 >>> cmd.stdout '-rw-r--r-- 1 root root 1790 Feb 11 00:28 /etc/passwd\n' >>> cmd.stderr '' >>> cmd.succeeded True >>> cmd.failed False ``` -------------------------------- ### Run Salt module functions for multiple packages Source: https://testinfra.readthedocs.io/en/latest/modules.html Execute a Salt module function for a list of packages. The result is a dictionary mapping each package to its version. ```python >>> host.salt("pkg.version", ["nginx", "php5-fpm"]) {'nginx': '1.6.2-5', 'php5-fpm': '5.6.7+dfsg-1'} ``` -------------------------------- ### Resolve Symbolic Link Target Source: https://testinfra.readthedocs.io/en/latest/modules.html Get the target path of a symbolic link. This property resolves the symlink to its destination. ```python >>> host.file("/var/lock").linked_to '/run/lock' ``` -------------------------------- ### Integrate with Nagios Source: https://testinfra.readthedocs.io/en/latest/examples.html Use the --nagios flag to make test results compatible with Nagios monitoring plugins. ```bash $ py.test -qq --nagios --tb line test_ok.py; echo $? TESTINFRA OK - 2 passed, 0 failed, 0 skipped in 2.30 seconds .. 0 $ py.test -qq --nagios --tb line test_fail.py; echo $? TESTINFRA CRITICAL - 1 passed, 1 failed, 0 skipped in 2.24 seconds .F /usr/lib/python3/dist-packages/example/example.py:95: error: [Errno 111] error msg 2 ``` -------------------------------- ### Get outdated packages Source: https://testinfra.readthedocs.io/en/latest/modules.html Identify outdated packages and their current and latest versions with `pip.get_outdated_packages`. A custom pip path can be provided. ```python >>> host.pip.get_outdated_packages( ... pip_path='~/venv/website/bin/pip') {'Django': {'current': '1.10.2', 'latest': '1.10.3'}} ``` -------------------------------- ### Run Salt module functions for a single package Source: https://testinfra.readthedocs.io/en/latest/modules.html Execute a Salt module function, such as `pkg.version`, for a single package. The result is returned directly. ```python >>> host.salt("pkg.version", "nginx") '1.6.2-5' ``` -------------------------------- ### Podman backend for container testing Source: https://testinfra.readthedocs.io/en/latest/backends.html Use the Podman backend to test running Podman containers via the `podman exec` command. Specify the container ID or name. ```bash $ py.test --hosts='podman://[user@]container_id_or_name' ``` -------------------------------- ### Test Docker images Source: https://testinfra.readthedocs.io/en/latest/examples.html Overload the host fixture to build and run Docker containers for infrastructure testing. ```python import pytest import subprocess import testinfra # scope='session' uses the same container for all the tests; # scope='function' uses a new container per test function. @pytest.fixture(scope='session') def host(request): # build local ./Dockerfile subprocess.check_call(['docker', 'build', '-t', 'myimage', '.']) # run a container docker_id = subprocess.check_output( ['docker', 'run', '-d', 'myimage']).decode().strip() # return a testinfra connection to the container yield testinfra.get_host("docker://" + docker_id) # at the end of the test suite, destroy the container subprocess.check_call(['docker', 'rm', '-f', docker_id]) def test_myimage(host): # 'host' now binds to the container assert host.check_output('myapp -v') == 'Myapp 1.0' ``` -------------------------------- ### Get Supervisor Service Status and PID Source: https://testinfra.readthedocs.io/en/latest/modules.html Provides properties for Supervisor-managed services, including their running status and process ID (PID). ```python >>> gunicorn = host.supervisor("gunicorn") >>> gunicorn.status 'RUNNING' >>> gunicorn.is_running True >>> gunicorn.pid 4242 ``` -------------------------------- ### Get Systemd Service Properties Source: https://testinfra.readthedocs.io/en/latest/modules.html Retrieves properties of a systemd service. This method is specific to the systemd implementation and will raise NotImplementedError on other systems. ```python >>> ntp = host.service("ntp") >>> ntp.systemd_properties["FragmentPath"] '/lib/systemd/system/ntp.service' ``` -------------------------------- ### Ansible backend with inventory specification Source: https://testinfra.readthedocs.io/en/latest/backends.html Specify an Ansible inventory file using the `--ansible-inventory` option. Otherwise, the default `/etc/ansible/hosts` is used. ```bash $ py.test --ansible-inventory=/path/to/inventory --hosts='ansible://all' ``` -------------------------------- ### Run commands with sudo Source: https://testinfra.readthedocs.io/en/latest/backends.html For all backends, commands can be run as superuser with the `--sudo` option or as a specific user with the `--sudo-user` option. ```bash $ py.test --sudo test_myinfra.py ``` -------------------------------- ### Ansible backend host selection Source: https://testinfra.readthedocs.io/en/latest/backends.html Use the Ansible backend with Ansible inventories to describe hosts. Prefix the `--hosts` option with `ansible://`. ```bash $ py.test --hosts='ansible://all' # tests all inventory hosts ``` ```bash $ py.test --hosts='ansible://host1,ansible://host2' ``` ```bash $ py.test --hosts='ansible://web*' ``` -------------------------------- ### Get Network Interface Routes Source: https://testinfra.readthedocs.io/en/latest/modules.html Retrieve routing table entries associated with a network interface. This helps in verifying network routing configurations. ```python >>> host.interface("eth0").routes() [{'dst': 'default', 'flags': [], 'gateway': '192.0.2.1', 'metric': 3003, 'prefsrc': '192.0.2.5', 'protocol': 'dhcp'}, {'dst': '192.0.2.0/24', 'flags': [], 'metric': 3003, 'prefsrc': '192.0.2.5', 'protocol': 'dhcp', 'scope': 'link'}] ``` -------------------------------- ### Execute Commands with Sudo Source: https://testinfra.readthedocs.io/en/latest/modules.html Allows executing commands as another user, supporting nested sudo contexts. Demonstrates switching between the current user, root, and a specified user. ```python >>> Command.check_output("whoami") 'phil' >>> with host.sudo(): ... host.check_output("whoami") ... with host.sudo("www-data"): ... host.check_output("whoami") ... 'root' 'www-data' ``` -------------------------------- ### SSH backend with custom config and identity file Source: https://testinfra.readthedocs.io/en/latest/backends.html Configure the SSH backend with a custom SSH configuration file or specify an identity file for authentication. ```bash $ py.test --ssh-config=/path/to/ssh_config --hosts='ssh://server' ``` ```bash $ py.test --ssh-identity-file=/path/to/key --hosts='ssh://server' ``` -------------------------------- ### Service Module Source: https://testinfra.readthedocs.io/en/latest/modules.html Provides methods to test the state and properties of system services. ```APIDOC ## Service Module ### Description Test system services across different platforms (Linux, FreeBSD, OpenBSD, NetBSD). ### Properties - **exists** (bool) - Test if service exists - **is_running** (bool) - Test if service is running - **is_enabled** (bool) - Test if service is enabled - **is_valid** (bool) - Test if service is valid (systemd only) - **is_masked** (bool) - Test if service is masked (systemd only) - **systemd_properties** (dict) - Return service properties (systemd only) ``` -------------------------------- ### Kubectl backend with specific container and namespace Source: https://testinfra.readthedocs.io/en/latest/backends.html Specify the container name and namespace when using the Kubectl backend to connect to a pod. ```bash # specify container name and namespace $ py.test --hosts='kubectl://somepod-2536ab?container=nginx&namespace=web' ``` -------------------------------- ### Docker backend for container testing Source: https://testinfra.readthedocs.io/en/latest/backends.html Use the Docker backend to test running Docker containers via the `docker exec` command. Specify the container ID or name. ```bash $ py.test --hosts='docker://[user@]container_id_or_name' ``` -------------------------------- ### SSH backend basic usage Source: https://testinfra.readthedocs.io/en/latest/backends.html Connect to a server using the pure SSH backend. Default timeout is 10 seconds and ControlPersist is 60 seconds. ```bash $ py.test --hosts='ssh://server' ``` -------------------------------- ### Get Default Network Interface (IPv4) Source: https://testinfra.readthedocs.io/en/latest/modules.html Identify the network interface used for the default IPv4 route. Essential for verifying outbound network connectivity. ```python >>> host.interface.default() ``` -------------------------------- ### Get File Modification Time Source: https://testinfra.readthedocs.io/en/latest/modules.html Retrieve the last modification time of a file as a datetime object. This property provides the timestamp of the last change to the file. ```python >>> host.file("/etc/passwd").mtime datetime.datetime(2015, 3, 15, 20, 25, 40) ``` -------------------------------- ### Host Object Methods Source: https://testinfra.readthedocs.io/en/latest/modules.html The host object provides various methods to interact with the target system. ```APIDOC ## Host Object Methods ### Description The host object provides various methods to interact with the target system, such as running commands, checking for command existence, and retrieving command output. ### Methods #### `run(command: str, *args: str, **kwargs: Any) -> CommandResult` ##### Description Run given command and return rc (exit status), stdout and stderr. ##### Parameters - **command** (str) - The command to run. - **args** (str) - Additional arguments for the command. - **kwargs** (Any) - Additional keyword arguments. ##### Request Example ```python cmd = host.run("ls -l /etc/passwd") print(cmd.rc) print(cmd.stdout) print(cmd.stderr) print(cmd.succeeded) print(cmd.failed) ``` ##### Response Example ```json { "rc": 0, "stdout": "-rw-r--r-- 1 root root 1790 Feb 11 00:28 /etc/passwd\n", "stderr": "", "succeeded": true, "failed": false } ``` #### `run_expect(expected: list[int], command: str, *args: str, **kwargs: Any) -> CommandResult` ##### Description Run command and check it return an expected exit status. ##### Parameters - **expected** (list[int]) - A list of expected exit status. - **command** (str) - The command to run. - **args** (str) - Additional arguments for the command. - **kwargs** (Any) - Additional keyword arguments. ##### Raises - AssertionError #### `run_test(command: str, *args: str, **kwargs: Any) -> CommandResult` ##### Description Run command and check it return an exit status of 0 or 1. ##### Parameters - **command** (str) - The command to run. - **args** (str) - Additional arguments for the command. - **kwargs** (Any) - Additional keyword arguments. ##### Raises - AssertionError #### `check_output(command: str, *args: str, **kwargs: Any) -> str` ##### Description Get stdout of a command which has run successfully. ##### Parameters - **command** (str) - The command to run. - **args** (str) - Additional arguments for the command. - **kwargs** (Any) - Additional keyword arguments. ##### Returns - stdout without trailing newline. ##### Raises - AssertionError #### `exists(command: str) -> bool` ##### Description Return True if given command exist in $PATH. ##### Parameters - **command** (str) - The command to check for existence. #### `find_command(command: str, extrapaths: Iterable[str] = ('/sbin', '/usr/sbin')) -> str` ##### Description Return path of given command. ##### Parameters - **command** (str) - The command to find. - **extrapaths** (Iterable[str]) - Additional paths to search in. Defaults to ('/sbin', '/usr/sbin'). ##### Raises - ValueError - if command cannot be found. #### `has_command_v() -> bool` ##### Description Return True if command -v is available. ### Security Note Good practice: always use shell arguments quoting to avoid shell injection. ### Shell Injection Example ```python # Example demonstrating potential shell injection and how to avoid it cmd = host.run("ls -l -- %s", "/;echo inject") # This command will likely fail safely due to quoting or the shell interpreting the injection attempt. ``` ``` -------------------------------- ### Integrate with Jenkins Source: https://testinfra.readthedocs.io/en/latest/examples.html Configure build scripts for Jenkins to run Testinfra tests on a Vagrant-managed environment. ```bash pip install pytest-testinfra paramiko vagrant up vagrant ssh-config > .vagrant/ssh-config py.test --hosts=default --ssh-config=.vagrant/ssh-config --junit-xml junit.xml tests.py ``` -------------------------------- ### Connection API - Compare Files Across Hosts Source: https://testinfra.readthedocs.io/en/latest/api.html Illustrates comparing file content on two different servers using testinfra's Connection API within a pytest function. ```APIDOC ## GET /api/hosts/files/compare ### Description Compare the content of a file across two different hosts. ### Method GET (conceptual, as this is a library function) ### Endpoint N/A (Library function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python import testinfra def test_same_passwd(): a = testinfra.get_host("ssh://a") b = testinfra.get_host("ssh://b") assert a.file("/etc/passwd").content == b.file("/etc/passwd").content ``` ### Response #### Success Response (200) - **assertion** (boolean) - True if the file contents are identical, False otherwise. #### Response Example ```python # The assertion itself is the result assert True ``` ``` -------------------------------- ### List Podman containers with filters Source: https://testinfra.readthedocs.io/en/latest/modules.html Retrieve a list of Podman containers, with options to filter by status, name, or other criteria defined in `podman-ps(1)`. Multiple filters can be applied. ```python [, , ] # Get all running containers >>> host.podman.get_containers(status="running") [] # Get containers named "nginx" >>> host.podman.get_containers(name="nginx") [] # Get containers named "nginx" or "redis" >>> host.podman.get_containers(name=["nginx", "redis"]) [, ] ``` -------------------------------- ### Retrieve system information Source: https://testinfra.readthedocs.io/en/latest/modules.html Access various system properties through the system_info object. ```python >>> host.system_info.type 'linux' ``` ```python >>> host.system_info.distribution 'debian' ``` ```python >>> host.system_info.release '10.2' ``` ```python >>> host.system_info.codename 'bullseye' ``` ```python >>> host.system_info.arch 'x86_64' ``` -------------------------------- ### Run Testinfra Tests Source: https://testinfra.readthedocs.io/en/latest/index.html Execute Testinfra tests using the py.test command with the -v flag for verbose output. ```bash $ py.test -v test_myinfra.py ``` -------------------------------- ### Host Modules Source: https://testinfra.readthedocs.io/en/latest/modules.html Testinfra provides various modules to interact with specific system components. ```APIDOC ## Host Modules ### Description Testinfra modules are provided through the host fixture. Declare it as an argument of your test function to make it available within it. The following modules are available: - **ansible**: `testinfra.modules.ansible.Ansible` class - **addr**: `testinfra.modules.addr.Addr` class - **blockdevice**: `testinfra.modules.blockdevice.BlockDevice` class - **docker**: `testinfra.modules.docker.Docker` class - **environment**: `testinfra.modules.environment.Environment` class - **file**: `testinfra.modules.file.File` class - **group**: `testinfra.modules.group.Group` class - **interface**: `testinfra.modules.interface.Interface` class - **iptables**: `testinfra.modules.iptables.Iptables` class - **mount_point**: `testinfra.modules.mountpoint.MountPoint` class - **package**: `testinfra.modules.package.Package` class - **pip**: `testinfra.modules.pip.Pip` class - **podman**: `testinfra.modules.podman.Podman` class - **process**: `testinfra.modules.process.Process` class - **puppet_resource**: `testinfra.modules.puppet.PuppetResource` class - **facter**: `testinfra.modules.puppet.Facter` class - **salt**: `testinfra.modules.salt.Salt` class - **service**: `testinfra.modules.service.Service` class - **socket**: `testinfra.modules.socket.Socket` class - **sudo**: `testinfra.modules.sudo.Sudo` class - **supervisor**: `testinfra.modules.supervisor.Supervisor` class - **sysctl**: `testinfra.modules.sysctl.Sysctl` class - **system_info**: `testinfra.modules.systeminfo.SystemInfo` class - **user**: `testinfra.modules.user.User` class ``` -------------------------------- ### BlockDevice Module Source: https://testinfra.readthedocs.io/en/latest/modules.html Provides information about block devices, including their size, partition status, and writability. ```APIDOC ## BlockDevice Module ### Description Provides information for block devices. Should be used with sudo or under root. If the device is not a block device, a `RuntimeError` is raised. ### Method `host.block_device(name)` ### Parameters #### Path Parameters - **name** (str) - Required - The name of the block device (e.g., `/dev/sda1`). ### Properties - **is_partition** (bool) - Returns `True` if the device is a partition. - **size** (int) - Returns the size of the device in bytes. - **sector_size** (int) - Returns the sector size for the device in bytes. - **block_size** (int) - Returns the block size for the device in bytes. - **start_sector** (int) - Returns the start sector of the device on the underlying device. - **is_writable** (bool) - Returns `True` if the device is writable (has no RO status). - **ra** (int) - Returns the Read Ahead value for the device in 512-bytes sectors. ### Request Example ```python print(host.block_device("/dev/sda1").is_partition) print(host.block_device("/dev/sda").is_partition) print(host.block_device("/dev/sda1").size) print(host.block_device("/dev/sda1").sector_size) print(host.block_device("/dev/sda").block_size) print(host.block_device("/dev/sda1").start_sector) print(host.block_device("/dev/md0").start_sector) print(host.block_device("/dev/sda").is_writable) print(host.block_device("/dev/loop1").is_writable) print(host.block_device("/dev/sda").ra) ``` ``` -------------------------------- ### Run Salt module functions for multiple grains Source: https://testinfra.readthedocs.io/en/latest/modules.html Retrieve multiple Salt grains items by providing a list of grain names to the `salt` function. The result is a dictionary of the requested grains. ```python >>> host.salt("grains.item", ["osarch", "mem_total", "num_cpus"]) {'osarch': 'amd64', 'num_cpus': 4, 'mem_total': 15520} ``` -------------------------------- ### Get Host Instance Dynamically Source: https://testinfra.readthedocs.io/en/latest/api.html Use testinfra.get_host to obtain a host instance outside of pytest. Specify connection details like protocol, user, host, and port. Supports sudo operations. ```python >>> import testinfra >>> host = testinfra.get_host("paramiko://root@server:2222", sudo=True) >>> host.file("/etc/shadow").mode == 0o640 True ``` -------------------------------- ### Salt API Source: https://testinfra.readthedocs.io/en/latest/modules.html API to execute Salt module functions. ```APIDOC ## Salt API ### Description Executes Salt module functions on the system. ### Method #### `salt(function, args=None, local=False, config=None)` - **Description**: Run a Salt module function. - **Parameters**: - `function` (str) - The Salt module function to execute (e.g., 'pkg.version', 'grains.item'). - `args` (list or str) - Optional - Arguments for the Salt function. - `local` (bool) - Optional - Whether to run locally. - `config` (dict) - Optional - Salt configuration. - **Example**: ```python # Get version of nginx package host.salt("pkg.version", "nginx") # Get versions of multiple packages host.salt("pkg.version", ["nginx", "php5-fpm"]) # Get specific grains items host.salt("grains.item", ["osarch", "mem_total", "num_cpus"]) ``` - **Note**: Run `salt-call sys.doc` to get a complete list of available functions. ``` -------------------------------- ### Configure Testinfra Hosts in Module Source: https://testinfra.readthedocs.io/en/latest/invocation.html Define the hosts to be tested directly within the test module using the `testinfra_hosts` variable. ```python testinfra_hosts = ["localhost", "root@webserver:2222"] def test_foo(host): [....] ``` -------------------------------- ### SystemInfo - Return system information Source: https://testinfra.readthedocs.io/en/latest/modules.html The SystemInfo class provides information about the operating system and architecture. ```APIDOC ## SystemInfo ### Description Return system information. ### Method GET (Implicit) ### Endpoint N/A (Class method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python host.system_info.type host.system_info.distribution host.system_info.release host.system_info.codename host.system_info.arch ``` ### Response #### Success Response (200) - **type** (string) - OS type. - **distribution** (string) - Distribution name. - **release** (string) - Distribution release number. - **codename** (string) - Release code name. - **arch** (string) - Host architecture. #### Response Example ```json { "type": "linux", "distribution": "debian", "release": "10.2", "codename": "bullseye", "arch": "x86_64" } ``` ``` -------------------------------- ### Socket Module Source: https://testinfra.readthedocs.io/en/latest/modules.html Provides methods to test listening TCP, UDP, and Unix sockets. ```APIDOC ## Socket Module ### Description Test listening tcp/udp and unix sockets. Requires netstat command. ### Properties - **is_listening** (bool) - Test if socket is listening - **clients** (List[Tuple[str, int] | None]) - Return list of clients connected to a listening socket ### Methods - **get_listening_sockets()** - Return a list of all listening sockets ``` -------------------------------- ### Ansible backend force execution Source: https://testinfra.readthedocs.io/en/latest/backends.html Force Testinfra to run all commands via Ansible itself, which is slower than other backends. This is useful when `ansible_connection` is not one of the supported values. ```bash $ py.test --force-ansible --hosts='ansible://all' ``` ```bash $ py.test --hosts='ansible://host?force_ansible=True' ``` -------------------------------- ### Check File Existence Source: https://testinfra.readthedocs.io/en/latest/modules.html Verify if a file exists at the specified path. Returns True if the file exists, False otherwise. ```python >>> host.file("/etc/passwd").exists True >>> host.file("/nonexistent").exists False ``` -------------------------------- ### Access Environment Variables Source: https://testinfra.readthedocs.io/en/latest/modules.html Retrieve environment variables from the system. The output is a dictionary of key-value pairs. ```python >>> host.environment() { "EDITOR": "vim", "SHELL": "/bin/bash", [...] } ``` -------------------------------- ### List Docker Containers with Filters Source: https://testinfra.readthedocs.io/en/latest/modules.html Retrieve a list of Docker containers. Supports filtering by status, name, and other criteria. Multiple filters for a given key can be provided as a list. ```python >>> host.docker.get_containers() [, , ] # Get all running containers >>> host.docker.get_containers(status="running") [] # Get containers named "nginx" >>> host.docker.get_containers(name="nginx") [] # Get containers named "nginx" or "redis" >>> host.docker.get_containers(name=["nginx", "redis"]) [, ] ```