set -e
-mirror=http://mirror.relativity.greenend.org.uk/mirror/ubuntu.good
-distro=feisty
-suite=main
salt=''
tmp=tmp
var=var
-administrator_email=ian@davenant.greenend.org.uk
-maintainer_email_override="$administrator_email"
-salutation="Ian"
-from="$salutation Jackson <ian@davenant.greenend.org.uk>"
rsync=rsync
+disable=true
+interactive=true
+target=source
+suppressrepeatedemails=false
+arch=`dpkg --print-architecture`
+logheadmaxbytes=32768
+logtailmaxbytes=32768
+
+for config in "$@"; do
+ case "$config" in
+ *=*) eval "$config" ;;
+ *) . "$config" ;;
+ esac
+done
+
+if $disable; then
+ echo >&2 'disabled because config inadequate (no disable=false)'
+ exit 1
+fi
+
+: ${destdirtail:=$distro-$target}
+: ${destdirfin:="$destdircommon$destdirtail"}
+
+case $target in
+source)
+ sources=Sources
+ descx=''
+ ;;
+binary-*)
+ sources=Packages
+ descx="${target#binary-}"
+ ;;
+*)
+ echo >&2 'target must be source or binary-*'
+ exit 1
+esac
-destdirtail=autopkgtest-output/$distro
-destrsynchead=ijackson@chiark:public-html/
-desthttphead=http://www.chiark.greenend.org.uk/~ijackson/
+exec 3>&1
+printf >&3 "starting "
rm -rf "$tmp"
mkdir "$tmp"
-exec >"$tmp"/log
+>"$tmp"/_log_raw
+
+if $interactive; then
+ echo '(log diverted to stdout)' >>"$tmp"/_log_raw
+else
+ exec >>"$tmp"/_log_raw
+fi
+exec 4>&1
progress () {
echo "++++++ $1 ++++++"
gurl () {
progress "fetching $1"
- curl -sS "$1" >"$2"
+ curl -fsS "$1" >"$2"
}
-gurl "$mirror/dists/$distro/$suite/source/Sources.gz" "$tmp"/sources.gz
-zcat "$tmp"/sources.gz >"$tmp"/sources-in
+gurl "$mirror/dists/$distro/$suite/$target/$sources.gz" "$tmp"/_$sources.gz
+zcat "$tmp"/_$sources.gz >"$tmp"/_$sources-in
-sed -n 's/^Package: \([-+.0-9a-z][-+.0-9a-z]*\)$/\1/p' \
- <"$tmp"/sources-in >"$tmp"/sources-packages
+lastinfo="$var"/lastinfo-$target
+: "${scorelog:="$var"/scores-$target}"
-if test -f "$var"/last; then
- sed -e 's/$/ _/' "$var"/last >>"$tmp"/sources-packages
+now=`date +%s`
+>>"$lastinfo"
+
+progress selecting
+
+if test $target = source; then
+ blacklist="$blacklistsourcepackages"
else
- echo ' _' >>"$tmp"/sources-packages
+ blacklist="$blacklistbinarypackages"
fi
-sort <"$tmp"/sources-packages >"$tmp"/all-sorted
-pkg="`
- perl -ne '
- if ($now) { print or die $!; $now++; exit; }
- $now = m/ _$/;
- END { die unless $now>1; }
- ' <"$tmp"/all-sorted
-`"
-
-progress "selected $pkg"
+if [ "x$pkg" = x ]; then
+ pkg="`perl -e '
+ use IO::Handle;
+
+ $pre= "[-+.0-9a-z]+";
+ $vre= "[-+.0-9a-zA-Z:~]+";
+
+ sub f1() { $fn=shift @ARGV; open F, $fn or die "$fn $!"; }
+ sub f2() { F->error and die "$fn $!"; close F or die "$fn $!"; }
+
+ $scorelog= "'"$scorelog"'";
+ if (length $scorelog) { open SCORE, "> $scorelog.new" or die $!; }
+ sub pscore ($;$) {
+ return unless length $scorelog;
+ printf SCORE "%$_[1]s", $_[0] or die $!;
+ }
+
+ sub readpkglist ($$) {
+ my ($arrayref, $filename) = @_;
+ return unless length $filename;
+ unshift @ARGV, $filename; f1();
+ while (<F>) {
+ next if m/^\#/ or !m/\S/;
+ die unless m/^($pre)\s*$/;
+ $arrayref->{$1}= 1;
+ }
+ f2();
+ }
+ readpkglist(\%suppress, "'"$suppresspackages"'");
+ readpkglist(\%blacklist, "'"$blacklist"'");
+
+ f1();
+ while (<F>) {
+ die unless m/^($pre) ($vre) (\d+)( .*)?$/;
+ $lastver{$1}= $2;
+ $lasttime{$1}= $3;
+ $extras{$1}= $4." ";
+ }
+ f2();
+ f1();
+ $best_score= -2e9;
+ sub scorepackage () {
+ return if length $skip;
+ return if $blacklist{$package};
+ return if $score < $best_score
+ or ($score==$best_score and \
+ $package gt $best_package);
+#printf STDERR " <----- best score=%s best_score=%s\n", $score, $best_score;
+ pscore(" (best)");
+ $best_score= $score;
+ $best_package= $package;
+ }
+ sub endpackage () {
+ return unless (defined $package
+ or defined $version
+ or defined $skip
+ or defined $source);
+ die unless defined $package;
+ die unless defined $version;
+ $source= $package if !defined $source;
+
+ $score= '$now' - $lasttime{$package};
+ pscore("$package ",-30);
+ pscore("$source ",-25);
+ pscore("$score",10);
+
+ if ($score>1e7) {
+ $score= 1e7;
+ $scorechars.='c';
+ }
+ pscore(" $lastver{$package}",-25);
+ pscore(" $version ",-25);
+ $scorechars= "";
+ if ($lastver{$package} ne $version) {
+ $score *= 5;
+ $scorechars.="U";
+ }
+ if ($extras{$package} =~ m/ nt /) {
+ $scorechars.="n";
+ } else {
+ $score *= 10;
+ }
+ if ($suppress{$source}) {
+ $score -= 2e7;
+ $scorechars.="s";
+ }
+ $scorechars.="[$skip]" if length $skip;
+
+ pscore("-$scorechars",-7);
+ pscore("$score",10);
+
+#print STDERR "SCORE package=$package score $score source=$source\n";
+ scorepackage();
+ pscore("\n");
+ undef $package;
+ undef $version;
+ undef $skip;
+ undef $source;
+ }
+ while (<F>) {
+ if (m/^Package: ($pre)$/) {
+ die if defined $package;
+ $package= $1;
+ } elsif (m/^Version: ($vre)$/) {
+ die if defined $version;
+ $version= $1;
+ } elsif (m/^Source: ($pre)$/) {
+ die if defined $source;
+ $source= $1;
+ } elsif (m/^Architecture:.*/ &&
+ !m/\s(?:'$arch'|all|any)\s/) {
+#printf STDERR " <----- skip %s %s\n", $&, "'$arch'";
+ $skip .= 'a';
+ } elsif (m/^$/) {
+ endpackage();
+ }
+ }
+ f2();
+ endpackage();
+ if (length $scorelog) {
+ close SCORE or die $!;
+ rename "$scorelog.new","$scorelog" or die $!;
+ }
+ die unless length $best_package;
+ open L, ">&4" or die $!;
+ printf L "selected %s (age %s, score %d)\n",
+ $best_package,
+ exists($lastime{$best_package})
+ ? '$now' - $lasttime{$best_package}
+ : "<never-yet>",
+ $best_score;
+ print "$best_package\n" or die $!;
+ ' "$lastinfo" "$tmp"/_$sources-in`"
+else
+ printf >&4 "package forced: %s\n" "$pkg"
+fi
sed -n "/^Package: $pkg\$/,/^\$/p" \
- <"$tmp"/sources-in >"$tmp"/this-stanza
+ <"$tmp"/_$sources-in >"$tmp"/_this-stanza
-cat "$tmp"/this-stanza
+echo
+cat "$tmp"/_this-stanza
getfield () {
eval 'p'$1'="`
sed -n '\''s/^'$1': //p'\'' \
- <"$tmp"/this-stanza
+ <"$tmp"/_this-stanza
`"'
}
-getfield Directory
-
-leafnames="`
- sed -n '/^Files:/,/^([^ ].*)?$/{ /^ /{
- s/^ [0-9a-z][0-9a-z]* *[0-9][0-9]* //; p
- }}' \
- <"$tmp"/this-stanza
-`"
+printf >&3 "selected \"%s\" " $pkg
tp="$tmp/$pkg"
mkdir "$tp" "$tp/src" "$tp/tmp" "$tp/out"
-for leafname in $leafnames; do
- df="$tp/src/$leafname"
- case "$leafname" in
- */*|.*) echo >&2 "bad leafname: $leafname"; exit 1;;
- *.dsc) dsc="$df";;
- esac
- gurl "$mirror/pool/$suite/$pDirectory/$leafname" "$df"
-done
+getfield Version
+
+getfield Source
+if [ "x$pSource" != x ]; then
+ src="$pSource"
+else
+ src="$pkg"
+fi
+
+if test $target = source; then
+ getfield Directory
+ leafnames="`
+ sed -n '/^Files:/,/^([^ ].*)?$/{ /^ /{
+ s/^ [0-9a-z][0-9a-z]* *[0-9][0-9]* //; p
+ }}' \
+ <"$tmp"/_this-stanza
+ `"
+ for leafname in $leafnames; do
+ df="$tp/src/$leafname"
+ case "$leafname" in
+ */*|.*) echo >&2 "bad leafname: $leafname"; exit 1;;
+ *.dsc) fot="$df";;
+ esac
+ gurl "$mirror/$pDirectory/$leafname" "$df"
+ done
+ testmode=--source
+ testmode2=''
+ desc="$pkg"
+ : ${upload_if_ok:=true}
+ email_package_header="$email_sourcepackage_header"
+else
+ getfield Filename
+ fot="$tp/src/$pkg.deb"
+ gurl "$mirror/$pFilename" "$fot"
+ testmode='--binaries=install --binary'
+ testmode2=--instantiate
+ desc="$pkg $descx"
+ : ${upload_if_ok:=false}
+ email_package_header="$email_binarypackage_header"
+fi
if [ "x$maintainer_email_override" = x ]; then
getfield Maintainer
maintainer_email=maintainer_email_override
fi
+printf >&3 "adt-run "
+
progress "starting test"
xrc () {
set -e
}
+echo 'fatal: adt-run did not start properly' >"$tmp"/_summary
+
xrc adt-run --tmp-dir "$tp"/tmp \
--output-dir "$tp"/out \
--log-file "$tp"/log \
- --source "$dsc" \
+ --summary "$tmp"/_summary \
+ $adtrun_extra_opts \
+ $testmode "$fot" $testmode2 \
--- \
adt-virt-xenlvm \
- distro="$distro" \
- 2>&1
+ $adtvirt_extra_opts \
+ --distro="$distro" \
+ -- \
+ 2>&1 3>&- 4>&-
+
+printf >&3 "%s " $rc
+
+ourx=0
+upload=true
+: ${upload_if_notests:=false}
+extras=''
case "$rc" in
-0) summary='all OK'; email='' ;;
-2) summary='OK (some skipped)'; email='' ;;
-8) summary='package declares no tests'; email='' ;;
+0) summary='all OK'; email=''
+ upload=$upload_if_ok ;;
+2) summary='OK (some skipped)'; email=''
+ upload=$upload_if_ok ;;
+8) summary='package declares no tests'; email=''
+ upload=$upload_if_notests; extras='nt' ;;
4|6) summary='test(s) failed!'; email="$maintainer_email" ;;
12) summary='erroneous package!'; email="$maintainer_email" ;;
16) summary='testbed failed!'; email="administrator_email" ;;
-*) summary='unexpected failure!'; email="administrator_email" ;;
+*) summary='unexpected failure!'; email="administrator_email"; ourx=20;;
esac
progress "RESULTS $summary"
-progress "contacting $email"
-for odir in tmp out; do
- if test -d "$tp"/$odir; then
- GZIP=-2 tar -f "$tp"/$odir.tar.gz -C "$tp" -zc $odir
- rm -r "$tp"/$odir
+if [ "x$suppresspackages" != x ] \
+ && grep -x "$src" "$suppresspackages" >/dev/null; then
+ printf >&3 "email-suppressed "
+ email=''
+fi
+
+if $upload; then
+ progress "bundling"
+ printf "\n%s\n" "$summary" >>"$tmp"/_summary
+
+ edest=${email%_email}
+ esummary="$var"/emailed/last-$pkg,$edest
+ if [ "x$edest" = x ]; then
+ printf >&3 "email-none "
+ rm -f "$var"/emailed/last-$pkg,*
+ esummary=''
+ elif $suppressrepeatedemails \
+ && [ -f "$esummary" ] \
+ && diff -u "$esummary" "$tmp"/_summary >"$var"/emailed/diff-$pkg; then
+ printf >&3 "email-same $email "
+ email=''
+ esummary=''
+ else
+ cp "$tmp"/_summary "$esummary".new
fi
-done
-$rsync -rltH --safe-links --delete "$tp" "$destrsynchead/$destdirtail/"
+ ln -f "$tmp"/_summary "$tp"/summary
+
+ for odir in tmp out; do
+ if test -d "$tp"/$odir; then
+ GZIP=-2 tar -f "$tp"/$odir.tar.gz -C "$tp" -zc $odir
+ rm -r "$tp"/$odir
+ fi
+ done
+
+ progress "uploading"
+ printf >&3 "uploading"
+ $rsync -rltH --safe-links --delete "$tp" "$destrsynchead/$destdirfin/"
+ printf >&3 " "
+fi
if [ "x$email" != x ]; then
+ progress "contacting $email"
eval "email_addr=\$$email"
- cat >"$tmp"/email <<END
+ printf >&3 "email \"%s\" " "$email_addr"
+ cat >"$tmp"/_email_header <<END
From: $from
To: $email_addr
-Subject: autopkgtest $distro $pkg: $summary
+Subject: autopkgtest $distro $desc: $summary
+
+END
+
+ email_package_header="${email_package_header//@p/$pkg}"
+ email_package_header="${email_package_header//@s/$src}"
+ email_package_header="${email_package_header//@v/$pVersion}"
+ email_package_header="${email_package_header//@a/@}"
+ printf >"$tmp"/_email "%s" "$email_package_header"
- Test executed for: $distro $pkg
+ cat >>"$tmp"/_email <<END
+ Test executed for: $distro $target $pkg
Outcome: $summary
+END
+ sed -e 's/^/ /' "$tmp"/_summary >>"$tmp"/_email
+ cat >>"$tmp"/_email <<END
This message is automatically generated by the autopkgtest package
testing system. You are receiving it because:
END
case "$email" in
pMaintainer)
- cat >>"$tmp"/email <<END
+ cat >>"$tmp"/_email <<END
You are listed in the Maintainer field of the $pkg package in $distro
- and the test results appear to indicate a problem with the package.
+ and the test results appear to indicate a problem with the package.
END
;;
maintainer_email_override)
- cat >>"$tmp"/email <<END
+ cat >>"$tmp"/_email <<END
The test results appear to indicate a problem with the package
- and reports for package maintainers for $distro are being directed to
- $maintainer_email_override
+ and reports for package maintainers for $distro are being directed to
+ $maintainer_email_override
END
;;
administrator_email)
- cat >>"$tmp"/email <<END
+ cat >>"$tmp"/_email <<END
You are the administrator for the autopkgtest installation.
END
;;
exit 1
;;
esac
- cat >>"$tmp/email" <<END
-
-The test log, which is intended to be sufficient to diagnose most
-failures, can be found below. However, in case this is not
-sufficient, another copy can be found along with output files, saved
-temporary files, and so on, at:
- $desthttphead/$destdirtail/
-
+ cat >>"$tmp/_email" <<END
+
+The top and tail of the test log, which is intended to be sufficient
+to diagnose most failures, can be found below. However, in case this
+is not sufficient, a complete log can be found along with output
+files, saved temporary files, and so on, at:
+ $desthttphead/$destdirfin/
+$email_extra_info
If you have any questions about this service please contact me at:
$from
-8<-
END
- cat >>"$tmp"/email 2>&1 "$tmp"/log ||:
- sendmail -odq -oem -t -oi <"$tmp"/email
fi
-printf >>"$var"/log "package=%s rc=%s emailed='%s'\n" \
- "$pkg" $rc "$email_addr"
-echo $pkg >"$var"/last.new
-mv "$var"/last.new "$var"/last
+printf >>"$var"/log "%s=%s rc=%s emailed='%s'\n" \
+ "$target" "$pkg" $rc "$email_addr"
+
+if [ "x$ourx" = x0 ]; then
+ sed -e "/^$pkg /d" <"$lastinfo" >"$lastinfo".new
+ printf "%s %s %s %s\n" "$pkg" "$pVersion" "$now" "$extras" \
+ >>"$lastinfo".new
+ mv "$lastinfo".new "$lastinfo"
+ progress "tested."
+else
+ progress "fault ($ourx)."
+fi
+
+perl <"$tmp"/_log_raw >"$tmp"/_log -ne '
+ s/[^\012\040-\133\135-\176]/
+ $& eq "\t" ? "\\t" :
+ $& eq "\r" ? "\\r" :
+ $& eq "\b" ? "\\b" :
+ $& eq "\\" ? "\\\\" :
+ sprintf "\\x%02x", ord $&
+ /ge;
+
+ if (!$middle) {
+ $headlen += length;
+ $middle=1 if $headlen > '"$logheadmaxbytes"';
+ }
+ if (!$middle) {
+ print or die $!;
+ } else {
+ $taillen += length;
+ push @tail, $_;
+ while ($taillen > '"$logtailmaxbytes"') {
+ $taillen -= length shift @tail;
+ $some_dropped= 1;
+ }
+ }
+ END {
+ print "...\n" or die $! if $some_dropped;
+ print @tail or die $!;
+ }
+'
+
+if [ "x$email" = x ]; then
+ if $interactive; then
+ cat "$tmp"/_log >&2
+ fi
+else
+ cat >>"$tmp"/_email 2>&1 "$tmp"/_log ||:
+
+ if [ "x$email_signing_key" != x ]; then
+ printf >&3 "signing "
+ echo >>"$tmp/_email"
+ gpg -u"$email_signing_key" --clearsign \
+ <"$tmp/_email" >"$tmp/_email.asc"
+ mv -f "$tmp/_email.asc" "$tmp/_email"
+ fi
+ cat "$tmp/_email_header" "$tmp/_email" >"$tmp/_email.new"
+ mv -f "$tmp/_email.new" "$tmp/_email"
+
+ if $interactive; then
+ cat "$tmp"/_email >&2
+ else
+ sendmail -odi -oem -t -oi <"$tmp"/_email
+ if [ "x$esummary" != x ]; then
+ printf >&3 "email-recorded "
+ mv "$esummary".new "esummary"
+ fi
+ fi
+fi
-progress "done."
+printf >&3 "done %s.\n" $ourx
+exit $ourx