diff options
Diffstat (limited to 'tests')
109 files changed, 4833 insertions, 130 deletions
diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 0000000..5bd3eee --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,14 @@ +# usage: tests/using-intree make -f tests/Makefile +# (optionally setting TESTSCRIPTS='tests/tests/foo tests/tests/bar') + +TESTSCRIPTS ?= $(shell tests/enumerate-tests) +TESTNAMES := $(notdir $(TESTSCRIPTS)) + +all: $(foreach t,$(TESTNAMES),tests/tmp/$t.ok) + @echo "ALL PASSED" + +tests/tmp: + mkdir -p $@ + +tests/tmp/%.ok: tests/tmp + tests/tests/$* >tests/tmp/$*.log 2>&1 diff --git a/tests/adhoc b/tests/adhoc new file mode 100755 index 0000000..b45251f --- /dev/null +++ b/tests/adhoc @@ -0,0 +1,51 @@ +#!/bin/bash +# +# usage: +# after tests/tests/some-test has been run (and maybe failed) +# cd tests/tmp/some-test/blah +# ../../adhoc ../../../dgit some options +# or +# after tests/tests/some-test has been run (and maybe failed) +# cd tests/tmp/some-test/blah +# ../../adhoc some rune run by some piece of infrastructure +# +# effects: +# directly sets the env variables which arrange to use +# programs etc. from the working tree + +ourname=adhoc + +case $0 in +*/$ourname) + : ${DGIT_TEST_INTREE:=$(realpath "${0%/$ourname}/..")} + ;; +*) + echo >&2 "$ourname must be invoked as .../$ourname not $0" + exit 127 + ;; +esac + +export DGIT_TEST_INTREE + +. $DGIT_TEST_INTREE/tests/lib-core + +t-set-intree + +pwd=$(realpath "$(pwd)") +basis=$DGIT_TEST_INTREE/tests/tmp +case "$pwd" in +"$basis" | "$basis"/*) + testname=${pwd/"$basis/"/} + testname=${testname%%/*} + tmp="$basis/$testname" + ;; +*) + fail "$ourname pwd must be inside some test (in $basis), not $pwd" + ;; +esac + +export ADTTMP=$tmp + +t-set-using-tmp + +exec "$@" diff --git a/tests/drs-git-ext b/tests/drs-git-ext index 52e7817..ad27c9b 100755 --- a/tests/drs-git-ext +++ b/tests/drs-git-ext @@ -2,12 +2,14 @@ set -e tmp=$DGIT_TEST_TMP +: ${DGIT_DRS_DEBUG:=1} +export DGIT_DRS_DEBUG echo >&2 '((((((((((((((((((((((((((((((((((((((((' set -x export SSH_ORIGINAL_COMMAND="$*" ${DGIT_REPOS_SERVER_TEST-dgit-repos-server} \ - $tmp/suites \ + test-dummy $tmp/distro=test-dummy \ $tmp/dd.gpg,a:$tmp/dm.gpg,m$tmp/dm.txt \ - $tmp/git \ + --repos=$tmp/git --suites=$tmp/suites \ --ssh : '))))))))))))))))))))))))))))))))))))))))' diff --git a/tests/dsd-ssh b/tests/dsd-ssh new file mode 100755 index 0000000..d5df5aa --- /dev/null +++ b/tests/dsd-ssh @@ -0,0 +1,18 @@ +#!/bin/sh +set -e + +echo >&2 '((((((((((((((((((((((((((((((((((((((((' +set -x + +tmp=$DGIT_TEST_TMP +cd / +userhost="$1"; shift +export SSH_ORIGINAL_COMMAND="$*" + +# undoes PERLLIB so that we rely on dgit-ssh-dispatch setting it +# we have to compensate with -I so that dgit-ssh-dispatch finds Dgit.pm +unset PERLLIB +${DGIT_TEST_INTREE+perl -I}$DGIT_TEST_INTREE \ +${DGIT_SSH_DISPATCH_TEST-dgit-ssh-dispatch} -D $tmp + +: '))))))))))))))))))))))))))))))))))))))))' diff --git a/tests/enumerate-tests b/tests/enumerate-tests new file mode 100755 index 0000000..2c00f97 --- /dev/null +++ b/tests/enumerate-tests @@ -0,0 +1,109 @@ +#!/bin/bash + +set -e + +. tests/lib-core +. tests/lib-restricts + +mode=$1 + +test-begin- () { + whynots='' +} + +restriction- () { + set +e + whynot=$(t-restriction-$r) + rc=$? + whynot="${whynot// +/ / }" + set -e + case "$rc.$whynot" in + 0.) ;; + 1.?*) whynots="$whynots${whynots:+; }$whynot" ;; + *) fail "restriction $r for $t gave $rc $whynot !" + esac +} + +dependencies- () { + : +} + +test-done- () { + case "$whynots" in + '') echo $t ;; + ?*) echo >&2 "SKIP $t $whynots" ;; + esac +} + +finish- () { + : +} + +test-begin-gencontrol () { + restrictions='' + dependencies='' +} + +restriction-gencontrol () { + restrictions+=" $r" +} + +dependencies-gencontrol () { + dependencies+=", $deps" +} + +test-done-gencontrol () { + stanza=$( + add_Depends="$dependencies" \ + perl <debian/tests/control.in -wpe ' + if (/^(\w+):/) { + my $h = $1; + s{$}{ $ENV{"add_$h"} // "" }e; + } + ' + case "$restrictions" in + ?*) echo "Restrictions:$restrictions" ;; + esac + ) + key=$(printf "%s" "$stanza" | sha256sum) + key=${key%% *} + eval " + stanza_$key=\"\$stanza\" + tests_$key+=\" \${t#tests/tests/}\" + " + keys=" ${keys/ $key /}" + keys+=" $key " +} + +finish-gencontrol () { + for key in $keys; do + eval " + stanza=\$stanza_$key + tests=\$tests_$key + " + printf "Tests:%s\n%s\n\n" "$tests" "$stanza" + done +} + +seddery () { + local seddery=$1 + sed <$t -n ' + 20q; + /^: t-enumerate-tests-end$/q; + '"$seddery"' + ' +} + +for t in $(run-parts --list tests/tests); do + test-begin-$mode + for r in $(seddery 's/^t-restrict //p'); do + restriction-$mode + done + for deps in $(seddery 's/^t-dependencies //p'); do + dependencies-$mode + done + test-done-$mode +done + +finish-$mode @@ -2,6 +2,36 @@ exec 2>&1 set -x +set -o pipefail + +. tests/lib-core +. tests/lib-restricts + +t-report-failure () { + set +x + rc=$1 + cat <<END >&2 +TEST FAILED +funcs: ${FUNCNAME[*]} +lines: ${BASH_LINENO[*]} +files: ${BASH_SOURCE[*]} +END + exit 16 +} + +trap 'test $? = 0 || t-report-failure' EXIT + +t-filter-out-git-hyphen-dir + +t-set-intree + +: ${DGIT_TEST_DEBUG=-D} +export DGIT_TEST_DEBUG + +: ${DGIT_TEST_DISTRO+ ${distro=${DGIT_TEST_DISTRO}}} + +export GIT_COMMITTER_DATE='1440253867 +0100' +export GIT_AUTHOR_DATE='1440253867 +0100' root=`pwd` troot=$root/tests @@ -10,21 +40,25 @@ testname="${DGIT_TEST_TESTNAME-${0##*/}}" tmp=$ADTTMP if [ x"$tmp" = x ]; then mkdir -p tests/tmp + tmpbase=$troot/tmp tmp=tests/tmp/$testname rm -rf $tmp mkdir $tmp +elif [ "x$DGIT_TEST_TMPBASE" != x ]; then + tmpbase="$DGIT_TEST_TMPBASE" fi cd $tmp -export HOME=$tmp tmp=`pwd` -export DGIT_TEST_DUMMY_DIR=$tmp + +t-set-using-tmp + +test -f $tmp/.save-env || \ +env -0 >$tmp/.save-env + ln -f $troot/ssh ssh -mkdir -p $tmp/gnupg -cp $troot/gnupg/* $tmp/gnupg -chmod go-rw $tmp/gnupg/* -export GNUPGHOME=$tmp/gnupg +export DEBCHANGE_VENDOR=dpkg mkdir -p $tmp/incoming cat <<END >$tmp/dput.cf @@ -34,16 +68,97 @@ incoming = $tmp/incoming run_dinstall = 0 END -fail () { - echo >&2 "failed: $*" - exit 1 +: ${t_archive_method:=aq} +: ${tagpfx:=archive/test-dummy} +: ${suitespecs:=sid:unstable} + +t-git-next-date () { + GIT_COMMITTER_DATE="$(( ${GIT_COMMITTER_DATE%% *} + 1 )) ${GIT_COMMITTER_DATE#* }" + GIT_AUTHOR_DATE="$GIT_COMMITTER_DATE" +} + +t-expect-fail () { + local mpat="$1"; shift + + set +o pipefail + LC_MESSAGES=C "$@" 2>&1 | tee $tmp/t.output + local ps="${PIPESTATUS[*]}" + set -o pipefail + + case $ps in + "0 0") fail "command unexpectedly succeeded (instead of: $mpat)" ;; + *" 0") ;; + *) fail "tee failed" ;; + esac + + t-grep-mpat "$mpat" $tmp/t.output +} + +t-grep-mpat () { + local mpat="$1" + local file="$2" + + local grepper=fgrep + case "$mpat" in + [A-Z]:*) + case "$mpat" in + E:*) grepper=egrep ;; + F:*) grepper=fgrep ;; + *) fail "bad mpat prefix in $mpat";; + esac + mpat=${mpat#[A-Z]:} + ;; + esac + + $grepper -e "$mpat" "$file" || + fail "message not found" +} + +t-expect-push-fail () { + local mpat="$1"; shift + + local triedpush; triedpush=`git rev-parse HEAD` + + t-reporefs pre-push + t-expect-fail "$mpat" "$@" + t-reporefs post-push + diff $tmp/show-refs.{pre,post}-push + + t-git-objects-not-present '' $triedpush + + eval "$t_expect_push_fail_hook" +} + +t-git-objects-not-present () { + # t-git-objects-not-present GITDIR|'' OBJID [...] + # specifying '' means the repo for package $p + local gitdir="${1-$dgitrepo}" + local obj + if ! [ -e "$gitdir" ]; then return; fi + for obj in "$@"; do + GIT_DIR=$gitdir \ + t-expect-fail 'unable to find' \ + git cat-file -t $obj + done +} + +t-reporefs () { + local whichoutput=$1; shift + local whichrepo=${1-$dgitrepo} + local outputfile="$tmp/show-refs.$whichoutput" + (set -e + exec >"$outputfile" + if test -d $whichrepo; then + cd $whichrepo + git show-ref |sort + fi) } t-untar () { local tarfile=$1.tar local edittree=$1.edit if test -d "$edittree"; then - cp -al "$edittree"/* . + cp -a "$edittree"/* . else tar xf "$tarfile" fi @@ -54,8 +169,13 @@ t-worktree () { t-untar $troot/worktrees/${p}_$1 } -t-git () { +t-select-package () { p=$1 + dgitrepo=$tmp/git/$p.git +} + +t-git () { + t-select-package $1 v=$2 mkdir -p $tmp/git local gs=$troot/git-srcs/${p}_$v.git @@ -67,56 +187,248 @@ t-git-none () { (set -e; cd $tmp/git; tar xf $troot/git-template.tar) } +t-git-merge-base () { + git merge-base $1 $2 || test $? = 1 +} + t-has-ancestor () { - local now=`git rev-parse HEAD` - local ancestor=`git rev-parse $1^{}` - local mbase=`git merge-base $ancestor $now` + # t-has-ancestor ANCESTOR + # (CHILD is implicit, HEAD) + local now; now=`git rev-parse HEAD` + local ancestor; ancestor=`git rev-parse $1^{}` + local mbase; mbase=`t-git-merge-base $ancestor $now` if [ x$mbase != x$ancestor ]; then fail "not ff $ancestor..$now, $mbase != $ancestor" fi -} +} + +t-has-parent-or-is () { + # t-has-parent-or-is CHILD PARENT + local child=$1 + local parent=$2 + local parents + parents=$(git show --pretty=format:' %P %H ' "$child") + parent=$(git rev-parse "$parent~0") + case "$parents" in + *" $parent "*) ;; + *) fail "child $child lacks parent $parent" ;; + esac +} + +t-prep-newpackage () { + t-select-package $1 + v=$2 + t-archive-none $p + t-git-none + t-worktree $v + cd $p + if ! git show-ref --verify --quiet refs/heads/master; then + git branch -m dgit/sid master + git remote rm dgit + fi + cd .. +} t-archive-none () { - p=$1 - mkdir -p $tmp/aq $tmp/mirror - echo sid >$tmp/aq/suite.unstable + t-select-package $1 + t-archive-none-$t_archive_method +} +t-archive-none-aq () { + mkdir -p $tmp/aq/dsc_in_suite $tmp/mirror/pool/main + + : >$tmp/aq/suites + local jsondelim="[" + + local suitespec + for suitespec in $suitespecs; do + local suite=${suitespec%%:*} + local sname=${suitespec#*:} + + >$tmp/aq/package.$suite.$p + t-aq-archive-updated $suite $p + + >$tmp/aq/package.new.$p + t-aq-archive-updated new $p + + ln -sf $suite $tmp/aq/dsc_in_suite/$sname + + cat <<END >>$tmp/aq/suites +$jsondelim + { + "archive" : "ftp-master", + "codename" : "$suite", + "components" : [ + "main", + "contrib", + "non-free" + ], + "name" : "$sname", + "dakname" : "$sname" +END + + jsondelim=" }," + + done + cat <<END >>$tmp/aq/suites + } +] +END +} + +t-aq-archive-updated () { + local suite=$1 + local p=$2 + local suitedir=$tmp/aq/dsc_in_suite/$suite + mkdir -p $suitedir + perl <$tmp/aq/package.$suite.$p >$suitedir/$p -wne ' + use JSON; + use strict; + our @v; + m{^(\S+) (\w+) ([^ \t/]+)/(\S+)} or die; + push @v, { + "version" => "$1", + "sha256sum" => "$2", + "component" => "$3", + "filename" => "$4", + }; + END { + my $json = JSON->new->canonical(); + print $json->encode(\@v) or die $!; + } + ' } t-archive-process-incoming () { - mv incoming/${p}_${v}[._]* mirror/ - t-archive-query + local suite=$1 + mv $tmp/incoming/${p}_* $tmp/mirror/pool/main/ + t-archive-query "$suite" } t-archive-query () { - local dscf=${p}_${v}.dsc - echo "${v} $dscf" >>$tmp/aq/package.sid.${p} + local suite=${1-sid} + local dscf=main/${p}_${v}.dsc + t-archive-query-$t_archive_method "$suite" "$p" "$v" "$dscf" +} +t-archive-query-aq () { + local suite=$1 + local p=$2 + local v=$3 + local dscf=$4 + local sha; sha=`sha256sum <$tmp/mirror/pool/$dscf` + echo "${v} ${sha% -} $dscf" >>$tmp/aq/package.$suite.${p} + t-aq-archive-updated $suite $p } t-archive () { t-archive-none $1 v=$2 local dscf=${p}_$2.dsc - rm -f $tmp/mirror/${p}_* - ln $troot/pkg-srcs/${p}_${2%-*}* $tmp/mirror/ - t-archive-query + rm -f $tmp/mirror/pool/main/${p}_* + ln $troot/pkg-srcs/${p}_${2%-*}* $tmp/mirror/pool/main/ + t-archive-query $suite rm -rf $tmp/extract mkdir $tmp/extract - (set -e; cd $tmp/extract; dpkg-source -x ../mirror/$dscf) + (set -e; cd $tmp/extract; dpkg-source -x ../mirror/pool/main/$dscf) +} + +t-git-dir-time-passes () { + touch -d 'last year' $dgitrepo +} + +t-git-dir-check () { + local gitdir=$dgitrepo + case "$1" in + enoent) + if test -e "$gitdir"; then fail "$gitdir exists"; fi + return + ;; + public) wantstat='7[75]5' ;; + secret) wantstat='7[70]0' ;; + *) fail "$1 t-git-dir-check ?" ;; + esac + gotstat=`stat -c%a $gitdir` + case "$gotstat" in + *$wantstat) return ;; + *) fail "$gitdir has mode $gotstat, expected $wantstat" ;; + esac +} + +t-expect-fsck-fail () { + echo >>$tmp/fsck.expected-errors "$1" +} + +t-git-fsck () { + set +e + LC_MESSAGES=C git fsck --no-dangling --strict 2>&1 \ + | tee dgit-test-fsck.errs + ps="${PIPESTATUS[*]}" + set -e + + local pats + if [ -f $tmp/fsck.expected-errors ]; then + pats=(-w -f $tmp/fsck.expected-errors) + else + test "$ps" = "0 0" + fi + pats+=(-e 'notice: HEAD points to an unborn branch') + pats+=(-e 'notice: No default references') + + set +e + grep -v "${pats[@]}" dgit-test-fsck.errs + rc=$? + set -e + case $rc in + 1) ;; # no unexpected errors + 0) fail "unexpected messages from git-fsck" ;; + *) fail "grep of git-fsck failed" ;; + esac +} + +t-fscks () { + ( + shopt -s nullglob + for d in $tmp/*/.git $tmp/git/*.git; do + cd "$d" + t-git-fsck + done + ) +} + +t-ok () { + : '========================================' + t-fscks + echo ok. +} + +t-rm-dput-dropping () { + rm -f $tmp/${p}_${v}_*.upload } t-dgit () { local dgit=${DGIT_TEST-dgit} + pwd : ' {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{' $dgit --dgit=$dgit --dget:-u --dput:--config=$tmp/dput.cf \ - -dtest-dummy $DGIT_TEST_OPTS ${DGIT_TEST_DEBUG--D} \ - -k39B13D8A "$@" + ${dgit_config_debian_alias-"--config-lookup-explode=dgit-distro.debian.alias-canon"} \ + ${distro+${distro:+-d}}${distro--dtest-dummy} \ + $DGIT_TEST_OPTS $DGIT_TEST_DEBUG \ + -k39B13D8A $t_dgit_xopts "$@" : '}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} ' } t-diff-nogit () { - diff --exclude=.git -ruN $* + diff --exclude=.git --exclude=.pc -ruN $* +} + +t-files-notexist () { + local f + for f in "$@"; do + if [ -e $f ]; then + fail "$f exists!" + fi + done } t-cloned-fetched-good () { @@ -126,11 +438,11 @@ t-cloned-fetched-good () { t-refs-same \ refs/heads/dgit/sid \ refs/remotes/dgit/dgit/sid - t-refs-notexist dgit/unstable remotes/dgit/dgit/unstable + t-refs-notexist refs/dgit/unstable refs/remotes/dgit/dgit/unstable } t-output () { - printf "%s\n" "$1" >$tmp/t.want + printf "%s${1:+\n}" "$1" >$tmp/t.want shift "$@" >$tmp/t.got diff $tmp/t.want $tmp/t.got @@ -140,38 +452,120 @@ t-clean-on-branch () { t-output "## $1" git status -b --porcelain } +t-setup-done () { + local savevars=$1 + local savedirs=$2 + local importeval=$3 + + local import=IMPORT.${0##*/} + exec 4>$tmp/$import.new + + local vn + for vn in $savevars; do + perl >&4 -I. -MDebian::Dgit -e ' + printf "%s=%s\n", $ARGV[0], shellquote $ARGV[1] + ' $vn "$(eval "printf '%s\n' \"\$$vn\"")" + done + + (set -e; cd $tmp; tar cf $import.tar $savedirs) + + printf >&4 "\n%s\n" "$importeval" + + mv -f $tmp/$import.new $tmp/$import +} + +t-setup-import () { + local setupname=$1 + + local setupsrc + local lock + if [ "x$tmpbase" = x ]; then + # ADTTMP was set on entry to tests/lib, so we + # are not sharing tmp area between tests + setupsrc="$tmp" + lock="$tmp/.dummy.lock" + else + setupsrc="$tmpbase/$setupname" + lock="$setupsrc.lock" + fi + + local simport="$setupsrc/IMPORT.$setupname" + + if ! [ -e "$simport" ]; then + with-lock-ex -w "$lock" \ + xargs -0 -a $tmp/.save-env \ + bash -xec ' + cd "$1"; shift + setupname="$1"; shift + simport="$1"; shift + if [ -e "$simport" ]; then exit 0; fi + env - "$@" \ + "tests/setup/$setupname" + ' x "$root" "$setupname" "$simport" + fi + + if [ "x$setupsrc" != "x$tmp" ]; then + (set -e; cd $tmp; tar xf "$simport.tar") + fi + + . "$simport" +} + +t-git-get-ref-exact () { + local ref=$1 + # does not dereference, unlike t-git-get-ref + case "$ref" in + refs/*) ;; + *) fail "t-git-get-ref-exact bad $ref" ;; + esac + git for-each-ref --format='%(objectname)' "[r]efs/${ref#refs/}" +} + t-git-get-ref () { local ref=$1 - git show-ref -d $1 | perl -ne ' + case "$ref" in + refs/*) ;; + *) fail "t-git-get-ref bad $ref" ;; + esac + (git show-ref -d $1 || test $? = 1) | perl -ne ' $x = $1 if m#^(\w+) \Q'$1'\E(?:\^\{\})?$#; END { print "$x\n" if length $x; } ' } +t-ref-same-exact () { + local name="$1" + local val; val=`t-git-get-ref-exact $name` + t-ref-same-val "$name" $val +} + t-ref-same () { local name="$1" - local val=`t-git-get-ref $name` + local val; val=`t-git-get-ref $name` t-ref-same-val "$name" $val } t-ref-head () { - local val=`git rev-parse HEAD` + local val; val=`git rev-parse HEAD` t-ref-same-val HEAD $val } t-ref-same-val () { local name="$1" local val=$2 - case "$t_ref_val" in - '') ;; + case "${t_ref_val-unset}" in + unset) ;; "$val") ;; - *) fail "ref varies: $name: $val != $t_ref_val" ;; + *) fail "ref varies: ($name)\ + ${val:-nothing} != ${t_ref_val:-nothing} (${t_ref_names[*]})" ;; esac t_ref_val="$val" + t_ref_names+=("$name") } t-refs-same-start () { - t_ref_val='' + unset t_ref_val + t_ref_names=() } t-refs-same () { @@ -184,7 +578,7 @@ t-refs-same () { t-refs-notexist () { local val for g in $*; do - val=`t-git-get-ref $g >$tmp/t.refx` + val=`t-git-get-ref $g` if [ "x$val" != x ]; then fail "ref $g unexpectedly exists ($val)" fi @@ -192,29 +586,188 @@ t-refs-notexist () { } t-v-tag () { - echo refs/tags/debian/${v//\~/_} + echo refs/tags/$tagpfx/${v//\~/_} +} + +t-format-ref () { + git log -n1 --pretty=format:"$1" "$2" +} + +t-sametree-parent () { + local ref=$1 + local parent + local ctree; ctree=$(t-format-ref '%T' "$ref") + while :; do + local psame='' + for parent in $(t-format-ref '%P' "$ref"); do + local ptree; ptree=$(t-format-ref '%T' "$parent") + if [ "x$ptree" = "x$ctree" ]; then + psame+=" $parent" + fi + done + case "$psame" in ""|" * *") break ;; esac + ref="${psame# }" + done + echo "$ref" +} + +t-check-pushed-master () { + local master; master=`t-git-get-ref refs/heads/master` + if [ x$master = x$t_ref_val ]; then return; fi + if [ x$master = x ]; then fail "failed to push master"; fi + # didn't update master, it must be not FF + local mbase; mbase=`t-git-merge-base $master $t_ref_val` + if [ x$mbase = x$master ]; then fail "failed to ff master"; fi } t-pushed-good () { local branch=$1 + local suite=${2:-sid} + t-refs-same \ + refs/heads/$branch + t-pushed-good-core +} + +t-pushed-good-core () { t-ref-dsc-dgit t-refs-same \ - refs/heads/$branch \ `t-v-tag` \ - refs/remotes/dgit/dgit/sid + refs/remotes/dgit/dgit/$suite t-refs-notexist \ refs/heads/dgit/unstable \ refs/remotes/dgit/dgit/unstable - (set -e; cd $tmp/git/$p.git + (set -e; cd $dgitrepo t-refs-same \ - refs/dgit/sid \ + refs/dgit/$suite \ `t-v-tag` + ${t_check_pushed_master:- : NOT-DRS-NO-CHECK-PUSHED-MASTER} t-refs-notexist \ refs/dgit/unstable ) git verify-tag `t-v-tag` } +t-splitbrain-pushed-good--unpack () { + cd $tmp + rm -rf t-unpack + mkdir t-unpack + cd t-unpack + ln -s $tmp/mirror/pool/main/*.orig*.tar* . + ln -s $tmp/incoming/*.orig*.tar* . ||: + ln -s $incoming_dsc . + ln -s ${incoming_dsc/.dsc/.debian.tar}* . + dpkg-source "$@" -x *.dsc + cd */. + git init + git fetch ../../$p "refs/tags/*:refs/tags/*" +} + +t-splitbrain-pushed-good--checkprep () { + git add -Af . + git rm --cached -r --ignore-unmatch .pc +} + +t-splitbrain-pushed-good--checkdiff () { + local tag=$1 + t-splitbrain-pushed-good--checkprep + t-output "" git diff --stat --cached $tag +} + +t-splitbrain-pushed-good-start () { + dep14tag=refs/tags/test-dummy/${v//\~/_} + dgittag=$(t-v-tag) + t-output "" git status --porcelain + t-ref-head + t-refs-same $dep14tag + (set -e; cd $dgitrepo; t-refs-same $dep14tag) + git merge-base --is-ancestor $dep14tag $dgittag + + t-refs-same-start + t-ref-same refs/heads/split.p + case "$(t-git-get-ref refs/heads/split.b)" in + "$t_ref_val") ;; + "$(git rev-parse refs/heads/split.p^0)") ;; + "$(git rev-parse refs/heads/split.p^1)") ;; + *) fail 'bad b/p' ;; + esac + t-pushed-good-core + + t-incoming-dsc + + t-splitbrain-pushed-good--unpack + t-splitbrain-pushed-good--checkdiff $dgittag +} +t-splitbrain-pushed-good-end-made-dep14 () { + t-splitbrain-pushed-good--checkdiff $dep14tag + cd $tmp/$p +} + +t-splitbrain-rm-gitignore-patch () { + perl -i -pe ' + next unless $_ eq "auto-gitignore\n"; + die if $counter++; + chomp; + rename "debian/patches/$_", "../t-auto-gitignore" or die $!; + $_ = ""; + ' debian/patches/series +} + +t-gbp-pushed-good () { + local suite=${1:-sid} + t-splitbrain-pushed-good-start + + # Right, now we want to check that the maintainer tree and + # the dgit tree differ in exactly the ways we expect. We + # achieve this by trying to reconstruct the maintainer tree + # from the dgit tree. + + # So, unpack it withut the patches applied + t-splitbrain-pushed-good--unpack --skip-patches + + # dgit might have added a .gitignore patch, which we need to + # drop and remove + t-splitbrain-rm-gitignore-patch + + # Now the result should differ only in non-debian/ .gitignores + t-splitbrain-pushed-good--checkprep + git diff --cached --name-only $dep14tag >../changed + perl -ne ' + next if !m#^debian/# && m#(^|/)\.gitignore#; + die "$_ mismatch"; + ' <../changed + + # If we actually apply the gitignore patch by hand, it + # should be perfect: + if [ -f ../t-auto-gitignore ]; then + patch --backup-if-mismatch -p1 -u <../t-auto-gitignore + fi + + t-splitbrain-pushed-good-end-made-dep14 +} + +t-unapplied-pushed-good () { + t-splitbrain-pushed-good-start + t-splitbrain-pushed-good--unpack --skip-patches + t-splitbrain-pushed-good-end-made-dep14 +} + +t-dpm-pushed-good () { + t-splitbrain-pushed-good-start + t-splitbrain-pushed-good--unpack + t-splitbrain-rm-gitignore-patch + t-splitbrain-pushed-good-end-made-dep14 +} + +t-commit-build-push-expect-log () { + local msg=$1 + local mpat=$2 + t-commit "$msg" + t-dgit build + LC_MESSAGES=C \ + t-dgit push --new 2>&1 |tee $tmp/push.log + t-grep-mpat "$mpat" $tmp/push.log +} + t-822-field () { local file=$1 local field=$2 @@ -228,18 +781,190 @@ t-822-field () { ' <$file } -t-ref-dsc-dgit () { +t-defdistro () { + export DGIT_TEST_DISTRO='' + distro='' + t-git-config dgit-suite.unstable.distro test-dummy +} + +t-stunt-envvar () { + local var=$1 + local tstunt=$2 + eval ' + case "$'$var'" in + "$tstunt:"*) ;; + *":$tstunt:"*) ;; + "") '$var'="$tstunt" ;; + *) '$var'="$tstunt:$'$var'" ;; + esac + export '$var' + ' +} + +t-tstunt--save-real () { + local f="$1" + case "$f" in + */*) return ;; + esac + + local rc + local real + set +e + real=$( + p=":$PATH:" + p="${p/:"$tmp/tstunt":/:}" + p="${p%:}" + p="${p#:}" + PATH="$p" + type -p "$f" + ) + rc=$? + set -e + + case $rc in + 1) return ;; + 0) ;; + *) fail "did not find $f on PATH $PATH" ;; + esac + + local varname=${f//[^_0-9a-zA-Z]/_} + varname=DGIT_TEST_REAL_${varname^^} + + eval " + : \${$varname:=\$real} + export $varname + " +} + +t-tstunt () { + local tstunt=$tmp/tstunt + t-stunt-envvar PATH $tstunt + t-stunt-envvar PERLLIB $tstunt + local f + for f in "$@"; do + t-tstunt--save-real $f + f="./$f" + local d="$tstunt/${f%/*}" + mkdir -p $d + ln -sf "$troot/tstunt/$f" "$d"/. + done +} + +t-tstunt-parsechangelog () { + t-tstunt dpkg-parsechangelog Dpkg/Changelog/Parse.pm +} + +t-tstunt-lintian () { + t-tstunt lintian +} + +t-tstunt-debuild () { + t-tstunt debuild +} + +t-incoming-dsc () { local dsc=${p}_${v}.dsc - local val=`t-822-field $tmp/incoming/$dsc Dgit` - perl -e '$_=shift @ARGV; die "$dsc Dgit $_ ?" unless m/^\w+\b/;' "$val" - t-ref-same-val $dsc "$val" + incoming_dsc=$tmp/incoming/$dsc +} + +t-ref-dsc-dgit () { + t-incoming-dsc + local val; val=`t-822-field $incoming_dsc Dgit` + val=$( perl -e ' + $_=shift @ARGV; + die "Dgit $_ ?" unless m/^\w+\b/; + print $&,"\n" or die $!; + ' "$val") + t-ref-same-val $incoming_dsc "$val" } t-apply-diff () { local v1=$1 local v2=$2 - (cd $troot/pkg-srcs; debdiff ${p}_${v1}.dsc ${p}_${v2}.dsc) \ - | patch -p1 -u + (cd $troot/pkg-srcs; + debdiff ${p}_${v1}.dsc ${p}_${v2}.dsc || test $? = 1) \ + | patch -p1 -u +} + +t-gbp-unapplied-pq2qc () { + # does `gbp pq export' + # commits the resulting debian/patches on qc/BRANCH + # leaves us on qc/BRANCH (eg "qc/quilt-tip")) + # qc/BRANCH is not fast-forwarding + + gbp pq export + + branch=`git symbolic-ref HEAD` + branch=${branch#refs/heads/} + + case "$branch" in + */*) fail "unexpected branch $branch" ;; + esac + + git branch -f qc/$branch + git checkout qc/$branch + git add debian/patches + git commit -m 'Commit patch queue' +} + +t-git-pseudo-merge () { + # like git merge -s ours + if [ ! "$git_pseuomerge_opts" ]; then + if git merge --help \ + | grep -q allow-unrelated-histories; then + git_pseuomerge_opts='--allow-unrelated-histories' + fi + git_pseuomerge_opts+=' -s ours' + fi + git merge $git_pseuomerge_opts "$@" +} + +t-gbp-example-prep-no-ff () { + t-tstunt-parsechangelog + t-archive example 1.0-1 + t-git-none + t-worktree 1.0 + + cd example + + t-dgit fetch + + git checkout -b patch-queue/quilt-tip-2 patch-queue/quilt-tip + gbp pq rebase + + echo '/* some comment */' >>src.c + git add src.c + git commit -m 'Add a comment to an upstream file' + + t-gbp-unapplied-pq2qc + + t-commit 'some updates' 1.0-2 +} + +t-gbp-example-prep () { + t-gbp-example-prep-no-ff + + t-git-pseudo-merge \ + -m 'Pseudo-merge to make descendant of archive' \ + remotes/dgit/dgit/sid +} + +t-make-badcommit () { + badcommit=$( + git cat-file commit HEAD | \ + perl -pe 's/^committer /commiter /' | \ + git hash-object -w -t commit --stdin + ) + t-expect-fsck-fail $badcommit +} + +t-commit () { + local msg=$1 + v=${2:-${majorv:-1}.$revision} + dch --force-distribution -v$v --distribution ${3:-unstable} "$1" + git add debian/changelog + debcommit + revision=$(( ${revision-0} + 1 )) } t-git-config () { @@ -248,18 +973,126 @@ t-git-config () { t-drs () { export DGIT_TEST_TROOT=$troot - export DGIT_TEST_TMP=$tmp t-git-config dgit-distro.test-dummy.git-url "ext::$troot/drs-git-ext %S " t-git-config dgit-distro.test-dummy.git-check true t-git-config dgit-distro.test-dummy.git-create true - cp $root/tests/gnupg/{dd.gpg,dm.gpg,dm.txt} $tmp/. - cp $root/tests/suites $tmp/. + t-git-config dgit-distro.test-dummy.dgit-tag-format new,old,maint + cp $troot/gnupg/{dd.gpg,dm.gpg,dm.txt} $tmp/. + cp $troot/suites $tmp/. + cp $troot/suites $tmp/suites-master + + export t_check_pushed_master=t-check-pushed-master + + drs_dispatch=$tmp/distro=test-dummy + mkdir $drs_dispatch + + if [ "x$DGIT_TEST_INTREE" != x ]; then + ln -sf "$DGIT_TEST_INTREE" $drs_dispatch/dgit-live + fi + + ln -sf $tmp/git $drs_dispatch/repos + ln -sf $tmp/suites $tmp/suites-master $tmp/dm.txt $drs_dispatch/ + mkdir -p $drs_dispatch/keyrings + ln -sf $tmp/dd.gpg $drs_dispatch/keyrings/debian-keyring.gpg + ln -sf $tmp/dm.gpg $drs_dispatch/keyrings/debian-maintainers.gpg + ln -sf /bin/true $drs_dispatch/policy-hook +} + +t-newtag () { + export tagpfx=archive/test-dummy + t-git-config dgit-distro.test-dummy.dgit-tag-format new,maint +} +t-oldtag () { + export tagpfx=test-dummy + t-git-config dgit-distro.test-dummy.dgit-tag-format old } -t-drs-test () { +t-dsd () { t-drs + t-git-config dgit-distro.test-dummy.ssh "$troot/dsd-ssh" + t-git-config dgit-distro.test-dummy.git-check ssh-cmd + t-git-config dgit-distro.test-dummy.git-create true + t-git-config dgit-distro.test-dummy.git-url \ + "ext::$troot/dsd-ssh X %S /dgit/test-dummy/repos" + + t-git-config dgit-distro.test-dummy.diverts.drs /drs + t-git-config dgit-distro.test-dummy/drs.ssh "$troot/ssh" + t-git-config dgit-distro.test-dummy/drs.git-url $tmp/git + t-git-config dgit-distro.test-dummy/drs.git-check ssh-cmd + t-git-config dgit-distro.test-dummy/drs.git-create ssh-cmd + + echo 'no-such-package* drs' >$drs_dispatch/diverts +} + +t-policy-admin () { + : '((((((((((((((((((((((((((((((((((((((((' + ${DGIT_INFRA_PFX}dgit-repos-admin-debian --repos $tmp/git "$@" + : '))))))))))))))))))))))))))))))))))))))))' +} + +t-policy-nonexist () { + ln -sf no-such-file-or-directory $drs_dispatch/policy-hook +} + +t-make-hook-link () { + local hook=$1 # in infra/ + local linkpath=$2 + hook=${DGIT_INFRA_PFX}$hook + case $hook in + */*) ;; + *) hook=`type -P $hook` ;; + esac + ln -sf "$hook" $linkpath +} + +t-policy () { + local policyhook=$1 + t-make-hook-link $policyhook $drs_dispatch/policy-hook +} + +t-debpolicy () { + t-dsd + t-policy dgit-repos-policy-debian + + mkdir $tmp/git + t-policy-admin create-db +} + +t-policy-periodic () { + : '((((((((((((((((((((((((((((((((((((((((' + ${DGIT_REPOS_SERVER_TEST-dgit-repos-server} \ + test-dummy $drs_dispatch '' --cron + : '))))))))))))))))))))))))))))))))))))))))' +} + +t-restrict () { + local restriction=$1 + (cd $root; t-restriction-$restriction >&2) +} + +t-dependencies () { + : "Hopefully installed: $*" +} + +t-chain-test () { + local ct=$1 + local d=${0%/*} cd $root export DGIT_TEST_TESTNAME="$testname" + export DGIT_TEST_TMPBASE="$tmpbase" export ADTTMP=$tmp - exec "${0///drs-//}" "$@" + exec "$d/$ct" +} + +t-alt-test () { + local t=${0##*/} + t-${t%%-*} + t-chain-test "${t#*-}" } + +t-git-config dgit.default.old-dsc-distro test-dummy + +case "$0" in +*/gnupg) ;; +*) t-setup-import gnupg ;; +esac diff --git a/tests/lib-build-modes b/tests/lib-build-modes new file mode 100644 index 0000000..ee2975d --- /dev/null +++ b/tests/lib-build-modes @@ -0,0 +1,235 @@ + +bm-prep-ownpackage-branches () { + cat <<'END' >$tmp/stunt-git +#!/bin/sh -e +case "$*" in +*clean*) echo >&2 "BUILD-MODES PROGRAM git $*" ;; +esac +exec git "$@" +END + chmod +x $tmp/stunt-git + + bm_branches="$1" +} + +bm-prep () { + t-tstunt-parsechangelog + + t-prep-newpackage example 1.0 + + cd $p + + git checkout -b bad-build-deps indep-arch + perl -pe 's/Build-Depends.*/$&, x-dgit-no-such-package/' \ + -i debian/control + git commit -a -m bad-build-deps + + bm-prep-ownpackage-branches 'indep-arch bad-build-deps' + + if zgrep 'dpkg-buildpackage: Make dependency checks fatal for -S' \ + /usr/share/doc/dpkg-dev/changelog.gz; then + dpkgbuildpackage_deps_for_clean=true + else + dpkgbuildpackage_deps_for_clean=false + fi + + cleanmodes_default="git none dpkg-source dpkg-source-d" + cleanmodes_all="$cleanmodes_default git-ff check" + cleanmodes="$cleanmodes_default" +} + +bm-gbp-example-acts () { + t-gbp-example-prep + + git checkout -b for-build-modes qc/quilt-tip-2 + # build-modes cannot cope with branches containing / + + bm-prep-ownpackage-branches for-build-modes + + cleanmodes='git dpkg-source' + + for act in "$@"; do + bm-guess-e-source-e-targets "$act" + real_act="--quilt=gbp $act" + case "$act" in + sbuild*) bm_quirk_after_act=bm-quirk-sbuild-after-act ;; + gbp-*) real_act="$real_act --git-ignore-branch" ;; + *) bm_quirk_after_act='' ;; + esac + bm-act-iterate + done +} + +bm-guess-e-source-e-targets () { + local some_act=$1 + case "$some_act" in + sbuild*" --no-arch-all"*) + e_source=true; e_targets='build-arch binary-arch' ;; + build-source) + e_source=true; e_targets='' ;; + *" -b") e_source=false; e_targets='build binary' ;; + *" -B") e_source=false; e_targets='build-arch binary-arch' ;; + *" -A") e_source=false; e_targets='build-indep binary-indep' ;; + *" -S") e_source=true; e_targets=' ' ;; + *" -F") e_source=true; e_targets='build binary' ;; + *" -G") e_source=true; e_targets='build-arch binary-arch' ;; + *" -g") e_source=true; e_targets='build-indep binary-indep' ;; + *) e_source=true; e_targets='build binary' ;; + esac +} + +bm-quirk-sbuild-after-act () { + # sbuild likes to run the package clean target in the chroot, + # which isn't necessary in our case. We don't disable it in + # dgit because we want to do what sbuild does, in case there + # are packages which don't build unless their clean target was + # run. We know it must be running it in the chroot because we + # provide sbuild with the dsc, not the tree, so we simply + # ignore all executions of the clean target by schroot. + local arch; arch=$(dpkg-architecture -qDEB_BUILD_ARCH) + local sblog=../example_${v}_$arch.build + if [ -e $sblog ]; then + sed ' + s/^EXAMPLE RULES TARGET clean/HOOK SUPPRESSED &/; + ' <$sblog >>$bmlog + else + echo "SBUILD LOG FILE ($sblog) MISSING" + fi +} + +bm-report-test () { + local desc=$1; shift + if "$@"; then + echo >&4 "$desc EXISTS" + else + echo >&4 "$desc MISSING" + fi +} + +bm-build-deps-ok () { + case "$branch" in + *bad-build-deps*) return 1 ;; + *) return 0 ;; + esac +} + +bm-compute-expected () { + require_fail=unexpect # or required + tolerate_fail=unexpect # or tolerate + + exec 4>$bmexp + echo >&4 "$heading" + + case $cleanmode in + git) echo >&4 'BUILD-MODES PROGRAM git clean -xdf' ;; + git-ff) echo >&4 'BUILD-MODES PROGRAM git clean -xdff' ;; + check) echo >&4 'BUILD-MODES PROGRAM git clean -xdn' ;; + dpkg-source-d) echo >&4 "EXAMPLE RULES TARGET clean" ;; + dpkg-source) bm-build-deps-ok || tolerate_fail=tolerate + echo >&4 "EXAMPLE RULES TARGET clean" + ;; + none) ;; + *) fail "t-compute-expected-run $cleanmode ??" ;; + esac + + if [ "x$e_targets" != x ]; then + # e_targets can be " " to mean `/may/ fail due to b-d' + bm-build-deps-ok || tolerate_fail=tolerate + fi + + for t in $e_targets; do + bm-build-deps-ok || require_fail=required + echo >&4 "EXAMPLE RULES TARGET $t" + done + + bm-report-test "SOURCE FILE" $e_source + bm-report-test "SOURCE IN CHANGES" $e_source + bm-report-test "DEBS IN CHANGES" expr "$e_targets" : '.*binary.*' + + exec 4>&- +} + +bm-run-one () { + local args="$DGIT_TEST_BM_BASEARGS --clean=$cleanmode $real_act" + + bmid="$act,$cleanmode,$branch" + bmid=${bmid// /_} + + rm -f ../${p}_{v}_*.changes + + heading="===== [$bmid] dgit $args =====" + + bmlog=$tmp/run.$bmid.output + bmexp=$tmp/run.$bmid.expected + bmgot=$tmp/run.$bmid.results + + bm-compute-expected + + git checkout $branch + git clean -xdf # since we might not do any actual cleaning + + dsc="../example_$v.dsc" + rm -f $dsc + + set +o pipefail + t-dgit --rm-old-changes --git=$tmp/stunt-git $args 2>&1 | tee $bmlog + local ps="${PIPESTATUS[*]}" + set -o pipefail + + $bm_quirk_after_act + + exec 4>$bmgot + echo >&4 "$heading" + + case $ps in + "0 0") actual_status=success ;; + *" 0") actual_status=failure; echo >&4 "OPERATION FAILED"; ;; + *) fail "tee failed" ;; + esac + + case "$require_fail-$tolerate_fail-$actual_status" in + required-********-failure) echo >>$bmexp "REQUIRED FAILURE" ;; + ********-tolerate-failure) echo >>$bmexp "TOLERATED FAILURE" ;; + unexpect-********-success) ;; + *) fail "RF=$require_fail TF=$tolerate_fail AS=$actual_status" ;; + esac + + egrep >&4 '^EXAMPLE RULES TARGET|^BUILD-MODES' $bmlog || [ $? = 1 ] + + bm-report-test "SOURCE FILE" [ -e $dsc ] + + if [ $actual_status = success ]; then + local changes; changes=$(echo ../example_${v}_*.changes) + case "$changes" in + *' '*) fail "build generated ambiguous .changes: $changes" ;; + esac + + perl -ne 'print if m/^files:/i ... m/^\S/' \ + <$changes >$changes.files + + bm-report-test "SOURCE IN CHANGES" grep '\.dsc$' $changes.files + bm-report-test "DEBS IN CHANGES" grep '\.deb$' $changes.files + fi + + exec 4>&- + + $bm_quirk_before_diff + + [ $actual_status = failure ] || diff -U10 $bmexp $bmgot +} + +bm-act-iterate () { + for cleanmode in $cleanmodes; do + for branch in $bm_branches; do + bm-run-one + done + done + : bm-act-iterate done. +} + +bm-alwayssplit () { + local t=${0##*/} + DGIT_TEST_BM_BASEARGS+=' --always-split-source-build' + export DGIT_TEST_BM_BASEARGS + t-chain-test "${t%%-asplit}" +} diff --git a/tests/lib-core b/tests/lib-core new file mode 100644 index 0000000..6cdffeb --- /dev/null +++ b/tests/lib-core @@ -0,0 +1,38 @@ +# + +fail () { + echo >&2 "failed: $*" + exit 1 +} + +t-set-intree () { + if [ "x$DGIT_TEST_INTREE" = x ]; then return; fi + : ${DGIT_TEST:=$DGIT_TEST_INTREE/dgit} + : ${DGIT_BADCOMMIT_FIXUP:=$DGIT_TEST_INTREE/dgit-badcommit-fixup} + : ${DGIT_REPOS_SERVER_TEST:=$DGIT_TEST_INTREE/infra/dgit-repos-server} + : ${DGIT_SSH_DISPATCH_TEST:=$DGIT_TEST_INTREE/infra/dgit-ssh-dispatch} + : ${DGIT_INFRA_PFX:=$DGIT_TEST_INTREE${DGIT_TEST_INTREE:+/infra/}} + export DGIT_TEST DGIT_BADCOMMIT_FIXUP + export DGIT_REPOS_SERVER_TEST DGIT_SSH_DISPATCH_TEST + export PERLLIB="$DGIT_TEST_INTREE${PERLLIB:+:}${PERLLIB}" +} + +t-set-using-tmp () { + export HOME=$tmp + export DGIT_TEST_DUMMY_DIR=$tmp + export DGIT_TEST_TMP=$tmp + export GNUPGHOME=$tmp/nonexistent + git config --global user.email 'dgit-test@debian.example.net' + git config --global user.name 'dgit test git user' +} + +t-filter-out-git-hyphen-dir () { + local pathent; pathent=$(type -p git-rev-parse ||:) + case "$pathent" in '') return ;; esac + pathent=${pathent%/*} + local path=":$PATH:" + path="${path//:$pathent:/}" + path="${path#:}" + path="${path%:}" + PATH="$path" +} diff --git a/tests/lib-import-chk b/tests/lib-import-chk new file mode 100644 index 0000000..88984c1 --- /dev/null +++ b/tests/lib-import-chk @@ -0,0 +1,97 @@ + +t-import-chk-authorship () { + perl -ne 'print $1,"\n" if m/^ -- (\S.*\>) /' debian/changelog \ + | sort -u \ + > $tmp/authorship.changelog + ${import_chk_changelog_massage:-:} $tmp/authorship.changelog + git log --pretty=format:'%an <%ae>%n%cn <%ce>' \ + | sort -u \ + > $tmp/authorship.commits + diff $tmp/authorship.{changelog,commits} +} + +t-import-chk1 () { + p=$1 + v=$2 + + t-archive $p $v +} +t-import-chk2() { + t-git-none + rm -rf $p + t-dgit --no-rm-on-error clone $p + + # And now we make an update using the same orig tarball, and + # check that the orig import is stable. + + cd $p + + t-import-chk-authorship + + git branch first-import + + m='Commit for import check' + echo "$m" >>import-check + + v=${v%-*}-99 + dch -v $v -D unstable -m "$m" + + git add import-check debian/changelog + git commit -m "$m" + + t-dgit -wgf quilt-fixup + t-dgit -wgf build-source + + # The resulting .dsc does not have a Dgit line (because dgit push + # puts that in). So we just shove it in the archive now + + ln ../${p}_${v}.* $tmp/mirror/pool/main/ + t-archive-query + + t-dgit fetch + + git branch first-2nd-import remotes/dgit/dgit/sid + + t-git-next-date + + git update-ref refs/remotes/dgit/dgit/sid first-import + + t-dgit fetch + + t-refs-same-start + t-ref-same refs/remotes/dgit/dgit/sid + t-ref-same refs/heads/first-2nd-import + + for orig in ../${p}_${v%-*}.orig*.tar.*; do + tar -atf $orig | LC_ALL=C sort >../files.o + pfx=$(perl <../files.o -ne ' + while (<>) { + m#^([^/]+/)# or exit 0; + $x //= $1; + $x eq $1 or exit 0; + } + print "$x\n"; + ') + perl -i~ -pe ' + s#^\Q'"$pfx"'\E##; + $_="" if m/^$/ || m#/$# || m#^\.git/#; + ' ../files.o + orig=${orig#../} + pat="^Import ${orig//./\\.}\$" + t-refs-same-start + for start in first-import first-2nd-import; do + git log --pretty='tformat:%H' --grep "$pat" $start \ + >../t.imp + test $(wc -l <../t.imp) = 1 + imp=$(cat ../t.imp) + t-ref-same-val "$orig $start" "$imp" + done + git ls-tree -r --name-only "$t_ref_val:" \ + | sort >../files.g + diff ../files.{o,g} + done + cd .. +} + +t-import-chk() { t-import-chk1 "$@"; t-import-chk2; } + diff --git a/tests/lib-mirror b/tests/lib-mirror new file mode 100644 index 0000000..25f0f90 --- /dev/null +++ b/tests/lib-mirror @@ -0,0 +1,42 @@ + +t-mirror-setup () { + # p must be set already + + reposmirror=$tmp/git-mirror + pmirror=$reposmirror/$p.git + queuedir=$tmp/git/_mirror-queue + + mkdir $reposmirror + + mirror_hook=$drs_dispatch/mirror-hook + t-make-hook-link dgit-mirror-rsync $mirror_hook + + >$drs_dispatch/mirror-settings + t-mirror-set remoterepos="$reposmirror" + + t-mirror-hook setup +} + +t-mirror-set () { + echo >>$drs_dispatch/mirror-settings "$1" +} + +t-mirror-hook () { + : '((((((((((((((((((((((((((((((((((((((((' + "$mirror_hook" "$drs_dispatch" "$@" + : '))))))))))))))))))))))))))))))))))))))))' +} + +t-check-mirrored () { + t-reporefs master + t-reporefs mirror $pmirror + diff $tmp/show-refs.{master,mirror} + cat $queuedir/$p.log ||: + t-files-notexist $queuedir/$p.{n,a,lock,err} +} + +t-check-not-mirrored () { + # uses previous t-reporefs-master + t-reporefs mirror $pmirror + diff $tmp/show-refs.{master,mirror} +} diff --git a/tests/lib-orig-include-exclude b/tests/lib-orig-include-exclude new file mode 100644 index 0000000..104cf0b --- /dev/null +++ b/tests/lib-orig-include-exclude @@ -0,0 +1,67 @@ +# designed to be .'d + +t-tstunt-parsechangelog + +t-archive example 1.0-1 +t-git-none + +t-dgit clone $p + +origs='orig orig-docs' +usvsns='1.0 1.1' + +for o in $origs; do + cp ${p}_{1.0,1.1}.${o}.tar.gz +done + +mkdir -p "$tmp/aq/file_in_archive/%" + +cd $p + +test-push-1 () { + v=$1 + ch=$2 + suite=$3 + + t-commit $v $v $suite + t-dgit $ch build +} + +test-push-2 () { + $test_push_2_hook + t-dgit $ch "$@" push +} + +test-push-1 1.0-2 --ch:-sa + +grep orig ../${p}_${v}_*.changes + +test-push-2 + +origs_findls () { + find $tmp/mirror -name '*orig*' -ls \ + | perl -pe 's/^(\s*\d+\s+\d+\s+\S+\s)\s*\d+(\s)/$1$2/' +} + +# check that dgit stripped out the orig update +origs_findls >../before + +t-archive-process-incoming sid + +origs_findls >../after +diff -u ../before ../after + +test-push-1 1.1-1.2 --ch:-sd + +test-push-2 + +t-archive-process-incoming sid + +cd .. +mkdir get +cd get + +t-dgit clone $p +# ^ checks that all the origs are there, ie that dgit added the origs + +cd .. diff --git a/tests/lib-reprepro b/tests/lib-reprepro new file mode 100644 index 0000000..0a688f6 --- /dev/null +++ b/tests/lib-reprepro @@ -0,0 +1,97 @@ +# -*- bash -*- + +t-reprepro () { + + t_archive_method=reprepro + + t-reprepro-cfg +} + +t-reprepro-cfg () { + local rrinst=$1 + local rrdistro=${2:-test-dummy} + + local etcapt=$tmp/${rrinst}etc-apt + local mir=$tmp/${rrinst}mirror + + t-git-config dgit-distro.$rrdistro.archive-query aptget: + t-git-config dgit-distro.$rrdistro.mirror file://$mir/ + + mkdir $etcapt + cat >$etcapt/conf <<END +Dir::Etc "$etcapt"; +END + export APT_CONFIG=$etcapt/conf + gpg --export Hannibal >han.pgp + fakeroot apt-key add <han.pgp + mkdir $etcapt/apt.conf.d +} + +t-archive-none-reprepro () { # hook called by t-archive-none + t-reprepro-setup + t-reprepro-regen + local rrinst= +} +t-archive-query-reprepro () { # hook called by t-archive-query + local suite=$1 + local p=$2 + local v=$3 + local dscf=$4 + local rrinst= + t-reprepro-includedsc $suite $tmp/mirror/pool/$dscf "$rrinst" +} + +t-reprepro-setup () { + local rrinst=$1 + + local mir=$tmp/${rrinst}mirror + local rrc=$mir/conf + mkdir -p $rrc + mkdir -p $mir/pool/main + + exec 3>$rrc/distributions + + local arch; arch=`dpkg --print-architecture` + + for suitespec in $suitespecs; do + local suite=${suitespec%%:*} + local sname=${suitespec#*:} + + mkdir -p $mir/dists + if [ $sname != $suite ]; then + rm -f $mir/dists/$sname + ln -s $suite $mir/dists/$sname + fi + + cat >&3 <<END +Suite: $sname +Codename: $suite +Components: main +Architectures: source binary-$arch +SignWith: Hannibal + +END + done +} + +t-reprepro-includedsc () { + local suite=$1 + local dscf=$2 + local rrinst=$3 + t-reprepro--run includedsc $suite $dscf +} + +t-reprepro--run () { + # caller is supposed to have set rrinst + local mir=$tmp/${rrinst}mirror + reprepro \ + --outdir $mir \ + --basedir $mir \ + "$@" +} + +t-reprepro-regen () { + local rrinst=$1 + + t-reprepro--run export +} diff --git a/tests/lib-restricts b/tests/lib-restricts new file mode 100644 index 0000000..bffe13a --- /dev/null +++ b/tests/lib-restricts @@ -0,0 +1,22 @@ +#!/bin/sh + +t-restriction-x-dgit-intree-only () { + if [ "x$DGIT_TEST_INTREE" != x ]; then return 0; fi + echo 'running installed package version' + return 1 +} + +t-restriction-x-dgit-git-only () { + if test -d .git; then return 0; fi + echo 'not running out of git clone' + return 1 +} + +t-restriction-x-dgit-schroot-build () { + schroot -l -c build 2>&1 >/dev/null || return 1 +} + +t-restriction-x-dgit-unfinished () { + echo 'unfinished test, or unfinished feature' + return 1 +} diff --git a/tests/pkg-srcs/example_1.0-1+absurd.debian.tar.xz b/tests/pkg-srcs/example_1.0-1+absurd.debian.tar.xz Binary files differnew file mode 100644 index 0000000..9a2dd12 --- /dev/null +++ b/tests/pkg-srcs/example_1.0-1+absurd.debian.tar.xz diff --git a/tests/pkg-srcs/example_1.0-1+absurd.dsc b/tests/pkg-srcs/example_1.0-1+absurd.dsc new file mode 100644 index 0000000..1ab743d --- /dev/null +++ b/tests/pkg-srcs/example_1.0-1+absurd.dsc @@ -0,0 +1,22 @@ +Format: 3.0 (quilt) +Source: example +Binary: example +Architecture: all +Version: 1.0-1+absurd +Maintainer: Ian Jackson <ijackson@chiark.greenend.org.uk> +Standards-Version: 3.9.4.0 +Build-Depends: debhelper (>= 8) +Package-List: + example deb devel extra arch=all +Checksums-Sha1: + 2bc730f941db49de57e9678fb0b07bd95507bb44 236 example_1.0.orig-docs.tar.gz + 4bff9170ce9b10cb59937195c5ae2c73719fe150 373 example_1.0.orig.tar.gz + dafb6f0db0580179ff246dba1dc2892246e84a2c 1416 example_1.0-1+absurd.debian.tar.xz +Checksums-Sha256: + ad9671f6b25cdd9f0573f803f702448a45a45183db1d79701aa760bccbeed29c 236 example_1.0.orig-docs.tar.gz + a3ef7c951152f3ec754f96fd483457aa88ba06df3084e6f1cc7c25b669567c17 373 example_1.0.orig.tar.gz + 4003c34398894e46823bb3fda69f4351dbd5649e321259cde266a135f0428c51 1416 example_1.0-1+absurd.debian.tar.xz +Files: + cb0cb5487b1e5bcb82547396b4fe93e5 236 example_1.0.orig-docs.tar.gz + 599f47808a7754c66aea3cda1b3208d6 373 example_1.0.orig.tar.gz + 0e88c1ed094f09ee7bf57607132d55ee 1416 example_1.0-1+absurd.debian.tar.xz diff --git a/tests/pkg-srcs/example_1.0-1.100.debian.tar.xz b/tests/pkg-srcs/example_1.0-1.100.debian.tar.xz Binary files differnew file mode 100644 index 0000000..ea8ec34 --- /dev/null +++ b/tests/pkg-srcs/example_1.0-1.100.debian.tar.xz diff --git a/tests/pkg-srcs/example_1.0-1.100.dsc b/tests/pkg-srcs/example_1.0-1.100.dsc new file mode 100644 index 0000000..5b075b5 --- /dev/null +++ b/tests/pkg-srcs/example_1.0-1.100.dsc @@ -0,0 +1,22 @@ +Format: 3.0 (quilt) +Source: example +Binary: example +Architecture: all +Version: 1.0-1.100 +Maintainer: Ian Jackson <ijackson@chiark.greenend.org.uk> +Standards-Version: 3.9.4.0 +Build-Depends: debhelper (>= 8) +Package-List: + example deb devel extra arch=all +Checksums-Sha1: + 2bc730f941db49de57e9678fb0b07bd95507bb44 236 example_1.0.orig-docs.tar.gz + 4bff9170ce9b10cb59937195c5ae2c73719fe150 373 example_1.0.orig.tar.gz + 86c31eba5e08c1765f8e557b97e59d7e1fd9c208 2108 example_1.0-1.100.debian.tar.xz +Checksums-Sha256: + ad9671f6b25cdd9f0573f803f702448a45a45183db1d79701aa760bccbeed29c 236 example_1.0.orig-docs.tar.gz + a3ef7c951152f3ec754f96fd483457aa88ba06df3084e6f1cc7c25b669567c17 373 example_1.0.orig.tar.gz + 163f1a753f0ea382148df8d9553240d503781badf03c600946f1400534da1349 2108 example_1.0-1.100.debian.tar.xz +Files: + cb0cb5487b1e5bcb82547396b4fe93e5 236 example_1.0.orig-docs.tar.gz + 599f47808a7754c66aea3cda1b3208d6 373 example_1.0.orig.tar.gz + 4b7f5d286eff2608107c77c96584a01a 2108 example_1.0-1.100.debian.tar.xz diff --git a/tests/pkg-srcs/example_1.0-1.debian.tar.xz b/tests/pkg-srcs/example_1.0-1.debian.tar.xz Binary files differnew file mode 100644 index 0000000..84ca563 --- /dev/null +++ b/tests/pkg-srcs/example_1.0-1.debian.tar.xz diff --git a/tests/pkg-srcs/example_1.0-1.dsc b/tests/pkg-srcs/example_1.0-1.dsc new file mode 100644 index 0000000..bb65f6e --- /dev/null +++ b/tests/pkg-srcs/example_1.0-1.dsc @@ -0,0 +1,22 @@ +Format: 3.0 (quilt) +Source: example +Binary: example +Architecture: all +Version: 1.0-1 +Maintainer: Ian Jackson <ijackson@chiark.greenend.org.uk> +Standards-Version: 3.9.4.0 +Build-Depends: debhelper (>= 8) +Package-List: + example deb devel extra arch=all +Checksums-Sha1: + 2bc730f941db49de57e9678fb0b07bd95507bb44 236 example_1.0.orig-docs.tar.gz + 4bff9170ce9b10cb59937195c5ae2c73719fe150 373 example_1.0.orig.tar.gz + f2398be1e588e10d11b20ee9bc5ca0eb16e4c158 1304 example_1.0-1.debian.tar.xz +Checksums-Sha256: + ad9671f6b25cdd9f0573f803f702448a45a45183db1d79701aa760bccbeed29c 236 example_1.0.orig-docs.tar.gz + a3ef7c951152f3ec754f96fd483457aa88ba06df3084e6f1cc7c25b669567c17 373 example_1.0.orig.tar.gz + fd97c0fb879bfa8084f24a0d0f808a56beb533f17d92c808dc293ff297007925 1304 example_1.0-1.debian.tar.xz +Files: + cb0cb5487b1e5bcb82547396b4fe93e5 236 example_1.0.orig-docs.tar.gz + 599f47808a7754c66aea3cda1b3208d6 373 example_1.0.orig.tar.gz + fd7840d249ee3dba5bdc3dcde7217bbe 1304 example_1.0-1.debian.tar.xz diff --git a/tests/pkg-srcs/example_1.0.orig-docs.tar.gz b/tests/pkg-srcs/example_1.0.orig-docs.tar.gz Binary files differnew file mode 100644 index 0000000..f8427aa --- /dev/null +++ b/tests/pkg-srcs/example_1.0.orig-docs.tar.gz diff --git a/tests/pkg-srcs/example_1.0.orig.tar.gz b/tests/pkg-srcs/example_1.0.orig.tar.gz Binary files differnew file mode 100644 index 0000000..e5d2cf3 --- /dev/null +++ b/tests/pkg-srcs/example_1.0.orig.tar.gz diff --git a/tests/pkg-srcs/sunxi-tools_1.2-2.~~dgittest.debian.tar.gz b/tests/pkg-srcs/sunxi-tools_1.2-2.~~dgittest.debian.tar.gz Binary files differnew file mode 100644 index 0000000..c376961 --- /dev/null +++ b/tests/pkg-srcs/sunxi-tools_1.2-2.~~dgittest.debian.tar.gz diff --git a/tests/pkg-srcs/sunxi-tools_1.2-2.~~dgittest.dsc b/tests/pkg-srcs/sunxi-tools_1.2-2.~~dgittest.dsc new file mode 100644 index 0000000..e0161cd --- /dev/null +++ b/tests/pkg-srcs/sunxi-tools_1.2-2.~~dgittest.dsc @@ -0,0 +1,22 @@ +Format: 3.0 (quilt) +Source: sunxi-tools +Binary: sunxi-tools +Architecture: any +Version: 1.2-2.~~dgittest +Maintainer: Ian Campbell <ijc@hellion.org.uk> +Homepage: http://linux-sunxi.org/Sunxi-tools +Standards-Version: 3.9.5 +Vcs-Browser: http://git.debian.org/?p=collab-maint/sunxi-tools.git +Vcs-Git: git://git.debian.org/collab-maint/sunxi-tools.git +Build-Depends: debhelper (>= 9), pkg-config, libusb-1.0-0-dev, u-boot-tools +Package-List: + sunxi-tools deb utils optional +Checksums-Sha1: + 2457216dbbf5552c413753f7211f7be3db6aff54 35076 sunxi-tools_1.2.orig.tar.gz + 6f30698cd897b350a4f92b2b5dded69adca6f82e 5182 sunxi-tools_1.2-2.~~dgittest.debian.tar.gz +Checksums-Sha256: + 03a63203ff79389e728d88ad705e546aa6362a6d08b9901392acb8639998ef95 35076 sunxi-tools_1.2.orig.tar.gz + 0a513f3254d245b59aaffbeb5c43159a6461617c1f6f3c6824646c4259cda406 5182 sunxi-tools_1.2-2.~~dgittest.debian.tar.gz +Files: + dbc55f60559f9db497559176c3c753dd 35076 sunxi-tools_1.2.orig.tar.gz + a6ec0eb0d897b0121dc978fc00db2ea6 5182 sunxi-tools_1.2-2.~~dgittest.debian.tar.gz diff --git a/tests/pkg-srcs/sunxi-tools_1.2.orig.tar.gz b/tests/pkg-srcs/sunxi-tools_1.2.orig.tar.gz Binary files differnew file mode 100644 index 0000000..fe397fa --- /dev/null +++ b/tests/pkg-srcs/sunxi-tools_1.2.orig.tar.gz diff --git a/tests/run-all b/tests/run-all index e2e2a6f..3877c76 100755 --- a/tests/run-all +++ b/tests/run-all @@ -1,13 +1,21 @@ -#!/bin/sh +#!/bin/bash set -e # convenience script for running the tests outside adt-run -if [ $# = 0 ]; then - set `run-parts --list tests/tests` +# usage: tests/using-intree tests/run-all + +set -o pipefail + +set +e +jcpus=`perl -MSys::CPU -we 'printf "-j%d\n", 1.34 * Sys::CPU::cpu_count()'` +set -e + +if [ $# != 0 ]; then + set TESTSCRIPTS="$*" fi -for f in $@; do - echo ================================================== - echo $f - $f - echo ================================================== -done -echo "ALL PASSED" + +mkdir -p tests/tmp + +( + set -x + exec make $jcpus -k -f tests/Makefile "$@" +) 2>&1 |tee tests/tmp/run-all.log diff --git a/tests/setup/examplegit b/tests/setup/examplegit new file mode 100755 index 0000000..112e27a --- /dev/null +++ b/tests/setup/examplegit @@ -0,0 +1,53 @@ +#!/bin/bash +set -e +. tests/lib + +suitespecs+=' stable testing' + +t-tstunt-parsechangelog + +t-prep-newpackage example 1.0 + +cd $p + +revision=1 + +push-to () { + t-refs-same-start + t-ref-head + t-dgit build + t-dgit push --new $2 + t-pushed-good $1 $2 + t-archive-process-incoming $2 +} + +echo ancestor >which +git add which +t-commit Ancestor '' stable +push-to master stable + +git checkout -b stable + +echo stable >which +git add which +t-commit Stable '' stable +push-to stable stable + +git checkout master + +majorv=2 +revision=0 + +echo sid >which +git add which +t-commit Sid +push-to master sid + +echo sid-again >>which +git add which +t-commit Sid +push-to master sid + +t-setup-done 'p v suitespecs majorv revision' "aq git mirror $p" + +t-ok diff --git a/tests/setup/gnupg b/tests/setup/gnupg new file mode 100755 index 0000000..43a5c96 --- /dev/null +++ b/tests/setup/gnupg @@ -0,0 +1,30 @@ +#!/bin/bash +set -e +. tests/lib + +mkdir -p $tmp/gnupg +cp $troot/gnupg/* $tmp/gnupg +chmod go-rw $tmp/gnupg/* + +export GNUPGHOME=$tmp/gnupg + +cat >$tmp/gnupg/gpg-agent.conf <<END +log-file $tmp/gnupg/AGENT.log +END +#debug-all + +setup=' + : ${DGIT_TEST_REAL_GPG_AGENT:=$(type -p gpg-agent)} + export DGIT_TEST_REAL_GPG_AGENT=$(type -p gpg-agent) + export DGIT_STUNT_AGENT=$troot/tstunt/gpg-agent + export GNUPGHOME + t-tstunt gpg +' + +eval "$setup" + +gpg --list-secret + +t-setup-done 'GNUPGHOME' 'gnupg' "$setup" + +t-ok diff --git a/tests/tartree-edit b/tests/tartree-edit index 2e0c017..40bd6e9 100755 --- a/tests/tartree-edit +++ b/tests/tartree-edit @@ -2,10 +2,74 @@ set -e fail () { echo >&2 "$0: $*"; exit 1; } +play=.git/tartree-edit-work + +git_manip_play () { + local wd; wd=$(pwd) + case "$wd" in + *.edit) fail "bad idea to run gitfetchinfo into a .edit tree!" ;; + esac + rm -rf $play + mkdir $play +} + +gitfetchdiff_list () { + git for-each-ref --format '%(refname) %(objectname)' \ + refs/remotes/"$1" \ + | sed 's/^refs\/remotes\/[^\/]*\///' \ + | sort >"$play/$2" +} + +gitfetchdiff () { + local how="$1" + local a="$2" + local b="$3" + git_manip_play + + rrab=refs/remotes/"$a+$b" + + ulf=\ +"delete refs/remotes/$a/%l +delete refs/remotes/$b/%l +" + case "$how" in + diff) + git for-each-ref --format 'delete %(refname)' $rrab \ + | git update-ref --stdin + ;; + merge) + ulf=\ +"create $rrab/%l +$ulf" + ;; + *) + fail "internal error bad how ($how)" + ;; + esac + + gitfetchdiff_list "$a" a + gitfetchdiff_list "$b" b + + diff --old-line-format='' --new-line-format='' \ + --unchanged-line-format="$ulf" \ + $play/a $play/b >$play/updates \ + || test $? = 1 + + git update-ref --stdin <$play/updates + exit 0 +} + case "$#.$1" in 2.edit|2.done) mode="$1"; arg="$2" ;; -2.-*) fail "no options understood" ;; -*) fail "usage: tartree-edit edit|done DIRECTORY" ;; +3.gitfetchinfo) mode="$1"; arg="$2"; remote="$3" ;; +3.gitfetchinfo-diff) gitfetchdiff diff "$2" "$3" ;; +3.gitfetchinfo-merge) gitfetchdiff merge "$2" "$3" ;; +?.-*) fail "no options understood" ;; +*) fail "usage: + tartree-edit edit|done DIRECTORY|TARBALL + tartree-edit gitfetchinfo DIRECTORY|TARBALL REMOTE + tartree-edit gitfetchinfo-merge REMOTE-A REMOTE-B" ;; + # we don't document gitfetchinfo-diff because it's rather poor esac case "$arg" in @@ -39,6 +103,83 @@ tryat_edit () { fi } +gitfetchinfo_perhaps_commit () { + local m="$1" + set +e + git diff --cached --quiet --exit-code HEAD + local rc=$? + set -e + case "$rc" in + 0) return ;; + 1) git commit --allow-empty --author='tartree-edit <>' -m "$m" ;; + *) fail "git diff failed ($rc)" ;; + esac +} + +tryat_gitfetchinfo () { + git_manip_play + + if test -d "$b.edit"; then + cp -a "$b.edit"/. "$play"/. + else + exec 3<"$b.tar" + tar -C $play -f - <&3 -x + exec 3<&- + fi + + local innerwd; innerwd="$(echo $play/*)" + + git for-each-ref --format='%(refname)' refs/remotes >$play/l + perl -w -ne ' + our %remerge; + use strict; + chomp; + next unless m#^refs/remotes/([^/]+)/#; + my $old = $_; + my $ab = $1; + my $rhs = $'\''; + my @ab = split /\+/, $ab; + next unless @ab == 2; + next unless (grep { $_ eq "'"$remote"'" } @ab) == 1; + $remerge{"@ab"} = 1; + print "update refs/remotes/$_/$rhs $old\n" or die $! foreach @ab; + print "delete $old\n" or die $!; + END { + open REMERGE, ">&3" or die $!; + print REMERGE "$_\n" or die $! foreach sort keys %remerge; + close REMERGE or die $!; + } + ' <$play/l >$play/unmerge 3>$play/remerge + git update-ref --stdin <$play/unmerge + + git remote remove "$remote" 2>/dev/null ||: + git remote add "$remote" $innerwd + git fetch --no-tags -p "$remote" \ + +"HEAD:refs/remotes/$remote/TT-HEAD" + cd $innerwd + GIT_AUTHOR_DATE=$(git log -n1 --pretty=format:'%ai') + GIT_COMMITTER_DATE=$GIT_AUTHOR_DATE + export GIT_COMMITTER_DATE GIT_AUTHOR_DATE + git checkout -b WORKTREE + gitfetchinfo_perhaps_commit 'UNCOMMITTED INDEX' + git add -Af . + gitfetchinfo_perhaps_commit 'UNCOMMITTED WORKING TREE' + cd ../../.. + git fetch --no-tags "$remote" --refmap \ + +"refs/*:refs/remotes/$remote/*" \ + +"refs/*:refs/remotes/$remote/*" + + exec 3<$play/remerge + # $play will be destroyed by what follows, but we have + # an fd open onto remerge, so this will work + while read <&3 a b; do + echo "Updating gitfetchinfo-merge $a $b" + "$0" gitfetchinfo-merge $a $b + done + + exit 0 +} + tryat_done () { local b="$1" if test -d "$b.edit"; then diff --git a/tests/tests/absurd-gitapply b/tests/tests/absurd-gitapply new file mode 100755 index 0000000..62eb190 --- /dev/null +++ b/tests/tests/absurd-gitapply @@ -0,0 +1,17 @@ +#!/bin/bash +set -e +. tests/lib +t-tstunt-parsechangelog + +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/badcommit-rewrite b/tests/tests/badcommit-rewrite new file mode 100755 index 0000000..b7fc701 --- /dev/null +++ b/tests/tests/badcommit-rewrite @@ -0,0 +1,47 @@ +#!/bin/bash +set -e +. tests/lib + +t-setup-import examplegit +t-tstunt-parsechangelog + +cd example + +suite=stable + +t-commit 'No changes, just send to stable' '' stable + +t-make-badcommit +git reset --hard $badcommit + +t-dgit -wgf build +t-dgit push --overwrite=1.2 stable +t-archive-process-incoming stable + +rstable=refs/remotes/dgit/dgit/stable + +t-dgit fetch stable +t-has-parent-or-is $rstable $badcommit + +fixup=${DGIT_BADCOMMIT_FIXUP-dgit-badcommit-fixup} + +cd $tmp/git/$p.git +$fixup --real + +cd $tmp/$p +git symbolic-ref HEAD >../sym.before +git rev-parse HEAD >../ref.before + +$fixup --real + +git symbolic-ref HEAD >../sym.after +git rev-parse HEAD >../ref.after +diff ../sym.before ../sym.after +set +e; diff ../ref.before ../ref.after; rc=$?; set -e; test $rc = 1 + +t-dgit fetch stable + +t-expect-fail "child $rstable lacks parent $badcommit" \ +t-has-parent-or-is $rstable $badcommit + +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 index 477eb55..e99dac3 100755 --- a/tests/tests/clone-nogit +++ b/tests/tests/clone-nogit @@ -22,4 +22,4 @@ t-dgit push t-pushed-good dgit/sid -echo ok. +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/defdistro-dsd-clone-drs b/tests/tests/defdistro-dsd-clone-drs new file mode 100755 index 0000000..1a1c138 --- /dev/null +++ b/tests/tests/defdistro-dsd-clone-drs @@ -0,0 +1,14 @@ +#!/bin/bash +. tests/lib + +t-restrict x-dgit-intree-only +t-restrict x-dgit-git-only + +export DGIT_TEST_DSD_CLONE_DRS_HOOK=' + t-git-config dgit.default.distro test-dummy + url=$(git config dgit-distro.test-dummy.git-url) + t-git-config dgit-distro.test-dummy/push.git-url "$url" + t-git-config dgit-distro.test-dummy.git-url nosuchprotocol:// +' + +t-alt-test diff --git a/tests/tests/defdistro-mirror b/tests/tests/defdistro-mirror new file mode 100755 index 0000000..8c63451 --- /dev/null +++ b/tests/tests/defdistro-mirror @@ -0,0 +1,5 @@ +#!/bin/bash +set -e +. tests/lib +t-dependencies rsync +t-alt-test diff --git a/tests/tests/defdistro-rpush b/tests/tests/defdistro-rpush new file mode 100755 index 0000000..915f9d3 --- /dev/null +++ b/tests/tests/defdistro-rpush @@ -0,0 +1,4 @@ +#!/bin/bash +set -e +. tests/lib +t-alt-test diff --git a/tests/tests/defdistro-setup b/tests/tests/defdistro-setup new file mode 100755 index 0000000..24faa33 --- /dev/null +++ b/tests/tests/defdistro-setup @@ -0,0 +1,19 @@ +#!/bin/bash +. tests/lib + +t-defdistro + +t-select-package example +t-worktree 1.0 + +cd example + +t-git-config dgit-suite.DGIT-SETUP-TREE.distro test-dummy + +t-dgit setup-useremail +t-dgit setup-mergechangelogs +t-dgit setup-gitattributes + +t-dgit setup-new-tree + +t-ok 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/downstream-gitless b/tests/tests/downstream-gitless new file mode 100755 index 0000000..6b2df1b --- /dev/null +++ b/tests/tests/downstream-gitless @@ -0,0 +1,111 @@ +#!/bin/bash +set -e +. tests/lib +. $troot/lib-reprepro + +t-dependencies reprepro +t-setup-import examplegit +t-tstunt-parsechangelog + + +# rewrite some things, so we test the rewriting code + +mkdir map +cd map +git init +cd .. + +record-map () { + old=$(t-git-get-ref-exact "refs/original/$r") + new=$(t-git-get-ref-exact "$r") + if [ "$old" = "$new" ]; then return; fi + echo >>$tmp/map/map "$old $new" +} + +filter () { + git filter-branch \ + --msg-filter 'sed s/Sid/Spong/' \ + --tag-name-filter cat \ + ^archive/test-dummy/2.0 \ + "$@" + for r in "$@"; do + record-map "$r" + done +} + +cd $p +filter \ + refs/heads/master \ + refs/remotes/dgit/dgit/sid + +t-ref-head + +cd ../git/$p.git +filter \ + refs/dgit/sid + +cd $tmp/map +git add map +git commit -m 'by test suite' +git push $tmp/git/$p.git master:refs/dgit-rewrite/map +cd .. + + +suitespecs=avon +t-reprepro-cfg ds- downstream +t-reprepro-setup ds- +distro='' + + +dscf=$tmp/mirror/pool/main/example_1.1.dsc +t-reprepro-includedsc avon $dscf ds- +t-reprepro-regen ds- + + +mkdir $p.import +cd $p.import +git init +t-dgit import-dsc $dscf x +cd .. + +t-git-config dgit-suite.avon.distro downstream +t-git-config dgit-distro.downstream.git-check false + +t-dgit clone example avon example.avon + + +perl -i -pe 's/ test-dummy / unknown-distro / if m/^Dgit:/' $dscf +cd $p.import + +t-expect-fail 'hinted url with protocol file which is unsafe' \ +t-dgit import-dsc $dscf xunk + +t-git-config dgit.dsc-url-proto-ok.file true +t-dgit import-dsc $dscf xunk + +cd .. + + +dscf=$tmp/mirror/pool/main/example_2.1.dsc +t-reprepro-includedsc avon $dscf ds- +t-reprepro-regen ds- + + +cd $p.avon +t-dgit fetch +t-ref-same refs/remotes/dgit/dgit/avon + +cd ../$p.import +git init +t-dgit import-dsc $dscf +x +t-ref-same refs/heads/x +git show x | grep Spong + +t-expect-fail 'Your git tree does not have that object' \ +t-dgit --no-chase-dsc-distro import-dsc $dscf +y + +cd ../$p +t-dgit --no-chase-dsc-distro import-dsc $dscf +y +git show y | grep Sid + +t-ok diff --git a/tests/tests/drs-clone-nogit b/tests/tests/drs-clone-nogit index dcfb193..915f9d3 100755 --- a/tests/tests/drs-clone-nogit +++ b/tests/tests/drs-clone-nogit @@ -1,4 +1,4 @@ #!/bin/bash set -e . tests/lib -t-drs-test +t-alt-test diff --git a/tests/tests/drs-push-masterupdate b/tests/tests/drs-push-masterupdate new file mode 100755 index 0000000..8457b59 --- /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; 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 index f6f8882..afaed4c 100755 --- a/tests/tests/drs-push-rejects +++ b/tests/tests/drs-push-rejects @@ -5,42 +5,24 @@ set -e t-drs t-git-none -p=pari-extra +t-select-package pari-extra t-worktree drs cd $p -reporefs () { - (set -e - if test -d $tmp/git/$p.git; then - cd $tmp/git/$p.git - git show-ref - fi) -} +git remote set-url origin \ + "ext::$troot/drs-git-ext %S /pari-extra.git" mustfail () { - local wantmsg="$1"; shift - reporefs >$tmp/show-refs.pre-push - set +e - git push origin "$@" 2>&1 |tee $tmp/mustfail.txt - ps="${PIPESTATUS[*]}" - set -e - case $ps in - "0 0") fail "push unexpectedly succeeded (instead of: $wantmsg)" ;; - *" 0") ;; - *) fail "tee failed" ;; - esac - if ! fgrep "$wantmsg" $tmp/mustfail.txt >/dev/null; then - fail "error message not found" - fi - reporefs >$tmp/show-refs.post-push - diff $tmp/show-refs.{pre,post}-push + local mpat="$1"; shift + t-expect-push-fail "$mpat" \ + git push origin "$@" } mustsucceed () { - reporefs >$tmp/show-refs.pre-push + t-reporefs pre-push git push origin "$@" - reporefs >$tmp/show-refs.post-push + t-reporefs post-push if diff $tmp/show-refs.{pre,post}-push >$tmp/show-refs.diff; then fail "no refs updated" fi @@ -48,16 +30,20 @@ mustsucceed () { prep () { local suite=$1 - local csuite=$2 + csuite=$2 cp $tmp/masters/* $tmp/. tag_signer='-u Senatus' tag_message="$p release $version for $suite ($csuite) [dgit]" - tag_name=debian/$version + 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 "$@" } @@ -86,7 +72,7 @@ for h in object type tag; do cat badtag.asc >>badtag set +e - LC_ALL=C git hash-object -w -t tag badtag >badtag.hash 2>badtag.err + LC_MESSAGES=C git hash-object -w -t tag badtag >badtag.hash 2>badtag.err rc=$? set -e @@ -101,6 +87,8 @@ for h in object type tag; do 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 @@ -119,10 +107,11 @@ mustfail 'sid != sponge' HEAD:refs/dgit/sponge $push_spec2 prep unstable sid mktag mustfail 'push is missing tag ref update' $push_spec1 -mustfail 'push is missing head ref update' $push_spec2 +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 'pushing multiple tags' $push_spec HEAD:refs/tags/debian/wombat +mustfail E:'pushing multiple tags|pushing too many similar tags' \ + $push_spec HEAD:refs/tags/$tagpfx/wombat prep unstable sid mktag @@ -149,18 +138,36 @@ mktag HEAD~: mustfail 'tag refers to wrong kind of object' $push_spec prep unstable sid -tag_name=debian/wombat +tag_name=$tagpfx/wombat mktag -#git update-ref debian/$version debian/wombat +#git update-ref $tagpfx/$version $tagpfx/wombat mustfail 'tag name in tag is wrong' \ - refs/tags/debian/wombat:refs/tags/debian/$version $push_spec1 + refs/tags/$tagpfx/wombat:refs/tags/$tagpfx/$version $push_spec1 +t-make-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 'not replacing previously-pushed version' $push_spec +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 @@ -196,4 +203,4 @@ mustfail "not in permissions list although in keyring" $push_spec prep_dm_mangle '' mustsucceed $push_spec # succeeds -echo ok. +t-ok diff --git a/tests/tests/dsd-clone-drs b/tests/tests/dsd-clone-drs new file mode 100755 index 0000000..6065c5f --- /dev/null +++ b/tests/tests/dsd-clone-drs @@ -0,0 +1,17 @@ +#!/bin/bash +set -e +. tests/lib + +t-restrict x-dgit-intree-only +t-restrict x-dgit-git-only + +t-dsd +eval "$DGIT_TEST_DSD_CLONE_DRS_HOOK" + +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 index 1177ed6..7d603b2 100755 --- a/tests/tests/fetch-localgitonly +++ b/tests/tests/fetch-localgitonly @@ -8,9 +8,13 @@ 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 -echo ok. +t-ok diff --git a/tests/tests/fetch-somegit-notlast b/tests/tests/fetch-somegit-notlast index 15b9404..63abe8a 100755 --- a/tests/tests/fetch-somegit-notlast +++ b/tests/tests/fetch-somegit-notlast @@ -12,4 +12,4 @@ cd $p t-cloned-fetched-good t-has-ancestor debian/3-1 -echo ok. +t-ok diff --git a/tests/tests/gbp-orig b/tests/tests/gbp-orig new file mode 100755 index 0000000..9a4937c --- /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 -m 'gbp-orig pseudomerge' 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/gitattributes b/tests/tests/gitattributes new file mode 100755 index 0000000..9e1c246 --- /dev/null +++ b/tests/tests/gitattributes @@ -0,0 +1,256 @@ +#!/bin/bash +set -e +. tests/lib + +t-dependencies bsdgames +t-dependencies man-db git-man +t-tstunt-parsechangelog + +t-archive-none example +t-git-none +bv=1.0 +t-worktree $bv + +: ----- prepare badnesses ----- + +mkdir af + +badattr1 () { + local filename=$1 + local attrspec=$2 + echo >>af/$filename "Test file with $attrspec" + printf >>af/$filename 'crlf: \r\n' + echo >>af/$filename 'id $Id: $' + echo >>af/$filename 'id $Id: SPLARK $' + echo >>gitattrs "af/$filename" "$attrspec" +} + +badattr () { + attrname=$1; shift + badattr1 $attrname-set $attrname + badattr1 $attrname-unset -$attrname + badattr1 $attrname-unspec \!$attrname + local val + for val in "$@"; do + badattr1 $attrname=$val $attrname=$val + done +} + +# xxx want to make each of these files into a quilt patch + +t-git-config core.eol crlf + +badattr text auto +badattr eol lf crlf +badattr ident + +t-git-config filter.dgit-test-crazy-f.smudge '/usr/games/rot13 2' +t-git-config filter.dgit-test-crazy-f.clean '/usr/games/rot13 24' +t-git-config filter.dgit-test-crazy-f.requrired true + +badattr filter dgit-test-crazy-f + +badattr diff +badattr merge text binary union +badattr whitespace +badattr export-ignore +badattr export-subst +badattr delta +badattr encoding no-such-encoding + +man gitattributes \ +| perl -ne 'print $1,"\n" if m/^ *(\w[-a-z]*)$/' \ +> grepped-attrs + +exec <grepped-attrs +while read attr; do + badattr $attr +done + +sha256sum af/* >sums + +# ----- common to source formats ----- + +sfmt_setup () { + v=$1 + sfmt=$2 + + pdb=$p.$sfmt + + local addpatch=${sfmt}_addpatch + local convert=${sfmt}_convert + + cp -a $p $pdb-edit + cd $pdb-edit + + $convert + + dch -v $v -m convert + + rm -rf .git + + cp ../gitattrs .gitattributes + $addpatch gitattrs + + cp -a ../af . + $addpatch files + + cp ../sums . + $addpatch sums + + dpkg-source -b . + + cd .. +} + +sums_check () { + # caller should cd into working directory, set + # $sums $branch + # and check out $branch + + sha256sum af/* >../$sums.checkout + diff -U0 ../sums ../$sums.checkout + + for f in af/*; do + git cat-file blob "refs/heads/$branch:$f" \ + | sha256sum \ + | sed -e 's#-$#'$f'#' \ + >>../$sums + done + + diff -U0 ../sums ../$sums +} + +sums_check_broken () { + # caller should cd into working directory, set + # $sums + # and check out the broken branch + + sha256sum af/* >../$sums.broken + + for s in ../sums ../$sums.broken; do + sed 's/[0-9a-f]* //' $s >$s.nosums + done + diff -U0 ../sums.nosums ../$sums.broken.nosums + set +e + diff -U0 ../sums ../$sums.broken + rc=$? + set -e + test $rc = 1 +} + +t-dgit-warn-check () { + local warnok=$1; shift + # warnok should be 0 if the warning is expected + # 1 if the warning is NOT expected + + local err=stderr.$wd + + LC_MESSAGES=C t-dgit "$@" 2>&1 |tee ../$err + + set +e + egrep 'warning: .* contains \.gitattributes' ../$err + rc=$? + set -e + + test "$rc" = "$warnok" +} + +sfmt_import () { + inst=$1 + dgitargs=$2 + branch="import.$sfmt-$inst" + dscf=${p}_${v}.dsc + sums=sums.$sfmt-$inst + wd=$pdb-import-$inst + + mkdir $wd + cd $wd + git init + + t-dgit-warn-check 0 $dgitargs import-dsc ../$dscf +$branch.broken + + git checkout $branch.broken + + sums_check_broken + + t-dgit setup-new-tree + + t-dgit-warn-check 1 $dgitargs import-dsc ../$dscf +$branch + git checkout $branch + touch af/* + git reset --hard + + sums_check + + cd .. +} + +: ----- generate the orig ----- + +origtar=${p}_${bv}.orig.tar.gz + +tar --exclude=debian --exclude=.git -zcf $origtar $p + +: ----- test 1.0 native ----- + +native_addpatch () { :; } +native_convert () { :; } + +sfmt_setup 1.1 native +sfmt_import norm + +: ----- test 1.0 diff ----- + +diff_addpatch () { :; } +diff_convert () { :; } + +sfmt_setup 1.1 diff +sfmt_import norm + +: ----- test "3.0 (quilt)" ----- + +quilt_addpatch () { + pname=$1 + cat >../editor.pl <<END + next if m/^$/..0; + s{^(description:).*}{\$1 dgit test patch $pname}i; + \$_='' if m/^ /; +END + EDITOR="perl -pi $tmp/editor.pl" dpkg-source -iX --commit . $pname + test -f debian/patches/$pname +} + +quilt_convert () { + mkdir -p debian/source + echo '3.0 (quilt)' >debian/source/format +} + +sfmt_setup 1.0-1 quilt +sfmt_import norm +sfmt_import absurd --force-import-gitapply-absurd + +: ----- 'test clone (with "3.0 (quilt)")' ----- + +mv $origtar ${dscf%.dsc}.* $tmp/mirror/pool/main/ +t-archive-query sid + +t-dgit-warn-check 0 -cdgit.default.setup-gitattributes=false \ + clone $p sid $p.clone.broken +cd $p.clone.broken + +sums=$p.clone.broken +sums_check_broken + +cd .. + +t-dgit-warn-check 1 clone $p sid $p.clone + +cd $p.clone +sums=sums.clone +branch=dgit/sid +sums_check + +cd .. + +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..073ba7b --- /dev/null +++ b/tests/tests/import-dsc @@ -0,0 +1,100 @@ +#!/bin/bash +set -e +. tests/lib +t-tstunt-parsechangelog + +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 --no-chase-dsc-distro + +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-maintmangle b/tests/tests/import-maintmangle new file mode 100755 index 0000000..31a5f88 --- /dev/null +++ b/tests/tests/import-maintmangle @@ -0,0 +1,41 @@ +#!/bin/bash +set -e +. tests/lib +. $troot/lib-import-chk + +t-tstunt-parsechangelog + +t-select-package example +v=1.0 +t-worktree $v + +cd $p + +dsc=${p}_${v}.dsc + +chk () { + local perl="$1" + local unperl="$2" + git checkout master~0 + perl -i -pe "next unless m/^ -- /; $perl" debian/changelog + git commit --allow-empty -a -m "perl $perl" + (cd ..; dpkg-source -i\.git -I.git -b $p) + t-dgit import-dsc ../$dsc +x + git checkout x~0 + t-import-chk-authorship +} + +massage () { + perl -i~ -pe "$unperl" "$1" +} + +import_chk_changelog_massage=massage + +chk + +chk 's/Ian Jackson/Ian Jackson, SPQR/' \ + 's/Ian Jackson, SPQR/Ian Jackson SPQR/' + +chk 's/Ian Jackson/"Ian Jackson, SPQR"/' + +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..3f84881 --- /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; 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; 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; 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..1e885ae --- /dev/null +++ b/tests/tests/mirror-private @@ -0,0 +1,30 @@ +#!/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-archive-process-incoming sid +t-policy-periodic +t-check-mirrored + +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..fee2181 --- /dev/null +++ b/tests/tests/overwrite-chkclog @@ -0,0 +1,50 @@ +#!/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 + +perl -i~ -pe 's/^(\w+ \(\S+\)) stable/$1 UNRELEASED/ if $.>1' debian/changelog +git add debian/changelog +git commit -m 'UNRELEASED changelog' + +t-dgit -wgf build + +t-expect-fail E:'Distribution.*is UNRELEASED' \ +t-dgit push --overwrite stable + +git revert --no-edit 'HEAD^{/UNRELEASED changelog}' + +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/protocol-compat b/tests/tests/protocol-compat new file mode 100755 index 0000000..fcbeedb --- /dev/null +++ b/tests/tests/protocol-compat @@ -0,0 +1,83 @@ +#!/bin/bash +set -e +. tests/lib +. $troot/lib-reprepro + +t-setup-import examplegit +t-tstunt-parsechangelog + +t-git-config dgit.default.distro foreign +t-git-config dgit-distro.foreign.cmd-git false + +prep () { + dscf=$tmp/mirror/pool/main/example_$v.dsc +} + +check () { + pd=$p.$suite + t-refs-same-start + + t-archive-none $p + t-archive-query $suite + + t-dgit clone $p $suite $pd + cd $pd + t-ref-head + + $1 + + local distro='' + t-dgit import-dsc $dscf +imported + t-ref-same refs/heads/imported + cd .. +} + +reset () { + cd .. + rm -rf $pd + mkdir $pd + cd $pd + git init +} + +: ---------- newer ---------- + +suite=sid +v=2.1 +prep + +perl -i~ -pe 's/^Dgit: .*/$& EXTRA DATA\n TO BE IGNORED/' $dscf + +check reset + +: ---------- newline ---------- + +suite=testing +v=2.0 +prep + +perl -i~ -pe 's/^(Dgit: \w+ \S+ \S+) (.*)/$1\n $2 EXTRA/' $dscf + +check reset + +: ---------- older ---------- + +suite=stable +v=1.2 +prep + +perl -i -pe 's/^(Dgit: \w+).*/$1/' $dscf + +check + +: ---------- expect fail ---------- + +pd=$p.fail + +t-git-config dgit.default.old-dsc-distro downstream + +t-expect-fail 'no configured url and .dsc provides no hint' \ +t-dgit clone $p $suite $pd + + +t-ok diff --git a/tests/tests/push-buildproductsdir b/tests/tests/push-buildproductsdir index 987c081..505d105 100755 --- a/tests/tests/push-buildproductsdir +++ b/tests/tests/push-buildproductsdir @@ -28,4 +28,4 @@ t-dgit --build-products-dir=../bpd push t-pushed-good dgit/sid -echo ok. +t-ok diff --git a/tests/tests/push-newpackage b/tests/tests/push-newpackage index 9954b3f..79355e3 100755 --- a/tests/tests/push-newpackage +++ b/tests/tests/push-newpackage @@ -2,20 +2,14 @@ set -e . tests/lib -t-archive-none pari-extra -t-git-none -t-worktree 3-1 -v=3-1 -cd $p -git branch -m dgit/sid master -git remote rm dgit +t-prep-newpackage pari-extra 3-1 +cd $p t-refs-same-start t-ref-head -LANG=C t-dgit push 2>&1 \ - | tee /dev/stderr \ - | grep 'package appears to be new in this suite' >/dev/null +t-expect-push-fail 'package appears to be new in this suite' \ +t-dgit push t-dgit build @@ -33,4 +27,4 @@ t-dgit push --new t-pushed-good master -echo ok. +t-ok diff --git a/tests/tests/push-nextdgit b/tests/tests/push-nextdgit index 8d4a36f..d0436ab 100755 --- a/tests/tests/push-nextdgit +++ b/tests/tests/push-nextdgit @@ -22,4 +22,4 @@ t-dgit push t-pushed-good dgit/sid -echo ok. +t-ok diff --git a/tests/tests/quilt b/tests/tests/quilt index 9a4b105..1a921b3 100755 --- a/tests/tests/quilt +++ b/tests/tests/quilt @@ -19,9 +19,7 @@ git fetch $tmp/incoming/$p dgit/sid:incoming dummy=0 -for cherry in incoming~1 incoming~0; do - git cherry-pick -x $cherry - +iteration () { dummy=$(( $dummy + 1)) v=3.2.6-2~dummy${dummy} @@ -29,9 +27,70 @@ for cherry in incoming~1 incoming~0; do 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' -echo ok. +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/quilt-useremail b/tests/tests/quilt-useremail new file mode 100755 index 0000000..f079395 --- /dev/null +++ b/tests/tests/quilt-useremail @@ -0,0 +1,27 @@ +#!/bin/bash +set -e +. tests/lib + +t-tstunt-parsechangelog +t-archive example 1.0-1 +t-worktree 1.0 +t-git-none + +cd $p + +git checkout quilt-tip-2 + +t-dgit -wgf fetch + +oe=other.email@example.com +on='Hannibal Barca' + +git config --local user.email "$oe" +git config --local user.name "$on" + +t-dgit -wgf --quilt=smash quilt-fixup + +git show | fgrep "$oe" +git show | fgrep "$on" + +t-ok diff --git a/tests/tests/rpush b/tests/tests/rpush index c627788..71bbe2b 100755 --- a/tests/tests/rpush +++ b/tests/tests/rpush @@ -28,4 +28,4 @@ t-dgit --ssh=$troot/ssh rpush somehost:$tmp/$p cd $tmp/$p t-pushed-good dgit/sid -echo ok. +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 diff --git a/tests/tstunt/Dpkg/Changelog/Parse.pm b/tests/tstunt/Dpkg/Changelog/Parse.pm new file mode 100644 index 0000000..d69b7df --- /dev/null +++ b/tests/tstunt/Dpkg/Changelog/Parse.pm @@ -0,0 +1,71 @@ +# -*- perl -*- +# +# Copyright (C) 2015-2016 Ian Jackson +# +# Some bits stolen from the proper Dpkg::Changelog::Parse +# (from dpkg-dev 1.16.16): +# +# Copyright (C) 2005, 2007 Frank Lichtenheld <frank@lichtenheld.de> +# Copyright (C) 2009 Raphael Hertzog <hertzog@debian.org> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +package Dpkg::Changelog::Parse; + +use strict; +use warnings; + +our $VERSION = "1.00"; + +use Dpkg::Control::Changelog; + +use base qw(Exporter); +our @EXPORT = qw(changelog_parse); + +die +(join " ", %ENV)." ?" if $ENV{'DGIT_NO_TSTUNT_CLPARSE'}; + +sub changelog_parse { + my (%options) = @_; # largely ignored + +#use Data::Dumper; +#print STDERR "CLOG PARSE ", Dumper(\%options); +# +# We can't do this because lots of things use `since' which +# we don't implement, and it's the test cases that arrange that +# the since value happens to be such that we are to print one output. +# +# foreach my $k (keys %options) { +# my $v = $options{$k}; +# if ($k eq 'file') { } +# elsif ($k eq 'offset') { die "$v ?" unless $v <= 1; } # wtf, 1==0 ? +# elsif ($k eq 'count') { die "$v ?" unless $v == 1; } +# else { die "$k ?"; } +# } + + $options{'file'} //= 'debian/changelog'; + + open P, "dpkg-parsechangelog -l$options{'file'} |" or die $!; + + my $fields = Dpkg::Control::Changelog->new(); + $fields->parse(\*P, "output of stunt changelog parser"); + +#use Data::Dumper; +#print STDERR "PARSE $0 ", Dumper($fields); + + close P or die "$! $?"; + + return $fields; +} + +1; diff --git a/tests/tstunt/debuild b/tests/tstunt/debuild new file mode 100755 index 0000000..2b2ca71 --- /dev/null +++ b/tests/tstunt/debuild @@ -0,0 +1,4 @@ +#!/bin/bash +set -e +echo "DGIT TEST STUNT DEBUILD $*" >&2 +"${DGIT_TEST_REAL_DEBUILD}" --preserve-env --preserve-envvar PATH "$@" diff --git a/tests/tstunt/dpkg-parsechangelog b/tests/tstunt/dpkg-parsechangelog new file mode 100755 index 0000000..6a9198a --- /dev/null +++ b/tests/tstunt/dpkg-parsechangelog @@ -0,0 +1,78 @@ +#!/usr/bin/perl -w +# +# In an example: +# +# $ time dpkg-parsechangelog >/dev/null +# +# real 0m0.712s +# user 0m0.656s +# sys 0m0.048s +# $ time ~/things/Dgit/dgit/tests/tstunt/dpkg-parsechangelog >/dev/null +# +# real 0m0.016s +# user 0m0.000s +# sys 0m0.012s +# $ + +$SIG{__WARN__} = sub { die $_[0]; }; # no use of system, so we avoid #793471 + +my $infile = "debian/changelog"; + +#print STDERR ">@ARGV<\n"; + +my @orgargv = @ARGV; + +if (@ARGV && $ARGV[0] =~ s/^-l//) { + $infile = shift @ARGV; +} + +if (@ARGV) { + my $strip = $0; + $strip =~ s#/[^/]+$## or die "$0 ?"; + foreach my $k (qw(PATH PERLLIB)) { + my @opath = defined $ENV{$k} ? split /\:/, $ENV{$k} : (); + my @npath = grep { $_ ne $strip } @opath; + @npath != @opath or die "$0 $k ".($ENV{$k}//"(undef)")." ?"; + $ENV{$k} = join ':', @npath; + delete $ENV{$k} if !@npath; + } + die if $ENV{'DGIT_NO_TSTUNT_CLPARSE'}++; + exec 'dpkg-parsechangelog', @orgargv; +} + +use strict; +open C, $infile or die $!; + +$!=0; $_ = <C>; +m/^(\S+) \(([^()]+)\) (\S+)\; urgency=(\S+)$/ or die "$!, $_ ?"; +print <<END or die $!; +Source: $1 +Version: $2 +Distribution: $3 +Urgency: $4 +Changes: + $& +END + +my $blanks = 0; +for (;;) { + $!=0; $_ = <C>; + if (m/^ -- ([^<>]+\<\S+\>) (\w[^<>]+\w)$/) { + print <<END or die $!; +Maintainer: $1 +Date: $2 +END + print "Timestamp: " or die $!; + exec qw(date +%s -d), $2; die $!; + } elsif (m/^ --\s*$/) { + last; + } elsif (!m/\S/) { + $blanks++; + } elsif (m/^ .*\n/) { + print " .\n" x $blanks or die $!; + $blanks=0; + print " $_" or die $!; + } else { + die "$!, $_ ?"; + } +} diff --git a/tests/tstunt/gpg b/tests/tstunt/gpg new file mode 100755 index 0000000..d71aa63 --- /dev/null +++ b/tests/tstunt/gpg @@ -0,0 +1,6 @@ +#!/bin/sh +set -e +exec \ +$DGIT_TEST_REAL_GPG \ + --agent-program=$DGIT_STUNT_AGENT \ + "$@" diff --git a/tests/tstunt/gpg-agent b/tests/tstunt/gpg-agent new file mode 100755 index 0000000..96ae839 --- /dev/null +++ b/tests/tstunt/gpg-agent @@ -0,0 +1,6 @@ +#!/bin/sh +set -e +exec \ +$DGIT_TEST_REAL_GPG_AGENT \ + --debug-quick-random \ + "$@" diff --git a/tests/tstunt/lintian b/tests/tstunt/lintian new file mode 100755 index 0000000..f7c2985 --- /dev/null +++ b/tests/tstunt/lintian @@ -0,0 +1,3 @@ +#!/bin/sh +echo >&2 'W: dgit test suite stunt lintian detects no problems' +exit 0 diff --git a/tests/using-intree b/tests/using-intree index 70d84e1..0235c20 100755 --- a/tests/using-intree +++ b/tests/using-intree @@ -1,6 +1,17 @@ #!/bin/bash +# +# usage: +# cd .../dgit.git +# tests/using-intree tests/test/some-test +# or +# cd .../dgit.git +# tests/using-intree tests/run-all +# +# effects: +# sets DGIT_TEST_INTREE which causes tests/lib to have test scripts +# using programs etc. from the working tree + set -e -tree=`pwd` -export DGIT_TEST="$tree/dgit" -export DGIT_REPOS_SERVER_TEST="$tree/dgit-repos-server" +pwd=`pwd` +export DGIT_TEST_INTREE="$pwd" exec "$@" diff --git a/tests/worktrees/example_1.0.tar b/tests/worktrees/example_1.0.tar Binary files differnew file mode 100644 index 0000000..50baa33 --- /dev/null +++ b/tests/worktrees/example_1.0.tar diff --git a/tests/worktrees/pari-extra_3-1.tar b/tests/worktrees/pari-extra_3-1.tar Binary files differindex 81a6a54..56b797d 100644 --- a/tests/worktrees/pari-extra_3-1.tar +++ b/tests/worktrees/pari-extra_3-1.tar diff --git a/tests/worktrees/pari-extra_drs.tar b/tests/worktrees/pari-extra_drs.tar Binary files differindex 1030178..94c8455 100644 --- a/tests/worktrees/pari-extra_drs.tar +++ b/tests/worktrees/pari-extra_drs.tar diff --git a/tests/worktrees/ruby-rails-3.2_test.tar b/tests/worktrees/ruby-rails-3.2_test.tar Binary files differindex 8c57662..6b0a824 100644 --- a/tests/worktrees/ruby-rails-3.2_test.tar +++ b/tests/worktrees/ruby-rails-3.2_test.tar |