Martinpitt (talk | contribs) m (fix formatting) |
Martinpitt (talk | contribs) (use consistent terminology, define the terms) |
||
Line 18: | Line 18: | ||
* Email: martin@piware.de | * Email: martin@piware.de | ||
<!-- * Release notes owner: To be assigned by docs team [[User:FASAccountName| Release notes owner name]] <email address> --> | <!-- * Release notes owner: To be assigned by docs team [[User:FASAccountName| Release notes owner name]] <email address> --> | ||
== Terminology == | |||
* '''Test Subject''': The items that are to be tested. Typically this is a set of RPMs (updating a package to a new version), a container, or a distribution install ISO/VM image. | |||
* '''Test''': A callable/runnable piece of code and corresponding test data and mocks which exercises and evaluates a ''subject''. | |||
* '''Test Suite''': The collection of all tests that apply to a ''subject''. It's common to split the testing of different aspects into different tests for easier result evaluation, code maintenance, or parallelization. | |||
* '''Test Result''': A boolean output of a ''test'' which decides whether the test passed. This is being used for automatic result processing (gating in Continuous Integration). | |||
* '''Test Artifact''': Any additional output of the ''test'' such as the stdout/err output, log files, screen shots, core dumps, or TAP/Junit/subunit streams. These are mostly for human consumption (evaluating test failures by developers), but in case of machine readable files like JUnit they can also be used in result browsers for presenting test results. | |||
== Detailed Description == | == Detailed Description == | ||
Line 39: | Line 47: | ||
'''Goals:''' | '''Goals:''' | ||
* Implementation details of the integration | * Implementation details of the integration test suite or its framework should not leak into or rely on the CI system invoking the test. | ||
* CI system implementation details should not leak into the | * CI system implementation details should not leak into the test suite or its metadata. | ||
* It should be possible to change the CI system that runs a | * It should be possible to change the CI system that runs a test suite. | ||
* It should be possible for a dist-git packager to run a | * It should be possible for a dist-git packager to run a test suite locally. | ||
'''Requirements:''' | '''Requirements:''' | ||
* | * Declare and install test suite dependencies cleanly | ||
* Standard way to locally invoke a test | * Standard way to locally invoke a test process | ||
* Standard location to place | * Standard location to place test subject, results, and artifacts | ||
What follows is a standard way to discover, package and invoke integration | What follows is a standard way to discover, package and invoke integration | ||
Line 70: | Line 77: | ||
=== Invocation === | === Invocation === | ||
To invoke the | To invoke the test suite, the subpackage is installed. Each test of the suite | ||
installs an executable in the path <code>/usr/tests/</code>. | |||
To invoke the | To invoke the test suite, one would: | ||
# Place the | # Place the subject being tested in <code>/var/cache/tests/</code> | ||
# Execute all executable files in <code>/usr/tests/</code> one at a time. | # Execute all executable files in <code>/usr/tests/</code> one at a time. | ||
## The | ## The test is invoked with a working directory of <code>/</code> | ||
## The | ## The test is invoked as root, and may drop privileges as desired | ||
## Treat the stdout/stderr of each | ## Treat the stdout/stderr of each tests process as the test log (standard artifact) | ||
## Examine the exit code of each | ## Examine the exit code of each test process. Zero exit code is success, non-zero is failure. | ||
# Gather any additional | # Gather any additional artifacts like screenshots which tests place in a <code>/var/log/tests/</code> directory | ||
Multiple subpackages may be installed as long as their dependencies do not conflict. | Multiple subpackages may be installed as long as their dependencies do not conflict. | ||
Line 91: | Line 98: | ||
or subsystems like <code>libvirt</code>. | or subsystems like <code>libvirt</code>. | ||
Some integration tests may choose to test in-situ, on the system on which the | Some integration tests may choose to test in-situ, on the system on which the test suite | ||
is installed. In these cases the <code>%{name}-tests</code> subpackage should directly | is installed. In these cases the <code>%{name}-tests</code> subpackage should directly | ||
depend on the package being tested. | depend on the package being tested. | ||
Line 124: | Line 131: | ||
iterating on tests. | iterating on tests. | ||
By packaging, staging and invoking tests consistently in Fedora we | By packaging, staging and invoking tests consistently in Fedora we | ||
create an eco-system for the tests that allows varied | create an eco-system for the tests that allows varied test frameworks as | ||
well as CI system infrastructure to interoperate. The integration tests | well as CI system infrastructure to interoperate. The integration tests | ||
outlast the implementation details of either the frameworks they're written | outlast the implementation details of either the frameworks they're written |
Revision as of 08:25, 28 March 2017
Standard Dicsovery, Packaging, Invocation of Integration Tests
Summary
What follows is a standard way to discover, package and invoke integration tests for a package stored in a Fedora dist-git repo.
Owner
- Name: Stef Walter
- Email: stefw@fedoraproject.org
- Name: Martin Pitt
- Email: martin@piware.de
Terminology
- Test Subject: The items that are to be tested. Typically this is a set of RPMs (updating a package to a new version), a container, or a distribution install ISO/VM image.
- Test: A callable/runnable piece of code and corresponding test data and mocks which exercises and evaluates a subject.
- Test Suite: The collection of all tests that apply to a subject. It's common to split the testing of different aspects into different tests for easier result evaluation, code maintenance, or parallelization.
- Test Result: A boolean output of a test which decides whether the test passed. This is being used for automatic result processing (gating in Continuous Integration).
- Test Artifact: Any additional output of the test such as the stdout/err output, log files, screen shots, core dumps, or TAP/Junit/subunit streams. These are mostly for human consumption (evaluating test failures by developers), but in case of machine readable files like JUnit they can also be used in result browsers for presenting test results.
Detailed Description
Many Fedora packages have unit tests. These tests are typically run during a
%check
RPM build step. These tests run in the build root in which
the package is built and may involve the BuildRequire
dependencies.
On the other hand, integration testing happens against a composed system. Several upstream projects have integration tests, but these integration tests have typically not been used or packaged in Fedora. Both Fedora QA and the Atomic Host team would like to create more integration tests, stored in dist-git, and use a CI system to run them on Fedora packages.
What follows is a standard way to discover, package and invoke integration tests for a package stored in a Fedora dist-git repo.
It is important that the CI system which runs the test is independent from the layout of the test themselves.
Goals:
- Implementation details of the integration test suite or its framework should not leak into or rely on the CI system invoking the test.
- CI system implementation details should not leak into the test suite or its metadata.
- It should be possible to change the CI system that runs a test suite.
- It should be possible for a dist-git packager to run a test suite locally.
Requirements:
- Declare and install test suite dependencies cleanly
- Standard way to locally invoke a test process
- Standard location to place test subject, results, and artifacts
What follows is a standard way to discover, package and invoke integration tests for a package stored in a Fedora dist-git repo.
The integration tests are packaged and delivered through Fedora as
%{name}-tests
subpackages of the package they are associated with.
Packaging
Each dist-git repo that has integration tests should package those tests in a
%{name}-tests
subpackage. This is similar to the
%{name}-debuginfo
or %{name}-docs
subpackages we have
today.
The spec file for a dist-git repo may include upstream integration tests into
its %{name}-tests
subpackage. The spec file may also include tests
directly from files in tests/
subdirectory of the dist-git repo itself.
Invocation
To invoke the test suite, the subpackage is installed. Each test of the suite
installs an executable in the path /usr/tests/
.
To invoke the test suite, one would:
- Place the subject being tested in
/var/cache/tests/
- Execute all executable files in
/usr/tests/
one at a time.- The test is invoked with a working directory of
/
- The test is invoked as root, and may drop privileges as desired
- Treat the stdout/stderr of each tests process as the test log (standard artifact)
- Examine the exit code of each test process. Zero exit code is success, non-zero is failure.
- The test is invoked with a working directory of
- Gather any additional artifacts like screenshots which tests place in a
/var/log/tests/
directory
Multiple subpackages may be installed as long as their dependencies do not conflict.
Staging
The %{name}-test
subpackage should Requires:
all other packages
that the testsuite executable needs in order to run. This includes libraries or frameworks,
or subsystems like libvirt
.
Some integration tests may choose to test in-situ, on the system on which the test suite
is installed. In these cases the %{name}-tests
subpackage should directly
depend on the package being tested.
More rigourous integration tests test an integrated system from the outside. It is the
responsibility of the %{name}-tests
subpackages to provision virtual
machines or containers necessary to do such testing. In almost all cases this will happen
by way of a provisioning framework such as Avocado, Ansible, Module Testing Framework,
linch-pin, etc.
Discovery
A check
file in a dist-git repo should list the various names of
packages that should be installed in order to run the integration tests for that
package. If this file is empty then the list of packages will default to
%{name}-tests
.
The format of this file has not yet been defined, but a simple text file similar to sources listing package N[VR]'s may suffice.
Scope
This change requires no changes to Fedora infrastructure itself. It is limited to changes in dist-git repos. However certain key infrastructure changes could mitigate usability or side-effects of this change.
Benefit to Fedora
Developers benefit by having a consistent target for how to describe tests, while also being able to execute them locally while debugging issues or iterating on tests.
By packaging, staging and invoking tests consistently in Fedora we create an eco-system for the tests that allows varied test frameworks as well as CI system infrastructure to interoperate. The integration tests outlast the implementation details of either the frameworks they're written in or the CI systems running them.
User Experience
Users benefit by having tests that they can reproduce on their own systems.
They can install the similar to how they consume %{name}-doc
or %{name}-debuginfo
subpackages today.
We may choose to avoid having such packages available in the standard repositories.
We may choose to only have them in updates-testing
or an
arrangement similar to debuginfo
. These choices will require some
markup and/or change to infrastructure.
Upgrade/compatibility impact
Although there may already be subpackages that are named
%{name}-tests
this is merely a convention, and such packages will
not affect the behavior of this proposal.
Examples
TODO: Build out this section
Notes
- ...
- ...