Description
Package standard-test-roles
provides shared Ansible roles and inventory scripts implementing the Standard Test Interface. It has support for multiple testing frameworks (such as BeakerLib or Avocado) and in this way allows to easily enable existing tests in Fedora CI.
Setup
As the first step install all necessary packages:
sudo dnf install fedpkg libselinux-python standard-test-roles
You can also install the latest version from the copr repo:
dnf copr -y enable @osci/standard-test-roles dnf update standard-test-roles
Testing
Classic
You can always invoke the tests locally. Many tests modify or change the system they are run against, so take that into account when looking at how to invoke tests. The following examples invoke tests against the same system that the package git repository is checked out on. Below there are further options for invoking tests against another fully formed and integrated systems, such as an Atomic Host or container image test subject.
There may be more than one test present in a package git repository, but the file tests.yml
is the main entry point. To run it use the following command:
# ansible-playbook tests.yml
You can find output artifacts of the tests in an artifacts/
or specify a specific directory like this:
# ansible-playbook -e artifacts=/tmp/output tests.yml
You can filter which kinds of tests are run by providing a --tags
argument. To only run tests that are suited for classic systems installed by yum
or dnf
you can use a command like:
# ansible-playbook --tags=classic tests.yml
When run by a CI System the tests are invoked according to a specification. Look here for more details and standard invocation variables.
Package
When you run the tests as above, the tests assume that the system to be tested is the same as the system invoking the tests. In particular, the test assumes that the thing to be tested is already installed.
A test subject is what we call the thing to be tested. RPMs are a particular kind of test subject. To turn a test subject into a launched, installed system to be tested, we use Ansible dynamic inventory. Lets invoke the tests with an inventory and a specific version of gzip:
# export ANSIBLE_INVENTORY=$(test -e inventory && echo inventory || echo /usr/share/ansible/inventory) # curl -o gzip.rpm https://kojipkgs.fedoraproject.org//packages/gzip/1.8/2.fc26/x86_64/gzip-1.8-2.fc26.x86_64.rpm # export TEST_SUBJECTS=$PWD/gzip.rpm # ansible-playbook tests.yml
You'll notice that the RPM is installed into the testable system before invoking the tests. Some tests contain their own inventory, that is their own instructions for turning a test subject into one or more testable systems. But in this case we use the default standard-test-roles
inventory in /usr/share/ansible/inventory
to do this.
Container
Another example is to use a test subject of a container image. This is also a fully formed and integrated deliverable. The test subject again represents the thing to be tested. The container image is pulled from a registry and launched using docker by an Ansible dynamic inventory.
# export ANSIBLE_INVENTORY=$(test -e inventory && echo inventory || echo /usr/share/ansible/inventory) # export TEST_SUBJECTS=docker:docker.io/library/fedora:26 # ansible-playbook --tags=container tests.yml
If you watch closely you'll notice the image is pulled if not already local, launched as a container, and then prepared for the tests to run on. The first time this may take a little longer. Not all tests are able to function in the somewhat different environment of a container. In fact, for certain tests, the software to be tested may not be included in the container. But many of the tests for core packages should work here.
The --tags
argument filters out tests that are not suitable for running in a container, either because the system functions differently, or the correct packages are not installable.
To diagnose why the tests failed, and log into the running container, you can specify the following environment variable. After the playbook runs, you'll see diagnosis information with a helpful docker exec
command to log into the container:
# export TEST_DEBUG=1
To increase verbosity you can also use keys -v
or -vvv
for full debugging, for example:
# ansible-playbook --tags=container tests.yml -v
or for full verbosity:
# ansible-playbook --tags=container tests.yml -vvv
Additional arguments for Docker
Tests for containers are run with a help of Docker. Containers are run within default security context. For more info see Seccomp security profiles for Docker. It is possible that some tests require additional privileges. In this case specify necessary arguments for Docker using an environment variable TEST_DOCKER_EXTRA_ARGS. For this create a file inventory file in tests directory with the following content:
#!/bin/bash export TEST_DOCKER_EXTRA_ARGS="--security-opt seccomp:unconfined" exec merge-standard-inventory "$@"
or
#!/bin/bash export TEST_DOCKER_EXTRA_ARGS="--privileged" exec merge-standard-inventory "$@"
You can find nformation about merge-standard-inventory script you can find at: README file for standard-test-roles
Atomic
The former example may seem a bit contrived, but the concept of a test subject starts to make more sense when you want to test a fully formed and integrated deliverable, such as Atomic Host. The test subject again represents the thing to be tested. The test subject in this case is a QCow2 image. To turn a test subject into a launched system ready to be tested, we use Ansible dynamic inventory.
# export ANSIBLE_INVENTORY=$(test -e inventory && echo inventory || echo /usr/share/ansible/inventory) # curl -Lo fedora-atomic-host.qcow2 https://getfedora.org/atomic_qcow2_latest # export TEST_SUBJECTS=$PWD/fedora-atomic-host.qcow2 # ansible-playbook --tags=atomic tests.yml
If you watch closely you'll see that the Atomic Host image is booted, and the tests run against the launched image. Not all tests are able to function in the somewhat different environment of Atomic Host, in fact, for certain cases, the software to be tested may not be included in the Atomic Host test subject. But most of the tests in core packages should work here.
Some tests contain their own inventory, that is their own instructions for turning a test subject into one or more testable systems. But in this case we use the default standard-test-roles
inventory to do this.
The --tags
argument filters out tests that are not suitable for running on an Atomic Host, either because the system functions differently, or the correct packages are not available on that system.
To diagnose why the tests failed, and log into the running Atomic Host, you can specify the following environment variable. After the playbook runs, you'll see diagnosis information with a helpful ssh
command to log into the host:
# export TEST_DEBUG=1
To increase verbosity you can also use keys -v
or -vvv
for full debugging, for example:
# ansible-playbook --tags=atomic tests.yml -v
or for full verbosity:
# ansible-playbook --tags=atomic tests.yml -vvv
Debug
For debugging tests option TEST_DEBUG should be set to 1. To do that, execute command:
# export TEST_DEBUG=1
After that you can run tests i.e. execute command:
# ansible-playbook --tags=atomic tests.yml
You'll see output like this:
PLAY RECAP **************************************************************************************************************************************** /home/sturi/Programs/Images/atomic.qcow2 : ok=1 changed=0 unreachable=0 failed=1 (.ansible) [root@kh226 docker]# DIAGNOSE: ssh -p 2222 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@127.0.0.3 # password: foobar DIAGNOSE: kill 13376 # when finished
Look for DIAGNOSE there creds for the Virtual machine, IP address, username, password, and port. In our case:
- IP address: 127.0.0.3
- username/password: root/foobar
- SSH port: 2222
Now you can connect to the VM using those creds. Open a new terminal and execute:
# ssh root@127.0.0.3 -p 2222
The output:
[root@kh226 docker]# ssh root@127.0.0.3 -p 2222 Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '[127.0.0.3]:2222' (ECDSA) to the list of known hosts. root@127.0.0.3's password: [root@localhost ~]#
Roles
Here's the list of currently supported roles:
- avocado
- basic
- beakerlib
- repo
- rhts
- rpm
- scripts
- source
BeakerLib
If you have a set of beakerlib tests, it is recommended to place each test in its own subdirectory.
Then, create tests.yml
file with contents similar to the following which runs tests using the 'standard-test-beakerlib' role included in the standard-test-roles
package. The list provided for the 'tests' parameter should be the list of names of your per-test subdirectories, and the 'required_packages' parameter should contain a list of additional packages that need to be installed to run the tests.
--- - hosts: localhost tags: - atomic - classic - container roles: - role: standard-test-beakerlib tests: - cmd-line-options required_packages: - which # which package required for cmd-line-options - rpm-build # upstream-testsuite requires rpmbuild command - libtool # upstream-testsuite requires libtool - gettext # upstream-testsuite requires gettext
Note: The 'required_packages' parameter is ignored when running on Atomic Host--since there is no way to install additional packages in that environment.
RHTS
If you have a set of tests you want to run using restraint, each test must be placed in its own subdirectory.
Then, create tests.yml
file with contents similar to the following which runs tests using the 'standard-test-rhts' role included in the standard-test-roles
package. The list provided for the 'tests' parameter should be the list of names of your per-test subdirectories, and the 'required_packages' parameter should contain a list of additional packages that need to be installed to run the tests.
--- - hosts: localhost tags: - classic - docker roles: - role: standard-test-rhts tests: - cmd-line-options required_packages: - which # which package required for cmd-line-options - rpm-build # upstream-testsuite requires rpmbuild command - libtool # upstream-testsuite requires libtool - gettext # upstream-testsuite requires gettext
Note: Tests using the 'standard-test-rhts' role are not compatible with Atomic Host--since it requires the installation of additional packages and there is no way to do so in that environment. We reflect that by omitting atomic
from the <tags> section.
More
Learn more about the Standard Test Roles.
Links
Pagure and Copr repositories:
- https://pagure.io/standard-test-roles/
- https://copr.fedorainfracloud.org/coprs/g/osci/standard-test-roles/builds/
Contact
- Andrei Stepanov (astepano)