chiark / gitweb /
adt-run: Fix typo to make "build-needed" work (Closes #637353)
[autopkgtest.git] / runner / adt-testreport-onepackage
index 122abfb552a6e26d7670784894b9a63ed931c53c..48e9b3b1257f20938020c3e33d9fb7fe70304999 100755 (executable)
@@ -9,7 +9,11 @@ rsync=rsync
 disable=true
 interactive=true
 target=source
+suppressrepeatedemails=false
 arch=`dpkg --print-architecture`
+logheadmaxbytes=32768
+logtailmaxbytes=32768
+upload_src=false
 
 for config in "$@"; do
        case "$config" in
@@ -46,12 +50,12 @@ printf >&3 "starting "
 rm -rf "$tmp"
 mkdir "$tmp"
 
->"$tmp"/_log
+>"$tmp"/_log_raw
 
 if $interactive; then
-       echo '(log diverted to stdout)' >>"$tmp"/_log
+       echo '(log diverted to stdout)' >>"$tmp"/_log_raw
 else
-       exec >>"$tmp"/_log
+       exec >>"$tmp"/_log_raw
 fi
 exec 4>&1
 
@@ -68,12 +72,19 @@ gurl "$mirror/dists/$distro/$suite/$target/$sources.gz" "$tmp"/_$sources.gz
 zcat "$tmp"/_$sources.gz >"$tmp"/_$sources-in
 
 lastinfo="$var"/lastinfo-$target
+: "${scorelog:="$var"/scores-$target}"
 
 now=`date +%s`
 >>"$lastinfo"
 
 progress selecting
 
+if test $target = source; then
+       blacklist="$blacklistsourcepackages"
+else
+       blacklist="$blacklistbinarypackages"
+fi
+
 if [ "x$pkg" = x ]; then
  pkg="`perl -e '
        use IO::Handle;
@@ -84,6 +95,27 @@ if [ "x$pkg" = x ]; then
        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.*)?\s*$/;
+                       $arrayref->{$1}= 1;
+               }
+               f2();
+       }
+       readpkglist(\%suppress, "'"$suppresspackages"'");
+       readpkglist(\%blacklist, "'"$blacklist"'");
+
        f1();
        while (<F>) {
                die unless m/^($pre) ($vre) (\d+)( .*)?$/;
@@ -93,25 +125,64 @@ if [ "x$pkg" = x ]; then
        }
        f2();
        f1();
-       $best_score= -1;
+       $best_score= -2e9;
        sub scorepackage () {
-               return if $skip;
+               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 $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)$/) {
@@ -120,19 +191,23 @@ if [ "x$pkg" = x ]; then
                } elsif (m/^Version: ($vre)$/) {
                        die if defined $version;
                        $version= $1;
-                       $score= '$now' - $lasttime{$package};
-                       $score= 1e7 if $score>1e7;
-                       $score *= 5 if $lastver{$package} ne $version;
-                       $score *= 10 unless $extras{$package} =~ m/ nt /;
+               } elsif (m/^Source: ($pre)$/) {
+                       die if defined $source;
+                       $source= $1;
                } elsif (m/^Architecture:.*/ &&
-                        !m/\s'$arch'\s/) {
-                       $skip= 1;
+                        !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",
@@ -167,6 +242,13 @@ mkdir "$tp" "$tp/src" "$tp/tmp" "$tp/out"
 
 getfield Version
 
+getfield Source
+if [ "x$pSource" != x ]; then
+       src="$pSource"
+else
+       src="$pkg"
+fi
+
 if test $target = source; then
        getfield Directory
        leafnames="`
@@ -187,6 +269,7 @@ if test $target = source; then
        testmode2=''
        desc="$pkg"
        : ${upload_if_ok:=true}
+       email_package_header="$email_sourcepackage_header"
 else
        getfield Filename
        fot="$tp/src/$pkg.deb"
@@ -195,6 +278,7 @@ else
        testmode2=--instantiate
        desc="$pkg $descx"
        : ${upload_if_ok:=false}
+       email_package_header="$email_binarypackage_header"
 fi
 
 if [ "x$maintainer_email_override" = x ]; then
@@ -253,10 +337,33 @@ esac
 
 progress "RESULTS $summary"
 
+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
-       ln "$tmp"/_summary "$tp"/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
+
+       ln -f "$tmp"/_summary "$tp"/summary
 
        for odir in tmp out; do
                if test -d "$tp"/$odir; then
@@ -265,6 +372,10 @@ if $upload; then
                fi
        done
 
+       if ! $upload_src; then
+               rm -r "$tp"/src
+       fi
+
        progress "uploading"
        printf >&3 "uploading"
        $rsync -rltH --safe-links --delete "$tp" "$destrsynchead/$destdirfin/"
@@ -275,11 +386,20 @@ if [ "x$email" != x ]; then
        progress "contacting $email"
        eval "email_addr=\$$email"
        printf >&3 "email \"%s\" " "$email_addr"
-       cat >"$tmp"/_email <<END
+       cat >"$tmp"/_email_header <<END
 From: $from
 To: $email_addr
 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//@_/@}"
+       printf >"$tmp"/_email "%s" "$email_package_header"
+
+       cat >>"$tmp"/_email <<END
  Test executed for:  $distro  $target  $pkg
  Outcome: $summary
 END
@@ -293,14 +413,14 @@ END
                pMaintainer)
                        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
  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)
@@ -315,12 +435,12 @@ END
        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:
+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
 
@@ -344,16 +464,60 @@ 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