chiark / gitweb /
Test suite: Use t-expect-push-fail everywhere
[dgit.git] / tests / lib
1 #
2
3 exec 2>&1
4 set -x
5 set -o pipefail
6
7 . tests/lib-core
8
9 t-set-intree
10
11 : ${DGIT_TEST_DEBUG:=-D}
12 export DGIT_TEST_DEBUG
13
14 root=`pwd`
15 troot=$root/tests
16 testname="${DGIT_TEST_TESTNAME-${0##*/}}"
17
18 tmp=$ADTTMP
19 if [ x"$tmp" = x ]; then
20         mkdir -p tests/tmp
21         tmp=tests/tmp/$testname
22         rm -rf $tmp
23         mkdir $tmp
24 fi
25 cd $tmp
26
27 tmp=`pwd`
28
29 t-set-using-tmp
30
31 ln -f $troot/ssh ssh
32
33 mkdir -p $tmp/gnupg
34 cp $troot/gnupg/* $tmp/gnupg
35 chmod go-rw $tmp/gnupg/*
36
37 mkdir -p $tmp/incoming
38 cat <<END >$tmp/dput.cf
39 [test-dummy]
40 method                  = local
41 incoming                = $tmp/incoming
42 run_dinstall            = 0
43 END
44
45 t-expect-fail () {
46         local mpat="$1"; shift
47
48         local grepper=fgrep
49         case "$mpat" in
50         [A-Z]:*)
51                 case "$mpat" in
52                 E:*)    grepper=egrep   ;;
53                 F:*)    grepper=fgrep   ;;
54                 *)      fail "bad mpat prefix in $mpat";;
55                 esac
56                 mpat=${mpat#[A-Z]:}
57                 ;;
58         esac
59
60         set +o pipefail
61         LC_MESSAGES=C "$@" 2>&1 | tee $tmp/t.output
62         local ps="${PIPESTATUS[*]}"
63         set -o pipefail
64
65         case $ps in
66         "0 0")  fail "command unexpectedly succeeded (instead of: $mpat)" ;;
67         *" 0")  ;;
68         *)      fail "tee failed"  ;;
69         esac
70
71         $grepper -e "$mpat" $tmp/t.output ||
72                 fail "error message not found"
73 }
74
75 t-expect-push-fail () {
76         local mpat="$1"; shift
77         t-reporefs pre-push
78         t-expect-fail "$mpat"  "$@"
79         t-reporefs post-push
80         diff $tmp/show-refs.{pre,post}-push
81 }
82
83 t-reporefs () {
84         local whichoutput=$1; shift
85         local outputfile="$tmp/show-refs.$whichoutput"
86         (set -e
87          exec >"$outputfile"
88          if test -d $tmp/git/$p.git; then
89                 cd $tmp/git/$p.git
90                 git show-ref |sort
91         fi)
92 }
93
94 t-untar () {
95         local tarfile=$1.tar
96         local edittree=$1.edit
97         if test -d "$edittree"; then
98                 cp -al "$edittree"/* .
99         else
100                 tar xf "$tarfile"
101         fi
102 }
103
104 t-worktree () {
105         rm -rf $p
106         t-untar $troot/worktrees/${p}_$1
107 }
108
109 t-git () {
110         p=$1
111         v=$2
112         mkdir -p $tmp/git
113         local gs=$troot/git-srcs/${p}_$v.git
114         (set -e; cd $tmp/git; t-untar $gs)
115 }
116
117 t-git-none () {
118         mkdir -p $tmp/git
119         (set -e; cd $tmp/git; tar xf $troot/git-template.tar)
120 }
121
122 t-has-ancestor () {
123         local now=`git rev-parse HEAD`
124         local ancestor=`git rev-parse $1^{}`
125         local mbase=`git merge-base $ancestor $now`
126         if [ x$mbase != x$ancestor ]; then
127                 fail "not ff $ancestor..$now, $mbase != $ancestor"
128         fi
129 }
130
131 t-prep-newpackage () {
132         p=$1
133         v=$2
134         t-archive-none $p
135         t-git-none
136         t-worktree $v
137         cd $p
138         if ! git-show-ref --verify --quiet refs/heads/master; then
139                 git branch -m dgit/sid master
140                 git remote rm dgit
141         fi
142         cd ..
143 }
144
145 t-archive-none () {
146         p=$1
147         mkdir -p $tmp/aq $tmp/mirror/pool/main
148
149         local suite=sid
150
151         >$tmp/aq/package.$suite.$p
152         t-archive-updated $suite $p
153
154         >$tmp/aq/package.new.$p
155         t-archive-updated new $p
156
157         ln -s sid $tmp/aq/dsc_in_suite/unstable
158         cat <<'END' >$tmp/aq/suites
159 [
160    {
161       "archive" : "ftp-master",
162       "codename" : "sid",
163       "components" : [
164          "main",
165          "contrib",
166          "non-free"
167       ],
168       "name" : "unstable",
169       "dakname" : "unstable"
170    }
171 ]
172 END
173 }
174
175 t-archive-updated () {
176         local suite=$1
177         local p=$2
178         local suitedir=$tmp/aq/dsc_in_suite/$suite
179         mkdir -p $suitedir
180         perl <$tmp/aq/package.$suite.$p >$suitedir/$p -wne '
181                 use JSON;
182                 use strict;
183                 our @v;
184                 m{^(\S+) (\w+) ([^ \t/]+)/(\S+)} or die;
185                 push @v, {
186                         "version" => "$1",
187                         "sha256sum" => "$2",
188                         "component" => "$3",
189                         "filename" => "$4",
190                 };
191                 END {
192                         print to_json \@v or die $!;
193                 }
194         '
195 }
196
197 t-archive-process-incoming () {
198         local suite=$1
199         mv $tmp/incoming/${p}_${v}[._]* $tmp/mirror/pool/main/
200         t-archive-query "$suite"
201 }
202
203 t-archive-query () {
204         local suite=${1-sid}
205         local dscf=main/${p}_${v}.dsc
206         local sha=`sha256sum <$tmp/mirror/pool/$dscf`
207         echo "${v} ${sha%  -} $dscf" >>$tmp/aq/package.$suite.${p}
208         t-archive-updated $suite $p
209 }
210
211 t-archive () {
212         t-archive-none $1
213         v=$2
214         local dscf=${p}_$2.dsc
215         rm -f $tmp/mirror/pool/main/${p}_*
216         ln $troot/pkg-srcs/${p}_${2%-*}* $tmp/mirror/pool/main/
217         t-archive-query
218         rm -rf $tmp/extract
219         mkdir $tmp/extract
220         (set -e; cd $tmp/extract; dpkg-source -x ../mirror/pool/main/$dscf)
221 }
222
223 t-git-dir-time-passes () {
224         touch -d 'last year' $tmp/git/$p.git
225 }
226
227 t-git-dir-check () {
228         local gitdir=$tmp/git/$p.git
229         case "$1" in
230         enoent)
231                 if test -e "$gitdir"; then fail "$gitdir exists"; fi
232                 return
233                 ;;
234         public) wantstat='7[75]5' ;;
235         secret) wantstat='7[70]0' ;;
236         *)      fail "$1 t-git-dir-check ?" ;;
237         esac
238         gotstat=`stat -c%a $gitdir`
239         case "$gotstat" in
240         *$wantstat) return ;;
241         *)      fail "$gitdir has mode $gotstat, expected $wantstat" ;;
242         esac
243 }
244
245 t-rm-dput-dropping () {
246         rm -f $tmp/${p}_${v}_*.upload
247 }
248
249 t-dgit () {
250         local dgit=${DGIT_TEST-dgit}
251         : '
252 {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{'
253         $dgit --dgit=$dgit --dget:-u --dput:--config=$tmp/dput.cf \
254                 -dtest-dummy $DGIT_TEST_OPTS $DGIT_TEST_DEBUG \
255                 -k39B13D8A "$@"
256         : '}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
257 '
258 }
259
260 t-diff-nogit () {
261         diff --exclude=.git --exclude=.pc -ruN $*
262 }
263
264 t-cloned-fetched-good () {
265         t-diff-nogit ../extract/$p-${v%-*} .
266         t-clean-on-branch dgit/sid
267         t-refs-same-start
268         t-refs-same \
269                 refs/heads/dgit/sid \
270                 refs/remotes/dgit/dgit/sid
271         t-refs-notexist refs/dgit/unstable refs/remotes/dgit/dgit/unstable
272 }
273
274 t-output () {
275         printf "%s\n" "$1" >$tmp/t.want
276         shift
277         "$@" >$tmp/t.got
278         diff $tmp/t.want $tmp/t.got
279 }
280
281 t-clean-on-branch () {
282         t-output "## $1" git status -b --porcelain
283 }
284
285 t-git-get-ref () {
286         local ref=$1
287         case "$ref" in
288         refs/*) ;;
289         *) fail "t-git-get-ref bad $ref" ;;
290         esac
291         (git show-ref -d $1 || test $? = 1) | perl -ne '
292                 $x = $1 if m#^(\w+) \Q'$1'\E(?:\^\{\})?$#;
293                 END { print "$x\n" if length $x; }
294         '
295 }
296
297 t-ref-same () {
298         local name="$1"
299         local val=`t-git-get-ref $name`
300         t-ref-same-val "$name" $val
301 }
302
303 t-ref-head () {
304         local val=`git rev-parse HEAD`
305         t-ref-same-val HEAD $val
306 }
307
308 t-ref-same-val () {
309         local name="$1"
310         local val=$2
311         case "$t_ref_val" in
312         '')             ;;
313         "$val")         ;;
314         *)              fail "ref varies: $name: $val != $t_ref_val" ;;
315         esac
316         t_ref_val="$val"
317 }
318
319 t-refs-same-start () {
320         t_ref_val=''
321 }
322
323 t-refs-same () {
324         local g
325         for g in $*; do
326                 t-ref-same $g
327         done
328 }
329
330 t-refs-notexist () {
331         local val
332         for g in $*; do
333                 val=`t-git-get-ref $g >$tmp/t.refx`
334                 if [ "x$val" != x ]; then
335                         fail "ref $g unexpectedly exists ($val)"
336                 fi
337         done
338 }
339
340 t-v-tag () {
341         echo refs/tags/debian/${v//\~/_}
342 }
343
344 t-pushed-good () {
345         local branch=$1
346         t-ref-dsc-dgit
347         t-refs-same \
348                 refs/heads/$branch \
349                 `t-v-tag` \
350                 refs/remotes/dgit/dgit/sid
351         t-refs-notexist \
352                 refs/heads/dgit/unstable \
353                 refs/remotes/dgit/dgit/unstable
354         (set -e; cd $tmp/git/$p.git
355          t-refs-same \
356                 refs/dgit/sid \
357                 `t-v-tag`
358          t-refs-notexist \
359                 refs/dgit/unstable
360         )
361         git verify-tag `t-v-tag`
362 }
363
364 t-822-field () {
365         local file=$1
366         local field=$2
367         perl -e '
368                 use Dpkg::Control::Hash;
369                 my $h = new Dpkg::Control::Hash allow_pgp=>1;
370                 $h->parse(\*STDIN,"'"$file"'");
371                 my $val = $h->{"'$field'"},"\n";
372                 die "'"$file $field"'" unless defined $val;
373                 print $val,"\n";
374         ' <$file
375 }
376
377 t-stunt-envvar () {
378         local var=$1
379         local tstunt=$2
380         eval '
381                 case "'$var'" in
382                 "$tstunt:"*)    ;;
383                 *":$tstunt:"*)  ;;
384                 *)              '$var'="$tstunt:$'$var'" ;;
385                 esac
386         '
387 }
388
389 t-tstunt () {
390         local tstunt=$tmp/tstunt
391         t-stunt-envvar PATH $tstunt
392         t-stunt-envvar PERLLIB $tstunt
393         local f
394         for f in "$@"; do
395                 f="./$f"
396                 local d="$tstunt/${f%/*}"
397                 mkdir -p $d
398                 ln -sf "$troot/tstunt/$f" "$d"/.
399         done
400 }
401
402 t-tstunt-parsechangelog () {
403         t-tstunt dpkg-parsechangelog Dpkg/Changelog/Parse.pm
404 }
405
406 t-ref-dsc-dgit () {
407         local dsc=${p}_${v}.dsc
408         local val=`t-822-field $tmp/incoming/$dsc Dgit`
409         perl -e '$_=shift @ARGV; die "$dsc Dgit $_ ?" unless m/^\w+\b/;' "$val"
410         t-ref-same-val $dsc "$val"
411 }
412
413 t-apply-diff () {
414         local v1=$1
415         local v2=$2
416         (cd $troot/pkg-srcs;
417          debdiff ${p}_${v1}.dsc ${p}_${v2}.dsc || test $? = 1) \
418          | patch -p1 -u
419 }
420
421 t-commit () {
422         local msg=$1
423         v=1.$revision
424         dch -v$v --distribution unstable "$1"
425         git add debian/changelog
426         debcommit
427         revision=$(( $revision + 1 ))
428 }
429
430 t-git-config () {
431         git config --global "$@"
432 }
433
434 t-drs () {
435         export DGIT_TEST_TROOT=$troot
436  t-git-config dgit-distro.test-dummy.git-url "ext::$troot/drs-git-ext %S "
437  t-git-config dgit-distro.test-dummy.git-check true
438  t-git-config dgit-distro.test-dummy.git-create true
439         cp $root/tests/gnupg/{dd.gpg,dm.gpg,dm.txt} $tmp/.
440         cp $root/tests/suites $tmp/.
441
442         drs_dispatch=$tmp/distro=test-dummy
443         mkdir $drs_dispatch
444         ln -sf $root $drs_dispatch/dgit-live
445         ln -sf $tmp/git $drs_dispatch/repos
446         ln -sf $tmp/suites $tmp/dm.txt $drs_dispatch/
447         mkdir -p $drs_dispatch/keyrings
448         ln -sf $tmp/dd.gpg $drs_dispatch/keyrings/debian-keyring.gpg
449         ln -sf $tmp/dm.gpg $drs_dispatch/keyrings/debian-maintainers.gpg
450         ln -sf /bin/true $drs_dispatch/policy-hook
451 }
452
453 t-dsd () {
454         t-drs
455  t-git-config dgit-distro.test-dummy.ssh "$troot/dsd-ssh"
456  t-git-config dgit-distro.test-dummy.git-check ssh-cmd
457  t-git-config dgit-distro.test-dummy.git-create true
458  t-git-config dgit-distro.test-dummy.git-url \
459                 "ext::$troot/dsd-ssh X %S /dgit/test-dummy/repos"
460
461  t-git-config dgit-distro.test-dummy.diverts.drs /drs
462  t-git-config dgit-distro.test-dummy/drs.ssh "$troot/ssh"
463  t-git-config dgit-distro.test-dummy/drs.git-url $tmp/git
464  t-git-config dgit-distro.test-dummy/drs.git-check ssh-cmd
465  t-git-config dgit-distro.test-dummy/drs.git-create ssh-cmd
466
467         echo 'no-such-package* drs' >$drs_dispatch/diverts
468 }
469
470 t-policy-admin () {
471         ${DGIT_INFRA_PFX}dgit-repos-admin-debian --repos $tmp/git "$@"
472 }
473
474 t-policy () {
475         local policyhook=$1
476         ln -sf ${DGIT_INFRA_PFX}$policyhook \
477                 $drs_dispatch/policy-hook
478 }
479
480 t-debpolicy () {
481         t-dsd
482         t-policy dgit-repos-policy-debian
483
484         mkdir $tmp/git
485         t-policy-admin create-db
486 }
487
488 t-policy-periodic () {
489         ${DGIT_REPOS_SERVER_TEST-dgit-repos-server} \
490                 test-dummy $drs_dispatch '' --cron
491 }
492
493 t-chain-test () {
494         local ct=$1
495         local d=${0%/*}
496         cd $root
497         export DGIT_TEST_TESTNAME="$testname"
498         export ADTTMP=$tmp
499         exec "$d/$ct"
500 }       
501
502 t-alt-test () {
503         local t=${0##*/}
504         t-${t%%-*}
505         t-chain-test "${t#*-}"
506 }