summaryrefslogtreecommitdiff
path: root/tests/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests/tests')
-rwxr-xr-xtests/tests/absurd-gitapply16
-rwxr-xr-xtests/tests/build-modes35
-rwxr-xr-xtests/tests/build-modes-asplit5
-rwxr-xr-xtests/tests/build-modes-gbp39
-rwxr-xr-xtests/tests/build-modes-gbp-asplit5
-rwxr-xr-xtests/tests/build-modes-sbuild18
-rwxr-xr-xtests/tests/clone-clogsigpipe10
-rwxr-xr-xtests/tests/clone-gitnosuite11
-rwxr-xr-xtests/tests/clone-nogit25
-rwxr-xr-xtests/tests/clone-reprepro33
-rwxr-xr-xtests/tests/debpolicy-dbretry67
-rwxr-xr-xtests/tests/debpolicy-newreject121
-rwxr-xr-xtests/tests/debpolicy-quilt-gbp4
-rwxr-xr-xtests/tests/distropatches-reject81
-rwxr-xr-xtests/tests/drs-clone-nogit4
-rwxr-xr-xtests/tests/drs-push-masterupdate50
-rwxr-xr-xtests/tests/drs-push-rejects209
-rwxr-xr-xtests/tests/dsd-clone-drs16
-rwxr-xr-xtests/tests/dsd-clone-nogit4
-rwxr-xr-xtests/tests/dsd-divert7
-rwxr-xr-xtests/tests/fetch-localgitonly20
-rwxr-xr-xtests/tests/fetch-somegit-notlast15
-rwxr-xr-xtests/tests/gbp-orig77
-rwxr-xr-xtests/tests/gitconfig38
-rwxr-xr-xtests/tests/import-dsc99
-rwxr-xr-xtests/tests/import-native69
-rwxr-xr-xtests/tests/import-nonnative17
-rwxr-xr-xtests/tests/import-tarbomb49
-rwxr-xr-xtests/tests/inarchivecopy79
-rwxr-xr-xtests/tests/mirror80
-rwxr-xr-xtests/tests/mirror-debnewgit26
-rwxr-xr-xtests/tests/mirror-private26
-rwxr-xr-xtests/tests/mismatches-contents24
-rwxr-xr-xtests/tests/mismatches-dscchanges34
-rwxr-xr-xtests/tests/multisuite57
-rwxr-xr-xtests/tests/newtag-clone-nogit4
-rwxr-xr-xtests/tests/oldnewtagalt25
-rwxr-xr-xtests/tests/oldtag-clone-nogit4
-rwxr-xr-xtests/tests/orig-include-exclude21
-rwxr-xr-xtests/tests/orig-include-exclude-chkquery33
-rwxr-xr-xtests/tests/overwrite-chkclog39
-rwxr-xr-xtests/tests/overwrite-junk22
-rwxr-xr-xtests/tests/overwrite-splitbrains27
-rwxr-xr-xtests/tests/overwrite-version20
-rwxr-xr-xtests/tests/push-buildproductsdir31
-rwxr-xr-xtests/tests/push-newpackage30
-rwxr-xr-xtests/tests/push-nextdgit25
-rwxr-xr-xtests/tests/quilt96
-rwxr-xr-xtests/tests/quilt-gbp61
-rwxr-xr-xtests/tests/quilt-gbp-build-modes13
-rwxr-xr-xtests/tests/quilt-gbp-build-modes-sbuild12
-rwxr-xr-xtests/tests/quilt-singlepatch39
-rwxr-xr-xtests/tests/quilt-splitbrains140
-rwxr-xr-xtests/tests/rpush31
-rwxr-xr-xtests/tests/spelling16
-rwxr-xr-xtests/tests/tag-updates37
-rwxr-xr-xtests/tests/test-list-uptodate11
-rwxr-xr-xtests/tests/trustingpolicy-replay85
-rwxr-xr-xtests/tests/unrepresentable52
-rwxr-xr-xtests/tests/version-opt32
60 files changed, 2376 insertions, 0 deletions
diff --git a/tests/tests/absurd-gitapply b/tests/tests/absurd-gitapply
new file mode 100755
index 0000000..90c44be
--- /dev/null
+++ b/tests/tests/absurd-gitapply
@@ -0,0 +1,16 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-archive example 1.0-1+absurd
+t-git-none
+
+t-expect-fail 'gbp pq import failed' \
+t-dgit --force-import-gitapply-no-absurd clone $p
+
+t-dgit clone $p
+
+cd $p
+grep moo moo
+
+t-ok
diff --git a/tests/tests/build-modes b/tests/tests/build-modes
new file mode 100755
index 0000000..c476ec8
--- /dev/null
+++ b/tests/tests/build-modes
@@ -0,0 +1,35 @@
+#!/bin/bash
+set -e
+. tests/lib
+. $troot/lib-build-modes
+
+bm-prep
+
+for act in \
+ 'build' \
+ 'build -S' \
+ 'build -b' \
+ 'build -B' \
+ 'build -A' \
+ 'build -F' \
+ 'build -g' \
+ 'build -G' \
+ build-source \
+; do
+ bm-guess-e-source-e-targets "$act"
+
+ case $act in
+ build-source)
+ cleanmodes="$cleanmodes_all"
+ ;;
+ *)
+ cleanmodes="$cleanmodes_default"
+ ;;
+ esac
+
+ real_act="$act"
+
+ bm-act-iterate
+done
+
+t-ok
diff --git a/tests/tests/build-modes-asplit b/tests/tests/build-modes-asplit
new file mode 100755
index 0000000..fa3bf8a
--- /dev/null
+++ b/tests/tests/build-modes-asplit
@@ -0,0 +1,5 @@
+#!/bin/bash
+set -e
+. tests/lib
+. $troot/lib-build-modes
+bm-alwayssplit
diff --git a/tests/tests/build-modes-gbp b/tests/tests/build-modes-gbp
new file mode 100755
index 0000000..50a6288
--- /dev/null
+++ b/tests/tests/build-modes-gbp
@@ -0,0 +1,39 @@
+#!/bin/bash
+set -e
+. tests/lib
+. $troot/lib-build-modes
+
+t-dependencies git-buildpackage
+
+quirk-clean-fixup () {
+ case $cleanmode in
+ dpkg-source*)
+ # git-buildpackage runs the clean target twice somehow
+ perl -i.unfixed -ne '
+ print unless
+ $_ eq $last &&
+ $_ eq "EXAMPLE RULES TARGET clean\n";
+ $last = $_;
+ ' $bmgot
+ ;;
+ esac
+}
+bm_quirk_before_diff=quirk-clean-fixup
+
+bm-prep
+
+for act in \
+ 'gbp-build -S' \
+ 'gbp-build -b' \
+ 'gbp-build -B' \
+ 'gbp-build -A' \
+ 'gbp-build -F' \
+ 'gbp-build -g' \
+ 'gbp-build -G' \
+; do
+ bm-guess-e-source-e-targets "$act"
+ real_act="$act --git-ignore-branch"
+ bm-act-iterate
+done
+
+t-ok
diff --git a/tests/tests/build-modes-gbp-asplit b/tests/tests/build-modes-gbp-asplit
new file mode 100755
index 0000000..fa3bf8a
--- /dev/null
+++ b/tests/tests/build-modes-gbp-asplit
@@ -0,0 +1,5 @@
+#!/bin/bash
+set -e
+. tests/lib
+. $troot/lib-build-modes
+bm-alwayssplit
diff --git a/tests/tests/build-modes-sbuild b/tests/tests/build-modes-sbuild
new file mode 100755
index 0000000..19dcc8a
--- /dev/null
+++ b/tests/tests/build-modes-sbuild
@@ -0,0 +1,18 @@
+#!/bin/bash
+set -e
+. tests/lib
+. $troot/lib-build-modes
+
+t-dependencies sbuild
+t-restrict x-dgit-schroot-build
+
+bm_quirk_after_act=bm-quirk-sbuild-after-act
+bm-prep
+
+act="sbuild -c build --no-arch-all"
+real_act="$act"
+
+bm-guess-e-source-e-targets "$act"
+bm-act-iterate
+
+t-ok
diff --git a/tests/tests/clone-clogsigpipe b/tests/tests/clone-clogsigpipe
new file mode 100755
index 0000000..4465cf3
--- /dev/null
+++ b/tests/tests/clone-clogsigpipe
@@ -0,0 +1,10 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-archive example 1.0-1.100
+t-git-none
+
+t-dgit clone $p
+
+t-ok
diff --git a/tests/tests/clone-gitnosuite b/tests/tests/clone-gitnosuite
new file mode 100755
index 0000000..83c996d
--- /dev/null
+++ b/tests/tests/clone-gitnosuite
@@ -0,0 +1,11 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-archive pari-extra 3-1
+t-git-none
+cp -a $tmp/git/_template $dgitrepo
+
+t-dgit clone $p
+
+t-ok
diff --git a/tests/tests/clone-nogit b/tests/tests/clone-nogit
new file mode 100755
index 0000000..e99dac3
--- /dev/null
+++ b/tests/tests/clone-nogit
@@ -0,0 +1,25 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-archive pari-extra 3-1
+t-git-none
+
+t-dgit clone $p
+
+cd $p
+t-cloned-fetched-good
+
+v=3-2~dummy1
+t-apply-diff 3-1 $v
+debcommit -a
+
+t-refs-same-start
+t-ref-head
+
+t-dgit --dpkg-buildpackage:-d build
+t-dgit push
+
+t-pushed-good dgit/sid
+
+t-ok
diff --git a/tests/tests/clone-reprepro b/tests/tests/clone-reprepro
new file mode 100755
index 0000000..063a138
--- /dev/null
+++ b/tests/tests/clone-reprepro
@@ -0,0 +1,33 @@
+#!/bin/bash
+set -e
+. tests/lib
+. $troot/lib-reprepro
+
+suitespecs+=' stable'
+
+t-dependencies reprepro
+t-reprepro
+t-tstunt-parsechangelog
+
+t-archive example 1.0-1
+t-git-none
+
+t-dgit clone $p
+
+cd $p
+t-cloned-fetched-good
+
+add_pari () {
+ local p
+ local v
+ local suite=stable
+ t-archive pari-extra 3-1
+}
+add_pari
+
+t-dgit fetch unstable,stable
+
+t-refs-same-start
+t-refs-same refs/remotes/dgit/sid,stable refs/remotes/dgit/sid
+
+t-ok
diff --git a/tests/tests/debpolicy-dbretry b/tests/tests/debpolicy-dbretry
new file mode 100755
index 0000000..a9f2334
--- /dev/null
+++ b/tests/tests/debpolicy-dbretry
@@ -0,0 +1,67 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-tstunt-parsechangelog
+
+t-debpolicy
+t-prep-newpackage example 1.0
+
+cd $p
+revision=1
+git tag start
+
+echo DUMMY >some-file
+git add some-file
+git commit -m some-file
+taint=`git rev-parse HEAD`
+t-policy-admin taint --global $taint dummy
+git reset --hard HEAD~
+
+t-commit 'Make something to autotaint'
+t-dgit build
+t-dgit push --new
+
+autotaint=`t-git-get-ref "refs/tags/$tagpfx/$v"`
+
+git reset --hard start
+t-commit 'Thing which will autotaint'
+t-dgit build
+
+fifo=$tmp/sqlite-cmds
+mkfifo $fifo
+exec 3<>$fifo
+sqlite3 -interactive $tmp/git/policy.sqlite3 0<$fifo 3>&- &
+sqlite3_pid=$!
+
+taintsout=$tmp/sqlite3.taints-out
+echo >&3 'begin;';
+echo >&3 ".output $taintsout"
+echo >&3 'select * from taints;';
+echo >&3 'create table dummy (x text);'
+
+t-dgit build
+
+while ! grep $taint $taintsout; do sleep 0.1; done
+
+DGIT_RPD_TEST_DBLOOP_HOOK='
+ print STDERR "DBLOOP HOOK $sleepy\n";
+ $poldbh->sqlite_busy_timeout(2500);
+ if ($sleepy > 2) {
+ system '\''
+ set -ex
+ echo >'"$fifo"' "rollback;"
+ touch '"$tmp/sqlite3.rolled-back"'
+ '\'' and die "$? $!";
+ }
+' \
+t-dgit push --deliberately-not-fast-forward
+
+exec 3>&-
+wait $sqlite3_pid
+
+ls $tmp/sqlite3.rolled-back
+
+t-policy-admin list-taints | tee $tmp/taints-list | grep $autotaint
+
+t-ok
diff --git a/tests/tests/debpolicy-newreject b/tests/tests/debpolicy-newreject
new file mode 100755
index 0000000..1fa6751
--- /dev/null
+++ b/tests/tests/debpolicy-newreject
@@ -0,0 +1,121 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-tstunt-parsechangelog
+
+t-debpolicy
+t-prep-newpackage example 1.0
+
+cd $p
+revision=1
+git tag start
+t-dgit setup-mergechangelogs
+
+echo FORBIDDEN >debian/some-file
+git add debian/some-file
+t-commit 'Commit a forbidden thing'
+
+bad=`git rev-parse HEAD:debian/some-file`
+t-policy-admin taint --global "$bad" "forbidden for testing"
+t-policy-admin taint --global "$bad" "forbidden for testing - again"
+
+t_expect_push_fail_hook+='
+t-git-objects-not-present "" $bad
+'
+
+t-dgit build
+t-expect-push-fail 'forbidden for testing' \
+t-dgit push --new
+t-git-dir-check enoent
+
+git reset --hard start
+t-commit 'will vanish from NEW'
+vanished=$v
+t-dgit build
+t-dgit push --new
+t-git-dir-check secret
+
+t-policy-periodic
+t-git-dir-check secret
+
+# pretend it vanished from new:
+rm $tmp/incoming/*
+t-archive-none example
+
+t-git-dir-time-passes
+
+t-policy-periodic
+t-git-dir-check enoent
+
+t-commit 'should require --deliberately...questionable'
+t-dgit build
+
+t-expect-push-fail E:"tag $tagpfx/${vanished//./\\.} referred to this object.*all previously pushed versions were found to have been removed" \
+t-dgit push --new
+t-git-dir-check enoent
+
+vanished=$v
+
+t-dgit push --new --deliberately-include-questionable-history
+t-git-dir-check secret
+
+t-policy-periodic
+t-git-dir-check secret
+
+t-archive-process-incoming new
+t-git-dir-time-passes
+
+t-policy-periodic
+t-git-dir-check secret
+
+oldobj=`git rev-parse HEAD`
+git reset --hard start
+t-commit 'should require --deliberately..not-ff'
+t-dgit build
+
+t-expect-push-fail "HEAD is not a descendant of the archive's version" \
+t-dgit push
+
+t-expect-push-fail \
+ "Package is in NEW and has not been accepted or rejected yet" \
+t-dgit --deliberately-TEST-dgit-only-not-fast-forward push
+
+t-dgit --deliberately-not-fast-forward push
+
+cd $dgitrepo
+t-expect-push-fail "Not a valid object name" \
+git cat-file -p $oldobj
+cd $tmp/$p
+
+t-commit 'Still not accepted, will override taint'
+t-dgit build
+t-expect-push-fail \
+ "Package is in NEW and has not been accepted or rejected yet" \
+t-dgit push
+
+t-dgit push --deliberately-include-questionable-history
+
+t-archive-process-incoming sid
+
+t-commit 'Check taint is no longer there'
+t-dgit build
+t-dgit push
+
+git checkout -b stoats $tagpfx/$vanished
+t-commit 'Simulate accidentally building on rejected version'
+t-dgit build
+t-expect-push-fail "HEAD is not a descendant of the archive's version" \
+t-dgit push
+
+: "check that uploader can't force it now"
+t-expect-push-fail "not fast forward on dgit branch" \
+t-dgit --deliberately-not-fast-forward push
+
+t-dgit pull
+t-dgit build
+t-expect-push-fail \
+ 'Reason: rewound suite sid; --deliberately-not-fast-forward specified' \
+t-dgit push
+
+t-ok
diff --git a/tests/tests/debpolicy-quilt-gbp b/tests/tests/debpolicy-quilt-gbp
new file mode 100755
index 0000000..915f9d3
--- /dev/null
+++ b/tests/tests/debpolicy-quilt-gbp
@@ -0,0 +1,4 @@
+#!/bin/bash
+set -e
+. tests/lib
+t-alt-test
diff --git a/tests/tests/distropatches-reject b/tests/tests/distropatches-reject
new file mode 100755
index 0000000..75f43db
--- /dev/null
+++ b/tests/tests/distropatches-reject
@@ -0,0 +1,81 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-archive ruby-rails-3.2 3.2.6-1
+t-git-none
+
+cp $troot/pkg-srcs/${p}_3.2.6.orig.tar.gz .
+t-worktree test
+cd $p
+
+t-dgit --quilt=smash -wgf quilt-fixup
+
+build () {
+ t-dgit -wg --dpkg-buildpackage:-d build
+}
+
+expect-fail-distro-series () {
+ local why=$1; shift
+ t-expect-fail \
+ E:"Found active distro-specific series file.*(.*$why.*)" \
+ "$@"
+}
+
+mkdir -p debian/patches
+
+cat >debian/patches/boo <<'END'
+Description: add boo
+Author: Ian Jackson <ijackson@chiark.greenend.org.uk>
+
+---
+
+--- a/boo
++++ b/boo
+@@ -0,0 +1 @@
++content
+END
+
+echo boo >debian/patches/test-dummy.series
+
+git add debian/patches/boo
+git add debian/patches/test-dummy.series
+t-commit 'Add boo (on test-dummy)' 3.2.6-2
+
+expect-fail-distro-series 'distro being accessed' \
+build
+
+defaultvendor=$(perl -we '
+ use Dpkg::Vendor;
+ print lc Dpkg::Vendor::get_current_vendor
+')
+git mv debian/patches/test-dummy.series \
+ debian/patches/$defaultvendor.series
+t-commit 'Move boo (to default vendor)' 3.2.6-3
+
+expect-fail-distro-series 'current vendor' \
+build
+
+git mv debian/patches/$defaultvendor.series \
+ debian/patches/test-dummy-aside.series
+t-commit 'Move boo (to test-dummy-aside)' 3.2.6-4
+
+build
+
+DEB_VENDOR=test-dummy-aside \
+expect-fail-distro-series DEB_VENDOR \
+t-dgit push
+
+t-dgit push
+
+cd ..
+perl -i~ -pe 's/^Dgit:.*\n//' incoming/${p}_${v}.dsc
+t-archive-process-incoming sid
+
+rm -rf $p
+
+DEB_VENDOR=test-dummy-aside \
+expect-fail-distro-series DEB_VENDOR \
+t-dgit clone $p
+
+t-ok
diff --git a/tests/tests/drs-clone-nogit b/tests/tests/drs-clone-nogit
new file mode 100755
index 0000000..915f9d3
--- /dev/null
+++ b/tests/tests/drs-clone-nogit
@@ -0,0 +1,4 @@
+#!/bin/bash
+set -e
+. tests/lib
+t-alt-test
diff --git a/tests/tests/drs-push-masterupdate b/tests/tests/drs-push-masterupdate
new file mode 100755
index 0000000..c8a5c5a
--- /dev/null
+++ b/tests/tests/drs-push-masterupdate
@@ -0,0 +1,50 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-drs
+t-tstunt-parsechangelog
+
+t-prep-newpackage example 1.0
+
+cd $p
+
+git tag common-ancestor
+
+revision=1
+t-dgit build
+t-dgit push --new
+
+push_and_check () {
+ git push $dgitrepo $1
+
+ oldmaster=`cd $dgitrepo && t-git-get-ref refs/heads/master`
+
+ t-refs-same-start
+ git checkout master
+ t-commit 'Empty update'
+ t-dgit build
+ t-dgit push --new
+
+ t-pushed-good master
+}
+
+t-check-master-undisturbed () {
+ local master=`t-git-get-ref refs/heads/master`
+ if [ x$master != x$oldmaster ]; then fail "bad update to master"; fi
+}
+
+t_check_pushed_master=t-check-master-undisturbed
+
+git checkout -b divergent common-ancestor
+git commit --allow-empty -m 'Has common ancestor'
+git push $dgitrepo HEAD:master
+
+push_and_check HEAD:master
+
+git checkout --orphan newroot
+git commit --allow-empty -m 'Has no common ancestor'
+
+push_and_check +HEAD:master
+
+t-ok
diff --git a/tests/tests/drs-push-rejects b/tests/tests/drs-push-rejects
new file mode 100755
index 0000000..8c4ad83
--- /dev/null
+++ b/tests/tests/drs-push-rejects
@@ -0,0 +1,209 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-drs
+t-git-none
+
+t-select-package pari-extra
+t-worktree drs
+
+cd $p
+
+mustfail () {
+ local mpat="$1"; shift
+ t-expect-push-fail "$mpat" \
+ git push origin "$@"
+}
+
+mustsucceed () {
+ t-reporefs pre-push
+ git push origin "$@"
+ t-reporefs post-push
+ if diff $tmp/show-refs.{pre,post}-push >$tmp/show-refs.diff; then
+ fail "no refs updated"
+ fi
+}
+
+prep () {
+ local suite=$1
+ csuite=$2
+ cp $tmp/masters/* $tmp/.
+ tag_signer='-u Senatus'
+ tag_message="$p release $version for $suite ($csuite) [dgit]"
+ re-prep
+}
+re-prep () {
+ tag_name=$tagpfx/$version
+ push_spec1="HEAD:refs/dgit/$csuite"
+ push_spec2="refs/tags/$tag_name"
+ push_spec="$push_spec1 $push_spec2"
+}
+mktag () {
+ t-git-next-date
+ git tag -f $tag_signer -m "$tag_message" $tag_name "$@"
+}
+
+mkdir $tmp/masters
+cp $tmp/d[dm].* $tmp/masters
+
+version=3-2_dummy1
+
+prep unstable sid
+tag_signer='-a'
+mktag
+mustfail 'missing signature' $push_spec
+
+git cat-file tag $tag_name >goodtag
+
+for h in object type tag; do
+ for how in missing dupe; do
+
+ case $how in
+ missing) perl -pe 's/^tag /wombat$&/ if 1..m/^$/' <goodtag >badtag ;;
+ dupe) perl -pe 'print if 1..m/^$/ and m/^'$h' /' <goodtag >badtag ;;
+ esac
+
+ rm -f badtag.asc
+ gpg --detach-sign --armor -u Senatus badtag
+ cat badtag.asc >>badtag
+
+ set +e
+ LC_MESSAGES=C git hash-object -w -t tag badtag >badtag.hash 2>badtag.err
+ rc=$?
+ set -e
+
+ if [ $rc = 128 ] && grep 'fatal: corrupt tag' badtag.err; then
+ continue
+ elif [ $rc != 0 ]; then
+ cat badtag.err
+ fail "could not make tag"
+ fi
+
+ read <badtag.hash badtag
+ git update-ref refs/tags/$tag_name $badtag
+
+ mustfail 'multiple headers '$h' in signed tag object' $push_spec
+
+ t-expect-fsck-fail $badtag
+ done
+done
+
+prep unstable sid
+tag_message='something'
+mktag
+mustfail 'tag message not in expected format' $push_spec
+
+prep unstable sid
+mktag
+mustfail 'sid != sponge' HEAD:refs/dgit/sponge $push_spec2
+
+# fixme test --sig-policy-url string
+# fixme cannot test reject "signature is not of type 00!";
+
+prep unstable sid
+mktag
+mustfail 'push is missing tag ref update' $push_spec1
+mustfail 'push is missing head ref update' +$push_spec2
+mustfail 'pushing unexpected ref' $push_spec HEAD:refs/wombat
+mustfail 'pushing multiple heads' $push_spec HEAD:refs/dgit/wombat
+mustfail E:'pushing multiple tags|pushing too many similar tags' \
+ $push_spec HEAD:refs/tags/$tagpfx/wombat
+
+prep unstable sid
+mktag
+echo woody >$tmp/suites
+mustfail 'unknown suite' $push_spec
+cp $root/tests/suites $tmp/.
+
+# fixme:
+# or reject "command string not understood";
+# reject "unknown method" unless $mainfunc;
+
+
+prep unstable sid
+mktag
+cp $tmp/dm.gpg $tmp/dd.gpg
+mustfail 'key not found in keyrings' $push_spec
+
+prep unstable sid
+mktag HEAD~
+mustfail 'tag refers to wrong commit' $push_spec
+
+prep unstable sid
+mktag HEAD~:
+mustfail 'tag refers to wrong kind of object' $push_spec
+
+prep unstable sid
+tag_name=$tagpfx/wombat
+mktag
+#git update-ref $tagpfx/$version $tagpfx/wombat
+mustfail 'tag name in tag is wrong' \
+ refs/tags/$tagpfx/wombat:refs/tags/$tagpfx/$version $push_spec1
+
+echo ====
+badcommit=$(
+ git cat-file commit HEAD | \
+ perl -pe 's/^committer.*\n//' | \
+ git hash-object -w -t commit --stdin
+)
+t-expect-fsck-fail $badcommit
+git checkout -b broken $badcommit
+prep unstable sid
+mktag
+mustfail "corrupted object $badcommit" $push_spec
+
+git checkout dgit/sid
+prep unstable sid
+mktag
+mustsucceed $push_spec # succeeds
+
+mktag
+mustfail 'push is missing head ref update' $push_spec1 +$push_spec2
+
+git commit --allow-empty -m 'Dummy update'
+mktag
+mustfail 'not replacing previously-pushed version' +$push_spec1 +$push_spec2
+
+t-newtag
+re-prep
+mktag
+mustfail 'not replacing previously-pushed version' +$push_spec1 +$push_spec2
+
+git reset --hard HEAD~
+
+prep_dm_mangle () {
+ prep unstable sid
+ perl -i.bak -pe '
+ next unless m/^fingerprint: 3A82860837A0CD32/i../^$/;
+ ' -e "$1" $tmp/dm.txt
+ tag_signer='-u Populus'
+ mktag
+}
+
+git commit --amend --message 'Make it not a fast forward'
+version=3-2_dummy2
+prep unstable sid
+mktag
+mustfail 'not fast forward on dgit branch' +$push_spec1 +$push_spec2
+
+git checkout v2
+version=3-2_dummy2
+
+prep_dm_mangle ''
+perl -i.bak -ne 'print if 1..s/(pari-extra).*\n/$1/' $tmp/dm.txt
+mustfail '' $push_spec # malformed (truncated) dm.txt; don't care about msg
+
+prep_dm_mangle 's/allow:/asponge:/i'
+mustfail 'missing Allow section in permission' $push_spec
+
+prep_dm_mangle 's/\bpari-extra\b/sponge/i'
+mustfail "package $p not allowed for key" $push_spec
+
+prep_dm_mangle 'y/0-9/5-90-4/ if m/^fingerprint:/i'
+mustfail "not in permissions list although in keyring" $push_spec
+
+prep_dm_mangle ''
+mustsucceed $push_spec # succeeds
+
+t-ok
diff --git a/tests/tests/dsd-clone-drs b/tests/tests/dsd-clone-drs
new file mode 100755
index 0000000..4346579
--- /dev/null
+++ b/tests/tests/dsd-clone-drs
@@ -0,0 +1,16 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-restrict x-dgit-intree-only
+t-restrict x-dgit-git-only
+
+t-dsd
+
+cd $tmp
+t-dgit clone-dgit-repos-server drs-cloned
+
+cd drs-cloned
+ls -al infra/dgit-repos-server
+
+t-ok
diff --git a/tests/tests/dsd-clone-nogit b/tests/tests/dsd-clone-nogit
new file mode 100755
index 0000000..915f9d3
--- /dev/null
+++ b/tests/tests/dsd-clone-nogit
@@ -0,0 +1,4 @@
+#!/bin/bash
+set -e
+. tests/lib
+t-alt-test
diff --git a/tests/tests/dsd-divert b/tests/tests/dsd-divert
new file mode 100755
index 0000000..3020a56
--- /dev/null
+++ b/tests/tests/dsd-divert
@@ -0,0 +1,7 @@
+#!/bin/bash
+set -e
+. tests/lib
+t-dsd
+rm $drs_dispatch/repos
+echo '* drs' >>$drs_dispatch/diverts
+t-chain-test fetch-somegit-notlast
diff --git a/tests/tests/fetch-localgitonly b/tests/tests/fetch-localgitonly
new file mode 100755
index 0000000..7d603b2
--- /dev/null
+++ b/tests/tests/fetch-localgitonly
@@ -0,0 +1,20 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-archive pari-extra 3-2~dummy1
+t-git-none
+t-worktree 3-1
+cd $p
+old=`git rev-parse HEAD`
+
+# pretend that we previously fetched 3-1 (otherwise, dgit
+# is entitled to, and will, make a new history)
+git update-ref refs/remotes/dgit/dgit/sid refs/heads/dgit/sid
+
+t-dgit pull
+
+t-cloned-fetched-good
+t-has-ancestor $old
+
+t-ok
diff --git a/tests/tests/fetch-somegit-notlast b/tests/tests/fetch-somegit-notlast
new file mode 100755
index 0000000..63abe8a
--- /dev/null
+++ b/tests/tests/fetch-somegit-notlast
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+set -e
+. tests/lib
+
+t-git pari-extra 3-1
+t-archive pari-extra 3-2~dummy1
+
+t-dgit clone $p
+cd $p
+
+t-cloned-fetched-good
+t-has-ancestor debian/3-1
+
+t-ok
diff --git a/tests/tests/gbp-orig b/tests/tests/gbp-orig
new file mode 100755
index 0000000..beea121
--- /dev/null
+++ b/tests/tests/gbp-orig
@@ -0,0 +1,77 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-tstunt-parsechangelog
+t-tstunt-debuild
+t-tstunt-lintian
+
+t-archive-none example
+t-git-none
+t-worktree 1.0
+
+cd $p
+
+: '----- construct an unpatched branch with patches -----'
+
+git checkout patch-queue/quilt-tip
+gbp pq export
+: 'now on quilt-tip'
+git add debian/patches
+git commit -m 'Commit patch queue'
+
+: '----- construct an upstream branch -----'
+
+git checkout --orphan upstream
+git reset --hard
+git clean -xdf
+
+tar --strip-components=1 -xf $troot/pkg-srcs/${p}_1.0.orig.tar.gz
+
+mkdir docs
+cd docs
+tar --strip-components=1 -xf $troot/pkg-srcs/${p}_1.0.orig-docs.tar.gz
+cd ..
+
+git add -Af .
+git commit -m 'Import 1.0'
+git tag upstream/1.0
+
+git checkout quilt-tip
+t-git-pseudo-merge upstream
+
+v=1.0-1
+
+: '----- let gbp build a .orig for comparison -----'
+
+gbp buildpackage --git-ignore-branch --git-no-sign-tags -us -uc
+
+mkdir ../gbp-output
+mv ../*1.0* ../gbp-output/.
+rm -f ../*.changes
+
+: '----- now do it ourselves -----'
+
+t-dgit -wgf --dgit-view-save=split.b gbp-build --git-ignore-branch
+
+t-dgit -wgf --quilt=gbp clean # gbp leaves dirty trees :-/
+
+t-dgit -wgf --dgit-view-save=split.p --quilt=gbp push --new
+
+t-gbp-pushed-good
+
+: '----- check .origs are the same -----'
+
+# if gbp weren't weird about .gitignore we could just debdiff the .dscs
+
+for d in . gbp-output; do
+ cd $tmp/$d
+ mkdir tar-x
+ cd tar-x
+ tar zxf ../${p}_${v%-*}.orig.tar.gz
+done
+
+cd $tmp
+diff -ruN gbp-output/tar-x tar-x
+
+t-ok
diff --git a/tests/tests/gitconfig b/tests/tests/gitconfig
new file mode 100755
index 0000000..12b342b
--- /dev/null
+++ b/tests/tests/gitconfig
@@ -0,0 +1,38 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-tstunt-parsechangelog
+
+t-prep-newpackage example 1.0
+
+cd $p
+
+t-dgit clean | tee ../t.output
+grep 'EXAMPLE RULES TARGET clean' ../t.output
+
+t-git-config dgit.default.clean-mode git
+
+t-dgit clean | tee ../t.output
+
+set +e
+grep 'EXAMPLE RULES TARGET clean' ../t.output
+rc=$?
+set -e
+test $rc = 1
+
+git config dgit.default.clean-mode dpkg-source-d
+
+t-dgit clean | tee ../t.output
+grep 'EXAMPLE RULES TARGET clean' ../t.output
+
+t-git-config dgit.default.opts-dpkg-buildpackage --dgit-fail-global
+git config --add dgit.default.opts-dpkg-buildpackage --dgit-fail-foo
+git config --add dgit.default.opts-dpkg-buildpackage --dgit-fail-bar
+
+t-expect-fail '--dgit-fail-global --dgit-fail-foo --dgit-fail-bar' \
+t-dgit clean
+
+t-dgit -cdgit.default.clean-mode=none clean
+
+t-ok
diff --git a/tests/tests/import-dsc b/tests/tests/import-dsc
new file mode 100755
index 0000000..b86eef6
--- /dev/null
+++ b/tests/tests/import-dsc
@@ -0,0 +1,99 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-setup-import examplegit
+
+p=example
+
+check-import () {
+ path=$1
+ v=$2
+ opts=$3
+ branch=t.$v
+
+ dsc=${path}/${p}_${v}.dsc
+ t-dgit $opts import-dsc $dsc $branch
+
+ git checkout $branch
+
+ check-imported $dsc
+}
+
+check-imported () {
+ local dsc=$1
+ (
+ rm -rf ../t.unpack
+ mkdir ../t.unpack
+ cd ../t.unpack
+ dpkg-source -x $dsc
+ )
+
+ git checkout HEAD~0
+ git branch -D u.$v ||:
+ git checkout -b u.$v $branch
+ git rm -rf .
+ git clean -xdf
+ cp -al ../t.unpack/*/. .
+ git add -Af .
+
+ git diff --stat --exit-code
+}
+
+cd $p
+
+check-import ../mirror/pool/main 1.2
+
+dgit12=`git rev-parse HEAD`
+
+dsc2=../mirror/pool/main/${p}_2.0.dsc
+
+git checkout $branch
+t-expect-fail 'is checked out - will not update' \
+t-dgit import-dsc $dsc2 $branch
+
+git checkout HEAD~0
+
+t-expect-fail 'Not fast forward' \
+t-dgit import-dsc $dsc2 $branch
+
+t-expect-fail 'Not fast forward' \
+t-dgit import-dsc $dsc2 ..$branch
+
+t-dgit import-dsc $dsc2 +$branch
+check-imported $dsc2
+
+cd ..
+mkdir $p.2
+cd $p.2
+
+git init
+
+check-import $troot/pkg-srcs 1.0-1
+
+t-expect-fail "Your git tree does not have that object" \
+check-import ../mirror/pool/main 1.2
+
+check-import ../mirror/pool/main 1.2 --force-import-dsc-with-dgit-field
+
+v=1.0-1.100
+dsc2=$troot/pkg-srcs/${p}_${v}.dsc
+
+t-expect-fail E:'Branch.*already exists' \
+t-dgit import-dsc $dsc2 $branch
+
+git branch merge-reset
+t-dgit import-dsc $dsc2 ..$branch
+t-has-ancestor merge-reset $branch
+
+git push . +merge-reset:$branch
+
+t-dgit import-dsc $dsc2 +$branch
+
+mb=$(t-git-merge-base merge-reset $branch)
+test "x$mb" = x
+
+t-expect-fail 'signature check failed' \
+t-dgit import-dsc --require-valid-signature $dsc2 +$branch
+
+t-ok
diff --git a/tests/tests/import-native b/tests/tests/import-native
new file mode 100755
index 0000000..1e09343
--- /dev/null
+++ b/tests/tests/import-native
@@ -0,0 +1,69 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-setup-import examplegit
+t-tstunt-parsechangelog
+
+mkdir $tmp/aside
+
+versions=""
+for f in $(find $tmp/mirror -name \*.dsc | sort); do
+ perl -i -pe '
+ $_="" if m/^-----BEGIN PGP SIGNED/..!m/\S/;
+ $_="" if m/^-----BEGIN PGP SIGNATURE/..0;
+ $_="" if m/^Dgit: /;
+ ' $f
+ mv $f $tmp/aside/.
+ version="${f%.dsc}"
+ version="${version##*/${p}_}"
+ versions+=" $version"
+done
+
+echo $versions
+
+rm -rf $tmp/git/$p.git
+t-archive-none $p
+
+cd $p
+
+lrref=refs/remotes/dgit/dgit/sid
+
+git update-ref -d $lrref
+
+for v in $versions; do
+ git show-ref
+
+ mv $tmp/aside/${p}_${v}.dsc $tmp/mirror/pool/main/
+ t-archive-query
+
+ t-dgit fetch
+
+ set +e
+ git merge-base HEAD remotes/dgit/dgit/sid
+ rc=$?
+ set -e
+ test $rc = 1
+
+ t-refs-same-start
+ t-ref-same-exact refs/tags/$p/$v:
+ t-ref-same-exact refs/remotes/dgit/dgit/sid:
+
+ first_imp=first-import/$v
+ git tag first-import/$v $lrref
+
+ if [ "$lastv_imp" ]; then
+ git update-ref $lrref $lastv_imp
+
+ t-git-next-date
+ t-dgit fetch
+
+ t-refs-same-start
+ t-ref-same $first_imp
+ t-ref-same $lrref
+ fi
+
+ lastv_imp=$this_imp
+done
+
+t-ok
diff --git a/tests/tests/import-nonnative b/tests/tests/import-nonnative
new file mode 100755
index 0000000..3568563
--- /dev/null
+++ b/tests/tests/import-nonnative
@@ -0,0 +1,17 @@
+#!/bin/bash
+set -e
+. tests/lib
+. $troot/lib-import-chk
+
+t-tstunt-parsechangelog
+
+# 1.0 with diff
+t-import-chk pari-extra 3-1
+
+# 3.0 (quilt), multiple patches, multiple origs
+t-import-chk example 1.0-1
+
+# 3.0 (quilt), single-debian-patch, one orig
+t-import-chk sunxi-tools 1.2-2.~~dgittest
+
+t-ok
diff --git a/tests/tests/import-tarbomb b/tests/tests/import-tarbomb
new file mode 100755
index 0000000..9b7f65a
--- /dev/null
+++ b/tests/tests/import-tarbomb
@@ -0,0 +1,49 @@
+#!/bin/bash
+set -e
+. tests/lib
+. $troot/lib-import-chk
+
+t-tstunt-parsechangelog
+
+mangle1 () {
+ rm -f ${1}_*
+ t-import-chk1 "$@"
+ cd $tmp/mirror/pool/main
+ dpkg-source -x ${p}_${v}.dsc td
+ orig=${p}_${v%-*}.orig.tar.gz
+ tar zxf $orig
+ rm $orig ${p}_${v}.*
+ cd $p
+ mkdir urk
+ echo urk >urk/urk
+ export GZIP=-1
+}
+mangle2 () {
+ cd ..
+ dpkg-source -b td
+ rm -rf $p td
+ cd $tmp
+ t-archive-none $p
+ t-archive-query
+ t-import-chk2
+}
+
+# 3.0 (quilt), multiple patches, tarbomb orig
+mangle1 example 1.0-1
+tar zvcf ../$orig *
+mangle2
+
+# 3.0 (quilt), multiple patches, tarbomb orig with dot
+mangle1 example 1.0-1
+tar zvcf ../$orig .
+mangle2
+
+# 3.0 (quilt), multiple patches, tarbomb orig with dot and .git and .pc
+mangle1 example 1.0-1
+git init
+mkdir .pc
+echo SPONG >.pc/SPONG
+tar zvcf ../$orig .
+mangle2
+
+t-ok
diff --git a/tests/tests/inarchivecopy b/tests/tests/inarchivecopy
new file mode 100755
index 0000000..b1e0c5f
--- /dev/null
+++ b/tests/tests/inarchivecopy
@@ -0,0 +1,79 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-setup-import examplegit
+t-tstunt-parsechangelog
+
+cd $p
+git checkout -b dgit/stable dgit/dgit/stable
+cd ..
+
+t-inarchive-copy () {
+ local vm=$1
+ local from=${2:-sid}
+ local to=${3:-stable}
+ egrep "^${vm//./\\.}" aq/package.$from.$p >>aq/package.$to.$p
+ t-aq-archive-updated $to $p
+}
+
+copy-check-good () {
+ git diff $vtag
+ t-refs-same refs/remotes/dgit/dgit/$tosuite
+ t-ref-head
+ t-has-parent-or-is HEAD $vtag
+}
+
+copy-check () {
+ local vm=$1
+ local tosuite=${2:-stable}
+ t-inarchive-copy $vm '' $tosuite
+
+ vtag=$(v=$vm t-v-tag)
+
+ cd $p
+ t-refs-same-start
+ t-dgit fetch $tosuite
+ git merge --ff-only dgit/dgit/$tosuite
+
+ copy-check-good
+ local fetched=$(t-sametree-parent HEAD)
+ cd ..
+
+ rm -rf example.cloned
+ t-dgit clone $p $tosuite example.cloned
+
+ cd example.cloned
+ t-refs-same-start
+ copy-check-good
+ local cloned=$(t-sametree-parent HEAD)
+ cd ..
+
+ rm -rf example.initd
+ mkdir example.initd
+ cd example.initd
+ git init
+ t-refs-same-start
+ t-dgit -p $p fetch $tosuite
+ git reset --hard refs/remotes/dgit/dgit/$tosuite
+ copy-check-good
+ local initd=$(t-sametree-parent HEAD)
+ cd ..
+
+ t-refs-same-start
+ t-ref-same-val fetched $fetched
+ t-ref-same-val cloned $cloned
+ t-ref-same-val initd $initd
+}
+
+copy-check 2.0
+
+copy-check 2.1
+
+cd $p
+git checkout -b dgit/testing $(v=1.1 t-v-tag)
+cd ..
+
+copy-check 2.1 testing
+
+t-ok
diff --git a/tests/tests/mirror b/tests/tests/mirror
new file mode 100755
index 0000000..4947688
--- /dev/null
+++ b/tests/tests/mirror
@@ -0,0 +1,80 @@
+#!/bin/bash
+set -e
+. tests/lib
+. $troot/lib-mirror
+
+t-dependencies rsync
+
+t-drs
+
+: ---- "basic test" ----
+
+t-tstunt-parsechangelog
+t-prep-newpackage example 1.0
+
+t-mirror-setup
+
+cd $p
+revision=1
+t-dgit build
+t-dgit push --new
+
+t-check-mirrored
+
+: ---- "stunt ssh test" ----
+
+sentinel=$tmp/stunt-ssh-sentinel
+
+cat <<END >$tmp/stunt-ssh
+#!/bin/sh
+set -ex
+: $sentinel
+cat >&2 $sentinel
+shift # eat HOST
+sh -c "\$*"
+END
+chmod +x $tmp/stunt-ssh
+
+t-mirror-set rsyncssh=$tmp/stunt-ssh
+t-mirror-set remoterepos=HOST:$reposmirror
+
+# mirror should fail due to lack of stunt-ssh-sentinel
+
+t-commit-build-push-expect-log "stunt ssh test" \
+ E:'mirror hook failed: .*exited'
+
+ls -al $queuedir/$p.a
+t-check-not-mirrored
+
+touch $sentinel
+
+t-mirror-hook backlog
+t-check-mirrored
+
+: ----- "stall timeout test" -----
+
+rm -f $sentinel
+mkfifo $sentinel
+
+t-mirror-set hooktimeout=5
+
+t-commit-build-push-expect-log "stall timeout test" \
+ E:'mirror hook failed: .*timeout'
+
+t-check-not-mirrored
+
+exec 3<>$sentinel
+exec 3>&-
+
+attempts=100
+while [ -f $queuedir/$p.lock ]; do
+ if [ $attempts = 0 ]; then \
+ fail "timed out waiting for lock to go away"
+ fi
+ attempts=$(( $attempts - 1 ))
+ sleep 0.1
+done
+
+t-check-mirrored
+
+t-ok
diff --git a/tests/tests/mirror-debnewgit b/tests/tests/mirror-debnewgit
new file mode 100755
index 0000000..59b96ef
--- /dev/null
+++ b/tests/tests/mirror-debnewgit
@@ -0,0 +1,26 @@
+#!/bin/bash
+set -e
+. tests/lib
+. $troot/lib-mirror
+
+t-dependencies rsync
+
+t-debpolicy
+
+t-archive pari-extra 3-1
+t-git-none
+
+t-mirror-setup
+
+t-dgit clone $p
+
+cd $p
+t-cloned-fetched-good
+
+t-commit 'test commit' 3-2
+
+t-dgit build
+t-dgit push
+t-check-mirrored
+
+t-ok
diff --git a/tests/tests/mirror-private b/tests/tests/mirror-private
new file mode 100755
index 0000000..c26ba89
--- /dev/null
+++ b/tests/tests/mirror-private
@@ -0,0 +1,26 @@
+#!/bin/bash
+set -e
+. tests/lib
+. $troot/lib-mirror
+
+t-dependencies rsync
+
+t-debpolicy
+
+t-tstunt-parsechangelog
+t-prep-newpackage example 1.0
+
+t-mirror-setup
+
+cd $p
+revision=1
+
+t-reporefs master
+
+t-dgit build
+t-dgit push --new
+
+t-check-not-mirrored
+t-files-notexist $reposmirror/$p.*
+
+t-ok
diff --git a/tests/tests/mismatches-contents b/tests/tests/mismatches-contents
new file mode 100755
index 0000000..ea0d724
--- /dev/null
+++ b/tests/tests/mismatches-contents
@@ -0,0 +1,24 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-tstunt-parsechangelog
+
+t-prep-newpackage example 1.0
+
+ln -s $troot/pkg-srcs/${p}_${v%-*}.orig.tar.* .
+
+cd $p
+
+v=1.0-1
+dch -v $v -D unstable -m 'Make a revision'
+echo foo >us-file
+git add us-file debian/changelog
+git commit -m "Commit $v"
+
+t-dgit build-source
+
+t-expect-fail 'debian/TRASH' \
+t-dgit push --new
+
+t-ok
diff --git a/tests/tests/mismatches-dscchanges b/tests/tests/mismatches-dscchanges
new file mode 100755
index 0000000..85c7086
--- /dev/null
+++ b/tests/tests/mismatches-dscchanges
@@ -0,0 +1,34 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-tstunt-parsechangelog
+
+t-prep-newpackage example 1.0
+
+cd $p
+revision=1
+
+check () {
+ local fext=$1
+ local emsgpat=$2
+
+ t-dgit -wgf build-source
+
+ perl -i~ -pe 's/^ ([0-9a-f])/ sprintf " %x", (hex $1)^1 /e' \
+ ../*.$fext
+
+ t-expect-fail "$emsgpat" \
+ t-dgit -wgf push --new
+}
+
+check dsc E:'dpkg-source.*error.*checksum'
+check changes E:'dgit.*hash or size.*varies'
+
+# and finally check that our test is basically working
+
+t-dgit -wgf build-source
+
+t-dgit -wgf push --new
+
+t-ok
diff --git a/tests/tests/multisuite b/tests/tests/multisuite
new file mode 100755
index 0000000..d39475b
--- /dev/null
+++ b/tests/tests/multisuite
@@ -0,0 +1,57 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-setup-import examplegit
+t-tstunt-parsechangelog
+
+cd $p
+
+rsta=$(t-git-get-ref refs/remotes/dgit/dgit/stable)
+rsid=$(t-git-get-ref refs/remotes/dgit/dgit/sid)
+
+multi-good () {
+ t-refs-same-start
+ t-refs-same refs/remotes/dgit/dgit/stable
+ t-ref-same-val "previous stable" $rsta
+
+ t-refs-same-start
+ t-refs-same refs/remotes/dgit/dgit/sid
+ t-ref-same-val "previous sid" $rsid
+
+ t-refs-same-start
+ t-refs-same refs/remotes/dgit/dgit/stable,sid
+ t-ref-same-val "previous combined" $rcombined
+}
+
+t-dgit fetch stable,unstable
+
+rcombined=$(t-git-get-ref refs/remotes/dgit/dgit/stable,sid)
+
+multi-good
+
+cd ..
+
+t-dgit clone --no-rm-on-error $p stable,unstable ./$p.clone
+
+cd $p.clone
+
+multi-good
+
+t-commit bogus 3.0 stable,unstable
+t-expect-fail "does not support multiple" \
+t-dgit -wgf build
+
+cd ..
+
+t-dgit clone --no-rm-on-error $p stable ./$p.pull
+cd $p.pull
+git checkout -b x
+git commit --allow-empty -m X
+t-dgit pull stable,unstable
+
+multi-good
+
+t-has-parent-or-is HEAD $rcombined
+
+t-ok
diff --git a/tests/tests/newtag-clone-nogit b/tests/tests/newtag-clone-nogit
new file mode 100755
index 0000000..915f9d3
--- /dev/null
+++ b/tests/tests/newtag-clone-nogit
@@ -0,0 +1,4 @@
+#!/bin/bash
+set -e
+. tests/lib
+t-alt-test
diff --git a/tests/tests/oldnewtagalt b/tests/tests/oldnewtagalt
new file mode 100755
index 0000000..098fe19
--- /dev/null
+++ b/tests/tests/oldnewtagalt
@@ -0,0 +1,25 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-setup-import examplegit
+t-tstunt-parsechangelog
+
+cd $p
+
+test-push () {
+ t-commit "$1"
+ t-dgit build-source
+ t-dgit push
+}
+
+for count in 1 2; do
+ t-oldtag
+ test-push "oldtag $count"
+
+ t-newtag
+ test-push "newtag $count"
+done
+
+t-ok
+
diff --git a/tests/tests/oldtag-clone-nogit b/tests/tests/oldtag-clone-nogit
new file mode 100755
index 0000000..915f9d3
--- /dev/null
+++ b/tests/tests/oldtag-clone-nogit
@@ -0,0 +1,4 @@
+#!/bin/bash
+set -e
+. tests/lib
+t-alt-test
diff --git a/tests/tests/orig-include-exclude b/tests/tests/orig-include-exclude
new file mode 100755
index 0000000..a37f997
--- /dev/null
+++ b/tests/tests/orig-include-exclude
@@ -0,0 +1,21 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+suitespecs+=' stable'
+
+. $troot/lib-orig-include-exclude
+
+ofb=example_1.1.orig.tar
+zcat $ofb.gz >$ofb.SPONG
+gzip -1Nv $ofb.SPONG
+mv $ofb.SPONG.gz $ofb.gz
+
+cd $p
+
+test-push-1 1.1-1.3 '' stable
+
+t-expect-fail E:'archive contains .* with different checksum' \
+test-push-2 --new
+
+t-ok
diff --git a/tests/tests/orig-include-exclude-chkquery b/tests/tests/orig-include-exclude-chkquery
new file mode 100755
index 0000000..f8eac57
--- /dev/null
+++ b/tests/tests/orig-include-exclude-chkquery
@@ -0,0 +1,33 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-git-config dgit-distro.test-dummy.archive-query ftpmasterapi:
+# ^ that will crash if it gets unexpected file_in_archive queries
+
+# orig-include-exclude will set origs and usvsns
+update-files_in_archive () {
+ for o in $origs; do for usvsn in $usvsns; do \
+ of=${p}_${v%-*}.${o}.tar.gz
+ pat="%/${of//_/\\_}"
+ # curl url-decodes these things so we have to have literals
+ find $tmp/mirror -name $of | \
+ xargs -r sha256sum | \
+ perl -pe '
+ BEGIN { print "["; }
+ chomp;
+ s/^/{"sha256sum":"/;
+ s/ /","filename":"/;
+ s/$/"}$delim/;
+ $delim=",";
+ END { print "]\n"; }
+ ' \
+ >$tmp/aq/"file_in_archive/$pat"
+ done; done
+}
+
+test_push_2_hook=update-files_in_archive
+
+. $troot/lib-orig-include-exclude
+
+t-ok
diff --git a/tests/tests/overwrite-chkclog b/tests/tests/overwrite-chkclog
new file mode 100755
index 0000000..3544390
--- /dev/null
+++ b/tests/tests/overwrite-chkclog
@@ -0,0 +1,39 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-setup-import examplegit
+
+cd example
+
+suite=stable
+
+t-commit 'No changes, just send to stable' '' stable
+
+t-dgit -wgf build
+
+t-expect-fail 'Perhaps debian/changelog does not mention' \
+t-dgit push --overwrite stable
+
+t-dgit setup-mergechangelogs
+
+t-expect-fail 'fix conflicts and then commit the result' \
+git merge dgit/dgit/stable
+
+git checkout master which
+EDITOR=: git commit
+
+t-dgit -wgf build
+
+perl -i~ -pe 's/^(\w+ \(\S+)(\) stable)/$1+X$2/ if $.>1' debian/changelog
+git add debian/changelog
+git commit -m 'Break changelog'
+
+t-expect-fail 'Perhaps debian/changelog does not mention' \
+t-dgit push --overwrite stable
+
+git revert --no-edit 'HEAD^{/Break changelog}'
+
+t-dgit push --overwrite stable
+
+t-ok
diff --git a/tests/tests/overwrite-junk b/tests/tests/overwrite-junk
new file mode 100755
index 0000000..e11d1f8
--- /dev/null
+++ b/tests/tests/overwrite-junk
@@ -0,0 +1,22 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-setup-import examplegit
+
+cd example
+
+suite=stable
+
+t-commit 'No changes, just send to stable' '' stable
+
+t-dgit -wgf build
+
+(
+ : "make a bit of a wrongness, which we still want to be able to overwrite"
+ cd $tmp/git/$p.git; git tag -f $tagpfx/1.2 $tagpfx/1.1
+)
+
+t-dgit push --overwrite=1.2 stable
+
+t-ok
diff --git a/tests/tests/overwrite-splitbrains b/tests/tests/overwrite-splitbrains
new file mode 100755
index 0000000..0ef03f6
--- /dev/null
+++ b/tests/tests/overwrite-splitbrains
@@ -0,0 +1,27 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-tstunt-parsechangelog
+
+t-gbp-example-prep-no-ff
+t-newtag
+
+t-dgit --quilt=gbp --dgit-view-save=split.b build-source
+
+t-dgit fetch
+
+t-refs-same-start
+t-ref-head
+
+t-expect-fail 'check failed (maybe --overwrite is needed' \
+t-dgit --quilt=gbp --dgit-view-save=split.p push
+
+t-refs-same-start
+t-ref-head
+
+t-dgit --quilt=gbp --dgit-view-save=split.p --overwrite push
+
+t-gbp-pushed-good
+
+t-ok
diff --git a/tests/tests/overwrite-version b/tests/tests/overwrite-version
new file mode 100755
index 0000000..34301ac
--- /dev/null
+++ b/tests/tests/overwrite-version
@@ -0,0 +1,20 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-setup-import examplegit
+
+cd example
+
+suite=stable
+
+t-commit 'No changes, just send to stable' '' stable
+
+t-dgit -wgf build
+
+t-expect-fail 'HEAD is not a descendant' \
+t-dgit push stable
+
+t-dgit push --overwrite=1.2 stable
+
+t-ok
diff --git a/tests/tests/push-buildproductsdir b/tests/tests/push-buildproductsdir
new file mode 100755
index 0000000..505d105
--- /dev/null
+++ b/tests/tests/push-buildproductsdir
@@ -0,0 +1,31 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-archive pari-extra 3-1
+t-git pari-extra 3-1
+
+t-dgit clone $p
+
+cd $p
+t-cloned-fetched-good
+
+v=3-2~dummy1
+t-apply-diff 3-1 $v
+debcommit -a
+
+t-refs-same-start
+t-ref-head
+
+t-dgit --dpkg-buildpackage:-d build
+
+cd ..
+mkdir bpd
+mv $p*_* bpd/
+cd $p
+
+t-dgit --build-products-dir=../bpd push
+
+t-pushed-good dgit/sid
+
+t-ok
diff --git a/tests/tests/push-newpackage b/tests/tests/push-newpackage
new file mode 100755
index 0000000..79355e3
--- /dev/null
+++ b/tests/tests/push-newpackage
@@ -0,0 +1,30 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-prep-newpackage pari-extra 3-1
+
+cd $p
+t-refs-same-start
+t-ref-head
+
+t-expect-push-fail 'package appears to be new in this suite' \
+t-dgit push
+
+t-dgit build
+
+git checkout bogus
+
+set +e
+(set -e; DGIT_TEST_DEBUG=' ' t-dgit push --new)
+rc=$?
+set -e
+if [ $rc = 0 ]; then fail "push succeeded when tree mismatch"; fi
+
+git checkout master
+
+t-dgit push --new
+
+t-pushed-good master
+
+t-ok
diff --git a/tests/tests/push-nextdgit b/tests/tests/push-nextdgit
new file mode 100755
index 0000000..d0436ab
--- /dev/null
+++ b/tests/tests/push-nextdgit
@@ -0,0 +1,25 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-archive pari-extra 3-1
+t-git pari-extra 3-1
+
+t-dgit clone $p
+
+cd $p
+t-cloned-fetched-good
+
+v=3-2~dummy1
+t-apply-diff 3-1 $v
+debcommit -a
+
+t-refs-same-start
+t-ref-head
+
+t-dgit --dpkg-buildpackage:-d build
+t-dgit push
+
+t-pushed-good dgit/sid
+
+t-ok
diff --git a/tests/tests/quilt b/tests/tests/quilt
new file mode 100755
index 0000000..1a921b3
--- /dev/null
+++ b/tests/tests/quilt
@@ -0,0 +1,96 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-archive ruby-rails-3.2 3.2.6-1
+t-git-none
+
+mkdir -p incoming
+cd incoming
+t-worktree test
+cd ..
+
+t-dgit clone $p
+
+cd $p
+t-cloned-fetched-good
+
+git fetch $tmp/incoming/$p dgit/sid:incoming
+
+dummy=0
+
+iteration () {
+ dummy=$(( $dummy + 1))
+ v=3.2.6-2~dummy${dummy}
+
+ t-refs-same-start
+ t-dgit --dpkg-buildpackage:-d build
+ t-dgit push
+ t-pushed-good dgit/sid
+}
+
+git cherry-pick -x incoming~1; iteration
+git cherry-pick -x incoming~0; iteration
+
+git fetch $tmp/incoming/$p incoming-branch:branch
+git checkout branch
+git rebase --onto dgit/sid incoming
+git checkout dgit/sid
+git merge branch
+iteration
+
+diff <<END - debian/patches/series
+ups-topic/ups-yml
+spongiform-upstream-new-file-incl-change
+zorkmid-options-=-42
+END
+
+for f in `cat debian/patches/series`; do
+ egrep -q '^From.*ijackson@chiark' debian/patches/$f
+done
+
+t-822-field ../${p}_${v}_*.changes Changes |
+ grep -Fx 'ruby-rails-3.2 (3.2.6-2~dummy1) unstable; urgency=low'
+
+t-git-next-date
+
+# Now we are going to check that our dgit-generated patches round
+# trip to similar git commits when imported by gbp pq:
+
+git clean -xdf
+
+# We need to make a patches-unapplied version
+unpa=$(git log --pretty=format:'%H' --grep '^\[dgit import unpatched')
+git checkout -b for-gbp
+git reset "$unpa" .
+git reset HEAD debian
+git commit -m UNAPPY
+git reset --hard
+git clean -xdf
+
+export GIT_AUTHOR_NAME='Someone Else'
+export GIT_AUTHOR_EMAIL='else@example.com'
+export GIT_COMMITTER_NAME='Someone Else'
+export GIT_COMMITTER_EMAIL='else@example.com'
+
+gbp pq import
+
+for compare in $(git log --pretty='format:%H' \
+ --grep 'Change something in the upstream yml')
+do
+ git cat-file commit $compare >../this.cmp
+ # normalise
+ perl -i~$compare~ -0777 -pe '
+ s/\n+$//; $_ .= "\n";
+ s/^(?:committer|parent|tree) .*\n//gm;
+ s/\n+(\(cherry picked from .*\)\n)\n*/\n\n/m
+ and s/$/$1/;
+ s/\n+$//; $_ .= "\n";
+ ' ../this.cmp
+ if test -f ../last.cmp; then
+ diff -u ../last.cmp ../this.cmp
+ fi
+ mv ../this.cmp ../last.cmp
+done
+
+t-ok
diff --git a/tests/tests/quilt-gbp b/tests/tests/quilt-gbp
new file mode 100755
index 0000000..3ef89e8
--- /dev/null
+++ b/tests/tests/quilt-gbp
@@ -0,0 +1,61 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-tstunt-parsechangelog
+
+t-gbp-example-prep
+
+t-expect-fail 'quilt fixup cannot be linear' \
+ t-dgit build-source
+
+t-git-config dgit-distro.test-dummy.dgit-tag-format new
+t-expect-fail 'requires split view so server needs to support' \
+t-dgit -wgf --quilt=gbp build-source
+t-newtag
+
+t-dgit --quilt=gbp --dgit-view-save=split.b1 build-source
+git rev-parse split.b1
+
+t-dgit --quilt=gbp --gbp-pq=no-such-command-gbp build-source
+
+echo spong >debian/pointless-for-dgit-test
+git add debian/pointless-for-dgit-test
+git commit -m Pointless
+
+t-expect-fail no-such-command-gbp \
+t-dgit --quilt=gbp --clean=git --gbp-pq=no-such-command-gbp build-source
+
+test-push-1 () {
+ t-refs-same-start
+ t-ref-head
+}
+
+test-push-2 () {
+ t-dgit --quilt=gbp --dgit-view-save=split.p push
+
+ t-gbp-pushed-good
+}
+
+test-push-1
+
+t-dgit --quilt=gbp --clean=git --dgit-view-save=split.b build-source
+
+t-expect-fail "HEAD specifies a different tree to $p" \
+ t-dgit push
+
+test-push-2
+
+echo wombat >>debian/pointless-for-dgit-test
+git add debian/pointless-for-dgit-test
+git commit -m 'Pointless 2'
+
+t-commit 'Check pseudomerge' 1.0-3
+
+test-push-1
+
+t-dgit --quilt=gbp --clean=git --dgit-view-save=split.b build-source
+
+test-push-2
+
+t-ok
diff --git a/tests/tests/quilt-gbp-build-modes b/tests/tests/quilt-gbp-build-modes
new file mode 100755
index 0000000..cd77dab
--- /dev/null
+++ b/tests/tests/quilt-gbp-build-modes
@@ -0,0 +1,13 @@
+#!/bin/bash
+set -e
+. tests/lib
+. $troot/lib-build-modes
+
+bm-gbp-example-acts \
+ 'build-source' \
+ 'build -b' \
+ 'build -S' \
+ 'gbp-build -S' \
+ 'gbp-build -b' \
+
+t-ok
diff --git a/tests/tests/quilt-gbp-build-modes-sbuild b/tests/tests/quilt-gbp-build-modes-sbuild
new file mode 100755
index 0000000..4c86bfe
--- /dev/null
+++ b/tests/tests/quilt-gbp-build-modes-sbuild
@@ -0,0 +1,12 @@
+#!/bin/bash
+set -e
+. tests/lib
+. $troot/lib-build-modes
+
+t-dependencies sbuild
+t-restrict x-dgit-schroot-build
+
+bm-gbp-example-acts \
+ 'sbuild -c build --arch-all' \
+
+t-ok
diff --git a/tests/tests/quilt-singlepatch b/tests/tests/quilt-singlepatch
new file mode 100755
index 0000000..3b6e228
--- /dev/null
+++ b/tests/tests/quilt-singlepatch
@@ -0,0 +1,39 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-archive sunxi-tools 1.2-2.~~dgittest
+t-git-none
+
+t-dgit clone $p
+cd $p
+t-cloned-fetched-good
+
+echo EXTRA-LINE-1 >>fel.c
+echo EXTRA-LINE-2 >>fel.c
+echo EXTRA-LINE-3 >>.gitignore
+
+git add fel.c .gitignore
+
+t-commit 'commit our stuff' 1.2-3
+
+t-dgit -wgf quilt-fixup
+
+t-refs-same-start
+t-ref-head
+
+t-dgit -wgf build-source
+
+t-dgit push
+t-pushed-good dgit/sid
+
+diff <<END - debian/patches/series
+debian-changes
+END
+
+diff <<END - <(ls debian/patches)
+debian-changes
+series
+END
+
+t-ok
diff --git a/tests/tests/quilt-splitbrains b/tests/tests/quilt-splitbrains
new file mode 100755
index 0000000..9f0ae5f
--- /dev/null
+++ b/tests/tests/quilt-splitbrains
@@ -0,0 +1,140 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+suitespecs+=' stable'
+
+# This test script tests each of the split brain quilt modes, and
+# --quilt=linear, with a tree suitable for each of those, and pushes
+# them in sequence. The idea is to check that each tree is rejected
+# by the wrong quilt modes, and accepted and processed correctly by
+# the right ones.
+
+t-tstunt-parsechangelog
+
+t-newtag
+
+# Easiest way to make a patches-unapplied but not-gbp tree is
+# to take the patches-unapplied tree and by-hand commit the .gitignore
+# changes as a debian patch.
+t-gbp-example-prep
+
+suite=sid
+
+want-success () {
+ local qmode=$1; shift
+ t-refs-same-start
+ t-ref-head
+
+ t-dgit "$@" --quilt=$qmode --dgit-view-save=split.b build-source
+
+ t-dgit "$@" --quilt=$qmode --dgit-view-save=split.p push
+ t-$qmode-pushed-good
+}
+
+
+echo "===== testing tree suitable for --quilt=gbp (only) ====="
+
+t-expect-fail 'grep: new-upstream-file: No such file or directory' \
+t-dgit --quilt=dpm build-source
+
+t-expect-fail 'git tree differs from result of applying' \
+t-dgit -wgf --quilt=dpm build-source
+
+t-expect-fail 'git tree differs from orig in upstream files' \
+t-dgit -wgf --quilt=unapplied build-source
+
+t-expect-fail 'This might be a patches-unapplied branch' \
+t-dgit -wgf build-source
+
+# testing success with --quilt=gbp are done in quilt-gbp test case
+
+
+echo "===== making tree suitable for --quilt=unapplied (only) ====="
+
+pf=debian/patches/test-gitignore
+
+cat >$pf <<END
+From: Senatus <spqr@example.com>
+Subject: Add .gitignore
+
+---
+END
+
+git diff /dev/null .gitignore >>$pf || test $? = 1
+echo ${pf##*/} >>debian/patches/series
+
+git add debian/patches
+git rm -f .gitignore
+git commit -m 'Turn gitignore into a debian patch'
+gitigncommit=`git rev-parse HEAD`
+
+t-commit unapplied 1.0-3
+
+echo "----- testing tree suitable for --quilt=unapplied (only) -----"
+
+t-expect-fail 'git tree differs from result of applying' \
+t-dgit -wgf --quilt=dpm build-source
+
+t-expect-fail 'gitignores: but, such patches exist' \
+t-dgit -wgf --quilt=gbp build-source
+
+t-expect-fail 'This might be a patches-unapplied branch' \
+t-dgit -wgf build-source
+
+want-success unapplied -wgf
+
+
+echo "===== making fully-applied tree suitable for --quilt-check ====="
+
+git checkout master
+git merge --ff-only dgit/dgit/sid
+
+t-commit vanilla 1.0-4
+
+echo "----- testing fully-applied tree suitable for --quilt-check -----"
+
+t-expect-fail 'gitignores: but, such patches exist' \
+t-dgit --quilt=dpm build-source
+
+t-expect-fail 'git tree differs from orig in upstream files' \
+t-dgit --quilt=gbp build-source
+
+t-expect-fail 'git tree differs from orig in upstream files' \
+t-dgit --quilt=unapplied build-source
+
+t-dgit --quilt=nofix build-source
+t-refs-same-start
+t-ref-head
+t-dgit --quilt=nofix push
+t-pushed-good-core
+
+
+echo "===== making tree suitable for --quilt=dpm (only) ====="
+
+git checkout master
+git merge --ff-only dgit/dgit/sid
+
+git revert --no-edit $gitigncommit
+
+t-commit dpmish 1.0-5
+
+echo "----- testing tree suitable for --quilt=dpm (only) -----"
+
+t-expect-fail 'git tree differs from orig in upstream files' \
+t-dgit -wgf --quilt=gbp build-source
+
+t-expect-fail 'git tree differs from orig in upstream files' \
+t-dgit -wgf --quilt=unapplied build-source
+
+t-expect-fail 'This might be a patches-applied branch' \
+t-dgit -wgf build-source
+
+want-success dpm
+
+suite=stable
+t-commit dpmish-stable 1.0-6 $suite
+
+want-success dpm --new
+
+t-ok
diff --git a/tests/tests/rpush b/tests/tests/rpush
new file mode 100755
index 0000000..71bbe2b
--- /dev/null
+++ b/tests/tests/rpush
@@ -0,0 +1,31 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-archive pari-extra 3-1
+t-git pari-extra 3-1
+
+t-dgit clone $p
+
+cd $p
+t-cloned-fetched-good
+
+v=3-2~dummy1
+t-apply-diff 3-1 $v
+debcommit -a
+
+t-refs-same-start
+t-ref-head
+
+t-dgit --dpkg-buildpackage:-d build
+
+mkdir $tmp/empty
+cd $tmp/empty
+#t-dgit --ssh=$troot/ssh rpush somehost:$troot/$p
+#echo $?
+t-dgit --ssh=$troot/ssh rpush somehost:$tmp/$p
+
+cd $tmp/$p
+t-pushed-good dgit/sid
+
+t-ok
diff --git a/tests/tests/spelling b/tests/tests/spelling
new file mode 100755
index 0000000..ed1290c
--- /dev/null
+++ b/tests/tests/spelling
@@ -0,0 +1,16 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-restrict x-dgit-git-only
+
+cd $root
+
+set +e
+git grep -q -i 'ps[u]edo'
+rc=$?
+set -e
+
+test $rc = 1
+
+t-ok
diff --git a/tests/tests/tag-updates b/tests/tests/tag-updates
new file mode 100755
index 0000000..824fd1e
--- /dev/null
+++ b/tests/tests/tag-updates
@@ -0,0 +1,37 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-tstunt-parsechangelog
+t-prep-newpackage example 1.0
+
+cd $p
+revision=1
+t-dgit build
+t-dgit push --new
+
+tagref=`t-v-tag`
+tagname=${tn#refs/tags}
+
+(set -e
+ cd $dgitrepo
+ git tag -m UNWANTED unwanted dgit/sid)
+
+fetch-check () {
+ t-dgit fetch
+ t-ref-same-exact $tagref
+ t-refs-notexist refs/tags/unwanted
+}
+
+t-ref-same-exact $tagref
+fetch-check
+
+git tag -d $tagname
+fetch-check
+
+git tag -f -m BOGUS $tagname HEAD
+t-refs-same-start
+t-ref-same-exact $tagref
+fetch-check
+
+t-ok
diff --git a/tests/tests/test-list-uptodate b/tests/tests/test-list-uptodate
new file mode 100755
index 0000000..1e5f199
--- /dev/null
+++ b/tests/tests/test-list-uptodate
@@ -0,0 +1,11 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+: "just verifies internal consistency of test suite"
+
+cd $root
+$troot/enumerate-tests gencontrol >$tmp/control-expected
+diff debian/tests/control $tmp/control-expected
+
+t-ok
diff --git a/tests/tests/trustingpolicy-replay b/tests/tests/trustingpolicy-replay
new file mode 100755
index 0000000..ad731f5
--- /dev/null
+++ b/tests/tests/trustingpolicy-replay
@@ -0,0 +1,85 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-tstunt-parsechangelog
+
+t-git-config dgit.default.dep14tag no
+
+t-dsd
+t-policy dgit-repos-policy-trusting
+t-prep-newpackage example 1.0
+
+cd $p
+revision=1
+git tag start
+
+t-dgit build
+t-dgit push --new
+
+t-commit 'Prep v1.1 which will be rewound'
+t-dgit build
+t-dgit push
+
+t-rm-dput-dropping
+git checkout $tagpfx/1.0
+t-dgit build
+t-dgit push --deliberately-fresh-repo
+
+remote="`git config dgit-distro.test-dummy.git-url`/$p.git"
+
+t-expect-push-fail 'Replay of previously-rewound upload' \
+git push "$remote" \
+ $tagpfx/1.1 \
+ $tagpfx/1.1~0:refs/dgit/sid
+
+git checkout master
+
+
+: "More subtle replay prevention checks"
+
+prepare-replay () {
+ delib=$1
+
+ # We have to stop the pushes succeeding because if they work they
+ # record the tag, which prevents the replays. We are simulating
+ # abortive pushes (since we do want to avoid a situation where
+ # dangerous old signed tags can exist).
+ t-policy-nonexist
+
+ t-commit "request with $delib that we will replay"
+ t-dgit build
+ t-expect-push-fail 'system: No such file or directory' \
+ t-dgit push $delib
+
+ t-policy dgit-repos-policy-trusting
+
+ replayv=$v
+}
+
+attempt-replay () {
+ local mpat=$1
+ git show $tagpfx/$replayv | grep -e $delib
+ t-expect-push-fail "$mpat" \
+ git push "$remote" \
+ $tagpfx/$replayv \
+ +$tagpfx/$replayv~0:refs/dgit/sid
+}
+
+prepare-replay --deliberately-fresh-repo
+
+# simulate some other thing that we shouldn't delete
+git push $dgitrepo +master:refs/heads/for-testing
+
+attempt-replay 'does not declare previously heads/for-testing'
+
+prepare-replay --deliberately-not-fast-forward
+
+t-commit 'later version to stop not fast forward rewinding'
+t-dgit build
+t-dgit push
+
+attempt-replay "does not declare previously tags/$tagpfx/$v"
+
+
+t-ok
diff --git a/tests/tests/unrepresentable b/tests/tests/unrepresentable
new file mode 100755
index 0000000..0d02c6a
--- /dev/null
+++ b/tests/tests/unrepresentable
@@ -0,0 +1,52 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+t-tstunt-parsechangelog
+
+t-prep-newpackage example 1.0
+
+ln -s $troot/pkg-srcs/${p}_${v%-*}.orig.tar.* .
+
+cd $p
+
+start () { git checkout quilt-tip~0; }
+attempt () { t-dgit -wgf --quilt=smash quilt-fixup; }
+
+badly-1 () {
+ wrongfn=$1
+ wrongmsg=$2
+ start
+}
+
+badly-2 () {
+ git commit -m "Commit wrongness $wrongfn ($wrongmsg)"
+ t-expect-fail E:"cannot represent change: $wrongmsg .*: $wrongfn" \
+ attempt
+}
+
+badly-1 symlink 'not a plain file'
+ ln -s TARGET symlink
+ git add symlink
+badly-2
+
+start
+ git rm src.c
+ git commit -m deleted
+attempt
+
+badly-1 src.c 'mode changed'
+ chmod +x src.c
+ git add src.c
+badly-2
+
+badly-1 new 'non-default mode'
+ echo hi >new
+ chmod 755 new
+ git add new
+badly-2
+
+start
+attempt
+
+t-ok
diff --git a/tests/tests/version-opt b/tests/tests/version-opt
new file mode 100755
index 0000000..22c35e7
--- /dev/null
+++ b/tests/tests/version-opt
@@ -0,0 +1,32 @@
+#!/bin/bash
+set -e
+. tests/lib
+
+# NOT t-tstunt-parsechangelog
+# because that doesn't honour the perl option corresponding to -v
+
+t-debpolicy
+t-prep-newpackage example 1.0
+
+cd $p
+revision=1
+git tag start
+t-dgit setup-mergechangelogs
+
+t-dgit build-source
+t-dgit push --new
+
+t-archive-process-incoming sid
+
+for v in 1.1 1.2; do
+ dch -v $v -D unstable -m "Update to version $v"
+
+ git add debian/changelog
+ git commit -m "Commit changelog for $v"
+
+ t-dgit build-source
+done
+
+fgrep 'Update to version 1.1' ../${p}_${v}_source.changes
+
+t-ok