I want to revisit our nightly testing and elevate how we end-to-end test and thereby verify the code that is landing within the ecosystem. This starts with how we think about and design our nightly testing and releases. And transitions to where do we want to go as a community, what do we want that process to look like and what other testing scenarios do we want to enable to reduce churn and provide more value.
This is a bit long as I wanted to cover how nightly pipelines are designed as of today. The goals they aim to meet and where I think we want to go based on conversations I’ve had with developers and users.
Nightly Testing Today
This first section covers background on the state of nightly testing and releasing today to inform the conversation of where we want to go and how we are going to get there.
Types of Builds
There are generally speaking three types of builds that flow through our nightly pipelines:
Continuously built packages: packages that are rebuilt on nearly every code change committed to the mainline development branch (e.g. foreman, katello, foreman-installer)
Dependencies: packages that Foreman, Proxy, Installer, Selinux, Katello or Plugins require to build or run
Plugins: packages that require Foreman or Foreman proxy and add functionality to either one
Types of Releases
Continuously Built Packages
Continuously built packages are built on nearly every commit to their respective source repositories. When a PR is merged, a job kicks off to run a series of unit and integration tests to produce a verified source for the project (e.g. a foreman tarball or katello rubygem). The source job kicks off a packaging build job that uses the verified source as input to generate a package into the respective build systems.
Dependencies
Dependencies have PRs created against foreman-packaging and run a series of tests:
- Did the PR properly bump the version or release
- Does the package build
- Are all dependencies of the package satisfied by the update
When the packaging update is merged, the dependency is built into appropriate build system(s) (i.e. RPM, Deb).
Plugins
Plugins have PRs created against foreman-packaging and run a series of tests:
- Did the PR properly bump the version or release
- Does the package build
- Are all dependencies of the package satisfied by the update
When the packaging update is merged, the plugin is built into appropriate build system(s) (i.e. RPM, Deb).
Release Pipelines
Foreman, Proxy, Installer and SELinux
At least once a day, the Foreman nightly pipeline kicks off generating an RPM and Debian staging repository with any of the continuously built packages and dependencies that have recently been built. The repository is then verified by:
- Installing the base Foreman scenario for each supported OS
- Running smoke tests
- Installing N-2 Foreman and successively upgrading to staging
- Running smoke tests against final upgrade
Katello
At least once a day or when a Foreman nightly pipeline completes, the Katello nightly pipeline kicks off generating an RPM staging repository with a new rubygem-katello and dependencies that have recently been built. The repository is then verified by:
- Installing the base Katello scenario (which includes an external proxy) for each supported OS
- Running smoke tests
- Installing N-2 Katello and successively upgrading to staging
- Running smoke tests against final upgrade
Plugins
At least once a day, the Foreman Plugins nightly pipeline kicks off generating an RPM and Debian staging repository with any newly built plugins or their dependencies. A test is ran that verifies all dependencies for all packages are met and then the staging repositories are pushed out to the nightly release repositories.
Nightly Releases (Where we want to go)
There are some issues we commonly see with the current approach:
- Foreman can push a new version of foreman, installer or proxy that breaks plugins or Katello
- Changes can build up in staging repository leading to compound failures that amplify debug
- Nightly pipelines are currently built to be continuous integration testing environments; some bugs are identified only in this environment and can take days or weeks to resolve given they are emergent
- Consumers of nightly plugins or Katello can be blocked for days or weeks if a change to Foreman propagates before the updated plugins or Katello make it into the repositories
Continuous Nightly Releases
Consistent, green nightly releases provides a basis for developers and some classes of users to test functionality, use new features and preview how the next Foreman release will look. There is a growing base of users wanting continuous stable nightlies. I believe this requires us to shift nightlies away from being the output of a continuous integration test to be treated instead more as a release that is continuous.
A change to help achieve this is to move the point at which continuously built packages are end-to-end tested to ensure that changes they introduce are tested prior to landing in the final release test bucket. The process would look like:
PR merged -> Test Source -> Build Source -> Build scratch package -> Run end-to-end test -> Build package into build system
Nightly releases would still contain a final end-to-end test of the staging repository but continuously built packages would only arrive after having been vetted previously.
Added Benefits
Building out this workflow would enable plugins that desire to, to have continuous built packages that are vetted against an end-to-end workflow targeted at their use case.
This change can also propagate to versioned releases of Foreman allowing the source code releases to be vetted before committing to a version bump or package build.
Katello and Foreman
Foreman and Katello have always had a special relationship as Katello is the largest plugin in the ecosystem and the only one to contain it’s own scenario in the installer. There are myriad architectural changes needed to align the two as discussed in another thread. From a testing stand point, the two butt heads more than other plugins due in part to how connected they are from a release stand point.
- Katello has a tightly coupled relationship to Foreman code wise
- Katello’s installation scenario is tied to releases of foreman-installer
- Katello and Foreman have divergent levels of testing
- Katello pipelines test external proxies
- Foreman just recently gained upgrade testing
Like other plugins, Foreman’s pipeline is gated only on Foreman itself and therefore can push a new nightly release that breaks both the nightly release of Katello and the nightly Katello release pipeline. This can often result in a compounding effect for Katello developers as they try to deal with both.
Further, the recent survey results show a growing trend of users who are deploying Foreman with Katello in their environments.
Without gating the two on each other, which has been long undesired approach, what changes can we make to ensure the two do not result in broken releases or have a reduced downtime between breakages?
What about End to End PR Tests
Our end-to-end tests are resource and time intensive and prevent us from running that level of tests at scale on PRs. For some projects, the amount of churn and benefit of testing on PRs would be a worthwhile trade off (i.e. foreman-installer). This even is not full proof as, for example, puppet module changes do not flow through installer PRs and therefore need that CI based end-to-end test.