chiark / gitweb /
* adt-testreport-onepackage: support for Launchpad bug filing
[autopkgtest.git] / runner / adt-testreport-onepackage
1 #!/bin/bash
2
3 set -e
4
5 salt=''
6 tmp=tmp
7 var=var
8 rsync=rsync
9 disable=true
10 interactive=true
11 target=source
12 suppressrepeatedemails=false
13 arch=`dpkg --print-architecture`
14
15 for config in "$@"; do
16         case "$config" in
17         *=*)    eval "$config"  ;;
18         *)      . "$config"     ;;
19         esac
20 done
21
22 if $disable; then
23         echo >&2 'disabled because config inadequate (no disable=false)'
24         exit 1
25 fi
26
27 : ${destdirtail:=$distro-$target}
28 : ${destdirfin:="$destdircommon$destdirtail"}
29
30 case $target in
31 source)
32         sources=Sources
33         descx=''
34         ;;
35 binary-*)
36         sources=Packages
37         descx="${target#binary-}"
38         ;;
39 *)
40         echo >&2 'target must be source or binary-*'
41         exit 1
42 esac
43
44 exec 3>&1
45 printf >&3 "starting "
46
47 rm -rf "$tmp"
48 mkdir "$tmp"
49
50 >"$tmp"/_log
51
52 if $interactive; then
53         echo '(log diverted to stdout)' >>"$tmp"/_log
54 else
55         exec >>"$tmp"/_log
56 fi
57 exec 4>&1
58
59 progress () {
60         echo "++++++ $1 ++++++"
61 }
62
63 gurl () {
64         progress "fetching $1"
65         curl -fsS "$1" >"$2"
66 }
67
68 gurl "$mirror/dists/$distro/$suite/$target/$sources.gz" "$tmp"/_$sources.gz
69 zcat "$tmp"/_$sources.gz >"$tmp"/_$sources-in
70
71 lastinfo="$var"/lastinfo-$target
72
73 now=`date +%s`
74 >>"$lastinfo"
75
76 progress selecting
77
78 if [ "x$pkg" = x ]; then
79  pkg="`perl -e '
80         use IO::Handle;
81
82         $pre= "[-+.0-9a-z]+";
83         $vre= "[-+.0-9a-zA-Z:~]+";
84
85         sub f1() { $fn=shift @ARGV; open F, $fn or die "$fn $!"; }
86         sub f2() { F->error and die "$fn $!"; close F or die "$fn $!"; }
87
88         f1();
89         while (<F>) {
90                 die unless m/^($pre) ($vre) (\d+)( .*)?$/;
91                 $lastver{$1}= $2;
92                 $lasttime{$1}= $3;
93                 $extras{$1}= $4." ";
94         }
95         f2();
96         f1();
97         $best_score= -1;
98         sub scorepackage () {
99                 return if $skip;
100                 return if $score < $best_score
101                      or ($score==$best_score and \
102                          $package gt $best_package);
103 #printf STDERR " <----- best score=%s best_score=%s\n", $score, $best_score;
104                 $best_score= $score;
105                 $best_package= $package;
106         }
107         sub endpackage () {
108                 return unless (defined $package
109                                 or defined $version
110                                 or defined $skip);
111                 die unless defined $package;
112                 die unless defined $version;
113                 scorepackage();
114                 undef $package;
115                 undef $version;
116                 undef $skip;
117         }
118         while (<F>) {
119                 if (m/^Package: ($pre)$/) {
120                         die if defined $package;
121                         $package= $1;
122                 } elsif (m/^Version: ($vre)$/) {
123                         die if defined $version;
124                         $version= $1;
125                         $score= '$now' - $lasttime{$package};
126                         $score= 1e7 if $score>1e7;
127                         $score *= 5 if $lastver{$package} ne $version;
128                         $score *= 10 unless $extras{$package} =~ m/ nt /;
129 #print STDERR "$package score $score\n";
130                 } elsif (m/^Architecture:.*/ &&
131                          !m/\s(?:'$arch'|all|any)\s/) {
132 #printf STDERR " <----- skip %s %s\n", $&, "'$arch'";
133                         $skip= 1;
134                 } elsif (m/^$/) {
135                         endpackage();
136                 }
137         }
138         f2();
139         endpackage();
140         die unless length $best_package;
141         open L, ">&4" or die $!;
142         printf L "selected %s (age %s, score %d)\n",
143                 $best_package,
144                 exists($lastime{$best_package})
145                 ? '$now' - $lasttime{$best_package}
146                 : "<never-yet>",
147                 $best_score;
148         print "$best_package\n" or die $!;
149  ' "$lastinfo" "$tmp"/_$sources-in`"
150 else
151         printf >&4 "package forced: %s\n" "$pkg"
152 fi
153
154 sed -n "/^Package: $pkg\$/,/^\$/p" \
155  <"$tmp"/_$sources-in >"$tmp"/_this-stanza
156
157 echo
158 cat "$tmp"/_this-stanza
159
160 getfield () {
161         eval 'p'$1'="`
162                 sed -n '\''s/^'$1': //p'\'' \
163                  <"$tmp"/_this-stanza
164         `"'
165 }
166
167 printf >&3 "selected \"%s\" " $pkg
168
169 tp="$tmp/$pkg"
170 mkdir "$tp" "$tp/src" "$tp/tmp" "$tp/out"
171
172 getfield Version
173
174 if test $target = source; then
175         getfield Directory
176         leafnames="`
177                 sed -n '/^Files:/,/^([^ ].*)?$/{ /^ /{
178                         s/^ [0-9a-z][0-9a-z]*  *[0-9][0-9]* //; p
179                         }}' \
180                  <"$tmp"/_this-stanza
181         `"
182         for leafname in $leafnames; do
183                 df="$tp/src/$leafname"
184                 case "$leafname" in
185                 */*|.*) echo >&2 "bad leafname: $leafname"; exit 1;;
186                 *.dsc) fot="$df";;
187                 esac
188                 gurl "$mirror/$pDirectory/$leafname" "$df"
189         done
190         testmode=--source
191         testmode2=''
192         desc="$pkg"
193         : ${upload_if_ok:=true}
194 else
195         getfield Filename
196         fot="$tp/src/$pkg.deb"
197         gurl "$mirror/$pFilename" "$fot"
198         testmode='--binaries=install --binary'
199         testmode2=--instantiate
200         desc="$pkg $descx"
201         : ${upload_if_ok:=false}
202 fi
203
204 if [ "x$maintainer_email_override" = x ]; then
205         getfield Maintainer
206         maintainer_email=pMaintainer
207 else
208         maintainer_email=maintainer_email_override
209 fi
210
211 printf >&3 "adt-run "
212
213 progress "starting test"
214
215 xrc () {
216         printf "+ %s\n" "$*"
217         set +e
218         "$@"
219         rc=$?
220         set -e
221 }
222
223 echo 'fatal: adt-run did not start properly' >"$tmp"/_summary
224
225 xrc adt-run --tmp-dir "$tp"/tmp                         \
226         --output-dir "$tp"/out                          \
227         --log-file "$tp"/log                            \
228         --summary "$tmp"/_summary                       \
229         $adtrun_extra_opts                              \
230         $testmode "$fot" $testmode2                     \
231  ---                                                    \
232  adt-virt-xenlvm                                        \
233         $adtvirt_extra_opts                             \
234         --distro="$distro"                              \
235  --                                                     \
236  2>&1 3>&- 4>&-
237
238 printf >&3 "%s " $rc
239
240 ourx=0
241 upload=true
242 : ${upload_if_notests:=false}
243 extras=''
244
245 case "$rc" in
246 0)      summary='all OK';                       email=''
247                                         upload=$upload_if_ok            ;;
248 2)      summary='OK (some skipped)';            email=''
249                                         upload=$upload_if_ok            ;;
250 8)      summary='package declares no tests';    email=''
251                                 upload=$upload_if_notests; extras='nt'  ;;
252 4|6)    summary='test(s) failed!';      email="$maintainer_email"       ;;
253 12)     summary='erroneous package!';   email="$maintainer_email"       ;;
254 16)     summary='testbed failed!';      email="administrator_email"     ;;
255 *)      summary='unexpected failure!';  email="administrator_email"; ourx=20;;
256 esac
257
258 progress "RESULTS $summary"
259
260 if  [ "x$suppresspackages" != x ] \
261  && grep -x "$pkg" "$suppresspackages" >/dev/null; then
262         printf >&3 "email-suppressed "
263         email=''
264 fi
265
266 if $upload; then
267         progress "bundling"
268         printf "\n%s\n" "$summary" >>"$tmp"/_summary
269
270         edest=${email%_email}
271         esummary="$var"/emailed/last-$pkg,$edest
272         if [ "x$edest" = x ]; then
273                 printf >&3 "email-none "
274                 rm -f "$var"/emailed/last-$pkg,*
275                 esummary=''
276         elif $suppressrepeatedemails \
277           && [ -f "$esummary" ] \
278           && diff -u "$esummary" "$tmp"/_summary >"$var"/emailed/diff-$pkg; then
279                 printf >&3 "email-same $email "
280                 email=''
281                 esummary=''
282         else
283                 cp "$tmp"/_summary "$esummary".new
284         fi
285
286         ln -f "$tmp"/_summary "$tp"/summary
287
288         for odir in tmp out; do
289                 if test -d "$tp"/$odir; then
290                         GZIP=-2 tar -f "$tp"/$odir.tar.gz -C "$tp" -zc $odir
291                         rm -r "$tp"/$odir
292                 fi
293         done
294
295         progress "uploading"
296         printf >&3 "uploading"
297         $rsync -rltH --safe-links --delete "$tp" "$destrsynchead/$destdirfin/"
298         printf >&3 " "
299 fi
300
301 if [ "x$email" != x ]; then
302         progress "contacting $email"
303         eval "email_addr=\$$email"
304         printf >&3 "email \"%s\" " "$email_addr"
305         cat >"$tmp"/_email_header <<END
306 From: $from
307 To: $email_addr
308 Subject: autopkgtest $distro $desc: $summary
309
310 END
311
312         printf >"$tmp"/_email "$email_package_header" "$pkg"
313
314         cat >>"$tmp"/_email <<END
315  Test executed for:  $distro  $target  $pkg
316  Outcome: $summary
317 END
318         sed -e 's/^/  /' "$tmp"/_summary >>"$tmp"/_email
319         cat >>"$tmp"/_email <<END
320
321 This message is automatically generated by the autopkgtest package
322 testing system.  You are receiving it because:
323 END
324         case "$email" in
325                 pMaintainer)
326                         cat >>"$tmp"/_email <<END
327  You are listed in the Maintainer field of the $pkg package in $distro
328  and the test results appear to indicate a problem with the package.
329 END
330                         ;;
331                 maintainer_email_override)
332                         cat >>"$tmp"/_email <<END
333  The test results appear to indicate a problem with the package
334  and reports for package maintainers for $distro are being directed to
335  $maintainer_email_override
336 END
337                         ;;
338                 administrator_email)
339                         cat >>"$tmp"/_email <<END
340  You are the administrator for the autopkgtest installation.
341 END
342                         ;;
343                 *)
344                         echo >&2 "huh email $email is what why?"
345                         exit 1
346                         ;;
347         esac
348         cat >>"$tmp/_email" <<END
349
350 The test log, which is intended to be sufficient to diagnose most
351 failures, can be found below.  However, in case this is not
352 sufficient, another copy can be found along with output files, saved
353 temporary files, and so on, at:
354  $desthttphead/$destdirfin/
355 $email_extra_info
356 If you have any questions about this service please contact me at:
357  $from
358
359 Regards,
360 $salutation
361
362 -8<-
363 END
364 fi
365
366 printf >>"$var"/log "%s=%s rc=%s emailed='%s'\n" \
367         "$target" "$pkg" $rc "$email_addr"
368
369 if [ "x$ourx" = x0 ]; then
370         sed -e "/^$pkg /d" <"$lastinfo" >"$lastinfo".new
371         printf "%s %s %s %s\n" "$pkg" "$pVersion" "$now" "$extras" \
372                 >>"$lastinfo".new
373         mv "$lastinfo".new "$lastinfo"
374         progress "tested."
375 else
376         progress "fault ($ourx)."
377 fi
378
379 if [ "x$email" = x ]; then
380         if $interactive; then
381                 cat "$tmp"/_log >&2
382         fi
383 else
384         cat >>"$tmp"/_email 2>&1 "$tmp"/_log ||:
385
386         if [ "x$email_signing_key" != x ]; then
387                 printf >&3 "signing "
388                 echo >>"$tmp/_email"
389                 gpg -u"$email_signing_key" --clearsign \
390                         <"$tmp/_email" >"$tmp/_email.asc"
391                 mv -f "$tmp/_email.asc" "$tmp/_email"
392         fi
393         cat "$tmp/_email_header" "$tmp/_email" >"$tmp/_email.new"
394         mv -f "$tmp/_email.new" "$tmp/_email"
395
396         if $interactive; then
397                 cat "$tmp"/_email >&2
398         else
399                 sendmail -odi -oem -t -oi <"$tmp"/_email
400                 if [ "x$esummary" != x ]; then
401                         printf >&3 "email-recorded "
402                         mv "$esummary".new "esummary"
403                 fi
404         fi
405 fi
406
407 printf >&3 "done %s.\n" $ourx
408 exit $ourx