#!/usr/bin/perl -T # Simple test for running debsums on a fake chroot use strict; use warnings; use Test::More; use Test::Command::Simple; my $chroot; my @command; # Untaint stuff delete $ENV{PATH}; # First check if we are testing a source package or an installed package. my $command = './debsums'; if (exists $ENV{AUTOPKGTEST_TMP} or exists $ENV{DEBIAN_AS_INSTALLED_TESTING}) { $command = '/usr/bin/debsums'; } ok(-e $command, "Command debsums found at $command"); ok(-x $command, "$command executable"); foreach my $state (qw(clean dirty)) { my $exit_code = $state eq 'clean' ? 0 : 2; $chroot = "t/fakechroots/$state"; @command = ($command, "--root=$chroot"); my $expected = <<"EOT"; $chroot/usr/share/doc/fakepkg/copyright OK $chroot/usr/share/doc/fakepkg/changelog.Debian.gz OK $chroot/usr/share/doc/fakepkg/README FAILED EOT $expected = remove_failed($expected) if $state eq 'clean'; my $expected_s = <<"EOT"; debsums: changed file $chroot/usr/share/doc/fakepkg/README (from fakepkg package) EOT $expected_s = remove_failed($expected_s) if $state eq 'clean'; my $expected_x = <<"EOT"; debsums: changed file $chroot/usr/share/doc/fakepkg/README (observed:1dd5525a854efa9dac37d84d0ef9bc9e expected:deadbeefcafebabedeadbeefcafebabe) (from fakepkg package) EOT $expected_x = remove_failed($expected_x) if $state eq 'clean'; my $expected_conffiles = <<"EOT"; $chroot/etc/fakepkg.cfg OK $chroot/etc/fakepkg-broken.cfg FAILED EOT $expected_conffiles = remove_failed($expected_conffiles) if $state eq 'clean'; # Test running with an unknown package run(@command, 'foobar'); is(stderr, "debsums: package foobar is not installed\n", 'Warning on STDERR'); is(stdout, '', 'STDOUT is empty'); expected_rc(1); # Test running with an unknown and a potentially dirty package run(@command, 'foobar', 'fakepkg'); expected_rc($exit_code | 1); foreach my $pkg ('', 'fakepkg') { @command = (@command, $pkg) if $pkg; # Test running without any further parameters run(@command); is(stderr, '', 'STDERR is empty'); is(stdout, $expected, 'STDOUT as expected'); expected_rc($exit_code); # Test option -c run(@command, '-c'); is(stderr, '', 'STDERR is empty'); is(stdout, $state eq 'clean' ? '' : failed_only($expected), 'STDOUT as expected'); expected_rc($exit_code); # Test option -s run(@command, '-s'); is(stderr, $state eq 'clean' ? '' : $expected_s, 'STDERR as expected'); is(stdout, '', 'STDOUT is empty'); expected_rc($exit_code); # Test option -x run(@command, '-x'); is(stderr, $state eq 'clean' ? '' : $expected_x, 'STDERR as expected'); is(stdout, '', 'STDOUT is empty'); expected_rc($exit_code); # Test option -e run(@command, '-e'); is(stderr, '', 'STDERR is empty'); is(sort_lines(stdout), sort_lines($expected_conffiles), 'STDOUT as expected'); expected_rc($exit_code); # Test option -a run(@command, '-a'); is(stderr, '', 'STDERR is empty'); is(sort_lines(stdout), sort_lines($expected.$expected_conffiles), 'STDOUT as expected'); expected_rc($exit_code); # Test option -ce and variants foreach my $option (qw(-ce -ec)) { run(@command, $option); is(stderr, '', 'STDERR is empty'); is(stdout, $state eq 'clean' ? '' : failed_only($expected_conffiles), 'STDOUT as expected'); expected_rc($exit_code); } } } ################################################ # Checks for handling of missing md5sums files # ################################################ # Expect a warning @command = ($command, "--root=t/fakechroots/lossy"); run(@command); is(stderr, "debsums: no md5sums for fakepkg\n", 'Warning on STDERR'); is(stdout, '', 'STDOUT is empty'); expected_rc(0); # Explicitly list packages run(@command, '-l'); is(stderr, '', 'STDERR is empty'); is(stdout, "fakepkg\n", 'Affected package listed'); expected_rc(0); ############################################## # Checks for handling of empty md5sums files # ############################################## # Expect a warning $chroot = "t/fakechroots/empty"; @command = ($command, "--root=$chroot"); run(@command); is(stderr, "$chroot/var/lib/dpkg/info/fakepkg.md5sums is empty but shouldn't!\n", 'Warning on STDERR'); is(stdout, '', 'STDOUT is empty'); expected_rc(2); ######################################## # Checks for handling of missing files # ######################################## # Expect a warning $chroot = "t/fakechroots/missing"; @command = ($command, "--root=$chroot"); foreach my $option (qw(-c -s)) { run(@command, $option); is(stderr, "debsums: missing file $chroot/usr/share/doc/fakepkg/copyright (from fakepkg package)\n", 'Warning on STDERR'); is(stdout, '', 'STDOUT is empty'); expected_rc(2); } ######################################## # Checks for handling of symlinks # ######################################## $chroot = "t/fakechroots/clean-with-link"; @command = ($command, "--root=$chroot"); foreach my $option (qw(-c -s)) { run(@command, $option); expected_rc(0); } ######################################## # Checks symlinks with loops # ######################################## # Expect a death $chroot = "t/fakechroots/link-with-loop"; @command = ($command, "--root=$chroot"); foreach my $option (qw(-c -s)) { run(@command, $option); is(stderr, "debsums: Error: symlink loop detected in path 'usr/share/doc/fakepkg/loop.1'. Please file a bug against fakepkg.\n", 'Warning on STDERR'); expected_rc(255); } ####################### ### All checks done ### ####################### done_testing(); ############################# ### Some helper functions ### ############################# sub sort_lines { my $string = shift; return join("\n", sort split("\n", $string)) . trailing_line_break_if_present($string); } sub remove_failed { my $string = shift; return join("\n", grep { !/FAILED|^debsums: changed file/ } split("\n", $string)) . trailing_line_break_if_present($string); } sub failed_only { my $string = shift; return join("\n", grep { /FAILED/ && s/\s*FAILED// } split("\n", $string)) . trailing_line_break_if_present($string); } sub expected_rc { my $exit_code = shift; is(rc >> 8, $exit_code, "Exit code is $exit_code"); } sub trailing_line_break_if_present { my $string = shift; if ($string =~ m/\n\z/) { return "\n"; } else { return ''; } }