=head1 NAME autopkgtest - Debian Perl Group autopkgtest implementation and team practices =head1 INTRODUCTION The C package, which provides as-installed testing of Debian packages, is integrated with pkg-perl packages as of version 3.5.1 (September 2014). The integration is intended to allow for continuous integration testing at L. This document describes the implementation and best practices for the team. =head1 IMPLEMENTATION Declaring Testsuite: autopkgtest-pkg-perl in the source package section of C will activate an implicit test control file that's currently embedded in the C package. This test control file has an indirection layer that pushes all the test logic into the C package, maintained inside the team. The entry point for the logic is the runner (L) script, which runs tests in C directories. Thanks to the uniformity of CPAN distributions, this implicit control file works with most (currently about 75%) of the pkg-perl packages. The rest will need package specific tweaks, as detailed below. An explicit test control file that corresponds to the implicit one described above is included in the C package in C and can be viewed at L. In case you want other tests, or need other dependencies or restrictions, you can add an explicit test control file and list them according the the spec manually. You can use the aforementioned C file as a starting point. The current tests activated by C are listed below. If some of them have expected failures, they can be skipped by listing the tests in C. The file can contain empty lines and comment lines starting with the C<#> sign. =head2 smoke Source: L This test re-uses the build time test suite present in most CPAN distributions to check that changes in the package's dependencies haven't introduced regressions in the package functionality. The package and its build dependencies are installed, the C directory and C files are copied into a temporary directory, and the build time test suite is run against the installed modules. The temporary directory is used to make sure that the installed modules get used instead of the source tree. If the test suite needs files outside the C directory, those can be listed in the C. Empty lines and #-style comment lines are supported. Note that this overrides the default list of C and C, so you normally need to include those too. Some common test files are removed from the temporary directory; they currently include C, C, C, C<04critic.t>, and C<97_meta.t>. If the file C exists, it is used as a list of files to be removed. Empty lines and #-style comments are supported. The environment variables C and C are set to 1 by default. These can be overridden and others can be added in the configuration file C. Empty lines and comments are allowed. The file syntax is one line per variable setting, in the form C; every such line is C'ed with a shell so you can compute C dynamically, for example: C. The tests are run with the C C<--merge> option, which merges and synchronizes stderr and stdout from the test scripts. In some rare cases this option can break the test suite. It can be disabled by unsetting C in C. For the benefit of tests looking for something in C or C, dummy module files are installed there and included in a dummy MANIFEST file. An empty MANIFEST.SKIP is also provided. If the file C exists and is executable, it will be executed right before running the tests, with the working directory set to the package source and C<$TDIR> set to the test running directory. The testing gets aborted if this program returns a nonzero value. Please use this facility responsibly and only as a last resort if the other hooks don't work for you. If the file C exists and is executable, it will be executed when the smoke tests exit, with the working directory set to the package source and C<$TDIR> set to the test running directory. The smoke test by default runs C with the C<--recurse> option on the F directory (prior to 0.37 only the F tests were run). In case a package should run other test scripts, C can be used to declare which files should be used instead. Example: F =head2 use.t Source: L This test ensures that the runtime dependencies are sufficient for the most basic usage of the module. Warnings from such basic usage are considered failures because they can be quite annoying on consumers of the module. The package and its runtime dependencies are installed, and the command C is executed, where C is the name of the main module in the package. If this exits with a nonzero status, or if there is output on stderr, the test is considered failed. The test is repeated with PERL_DL_NONLAZY=1 set in the environment; this makes sure there are no unresolved symbols in binary modules. The name of the module is read from C or C, but it can be overridden in C, which also allows listing multiple module names, one per line. The test is skipped if the name isn't present in one of the above sources. There are some rare cases where warnings are to be expected even from the most basic usage. Such expected warnings can be listed in C. Each line in this file is interpreted as a regular expression. =head2 syntax.t Source: L This test checks that the runtime dependencies and recommendations cover all the requirements of the modules shipped in the package, and that the modules are syntactically valid Perl. The test first installs the package and its runtime dependencies, including recommendations. All the C<.pm> files in the package are then run through a syntax check with C. If the command exits with a nonzero status, the test is considered failed. Standard error output is not treated as a failure. If there are other files that you'd like to check, you can specify those as regular expressions in C. Don't include the match delimiters (//). Empty lines and #-style comments are supported. If some of the module files have expected problems passing this test, they can be skipped by listing them in C. The lines are matched as fixed substrings (not regular expressions). Empty lines and #-style comments are supported. Packages that I other packages are exempt from this test, unless they include a (possibly empty) C file. This is because some of the module files are expected to need the suggested packages to work, but there is no mechanism to install them in the environment provided by C. To test all module files despite a I, an empty C (with optional comments) can be used since C version 0.45. =head1 ci.debian.net Even with the implicit test control file, all the packages would need source uploads to include the C header, which would take quite a while to happen for all the team packages (currently numbering almost 3000). To speed up adoption, the current plan is to make L use a whitelist of known good pkg-perl packages that it will treat as having the C header. This whitelist is maintained at L and is based on test runs of all our packages such as L. The whitelist is considered a temporary measure that can be dropped once we have C headers in all our packages. As of May 2015, there are 2029 whitelisted packages, 378 packages that declare C, and 604 non-whitelisted pkg-perl packages that currently don't pass the default checks and therefore need manual work. The list of packages needing manual work is available at L and current as of 20150524, but is not actively updated at the moment (volunteers welcome.) =head1 Team practices Once the set of known good packages has stabilized and is live on L, we should do a mass commit in our git repository adding C headers to the known good packages. A team specific lintian check (activated by C) triggers on the lack of the C header and points to this document. Coupled with the mass commit above, affected packages are expected to be those that need tweaking to get the tests working. Maintainers encountering the lintian warning are encouraged to fix those (other team members are happy to help with that!), but they are also naturally free to ignore the warning and postpone the addition of the header. When uploading a package with a C header, uploaders should adopt a habit of verifying that the tests pass so as not to cause unnecessary work to the L volunteers. Bugs related to autopkgtest failures should be filed with User: debian-perl@lists.debian.org Usertags: autopkgtest so that they show up on the tracking list at L See L for more information about usertags. =head1 SETUP To set up a C chroot for C (formerly known as C), follow the following steps. =head2 chroot type You need to setup a chroot type that supports ephemeral sessions for autopkgtest to run properly. It will fail otherwise. One option is to use B, so you need to create a logical volume and mount it first. For instance, assuming that C is empty and available to be used as a physical volume: sudo apt-get install lvm2 sudo pvcreate /dev/sdb1 sudo vgcreate sbuild /dev/sdb1 sudo lvcreate -L2G -n sid sbuild sudo mkfs.ext4 /dev/sbuild/sid sudo mkdir -p /srv/sbuild/sid sudo mount /dev/sbuild/sid /srv/sbuild/sid A simpler alternative would be to use B type, which doesn't need any previous setup before it is created, just a regular directory (ephemeral sessions will be setup through union filesystem). =head2 sbuild Note that C uses C underneath to manage the chroots. =over =item * Create a new chroot Note that installing recommends is needed so all the autopkgtest tools are available later. Especially a missing B package will lead to grief and sorrow. sudo apt-get install --install-recommends sbuild autopkgtest sudo sbuild-createchroot sid /srv/sbuild/sid http://deb.debian.org/debian At this point you can run C if you used LVM. =item * Grant permission to use the chroot sudo adduser {username} sbuild =item * Setup directory chroot First, you should rename the file created automatically on the previous step (it's not mandatory but useful): sudo mv /etc/schroot/chroot.d/sid-amd64-sbuild-* /etc/schroot/chroot.d/sid-amd64-sbuild.conf Then, you have to setup the chroot properties for the B type to make sure ephemeral sessions can be created: sudo sed -i -e 's,^union-type=none,union-type=aufs,' /etc/schroot/chroot.d/sid-amd64-sbuild.conf Or B type replacing the contents with these: [sid-amd64-sbuild] type=lvm-snapshot lvm-snapshot-options=--size 2G device=/dev/sbuild/sid groups=root,sbuild root-groups=root,sbuild profile=sbuild description=Debian sid/amd64 autobuilder =item * Update chroot source Use this command to B the package list, perform a B, and B obsolete packages in the chroot. sudo sbuild-update -udr sid-amd64-sbuild =item * Modify chroot source In case you need to make other kind of changes to the chroot. sudo schroot -c source:sid-amd64-sbuild =item * Instantiate chroot Play with an ephemeral chroot based on the source chroot setup before (you do not need to be root at this point). Please, be warned that this chroot instance will be automatically removed when you exit the shell. schroot -c sid-amd64-sbuild =item * Additional mounts Sometimes you need to mount other filesystem or directories in the chroot (e.g. C). If you miss anything, you can add that directory in the file C, where B is the profile for the chroots created by sbuild. You can find several examples in the B and B profiles. =back See Enrico Zini's blog entry at L and/or C for details. =head2 eatmydata You can use C do improve the speed of your builds inside the chroot pretty easily. =over =item * Make sure C is installed in the chroot You can either install it manually in the source chroot or add C<--include=eatmydata> option before running C above. =item * Enable C in the chroot configuration Add C to C. =back See L for more details. =head2 Examples =over =item An example package using C: C L =item An example package using C: C L =item An example package using C: C L =item An example package that uses C: C L =item An example package using C: C L =item An example package using C: C L =item An example package disabling C in C: C L =item An example package using C: C L =item An example package using C: C L =back =head2 Usage =over =item Running C against a package in the archive, assuming your schroot name is C: autopkgtest libfoo-bar-perl -- schroot sid-amd64-sbuild # since autopkgtest 4.0 adt-run libfoo-bar-perl --- schroot sid-amd64-sbuild (Make sure that I has a C entry in C and that you have run C there at least once before trying this example.) =item Running C on a C<.changes> file: autopkgtest libfoo-bar-perl_0.01_amd64.changes -- schroot sid-amd64-sbuild # since autopkgtest 4.0 adt-run libfoo-bar-perl_0.01_amd64.changes --- schroot sid-amd64-sbuild =item Running C with the control information in the current directory but the actual package from the archive: autopkgtest -B . -- schroot sid-amd64-sbuild # since autopkgtest 4.0 adt-run -B .// --- schroot sid-amd64-sbuild (The source tree doesn't need to be built, the binary package is installed from the archive with apt.) See C for more information. =back =head1 AUTHORS =over =item * Niko Tyni =item * Alex Muntada =item * gregor herrmann =item * intrigeri =back =head1 LICENSE Copyright (c) 2014-2022 by the individual authors and contributors noted above. All rights reserved. This document is free software; you may redistribute it and/or modify it under the same terms as Perl itself Perl is distributed under your choice of the GNU General Public License or the Artistic License. On Debian GNU/Linux systems, the complete text of the GNU General Public License can be found in `/usr/share/common-licenses/GPL' and the Artistic License in `/usr/share/common-licenses/Artistic'.